/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* @APPLE_LICENSE_HEADER_END@
*/
+/*
+ * Modification History
+ *
+ * June 1, 2001 Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 24, 2000 Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
#include "configd.h"
#include "session.h"
-SCDStatus
-_SCDGet(SCDSessionRef session, CFStringRef key, SCDHandleRef *handle)
+int
+__SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef *value)
{
- SCDSessionPrivateRef sessionPrivate = (SCDSessionPrivateRef)session;
- CFDictionaryRef dict;
- CFNumberRef num;
- int dictInstance;
+ SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
+ CFDictionaryRef dict;
- SCDLog(LOG_DEBUG, CFSTR("_SCDGet:"));
- SCDLog(LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyValue:"));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
- if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
- return SCD_NOSESSION;
+ if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+ return kSCStatusNoStoreSession; /* you must have an open session to play */
}
- dict = CFDictionaryGetValue(cacheData, key);
+ dict = CFDictionaryGetValue(storeData, key);
if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
/* key doesn't exist (or data never defined) */
- return SCD_NOKEY;
+ return kSCStatusNoKey;
}
- /* Create a new handle associated with the cached data */
- *handle = SCDHandleInit();
-
/* Return the data associated with the key */
- SCDHandleSetData(*handle, CFDictionaryGetValue(dict, kSCDData));
-
- /* Return the instance number associated with the key */
- num = CFDictionaryGetValue(dict, kSCDInstance);
- (void) CFNumberGetValue(num, kCFNumberIntType, &dictInstance);
- _SCDHandleSetInstance(*handle, dictInstance);
+ *value = CFRetain(CFDictionaryGetValue(dict, kSCDData));
- SCDLog(LOG_DEBUG, CFSTR(" data = %@"), SCDHandleGetData(*handle));
- SCDLog(LOG_DEBUG, CFSTR(" instance = %d"), SCDHandleGetInstance(*handle));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" value = %@"), *value);
- return SCD_OK;
+ return kSCStatusOK;
}
-
kern_return_t
_configget(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
xmlDataOut_t *dataRef, /* raw XML bytes */
mach_msg_type_number_t *dataLen,
int *newInstance,
- int *scd_status
+ int *sc_status
)
{
- kern_return_t status;
- serverSessionRef mySession = getSession(server);
- CFDataRef xmlKey; /* key (XML serialized) */
CFStringRef key; /* key (un-serialized) */
- CFDataRef xmlData; /* data (XML serialized) */
- SCDHandleRef handle;
- CFStringRef xmlError;
+ serverSessionRef mySession = getSession(server);
+ Boolean ok;
+ CFPropertyListRef value;
+
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Get key from configuration database."));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
- SCDLog(LOG_DEBUG, CFSTR("Get key from configuration database."));
- SCDLog(LOG_DEBUG, CFSTR(" server = %d"), server);
+ *dataRef = NULL;
+ *dataLen = 0;
/* un-serialize the key */
- xmlKey = CFDataCreate(NULL, keyRef, keyLen);
- status = vm_deallocate(mach_task_self(), (vm_address_t)keyRef, keyLen);
- if (status != KERN_SUCCESS) {
- SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
- /* non-fatal???, proceed */
- }
- key = CFPropertyListCreateFromXMLData(NULL,
- xmlKey,
- kCFPropertyListImmutable,
- &xmlError);
- CFRelease(xmlKey);
- if (xmlError) {
- SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
- *scd_status = SCD_FAILED;
+ if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
+ *sc_status = kSCStatusFailed;
return KERN_SUCCESS;
}
- *scd_status = _SCDGet(mySession->session, key, &handle);
- CFRelease(key);
- if (*scd_status != SCD_OK) {
- *dataRef = NULL;
- *dataLen = 0;
+ if (!isA_CFString(key)) {
+ CFRelease(key);
+ *sc_status = kSCStatusInvalidArgument;
return KERN_SUCCESS;
}
- /*
- * serialize the data, copy it into an allocated buffer which will be
- * released when it is returned as part of a Mach message.
- */
- xmlData = CFPropertyListCreateXMLData(NULL, SCDHandleGetData(handle));
- *dataLen = CFDataGetLength(xmlData);
- status = vm_allocate(mach_task_self(), (void *)dataRef, *dataLen, TRUE);
- if (status != KERN_SUCCESS) {
- SCDLog(LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
- *scd_status = SCD_FAILED;
- CFRelease(xmlData);
- *dataRef = NULL;
- *dataLen = 0;
+ *sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value);
+ CFRelease(key);
+ if (*sc_status != kSCStatusOK) {
return KERN_SUCCESS;
}
- bcopy((char *)CFDataGetBytePtr(xmlData), *dataRef, *dataLen);
- CFRelease(xmlData);
+ /* serialize the data */
+ ok = _SCSerialize(value, NULL, (void **)dataRef, (CFIndex *)dataLen);
+ CFRelease(value);
+ if (!ok) {
+ *sc_status = kSCStatusFailed;
+ return KERN_SUCCESS;
+ }
/*
* return the instance number associated with the returned data.
*/
- *newInstance = SCDHandleGetInstance(handle);
+ *newInstance = 1;
+
+ return KERN_SUCCESS;
+}
+
+/*
+ * "context" argument for addSpecificKey() and addSpecificPattern()
+ */
+typedef struct {
+ SCDynamicStoreRef store;
+ CFMutableDictionaryRef dict;
+} addSpecific, *addSpecificRef;
+
+static void
+addSpecificKey(const void *value, void *context)
+{
+ CFStringRef key = (CFStringRef)value;
+ addSpecificRef myContextRef = (addSpecificRef)context;
+ int sc_status;
+ CFPropertyListRef data;
- SCDHandleRelease(handle);
+ if (!isA_CFString(key)) {
+ return;
+ }
+
+ sc_status = __SCDynamicStoreCopyValue(myContextRef->store, key, &data);
+ if (sc_status == kSCStatusOK) {
+ CFDictionaryAddValue(myContextRef->dict, key, data);
+ CFRelease(data);
+ }
+
+ return;
+}
+
+static void
+addSpecificPattern(const void *value, void *context)
+{
+ CFStringRef pattern = (CFStringRef)value;
+ addSpecificRef myContextRef = (addSpecificRef)context;
+ int sc_status;
+ CFArrayRef keys;
+
+ if (!isA_CFString(pattern)) {
+ return;
+ }
+
+ sc_status = __SCDynamicStoreCopyKeyList(myContextRef->store, pattern, TRUE, &keys);
+ if (sc_status == kSCStatusOK) {
+ CFArrayApplyFunction(keys,
+ CFRangeMake(0, CFArrayGetCount(keys)),
+ addSpecificKey,
+ context);
+ CFRelease(keys);
+ }
+
+ return;
+}
+
+kern_return_t
+_configget_m(mach_port_t server,
+ xmlData_t keysRef,
+ mach_msg_type_number_t keysLen,
+ xmlData_t patternsRef,
+ mach_msg_type_number_t patternsLen,
+ xmlDataOut_t *dataRef,
+ mach_msg_type_number_t *dataLen,
+ int *sc_status)
+{
+ CFArrayRef keys = NULL; /* keys (un-serialized) */
+ addSpecific myContext;
+ serverSessionRef mySession = getSession(server);
+ Boolean ok;
+ CFArrayRef patterns = NULL; /* patterns (un-serialized) */
+
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Get key from configuration database."));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+
+ *dataRef = NULL;
+ *dataLen = 0;
+ *sc_status = kSCStatusOK;
+
+ if (keysRef && (keysLen > 0)) {
+ /* un-serialize the keys */
+ if (!_SCUnserialize((CFPropertyListRef *)&keys, (void *)keysRef, keysLen)) {
+ *sc_status = kSCStatusFailed;
+ }
+
+ if (!isA_CFArray(keys)) {
+ *sc_status = kSCStatusInvalidArgument;
+ }
+ }
+
+ if (patternsRef && (patternsLen > 0)) {
+ /* un-serialize the patterns */
+ if (!_SCUnserialize((CFPropertyListRef *)&patterns, (void *)patternsRef, patternsLen)) {
+ *sc_status = kSCStatusFailed;
+ }
+
+ if (!isA_CFArray(patterns)) {
+ *sc_status = kSCStatusInvalidArgument;
+ }
+ }
+
+ if (*sc_status != kSCStatusOK) {
+ if (keys) CFRelease(keys);
+ if (patterns) CFRelease(patterns);
+ return KERN_SUCCESS;
+ }
+
+ myContext.store = mySession->store;
+ myContext.dict = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ if (keys) {
+ CFArrayApplyFunction(keys,
+ CFRangeMake(0, CFArrayGetCount(keys)),
+ addSpecificKey,
+ &myContext);
+ CFRelease(keys);
+ }
+
+ if (patterns) {
+ CFArrayApplyFunction(patterns,
+ CFRangeMake(0, CFArrayGetCount(patterns)),
+ addSpecificPattern,
+ &myContext);
+ CFRelease(patterns);
+ }
+
+ /* serialize the dictionary of matching keys/patterns */
+ ok = _SCSerialize(myContext.dict, NULL, (void **)dataRef, (CFIndex *)dataLen);
+ CFRelease(myContext.dict);
+ if (!ok) {
+ *sc_status = kSCStatusFailed;
+ return KERN_SUCCESS;
+ }
return KERN_SUCCESS;
}