/* * Wait until a console user logs in (or don't wait if one is already logged in). */ static bool wait_for_console_user(char *devname) { CFStringRef key; CFMutableArrayRef keys; Boolean ok; SCDynamicStoreRef store = NULL; CFRunLoopSourceRef rls; CFStringRef user; uid_t uid; gid_t gid; bool ret = false; store = SCDynamicStoreCreate(NULL, CFSTR("com.apple.nofs"), console_user_changed_cb, NULL); if (store == NULL) { return ret; } /* check if a console user is already logged in */ user = SCDynamicStoreCopyConsoleUser(store, &uid, &gid); if (user != NULL) { CFRelease(user); ret = true; goto out; } /* wait for a notification that a console user logged in */ keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); key = SCDynamicStoreKeyCreateConsoleUser(NULL); CFArrayAppendValue(keys, key); CFRelease(key); ok = SCDynamicStoreSetNotificationKeys(store, keys, NULL); CFRelease(keys); if (!ok) { syslog(LOG_ERR, "nofs: SCDynamicStoreSetNotificationKeys() failed"); goto out; } rls = SCDynamicStoreCreateRunLoopSource(NULL, store, -1); if (rls == NULL) { syslog(LOG_ERR, "nofs: SCDynamicStoreCreateRunLoopSource() failed"); goto out; } CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode); CFRunLoopRun(); CFRunLoopSourceInvalidate(rls); CFRelease(rls); ret = true; out: if (store) { CFRelease(store); } return ret; }
static Boolean RegisterConsoleUserChangeCallback() { CFStringRef consoleUserNameChangeKey = NULL; CFArrayRef notificationKeys = NULL; Boolean success = TRUE; write_log(LOG_NOTICE, "Creating ConsoleUser key."); consoleUserNameChangeKey = SCDynamicStoreKeyCreateConsoleUser(NULL); if(consoleUserNameChangeKey == NULL) { write_log(LOG_ERR, "Couldn't create ConsoleUser key!"); success = FALSE; goto EXIT; } write_log(LOG_NOTICE, "Creating notification key array."); notificationKeys = CFArrayCreate(NULL, (void*)&consoleUserNameChangeKey, (CFIndex)1, &kCFTypeArrayCallBacks); if(notificationKeys == NULL) { write_log(LOG_ERR, "Couldn't create notification key array!"); success = FALSE; goto EXIT; } write_log(LOG_NOTICE, "Setting up DynamicStore notification."); if(SCDynamicStoreSetNotificationKeys(dsSession, notificationKeys, NULL) == FALSE) { write_log(LOG_ERR, "Couldn't set up DynamicStore notification!"); success = FALSE; goto EXIT; } EXIT: if(notificationKeys != NULL) { CFRelease(notificationKeys); notificationKeys = NULL; } if(consoleUserNameChangeKey != NULL) { CFRelease(consoleUserNameChangeKey); consoleUserNameChangeKey = NULL; } return success; }
int InstallLoginLogoutNotifiers(CFRunLoopSourceRef* RunloopSourceReturned) { SCDynamicStoreContext DynamicStoreContext = { 0, NULL, NULL, NULL, NULL }; SCDynamicStoreRef DynamicStoreCommunicationMechanism = NULL; CFStringRef KeyRepresentingConsoleUserNameChange = NULL; CFMutableArrayRef ArrayOfNotificationKeys; Boolean Result; *RunloopSourceReturned = NULL; DynamicStoreCommunicationMechanism = SCDynamicStoreCreate(NULL, CFSTR("logKext"), LoginLogoutCallBackFunction, &DynamicStoreContext); if (DynamicStoreCommunicationMechanism == NULL) return(-1); //unable to create dynamic store. KeyRepresentingConsoleUserNameChange = SCDynamicStoreKeyCreateConsoleUser(NULL); if (KeyRepresentingConsoleUserNameChange == NULL) { CFRelease(DynamicStoreCommunicationMechanism); return(-2); } ArrayOfNotificationKeys = CFArrayCreateMutable(NULL, (CFIndex)1, &kCFTypeArrayCallBacks); if (ArrayOfNotificationKeys == NULL) { CFRelease(DynamicStoreCommunicationMechanism); CFRelease(KeyRepresentingConsoleUserNameChange); return(-3); } CFArrayAppendValue(ArrayOfNotificationKeys, KeyRepresentingConsoleUserNameChange); Result = SCDynamicStoreSetNotificationKeys(DynamicStoreCommunicationMechanism, ArrayOfNotificationKeys, NULL); CFRelease(ArrayOfNotificationKeys); CFRelease(KeyRepresentingConsoleUserNameChange); if (Result == FALSE) //unable to add keys to dynamic store. { CFRelease(DynamicStoreCommunicationMechanism); return(-4); } *RunloopSourceReturned = SCDynamicStoreCreateRunLoopSource(NULL, DynamicStoreCommunicationMechanism, (CFIndex) 0); return(0); }