[38760] branches/gsoc08-framework/MacPorts_Framework
armahg at macports.org
armahg at macports.org
Wed Jul 30 09:29:12 PDT 2008
Revision: 38760
http://trac.macosforge.org/projects/macports/changeset/38760
Author: armahg at macports.org
Date: 2008-07-30 09:29:11 -0700 (Wed, 30 Jul 2008)
Log Message:
-----------
Things are about to get messy with MPHelperTool. Need a sane place to revert to if they go really awry. This is it
Modified Paths:
--------------
branches/gsoc08-framework/MacPorts_Framework/MPHelperTool.m
branches/gsoc08-framework/MacPorts_Framework/MPInterpreter.h
branches/gsoc08-framework/MacPorts_Framework/MPInterpreter.m
branches/gsoc08-framework/MacPorts_Framework/MPInterpreterTest.h
branches/gsoc08-framework/MacPorts_Framework/MPInterpreterTest.m
branches/gsoc08-framework/MacPorts_Framework/MPMacPortsTest.h
branches/gsoc08-framework/MacPorts_Framework/MPMacPortsTest.m
branches/gsoc08-framework/MacPorts_Framework/MPNotifications.m
branches/gsoc08-framework/MacPorts_Framework/MacPorts.Framework.xcodeproj/project.pbxproj
Modified: branches/gsoc08-framework/MacPorts_Framework/MPHelperTool.m
===================================================================
--- branches/gsoc08-framework/MacPorts_Framework/MPHelperTool.m 2008-07-30 12:30:35 UTC (rev 38759)
+++ branches/gsoc08-framework/MacPorts_Framework/MPHelperTool.m 2008-07-30 16:29:11 UTC (rev 38760)
@@ -8,34 +8,181 @@
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
+#import <Security/Security.h>
#import "MPInterpreter.h"
+#include <stdlib.h>
+#include <sys/stat.h>
-int main(int argc, char * const *argv) {
+// /////////////////////////////////////////////////////////////////////////////
+// exitCleanly
+//
+// Exits the program with the correct status and releases the autorelease pool.
+void exitCleanly(int code, NSAutoreleasePool *pool)
+{
+ [pool release];
+ exit(code);
+}
+
+
+
+//This code is adapted from :
+// http://forums.macrumors.com/showthread.php?t=508394
+
+//I will first try implementing this without any Authorization services.
+//I just want a helper tool whose user id is set to 0 and can self repair itself
+//I will be using message passing for IPC rather than piping or anything else
+//like that. Check on IRC if there are any dangers in doing that.
+
+
+
+
+//Usage
+// ./MPHelperTool --self-repair srOptions --rec-count recOptions interpCmd
+// So argv is of size 6 ... no more no less
+
+// srOptions is a C string with value of "yes" or "no" to tell us whether or not
+// to run self repair
+
+//recOptions is a number telling us how many times we have been called recursively
+
+//interpCmd is a the
+
+int main(int argc, char const * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
- NSString * pathtoself = [[NSBundle mainBundle] pathForResource:@"MPHelperTool"
- ofType:nil];
+ setuid(0);
+ NSLog(@"UID is %i", geteuid());
+ //Check for right number of args
+ if (argc != 6) {
+ exitCleanly(TCL_ERROR , pool);
+ }
- NSLog(@"Path to executable is %@", pathtoself);
+ //The second thing to check for is recOptions ... This method should be called
+ //recursively at most once. Its a bit weird but I think from the code above,
+ //this tool repairs itself AND THEN proceeds to execute the required command all in
+ //one process. This means the number of recursive calls should not exceed one.
+ //If we fail to self repair at the first try, we should just exit.
+
+
+ int recOptions = [[NSString stringWithCString:argv[4] encoding:NSUTF8StringEncoding] intValue];
+ if (recOptions > 1) {
+ exitCleanly(TCL_ERROR, pool);
+ }
+ else {
+ ++recOptions;
+ }
- if (argc == 2) {
- MPInterpreter * interp = [MPInterpreter sharedInterpreter];
+ MPInterpreter * interp = [MPInterpreter sharedInterpreter];
+ NSString * interpCmd = [NSString stringWithCString:argv[5] encoding:NSUTF8StringEncoding];
+ NSString * _path_to_self = [[NSBundle mainBundle] pathForResource:@"MPHelperTool"
+ ofType:nil];
+
+ //OSStatus status;
+ BOOL authenticatedMode = YES;
+ //AuthorizationRef auth;
+ //AuthorizationExternalForm extAuth;
+
+ //This memory pointer should be valid till _path_to_self is freed or released
+ //in the autorelease pool .. in other words its save for our purposes
+ //and we dont' have to worry about releasing memory
+ const char * path_to_self = [_path_to_self cStringUsingEncoding:NSUTF8StringEncoding];
+
+ if (!strcmp(argv[1], "--self-repair") && !strcmp(argv[2], "yes") )
+ {
+ NSLog(@"MacPortsFramework MPHelperTool main Self-repair. Starting");
+ // We have started ourself in self-repair mode. This means that this executable is not owned by root and/or the setuid bit is not set. We need to recover that...
+ struct stat st;
+ int fd_tool;
+
+
+ //We don't need this code for now
+ /* Recover the passed in AuthorizationRef.*/
+
+
+ /* Open tool exclusively, so noone can change it while we bless it */
+ fd_tool = open(path_to_self, O_NONBLOCK|O_RDONLY|O_EXLOCK, 0);
+
+ if (fd_tool == -1)
+ {
+ NSLog(@"MacPortsFramework MPHelperTool main Self-Repair. Exclusive open while repairing tool failed: %d.",errno);
+ exitCleanly(-1,pool);
+ }
+
+ if (fstat(fd_tool, &st))
+ {
+ NSLog(@"MacPortsFramework MPHelperTool main Self-Repair. fstat failed");
+ exitCleanly(-1,pool);
+ }
+
+ if (st.st_uid != 0)
+ {
+ fchown(fd_tool, 0, st.st_gid);
+ }
+
+
+ /* Disable group and world writability and make setuid root. */
+ fchmod(fd_tool, (st.st_mode & (~(S_IWGRP|S_IWOTH))) | S_ISUID);
+
+ close(fd_tool);
+
+ NSLog(@"MacPortsFramework MPHelperTool main Self-repair. Complete");
+ authenticatedMode = YES;
+
+
+ /*/Hopefully this works
+ int result = [interp execute:_path_to_self
+ withArgs:[NSArray arrayWithObjects:SELF_REPAIR, @"no", REC_COUNT,
+ [NSString stringWithFormat:@"%d", recOptions], interpCmd, nil]];
+
+ exitCleanly(result, pool);*/
+
+
+ }
+ else
+ {
+ //To Do
+ //Add code here to receive Authorization reference from somwhere
+
+ authenticatedMode = YES;
+ }
+
+ /* If we are not running as root we need to self-repair. But we don't want to do it more than once
+ which means */
+ if (authenticatedMode && geteuid() != 0)
+ {
+ NSLog(@"MacPortsFramework MPHelperTool main Normal-Mode. Not running as root! Starting self-repair mode.");
+
+ //We run again in self repair mode. I am assuming that this new "forked" process
+ // will be able to repair the binary and execute the command successfully ...
+ //if it fails I guess i should return something to that effect?
+ int result = [interp execute:_path_to_self
+ withArgs:[NSArray arrayWithObjects:SELF_REPAIR, @"yes", REC_COUNT,
+ [NSString stringWithFormat:@"%d", recOptions], interpCmd, nil]];
+
+
+ //Is the above method guaranteed to always complete before the
+ //program execution gets here?
+ exitCleanly(result, pool);
+
+
+ }
+
+ //Now we can finally execute the method ... whew
+ if (interpCmd != nil) {
NSError * evalError;
- ++argv;
- NSString * interpCmd = [NSString stringWithCString:*argv];
NSLog(@"Executin Tcl command %@", interpCmd);
NSString * result = [interp evaluateStringAsString:interpCmd
error:&evalError];
if(result == nil && evalError) {
NSLog(@"Command %@ exited with Error %@", interpCmd, evalError);
- return TCL_ERROR;
+ exitCleanly(TCL_ERROR,pool);
}
else {
NSLog(@"Command %@ returned %@", interpCmd, result);
- return TCL_OK;
+ exitCleanly(TCL_OK, pool);
}
/*while(*argv != NULL) {
NSLog(@"Passed parameter is %@", [NSString stringWithCString:*argv]);
Modified: branches/gsoc08-framework/MacPorts_Framework/MPInterpreter.h
===================================================================
--- branches/gsoc08-framework/MacPorts_Framework/MPInterpreter.h 2008-07-30 12:30:35 UTC (rev 38759)
+++ branches/gsoc08-framework/MacPorts_Framework/MPInterpreter.h 2008-07-30 16:29:11 UTC (rev 38760)
@@ -43,6 +43,11 @@
#include <tcl.h>
#import "MPNotifications.h"
+
+//Defining some flags for MPHelperTool
+#define SELF_REPAIR @"--self-repair"
+#define REC_COUNT @"--rec-count"
+
#define MPPackage @"macports"
#define MPPackageVersion @"1.0"
#define MP_DEFAULT_PKG_PATH @"/Library/Tcl"
@@ -70,8 +75,8 @@
+ (MPInterpreter *)sharedInterpreter;
- (Tcl_Interp *) sharedTclInterpreter;
+- (int) execute:(NSString *)pathToExecutable withArgs:(NSArray*)args;
-
+ (MPInterpreter *)sharedInterpreterWithPkgPath:(NSString *)path;
- (id) initWithPkgPath:(NSString *)path;
Modified: branches/gsoc08-framework/MacPorts_Framework/MPInterpreter.m
===================================================================
--- branches/gsoc08-framework/MacPorts_Framework/MPInterpreter.m 2008-07-30 12:30:35 UTC (rev 38759)
+++ branches/gsoc08-framework/MacPorts_Framework/MPInterpreter.m 2008-07-30 16:29:11 UTC (rev 38760)
@@ -243,6 +243,17 @@
#pragma Utilities
+- (int) execute:(NSString *)pathToExecutable withArgs:(NSArray *)args {
+ NSTask * task = [[NSTask alloc] init];
+ [task setLaunchPath:pathToExecutable];
+ [task setArguments:args];
+ [task launch];
+ [task waitUntilExit];
+ int status = [task terminationStatus];
+ [task release];
+ return status;
+}
+
/*- (NSDictionary *)evaluateArrayAsString:(NSArray *)statement {
return [self evaluateStringAsString:[statement componentsJoinedByString:@" "]];
}
@@ -257,10 +268,10 @@
Tcl_Obj * interpObj = Tcl_GetObjResult(_interpreter);
int length, errCode;
NSString * errString = [NSString stringWithUTF8String:Tcl_GetStringFromObj(interpObj, &length)];
- NSLog(@"TclObj string is %@ with length %d", errString , length);
+ //NSLog(@"TclObj string is %@ with length %d", errString , length);
errCode = Tcl_GetErrno();
- NSLog(@"Errno Id is %@ with value %d", [NSString stringWithUTF8String:Tcl_ErrnoId()], errCode);
- NSLog(@"Errno Msg is %@", [NSString stringWithUTF8String:Tcl_ErrnoMsg(errCode)]);
+ //NSLog(@"Errno Id is %@ with value %d", [NSString stringWithUTF8String:Tcl_ErrnoId()], errCode);
+ //NSLog(@"Errno Msg is %@", [NSString stringWithUTF8String:Tcl_ErrnoMsg(errCode)]);
//Handle errors here ... Framework users can do !mportError to find out if
//method was successful
Modified: branches/gsoc08-framework/MacPorts_Framework/MPInterpreterTest.h
===================================================================
--- branches/gsoc08-framework/MacPorts_Framework/MPInterpreterTest.h 2008-07-30 12:30:35 UTC (rev 38759)
+++ branches/gsoc08-framework/MacPorts_Framework/MPInterpreterTest.h 2008-07-30 16:29:11 UTC (rev 38760)
@@ -43,6 +43,7 @@
- (void)testInitialization;
- (void)testGetVariableAsArray;
+//- (void)testMPHelperTool;
//- (void)testMutableDictionaryFromTclListAsString;
//- (void)testEvaluateStringAsString;
Modified: branches/gsoc08-framework/MacPorts_Framework/MPInterpreterTest.m
===================================================================
--- branches/gsoc08-framework/MacPorts_Framework/MPInterpreterTest.m 2008-07-30 12:30:35 UTC (rev 38759)
+++ branches/gsoc08-framework/MacPorts_Framework/MPInterpreterTest.m 2008-07-30 16:29:11 UTC (rev 38760)
@@ -59,6 +59,16 @@
/*
+- (void)testMPHelperTool {
+
+ //Interesting ... we'll see who MPInterpreter belongs to
+ //at the time of execution MPHelperTool ... or MacPorts.Framework
+ [interp execute:[[NSBundle bundleForClass:MPInterpreter] pathForResource:@"MPHelperTool" ofType:nil]
+ withArgs:[NSArray arrayWithObjects:@"--sel-repair", @"no", @"--rec-count",
+ @"0", @"mportselfupdate", nil]];
+}
+
+/*
Having trouble coming up with test cases for the methods below. Speak to Randall
about that.
*
Modified: branches/gsoc08-framework/MacPorts_Framework/MPMacPortsTest.h
===================================================================
--- branches/gsoc08-framework/MacPorts_Framework/MPMacPortsTest.h 2008-07-30 12:30:35 UTC (rev 38759)
+++ branches/gsoc08-framework/MacPorts_Framework/MPMacPortsTest.h 2008-07-30 16:29:11 UTC (rev 38760)
@@ -42,7 +42,7 @@
}
--(void) testMPHelperTool;
+
-(void) testPortCreation;
-(void) testPrefix;
-(void) testSources;
@@ -52,5 +52,6 @@
-(void) testSync;
-(void) testVersion;
//-(void) testInstall;
+-(void) testMPHelperTool;
@end
Modified: branches/gsoc08-framework/MacPorts_Framework/MPMacPortsTest.m
===================================================================
--- branches/gsoc08-framework/MacPorts_Framework/MPMacPortsTest.m 2008-07-30 12:30:35 UTC (rev 38759)
+++ branches/gsoc08-framework/MacPorts_Framework/MPMacPortsTest.m 2008-07-30 16:29:11 UTC (rev 38760)
@@ -111,7 +111,8 @@
pathForResource:@"MPHelperTool"
ofType:nil]];
- NSArray * args = [NSArray arrayWithObjects:@"return [macports::version]", nil];
+ NSArray * args = [NSArray arrayWithObjects:SELF_REPAIR, @"no",
+ REC_COUNT, @"0", @"return [macports::version]", nil];
[task setArguments:args];
[task launch];
Modified: branches/gsoc08-framework/MacPorts_Framework/MPNotifications.m
===================================================================
--- branches/gsoc08-framework/MacPorts_Framework/MPNotifications.m 2008-07-30 12:30:35 UTC (rev 38759)
+++ branches/gsoc08-framework/MacPorts_Framework/MPNotifications.m 2008-07-30 16:29:11 UTC (rev 38760)
@@ -85,7 +85,7 @@
[NSNumber numberWithInt:0], MPMSG, [NSNumber numberWithInt:0], MPINFO,
[NSNumber numberWithInt:0], MPWARN, [NSNumber numberWithInt:0], MPERROR,
[NSNumber numberWithInt:1], MPDEBUG, [NSNumber numberWithInt:0], MPALL, nil];
- NSLog(@"Dictionary is %@ ", [blockOptions description]);
+ //NSLog(@"Dictionary is %@ ", [blockOptions description]);
}
return self;
}
Modified: branches/gsoc08-framework/MacPorts_Framework/MacPorts.Framework.xcodeproj/project.pbxproj
===================================================================
--- branches/gsoc08-framework/MacPorts_Framework/MacPorts.Framework.xcodeproj/project.pbxproj 2008-07-30 12:30:35 UTC (rev 38759)
+++ branches/gsoc08-framework/MacPorts_Framework/MacPorts.Framework.xcodeproj/project.pbxproj 2008-07-30 16:29:11 UTC (rev 38760)
@@ -56,6 +56,7 @@
6ED12AFB0E3E9F980026773D /* MPNotifications.h in Headers */ = {isa = PBXBuildFile; fileRef = 6E270D070E158CED00BAE687 /* MPNotifications.h */; };
6ED12AFC0E3E9FA60026773D /* MPNotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = 6E270D080E158CED00BAE687 /* MPNotifications.m */; };
6ED12B060E3EA9E30026773D /* init.tcl in Resources */ = {isa = PBXBuildFile; fileRef = 48E9939E0C82CEB000219DDF /* init.tcl */; };
+ 6ED12C9E0E40C3320026773D /* template.c in Resources */ = {isa = PBXBuildFile; fileRef = 6ED12C9D0E40C3320026773D /* template.c */; };
8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; };
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; };
/* End PBXBuildFile section */
@@ -118,6 +119,8 @@
6ED12A540E3E55DF0026773D /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = "<absolute>"; };
6ED12AA20E3E7E7C0026773D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
6ED12AA60E3E7E900026773D /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+ 6ED12C2D0E405E660026773D /* finkLauncher.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = finkLauncher.c; sourceTree = "<group>"; };
+ 6ED12C9D0E40C3320026773D /* template.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = template.c; sourceTree = "<group>"; };
8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
8DC2EF5B0486A6940098B216 /* MacPorts.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MacPorts.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
@@ -288,6 +291,8 @@
isa = PBXGroup;
children = (
6ED12A4E0E3E55660026773D /* MPHelperTool.m */,
+ 6ED12C2D0E405E660026773D /* finkLauncher.c */,
+ 6ED12C9D0E40C3320026773D /* template.c */,
);
name = MPHelperTool;
sourceTree = "<group>";
@@ -418,6 +423,7 @@
buildActionMask = 2147483647;
files = (
6ED12B060E3EA9E30026773D /* init.tcl in Resources */,
+ 6ED12C9E0E40C3320026773D /* template.c in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/macports-changes/attachments/20080730/50f30df1/attachment.html
More information about the macports-changes
mailing list