+#if READ_JETSAM_DEFAULTS
+
+static CFDictionaryRef
+read_jetsam_defaults_from_cache(void) {
+ CFPropertyListRef cache = GetPropertyListFromCache();
+ CFPropertyListRef defaults = NULL;
+ const void **keys = 0;
+ CFIndex count, i;
+
+ if (!cache) {
+ return NULL;
+ }
+
+ CFPropertyListRef cachefiles = CFDictionaryGetValue(cache, CFSTR(XPC_PLIST_CACHE_KEY));
+ if (!cachefiles) {
+ return NULL;
+ }
+
+ count = CFDictionaryGetCount(cachefiles);
+ keys = (const void **)malloc(sizeof(void *) * count);
+ if (!keys) {
+ return NULL;
+ }
+
+ CFDictionaryGetKeysAndValues(cachefiles, keys, NULL);
+ for (i = 0; i < count; i++) {
+ CFStringRef key = (CFStringRef)keys[i];
+ CFIndex key_length = CFStringGetLength(key);
+
+ if (key_length <= (CFIndex)(JETSAM_PROP_DIR_LENGTH + JETSAM_PROP_PREFIX_LENGTH + JETSAM_PROP_SUFFIX_LENGTH + 1)) {
+ continue;
+ }
+
+ if (CFStringCompareWithOptions(key, CFSTR(JETSAM_PROP_DIR "/" JETSAM_PROP_PREFIX),
+ CFRangeMake(0, JETSAM_PROP_DIR_LENGTH + JETSAM_PROP_PREFIX_LENGTH + 1), 0)) {
+ continue;
+ }
+
+ if (CFStringCompareWithOptions(key, CFSTR(JETSAM_PROP_SUFFIX),
+ CFRangeMake(key_length - JETSAM_PROP_SUFFIX_LENGTH, JETSAM_PROP_SUFFIX_LENGTH), 0)) {
+ continue;
+ }
+
+ defaults = CFDictionaryGetValue(cachefiles, key);
+ break;
+ }
+
+ free(keys);
+
+ return defaults;
+}
+
+static CFDictionaryRef
+read_jetsam_defaults_from_file(void) {
+ DIR *dirp;
+ struct dirent *dp;
+ CFDictionaryRef defaults = NULL;
+
+ dirp = opendir(JETSAM_PROP_DIR);
+ while ((dp = readdir(dirp)) != NULL) {
+ char *fullpath;
+
+ if (dp->d_namlen <= (JETSAM_PROP_PREFIX_LENGTH + JETSAM_PROP_SUFFIX_LENGTH)) {
+ continue;
+ }
+
+ if (strncmp(dp->d_name, JETSAM_PROP_PREFIX, JETSAM_PROP_PREFIX_LENGTH)) {
+ continue;
+ }
+
+ if (strncmp(dp->d_name + dp->d_namlen - JETSAM_PROP_SUFFIX_LENGTH, JETSAM_PROP_SUFFIX, JETSAM_PROP_SUFFIX_LENGTH)) {
+ continue;
+ }
+
+ if (-1 != asprintf(&fullpath, "%s/%s", JETSAM_PROP_DIR, dp->d_name)) {
+ defaults = (CFDictionaryRef)CreateMyPropertyListFromFile(fullpath);
+ free(fullpath);
+ }
+
+ break;
+ }
+
+ if (dirp) {
+ closedir(dirp);
+ }
+
+ return defaults;
+}
+
+static bool
+submit_cached_defaults(void) {
+ launch_data_t msg, resp;
+ const void **keys = NULL;
+ int i;
+
+ if (_launchctl_jetsam_defaults_cached == NULL) {
+ return false;
+ }
+
+ /* The dictionary to transmit */
+ CFMutableDictionaryRef payload_dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+ /* Add a key to indicate that this is a special job */
+ CFBooleanRef ID = kCFBooleanTrue;
+ CFDictionaryAddValue(payload_dict, CFSTR(LAUNCH_JOBKEY_DEFAULTS), ID);
+
+ CFMutableDictionaryRef defaults_dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+ CFDictionaryAddValue(payload_dict, CFSTR(LAUNCHD_JOB_DEFAULTS), defaults_dict);
+
+ /* Compile appropriate launchd dictionary... */
+ CFIndex count = CFDictionaryGetCount(_launchctl_jetsam_defaults_cached);
+ keys = (const void **)malloc(sizeof(void *) * count);
+ if (!keys) {
+ goto exit;
+ }
+
+ CFDictionaryGetKeysAndValues(_launchctl_jetsam_defaults_cached, keys, NULL);
+
+ for (i = 0; i < count; i++) {
+ CFStringRef label = (CFStringRef)keys[i];
+
+ /* Get the defaults for the job */
+ CFDictionaryRef job_defaults_dict = CFDictionaryGetValue(_launchctl_jetsam_defaults_cached, label);
+ if (!(job_defaults_dict && CFTypeCheck(job_defaults_dict, CFDictionary))) {
+ continue;
+ }
+
+ /* Create a new dictionary to represent the job */
+ CFMutableDictionaryRef job_dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+ /* Add the defaults */
+ CFDictionaryAddValue(job_dict, CFSTR(LAUNCH_JOBKEY_JETSAMPROPERTIES), job_defaults_dict);
+
+ /* Finally, add the result to the main dictionary */
+ CFDictionaryAddValue(defaults_dict, label, job_dict);
+
+ /* Cleanup */
+ CFRelease(job_dict);
+ }
+
+ /* Send the payload */
+ launch_data_t ldp = CF2launch_data(payload_dict);
+
+ msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
+ launch_data_dict_insert(msg, ldp, LAUNCH_KEY_SUBMITJOB);
+
+ resp = launch_msg(msg);
+ launch_data_free(msg);
+
+ launch_data_free(resp);
+
+exit:
+ CFRelease(defaults_dict);
+ CFRelease(payload_dict);
+
+ free(keys);
+
+ return true;
+}
+
+static boolean_t
+read_jetsam_defaults(void)