authTool.c 3.65 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
#include <unistd.h>
#include <stdbool.h>
#include <CoreFoundation/CoreFoundation.h>

static void CFQRelease(CFTypeRef cf)
// A version of CFRelease that's tolerant of NULL.
{
    if (cf != NULL) {
        CFRelease(cf);
    }
}

static int GetPathToSelf(char **pathToSelfPtr)
// A drop-in replacement for GetPathToSelf() from MoreAuthSample's MoreSecurity.c,
// implemented using CoreFoundation. From CocoaDev.com
{
	int err = 0;
	
	assert( pathToSelfPtr != NULL);
	assert(*pathToSelfPtr == NULL);
	
	CFBundleRef mainBundle = CFBundleGetMainBundle();
	CFURLRef executableURL = NULL;
	CFStringRef pathStringRef = NULL;
	
	char *path = NULL;
	
	if (mainBundle != NULL) {
		executableURL =  CFBundleCopyExecutableURL(mainBundle);
		if (executableURL != NULL) {
			pathStringRef = CFURLCopyFileSystemPath(executableURL, kCFURLPOSIXPathStyle);
			if (pathStringRef != NULL) {
				CFIndex pathSize = CFStringGetLength(pathStringRef) + 1;
				path = (char *)calloc(pathSize,1);
				if (path != NULL) {
					Boolean gotCString = CFStringGetCString(pathStringRef, path, pathSize, kCFStringEncodingUTF8);
					if (!gotCString) {
						free(path);
						path = NULL;
					}
				}
			}
		}
	}
	
	*pathToSelfPtr = path;
	
	// Do the CF memory management.
	CFQRelease(executableURL);
	CFQRelease(pathStringRef);
	
	assert(*pathToSelfPtr != NULL);
	if (*pathToSelfPtr == NULL)
	{
		err = -1;
	}
	return err;
}

60
static bool openfireIsRunning()
61 62 63 64
{
    FILE *ps;
    char buff[1024];
    
David Smith's avatar
David Smith committed
65
    if((ps=popen("/bin/ps auxww | fgrep -v 'fgrep' | fgrep openfire/lib/startup.jar", "r")) == NULL)
66 67 68 69 70 71 72 73 74 75 76 77 78 79
    {
        return false;
    }
    else
    {
		bool running = false;
        if(fgets(buff, 1024, ps)) {
			running = true;
		}
        pclose(ps);
        return running;
    }
}

80
static void toggleStartOpenfireAtBoot()
81 82
{
	CFURLRef propFile = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
83
													  CFSTR("/Library/LaunchDaemons/org.jivesoftware.openfire.plist"),
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
													  kCFURLPOSIXPathStyle,
													  false);
	CFDataRef xmlData;
    CFURLCreateDataAndPropertiesFromResource (kCFAllocatorDefault,
											  propFile,
											  &xmlData,
											  NULL,
											  NULL,
											  NULL);
	CFPropertyListRef props = CFPropertyListCreateFromXMLData(kCFAllocatorDefault,
															  xmlData,
															  kCFPropertyListMutableContainersAndLeaves,
															  NULL);
	if(CFGetTypeID(props) == CFDictionaryGetTypeID()) {
		CFMutableDictionaryRef propsDict = (CFMutableDictionaryRef)props;
		CFBooleanRef currentValue = CFDictionaryGetValue(propsDict,CFSTR("RunAtLoad"));
		CFDictionaryReplaceValue(propsDict, CFSTR("RunAtLoad"), ((currentValue == kCFBooleanTrue) ? kCFBooleanFalse : kCFBooleanTrue));
		
		CFQRelease(xmlData);
		xmlData = CFPropertyListCreateXMLData(kCFAllocatorDefault,(CFPropertyListRef)propsDict);
		CFURLWriteDataAndPropertiesToResource(propFile,xmlData,NULL,NULL);
	}
	CFQRelease(props);
	CFQRelease(xmlData);
	CFQRelease(propFile);
}

111
static void toggleOpenfire()
112 113 114
{
	char *args[4];
	args[0] = "launchctl";
115
	if(openfireIsRunning())
116 117 118
		args[1] = "unload";
	else
		args[1] = "load";
David Smith's avatar
David Smith committed
119
	args[2] = "/Library/LaunchDaemons/org.jivesoftware.openfire.plist";
120 121 122 123 124 125 126 127 128
	args[3] = NULL;
	
	execv("/bin/launchctl", args);
}

int main(int inArgsCount, char * const inArgs[])
{
	char* selfPath = NULL;
	int err = GetPathToSelf(&selfPath);
129
	const char* correctPath = "/Library/PreferencePanes/Openfire.prefPane/Contents/MacOS/HelperTool";
130 131 132 133
	if(err == 0 && strncmp(correctPath, selfPath, strlen(correctPath)) == 0) {
		setuid(0);

		if(inArgs[1] && strlen(inArgs[1]) == strlen("boot") && strncmp("boot", inArgs[1], strlen("boot")) == 0) {
134
			toggleStartOpenfireAtBoot();
135
		} else {
136
			toggleOpenfire();
137 138 139 140 141
		}
	}
	
	return 1;
}