QMacSettingsPrivate::QMacSettingsPrivate(QSettings::Scope scope, const QString &organization, const QString &application) : QSettingsPrivate(QSettings::NativeFormat, scope, organization, application) { QString javaPackageName; int curPos = 0; int nextDot; // attempt to use the organization parameter QString domainName = comify(organization); // if not found, attempt to use the bundle identifier. if (domainName.isEmpty()) { CFBundleRef main_bundle = CFBundleGetMainBundle(); if (main_bundle != NULL) { CFStringRef main_bundle_identifier = CFBundleGetIdentifier(main_bundle); if (main_bundle_identifier != NULL) { QString bundle_identifier(qtKey(main_bundle_identifier)); // CFBundleGetIdentifier returns identifier separated by slashes rather than periods. QStringList bundle_identifier_components = bundle_identifier.split(QLatin1Char('/')); // pre-reverse them so that when they get reversed again below, they are in the com.company.product format. QStringList bundle_identifier_components_reversed; for (int i=0; i<bundle_identifier_components.size(); ++i) { const QString &bundle_identifier_component = bundle_identifier_components.at(i); bundle_identifier_components_reversed.push_front(bundle_identifier_component); } domainName = bundle_identifier_components_reversed.join(QLatin1Char('.')); } } } // if no bundle identifier yet. use a hard coded string. if (domainName.isEmpty()) { domainName = QLatin1String("unknown-organization.trolltech.com"); } while ((nextDot = domainName.indexOf(QLatin1Char('.'), curPos)) != -1) { javaPackageName.prepend(domainName.midRef(curPos, nextDot - curPos)); javaPackageName.prepend(QLatin1Char('.')); curPos = nextDot + 1; } javaPackageName.prepend(domainName.midRef(curPos)); javaPackageName = javaPackageName.toLower(); if (curPos == 0) javaPackageName.prepend(QLatin1String("com.")); suiteId = javaPackageName; if (scope == QSettings::SystemScope) spec |= F_System; if (application.isEmpty()) { spec |= F_Organization; } else { javaPackageName += QLatin1Char('.'); javaPackageName += application; applicationId = javaPackageName; } numDomains = 0; for (int i = (spec & F_System) ? 1 : 0; i < 2; ++i) { for (int j = (spec & F_Organization) ? 1 : 0; j < 3; ++j) { SearchDomain &domain = domains[numDomains++]; domain.userName = (i == 0) ? kCFPreferencesCurrentUser : kCFPreferencesAnyUser; if (j == 0) domain.applicationOrSuiteId = applicationId; else if (j == 1) domain.applicationOrSuiteId = suiteId; else domain.applicationOrSuiteId = kCFPreferencesAnyApplication; } } hostName = (scope == QSettings::SystemScope) ? kCFPreferencesCurrentHost : kCFPreferencesAnyHost; sync(); }
void load(CFBundleRef bundle, Boolean bundleVerbose) { int so; int status; struct kev_request kev_req; CFSocketRef es; CFSocketContext context = { 0, NULL, NULL, NULL, NULL }; CFRunLoopSourceRef rls; if (bundleVerbose) { _verbose = TRUE; } SCLog(_verbose, LOG_DEBUG, CFSTR("load() called")); SCLog(_verbose, LOG_DEBUG, CFSTR(" bundle ID = %@"), CFBundleGetIdentifier(bundle)); /* open a "configd" session to allow cache updates */ store = SCDynamicStoreCreate(NULL, CFSTR("Kernel Event Monitor plug-in"), NULL, NULL); if (!store) { SCLog(TRUE, LOG_ERR, CFSTR("SCDnamicStoreCreate() failed: %s"), SCErrorString(SCError())); SCLog(TRUE, LOG_ERR, CFSTR("kernel event monitor disabled.")); return; } /* Open an event socket */ so = socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT); if (so != -1) { /* establish filter to return all events */ kev_req.vendor_code = 0; kev_req.kev_class = 0; /* Not used if vendor_code is 0 */ kev_req.kev_subclass = 0; /* Not used if either kev_class OR vendor_code are 0 */ status = ioctl(so, SIOCSKEVFILT, &kev_req); if (status) { SCLog(TRUE, LOG_ERR, CFSTR("could not establish event filter, ioctl() failed: %s"), strerror(errno)); (void) close(so); so = -1; } } else { SCLog(TRUE, LOG_ERR, CFSTR("could not open event socket, socket() failed: %s"), strerror(errno)); } if (so != -1) { int yes = 1; status = ioctl(so, FIONBIO, &yes); if (status) { SCLog(TRUE, LOG_ERR, CFSTR("could not set non-blocking io, ioctl() failed: %s"), strerror(errno)); (void) close(so); so = -1; } } if (so == -1) { SCLog(TRUE, LOG_ERR, CFSTR("kernel event monitor disabled.")); CFRelease(store); return; } /* Create a CFSocketRef for the PF_SYSTEM kernel event socket */ es = CFSocketCreateWithNative(NULL, so, kCFSocketReadCallBack, eventCallback, &context); /* Create and add a run loop source for the event socket */ rls = CFSocketCreateRunLoopSource(NULL, es, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); CFRelease(es); return; }
static void _INXIsSpringBoardInit() { CFStringRef thisBundleID = CFBundleGetIdentifier(CFBundleGetMainBundle()); _INXIsSpringBoard = CFEqual(thisBundleID, CFSTR("com.apple.springboard")); }
static void setup_env(void) { char *temp; const char *pds = NULL; const char *disp = getenv("DISPLAY"); size_t len; /* Pass on our prefs domain to startx and its inheritors (mainly for * quartz-wm and the Xquartz stub's MachIPC) */ CFBundleRef bundle = CFBundleGetMainBundle(); if(bundle) { CFStringRef pd = CFBundleGetIdentifier(bundle); if(pd) { pds = CFStringGetCStringPtr(pd, 0); } } /* fallback to hardcoded value if we can't discover it */ if(!pds) { pds = LAUNCHD_ID_PREFIX".X11"; } server_bootstrap_name = malloc(sizeof(char) * (strlen(pds) + 1)); if(!server_bootstrap_name) { fprintf(stderr, "X11.app: Memory allocation error.\n"); exit(1); } strcpy(server_bootstrap_name, pds); setenv("X11_PREFS_DOMAIN", server_bootstrap_name, 1); len = strlen(server_bootstrap_name); launchd_id_prefix = malloc(sizeof(char) * (len - 3)); if(!launchd_id_prefix) { fprintf(stderr, "X11.app: Memory allocation error.\n"); exit(1); } strlcpy(launchd_id_prefix, server_bootstrap_name, len - 3); /* We need to unset DISPLAY if it is not our socket */ if(disp) { /* s = basename(disp) */ const char *d, *s; for(s = NULL, d = disp; *d; d++) { if(*d == '/') s = d + 1; } if(s && *s) { if(strcmp(launchd_id_prefix, "org.x") == 0 && strcmp(s, ":0") == 0) { fprintf(stderr, "X11.app: Detected old style launchd DISPLAY, please update xinit.\n"); } else { temp = (char *)malloc(sizeof(char) * len); if(!temp) { fprintf(stderr, "X11.app: Memory allocation error creating space for socket name test.\n"); exit(1); } strlcpy(temp, launchd_id_prefix, len); strlcat(temp, ":0", len); if(strcmp(temp, s) != 0) { /* If we don't have a match, unset it. */ fprintf(stderr, "X11.app: DISPLAY (\"%s\") does not match our id (\"%s\"), unsetting.\n", disp, launchd_id_prefix); unsetenv("DISPLAY"); } free(temp); } } else { /* The DISPLAY environment variable is not formatted like a launchd socket, so reset. */ fprintf(stderr, "X11.app: DISPLAY does not look like a launchd set variable, unsetting.\n"); unsetenv("DISPLAY"); } } /* Make sure PATH is right */ ensure_path(X11BINDIR); /* cd $HOME */ temp = getenv("HOME"); if(temp != NULL && temp[0] != '\0') chdir(temp); }
void load(CFBundleRef bundle, Boolean bundleVerbose) { CFStringRef key; CFMutableArrayRef keys = NULL; CFStringRef pattern; CFMutableArrayRef patterns = NULL; CFRunLoopSourceRef rls; if (bundleVerbose) { _verbose = TRUE; } SCLog(_verbose, LOG_DEBUG, CFSTR("load() called")); SCLog(_verbose, LOG_DEBUG, CFSTR(" bundle ID = %@"), CFBundleGetIdentifier(bundle)); /* initialize a few globals */ curGlobals = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); curConfigFile = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); curDefaults = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); curStartup = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); /* open a "configd" store to allow cache updates */ store = SCDynamicStoreCreate(NULL, CFSTR("AppleTalk Configuraton plug-in"), atConfigChangedCallback, NULL); if (!store) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreCreate() failed: %s"), SCErrorString(SCError())); goto error; } /* establish notificaiton keys and patterns */ keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); /* ...watch for (global) AppleTalk configuration changes */ key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainSetup, kSCEntNetAppleTalk); CFArrayAppendValue(keys, key); CFRelease(key); /* ...watch for (per-service) AppleTalk configuration changes */ pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, kSCDynamicStoreDomainSetup, kSCCompAnyRegex, kSCEntNetAppleTalk); CFArrayAppendValue(patterns, pattern); CFRelease(pattern); /* ...watch for network interface link status changes */ pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetLink); CFArrayAppendValue(patterns, pattern); CFRelease(pattern); /* ...watch for (per-interface) AppleTalk configuration changes */ pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, kSCDynamicStoreDomainState, kSCCompAnyRegex, kSCEntNetAppleTalk); CFArrayAppendValue(patterns, pattern); CFRelease(pattern); /* ...watch for computer name changes */ key = SCDynamicStoreKeyCreateComputerName(NULL); CFArrayAppendValue(keys, key); CFRelease(key); /* register the keys/patterns */ if (!SCDynamicStoreSetNotificationKeys(store, keys, patterns)) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s"), SCErrorString(SCError())); goto error; } rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); if (!rls) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s"), SCErrorString(SCError())); goto error; } CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRelease(rls); CFRelease(keys); CFRelease(patterns); return; error : if (curGlobals) CFRelease(curGlobals); if (curConfigFile) CFRelease(curConfigFile); if (curDefaults) CFRelease(curDefaults); if (curStartup) CFRelease(curStartup); if (store) CFRelease(store); if (keys) CFRelease(keys); if (patterns) CFRelease(patterns); return; }
/* This function returns the absolute path of the user's home directory/.mysqlcc/ For example, assuming the users home directory is "/home/jorge/", this function will return: "/home/jorge/.mysqlcc/" If the directory doesn't exist, it will automatically be created. */ QString CConfig::getRootConfigPath() { #ifdef DEBUG qDebug("static CConfig::getRootConfigPath()"); #endif #ifdef QT_OSX_BUILD QString tmpstr; CFBundleRef appBundle = CFBundleGetMainBundle(); // No need to release this CFStringRef ident = CFBundleGetIdentifier(appBundle); // Do not release int strsize = 1024; char * pathstr = (char *)malloc(strsize); if (ident) { while (!CFStringGetCString(ident, pathstr, strsize, kCFStringEncodingUTF8)) { strsize += 1024; pathstr = (char *)realloc(pathstr, strsize); } } else { free(pathstr); pathstr = strdup(EXENAME); } FSRef foundref; OSStatus errCode = FSFindFolder(kUserDomain, kPreferencesFolderType, 1, &foundref); if (!errCode) { int strsize1 = 1024; char * pathstr1 = (char *)malloc(strsize); while (errFSBadBuffer == FSRefMakePath(&foundref, pathstr1, strsize1)) { strsize += 1024; pathstr1 = (char *)realloc(pathstr1, strsize); } if (pathstr1 && strlen(pathstr1)) { tmpstr = pathstr1; tmpstr += "/"; } else { tmpstr = QDir::homeDirPath(); tmpstr += "/Library/Preferences/"; } free(pathstr1); } else { tmpstr = QDir::homeDirPath(); tmpstr += "/Library/Preferences/"; } if (pathstr && strlen (pathstr)) { tmpstr += pathstr; free (pathstr); } else tmpstr += EXENAME; createDirectory(tmpstr); tmpstr += "/"; #else QString tmpstr(QDir::homeDirPath() + "/." + EXENAME); createDirectory(tmpstr); tmpstr += "/"; #endif return tmpstr; }
QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope, const QString &organization, const QString &application) { #ifndef QT_BOOTSTRAPPED static bool useAppLocalStorage = false; static bool initialized = false; if (!initialized) { bool inSandbox = false; #if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 // If we are running on at least 10.7.0 and have the com.apple.security.app-sandbox // entitlement, we are in a sandbox SInt32 version = 0; Gestalt(gestaltSystemVersion, &version); SecCodeRef secCodeSelf; if (version >= 0x1070 && SecCodeCopySelf(kSecCSDefaultFlags, &secCodeSelf) == errSecSuccess) { SecRequirementRef sandboxReq; CFStringRef entitlement = CFSTR("entitlement [\"com.apple.security.app-sandbox\"]"); if (SecRequirementCreateWithString(entitlement, kSecCSDefaultFlags, &sandboxReq) == errSecSuccess) { if (SecCodeCheckValidity(secCodeSelf, kSecCSDefaultFlags, sandboxReq) == errSecSuccess) inSandbox = true; CFRelease(sandboxReq); } CFRelease(secCodeSelf); } #endif bool forAppStore = false; if (!inSandbox) { CFTypeRef val = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("ForAppStore")); forAppStore = (val && CFGetTypeID(val) == CFStringGetTypeID() && CFStringCompare(CFStringRef(val), CFSTR("yes"), kCFCompareCaseInsensitive) == 0); } useAppLocalStorage = inSandbox || forAppStore; initialized = true; } if (useAppLocalStorage) { // Ensure that the global and app-local settings go to the same file, since that's // what we really want if (organization == QLatin1String("Trolltech") || organization.isEmpty() || (organization == qApp->organizationDomain() && application == qApp->applicationName()) || (organization == qApp->organizationName()) && application == qApp->applicationName()) { CFStringRef bundleIdentifier = CFBundleGetIdentifier(CFBundleGetMainBundle()); if (!bundleIdentifier) { qWarning("QSettingsPrivate::create: You must set the bundle identifier when using ForAppStore"); } else { QSettingsPrivate* settings = new QMacSettingsPrivate(bundleIdentifier); if (organization == QLatin1String("Trolltech")) settings->beginGroupOrArray(QSettingsGroup("QtLibrarySettings")); return settings; } } } #endif if (format == QSettings::NativeFormat) { return new QMacSettingsPrivate(scope, organization, application); } else { return new QConfFileSettingsPrivate(format, scope, organization, application); } }
KXKextManagerError PreLink(KXKextManagerRef theKextManager, CFDictionaryRef kextDict, const char * kernelCacheFilename, const char * kernel_file_name, const char * platform_name, const char * root_path, CFSetRef kernel_requests, Boolean all_plists, const NXArchInfo * arch, int verbose_level, Boolean debug_mode) { KXKextManagerError result = kKXKextManagerErrorFileAccess; CFIndex kexts_count, i; KXKextRef * kexts = NULL; // must free KXKextRef theKext = NULL; // don't release char symbol_dir[1 + strlen(TEMP_DIR)]; const char * temp_file = "cache.out"; int outfd = -1, curwd = -1; CFBundleRef kextBundle = NULL; // don't release CFMutableArrayRef moduleList; CFMutableDictionaryRef infoDict; vm_offset_t nextKernelVM; Boolean use_existing, kernel_swapped, includeInfo; vm_offset_t kernel_file, kernel_map; off_t kernel_size; vm_size_t kernel_file_size, bytes, totalBytes; vm_size_t totalModuleBytes, totalInfoBytes; vm_size_t totalSymbolBytes, totalSymbolSetBytes, totalSymbolDiscardedBytes; vm_size_t remainingModuleBytes, fileoffset, vmoffset, tailoffset; CFIndex idx, ncmds, cmd; IOReturn err; struct segment_command * seg; struct segment_command * prelinkseg; struct section * prelinksects; struct PrelinkState { kmod_info_t modules[1]; }; struct PrelinkState prelink_state_init; struct PrelinkState * prelink_state; vm_size_t prelink_size; int * prelink_dependencies; vm_size_t prelink_dependencies_size; kmod_info_t * lastInfo; struct FileInfo { vm_offset_t mapped; vm_size_t mappedSize; vm_offset_t symtaboffset; vm_offset_t symbolsetoffset; vm_size_t symtabsize; vm_size_t symtabdiscarded; CFStringRef key; KXKextRef kext; Boolean code; Boolean swapped; }; struct FileInfo * files = NULL; // -- symbol_dir[0] = 0; moduleList = CFArrayCreateMutable( kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks ); if (kKXKextManagerErrorNone != (err = readFile(kernel_file_name, &kernel_file, &kernel_file_size))) goto finish; find_arch( (u_int8_t **) &kernel_map, &kernel_size, arch->cputype, arch->cpusubtype, (u_int8_t *) kernel_file, kernel_file_size); if (!kernel_size) { fprintf(stderr, "can't find architecture %s in %s\n", arch->name, kernel_file_name); err = kKXKextManagerErrorLinkLoad; goto finish; } if (arch->cputype != CPU_TYPE_ANY) kld_set_architecture(arch); kernel_swapped = kld_macho_swap((struct mach_header *)kernel_map); ncmds = ((struct mach_header *)kernel_map)->ncmds; seg = (struct segment_command *)(((struct mach_header *)kernel_map) + 1); for (cmd = 0; cmd < ncmds; cmd++, seg = (struct segment_command *)(((vm_offset_t)seg) + seg->cmdsize)) { if (LC_SEGMENT != seg->cmd) continue; if (strcmp("__PRELINK", seg->segname)) continue; break; } if (cmd >= ncmds) { fprintf(stderr, "no __PRELINK segment in %s\n", kernel_file_name); err = kKXKextManagerErrorLinkLoad; goto finish; } prelinkseg = seg; prelinksects = (struct section *) (prelinkseg + 1); if ((prelinkseg->nsects != 3) || (strcmp("__text", prelinksects[0].sectname)) || (strcmp("__symtab", prelinksects[1].sectname)) || (strcmp("__info", prelinksects[2].sectname))) { fprintf(stderr, "unexpected __PRELINK sections in %s\n", kernel_file_name); err = kKXKextManagerErrorLinkLoad; goto finish; } if (!prelinkseg->fileoff) prelinkseg->fileoff = prelinksects[0].offset; strcpy(symbol_dir, TEMP_DIR); mktemp(symbol_dir); if (0 != mkdir(symbol_dir, 0755)) { fprintf(stderr, "mkdir(%s) failed: %s\n", symbol_dir, strerror(errno)); symbol_dir[0] = 0; err = kKXKextManagerErrorFileAccess; goto finish; } curwd = open(".", O_RDONLY, 0); if (0 != chdir(symbol_dir)) { perror("chdir"); err = kKXKextManagerErrorFileAccess; goto finish; } use_existing = false; if (!use_existing) { int fd; bzero(&prelink_state_init, sizeof(prelink_state_init)); prelink_state_init.modules[0].address = prelinkseg->vmaddr; fd = open("prelinkstate", O_WRONLY|O_CREAT|O_TRUNC, 0755); if (-1 == fd) { perror("create prelinkstate failed"); err = kKXKextManagerErrorFileAccess; goto finish; } err = writeFile(fd, &prelink_state_init, sizeof(prelink_state_init)); close(fd); if (kKXKextManagerErrorNone != err) goto finish; } /* Prepare to iterate over the kexts in the dictionary. */ kexts_count = CFDictionaryGetCount(kextDict); kexts = (KXKextRef *) calloc(kexts_count, sizeof(KXKextRef)); if (!kexts) { fprintf(stderr, "memory allocation failure\n"); err = kKXKextManagerErrorNoMemory; goto finish; } CFDictionaryGetKeysAndValues(kextDict, (const void **)NULL, (const void **)kexts); for (i = 0; i < kexts_count; i++) { Boolean linkit; theKext = (KXKextRef) kexts[i]; linkit = KXKextGetDeclaresExecutable(theKext) && (kextBundle = KXKextGetBundle(theKext)); if (linkit && kernel_requests) { CFStringRef bundleIdentifier = CFBundleGetIdentifier(kextBundle); linkit = (bundleIdentifier && CFSetContainsValue(kernel_requests, bundleIdentifier)); } if (linkit) { result = _KXKextManagerPrepareKextForLoading( theKextManager, theKext, NULL /*kext_name*/, FALSE /*check_loaded_for_dependencies*/, FALSE /*do_load*/, NULL /*inauthenticKexts*/); if (!use_existing && (result == kKXKextManagerErrorNone)) { result = _KXKextManagerLoadKextUsingOptions( theKextManager, theKext, NULL /*kext_name*/, kernel_file_name, NULL /*patch_dir*/, symbol_dir, kKXKextManagerLoadPrelink /*load_options*/, FALSE /*do_start_kmod*/, 0 /*interactive_level*/, FALSE /*ask_overwrite_symbols*/, FALSE /*overwrite_symbols*/, FALSE /*get_addrs_from_kernel*/, 0 /*num_addresses*/, NULL /*addresses*/); } if ((result != kKXKextManagerErrorNone) && (verbose_level > 0)) { const char * kext_path = NULL; // must free kext_path = _KXKextCopyCanonicalPathnameAsCString(theKext); if (kext_path) { fprintf(stderr, kext_path); free((char *)kext_path); } fprintf(stderr, " error 0x%x\n", result); } } } { struct module_header { struct mach_header h; struct segment_command seg[1]; }; struct module_header * header; int num_modules; if (kKXKextManagerErrorNone != (err = readFile("prelinkstate", (vm_offset_t *) &prelink_state, &prelink_size))) goto finish; if (kKXKextManagerErrorNone != (err = readFile("prelinkdependencies", (vm_offset_t *) &prelink_dependencies, &prelink_dependencies_size))) goto finish; num_modules = prelink_state->modules[0].id; nextKernelVM = prelink_state->modules[0].address; if (!num_modules || (prelink_size < ((num_modules + 1) * sizeof(kmod_info_t)))) { fprintf(stderr, "read prelinkstate failed\n"); err = kKXKextManagerErrorFileAccess; goto finish; } if (verbose_level > 0) { verbose_log("%d modules - code VM 0x%lx - 0x%x (0x%lx, %.2f Mb)", num_modules, prelinkseg->vmaddr, nextKernelVM, nextKernelVM - prelinkseg->vmaddr, ((float)(nextKernelVM - prelinkseg->vmaddr)) / 1024.0 / 1024.0 ); } // map files, get sizes files = (struct FileInfo *) calloc(num_modules, sizeof(struct FileInfo)); totalModuleBytes = 0; for (idx = 0; idx < num_modules; idx++) { files[idx].key = CFStringCreateWithCString(kCFAllocatorDefault, prelink_state->modules[1+idx].name, kCFStringEncodingMacRoman); files[idx].kext = KXKextManagerGetKextWithIdentifier(theKextManager, files[idx].key); if (!prelink_state->modules[1+idx].size) continue; if (kKXKextManagerErrorNone != (err = readFile(prelink_state->modules[1+idx].name, &files[idx].mapped, &files[idx].mappedSize))) goto finish; header = (struct module_header *) files[idx].mapped; files[idx].swapped = kld_macho_swap(&header->h); files[idx].code = (LC_SEGMENT == header->seg[0].cmd); if (files[idx].code) totalModuleBytes += header->seg[0].vmaddr + round_page(header->seg[0].vmsize) - prelink_state->modules[1+idx].address; } totalSymbolBytes = 0; totalSymbolDiscardedBytes = 0; totalSymbolSetBytes = 0; remainingModuleBytes = totalModuleBytes; // create prelinked kernel file outfd = open("mach_kernel.prelink", O_WRONLY|O_CREAT|O_TRUNC, 0666); if (-1 == outfd) { fprintf(stderr, "can't create %s: %s\n", "mach_kernel.prelink", strerror(errno)); err = kKXKextManagerErrorFileAccess; goto finish; } // start writing at the prelink segs file offset if (-1 == lseek(outfd, prelinkseg->fileoff, SEEK_SET)) { perror("couldn't write output"); err = kKXKextManagerErrorFileAccess; goto finish; } for (idx = 0, lastInfo = NULL; idx < num_modules; idx++) { kmod_info_t * info; unsigned long modcmd; struct symtab_command * symcmd; struct section * sect; vm_size_t headerOffset; if (!files[idx].code && prelink_state->modules[1+idx].size) { // for symbol sets the whole file ends up in the symbol sect files[idx].symtaboffset = 0; files[idx].symtabsize = prelink_state->modules[1+idx].size; files[idx].symbolsetoffset = totalSymbolBytes; totalSymbolBytes += files[idx].symtabsize; totalSymbolSetBytes += files[idx].symtabsize; continue; } header = (struct module_header *) files[idx].mapped; // patch kmod_info info = (kmod_info_t *) (prelink_state->modules[1+idx].id - header->seg[0].vmaddr + header->seg[0].fileoff + files[idx].mapped); info->next = lastInfo; lastInfo = info; bcopy(prelink_state->modules[1+idx].name, info->name, sizeof(info->name)); bcopy(prelink_state->modules[1+idx].version, info->version, sizeof(info->version)); info->address = prelink_state->modules[1+idx].address; info->size = prelink_state->modules[1+idx].size; info->id = prelink_state->modules[1+idx].id; info->hdr_size = header->seg[0].vmaddr - prelink_state->modules[1+idx].address; // patch offsets // how far back the header moves headerOffset = info->hdr_size - header->seg[0].fileoff; header->seg[0].fileoff += headerOffset; header->seg[0].filesize += headerOffset; // module code size tailoffset = round_page(header->seg[0].vmsize) + info->hdr_size - headerOffset; for (modcmd = 0, sect = (struct section *) &header->seg[1]; modcmd < header->seg[0].nsects; modcmd++, sect++) sect->offset += headerOffset; for (modcmd = 0, seg = &header->seg[0]; (modcmd < header->h.ncmds) && (LC_SYMTAB != seg->cmd); modcmd++, seg = (struct segment_command *)(((vm_offset_t)seg) + seg->cmdsize)) {} if (modcmd >= header->h.ncmds) { fprintf(stderr, "No LC_SYMTAB in %s\n", prelink_state->modules[1+idx].name); err = kKXKextManagerErrorLinkLoad; goto finish; } symcmd = (struct symtab_command *) seg; theKext = files[idx].kext; if (false && theKext && (kextBundle = KXKextGetBundle(theKext)) && CFBundleGetValueForInfoDictionaryKey(kextBundle, CFSTR("OSBundleCompatibleVersion"))) { // keeping symbols for this module struct nlist * sym; long align, lastUsedOffset = 0; const char * lastUsedString; unsigned int strIdx; files[idx].symtaboffset = symcmd->symoff; files[idx].symtabsize = symcmd->nsyms * sizeof(struct nlist); // .. but just the external strings sym = (struct nlist *) (symcmd->symoff + files[idx].mapped); for(strIdx = 0; strIdx < symcmd->nsyms; strIdx++, sym++) { if (!lastUsedOffset) lastUsedOffset = sym->n_un.n_strx; else if (!(sym->n_type & N_EXT)) sym->n_un.n_strx = 0; else if (sym->n_un.n_strx > lastUsedOffset) lastUsedOffset = sym->n_un.n_strx; } lastUsedString = (const char *) (symcmd->stroff + lastUsedOffset + files[idx].mapped); lastUsedOffset += (1 + strlen(lastUsedString)); align = lastUsedOffset % sizeof(long); if (align) { align = sizeof(long) - align; bzero((void *) (symcmd->stroff + lastUsedOffset + files[idx].mapped), align); lastUsedOffset += align; } files[idx].symtabsize += lastUsedOffset; files[idx].symtabdiscarded = symcmd->strsize - lastUsedOffset; symcmd->strsize = lastUsedOffset; // unswap symbols kld_macho_unswap(&header->h, files[idx].swapped, 1); // patch offset to symbols // how far ahead the symtab moves bytes = remainingModuleBytes + totalSymbolBytes; symcmd->symoff = bytes; symcmd->stroff += bytes - files[idx].symtaboffset; totalSymbolBytes += files[idx].symtabsize; totalSymbolDiscardedBytes += files[idx].symtabdiscarded; } else { // ditching symbols for this module files[idx].symtaboffset = 0; files[idx].symtabsize = 0; symcmd->nsyms = 0; symcmd->symoff = 0; symcmd->stroff = 0; } remainingModuleBytes -= prelink_state->modules[1+idx].size; // unswap rest of module if (files[idx].swapped) { info->next = (void *) NXSwapLong((long) info->next); info->address = NXSwapLong(info->address); info->size = NXSwapLong(info->size); info->hdr_size = NXSwapLong(info->hdr_size); info->id = NXSwapLong(info->id); } kld_macho_unswap(&header->h, files[idx].swapped, -1); files[idx].swapped = false; header = 0; info = 0; // copy header to start of VM allocation if (kKXKextManagerErrorNone != (err = writeFile(outfd, (const void *) files[idx].mapped, headerOffset))) goto finish; // write the module if (kKXKextManagerErrorNone != (err = writeFile(outfd, (const void *) files[idx].mapped, tailoffset ))) goto finish; } // write the symtabs, get info, unmap for (idx = 0; idx < num_modules; idx++) { bytes = files[idx].symtabsize; if (bytes && prelink_state->modules[1+idx].size) { if (files[idx].mappedSize < (files[idx].symtaboffset + bytes)) { fprintf(stderr, "%s is truncated\n", prelink_state->modules[1+idx].name); result = kKXKextManagerErrorFileAccess; goto finish; } else if (files[idx].mappedSize > (files[idx].symtaboffset + bytes + files[idx].symtabdiscarded)) fprintf(stderr, "%s has extra data\n", prelink_state->modules[1+idx].name); // write symtab if (kKXKextManagerErrorNone != (err = writeFile(outfd, (const void *) files[idx].mapped + files[idx].symtaboffset, bytes))) goto finish; } // unmap file if (files[idx].mappedSize) { vm_deallocate(mach_task_self(), files[idx].mapped, files[idx].mappedSize); files[idx].mapped = 0; files[idx].mappedSize = 0; } // make info dict theKext = files[idx].kext; infoDict = NULL; includeInfo = (theKext && (kextBundle = KXKextGetBundle(theKext))); if (includeInfo && !all_plists) { CFStringRef str; // check OSBundleRequired to see if safe for boot time matching str = CFBundleGetValueForInfoDictionaryKey(kextBundle, CFSTR("OSBundleRequired")); includeInfo = (str && (kCFCompareEqualTo != CFStringCompare(str, CFSTR("Safe Boot"), 0))); } if (includeInfo) infoDict = copyInfoDict(kextBundle); if (!infoDict) { if (debug_mode > 0) { verbose_log("skip info for %s", prelink_state->modules[1+idx].name); } infoDict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(infoDict, CFSTR("CFBundleIdentifier"), files[idx].key); } CFRelease(files[idx].key); files[idx].key = 0; if (prelink_state->modules[1+idx].address) { CFMutableDataRef data; enum { kPrelinkReservedCount = 4 }; UInt32 prelinkInfo[kPrelinkReservedCount]; prelinkInfo[0] = NXSwapHostIntToBig(prelink_state->modules[1+idx].id); prelinkInfo[1] = NXSwapHostIntToBig(0); prelinkInfo[2] = NXSwapHostIntToBig(sizeof(prelinkInfo)); prelinkInfo[3] = NXSwapHostIntToBig( prelink_state->modules[1+idx].reference_count * sizeof(UInt32) + sizeof(prelinkInfo)); data = CFDataCreateMutable(kCFAllocatorDefault, 0); CFDataAppendBytes( data, (const UInt8 *) prelinkInfo, sizeof(prelinkInfo) ); if (prelink_state->modules[1+idx].reference_count) { CFIndex start = (CFIndex) prelink_state->modules[1+idx].reference_list; CFDataAppendBytes( data, (const UInt8 *) &prelink_dependencies[start], prelink_state->modules[1+idx].reference_count * sizeof(CFIndex) ); } CFDictionarySetValue(infoDict, CFSTR("OSBundlePrelink"), data); CFRelease(data); } else if (files[idx].symtabsize) { CFNumberRef num; num = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, (const void *) &files[idx].symbolsetoffset); CFDictionarySetValue(infoDict, CFSTR("OSBundlePrelinkSymbols"), num); CFRelease(num); } CFArrayAppendValue(moduleList, infoDict); CFRelease(infoDict); } bytes = round_page(totalSymbolBytes) - totalSymbolBytes; totalSymbolBytes += bytes; if (-1 == lseek(outfd, bytes, SEEK_CUR)) { perror("couldn't write output"); err = kKXKextManagerErrorFileAccess; goto finish; } // deferred load __info if (!all_plists) for (i = 0; i < kexts_count; i++) { theKext = (KXKextRef) kexts[i]; for (idx = 0; (idx < num_modules) && (theKext != files[idx].kext); idx++) {} if (idx < num_modules) continue; includeInfo = (theKext && (kextBundle = KXKextGetBundle(theKext))); if (includeInfo) { CFStringRef str; // check OSBundleRequired to see if safe for boot time matching str = CFBundleGetValueForInfoDictionaryKey(kextBundle, CFSTR("OSBundleRequired")); includeInfo = (str && (kCFCompareEqualTo != CFStringCompare(str, CFSTR("Safe Boot"), 0))); if (includeInfo) { infoDict = copyInfoDict(kextBundle); if (infoDict) { CFDictionarySetValue(infoDict, CFSTR("OSBundleDefer"), kCFBooleanTrue); CFArrayAppendValue(moduleList, infoDict); CFRelease(infoDict); } } } } // write __info { CFDataRef data; data = IOCFSerialize(moduleList, kNilOptions); if (!data) { fprintf(stderr, "couldn't serialize property lists\n"); err = kKXKextManagerErrorSerialization; goto finish; } totalInfoBytes = round_page(CFDataGetLength(data)); if (kKXKextManagerErrorNone != (err = writeFile(outfd, CFDataGetBytePtr(data), CFDataGetLength(data)))) goto finish; if (-1 == lseek(outfd, totalInfoBytes - CFDataGetLength(data), SEEK_CUR)) { perror("couldn't write output"); err = kKXKextManagerErrorFileAccess; goto finish; } CFRelease(data); } totalBytes = totalModuleBytes + totalSymbolBytes + totalInfoBytes; if (verbose_level > 0) { verbose_log("added 0x%x bytes %.2f Mb (code 0x%x + symbol 0x%x + sets 0x%x - strings 0x%x + info 0x%x)", totalBytes, ((float) totalBytes) / 1024.0 / 1024.0, totalModuleBytes, totalSymbolBytes, totalSymbolSetBytes, totalSymbolDiscardedBytes, totalInfoBytes); } fileoffset = totalBytes - prelinkseg->filesize; vmoffset = totalBytes - round_page(prelinkseg->filesize); // unswap kernel symbols kld_macho_unswap((struct mach_header *)kernel_map, kernel_swapped, 1); // write tail of base kernel tailoffset = prelinkseg->fileoff + prelinkseg->filesize; if (kKXKextManagerErrorNone != (err = writeFile(outfd, (const void *) (kernel_map + tailoffset), kernel_size - tailoffset))) goto finish; // patch prelink sects sizes and offsets prelinkseg->vmsize = totalBytes; prelinkseg->filesize = totalBytes; prelinksects[0].size = totalModuleBytes; prelinksects[1].addr = prelinksects[0].addr + totalModuleBytes; prelinksects[1].size = totalSymbolBytes; prelinksects[1].offset = prelinksects[0].offset + totalModuleBytes; prelinksects[2].addr = prelinksects[1].addr + totalSymbolBytes; prelinksects[2].size = totalInfoBytes; prelinksects[2].offset = prelinksects[1].offset + totalSymbolBytes; // patch following segs address & offsets seg = prelinkseg; for (; cmd < ncmds; cmd++) { seg = (struct segment_command *)(((vm_offset_t)seg) + seg->cmdsize); if (LC_SYMTAB == seg->cmd) { ((struct symtab_command *)seg)->symoff += fileoffset; ((struct symtab_command *)seg)->stroff += fileoffset; } else if (LC_SEGMENT == seg->cmd) { seg->fileoff += fileoffset; seg->vmaddr += vmoffset; } } bytes = prelinkseg->fileoff; // unswap kernel headers kld_macho_unswap((struct mach_header *)kernel_map, kernel_swapped, -1); kernel_swapped = false; prelinkseg = 0; // write head of base kernel, & free it if (-1 == lseek(outfd, 0, SEEK_SET)) { perror("couldn't write output"); err = kKXKextManagerErrorFileAccess; goto finish; } if (kKXKextManagerErrorNone != (err = writeFile(outfd, (const void *) kernel_map, bytes))) goto finish; close(outfd); outfd = -1; vm_deallocate( mach_task_self(), kernel_file, kernel_file_size ); kernel_file = 0; kernel_map = 0; } // compresss { char * buf; char * bufend; vm_size_t bufsize; struct { uint32_t signature; uint32_t compress_type; uint32_t adler32; vm_size_t uncompressed_size; vm_size_t compressed_size; uint32_t reserved[11]; char platform_name[64]; char root_path[256]; char data[0]; } kernel_header = { 0 }; if (kKXKextManagerErrorNone != (err = readFile("mach_kernel.prelink", &kernel_file, &kernel_file_size))) goto finish; bufsize = kernel_file_size; buf = malloc(bufsize); kernel_header.signature = NXSwapHostIntToBig('comp'); kernel_header.compress_type = NXSwapHostIntToBig('lzss'); kernel_header.adler32 = NXSwapHostIntToBig(local_adler32( (u_int8_t *) kernel_file, kernel_file_size)); kernel_header.uncompressed_size = NXSwapHostIntToBig(kernel_file_size); strcpy(kernel_header.platform_name, platform_name); strcpy(kernel_header.root_path, root_path); if (verbose_level > 0) verbose_log("adler32 0x%08x, compressing...", NXSwapBigIntToHost(kernel_header.adler32)); bufend = compress_lzss(buf, bufsize, (u_int8_t *) kernel_file, kernel_file_size); totalBytes = bufend - buf; kernel_header.compressed_size = NXSwapHostIntToBig(totalBytes); if (verbose_level > 0) verbose_log("final size 0x%x bytes %.2f Mb", totalBytes, ((float) totalBytes) / 1024.0 / 1024.0); vm_deallocate( mach_task_self(), kernel_file, kernel_file_size ); outfd = open(temp_file, O_WRONLY|O_CREAT|O_TRUNC, 0666); if (-1 == outfd) { fprintf(stderr, "can't create %s - %s\n", temp_file, strerror(errno)); err = kKXKextManagerErrorFileAccess; goto finish; } // write header if (kKXKextManagerErrorNone != (err = writeFile(outfd, &kernel_header, sizeof(kernel_header)))) goto finish; // write compressed data if (kKXKextManagerErrorNone != (err = writeFile(outfd, buf, bufend - buf))) goto finish; close(outfd); outfd = -1; } // move it to the final destination if (-1 == rename(temp_file, kernelCacheFilename)) { fprintf(stderr, "can't create file %s: %s\n", kernelCacheFilename, strerror(errno)); err = kKXKextManagerErrorFileAccess; goto finish; } if (verbose_level > 0) verbose_log("created cache: %s", kernelCacheFilename); result = kKXKextManagerErrorNone; finish: if (-1 != outfd) close(outfd); if (debug_mode) symbol_dir[0] = 0; if (symbol_dir[0]) { FTS * fts; FTSENT * fts_entry; char * paths[2]; paths[0] = symbol_dir; paths[1] = 0; fts = fts_open(paths, FTS_NOCHDIR, NULL); if (fts) { while ((fts_entry = fts_read(fts))) { if (fts_entry->fts_errno) continue; if (FTS_F != fts_entry->fts_info) continue; if (-1 == unlink(fts_entry->fts_path)) fprintf(stderr, "can't remove file %s: %s\n", fts_entry->fts_path, strerror(errno)); } fts_close(fts); } } if (-1 != curwd) fchdir(curwd); if (symbol_dir[0] && (-1 == rmdir(symbol_dir))) perror("rmdir"); if (kexts) free(kexts); if (files) free(files); return result; }
__private_extern__ void load_PreferencesMonitor(CFBundleRef bundle, Boolean bundleVerbose) { Boolean initPrefs = TRUE; if (bundleVerbose) { _verbose = TRUE; } SCLog(_verbose, LOG_DEBUG, CFSTR("load() called")); SCLog(_verbose, LOG_DEBUG, CFSTR(" bundle ID = %@"), CFBundleGetIdentifier(bundle)); /* open a SCDynamicStore session to allow cache updates */ store = SCDynamicStoreCreate(NULL, CFSTR("PreferencesMonitor.bundle"), watchQuietCallback, NULL); if (store == NULL) { SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStoreCreate() failed: %s"), SCErrorString(SCError())); goto error; } /* open a SCPreferences session */ #ifndef MAIN prefs = SCPreferencesCreate(NULL, CFSTR("PreferencesMonitor.bundle"), NULL); #else // !MAIN prefs = SCPreferencesCreate(NULL, CFSTR("PreferencesMonitor.bundle"), CFSTR("/tmp/preferences.plist")); #endif // !MAIN if (prefs != NULL) { Boolean need_update = FALSE; CFStringRef new_model; new_model = _SC_hw_model(FALSE); /* Need to regenerate the new configuration for new model */ if (new_model != NULL) { CFStringRef old_model; old_model = SCPreferencesGetValue(prefs, MODEL); if (old_model != NULL && !_SC_CFEqual(old_model, new_model)) { // if new hardware need_update = TRUE; } } if (need_update == FALSE) { SCNetworkSetRef current; current = SCNetworkSetCopyCurrent(prefs); if (current != NULL) { /* network configuration available, disable template creation */ initPrefs = FALSE; CFRelease(current); } } } else { SCLog(TRUE, LOG_ERR, CFSTR("SCPreferencesCreate() failed: %s"), SCErrorString(SCError())); goto error; } /* * register for change notifications. */ if (!SCPreferencesSetCallback(prefs, updateConfiguration, NULL)) { SCLog(TRUE, LOG_ERR, CFSTR("SCPreferencesSetCallBack() failed: %s"), SCErrorString(SCError())); goto error; } if (!SCPreferencesScheduleWithRunLoop(prefs, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) { SCLog(TRUE, LOG_ERR, CFSTR("SCPreferencesScheduleWithRunLoop() failed: %s"), SCErrorString(SCError())); goto error; } /* * if no preferences, initialize with a template (now or * when IOKit has quiesced). */ if (initPrefs) { watchQuietEnable(); watchQuietCallback(store, NULL, NULL); } return; error : watchQuietDisable(); if (store != NULL) CFRelease(store); if (prefs != NULL) CFRelease(prefs); return; }
void ArchHooks_MacOSX::Init() { // First, handle non-fatal termination signals. SignalHandler::OnClose( DoCleanShutdown ); CrashHandler::CrashHandlerHandleArgs( g_argc, g_argv ); CrashHandler::InitializeCrashHandler(); SignalHandler::OnClose( DoCrashSignalHandler ); SignalHandler::OnClose( DoEmergencyShutdown ); // Now that the crash handler is set up, disable crash reporter. // Breaks gdb // task_set_exception_ports( mach_task_self(), EXC_MASK_ALL, MACH_PORT_NULL, EXCEPTION_DEFAULT, 0 ); // CF*Copy* functions' return values need to be released, CF*Get* functions' do not. CFStringRef key = CFSTR( "ApplicationBundlePath" ); CFBundleRef bundle = CFBundleGetMainBundle(); CFStringRef appID = CFBundleGetIdentifier( bundle ); if( appID == NULL ) { // We were probably launched through a symlink. Don't bother hunting down the real path. return; } CFStringRef version = CFStringRef( CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey) ); CFPropertyListRef old = CFPreferencesCopyAppValue( key, appID ); CFURLRef path = CFBundleCopyBundleURL( bundle ); CFPropertyListRef value = CFURLCopyFileSystemPath( path, kCFURLPOSIXPathStyle ); CFMutableDictionaryRef newDict = NULL; if( old && CFGetTypeID(old) != CFDictionaryGetTypeID() ) { CFRelease( old ); old = NULL; } if( !old ) { newDict = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); CFDictionaryAddValue( newDict, version, value ); } else { CFTypeRef oldValue; CFDictionaryRef dict = CFDictionaryRef( old ); if( !CFDictionaryGetValueIfPresent(dict, version, &oldValue) || !CFEqual(oldValue, value) ) { // The value is either not present or it is but it is different newDict = CFDictionaryCreateMutableCopy( kCFAllocatorDefault, 0, dict ); CFDictionarySetValue( newDict, version, value ); } CFRelease( old ); } if( newDict ) { CFPreferencesSetAppValue( key, newDict, appID ); if( !CFPreferencesAppSynchronize(appID) ) LOG->Warn( "Failed to record the run path." ); CFRelease( newDict ); } CFRelease( value ); CFRelease( path ); }