// // Perforce_ServerConfig.m // Perforce Server // // Created by Mike Ashmore on 3/3/10. // Copyright 2010 Mike Ashmore. All rights reserved. // #import "Perforce_ServerConfig.h" NSString *kLogPath = @"com.perforce.p4d.logPath"; NSString *kRootPath = @"com.perforce.p4d.rootPath"; NSString *kPortNumber = @"com.perforce.p4d.portNumber"; @implementation Perforce_ServerConfig @synthesize isRunning; - (BOOL) authenticatedRunCommand:(NSString *)command { BOOL ret = NO; char *buf = NULL; asprintf(&buf, [command UTF8String]); if(!buf) { return FALSE; } char* arguments[] = { "-c", buf, NULL }; if(AuthorizationExecuteWithPrivileges(auth, "/bin/sh", kAuthorizationFlagDefaults, arguments, NULL) == errAuthorizationSuccess) { int status; int pid = wait(&status); if(pid != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) ret = YES; } free(buf); return ret; } - (BOOL) installPlist { NSDictionary *launchdPlist = [self launchdPrefList]; [launchdPlist writeToFile:@"/tmp/com.perforce.p4d.plist" atomically:YES]; return [self authenticatedRunCommand:@"cp /tmp/com.perforce.p4d.plist /Library/LaunchDaemons/com.perforce.p4d.plist"]; } - (void) startServer { NSFileManager *fileManager = [NSFileManager defaultManager]; if (auth == nil && AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagInteractionAllowed, &auth) != errAuthorizationSuccess) { auth = nil; } NSString *plistPath = @"/Library/LaunchDaemons/com.perforce.p4d.plist"; if (![fileManager fileExistsAtPath:plistPath]) { [self installPlist]; } [self authenticatedRunCommand:[@"launchctl load " stringByAppendingString:plistPath]]; self.isRunning = true; } - (void) stopServer { if (auth == nil && AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagInteractionAllowed, &auth) != errAuthorizationSuccess) { auth = nil; } NSString *plistPath = @"/Library/LaunchDaemons/com.perforce.p4d.plist"; [self authenticatedRunCommand:[@"launchctl unload " stringByAppendingString:plistPath]]; [self authenticatedRunCommand:[@"rm " stringByAppendingString:plistPath]]; self.isRunning = false; } - (NSDictionary *) baseConfig { // default locations for some files we're going to use NSString *defaultRootPath = [@"~/Documents/p4d" stringByStandardizingPath]; NSString *defaultLogPath = [@"~/Documents/p4d/log" stringByStandardizingPath]; // Set up environment variables NSDictionary *defaultEnvironment = [NSDictionary dictionaryWithObjectsAndKeys: defaultRootPath, kRootPath, defaultLogPath, kLogPath, [NSNumber numberWithInt:1666], kPortNumber, nil]; return defaultEnvironment; } - (void) awakeFromNib { auth = nil; defaultsController = [[NSUserDefaultsController alloc] initWithDefaults:nil initialValues:[self baseConfig]]; } - (NSDictionary *) launchdPrefList { NSBundle *mb = [NSBundle bundleWithIdentifier:@"com.perforce.p4d"]; NSString *launchdPlistTemplatePath = [mb pathForResource:@"com.perforce.p4d.plist" ofType:nil]; NSDictionary *launchdTemplate = [NSDictionary dictionaryWithContentsOfFile:launchdPlistTemplatePath]; NSString *p4dPath = [mb pathForResource:@"p4d" ofType:nil]; // Only one program argument, the path to the server. NSArray *programArgs = [NSArray arrayWithObject:p4dPath]; [launchdTemplate setValue:programArgs forKey:@"ProgramArguments"]; NSString *rootPath = [@"~/Documents/p4d" stringByStandardizingPath]; NSString *logPath = [@"~/Documents/p4d/log" stringByStandardizingPath]; NSNumber *portNumber = [NSNumber numberWithInt:1666]; // and the environment variables we're setting ... NSDictionary *environment = [NSDictionary dictionaryWithObjectsAndKeys: rootPath, @"P4ROOT", logPath, @"P4LOG", [NSString stringWithFormat:@"%@", portNumber], @"P4PORT", nil]; [launchdTemplate setValue:environment forKey:@"EnvironmentVariables"]; return launchdTemplate; } - (void) dealloc { [defaultsController release]; [super dealloc]; } @end