]> git.saurik.com Git - apple/configd.git/blobdiff - SystemConfiguration.fproj/SCDNotifierAdd.c
configd-1061.40.2.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCDNotifierAdd.c
index 392ca2748d7491e81f21bcd7d31d0752b8889085..42e5800028baefff9d546eeb10452637d7065c2c 100644 (file)
@@ -1,21 +1,22 @@
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2005, 2009-2011, 2013, 2016, 2017, 2019 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
  *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  *
  * @APPLE_LICENSE_HEADER_END@
  */
  * - initial revision
  */
 
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-
-#include <SystemConfiguration/SystemConfiguration.h>
-#include <SystemConfiguration/SCPrivate.h>
 #include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
 
+
+static void
+addKey(CFMutableArrayRef *keysP, CFStringRef key)
+{
+       if (*keysP == NULL) {
+               *keysP = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       }
+
+       CFArrayAppendValue(*keysP, key);
+       return;
+}
+
+
 Boolean
 SCDynamicStoreAddWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex)
 {
        SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
        kern_return_t                   status;
-       CFDataRef                       xmlKey;         /* serialized key */
+       CFDataRef                       utfKey;         /* serialized key */
        xmlData_t                       myKeyRef;
        CFIndex                         myKeyLen;
        int                             sc_status;
 
-       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreAddWatchedKey:"));
-       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key     = %@"), key);
-       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  isRegex = %s"), isRegex ? "TRUE" : "FALSE");
-
-       if (!store) {
+       if (store == NULL) {
                /* sorry, you must provide a session */
                _SCErrorSet(kSCStatusNoStoreSession);
                return FALSE;
@@ -64,53 +69,40 @@ SCDynamicStoreAddWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean is
                return FALSE;
        }
 
-       /*
-        * add new key after checking if key has already been defined
-        */
-       if (isRegex) {
-               if (CFSetContainsValue(storePrivate->reKeys, key)) {
-                       /* sorry, key already exists in notifier list */
-                       _SCErrorSet(kSCStatusKeyExists);
-                       return FALSE;
-               }
-               CFSetAddValue(storePrivate->reKeys, key);       /* add key to this sessions notifier list */
-       } else {
-               if (CFSetContainsValue(storePrivate->keys, key)) {
-                       /* sorry, key already exists in notifier list */
-                       _SCErrorSet(kSCStatusKeyExists);
-                       return FALSE;
-               }
-               CFSetAddValue(storePrivate->keys, key); /* add key to this sessions notifier list */
+       /* serialize the key */
+       if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) {
+               _SCErrorSet(kSCStatusFailed);
+               return FALSE;
        }
 
-       /* serialize the key */
-       xmlKey = CFPropertyListCreateXMLData(NULL, key);
-       myKeyRef = (xmlData_t)CFDataGetBytePtr(xmlKey);
-       myKeyLen = CFDataGetLength(xmlKey);
+    retry :
 
-       /* send the key & data to the server */
+       /* send the key to the server */
        status = notifyadd(storePrivate->server,
                           myKeyRef,
-                          myKeyLen,
+                          (mach_msg_type_number_t)myKeyLen,
                           isRegex,
                           (int *)&sc_status);
 
-       /* clean up */
-       CFRelease(xmlKey);
-
-       if (status != KERN_SUCCESS) {
-               if (status != MACH_SEND_INVALID_DEST)
-                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifyadd(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
-               storePrivate->server = MACH_PORT_NULL;
-               _SCErrorSet(status);
-               return FALSE;
+       if (__SCDynamicStoreCheckRetryAndHandleError(store,
+                                                    status,
+                                                    &sc_status,
+                                                    "SCDynamicStoreAddWatchedKey notifyadd()")) {
+               goto retry;
        }
 
+       /* clean up */
+       CFRelease(utfKey);
+
        if (sc_status != kSCStatusOK) {
                _SCErrorSet(sc_status);
                return FALSE;
        }
 
+       if (isRegex) {
+               addKey(&storePrivate->patterns, key);
+       } else {
+               addKey(&storePrivate->keys, key);
+       }
        return TRUE;
 }