/*
- * 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@
*
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);
}
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);
/*
*/
CFSetAddValue(changedKeys, key);
+ done :
+
/*
* 8. Release our lock.
*/
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 */
*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;
}
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 */
}
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 *)¬ify, 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;
}
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;
}