]> git.saurik.com Git - apple/configd.git/blobdiff - configd.tproj/_configset.c
configd-204.tar.gz
[apple/configd.git] / configd.tproj / _configset.c
index 08747c313418daef826671a90ad06ade3ba4ae5a..3fda0fe243d087a4af90160464a3a290ad502163 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2004, 2006 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -49,24 +49,15 @@ __SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef val
        CFStringRef                     sessionKey;
        CFStringRef                     storeSessionKey;
 
-       if (_configd_verbose) {
-               CFPropertyListRef       val;
-
-               (void) _SCUnserialize(&val, value, NULL, NULL);
-               SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreSetValue:"));
-               SCLog(TRUE, LOG_DEBUG, CFSTR("  key          = %@"), key);
-               SCLog(TRUE, LOG_DEBUG, CFSTR("  value        = %@"), val);
-               CFRelease(val);
-       }
-
-       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+       if ((store == NULL) || (storePrivate->server == MACH_PORT_NULL)) {
                return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
        if (_configd_trace) {
                SCTrace(TRUE, _configd_trace,
-                       CFSTR("%s : %5d : %@\n"),
-                       internal ? "*set   " : "set    ",
+                       CFSTR("%s%s : %5d : %@\n"),
+                       internal ? "*set " : "set  ",
+                       storePrivate->useSessionKeys ? "t " : "  ",
                        storePrivate->server,
                        key);
        }
@@ -101,24 +92,91 @@ __SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef val
        newEntry = !CFDictionaryContainsKey(newDict, kSCDData);
        CFDictionarySetValue(newDict, kSCDData, value);
 
-       /*
-        * 4. Since we are updating this key we need to check and, if
-        *    necessary, remove the indication that this key is on
-        *    another session's remove-on-close list.
-        */
        sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
-       if (CFDictionaryGetValueIfPresent(newDict, kSCDSession, (void *)&storeSessionKey) &&
-           !CFEqual(sessionKey, storeSessionKey)) {
-               CFStringRef     removedKey;
-
-               /* We are no longer a session key! */
-               CFDictionaryRemoveValue(newDict, kSCDSession);
 
-               /* add this session key to the (session) removal list */
-               removedKey = CFStringCreateWithFormat(NULL, 0, CFSTR("%@:%@"), storeSessionKey, key);
-               CFSetAddValue(removedSessionKeys, removedKey);
-               CFRelease(removedKey);
+       /*
+        * 4. Manage per-session keys.
+        */
+       if (storePrivate->useSessionKeys) {
+               if (newEntry) {
+                       CFArrayRef              keys;
+                       CFMutableDictionaryRef  newSession;
+                       CFMutableArrayRef       newKeys;
+                       CFDictionaryRef         session;
+
+                       /*
+                        * Add this key to my list of per-session keys
+                        */
+                       session = CFDictionaryGetValue(sessionData, sessionKey);
+                       keys = CFDictionaryGetValue(session, kSCDSessionKeys);
+                       if ((keys == NULL) ||
+                           (CFArrayGetFirstIndexOfValue(keys,
+                                                        CFRangeMake(0, CFArrayGetCount(keys)),
+                                                        key) == kCFNotFound)) {
+                               /*
+                                * if no session keys defined "or" keys defined but not
+                                * this one...
+                                */
+                               if (keys != NULL) {
+                                       /* this is the first session key */
+                                       newKeys = CFArrayCreateMutableCopy(NULL, 0, keys);
+                               } else {
+                                       /* this is an additional session key */
+                                       newKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                               }
+                               CFArrayAppendValue(newKeys, key);
+
+                               /* update session dictionary */
+                               newSession = CFDictionaryCreateMutableCopy(NULL, 0, session);
+                               CFDictionarySetValue(newSession, kSCDSessionKeys, newKeys);
+                               CFRelease(newKeys);
+                               CFDictionarySetValue(sessionData, sessionKey, newSession);
+                               CFRelease(newSession);
+                       }
+
+                       /*
+                        * Mark the key as a "session" key and track the creator.
+                        */
+                       CFDictionarySetValue(newDict, kSCDSession, sessionKey);
+               } else {
+                       /*
+                        * Since we are using per-session keys and this key already
+                        * exists, check if it was created by "our" session
+                        */
+                       dict = CFDictionaryGetValue(storeData, key);
+                       if (!CFDictionaryGetValueIfPresent(dict, kSCDSession, (void *)&storeSessionKey) ||
+                           !CFEqual(sessionKey, storeSessionKey)) {
+                               /*
+                                * if the key exists and is not a session key or
+                                * if the key exists it's not "our" session.
+                                */
+                               sc_status = kSCStatusKeyExists;
+                               CFRelease(sessionKey);
+                               CFRelease(newDict);
+                               goto done;
+                       }
+               }
+       } else {
+               /*
+               * Since we are updating this key we need to check and, if
+               * necessary, remove the indication that this key is on
+               * another session's remove-on-close list.
+               */
+               if (!newEntry &&
+                   CFDictionaryGetValueIfPresent(newDict, kSCDSession, (void *)&storeSessionKey) &&
+                   !CFEqual(sessionKey, storeSessionKey)) {
+                       CFStringRef     removedKey;
+
+                       /* We are no longer a session key! */
+                       CFDictionaryRemoveValue(newDict, kSCDSession);
+
+                       /* add this session key to the (session) removal list */
+                       removedKey = CFStringCreateWithFormat(NULL, 0, CFSTR("%@:%@"), storeSessionKey, key);
+                       CFSetAddValue(removedSessionKeys, removedKey);
+                       CFRelease(removedKey);
+               }
        }
+
        CFRelease(sessionKey);
 
        /*
@@ -152,6 +210,8 @@ __SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef val
         */
        CFSetAddValue(changedKeys, key);
 
+    done :
+
        /*
         * 8. Release our lock.
         */
@@ -172,22 +232,15 @@ _configset(mach_port_t                    server,
           int                          *sc_status
 )
 {
-       serverSessionRef        mySession = getSession(server);
-       CFStringRef             key;            /* key  (un-serialized) */
-       CFDataRef               data;           /* data (un-serialized) */
-
-       if (_configd_verbose) {
-               SCLog(TRUE, LOG_DEBUG, CFSTR("Set key to configuration database."));
-               SCLog(TRUE, LOG_DEBUG, CFSTR("  server = %d"), server);
-       }
+       CFDataRef               data            = NULL; /* data (un-serialized) */
+       CFStringRef             key             = NULL; /* key  (un-serialized) */
+       serverSessionRef        mySession       = getSession(server);
 
        *sc_status = kSCStatusOK;
 
        /* un-serialize the key */
        if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
                *sc_status = kSCStatusFailed;
-       } else if (!isA_CFString(key)) {
-               *sc_status = kSCStatusInvalidArgument;
        }
 
        /* un-serialize the data */
@@ -195,22 +248,27 @@ _configset(mach_port_t                    server,
                *sc_status = kSCStatusFailed;
        }
 
-       if (!mySession) {
-               *sc_status = kSCStatusNoStoreSession;   /* you must have an open session to play */
+       if (*sc_status != kSCStatusOK) {
+               goto done;
        }
 
-       if (*sc_status != kSCStatusOK) {
-               if (key)        CFRelease(key);
-               if (data)       CFRelease(data);
-               return KERN_SUCCESS;
+       if (!isA_CFString(key)) {
+               *sc_status = kSCStatusInvalidArgument;
+               goto done;
+       }
+
+       if (mySession == NULL) {
+               *sc_status = kSCStatusNoStoreSession;   /* you must have an open session to play */
+               goto done;
        }
 
        *sc_status = __SCDynamicStoreSetValue(mySession->store, key, data, FALSE);
        *newInstance = 0;
 
-       CFRelease(key);
-       CFRelease(data);
+    done :
 
+       if (key)        CFRelease(key);
+       if (data)       CFRelease(data);
        return KERN_SUCCESS;
 }
 
@@ -271,18 +329,7 @@ __SCDynamicStoreSetMultiple(SCDynamicStoreRef store, CFDictionaryRef keysToSet,
        SCDynamicStorePrivateRef        storePrivate    = (SCDynamicStorePrivateRef)store;
        int                             sc_status       = kSCStatusOK;
 
-       if (_configd_verbose) {
-               CFDictionaryRef expDict;
-
-               expDict = keysToSet ? _SCUnserializeMultiple(keysToSet) : NULL;
-               SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreSetMultiple:"));
-               SCLog(TRUE, LOG_DEBUG, CFSTR("  keysToSet    = %@"), expDict);
-               SCLog(TRUE, LOG_DEBUG, CFSTR("  keysToRemove = %@"), keysToRemove);
-               SCLog(TRUE, LOG_DEBUG, CFSTR("  keysToNotify = %@"), keysToNotify);
-               if (expDict) CFRelease(expDict);
-       }
-
-       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+       if ((store == NULL) || (storePrivate->server == MACH_PORT_NULL)) {
                return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
@@ -349,51 +396,56 @@ _configset_m(mach_port_t          server,
             mach_msg_type_number_t     notifyLen,
             int                        *sc_status)
 {
-       serverSessionRef        mySession = getSession(server);
-       CFDictionaryRef         dict    = NULL;         /* key/value dictionary (un-serialized) */
-       CFArrayRef              remove  = NULL;         /* keys to remove (un-serialized) */
-       CFArrayRef              notify  = NULL;         /* keys to notify (un-serialized) */
-
-       if (_configd_verbose) {
-               SCLog(TRUE, LOG_DEBUG, CFSTR("Set/remove/notify keys to configuration database."));
-               SCLog(TRUE, LOG_DEBUG, CFSTR("  server = %d"), server);
-       }
+       CFDictionaryRef         dict            = NULL;         /* key/value dictionary (un-serialized) */
+       serverSessionRef        mySession       = getSession(server);
+       CFArrayRef              notify          = NULL;         /* keys to notify (un-serialized) */
+       CFArrayRef              remove          = NULL;         /* keys to remove (un-serialized) */
 
        *sc_status = kSCStatusOK;
 
-       if (dictRef && (dictLen > 0)) {
+       if ((dictRef != NULL) && (dictLen > 0)) {
                /* un-serialize the key/value pairs to set */
                if (!_SCUnserialize((CFPropertyListRef *)&dict, NULL, (void *)dictRef, dictLen)) {
                        *sc_status = kSCStatusFailed;
-               } else if (!isA_CFDictionary(dict)) {
-                       *sc_status = kSCStatusInvalidArgument;
                }
        }
 
-       if (removeRef && (removeLen > 0)) {
+       if ((removeRef != NULL) && (removeLen > 0)) {
                /* un-serialize the keys to remove */
                if (!_SCUnserialize((CFPropertyListRef *)&remove, NULL, (void *)removeRef, removeLen)) {
                        *sc_status = kSCStatusFailed;
-               } else if (!isA_CFArray(remove)) {
-                       *sc_status = kSCStatusInvalidArgument;
                }
        }
 
-       if (notifyRef && (notifyLen > 0)) {
+       if ((notifyRef != NULL) && (notifyLen > 0)) {
                /* un-serialize the keys to notify */
                if (!_SCUnserialize((CFPropertyListRef *)&notify, NULL, (void *)notifyRef, notifyLen)) {
                        *sc_status = kSCStatusFailed;
-               } else if (!isA_CFArray(notify)) {
-                       *sc_status = kSCStatusInvalidArgument;
                }
        }
 
-       if (!mySession) {
-               /* you must have an open session to play */
-               *sc_status = kSCStatusNoStoreSession;
+       if (*sc_status != kSCStatusOK) {
+               goto done;
        }
 
-       if (*sc_status != kSCStatusOK) {
+       if ((dict != NULL) && !isA_CFDictionary(dict)) {
+               *sc_status = kSCStatusInvalidArgument;
+               goto done;
+       }
+
+       if ((remove != NULL) && !isA_CFArray(remove)) {
+               *sc_status = kSCStatusInvalidArgument;
+               goto done;
+       }
+
+       if ((notify != NULL) && !isA_CFArray(notify)) {
+               *sc_status = kSCStatusInvalidArgument;
+               goto done;
+       }
+
+       if (mySession == NULL) {
+               /* you must have an open session to play */
+               *sc_status = kSCStatusNoStoreSession;
                goto done;
        }
 
@@ -401,9 +453,9 @@ _configset_m(mach_port_t            server,
 
     done :
 
-       if (dict)       CFRelease(dict);
-       if (remove)     CFRelease(remove);
-       if (notify)     CFRelease(notify);
+       if (dict != NULL)       CFRelease(dict);
+       if (remove != NULL)     CFRelease(remove);
+       if (notify != NULL)     CFRelease(notify);
 
        return KERN_SUCCESS;
 }