mirror of
https://github.com/macports/pallet.git
synced 2026-07-12 18:18:47 -07:00
Merging with gsoc09-gui branch so that this is not outdated.
git-svn-id: https://svn.macports.org/repository/macports/contrib/MacPorts_Framework@65491 d073be05-634f-4543-b044-5fe20cf6d1d6
This commit is contained in:
@@ -47,6 +47,7 @@
|
||||
// Define BAS_PRIVATE so that we pick up our private definitions from
|
||||
// "BetterAuthorizationSampleLib.h".
|
||||
|
||||
|
||||
#define BAS_PRIVATE 1
|
||||
|
||||
#include "BetterAuthorizationSampleLib.h"
|
||||
@@ -77,7 +78,7 @@
|
||||
|
||||
enum {
|
||||
kIdleTimeoutInSeconds = 120, // if we get no requests in 2 minutes, we quit
|
||||
kWatchdogTimeoutInSeconds = 65 // any given request must be completely in 65 seconds
|
||||
kWatchdogTimeoutInSeconds = 500000 // any given request must be completed in ~5 days (is this ok?)
|
||||
};
|
||||
|
||||
// IMPORTANT:
|
||||
@@ -93,12 +94,12 @@ enum {
|
||||
// 2. Because it's less than 4 GB, this limit ensures that the dictionary size
|
||||
// can be sent as an architecture-neutral uint32_t.
|
||||
|
||||
#define kBASMaxNumberOfKBytes (1024 * 1024)
|
||||
#define kBASMaxNumberOfKBytes (1024 * 1024)
|
||||
|
||||
// A hard-wired file system path for the UNIX domain socket; %s is the placeholder
|
||||
// for the bundle ID (in file system representation).
|
||||
|
||||
#define kBASSocketPathFormat "/var/run/%s.socket"
|
||||
#define kBASSocketPathFormat "/var/run/%s.socket"
|
||||
|
||||
// The key used to get our describe our socket in the launchd property list file.
|
||||
|
||||
@@ -117,9 +118,9 @@ extern int BASOSStatusToErrno(OSStatus errNum)
|
||||
retval = ident; \
|
||||
break
|
||||
switch (errNum) {
|
||||
case noErr:
|
||||
retval = 0;
|
||||
break;
|
||||
case noErr:
|
||||
retval = 0;
|
||||
break;
|
||||
case kENORSRCErr:
|
||||
retval = ESRCH; // no ENORSRC on Mac OS X, so use ESRCH
|
||||
break;
|
||||
@@ -128,9 +129,9 @@ extern int BASOSStatusToErrno(OSStatus errNum)
|
||||
break;
|
||||
CASE(EDEADLK);
|
||||
CASE(EAGAIN);
|
||||
case kEOPNOTSUPPErr:
|
||||
retval = ENOTSUP;
|
||||
break;
|
||||
case kEOPNOTSUPPErr:
|
||||
retval = ENOTSUP;
|
||||
break;
|
||||
CASE(EPROTO);
|
||||
CASE(ETIME);
|
||||
CASE(ENOSR);
|
||||
@@ -145,12 +146,12 @@ extern int BASOSStatusToErrno(OSStatus errNum)
|
||||
CASE(ENOMSG);
|
||||
default:
|
||||
if ( (errNum <= kEPERMErr) && (errNum >= kENOMSGErr) ) {
|
||||
retval = (-3200 - errNum) + 1; // OT based error
|
||||
retval = (-3200 - errNum) + 1; // OT based error
|
||||
} else if ( (errNum >= errSecErrnoBase) && (errNum <= (errSecErrnoBase + ELAST)) ) {
|
||||
retval = (int) errNum - errSecErrnoBase; // POSIX based error
|
||||
retval = (int) errNum - errSecErrnoBase; // POSIX based error
|
||||
} else {
|
||||
retval = (int) errNum; // just return the value unmodified
|
||||
}
|
||||
retval = (int) errNum; // just return the value unmodified
|
||||
}
|
||||
}
|
||||
#undef CASE
|
||||
return retval;
|
||||
@@ -1920,39 +1921,45 @@ static const char * kPlistTemplate =
|
||||
|
||||
// We install the job disabled, then enable it as the last step.
|
||||
|
||||
" <key>Disabled</key>\n"
|
||||
" <true/>\n"
|
||||
" <key>Disabled</key>\n"
|
||||
" <true/>\n"
|
||||
|
||||
// Use the bundle identifier as the job label.
|
||||
|
||||
" <key>Label</key>\n"
|
||||
" <string>%s</string>\n"
|
||||
" <key>Label</key>\n"
|
||||
" <string>%s</string>\n"
|
||||
|
||||
// Use launch on demaind.
|
||||
|
||||
" <key>OnDemand</key>\n"
|
||||
" <true/>\n"
|
||||
" <key>OnDemand</key>\n"
|
||||
" <true/>\n"
|
||||
|
||||
// We don't want our helper tool to be respawned every 10 seconds
|
||||
// after a faliure ... hopefully this won't ALSO prevent us from
|
||||
// rerunning the helper tool without rebooting the machine
|
||||
// " <key>LaunchOnlyOnce</key>\n"
|
||||
// " <true/>\n"
|
||||
// We don't want our helper tool to be respawned every 10 seconds
|
||||
// after a faliure ... hopefully this won't ALSO prevent us from
|
||||
// rerunning the helper tool without rebooting the machine
|
||||
" <key>LaunchOnlyOnce</key>\n"
|
||||
" <true/>\n"
|
||||
|
||||
// There are no program arguments, other that the path to the helper tool itself.
|
||||
// There are no program arguments, other that the path to the helper tool itself
|
||||
// but we must force it to run using the i386 binary if the Framework is
|
||||
// being used as a i386 binary.
|
||||
//
|
||||
// IMPORTANT
|
||||
// kBASToolPathFormat embeds a %s
|
||||
|
||||
" <key>ProgramArguments</key>\n"
|
||||
" <array>\n"
|
||||
" <string>" kBASToolPathFormat "</string>\n"
|
||||
" </array>\n"
|
||||
" <key>ProgramArguments</key>\n"
|
||||
" <array>\n"
|
||||
#ifdef __i386__
|
||||
" <string>/usr/bin/arch</string>\n"
|
||||
" <string>-i386</string>\n"
|
||||
#endif
|
||||
" <string>" kBASToolPathFormat "</string>\n"
|
||||
" </array>\n"
|
||||
|
||||
// The tool is required to check in with launchd.
|
||||
|
||||
" <key>ServiceIPC</key>\n"
|
||||
" <true/>\n"
|
||||
" <key>ServiceIPC</key>\n"
|
||||
" <true/>\n"
|
||||
|
||||
// This specifies the UNIX domain socket used to launch the tool, including
|
||||
// the permissions on the socket (438 is 0666).
|
||||
@@ -1960,20 +1967,20 @@ static const char * kPlistTemplate =
|
||||
// IMPORTANT
|
||||
// kBASSocketPathFormat embeds a %s
|
||||
|
||||
" <key>Sockets</key>\n"
|
||||
" <dict>\n"
|
||||
" <key>" kLaunchDSocketDictKey "</key>\n"
|
||||
" <dict>\n"
|
||||
" <key>SockFamily</key>\n"
|
||||
" <string>Unix</string>\n"
|
||||
" <key>SockPathMode</key>\n"
|
||||
" <integer>438</integer>\n"
|
||||
" <key>SockPathName</key>\n"
|
||||
" <string>" kBASSocketPathFormat "</string>\n"
|
||||
" <key>SockType</key>\n"
|
||||
" <string>Stream</string>\n"
|
||||
" </dict>\n"
|
||||
" </dict>\n"
|
||||
" <key>Sockets</key>\n"
|
||||
" <dict>\n"
|
||||
" <key>" kLaunchDSocketDictKey "</key>\n"
|
||||
" <dict>\n"
|
||||
" <key>SockFamily</key>\n"
|
||||
" <string>Unix</string>\n"
|
||||
" <key>SockPathMode</key>\n"
|
||||
" <integer>438</integer>\n"
|
||||
" <key>SockPathName</key>\n"
|
||||
" <string>" kBASSocketPathFormat "</string>\n"
|
||||
" <key>SockType</key>\n"
|
||||
" <string>Stream</string>\n"
|
||||
" </dict>\n"
|
||||
" </dict>\n"
|
||||
"</dict>\n"
|
||||
"</plist>\n"
|
||||
;
|
||||
@@ -2460,3 +2467,23 @@ extern OSStatus BASFixFailure(
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
extern void BASTerminateCommand (
|
||||
AuthorizationRef auth,
|
||||
const char * bundleID,
|
||||
const char * installToolPath
|
||||
)
|
||||
// Terminate the HelperTool.
|
||||
{
|
||||
// Pre-conditions
|
||||
|
||||
assert(auth != NULL);
|
||||
assert(bundleID != NULL);
|
||||
assert(installToolPath != NULL);
|
||||
|
||||
// Run the install tool as root using AuthorizationExecuteWithPrivileges.
|
||||
RunInstallToolAsRoot(auth, installToolPath, kBASInstallToolTerminateCommand, bundleID, NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -738,6 +738,12 @@ extern void BASCloseDescriptorArray(
|
||||
CFArrayRef descArray
|
||||
);
|
||||
|
||||
extern void BASTerminateCommand(
|
||||
AuthorizationRef auth,
|
||||
const char * bundleID,
|
||||
const char * installToolPath
|
||||
);
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
#pragma mark ***** Utility Routines
|
||||
|
||||
@@ -763,6 +769,7 @@ extern void BASCloseDescriptorArray(
|
||||
|
||||
#define kBASInstallToolInstallCommand "install"
|
||||
#define kBASInstallToolEnableCommand "enable"
|
||||
#define kBASInstallToolTerminateCommand "terminate"
|
||||
|
||||
// Magic values used to bracket the process ID returned by the install tool.
|
||||
|
||||
|
||||
@@ -395,6 +395,24 @@ static int EnableCommand(
|
||||
return err;
|
||||
}
|
||||
|
||||
static int TerminateCommand(
|
||||
const char *bundleID
|
||||
)
|
||||
// Utility function to call through to RunLaunchCtl in order to terminate a job
|
||||
// given by the path contructed from the (const char *) bundleID.
|
||||
{
|
||||
int err;
|
||||
char plistPath[PATH_MAX];
|
||||
|
||||
// Pre-condition.
|
||||
assert(bundleID != NULL);
|
||||
|
||||
(void) snprintf(plistPath, sizeof(plistPath), kBASPlistPathFormat, bundleID);
|
||||
err = RunLaunchCtl(false, "unload", plistPath);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int err;
|
||||
@@ -453,10 +471,17 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "usage4\n");
|
||||
err = EINVAL;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "usage2\n");
|
||||
err = EINVAL;
|
||||
}
|
||||
} else if (strcmp(argv[1], kBASInstallToolTerminateCommand) == 0) {
|
||||
if (argc == 3) {
|
||||
err = TerminateCommand(argv[2]);
|
||||
} else {
|
||||
fprintf(stderr, "usage4\n");
|
||||
err = EINVAL;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "usage2\n");
|
||||
err = EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
// Write "oK" to stdout and quit. The presence of the "oK" on the last
|
||||
|
||||
@@ -19,8 +19,15 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>Randall Wood</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<string>1.1</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
<key>LSMinimumSystemVersionByArchitecture</key>
|
||||
<dict>
|
||||
<key>i386</key>
|
||||
<string>10.4.0</string>
|
||||
<key>x86_64</key>
|
||||
<string>10.6.0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -53,7 +53,6 @@
|
||||
#include <signal.h>
|
||||
|
||||
|
||||
|
||||
//According to the docs all I need is
|
||||
//the file descriptor that MPNotifications
|
||||
//obtained when creating the server socket
|
||||
@@ -822,12 +821,6 @@ int SimpleLog_Command
|
||||
/////////////////////////////////////////////////////////////////
|
||||
#pragma mark ***** Tool Infrastructure
|
||||
|
||||
/*
|
||||
IMPORTANT
|
||||
---------
|
||||
This array must be exactly parallel to the kMPHelperCommandSet array
|
||||
in "MPHelperCommon.c".
|
||||
*/
|
||||
|
||||
static OSStatus DoEvaluateTclString
|
||||
(
|
||||
@@ -984,6 +977,12 @@ static OSStatus DoEvaluateTclString
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
IMPORTANT
|
||||
---------
|
||||
This array must be exactly parallel to the kMPHelperCommandSet array
|
||||
in "MPHelperCommon.c".
|
||||
*/
|
||||
static const BASCommandProc kMPHelperCommandProcs[] = {
|
||||
DoEvaluateTclString,
|
||||
NULL
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
|
||||
#define MPPackage @"macports"
|
||||
#define MPPackageVersion @"1.0"
|
||||
#define MP_DEFAULT_PKG_PATH @"/Library/Tcl"
|
||||
#define TCL_RETURN_CODE @"return code"
|
||||
#define TCL_RETURN_STRING @"return string"
|
||||
#define MPFrameworkErrorDomain @"MacPortsFrameworkErrorDomain"
|
||||
@@ -85,9 +84,6 @@
|
||||
#define MPTRACE @"ports_trace"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
@class MPInterpreter
|
||||
@abstract Tcl interpreter object
|
||||
@@ -104,9 +100,19 @@
|
||||
|
||||
}
|
||||
|
||||
+(NSString*) PKGPath;
|
||||
|
||||
+(void) setPKGPath:(NSString*)newPath;
|
||||
|
||||
+(void) terminateMPHelperTool;
|
||||
|
||||
+(NSTask*) task;
|
||||
|
||||
//Internal methods
|
||||
-(BOOL) setOptionsForNewTclPort:(NSArray *)options;
|
||||
|
||||
-(BOOL) resetTclInterpreterWithPath:(NSString *)path;
|
||||
|
||||
/*!
|
||||
@brief Return singleton shared MPInterpreter instance
|
||||
*/
|
||||
@@ -198,5 +204,6 @@
|
||||
- (void)setAuthorizationRef:(AuthorizationRef)authRef;
|
||||
- (BOOL)checkIfAuthorized;
|
||||
-(NSString *)evaluateStringWithMPHelperTool:(NSString *)statement error:(NSError **)mportError;
|
||||
-(NSString *)evaluateStringWithMPPortProcess:(NSString *)statement error:(NSError **)mportError;
|
||||
|
||||
@end
|
||||
|
||||
@@ -34,18 +34,19 @@
|
||||
*/
|
||||
|
||||
#import "MPInterpreter.h"
|
||||
#import "MPMacPorts.h"
|
||||
#include "BetterAuthorizationSampleLib.h"
|
||||
#include "MPHelperCommon.h"
|
||||
#include "MPHelperNotificationsProtocol.h"
|
||||
static AuthorizationRef internalMacPortsAuthRef;
|
||||
|
||||
|
||||
static NSString* PKGPath = @"/Library/Tcl";
|
||||
static NSTask* aTask;
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation MPInterpreter
|
||||
|
||||
#pragma mark Notifications Code
|
||||
#pragma mark Notifications Code
|
||||
int Notifications_Send(int objc, Tcl_Obj *CONST objv[], int global, Tcl_Interp *interpreter) {
|
||||
NSString *name;
|
||||
NSMutableString *msg;
|
||||
@@ -164,6 +165,20 @@ int Notifications_Command(ClientData clientData, Tcl_Interp *interpreter, int ob
|
||||
//tool
|
||||
static NSString * tclInterpreterPkgPath = nil;
|
||||
|
||||
+(NSString*) PKGPath {
|
||||
return PKGPath;
|
||||
}
|
||||
|
||||
+(void) setPKGPath:(NSString*)newPath {
|
||||
if([PKGPath isNotEqualTo:newPath]) {
|
||||
[PKGPath release];
|
||||
PKGPath = [newPath copy];
|
||||
//I should check if interp is nil. *not needed now
|
||||
MPInterpreter *interp = (MPInterpreter*) [[[NSThread currentThread] threadDictionary] objectForKey:@"sharedMPInterpreter"];
|
||||
[interp resetTclInterpreterWithPath:PKGPath];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Internal Methods
|
||||
//Internal method for initializing actual C Tcl interpreter
|
||||
@@ -184,7 +199,7 @@ static NSString * tclInterpreterPkgPath = nil;
|
||||
}
|
||||
|
||||
if (path == nil)
|
||||
path = MP_DEFAULT_PKG_PATH;
|
||||
path = PKGPath;
|
||||
|
||||
|
||||
NSString * mport_fastload = [[@"source [file join \"" stringByAppendingString:path]
|
||||
@@ -247,7 +262,7 @@ static NSString * tclInterpreterPkgPath = nil;
|
||||
Tcl_DeleteInterp(_interpreter);
|
||||
|
||||
if (tclInterpreterPkgPath == nil)
|
||||
result = [self initTclInterpreter:&_interpreter withPath:MP_DEFAULT_PKG_PATH];
|
||||
result = [self initTclInterpreter:&_interpreter withPath:PKGPath];
|
||||
else
|
||||
result = [self initTclInterpreter:&_interpreter withPath:tclInterpreterPkgPath];
|
||||
|
||||
@@ -259,9 +274,13 @@ static NSString * tclInterpreterPkgPath = nil;
|
||||
return (result && tempResult) ;
|
||||
}
|
||||
|
||||
-(BOOL) resetTclInterpreterWithPath:(NSString*) path {
|
||||
Tcl_DeleteInterp(_interpreter);
|
||||
return [self initTclInterpreter:&_interpreter withPath:PKGPath];
|
||||
}
|
||||
|
||||
- (id) initWithPkgPath:(NSString *)path portOptions:(NSArray *)options {
|
||||
if (self = [super init]) {
|
||||
|
||||
[self initTclInterpreter:&_interpreter withPath:path];
|
||||
|
||||
//set port options maybe I should do this elsewhere?
|
||||
@@ -284,26 +303,23 @@ static NSString * tclInterpreterPkgPath = nil;
|
||||
|
||||
#pragma mark API methods
|
||||
- (id) init {
|
||||
return [self initWithPkgPath:MP_DEFAULT_PKG_PATH portOptions:nil];
|
||||
return [self initWithPkgPath:PKGPath portOptions:nil];
|
||||
}
|
||||
|
||||
+ (MPInterpreter*)sharedInterpreterWithPkgPath:(NSString *)path {
|
||||
@synchronized(self) {
|
||||
if ([[[NSThread currentThread] threadDictionary] objectForKey:@"sharedMPInterpreter"] == nil) {
|
||||
[[self alloc] initWithPkgPath:path portOptions:nil]; // assignment not done here
|
||||
}
|
||||
}
|
||||
return [[[NSThread currentThread] threadDictionary] objectForKey:@"sharedMPInterpreter"];
|
||||
return [self sharedInterpreterWithPkgPath:path portOptions:nil];
|
||||
}
|
||||
|
||||
+ (MPInterpreter*)sharedInterpreter{
|
||||
return [self sharedInterpreterWithPkgPath:MP_DEFAULT_PKG_PATH];
|
||||
return [self sharedInterpreterWithPkgPath:PKGPath];
|
||||
}
|
||||
|
||||
|
||||
|
||||
+ (MPInterpreter*)sharedInterpreterWithPkgPath:(NSString *)path portOptions:(NSArray *)options {
|
||||
@synchronized(self) {
|
||||
if ([PKGPath isNotEqualTo:path]) {
|
||||
[self setPKGPath:path];
|
||||
}
|
||||
|
||||
if ([[[NSThread currentThread] threadDictionary] objectForKey:@"sharedMPInterpreter"] == nil) {
|
||||
[[self alloc] initWithPkgPath:path portOptions:options]; // assignment not done here
|
||||
}
|
||||
@@ -438,30 +454,24 @@ static NSString * tclInterpreterPkgPath = nil;
|
||||
}
|
||||
|
||||
- (NSString *)evaluateStringWithPossiblePrivileges:(NSString *)statement error:(NSError **)mportError {
|
||||
|
||||
|
||||
|
||||
//N.B. I am going to insist that funciton users not pass in nil for the
|
||||
//mportError parameter
|
||||
NSString * firstResult;
|
||||
NSString * secondResult;
|
||||
NSString * result;
|
||||
|
||||
*mportError = nil;
|
||||
firstResult = [self evaluateStringAsString:statement error:mportError];
|
||||
|
||||
//Because of string results of methods like mportsync (which returns the empty string)
|
||||
//the only way to truly check for an error is to check the mportError parameter.
|
||||
//If it is nil then there was no error, if not we re-evaluate with privileges using
|
||||
//the helper tool
|
||||
|
||||
if ( *mportError != nil) {
|
||||
*mportError = nil;
|
||||
secondResult = [self evaluateStringWithMPHelperTool:statement error:mportError];
|
||||
|
||||
return secondResult;
|
||||
}
|
||||
|
||||
return firstResult;
|
||||
[[MPNotifications sharedListener]
|
||||
sendIPCNotification:@"MPInfoNotification_&MP&_stdout_&MP&_None_&MP&_Starting up"];
|
||||
|
||||
// Is this the best way to know if the running user can use macports without privileges?
|
||||
if ([[NSFileManager defaultManager] isWritableFileAtPath:PKGPath]) {
|
||||
result = [self evaluateStringWithMPPortProcess:statement error:mportError];
|
||||
} else {
|
||||
result = [self evaluateStringWithMPHelperTool:statement error:mportError];
|
||||
}
|
||||
|
||||
[[MPNotifications sharedListener]
|
||||
sendIPCNotification:@"MPInfoNotification_&MP&_stdout_&MP&_None_&MP&_Shutting down"];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//NOTE: We expect the Framework client to initialize the AuthorizationRef
|
||||
@@ -583,38 +593,10 @@ static NSString * tclInterpreterPkgPath = nil;
|
||||
//Making the following assumption in error handling. If we return
|
||||
//a noErr then response dictionary cannot be nil since everything went ok.
|
||||
//Hence I'm only checking for errors WITHIN the following blocks ...
|
||||
if (err == noErr) {
|
||||
err = BASExecuteRequestInHelperTool(internalMacPortsAuthRef,
|
||||
kMPHelperCommandSet,
|
||||
(CFStringRef) bundleID,
|
||||
(CFDictionaryRef) request,
|
||||
&response);
|
||||
if (err == noErr){// retrieve result here if available
|
||||
if( response != NULL)
|
||||
result = (NSString *) (CFStringRef) CFDictionaryGetValue(response, CFSTR(kTclStringEvaluationResult));
|
||||
}
|
||||
else { //If we executed unsuccessfully
|
||||
if (mportError != NULL) {
|
||||
NSError * undError = [[[NSError alloc] initWithDomain:NSOSStatusErrorDomain
|
||||
code:err
|
||||
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSLocalizedString(@"Check error code for OSStatus returned",@""),
|
||||
NSLocalizedDescriptionKey,
|
||||
nil]] autorelease];
|
||||
|
||||
*mportError = [[[NSError alloc] initWithDomain:MPFrameworkErrorDomain
|
||||
code:MPHELPINSTFAILED
|
||||
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
NSLocalizedString(@"Unable to execute MPHelperTool successfuly", @""),
|
||||
NSLocalizedDescriptionKey,
|
||||
undError, NSUnderlyingErrorKey,
|
||||
NSLocalizedString(@"BASExecuteRequestInHelperTool execution failed", @""),
|
||||
NSLocalizedFailureReasonErrorKey,
|
||||
nil]] autorelease];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {//This means FixFaliure failed ... Report that in returned error
|
||||
//
|
||||
// NOTE: We don't automatically retry as the user wants to have a consistent cancel
|
||||
// action (i.e. terminate the process when he wants to)
|
||||
if (err != noErr) {//This means FixFaliure failed ... Report that in returned error
|
||||
if (mportError != NULL) {
|
||||
//I'm not sure of exactly how to report this error ...
|
||||
//Do we need some error codes for our domain? I'll define one
|
||||
@@ -643,6 +625,79 @@ static NSString * tclInterpreterPkgPath = nil;
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSString *) evaluateStringWithMPPortProcess:(NSString *) statement error:(NSError **)mportError {
|
||||
aTask = [[NSTask alloc] init];
|
||||
NSMutableArray *args = [NSMutableArray array];
|
||||
|
||||
/* set arguments */
|
||||
[args addObject:PKGPath];
|
||||
[aTask setCurrentDirectoryPath:[[NSBundle bundleForClass:[self class]] resourcePath]];
|
||||
[aTask setLaunchPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"MPPortProcess" ofType:@""]];
|
||||
[aTask setArguments:args];
|
||||
[aTask launch];
|
||||
|
||||
NSConnection *notificationsConnection = [NSConnection defaultConnection];
|
||||
// Vending MPNotifications sharedListener
|
||||
[notificationsConnection setRootObject:[MPNotifications sharedListener]];
|
||||
|
||||
// Register the named connection
|
||||
if ( [notificationsConnection registerName:@"MPNotifications"] ) {
|
||||
NSLog( @"Successfully registered connection with port %@",
|
||||
[[notificationsConnection receivePort] description] );
|
||||
} else {
|
||||
NSLog( @"Name used by %@",
|
||||
[[[NSPortNameServer systemDefaultPortNameServer] portForName:@"MPNotifications"] description] );
|
||||
}
|
||||
|
||||
|
||||
id theProxy;
|
||||
do {
|
||||
theProxy = [NSConnection
|
||||
rootProxyForConnectionWithRegisteredName:@"MPPortProcess"
|
||||
host:nil];
|
||||
}
|
||||
while (theProxy == nil);
|
||||
|
||||
[theProxy evaluateString:statement];
|
||||
[aTask waitUntilExit];
|
||||
|
||||
int status = [aTask terminationStatus];
|
||||
|
||||
if (status != TCL_OK) {
|
||||
NSLog(@"Task failed. Code: %i", status);
|
||||
}
|
||||
[[notificationsConnection receivePort] invalidate];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (NSTask*) task {
|
||||
return aTask;
|
||||
}
|
||||
|
||||
+ (void) terminateMPHelperTool {
|
||||
NSString * bundleID;
|
||||
|
||||
//In order to make the framework work normally by default ... we do a bare initialization
|
||||
//of internalMacPortsAuthRef if the delegate hasn't iniitialzed it already
|
||||
if (internalMacPortsAuthRef == NULL) {
|
||||
OSStatus res = AuthorizationCreate (NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &internalMacPortsAuthRef);
|
||||
assert(res == noErr);
|
||||
}
|
||||
|
||||
NSBundle * mpBundle = [NSBundle bundleForClass:[self class]];
|
||||
NSString * installToolPath = [mpBundle pathForResource:@"MPHelperInstallTool" ofType:nil];
|
||||
bundleID = [mpBundle bundleIdentifier];
|
||||
|
||||
BASSetDefaultRules(internalMacPortsAuthRef,
|
||||
kMPHelperCommandSet,
|
||||
(CFStringRef) bundleID,
|
||||
NULL);
|
||||
BASTerminateCommand(internalMacPortsAuthRef,
|
||||
[bundleID UTF8String],
|
||||
[installToolPath UTF8String]);
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark Authorization Code
|
||||
|
||||
@@ -76,15 +76,15 @@
|
||||
|
||||
}
|
||||
|
||||
+ (NSString*) PKGPath;
|
||||
|
||||
+ (void) setPKGPath:(NSString*)newPath;
|
||||
|
||||
/*!
|
||||
@brief Returns an MPMacPorts object that represents the MacPorts system on user's machine.
|
||||
*/
|
||||
+ (MPMacPorts *)sharedInstance;
|
||||
|
||||
+ (MPMacPorts *)sharedInstanceWithPortOptions:(NSArray *)options;
|
||||
|
||||
//Names of messages below are subject to change
|
||||
+ (MPMacPorts *)sharedInstanceWithPkgPath:(NSString *)path;
|
||||
+ (MPMacPorts *)sharedInstanceWithPkgPath:(NSString *)path portOptions:(NSArray *)options;
|
||||
- (id) initWithPkgPath:(NSString *)path portOptions:(NSArray *)options;
|
||||
- (BOOL) setPortOptions:(NSArray *)options;
|
||||
@@ -221,6 +221,7 @@
|
||||
*/
|
||||
-(BOOL) authorizationMode;
|
||||
|
||||
- (void) cancelCurrentCommand;
|
||||
|
||||
//Notifications stuff for private use and testing purposes
|
||||
-(void)registerForLocalNotifications;
|
||||
|
||||
@@ -39,12 +39,10 @@
|
||||
|
||||
@implementation MPMacPorts
|
||||
|
||||
|
||||
- (id) init {
|
||||
return [self initWithPkgPath:MP_DEFAULT_PKG_PATH portOptions:nil];
|
||||
return [self initWithPkgPath:[MPInterpreter PKGPath] portOptions:nil];
|
||||
}
|
||||
|
||||
|
||||
- (id) initWithPkgPath:(NSString *)path portOptions:(NSArray *)options {
|
||||
if (self = [super init]) {
|
||||
interpreter = [MPInterpreter sharedInterpreterWithPkgPath:path portOptions:nil];
|
||||
@@ -53,16 +51,40 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (MPMacPorts *)sharedInstance {
|
||||
return [self sharedInstanceWithPkgPath:MP_DEFAULT_PKG_PATH];
|
||||
+(NSString*) PKGPath {
|
||||
return [MPInterpreter PKGPath];
|
||||
}
|
||||
|
||||
+ (MPMacPorts *)sharedInstanceWithPortOptions:(NSArray *)options {
|
||||
return [self sharedInstanceWithPkgPath:MP_DEFAULT_PKG_PATH portOptions:options];
|
||||
+(void) setPKGPath:(NSString*)newPath {
|
||||
[MPInterpreter setPKGPath:newPath];
|
||||
}
|
||||
|
||||
- (void) cancelCurrentCommand {
|
||||
if ([[NSFileManager defaultManager] isWritableFileAtPath:[MPInterpreter PKGPath]]) {
|
||||
NSLog(@"Terminating MPPortProcess");
|
||||
NSTask *task = [MPInterpreter task];
|
||||
if(task != nil && [task isRunning]) {
|
||||
[task terminate];
|
||||
}
|
||||
} else {
|
||||
NSLog(@"Terminating MPHelperTool");
|
||||
[MPInterpreter terminateMPHelperTool];
|
||||
}
|
||||
}
|
||||
|
||||
+ (MPMacPorts *)sharedInstance {
|
||||
return [self sharedInstanceWithPkgPath:[MPInterpreter PKGPath] portOptions:nil];
|
||||
}
|
||||
|
||||
+ (MPMacPorts *)sharedInstanceWithPkgPath:(NSString *)path portOptions:(NSArray *)options {
|
||||
@synchronized(self) {
|
||||
if ([path isEqual:nil]) {
|
||||
path = [MPInterpreter PKGPath];
|
||||
}
|
||||
if ([[MPInterpreter PKGPath] isNotEqualTo:path]) {
|
||||
[self setPKGPath:path];
|
||||
}
|
||||
|
||||
if ([[[NSThread currentThread] threadDictionary] objectForKey:@"sharedMPMacPorts"] == nil) {
|
||||
[[self alloc] initWithPkgPath:path portOptions:options ]; // assignment not done here
|
||||
}
|
||||
@@ -70,15 +92,6 @@
|
||||
return [[[NSThread currentThread] threadDictionary] objectForKey:@"sharedMPMacPorts"];
|
||||
}
|
||||
|
||||
+ (MPMacPorts *)sharedInstanceWithPkgPath:(NSString *)path {
|
||||
@synchronized(self) {
|
||||
if ([[[NSThread currentThread] threadDictionary] objectForKey:@"sharedMPMacPorts"] == nil) {
|
||||
[[self alloc] initWithPkgPath:path portOptions:nil ]; // assignment not done here
|
||||
}
|
||||
}
|
||||
return [[[NSThread currentThread] threadDictionary] objectForKey:@"sharedMPMacPorts"];
|
||||
}
|
||||
|
||||
- (BOOL) setPortOptions:(NSArray *)options {
|
||||
return [interpreter setOptionsForNewTclPort:options];
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
//Ask Randall about what exactly port tree path is
|
||||
-(void) testPathToPortIndex {
|
||||
NSURL *pindex = [testPort pathToPortIndex:@"file:///Users/Armahg/macportsbuild/build1/"];
|
||||
NSURL *pindex = [testPort pathToPortIndex:@"file:///Users/juanger/local/macportsbuild/branch-unprivileged/"];
|
||||
STAssertNotNil(pindex, @"URL for port index should not be nil");
|
||||
}
|
||||
|
||||
@@ -74,7 +74,14 @@
|
||||
STAssertNotNil(searchResults, @"This dictionary should have at least %d key value pairs", [searchResults count]);
|
||||
}
|
||||
|
||||
-(void) testPKGPathChange {
|
||||
NSString *newPkgPath = @"/Users/juanger/local/macportsbuild/branch-unprivileged/Library/Tcl";
|
||||
|
||||
STAssertEqualObjects([MPInterpreter PKGPath], @"/Library/Tcl", @"Initialy, the PKGPath should be /Library/Tcl");
|
||||
|
||||
[MPMacPorts sharedInstanceWithPkgPath:newPkgPath portOptions:nil];
|
||||
STAssertEqualObjects([MPInterpreter PKGPath], newPkgPath, @"The global PKGPath should change as needed");
|
||||
}
|
||||
/*-(void) testSync {
|
||||
NSError * syncError = nil;
|
||||
[testPort sync:&syncError];
|
||||
|
||||
@@ -140,6 +140,13 @@
|
||||
*/
|
||||
- (void)deactivateWithVersion:(NSString *)version error:(NSError**)mpError;
|
||||
|
||||
/*!
|
||||
@brief Upgrades an outdated MPPort.
|
||||
@discussion Only installed and active ports
|
||||
should be upgraded
|
||||
*/
|
||||
- (void)upgradeWithError:(NSError**)mpError;
|
||||
|
||||
|
||||
/*!
|
||||
@brief Executes the specified target for this MPPort
|
||||
@@ -290,4 +297,5 @@
|
||||
- (void)execPortProc:(NSString *)procedure withOptions:(NSArray *)options version:(NSString *)version error:(NSError **)execError;
|
||||
//Even more generic method to execute a Tcl command with any given number of args
|
||||
- (void)execPortProc:(NSString *)procedure withParams:(NSArray *)params error:(NSError **)execError;
|
||||
@end
|
||||
|
||||
@end
|
||||
+47
-21
@@ -98,6 +98,10 @@
|
||||
[self setObject:[self objectForKey:@"categories"] forKey:@"categoriesAsString"];
|
||||
[self setObject:[interpreter arrayFromTclListAsString:[self objectForKey:@"categories"]] forKey:@"categories"];
|
||||
}
|
||||
if ([self objectForKey:@"variants"] != nil) {
|
||||
[self setObject:[self objectForKey:@"variants"] forKey:@"variantsAsString"];
|
||||
[self setObject:[interpreter arrayFromTclListAsString:[self objectForKey:@"variants"]] forKey:@"variants"];
|
||||
}
|
||||
if ([self objectForKey:@"depends_build"] != nil) {
|
||||
[self setObject:[self objectForKey:@"depends_build"] forKey:@"depends_buildAsString"];
|
||||
[self setObject:[interpreter arrayFromTclListAsString:[self objectForKey:@"depends_build"]] forKey:@"depends_build"];
|
||||
@@ -115,8 +119,8 @@
|
||||
}
|
||||
|
||||
@try {
|
||||
if ([[self valueForKey:@"long_description"] characterAtIndex:0] == '{') {
|
||||
[self setValue:[self valueForKey:@"description"] forKey:@"long_description"];
|
||||
if ([[self valueForKey:@"description"] characterAtIndex:0] == '{') {
|
||||
[self setValue:[self valueForKey:@"description"] forKey:@"description"];
|
||||
}
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
@@ -124,7 +128,22 @@
|
||||
NSLocalizedStringWithDefaultValue(@"setPortWithTclListAsStringDescreiptionError",
|
||||
@"Localizable",
|
||||
[NSBundle mainBundle],
|
||||
@"Port has an invalid desciption or long_description key.",
|
||||
@"Port has an invalid desciption key.",
|
||||
@"Error statement for exception raised when testing description.")]
|
||||
forKey:@"description"];
|
||||
}
|
||||
|
||||
@try {
|
||||
if ([[self valueForKey:@"long_description"] characterAtIndex:0] == '{') {
|
||||
[self setValue:[self valueForKey:@"long_description"] forKey:@"long_description"];
|
||||
}
|
||||
}
|
||||
@catch (NSException *e) {
|
||||
[self setValue:[NSString stringWithFormat:
|
||||
NSLocalizedStringWithDefaultValue(@"setPortWithTclListAsStringDescreiptionError",
|
||||
@"Localizable",
|
||||
[NSBundle mainBundle],
|
||||
@"Port has an invalid long_description key.",
|
||||
@"Error statement for exception raised when testing long_description.")]
|
||||
forKey:@"long_description"];
|
||||
}
|
||||
@@ -211,7 +230,13 @@
|
||||
procedure, [self name], v, opts]
|
||||
error:execError];
|
||||
}
|
||||
|
||||
// I must get the new state of the port from the registry
|
||||
// instead of just [self setState:MPPortStateLearnState];
|
||||
//NSArray *receipts = [[[MPRegistry sharedRegistry] installed:[self name]] objectForKey:[self name]];
|
||||
//[self setStateFromReceipts:receipts];
|
||||
[self removeObjectForKey:@"receipts"];
|
||||
[self setState:MPPortStateLearnState];
|
||||
|
||||
[[MPNotifications sharedListener] setPerformingTclCommand:@""];
|
||||
[self sendGlobalExecNotification:procedure withStatus:@"Finished"];
|
||||
}
|
||||
@@ -241,23 +266,14 @@
|
||||
//NSString * tclCmd = [@"YES_" stringByAppendingString:target];
|
||||
[[MPNotifications sharedListener] setPerformingTclCommand:target];
|
||||
|
||||
if ([parentMacPortsInstance authorizationMode]) {
|
||||
[interpreter evaluateStringWithMPHelperTool:
|
||||
[NSString stringWithFormat:
|
||||
@"set portHandle [mportopen %@ %@ %@]; mportexec $portHandle %@; mportclose $portHandle",
|
||||
[self valueForKey:@"porturl"], opts, vrnts, target]
|
||||
error:execError];
|
||||
}
|
||||
else {
|
||||
[interpreter evaluateStringWithPossiblePrivileges:
|
||||
[NSString stringWithFormat:
|
||||
@"set portHandle [mportopen %@ %@ %@]; mportexec $portHandle %@; mportclose $portHandle",
|
||||
[self valueForKey:@"porturl"], opts, vrnts, target]
|
||||
error:execError];
|
||||
}
|
||||
|
||||
[interpreter evaluateStringWithPossiblePrivileges:
|
||||
[NSString stringWithFormat:
|
||||
@"set portHandle [mportopen %@ %@ %@]; mportexec $portHandle %@; mportclose $portHandle",
|
||||
[self valueForKey:@"porturl"], opts, vrnts, target]
|
||||
error:execError];
|
||||
|
||||
|
||||
[self setState:MPPortStateLearnState];
|
||||
[[MPNotifications sharedListener] setPerformingTclCommand:@""];
|
||||
[self sendGlobalExecNotification:target withStatus:@"Finished"];
|
||||
|
||||
@@ -331,6 +347,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)upgradeWithError:(NSError **)mError {
|
||||
[self execPortProc:@"mportupgrade" withOptions:nil version:@"" error:mError];
|
||||
}
|
||||
|
||||
-(void)configureWithOptions:(NSArray *)options variants:(NSArray *)variants error:(NSError **)mError {
|
||||
[self exec:@"configure" withOptions:options variants:variants error:mError];
|
||||
}
|
||||
@@ -383,6 +403,7 @@
|
||||
[self exec:@"srpm" withOptions:options variants:variants error:mError];
|
||||
}
|
||||
|
||||
|
||||
# pragma mark -
|
||||
|
||||
|
||||
@@ -390,7 +411,12 @@
|
||||
|
||||
- (id)objectForKey:(id)aKey {
|
||||
if ([aKey isEqualToString:@"receipts"] && ![super objectForKey:aKey]) {
|
||||
[self setObject:[[[MPRegistry sharedRegistry] installed:[self objectForKey:@"name"]] objectForKey:[self objectForKey:@"name"]]forKey:aKey];
|
||||
NSArray *receipts = [[[MPRegistry sharedRegistry] installed:[self objectForKey:@"name"]] objectForKey:[self objectForKey:@"name"]];
|
||||
if (receipts == nil) {
|
||||
return nil;
|
||||
} else {
|
||||
[self setObject:receipts forKey:aKey];
|
||||
}
|
||||
}
|
||||
return [super objectForKey:aKey];
|
||||
}
|
||||
@@ -436,7 +462,7 @@
|
||||
}
|
||||
|
||||
- (void)setStateFromReceipts:(NSArray *)receipts {
|
||||
[self setObject:receipts forKey:@"receipts"];
|
||||
[self setObject:receipts forKey:@"receipts"];
|
||||
[self setState:MPPortStateLearnState];
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,11 @@
|
||||
-(BOOL) installUninstallManipulation:(NSString *)portName {
|
||||
BOOL ret = NO;
|
||||
|
||||
MPMacPorts * port = [MPMacPorts sharedInstanceWithPkgPath:@"/Users/juanger/Projects/gsoc09-gui/MPGUI/build/Debug-InstallMacPorts/macports-1.8/Library/Tcl"
|
||||
portOptions:nil];
|
||||
NSLog(@"PkgPath1: %@", [MPInterpreter PKGPath]);
|
||||
MPRegistry * registry = [MPRegistry sharedRegistry];
|
||||
MPMacPorts * port = [MPMacPorts sharedInstance];
|
||||
|
||||
NSLog(@"PkgPath2: %@", [MPInterpreter PKGPath]);
|
||||
// Check if portName is installed
|
||||
unsigned int installed = [[registry installed:portName] count];
|
||||
|
||||
@@ -41,7 +43,7 @@
|
||||
//I guess we should just return here
|
||||
return ret;
|
||||
}
|
||||
|
||||
NSLog(@"Uninstallation Successful.");
|
||||
//Uninstallation was successful ... now check registry to make sure its gone
|
||||
installed = [[registry installed:portName] count];
|
||||
if (installed > 0) { //Uh oh ... is this suppose to happen?
|
||||
@@ -67,9 +69,11 @@
|
||||
//I guess we should just return here
|
||||
return ret;
|
||||
}
|
||||
|
||||
NSLog(@"Installation successful");
|
||||
//Installation was successful ... now check registry to make sure its gone
|
||||
installed = [[registry installed:portName] count];
|
||||
NSLog(@"%@", [registry installed]);
|
||||
|
||||
if (installed == 0) { //Uh oh ... is this suppose to happen?
|
||||
NSLog(@"%@ is not installed after successful install operation ... double check this from commandline", portName);
|
||||
//for now return
|
||||
@@ -119,15 +123,16 @@
|
||||
// NSLog(@"\n\n Installation successful \n\n");
|
||||
//
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //Double check somehow
|
||||
// MPRegistry * registry = [MPRegistry sharedRegistry];
|
||||
// NSLog(@"\n\n Result from registry is %@ \n\n", [registry installed:[keyArray objectAtIndex:0]]);
|
||||
|
||||
|
||||
PortManipulator * pm = [[PortManipulator alloc] init];
|
||||
STAssertTrue([pm installUninstallManipulation:@"pngcrush"] , @"This test should always return true on success");
|
||||
[pm release];
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
//
|
||||
// MPPortProcess.h
|
||||
// MacPorts.Framework
|
||||
//
|
||||
// Created by Juan Germán Castañeda Echevarría on 7/9/09.
|
||||
// Copyright 2009 UNAM. All rights reserved.
|
||||
//
|
||||
|
||||
#include <tcl.h>
|
||||
|
||||
@interface MPPortProcess : NSObject {
|
||||
Tcl_Interp *interpreter;
|
||||
NSString *PKGPath;
|
||||
}
|
||||
|
||||
|
||||
- (oneway void)evaluateString:(bycopy id)statement;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,104 @@
|
||||
//
|
||||
// MPPortProcess.m
|
||||
// MacPorts.Framework
|
||||
//
|
||||
// Created by Juan Germán Castañeda Echevarría on 7/9/09.
|
||||
// Copyright 2009 UNAM. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MPPortProcess.h"
|
||||
#import "SimpleLog.h"
|
||||
|
||||
@interface MPPortProcess (PrivateMethods)
|
||||
|
||||
- (void)initializeInterpreter;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPPortProcess
|
||||
|
||||
- (id)initWithPKGPath:(NSString*)pkgPath {
|
||||
PKGPath = pkgPath;
|
||||
[self initializeInterpreter];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (oneway void)evaluateString:(bycopy id)statement {
|
||||
// TODO Handle the posible errors and notifications
|
||||
int retCode = Tcl_Eval(interpreter, [statement UTF8String]);
|
||||
if (retCode != TCL_OK) {
|
||||
Tcl_Obj * interpObj = Tcl_GetObjResult(interpreter);
|
||||
int length, errCode;
|
||||
NSString * errString = [NSString stringWithUTF8String:Tcl_GetStringFromObj(interpObj, &length)];
|
||||
errCode = Tcl_GetErrno();
|
||||
|
||||
NSLog(@"- %@ - %i", errString, errCode);
|
||||
exit(errCode);
|
||||
}
|
||||
|
||||
exit(retCode);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Private Methods
|
||||
|
||||
- (void)initializeInterpreter {
|
||||
// Create interpreter
|
||||
interpreter = Tcl_CreateInterp();
|
||||
if(interpreter == NULL) {
|
||||
NSLog(@"Error in Tcl_CreateInterp, aborting.");
|
||||
}
|
||||
// Initialize interpreter
|
||||
if(Tcl_Init(interpreter) == TCL_ERROR) {
|
||||
NSLog(@"Error in Tcl_Init: %s", Tcl_GetStringResult(interpreter));
|
||||
Tcl_DeleteInterp(interpreter);
|
||||
}
|
||||
// Load macports_fastload.tcl from PKGPath/macports1.0
|
||||
NSString * mport_fastload = [[@"source [file join \"" stringByAppendingString:PKGPath]
|
||||
stringByAppendingString:@"\" macports1.0 macports_fastload.tcl]"];
|
||||
if(Tcl_Eval(interpreter, [mport_fastload UTF8String]) == TCL_ERROR) {
|
||||
NSLog(@"Error in Tcl_EvalFile macports_fastload.tcl: %s", Tcl_GetStringResult(interpreter));
|
||||
Tcl_DeleteInterp(interpreter);
|
||||
}
|
||||
// Load notifications methods
|
||||
Tcl_CreateObjCommand(interpreter, "simplelog", SimpleLog_Command, NULL, NULL);
|
||||
if (Tcl_PkgProvide(interpreter, "simplelog", "1.0") != TCL_OK) {
|
||||
NSLog(@"Error in Tcl_PkgProvide: %s", Tcl_GetStringResult(interpreter));
|
||||
}
|
||||
// Load portProcessInit.tcl
|
||||
NSString *portProcessInitPath = @"portProcessInit.tcl";
|
||||
if( Tcl_EvalFile(interpreter, [portProcessInitPath UTF8String]) == TCL_ERROR) {
|
||||
NSLog(@"Error in Tcl_EvalFile portProcessInit.tcl: %s", Tcl_GetStringResult(interpreter));
|
||||
Tcl_DeleteInterp(interpreter);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
int main(int argc, char const * argv[]) {
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
NSConnection *portProcessConnection;
|
||||
portProcessConnection = [NSConnection defaultConnection];
|
||||
NSString *PKGPath = [[NSString alloc] initWithCString:argv[1] encoding:NSUTF8StringEncoding];
|
||||
// NSString *portProcessInitPath = [[NSString alloc] initWithCString:argv[2] encoding:NSUTF8StringEncoding];
|
||||
|
||||
MPPortProcess *portProcess = [[MPPortProcess alloc] initWithPKGPath:PKGPath];
|
||||
|
||||
// Vending portProcess
|
||||
[portProcessConnection setRootObject:portProcess];
|
||||
|
||||
// Register the named connection
|
||||
if ( [portProcessConnection registerName:@"MPPortProcess"] ) {
|
||||
NSLog( @"Successfully registered connection with port %@",
|
||||
[[portProcessConnection receivePort] description] );
|
||||
} else {
|
||||
NSLog( @"Name used by %@",
|
||||
[[[NSPortNameServer systemDefaultPortNameServer] portForName:@"MPPortProcess"] description] );
|
||||
}
|
||||
|
||||
// Wait for any message
|
||||
[[NSRunLoop currentRunLoop] run];
|
||||
[pool release];
|
||||
return 0;
|
||||
}
|
||||
@@ -60,7 +60,7 @@
|
||||
- (NSDictionary *)installed;
|
||||
|
||||
/*
|
||||
@brief Calls [self installed:name version:@""]
|
||||
@brief Calls [self installed:name withVersion:@""]
|
||||
@param name Text to match the port name
|
||||
*/
|
||||
- (NSDictionary *)installed:(NSString *)name;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* SimpleLog.h
|
||||
* MacPorts.Framework
|
||||
*
|
||||
* Created by Juan Germán Castañeda Echevarría on 7/21/09.
|
||||
* Copyright 2009 UNAM. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <tcl.h>
|
||||
|
||||
int SimpleLog_Command(ClientData clientData, Tcl_Interp *interpreter, int objc, Tcl_Obj *CONST objv[]);
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* SimpleLog.m
|
||||
* MacPorts.Framework
|
||||
*
|
||||
* Created by Juan Germán Castañeda Echevarría on 7/21/09.
|
||||
* Copyright 2009 UNAM. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "SimpleLog.h"
|
||||
|
||||
#define MPSEPARATOR @"_&MP&_"
|
||||
|
||||
int SimpleLog_Command(ClientData clientData, Tcl_Interp *interpreter, int objc, Tcl_Obj *CONST objv[]) {
|
||||
int tclResult = TCL_ERROR;
|
||||
NSMutableString * data;
|
||||
|
||||
++objv, --objc;
|
||||
|
||||
if (objc) {
|
||||
int tclCount;
|
||||
const char **tclElements;
|
||||
|
||||
tclResult = Tcl_SplitList(interpreter, Tcl_GetString(*objv), &tclCount, &tclElements);
|
||||
|
||||
|
||||
if (tclResult == TCL_OK) {
|
||||
if (tclCount > 0) {
|
||||
NSLog([NSString stringWithUTF8String:tclElements[0]]);
|
||||
data = [NSMutableString stringWithUTF8String:tclElements[0]];
|
||||
[data appendString:MPSEPARATOR];
|
||||
|
||||
if(tclCount > 1 && tclElements[1]) {
|
||||
NSLog([NSString stringWithUTF8String:tclElements[1]]);
|
||||
[data appendString:[NSString stringWithUTF8String:tclElements[1]]];
|
||||
[data appendString:MPSEPARATOR];
|
||||
}
|
||||
else {
|
||||
[data appendString:@"None"];
|
||||
[data appendString:MPSEPARATOR];
|
||||
}
|
||||
|
||||
if(tclCount > 2 && tclElements[2]) {
|
||||
NSLog([NSString stringWithUTF8String:tclElements[2]]);
|
||||
[data appendString:[NSString stringWithUTF8String:tclElements[2]]];
|
||||
[data appendString:MPSEPARATOR];
|
||||
}
|
||||
else {
|
||||
[data appendString:@"None"];
|
||||
[data appendString:MPSEPARATOR];
|
||||
}
|
||||
}
|
||||
else {
|
||||
data = [NSMutableString stringWithFormat:@"None%@None%@None%@", MPSEPARATOR, MPSEPARATOR, MPSEPARATOR ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Now get the actual message
|
||||
++objv; --objc;
|
||||
if (objc) {
|
||||
[data appendString:[NSString stringWithUTF8String:Tcl_GetString(*objv)]];
|
||||
}
|
||||
else {
|
||||
[data appendString:@"None"];
|
||||
}
|
||||
|
||||
id theProxy = [NSConnection
|
||||
rootProxyForConnectionWithRegisteredName:@"MPNotifications"
|
||||
host:nil];
|
||||
[theProxy sendIPCNotification:data];
|
||||
|
||||
NSLog(@"-----%@", data);
|
||||
|
||||
return tclResult;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.yourcompany.${PRODUCT_NAME:identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user