]> git.saurik.com Git - apple/configd.git/blobdiff - configd.tproj/_configget.c
configd-53.1.tar.gz
[apple/configd.git] / configd.tproj / _configget.c
index 7b1e64d59c8d0ffa3ca421d6a3838a7ab70f4253..c51edd33d1b40d545477b97df72c36ef9bbe09d5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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 */
@@ -69,71 +67,187 @@ _configget(mach_port_t                     server,
           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;
 }