1 #include <CoreFoundation/CoreFoundation.h>
5 #include <mach/mach_error.h>
6 #include <servers/bootstrap.h>
13 static void regServ(uid_t u
, bool on_demand
, bool is_kunc
, const char *serv_name
, const char *serv_cmd
);
14 static void handleConfigFile(const char *file
);
15 static CFPropertyListRef
CreateMyPropertyListFromFile(const char *posixfile
);
17 int main(int argc
, char *argv
[])
24 fprintf(stderr
, "usage: %s: <configdir|configfile>\n", getprogname());
30 if (S_ISREG(sb
.st_mode
)) {
31 handleConfigFile(argv
[1]);
35 if (getenv("SECURITYSESSIONID")) {
37 const char *h
= getenv("HOME");
38 struct passwd
*pwe
= getpwuid(getuid());
40 asprintf(&buf
, "%s/%s", h
? h
: pwe
->pw_dir
, "Library/LaunchAgents");
41 execlp("launchctl", "launchctl", "load", buf
, "/Library/LaunchAgents", "/System/Library/LaunchAgents", NULL
);
46 if ((d
= opendir(argv
[1])) == NULL
) {
47 fprintf(stderr
, "%s: opendir() failed to open the directory\n", getprogname());
51 while ((de
= readdir(d
)) != NULL
) {
52 if ((de
->d_name
[0] != '.')) {
54 if (asprintf(&foo
, "%s/%s", argv
[1], de
->d_name
))
55 handleConfigFile(foo
);
63 static void handleConfigFile(const char *file
)
65 bool on_demand
= true, is_kunc
= false;
71 CFPropertyListRef plist
= CreateMyPropertyListFromFile(file
);
74 if (CFDictionaryContainsKey(plist
, CFSTR("Username"))) {
75 const void *v
= CFDictionaryGetValue(plist
, CFSTR("Username"));
77 if (v
) CFStringGetCString(v
, usr
, sizeof(usr
), kCFStringEncodingUTF8
);
80 if ((pwe
= getpwnam(usr
))) {
83 fprintf(stderr
, "%s: user not found\n", getprogname());
87 if (CFDictionaryContainsKey(plist
, CFSTR("OnDemand"))) {
88 const void *v
= CFDictionaryGetValue(plist
, CFSTR("OnDemand"));
90 on_demand
= CFBooleanGetValue(v
);
93 if (CFDictionaryContainsKey(plist
, CFSTR("ServiceName"))) {
94 const void *v
= CFDictionaryGetValue(plist
, CFSTR("ServiceName"));
96 if (v
) CFStringGetCString(v
, serv_name
, sizeof(serv_name
), kCFStringEncodingUTF8
);
99 if (CFDictionaryContainsKey(plist
, CFSTR("Command"))) {
100 const void *v
= CFDictionaryGetValue(plist
, CFSTR("Command"));
102 if (v
) CFStringGetCString(v
, serv_cmd
, sizeof(serv_cmd
), kCFStringEncodingUTF8
);
105 if (CFDictionaryContainsKey(plist
, CFSTR("isKUNCServer"))) {
106 const void *v
= CFDictionaryGetValue(plist
, CFSTR("isKUNCServer"));
107 if (v
&& CFBooleanGetValue(v
)) is_kunc
= true;
110 regServ(u
, on_demand
, is_kunc
, serv_name
, serv_cmd
);
113 fprintf(stdout
, "%s: failed to register: %s\n", getprogname(), file
);
117 fprintf(stderr
, "%s: no plist was returned for: %s\n", getprogname(), file
);
121 static void regServ(uid_t u
, bool on_demand
, bool is_kunc
, const char *serv_name
, const char *serv_cmd
)
124 mach_port_t msr
, msv
, mhp
;
126 if ((kr
= bootstrap_create_server(bootstrap_port
, (char*)serv_cmd
, u
, on_demand
, &msr
)) != KERN_SUCCESS
) {
127 fprintf(stderr
, "%s: bootstrap_create_server(): %d\n", getprogname(), kr
);
130 if ((kr
= bootstrap_create_service(msr
, (char*)serv_name
, &msv
)) != KERN_SUCCESS
) {
131 fprintf(stderr
, "%s: bootstrap_register(): %d\n", getprogname(), kr
);
135 mhp
= mach_host_self();
136 if ((kr
= host_set_UNDServer(mhp
, msv
)) != KERN_SUCCESS
) {
137 fprintf(stderr
, "%s: host_set_UNDServer(): %s\n", getprogname(), mach_error_string(kr
));
140 mach_port_deallocate(mach_task_self(), mhp
);
144 static CFPropertyListRef
CreateMyPropertyListFromFile(const char *posixfile
)
146 CFPropertyListRef propertyList
;
147 CFStringRef errorString
;
148 CFDataRef resourceData
;
152 fileURL
= CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault
, posixfile
, strlen(posixfile
), false);
154 fprintf(stderr
, "%s: CFURLCreateFromFileSystemRepresentation(%s) failed\n", getprogname(), posixfile
);
155 if (!CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault
, fileURL
, &resourceData
, NULL
, NULL
, &errorCode
))
156 fprintf(stderr
, "%s: CFURLCreateDataAndPropertiesFromResource(%s) failed: %d\n", getprogname(), posixfile
, (int)errorCode
);
157 propertyList
= CFPropertyListCreateFromXMLData(kCFAllocatorDefault
, resourceData
, kCFPropertyListImmutable
, &errorString
);
159 fprintf(stderr
, "%s: propertyList is NULL\n", getprogname());
161 CFRelease(errorString
);
164 CFRelease(resourceData
);