コード例 #1
0
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();
}
コード例 #2
0
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;
}
コード例 #3
0
ファイル: INXCommon.c プロジェクト: 525828027/networkpx
static void _INXIsSpringBoardInit() {
	CFStringRef thisBundleID = CFBundleGetIdentifier(CFBundleGetMainBundle());
	_INXIsSpringBoard = CFEqual(thisBundleID, CFSTR("com.apple.springboard"));
}
コード例 #4
0
ファイル: bundle-main.c プロジェクト: L3oV1nc3/VMGL
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);
}
コード例 #5
0
ファイル: atconfig.c プロジェクト: aosm/configd_plugins
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;
}
コード例 #6
0
ファイル: CConfig.cpp プロジェクト: soundgnome/mysqlcc
/*
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;
}
コード例 #7
0
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);
    }
}
コード例 #8
0
ファイル: prelink.c プロジェクト: OpenDarwin-CVS/SEDarwin
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;
}
コード例 #9
0
ファイル: prefsmon.c プロジェクト: 010001111/darling
__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;
}
コード例 #10
0
ファイル: ArchHooks_MacOSX.cpp プロジェクト: Ancaro/stepmania
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 );
}