]> git.saurik.com Git - apple/configd.git/commitdiff
configd-42.tar.gz mac-os-x-101 mac-os-x-1011 mac-os-x-1012 mac-os-x-1013 mac-os-x-1014 mac-os-x-1015 v42
authorApple <opensource@apple.com>
Sun, 26 Aug 2001 18:38:45 +0000 (18:38 +0000)
committerApple <opensource@apple.com>
Sun, 26 Aug 2001 18:38:45 +0000 (18:38 +0000)
140 files changed:
PB.project
SystemConfiguration.fproj/CustomInfo.plist
SystemConfiguration.fproj/DHCP.c [new file with mode: 0644]
SystemConfiguration.fproj/DHCPClientPreferences.h [new file with mode: 0644]
SystemConfiguration.fproj/Makefile
SystemConfiguration.fproj/Makefile.postamble
SystemConfiguration.fproj/Makefile.preamble
SystemConfiguration.fproj/PB.project
SystemConfiguration.fproj/SCD.c
SystemConfiguration.fproj/SCD.h
SystemConfiguration.fproj/SCDAdd.c
SystemConfiguration.fproj/SCDAddSession.c
SystemConfiguration.fproj/SCDClose.c [deleted file]
SystemConfiguration.fproj/SCDConsoleUser.c
SystemConfiguration.fproj/SCDConsoleUser.h
SystemConfiguration.fproj/SCDGet.c
SystemConfiguration.fproj/SCDHandle.c [deleted file]
SystemConfiguration.fproj/SCDHostName.c
SystemConfiguration.fproj/SCDHostName.h
SystemConfiguration.fproj/SCDKeys.c
SystemConfiguration.fproj/SCDKeys.h
SystemConfiguration.fproj/SCDList.c
SystemConfiguration.fproj/SCDLock.c
SystemConfiguration.fproj/SCDNotifierAdd.c
SystemConfiguration.fproj/SCDNotifierCancel.c
SystemConfiguration.fproj/SCDNotifierGetChanges.c
SystemConfiguration.fproj/SCDNotifierInformViaCallback.c
SystemConfiguration.fproj/SCDNotifierInformViaFD.c
SystemConfiguration.fproj/SCDNotifierInformViaMachPort.c
SystemConfiguration.fproj/SCDNotifierInformViaSignal.c
SystemConfiguration.fproj/SCDNotifierList.c
SystemConfiguration.fproj/SCDNotifierRemove.c
SystemConfiguration.fproj/SCDNotifierSetKeys.c [new file with mode: 0644]
SystemConfiguration.fproj/SCDNotifierWait.c
SystemConfiguration.fproj/SCDNotify.c [new file with mode: 0644]
SystemConfiguration.fproj/SCDOpen.c
SystemConfiguration.fproj/SCDPlugin.h [new file with mode: 0644]
SystemConfiguration.fproj/SCDPrivate.c
SystemConfiguration.fproj/SCDPrivate.h [deleted file]
SystemConfiguration.fproj/SCDRemove.c
SystemConfiguration.fproj/SCDSet.c
SystemConfiguration.fproj/SCDSnapshot.c
SystemConfiguration.fproj/SCDTouch.c
SystemConfiguration.fproj/SCDUnlock.c
SystemConfiguration.fproj/SCDynamicStore.h [new file with mode: 0644]
SystemConfiguration.fproj/SCDynamicStoreCopyDHCPInfo.h [new file with mode: 0644]
SystemConfiguration.fproj/SCDynamicStoreCopySpecific.h [new file with mode: 0644]
SystemConfiguration.fproj/SCDynamicStoreInternal.h [new file with mode: 0644]
SystemConfiguration.fproj/SCDynamicStoreKey.h [new file with mode: 0644]
SystemConfiguration.fproj/SCDynamicStorePrivate.h [new file with mode: 0644]
SystemConfiguration.fproj/SCDynamicStoreSetSpecificPrivate.h [new file with mode: 0644]
SystemConfiguration.fproj/SCNetwork.c
SystemConfiguration.fproj/SCNetwork.h
SystemConfiguration.fproj/SCP.c
SystemConfiguration.fproj/SCP.h
SystemConfiguration.fproj/SCPAdd.c
SystemConfiguration.fproj/SCPApply.c
SystemConfiguration.fproj/SCPClose.c [deleted file]
SystemConfiguration.fproj/SCPCommit.c
SystemConfiguration.fproj/SCPGet.c
SystemConfiguration.fproj/SCPList.c
SystemConfiguration.fproj/SCPLock.c
SystemConfiguration.fproj/SCPOpen.c
SystemConfiguration.fproj/SCPPath.c
SystemConfiguration.fproj/SCPPath.h
SystemConfiguration.fproj/SCPPrivate.h [deleted file]
SystemConfiguration.fproj/SCPRemove.c
SystemConfiguration.fproj/SCPSet.c
SystemConfiguration.fproj/SCPUnlock.c
SystemConfiguration.fproj/SCPreferences.h [new file with mode: 0644]
SystemConfiguration.fproj/SCPreferencesInternal.h [new file with mode: 0644]
SystemConfiguration.fproj/SCPreferencesPath.h [new file with mode: 0644]
SystemConfiguration.fproj/SCPreferencesPrivate.h [new file with mode: 0644]
SystemConfiguration.fproj/SCPreferencesSetSpecific.h [new file with mode: 0644]
SystemConfiguration.fproj/SCPrivate.h [new file with mode: 0644]
SystemConfiguration.fproj/SCProxies.c [new file with mode: 0644]
SystemConfiguration.fproj/SCValidation.h [new file with mode: 0644]
SystemConfiguration.fproj/SystemConfiguration.h
SystemConfiguration.fproj/config.defs
SystemConfiguration.fproj/genSCPreferences.c
SystemConfiguration.fproj/ppp.c
SystemConfiguration.fproj/ppp.h
SystemConfiguration.fproj/ppp_msg.h
SystemConfiguration.fproj/v1Compatibility.c [new file with mode: 0644]
SystemConfiguration.fproj/v1Compatibility.h [new file with mode: 0644]
configd.tproj/Makefile
configd.tproj/PB.project
configd.tproj/_SCD.c
configd.tproj/_SCD.h
configd.tproj/_configadd.c
configd.tproj/_configadd_s.c
configd.tproj/_configclose.c
configd.tproj/_configget.c
configd.tproj/_configlist.c
configd.tproj/_configlock.c
configd.tproj/_confignotify.c [new file with mode: 0644]
configd.tproj/_configopen.c
configd.tproj/_configremove.c
configd.tproj/_configset.c
configd.tproj/_configtouch.c
configd.tproj/_configunlock.c
configd.tproj/_notifyadd.c
configd.tproj/_notifycancel.c
configd.tproj/_notifychanges.c
configd.tproj/_notifyremove.c
configd.tproj/_notifyviafd.c
configd.tproj/_notifyviaport.c
configd.tproj/_notifyviasignal.c
configd.tproj/_snapshot.c
configd.tproj/configd.h
configd.tproj/configd.m
configd.tproj/configd_server.c
configd.tproj/configd_server.h
configd.tproj/notify.c
configd.tproj/notify.h
configd.tproj/notify_server.c
configd.tproj/notify_server.h
configd.tproj/plugin_support.c
configd.tproj/plugin_support.h
configd.tproj/session.c
configd.tproj/session.h
scselect.tproj/Makefile
scselect.tproj/PB.project
scselect.tproj/scselect.c
scutil.tproj/Makefile
scutil.tproj/PB.project
scutil.tproj/cache.c
scutil.tproj/cache.h
scutil.tproj/commands.c
scutil.tproj/commands.h
scutil.tproj/dictionary.c
scutil.tproj/dictionary.h
scutil.tproj/notify.c
scutil.tproj/notify.h
scutil.tproj/scutil.c
scutil.tproj/scutil.h
scutil.tproj/session.c
scutil.tproj/session.h
scutil.tproj/tests.c
scutil.tproj/tests.h

index 3af9f5553fc157e7627d6accbc1ed912dd47aacb..5726c0db98d7b874d5b167d63ce2275c7667e6cb 100644 (file)
@@ -3,11 +3,14 @@
     FILESTABLE = {
         H_FILES = (); 
         OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
         SUBPROJECTS = (SystemConfiguration.fproj, configd.tproj, scselect.tproj, scutil.tproj); 
     }; 
     LANGUAGE = English; 
     MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
-    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_BUILDTOOL = /usr/bin/gnumake; 
     NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
     NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
     PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
index 9fe5a3dc19df4a7cb0d343d6103485bc4058f32f..8be4e1f8968dd06d7c0590200abfaf3207528251 100644 (file)
@@ -1,5 +1,5 @@
 {
        CFBundleName = "SystemConfiguration";
        CFBundleIdentifier = "com.apple.SystemConfiguration";
-       CFBundleShortVersionString = "1.0.1";
+       CFBundleShortVersionString = "1.1.0";
 }
diff --git a/SystemConfiguration.fproj/DHCP.c b/SystemConfiguration.fproj/DHCP.c
new file mode 100644 (file)
index 0000000..f4b7a24
--- /dev/null
@@ -0,0 +1,628 @@
+/*
+ * Copyright (c) 2001 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+
+
+#include "SystemConfiguration.h"
+#include "SCValidation.h"
+#include "SCDynamicStoreCopyDHCPInfo.h"
+#include "DHCPClientPreferences.h"
+
+#define DHCPCLIENT_PREFERENCES_ID              "DHCPClient.xml"
+#define DHCPCLIENT_APPLICATION_PREF            "Application"
+
+#define DHCP_REQUESTED_PARAMETER_LIST          "DHCPRequestedParameterList"
+
+/**
+ ** DHCPClientPreferences{Set,Get}ApplicationOptions()
+ **/
+static UInt8 *
+S_get_char_array(CFArrayRef arr, CFIndex * len)
+{
+    UInt8 *    buf = NULL;
+    int                count = 0;
+    int        i;
+    int        real_count;
+
+    if (arr) {
+       count = CFArrayGetCount(arr);
+    }
+    if (count == 0) {
+       goto done;
+    }
+    buf = malloc(count);
+    if (buf == NULL) {
+       goto done;
+    }
+    for (i = 0, real_count = 0; i < count; i++) {
+       CFNumberRef     n = isA_CFNumber(CFArrayGetValueAtIndex(arr, i));
+       int             val;
+
+       if (n && CFNumberGetValue(n, kCFNumberIntType, &val)) {
+           buf[real_count++] = (UInt8) val;
+       }
+    }
+    count = real_count;
+ done:
+    *len = count;
+    if (count == 0 && buf) {
+       free(buf);
+       buf = NULL;
+    }
+    return (buf);
+}
+
+static void
+my_CFArrayAppendUniqueValue(CFMutableArrayRef arr, CFTypeRef new)
+{
+    int i;
+
+    for (i = 0; i < CFArrayGetCount(arr); i++) {
+       CFStringRef element = CFArrayGetValueAtIndex(arr, i);
+       if (CFEqual(element, new)) {
+           return;
+       }
+    }
+    CFArrayAppendValue(arr, new);
+    return;
+}
+
+static __inline__ CFStringRef
+S_application_path(CFStringRef applicationID)
+{
+    return (CFStringCreateWithFormat(NULL, NULL,
+                                    CFSTR("/" DHCPCLIENT_APPLICATION_PREF
+                                          "/%@"),
+                                    applicationID));
+}
+
+Boolean
+DHCPClientPreferencesSetApplicationOptions(CFStringRef applicationID,
+                                          UInt8 * options,
+                                          CFIndex count)
+{
+    CFMutableDictionaryRef     dict = NULL;
+    CFStringRef                        path = NULL;
+    SCPreferencesRef           session = NULL;
+    Boolean                    success = FALSE;
+
+    if (applicationID == NULL) {
+       goto done;
+    }
+    path = S_application_path(applicationID);
+    if (path == NULL) {
+       goto done;
+    }
+    session = SCPreferencesCreate(NULL, CFSTR("DHCPClientSetAppReqParams"),
+                                 CFSTR(DHCPCLIENT_PREFERENCES_ID));
+    if (session == NULL) {
+       goto done;
+    }
+    dict = (CFMutableDictionaryRef)SCPreferencesPathGetValue(session, path);
+    if (dict == NULL) {
+       dict = CFDictionaryCreateMutable(NULL, 0,
+                                        &kCFTypeDictionaryKeyCallBacks,
+                                        &kCFTypeDictionaryValueCallBacks);
+    }
+    else {
+       dict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
+    }
+    if (dict == NULL) {
+       goto done;
+    }
+    if (options && count > 0) {
+       int                     i;
+       CFMutableArrayRef       array;
+
+       array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       if (array == NULL) {
+           goto done;
+       }
+       for (i = 0; i < count; i++) {
+           int                 val;
+           CFNumberRef         number;
+
+           if (options[i] == 0 || options[i] == 255) {
+               /* ignore pads and end */
+               continue;
+           }
+           val = options[i];
+           number = CFNumberCreate(NULL, kCFNumberIntType, &val);
+           if (number == NULL) {
+               CFRelease(array);
+               goto done;
+           }
+           my_CFArrayAppendUniqueValue(array, number);
+           CFRelease(number);
+       }
+       CFDictionarySetValue(dict, CFSTR(DHCP_REQUESTED_PARAMETER_LIST),
+                            array);
+       CFRelease(array);
+    }
+    else {
+       CFDictionaryRemoveValue(dict, CFSTR(DHCP_REQUESTED_PARAMETER_LIST));
+    }
+    if (SCPreferencesLock(session, TRUE)) {
+       success = SCPreferencesPathSetValue(session, path, dict);
+       if (success) {
+           success = SCPreferencesCommitChanges(session);
+           if (success) {
+               (void)SCPreferencesApplyChanges(session);
+           }
+       }
+       (void)SCPreferencesUnlock(session);
+    }
+ done:
+    if (session) {
+       CFRelease(session);
+    }
+    if (path) {
+       CFRelease(path);
+    }
+    if (dict) {
+       CFRelease(dict);
+    }
+    return (success);
+}
+
+UInt8 *
+DHCPClientPreferencesCopyApplicationOptions(CFStringRef applicationID,
+                                           CFIndex * count)
+{
+    CFDictionaryRef            dict = NULL;
+    UInt8 *                    options = NULL;
+    CFArrayRef                 parms;
+    CFStringRef                        path = NULL;
+    SCPreferencesRef           session = NULL;
+
+    if (applicationID == NULL) {
+       goto done;
+    }
+    path = S_application_path(applicationID);
+    if (path == NULL) {
+       goto done;
+    }
+    session = SCPreferencesCreate(NULL, CFSTR("DHCPClientCopyAppReqParams"),
+                                 CFSTR(DHCPCLIENT_PREFERENCES_ID));
+    if (session == NULL) {
+       goto done;
+    }
+    dict = SCPreferencesPathGetValue(session, path);
+    if (dict == NULL) {
+       goto done;
+    }
+    parms = CFDictionaryGetValue(dict,
+                                CFSTR(DHCP_REQUESTED_PARAMETER_LIST));
+    if (isA_CFArray(parms) == NULL) {
+       goto done;
+    }
+    options = S_get_char_array(parms, count);
+
+ done:
+    if (session) {
+       CFRelease(session);
+    }
+    if (path) {
+       CFRelease(path);
+    }
+    return (options);
+}
+
+/**
+ ** DHCPClientInfo*()
+ **/
+
+CFDictionaryRef
+SCDynamicStoreCopyDHCPInfo(SCDynamicStoreRef store, CFStringRef serviceID)
+{
+    CFDictionaryRef    dhcp_dict = NULL;
+    CFStringRef                key = NULL;
+    boolean_t          needs_close = FALSE;
+    CFDictionaryRef    primary_dict = NULL;
+
+    if (store == NULL) {
+       needs_close = TRUE;
+       store = SCDynamicStoreCreate(NULL,
+                                    CFSTR("SCDynamicStoreCopyDHCPInfo"),
+                                    NULL, NULL);
+       if (store == NULL) {
+           goto done;
+       }
+    }
+
+    if (serviceID == NULL) {
+       /* get the primary service name */
+       key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                        kSCDynamicStoreDomainState,
+                                                        kSCEntNetIPv4);
+       if (key) {
+           primary_dict = SCDynamicStoreCopyValue(store, key);
+           if (primary_dict) {
+               serviceID = CFDictionaryGetValue(primary_dict,
+                                                kSCDynamicStorePropNetPrimaryService);
+           }
+           CFRelease(key);
+       }
+    }
+    if (serviceID == NULL) {
+       goto done;
+    }
+    key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                     kSCDynamicStoreDomainState,
+                                                     serviceID,
+                                                     kSCEntNetDHCP);
+    if (key) {
+       dhcp_dict = SCDynamicStoreCopyValue(store, key);
+       if (dhcp_dict != NULL
+           && isA_CFDictionary(dhcp_dict) == NULL) {
+           CFRelease(dhcp_dict);
+           dhcp_dict = NULL;
+       }
+       CFRelease(key);
+    }
+ done:
+    if (primary_dict) {
+       CFRelease(primary_dict);
+    }
+    if (needs_close == TRUE && store != NULL) {
+       CFRelease(store);
+    }
+    return (dhcp_dict);
+}
+
+CFDataRef
+DHCPInfoGetOptionData(CFDictionaryRef dhcp_dict, UInt8 code)
+{
+    CFDataRef          data = NULL;
+    CFStringRef                option_code_str = NULL;
+
+    option_code_str = CFStringCreateWithFormat(NULL, NULL,
+                                              CFSTR("Option_%d"), code);
+    if (option_code_str == NULL) {
+       goto done;
+    }
+
+    data = CFDictionaryGetValue(dhcp_dict, option_code_str);
+    data = isA_CFData(data);
+ done:
+    if (option_code_str)
+       CFRelease(option_code_str);
+    return (data);
+}
+
+CFDateRef
+DHCPInfoGetLeaseStartTime(CFDictionaryRef dhcp_dict)
+{
+    return (CFDictionaryGetValue(dhcp_dict, CFSTR("LeaseStartTime")));
+}
+
+#ifdef TEST_DHCPCLIENT_PREFERENCES
+void
+print_data(u_char * data_p, int n_bytes)
+{
+#define CHARS_PER_LINE         16
+    char               line_buf[CHARS_PER_LINE + 1];
+    int                        line_pos;
+    int                        offset;
+
+    for (line_pos = 0, offset = 0; offset < n_bytes; offset++, data_p++) {
+       if (line_pos == 0)
+           printf("%04x ", offset);
+
+       line_buf[line_pos] = isprint(*data_p) ? *data_p : '.';
+       printf(" %02x", *data_p);
+       line_pos++;
+       if (line_pos == CHARS_PER_LINE) {
+           line_buf[CHARS_PER_LINE] = '\0';
+           printf("  %s\n", line_buf);
+           line_pos = 0;
+       }
+       else if (line_pos == (CHARS_PER_LINE / 2))
+           printf(" ");
+    }
+    if (line_pos) { /* need to finish up the line */
+       for (; line_pos < CHARS_PER_LINE; line_pos++) {
+           printf("   ");
+           line_buf[line_pos] = ' ';
+       }
+       line_buf[CHARS_PER_LINE] = '\0';
+       printf("  %s\n", line_buf);
+    }
+}
+
+#define CMDSTR_GETOPTION       "getoption"
+#define CMDSTR_LEASE           "leaseinfo"
+#define CMDSTR_GETPARAMS       "getparams"
+#define CMDSTR_SETPARAMS       "setparams"
+
+static __inline__ void
+S_print_char_array(UInt8 * params, int n_params)
+{
+    int i;
+
+    for (i = 0; i < n_params; i++) {
+       if (i == 0)
+           printf("%d", params[i]);
+       else
+           printf(", %d", params[i]);
+    }
+    return;
+}
+
+void
+usage(char * prog)
+{
+    printf("%s " CMDSTR_GETOPTION " <serviceID> <opt> [ <type> ]\n"
+          "%s " CMDSTR_LEASE " <serviceID>\n"
+          "%s " CMDSTR_GETPARAMS " <app_id>\n"
+          "%s " CMDSTR_SETPARAMS " <app_id> [ <opt> [ <opt> ] ... [ <opt> ] ] ]\n"
+          "where:\n"
+          "  <serviceID>     : service ID string | \"\"\n"
+          "  <opt>           : DHCP/BOOTP option code\n"
+          "                    (e.g. 1 == subnet mask, 3 == router, 6 = dns, 15 = domain)\n"
+          "  <type>          : type of option: string, ip\n"
+          "  <app_id>        : application id (e.g. com.apple.ntpd, com.thursby.Dave)\n",
+          prog, prog, prog, prog);
+    exit(0);
+}
+
+static void
+dump_gregorian_date(CFGregorianDate d)
+{
+    printf("%d/%d/%d %02d:%02d:%02d\n",
+          (int)d.year, d.month, d.day, d.hour, d.minute, (int)d.second);
+    return;
+}
+
+static void
+show_date(CFAbsoluteTime t)
+{
+    CFGregorianDate d;
+    static CFTimeZoneRef tz = NULL;
+
+    if (tz == NULL) {
+       tz = CFTimeZoneCopySystem();
+    }
+
+    d = CFAbsoluteTimeGetGregorianDate(t, tz);
+    dump_gregorian_date(d);
+    return;
+}
+
+#define IP_FORMAT      "%d.%d.%d.%d"
+#define IP_CH(ip, i)   (((u_char *)(ip))[i])
+#define IP_LIST(ip)    IP_CH(ip,0),IP_CH(ip,1),IP_CH(ip,2),IP_CH(ip,3)
+
+typedef enum {
+    command_none_e,
+    command_getoption_e,
+    command_lease_e,
+    command_setparams_e,
+    command_getparams_e,
+} command_t;
+
+int
+main(int argc, char * argv[])
+{
+    CFStringRef                app_id;
+    command_t          command = command_none_e;
+    char *             command_str;
+    CFIndex            count;
+    CFDictionaryRef    info;
+    UInt8 *            params;
+    CFStringRef                serviceID = NULL;
+
+    command_str = argv[1];
+    if (argc < 2)
+       usage(argv[0]);
+    if (strcmp(command_str, CMDSTR_GETOPTION) == 0) {
+       if (argc < 4 || argc > 5) {
+           usage(argv[0]);
+       }
+       command = command_getoption_e;
+    }
+    else if (strcmp(command_str, CMDSTR_LEASE) == 0) {
+       if (argc != 3) {
+           usage(argv[0]);
+       }
+       command = command_lease_e;
+    }
+    else if (strcmp(command_str, CMDSTR_SETPARAMS) == 0) {
+       command = command_setparams_e;
+       if (argc < 3) {
+           usage(argv[0]);
+       }
+    }
+    else if (strcmp(command_str, CMDSTR_GETPARAMS) == 0) {
+       command = command_getparams_e;
+       if (argc != 3) {
+           usage(argv[0]);
+       }
+    }
+    else {
+       usage(argv[0]);
+    }
+
+    switch (command) {
+      case command_getoption_e: {
+         UInt8         code;
+         char *        code_str;
+         CFDataRef     option;
+         boolean_t     printed = FALSE;
+         CFIndex       len;
+         char *        type = NULL;
+
+         if (argv[2][0]) {
+             serviceID = CFStringCreateWithFormat(NULL, NULL,
+                                                  CFSTR("%s"), argv[2]);
+         }
+
+         info = SCDynamicStoreCopyDHCPInfo(NULL, serviceID);
+         if (info == NULL) {
+             exit(1);
+         }
+
+         code_str = argv[3];
+         if (argc > 4) {
+             type = argv[4];
+         }
+         code = atoi(code_str);
+
+         option = DHCPInfoGetOptionData(info, code);
+         if (option == NULL) {
+             exit(1);
+         }
+         len = CFDataGetLength(option);
+         if (type) {
+             printed = TRUE;
+             if (strcmp(type, "ip") == 0) {
+                 int i = 0;
+                 const void * ptr = CFDataGetBytePtr(option);
+
+                 while (len >= 4) {
+                     if (i == 0) {
+                         printf(IP_FORMAT, IP_LIST(ptr));
+                     }
+                     else {
+                         printf(" " IP_FORMAT, IP_LIST(ptr));
+                     }
+                     i++;
+                     len -= 4;
+                     ptr += 4;
+                 }
+                 printf("\n");
+             }
+             else if (strcmp(type, "string") == 0) {
+                 printf("%.*s\n", (int)len, (char *)CFDataGetBytePtr(option));
+             }
+             else {
+                 printed = FALSE;
+             }
+         }
+         if (printed == FALSE) {
+             print_data((void *)CFDataGetBytePtr(option), len);
+         }
+         if (serviceID)
+             CFRelease(serviceID);
+         CFRelease(info);
+         break;
+      }
+      case command_lease_e: {
+         CFDateRef     start;
+
+         if (argv[2][0]) {
+             serviceID = CFStringCreateWithFormat(NULL, NULL,
+                                                  CFSTR("%s"), argv[2]);
+         }
+
+         info = SCDynamicStoreCopyDHCPInfo(NULL, serviceID);
+         if (info == NULL) {
+             exit(1);
+         }
+         start = DHCPInfoGetLeaseStartTime(info);
+
+         if (start) {
+             CFDataRef         option;
+             int32_t           lease;
+
+#define OPTION_LEASE_TIME      51
+#define SERVER_ID              54
+             option = DHCPInfoGetOptionData(info, OPTION_LEASE_TIME);
+             if (option == NULL) {
+                 fprintf(stderr, "what, no lease time?\n");
+                 exit(1);
+             }
+             printf("Lease start: ");
+             show_date(CFDateGetAbsoluteTime(start));
+             lease = ntohl(*((int32_t *)CFDataGetBytePtr(option)));
+             if (lease == 0xffffffff) {
+                 printf("Lease is infinite\n");
+             }
+             else {
+                 printf("Lease expires: ");
+                 show_date(lease + CFDateGetAbsoluteTime(start));
+             }
+             option = DHCPInfoGetOptionData(info, SERVER_ID);
+             if (option) {
+                 printf("Server IP: " IP_FORMAT "\n",
+                        IP_LIST(CFDataGetBytePtr(option)));
+             }
+         }
+         else {
+             printf("no lease\n");
+         }
+         if (serviceID)
+             CFRelease(serviceID);
+         CFRelease(info);
+         break;
+      }
+      case command_getparams_e: {
+         app_id = CFStringCreateWithFormat(NULL, NULL,
+                                           CFSTR("%s"), argv[2]);
+         params = DHCPClientPreferencesCopyApplicationOptions(app_id, &count);
+         if (params) {
+             printf("%s params = {", argv[2]);
+             S_print_char_array(params, count);
+             printf("}\n");
+             free(params);
+         }
+         break;
+      }
+      case command_setparams_e: {
+         int           count = 0;
+         UInt8 *       options = NULL;
+
+         if (argc > 3) {
+             int i;
+
+             count = argc - 3;
+             options = malloc(count);
+             if (options == NULL) {
+                 fprintf(stderr, "malloc failed %s\n",
+                         strerror(errno));
+                 exit(1);
+             }
+             for (i = 0; i < count; i++) {
+                 options[i] = atoi(argv[3 + i]);
+             }
+         }
+         app_id = CFStringCreateWithFormat(NULL, NULL,
+                                           CFSTR("%s"), argv[2]);
+         if (DHCPClientPreferencesSetApplicationOptions(app_id, options,
+                                                        count) == FALSE) {
+             printf("operation failed\n");
+         }
+         if (options) {
+             free(options);
+         }
+         break;
+      }
+      default:
+         break;
+    }
+    exit(0);
+    return(0);
+}
+#endif TEST_DHCPCLIENT_PREFERENCES
+
diff --git a/SystemConfiguration.fproj/DHCPClientPreferences.h b/SystemConfiguration.fproj/DHCPClientPreferences.h
new file mode 100644 (file)
index 0000000..725f4d3
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2001 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _DHCPCLIENTPREFERENCES_H
+#define _DHCPCLIENTPREFERENCES_H
+
+#include <sys/cdefs.h>
+#include <CoreFoundation/CFString.h>
+
+/*!
+       @header DHCPClientPreferences.h
+ */
+
+__BEGIN_DECLS
+
+/*!
+       @function DHCPClientPreferencesSetApplicationOptions
+       @discussion Updates the DHCP client preferences to include the
+               given list of options for the given "applicationID".
+       @param applicationID The application's preference ID, for example:
+               "com.apple.SystemPreferences".
+       @param options An array of 8-bit values containing the
+               DHCP option codes (see RFC 2132) for this applicationID.
+               A NULL value will clear the list of options for this
+               application ID.
+       @param count The number of elements in "options".
+       @result TRUE if the operation succeeded, FALSE otherwise.
+ */
+
+Boolean
+DHCPClientPreferencesSetApplicationOptions(CFStringRef applicationID,
+                                          UInt8 * options,
+                                          CFIndex count);
+
+/*!
+       @function DHCPClientPreferencesCopyApplicationOptions
+       @discussion Copies the requested DHCP options for the
+               given "applicationID".
+       @param applicationID The application's preference ID, for example
+               "com.apple.SystemPreferences".
+       @param count The number of elements in the returned array.
+       @result The list of options for the given "applicationID", or
+               NULL if no options are defined or an error occurred.
+
+               When done, use free() to release a non-NULL return value.
+ */
+
+UInt8 *
+DHCPClientPreferencesCopyApplicationOptions(CFStringRef applicationID,
+                                           CFIndex * count);
+
+__END_DECLS
+
+#endif /* _DHCPCLIENTPREFERENCES_H */
index 20f1e2cc560ea606e74384a9ae6940614028b7ca..7235655b1fa92d4e07f3c04a7f0e1962c8f3fc12 100644 (file)
@@ -12,21 +12,28 @@ NAME = SystemConfiguration
 PROJECTVERSION = 2.8
 PROJECT_TYPE = Framework
 
-HFILES = SystemConfiguration.h config_types.h SCD.h SCDKeys.h\
-         SCDPrivate.h SCP.h SCPPrivate.h SCPPath.h SCDConsoleUser.h\
-         SCDHostName.h SCNetwork.h ppp_msg.h ppp.h
-
-CFILES = SCD.c SCDKeys.c SCDPrivate.c SCDHandle.c SCDOpen.c\
-         SCDClose.c SCDLock.c SCDUnlock.c SCDList.c SCDAdd.c\
-         SCDAddSession.c SCDGet.c SCDSet.c SCDRemove.c SCDTouch.c\
+HFILES = SystemConfiguration.h SCPrivate.h SCDPlugin.h config_types.h\
+         SCDynamicStoreInternal.h SCDynamicStore.h\
+         SCDynamicStorePrivate.h SCDynamicStoreKey.h\
+         SCDynamicStoreCopySpecific.h SCDynamicStoreSetSpecificPrivate.h\
+         SCPreferencesInternal.h SCPreferences.h SCPreferencesPrivate.h\
+         SCPreferencesPath.h SCPreferencesSetSpecific.h SCNetwork.h\
+         SCValidation.h ppp_msg.h ppp.h v1Compatibility.h SCD.h\
+         SCDKeys.h SCP.h SCPPath.h SCDConsoleUser.h SCDHostName.h\
+         DHCPClientPreferences.h SCDynamicStoreCopyDHCPInfo.h
+
+CFILES = SCD.c SCDKeys.c SCDPrivate.c SCDOpen.c SCDLock.c SCDUnlock.c\
+         SCDList.c SCDAdd.c SCDAddSession.c SCDGet.c SCDSet.c\
+         SCDRemove.c SCDTouch.c SCDNotify.c SCDNotifierSetKeys.c\
          SCDNotifierList.c SCDNotifierAdd.c SCDNotifierRemove.c\
          SCDNotifierGetChanges.c SCDNotifierWait.c\
          SCDNotifierInformViaCallback.c SCDNotifierInformViaMachPort.c\
          SCDNotifierInformViaFD.c SCDNotifierInformViaSignal.c\
-         SCDNotifierCancel.c SCDSnapshot.c SCP.c SCPOpen.c SCPClose.c\
-         SCPLock.c SCPUnlock.c SCPList.c SCPGet.c SCPAdd.c SCPSet.c\
-         SCPRemove.c SCPCommit.c SCPApply.c SCPPath.c SCDConsoleUser.c\
-         SCDHostName.c SCNetwork.c ppp.c
+         SCDNotifierCancel.c SCDSnapshot.c SCP.c SCPOpen.c SCPLock.c\
+         SCPUnlock.c SCPList.c SCPGet.c SCPAdd.c SCPSet.c SCPRemove.c\
+         SCPCommit.c SCPApply.c SCPPath.c SCDConsoleUser.c\
+         SCDHostName.c SCNetwork.c SCProxies.c ppp.c v1Compatibility.c\
+         DHCP.c
 
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\
             h.template config.defs genSCPreferences.c CustomInfo.plist
@@ -37,7 +44,7 @@ CURRENTLY_ACTIVE_VERSION = YES
 DEPLOY_WITH_VERSION_NAME = A
 CODE_GEN_STYLE = DYNAMIC
 MAKEFILE = framework.make
-NEXTSTEP_INSTALLDIR = $(SYSTEM_LIBRARY_DIR)/PrivateFrameworks
+NEXTSTEP_INSTALLDIR = $(SYSTEM_LIBRARY_DIR)/Frameworks
 WINDOWS_INSTALLDIR = /Library/Frameworks
 PDO_UNIX_INSTALLDIR = /Library/Frameworks
 LIBS = 
@@ -45,13 +52,22 @@ DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
 
+NEXTSTEP_PB_CFLAGS = -DUSE_SYSTEMCONFIGURATION_PUBLIC_APIS
 FRAMEWORKS = -framework CoreFoundation
-PUBLIC_HEADERS = SystemConfiguration.h SCD.h SCDKeys.h SCP.h SCPPath.h\
-                 SCDConsoleUser.h SCDHostName.h SCNetwork.h
-
-PROJECT_HEADERS = SystemConfiguration.h config_types.h SCD.h\
-                  SCDPrivate.h SCP.h SCPPrivate.h SCPPath.h\
-                  SCDConsoleUser.h SCDHostName.h SCNetwork.h
+PUBLIC_HEADERS = SystemConfiguration.h SCDynamicStore.h\
+                 SCDynamicStoreKey.h SCDynamicStoreCopySpecific.h\
+                 SCPreferences.h SCPreferencesPath.h\
+                 SCPreferencesSetSpecific.h SCNetwork.h
+
+PROJECT_HEADERS = SystemConfiguration.h SCPrivate.h config_types.h\
+                  SCDynamicStoreInternal.h SCDynamicStore.h\
+                  SCDynamicStorePrivate.h SCDynamicStoreKey.h\
+                  SCDynamicStoreCopySpecific.h\
+                  SCDynamicStoreSetSpecificPrivate.h\
+                  SCPreferencesInternal.h SCPreferences.h\
+                  SCPreferencesPrivate.h SCPreferencesPath.h\
+                  SCPreferencesSetSpecific.h SCNetwork.h SCValidation.h\
+                  v1Compatibility.h
 
 
 
index 888849f926c216b7a1dd2cca35a46f9931f0196e..575e099f4d65a5259404f14781baef2ef6fafde3 100644 (file)
@@ -107,13 +107,16 @@ before_installhdrs: $(OFILE_DIR)
 $(OFILE_DIR)/genSCPreferences: genSCPreferences.o
        $(CC) -o $@ $(ARCHITECTURE_FLAGS) $<
 
-SCPreferences.h: $(OFILE_DIR)/genSCPreferences
+SCSchemaDefinitions.h: $(OFILE_DIR)/genSCPreferences
        $(CD) $(SFILE_DIR) && $(OFILE_DIR)/genSCPreferences header > $@
 
-SCPreferences.c: $(OFILE_DIR)/genSCPreferences
+SCSchemaDefinitions.c: $(OFILE_DIR)/genSCPreferences
        $(CD) $(SFILE_DIR) && $(OFILE_DIR)/genSCPreferences cfile  > $@
 
 genSCFiles:
        cc -o /tmp/genSCFiles genSCPreferences.c -framework CoreFoundation
-       /tmp/genSCFiles header > /tmp/SCPreferences.h
-       /tmp/genSCFiles cfile  > /tmp/SCPreferences.c
+       /tmp/genSCFiles header > /tmp/SCSchemaDefinitions.h
+       /tmp/genSCFiles cfile  > /tmp/SCSchemaDefinitions.c
+
+dhcp: DHCP.c
+       cc -Wall -DUSE_SYSTEMCONFIGURATION_PUBLIC_APIS -DTEST_DHCPCLIENT_PREFERENCES -g -o dhcp DHCP.c -framework CoreFoundation -framework SystemConfiguration
index cb948337dfa3a2fc58494082a83309a2e4615a84..ac3fc04331e5ecf30e568bd1c7e254eb1452b643 100644 (file)
@@ -138,22 +138,45 @@ OTHER_GENERATED_OFILES = $(VERS_OFILE)
 
 # Additional flags for MiG generated files
 OTHER_PROJECT_HEADERS += config.defs config.h
+
+OTHER_PRIVATE_HEADERS += SCPrivate.h
+OTHER_PRIVATE_HEADERS += SCDynamicStorePrivate.h
+OTHER_PRIVATE_HEADERS += SCDynamicStoreSetSpecificPrivate.h
+OTHER_PRIVATE_HEADERS += SCPreferencesPrivate.h
+OTHER_PRIVATE_HEADERS += SCValidation.h
+OTHER_PRIVATE_HEADERS += SCDPlugin.h
+OTHER_PRIVATE_HEADERS += SCDynamicStoreCopyDHCPInfo.h
+OTHER_PRIVATE_HEADERS += DHCPClientPreferences.h
+
+#  
+# XXX INSTALL V1 COMPATIBILITY HEADERS XXX
+#
+OTHER_PRIVATE_HEADERS += v1Compatibility.h
+OTHER_PRIVATE_HEADERS += SCD.h
+OTHER_PRIVATE_HEADERS += SCDKeys.h
+OTHER_PRIVATE_HEADERS += SCP.h
+OTHER_PRIVATE_HEADERS += SCPPath.h
+OTHER_PRIVATE_HEADERS += SCDConsoleUser.h
+OTHER_PRIVATE_HEADERS += SCDHostName.h
+
+#
+# MiG generated files
+#
 OTHER_OFILES          += configUser.o
 
 # Additional options to create generated headers, source
 BEFORE_INSTALLHDRS       =  before_installhdrs
 OTHER_SOURCEFILES        += genSCPreferences.c
-OTHER_GENERATED_SRCFILES += SCPreferences.h SCPreferences.c
-OTHER_PUBLIC_HEADERS     += SCPreferences.h
-OTHER_OFILES             += SCPreferences.o
-
-# Specify framework initialization code
-OTHER_LDFLAGS += -Wl,-init,___Initialize
+OTHER_GENERATED_SRCFILES += SCSchemaDefinitions.h SCSchemaDefinitions.c
+OTHER_PUBLIC_HEADERS     += SCSchemaDefinitions.h
+OTHER_OFILES             += SCSchemaDefinitions.o
 
 # Additional build flags
 ifeq "$(PLATFORM_OS)" "macos"
+ifneq "$(RC_RELEASE)" "Darwin"
        APPLE_INTERNAL_DIR ?= /AppleInternal
        APPLE_INTERNAL_DEVELOPER_DIR ?= /AppleInternal/Developer
        OTHER_LDFLAGS += -seg_addr_table $(APPLE_INTERNAL_DEVELOPER_DIR)/seg_addr_table
        SECTORDER_FLAGS = -sectorder __TEXT __text $(APPLE_INTERNAL_DIR)/OrderFiles/SystemConfiguration.order
 endif
+endif
index f132d48aadb6305ecb2e719858bfd1f24f961a17..8c1c394946c8d1221f8c4b54bdf5618400461c30 100644 (file)
@@ -7,26 +7,39 @@
         FRAMEWORKSEARCH = (); 
         H_FILES = (
             SystemConfiguration.h, 
+            SCPrivate.h, 
+            SCDPlugin.h, 
             config_types.h, 
+            SCDynamicStoreInternal.h, 
+            SCDynamicStore.h, 
+            SCDynamicStorePrivate.h, 
+            SCDynamicStoreKey.h, 
+            SCDynamicStoreCopySpecific.h, 
+            SCDynamicStoreSetSpecificPrivate.h, 
+            SCPreferencesInternal.h, 
+            SCPreferences.h, 
+            SCPreferencesPrivate.h, 
+            SCPreferencesPath.h, 
+            SCPreferencesSetSpecific.h, 
+            SCNetwork.h, 
+            SCValidation.h, 
+            ppp_msg.h, 
+            ppp.h, 
+            v1Compatibility.h, 
             SCD.h, 
             SCDKeys.h, 
-            SCDPrivate.h, 
             SCP.h, 
-            SCPPrivate.h, 
             SCPPath.h, 
             SCDConsoleUser.h, 
             SCDHostName.h, 
-            SCNetwork.h, 
-            ppp_msg.h, 
-            ppp.h
+            DHCPClientPreferences.h, 
+            SCDynamicStoreCopyDHCPInfo.h
         ); 
         OTHER_LINKED = (
             SCD.c, 
             SCDKeys.c, 
             SCDPrivate.c, 
-            SCDHandle.c, 
             SCDOpen.c, 
-            SCDClose.c, 
             SCDLock.c, 
             SCDUnlock.c, 
             SCDList.c, 
@@ -36,6 +49,8 @@
             SCDSet.c, 
             SCDRemove.c, 
             SCDTouch.c, 
+            SCDNotify.c, 
+            SCDNotifierSetKeys.c, 
             SCDNotifierList.c, 
             SCDNotifierAdd.c, 
             SCDNotifierRemove.c, 
@@ -49,7 +64,6 @@
             SCDSnapshot.c, 
             SCP.c, 
             SCPOpen.c, 
-            SCPClose.c, 
             SCPLock.c, 
             SCPUnlock.c, 
             SCPList.c, 
             SCDConsoleUser.c, 
             SCDHostName.c, 
             SCNetwork.c, 
-            ppp.c
+            SCProxies.c, 
+            ppp.c, 
+            v1Compatibility.c, 
+            DHCP.c
         ); 
         OTHER_SOURCES = (
             Makefile.preamble, 
         PRECOMPILED_HEADERS = (); 
         PROJECT_HEADERS = (
             SystemConfiguration.h, 
+            SCPrivate.h, 
             config_types.h, 
-            SCD.h, 
-            SCDPrivate.h, 
-            SCP.h, 
-            SCPPrivate.h, 
-            SCPPath.h, 
-            SCDConsoleUser.h, 
-            SCDHostName.h, 
-            SCNetwork.h
+            SCDynamicStoreInternal.h, 
+            SCDynamicStore.h, 
+            SCDynamicStorePrivate.h, 
+            SCDynamicStoreKey.h, 
+            SCDynamicStoreCopySpecific.h, 
+            SCDynamicStoreSetSpecificPrivate.h, 
+            SCPreferencesInternal.h, 
+            SCPreferences.h, 
+            SCPreferencesPrivate.h, 
+            SCPreferencesPath.h, 
+            SCPreferencesSetSpecific.h, 
+            SCNetwork.h, 
+            SCValidation.h, 
+            v1Compatibility.h
         ); 
         PUBLIC_HEADERS = (
             SystemConfiguration.h, 
-            SCD.h, 
-            SCDKeys.h, 
-            SCP.h, 
-            SCPPath.h, 
-            SCDConsoleUser.h, 
-            SCDHostName.h, 
+            SCDynamicStore.h, 
+            SCDynamicStoreKey.h, 
+            SCDynamicStoreCopySpecific.h, 
+            SCPreferences.h, 
+            SCPreferencesPath.h, 
+            SCPreferencesSetSpecific.h, 
             SCNetwork.h
         ); 
         SUBPROJECTS = (); 
     LANGUAGE = English; 
     MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
     NEXTSTEP_BUILDTOOL = /usr/bin/gnumake; 
-    NEXTSTEP_INSTALLDIR = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; 
+    NEXTSTEP_COMPILEROPTIONS = "-DUSE_SYSTEMCONFIGURATION_PUBLIC_APIS"; 
+    NEXTSTEP_INSTALLDIR = "$(SYSTEM_LIBRARY_DIR)/Frameworks"; 
     NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
     NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
     PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
index 169af6bd3bf42bcfc5147e87d3db9e40adddcefc..4a480dc6a93b825f9a6ce068e8b16e615cbd0506 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SCD.h>
-#include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 24, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
+#include <mach/mach.h>
+#include <mach/mach_error.h>
+#include <pthread.h>
 
-static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
+#include "config.h"            /* MiG generated file */
 
-static _SCDFlags       globalFlags = {
-       FALSE           /* debug        */,
-       FALSE           /* verbose      */,
-       FALSE           /* useSyslog    */,
-       FALSE           /* isLocked     */,
-       TRUE            /* useCFRunLoop */,
+/* framework variables */
+Boolean        _sc_debug       = FALSE;        /* TRUE if debugging enabled */
+Boolean        _sc_verbose     = FALSE;        /* TRUE if verbose logging enabled */
+Boolean        _sc_log         = TRUE;         /* TRUE if SCLog() output goes to syslog */
+
+static const struct sc_errmsg {
+       int     status;
+       char    *message;
+} sc_errmsgs[] = {
+       { kSCStatusAccessError,         "Permission denied" },
+       { kSCStatusFailed,              "Failed!" },
+       { kSCStatusInvalidArgument,     "Invalid argument" },
+       { kSCStatusKeyExists,           "Key already defined" },
+       { kSCStatusLocked,              "Lock already held" },
+       { kSCStatusNeedLock,            "Lock required for this operation" },
+       { kSCStatusNoStoreServer,       "Configuration daemon not (no longer) available" },
+       { kSCStatusNoStoreSession,      "Configuration daemon session not active" },
+       { kSCStatusNoConfigFile,        "Configuration file not found" },
+       { kSCStatusNoKey,               "No such key" },
+       { kSCStatusNoLink,              "No such link" },
+       { kSCStatusNoPrefsSession,      "Preference session not active" },
+       { kSCStatusNotifierActive,      "Notifier is currently active" },
+       { kSCStatusOK,                  "Success!" },
+       { kSCStatusPrefsBusy,           "Configuration daemon busy" },
+       { kSCStatusReachabilityUnknown, "Network reachability cannot be determined" },
+       { kSCStatusStale,               "Write attempted on stale version of object" },
 };
+#define nSC_ERRMSGS (sizeof(sc_errmsgs)/sizeof(struct sc_errmsg))
 
-static boolean_t       isSCDServer = FALSE;
-
-static const struct scd_errmsg {
-       SCDStatus       status;
-       char            *message;
-} scd_errmsgs[] = {
-       { SCD_OK,               "Success!" },
-       { SCD_NOSESSION,        "Configuration daemon session not active" },
-       { SCD_NOSERVER,         "Configuration daemon not (no longer) available" },
-       { SCD_LOCKED,           "Lock already held" },
-       { SCD_NEEDLOCK,         "Lock required for this operation" },
-       { SCD_EACCESS,          "Permission denied (must be root to obtain lock)" },
-       { SCD_NOKEY,            "No such key" },
-       { SCD_EXISTS,           "Data associated with key already defined" },
-       { SCD_STALE,            "Write attempted on stale version of object" },
-       { SCD_INVALIDARGUMENT,  "Invalid argument" },
-       { SCD_NOTIFIERACTIVE,   "Notifier is currently active" },
-       { SCD_FAILED,           "Failed!" }
-};
-#define nSCD_ERRMSGS (sizeof(scd_errmsgs)/sizeof(struct scd_errmsg))
 
+#define        USE_SCCOPYDESCRIPTION
+#ifdef USE_SCCOPYDESCRIPTION
 
-int
-SCDOptionGet(SCDSessionRef session, const int option)
-{
-       _SCDFlags       *theFlags = &globalFlags;
-       int             value     = 0;
+// from <CoreFoundation/CFVeryPrivate.h>
+extern CFStringRef _CFStringCreateWithFormatAndArgumentsAux(CFAllocatorRef alloc, CFStringRef (*copyDescFunc)(void *, CFDictionaryRef), CFDictionaryRef formatOptions, CFStringRef format, va_list arguments);
 
-       if (session != NULL) {
-               theFlags = &((SCDSessionPrivateRef)session)->flags;
+static CFStringRef
+_SCCopyDescription(void *info, CFDictionaryRef formatOptions)
+{
+       CFMutableDictionaryRef  nFormatOptions;
+       CFStringRef             prefix1;
+       CFStringRef             prefix2;
+       CFTypeID                type    = CFGetTypeID(info);
+
+       if (!formatOptions ||
+           !CFDictionaryGetValueIfPresent(formatOptions, CFSTR("PREFIX1"), (void **)&prefix1)) {
+               prefix1 = CFSTR("");
        }
 
-       switch (option) {
-
-               /* session dependent flags */
+       if (type == CFStringGetTypeID()) {
+               return CFStringCreateWithFormat(NULL,
+                                               formatOptions,
+                                               CFSTR("%@%@"),
+                                               prefix1,
+                                               info);
+       }
 
-               case kSCDOptionDebug :
-                       value = theFlags->debug;
-                       break;
+       if (type == CFBooleanGetTypeID()) {
+               return CFStringCreateWithFormat(NULL,
+                                               formatOptions,
+                                               CFSTR("%@%s"),
+                                               prefix1,
+                                               CFBooleanGetValue(info) ? "TRUE" : "FALSE");
+       }
 
-               case kSCDOptionVerbose :
-                       value = theFlags->verbose;
-                       break;
+       if (type == CFDataGetTypeID()) {
+               const u_int8_t          *data;
+               CFIndex                 dataLen;
+               CFIndex                 i;
+               CFMutableStringRef      str;
 
-               case kSCDOptionIsLocked :
-                       value = theFlags->isLocked;
-                       break;
+               str = CFStringCreateMutable(NULL, 0);
+               CFStringAppendFormat(str, formatOptions, CFSTR("%@<data> 0x"), prefix1);
 
-               case kSCDOptionUseSyslog :
-                       value = theFlags->useSyslog;
-                       break;
+               data    = CFDataGetBytePtr(info);
+               dataLen = CFDataGetLength(info);
+               for (i = 0; i < dataLen; i++) {
+                       CFStringAppendFormat(str, NULL, CFSTR("%02x"), data[i]);
+               }
 
-               case kSCDOptionUseCFRunLoop :
-                       value = theFlags->useCFRunLoop;
-                       break;
+               return str;
+       }
 
-               /* session independent flags */
+       if (type == CFNumberGetTypeID()) {
+               return CFStringCreateWithFormat(NULL,
+                                               formatOptions,
+                                               CFSTR("%@%@"),
+                                               prefix1,
+                                               info);
+       }
 
-               case kSCDOptionIsServer :
-                       value = isSCDServer;
-                       break;
+       if (type == CFDateGetTypeID()) {
+               CFGregorianDate gDate;
+               CFStringRef     str;
+               CFTimeZoneRef   tZone;
+
+               tZone = CFTimeZoneCopySystem();
+               gDate = CFAbsoluteTimeGetGregorianDate(CFDateGetAbsoluteTime(info), tZone);
+               str   = CFStringCreateWithFormat(NULL,
+                                               formatOptions,
+                                               CFSTR("%@%02d/%02d/%04d %02d:%02d:%02.0f %@"),
+                                               prefix1,
+                                               gDate.month,
+                                               gDate.day,
+                                               gDate.year,
+                                               gDate.hour,
+                                               gDate.minute,
+                                               gDate.second,
+                                               CFTimeZoneGetName(tZone));
+               CFRelease(tZone);
+               return str;
        }
 
-       return value;
-}
+       if (!formatOptions ||
+           !CFDictionaryGetValueIfPresent(formatOptions, CFSTR("PREFIX2"), (void **)&prefix2)) {
+               prefix2 = CFStringCreateCopy(NULL, prefix1);
+       }
 
+       if (formatOptions) {
+               nFormatOptions = CFDictionaryCreateMutableCopy(NULL, 0, formatOptions);
+       } else {
+               nFormatOptions = CFDictionaryCreateMutable(NULL,
+                                                          0,
+                                                          &kCFTypeDictionaryKeyCallBacks,
+                                                          &kCFTypeDictionaryValueCallBacks);
+       }
 
-void
-SCDOptionSet(SCDSessionRef session, int option, const int value)
-{
-       _SCDFlags       *theFlags = &globalFlags;
+       if (type == CFArrayGetTypeID()) {
+               void                    **elements;
+               CFIndex                 i;
+               CFIndex                 nElements;
+               CFMutableStringRef      str;
+
+               str = CFStringCreateMutable(NULL, 0);
+               CFStringAppendFormat(str, formatOptions, CFSTR("%@<array> {"), prefix1);
+
+               nElements = CFArrayGetCount(info);
+               elements  = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+               CFArrayGetValues(info, CFRangeMake(0, nElements), elements);
+               for (i=0; i<nElements; i++) {
+                       CFMutableStringRef      nPrefix1;
+                       CFMutableStringRef      nPrefix2;
+                       CFStringRef             nStr;
+                       CFStringRef             vStr;
+
+                       nStr = CFStringCreateWithFormat(NULL, NULL, CFSTR("%u"), i);
+
+                       nPrefix1 = CFStringCreateMutable(NULL, 0);
+                       CFStringAppendFormat(nPrefix1,
+                                            formatOptions,
+                                            CFSTR("%@  %@ : "),
+                                            prefix2,
+                                            nStr);
+                       nPrefix2 = CFStringCreateMutable(NULL, 0);
+                       CFStringAppendFormat(nPrefix2,
+                                            formatOptions,
+                                            CFSTR("%@  "),
+                                            prefix2);
+
+                       CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX1"), nPrefix1);
+                       CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX2"), nPrefix2);
+                       CFRelease(nPrefix1);
+                       CFRelease(nPrefix2);
+                       CFRelease(nStr);
+
+                       vStr = _SCCopyDescription(elements[i], nFormatOptions);
+                       CFStringAppendFormat(str,
+                                            formatOptions,
+                                            CFSTR("\n%@"),
+                                            vStr);
+                       CFRelease(vStr);
+               }
+               CFAllocatorDeallocate(NULL, elements);
+               CFStringAppendFormat(str, formatOptions, CFSTR("\n%@}"), prefix2);
 
-       if (session != NULL) {
-               theFlags = &((SCDSessionPrivateRef)session)->flags;
+               CFRelease(nFormatOptions);
+               return str;
        }
 
-       switch (option) {
+       if (type == CFDictionaryGetTypeID()) {
+               void                    **keys;
+               CFIndex                 i;
+               CFIndex                 nElements;
+               CFMutableStringRef      nPrefix1;
+               CFMutableStringRef      nPrefix2;
+               CFMutableStringRef      str;
+               void                    **values;
+
+               str = CFStringCreateMutable(NULL, 0);
+               CFStringAppendFormat(str, formatOptions, CFSTR("%@<dictionary> {"), prefix1);
+
+               nElements = CFDictionaryGetCount(info);
+               keys      = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+               values    = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+               CFDictionaryGetKeysAndValues(info, keys, values);
+               for (i=0; i<nElements; i++) {
+                       CFStringRef             kStr;
+                       CFStringRef             vStr;
+
+                       kStr = _SCCopyDescription(keys[i], NULL);
+
+                       nPrefix1 = CFStringCreateMutable(NULL, 0);
+                       CFStringAppendFormat(nPrefix1,
+                                            formatOptions,
+                                            CFSTR("%@  %@ : "),
+                                            prefix2,
+                                            kStr);
+                       nPrefix2 = CFStringCreateMutable(NULL, 0);
+                       CFStringAppendFormat(nPrefix2,
+                                            formatOptions,
+                                            CFSTR("%@  "),
+                                            prefix2);
+
+                       CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX1"), nPrefix1);
+                       CFDictionarySetValue(nFormatOptions, CFSTR("PREFIX2"), nPrefix2);
+                       CFRelease(nPrefix1);
+                       CFRelease(nPrefix2);
+                       CFRelease(kStr);
+
+                       vStr = _SCCopyDescription(values[i], nFormatOptions);
+                       CFStringAppendFormat(str,
+                                            formatOptions,
+                                            CFSTR("\n%@"),
+                                            vStr);
+                       CFRelease(vStr);
+               }
+               CFAllocatorDeallocate(NULL, keys);
+               CFAllocatorDeallocate(NULL, values);
+               CFStringAppendFormat(str, formatOptions, CFSTR("\n%@}"), prefix2);
 
-               /* session independent flags */
+               CFRelease(nFormatOptions);
+               return str;
+       }
 
-               case kSCDOptionDebug :
-                       theFlags->debug = value;
-                       break;
+       {
+               CFStringRef     cfStr;
+               CFStringRef     str;
+
+               cfStr = CFCopyDescription(info);
+               str = CFStringCreateWithFormat(NULL,
+                                              formatOptions,
+                                              CFSTR("%@%@"),
+                                              prefix1,
+                                              cfStr);
+               CFRelease(cfStr);
+               return str;
+       }
+}
 
-               case kSCDOptionVerbose :
-                       theFlags->verbose = value;
-                       break;
+#endif /* USE_SCCOPYDESCRIPTION */
 
-               case kSCDOptionIsLocked :
-                       theFlags->isLocked = value;
-                       break;
 
-               case kSCDOptionUseSyslog :
-                       theFlags->useSyslog = value;
-                       break;
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
 
-               case kSCDOptionUseCFRunLoop :
-                       theFlags->useCFRunLoop = value;
-                       break;
 
-               /* session independent flags */
+__private_extern__ void
+__SCLog(int level, CFStringRef str)
+{
+       CFArrayRef      lines;
 
-               case kSCDOptionIsServer :
-                       isSCDServer = value;
-                       break;
+       lines = CFStringCreateArrayBySeparatingStrings(NULL, str, CFSTR("\n"));
+       if (lines) {
+               int             i;
+
+               pthread_mutex_lock(&lock);
+               for (i=0; i<CFArrayGetCount(lines); i++) {
+                       CFDataRef       line;
+
+                       line = CFStringCreateExternalRepresentation(NULL,
+                                                                   CFArrayGetValueAtIndex(lines, i),
+                                                                   kCFStringEncodingMacRoman,
+                                                                   '?');
+                       if (line) {
+                               syslog (level, "%.*s", (int)CFDataGetLength(line), CFDataGetBytePtr(line));
+                               CFRelease(line);
+                       }
+               }
+               pthread_mutex_unlock(&lock);
+               CFRelease(lines);
        }
 
        return;
 }
 
 
-static void
-_SCDLog(SCDSessionRef session, int level, CFArrayRef lines)
+__private_extern__ void
+__SCPrint(FILE *stream, CFStringRef str)
 {
-       FILE            *f = (LOG_PRI(level) > LOG_NOTICE) ? stderr : stdout;
        CFDataRef       line;
-       int             i;
-
-       if ((LOG_PRI(level) == LOG_DEBUG) && !SCDOptionGet(session, kSCDOptionVerbose)) {
-               /* it's a debug message and we haven't requested verbose logging */
-               return;
-       }
-
-       pthread_mutex_lock(&lock);
 
-       for (i=0; i<CFArrayGetCount(lines); i++) {
-               line = CFStringCreateExternalRepresentation(NULL,
-                                                           CFArrayGetValueAtIndex(lines, i),
-                                                           kCFStringEncodingMacRoman,
-                                                           '?');
-               if (line != NULL) {
-                       if (SCDOptionGet(session, kSCDOptionUseSyslog)) {
-                               syslog (level,  "%.*s",   (int)CFDataGetLength(line), CFDataGetBytePtr(line));
-                       } else {
-                               fprintf(f, "%.*s\n", (int)CFDataGetLength(line), CFDataGetBytePtr(line));
-                               fflush (f);
-                       }
-                       CFRelease(line);
-               }
+       line = CFStringCreateExternalRepresentation(NULL,
+                                                   str,
+                                                   kCFStringEncodingMacRoman,
+                                                   '?');
+       if (line) {
+               pthread_mutex_lock(&lock);
+               fprintf(stream, "%.*s", (int)CFDataGetLength(line), CFDataGetBytePtr(line));
+               fflush (stream);
+               pthread_mutex_unlock(&lock);
+               CFRelease(line);
        }
 
-       pthread_mutex_unlock(&lock);
+       return;
 }
 
 
 void
-SCDSessionLog(SCDSessionRef session, int level, CFStringRef formatString, ...)
+SCLog(Boolean condition, int level, CFStringRef formatString, ...)
 {
        va_list         argList;
        CFStringRef     resultString;
-       CFArrayRef      lines;
+
+       if (!condition) {
+               return;
+       }
 
        va_start(argList, formatString);
+#ifdef USE_SCCOPYDESCRIPTION
+       resultString = _CFStringCreateWithFormatAndArgumentsAux(NULL,
+                                                               _SCCopyDescription,
+                                                               NULL,
+                                                               formatString,
+                                                               argList);
+#else  /* USE_SCCOPYDESCRIPTION */
        resultString = CFStringCreateWithFormatAndArguments(NULL, NULL, formatString, argList);
+#endif /* !USE_SCCOPYDESCRIPTION */
        va_end(argList);
 
-       lines = CFStringCreateArrayBySeparatingStrings(NULL, resultString, CFSTR("\n"));
-       _SCDLog(session, level, lines);
-       CFRelease(lines);
+       if (_sc_log) {
+               __SCLog(level, resultString);
+       } else {
+               FILE            *f = (LOG_PRI(level) > LOG_NOTICE) ? stderr : stdout;
+               CFStringRef     newString;
+
+               /* add a new-line */
+               newString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@\n"), resultString);
+              __SCPrint(f, newString);
+               CFRelease(newString);
+       }
        CFRelease(resultString);
+       return;
 }
 
 
 void
-SCDLog(int level, CFStringRef formatString, ...)
+SCPrint(Boolean condition, FILE *stream, CFStringRef formatString, ...)
 {
        va_list         argList;
        CFStringRef     resultString;
-       CFArrayRef      lines;
+
+       if (!condition) {
+               return;
+       }
 
        va_start(argList, formatString);
+#ifdef USE_SCCOPYDESCRIPTION
+       resultString = _CFStringCreateWithFormatAndArgumentsAux(NULL,
+                                                               _SCCopyDescription,
+                                                               NULL,
+                                                               formatString,
+                                                               argList);
+#else  /* USE_SCCOPYDESCRIPTION */
        resultString = CFStringCreateWithFormatAndArguments(NULL, NULL, formatString, argList);
+#endif /* !USE_SCCOPYDESCRIPTION */
        va_end(argList);
 
-       lines = CFStringCreateArrayBySeparatingStrings(NULL, resultString, CFSTR("\n"));
-       _SCDLog(NULL, level, lines);
-       CFRelease(lines);
+       __SCPrint(stream, resultString);
        CFRelease(resultString);
+       return;
+}
+
+
+typedef struct {
+       int     _sc_error;
+} __SCThreadSpecificData, *__SCThreadSpecificDataRef;
+
+
+static pthread_once_t  tsKeyInitialized        = PTHREAD_ONCE_INIT;
+static pthread_key_t   tsDataKey               = NULL;
+
+
+static void
+__SCThreadSpecificDataFinalize(void *arg)
+{
+       __SCThreadSpecificDataRef       tsd = (__SCThreadSpecificDataRef)arg;
+
+       if (!tsd) return;
+
+       CFAllocatorDeallocate(kCFAllocatorSystemDefault, tsd);
+       return;
+}
+
+
+static void
+__SCThreadSpecificKeyInitialize()
+{
+       pthread_key_create(&tsDataKey, __SCThreadSpecificDataFinalize);
+       return;
+}
+
+
+void
+_SCErrorSet(int error)
+{
+       __SCThreadSpecificDataRef       tsd;
+
+       pthread_once(&tsKeyInitialized, __SCThreadSpecificKeyInitialize);
+
+       tsd = pthread_getspecific(tsDataKey);
+       if (!tsd) {
+               tsd = CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(__SCThreadSpecificData), 0);
+               bzero(tsd, sizeof(__SCThreadSpecificData));
+               pthread_setspecific(tsDataKey, tsd);
+       }
+
+       tsd->_sc_error = error;
+       return;
+}
+
+
+int
+SCError()
+{
+       __SCThreadSpecificDataRef       tsd;
+
+       pthread_once(&tsKeyInitialized, __SCThreadSpecificKeyInitialize);
+
+       tsd = pthread_getspecific(tsDataKey);
+       return tsd ? tsd->_sc_error : kSCStatusOK;
 }
 
 
 const char *
-SCDError(SCDStatus status)
+SCErrorString(int status)
 {
        int i;
 
-       for (i = 0; i < nSCD_ERRMSGS; i++) {
-               if (scd_errmsgs[i].status == status) {
-                       return scd_errmsgs[i].message;
+       for (i = 0; i < nSC_ERRMSGS; i++) {
+               if (sc_errmsgs[i].status == status) {
+                       return sc_errmsgs[i].message;
                }
        }
-       return "(unknown error)";
+
+       if ((status > 0) && (status <= ELAST)) {
+               return strerror(status);
+       }
+
+       return mach_error_string(status);
 }
index d580665d664cfec72e718c858bbc20248e171b35..9a2ef169846c162cd0c3b30d0052adb701c97c00 100644 (file)
 #ifndef _SCD_H
 #define _SCD_H
 
-#include <CoreFoundation/CoreFoundation.h>
-#include <CoreFoundation/CFRunLoop.h>
-#include <mach/message.h>
-#include <sys/cdefs.h>
-#include <sys/syslog.h>
-
-
-/*!
-       @header SCD.h
-       The SystemConfiguration framework provides access to the data used to configure a running system.  The APIs provided by this framework communicate with the "configd" daemon.
-
-The "configd" daemon manages a "cache" reflecting the desired configuration settings as well as the current state of the system.  The daemon provides a notification mechanism for user-level processes which need to be aware of changes made to the "cache" data.  Lastly, the daemon loads a number of bundles(or plug-ins) which monitor low-level kernel events and, via a set of policy modules, keep this cached data up to date.
-
-The "configd" daemon also provides an address space/task/process which can be used by other CFRunLoop based functions which would otherwise require their own process/daemon for execution.
-
- */
-
-
-/*!
-       @enum SCDStatus
-       @discussion Returned status codes.
-       @constant SCD_OK                Success
-       @constant SCD_NOSESSION         Configuration daemon session not active
-       @constant SCD_NOSERVER          Configuration daemon not (no longer) available
-       @constant SCD_LOCKED            Lock already held
-       @constant SCD_NEEDLOCK          Lock required for this operation
-       @constant SCD_EACCESS           Permission denied (must be root to obtain lock)
-       @constant SCD_NOKEY             No such key
-       @constant SCD_EXISTS            Data associated with key already defined
-       @constant SCD_STALE             Write attempted on stale version of object
-       @constant SCD_INVALIDARGUMENT   Invalid argument
-       @constant SCD_NOTIFIERACTIVE    Notifier is currently active
-       @constant SCD_FAILED            Generic error
- */
-typedef enum {
-       SCD_OK                  = 0,    /* Success */
-       SCD_NOSESSION           = 1,    /* Configuration daemon session not active */
-       SCD_NOSERVER            = 2,    /* Configuration daemon not (no longer) available */
-       SCD_LOCKED              = 3,    /* Lock already held */
-       SCD_NEEDLOCK            = 4,    /* Lock required for this operation */
-       SCD_EACCESS             = 5,    /* Permission denied (must be root to obtain lock) */
-       SCD_NOKEY               = 6,    /* No such key */
-       SCD_EXISTS              = 7,    /* Data associated with key already defined */
-       SCD_STALE               = 8,    /* Write attempted on stale version of object */
-       SCD_INVALIDARGUMENT     = 9,    /* Invalid argument */
-       SCD_NOTIFIERACTIVE      = 10,   /* Notifier is currently active */
-       SCD_FAILED              = 9999  /* Generic error */
-} SCDStatus;
-
-
-/*!
-       @typedef SCDSessionRef
-       @discussion This is the type of a handle to an open "session" with the system
-               configuration daemon.
- */
-typedef const struct __SCDSession *    SCDSessionRef;
-
-/*!
-       @typedef SCDHandleRef
-       @discussion This is the type of a handle to data being retrieved from or to be
-               stored by the system configuration daemon.
- */
-typedef const struct __SCDHandle *     SCDHandleRef;
-
-
-/*!
-       @typedef SCDCallbackRoutine_t
-       @discussion Type of the callback function used by the SCDNotifierInformViaCallback()
-               function.
-       @param session The session handle.
-       @param callback_argument The user-defined argument to be passed to the callback
-               function.
- */
-typedef boolean_t (*SCDCallbackRoutine_t)       (SCDSessionRef         session,
-                                                 void                  *callback_argument);
-
-
-/*!
-       @enum SCDKeyOption
-       @discussion Used with the SCDList() and SCDNotifierAdd() functions to describe
-               the CFStringRef argument.
-       @constant kSCDRegexKey Specifies that the key consists of a regular expression.
- */
-typedef enum {
-       kSCDRegexKey            = 0100000,      /* pattern string is a regular expression */
-} SCDKeyOption;
-
-
-/*!
-       @enum SCDOption
-       @discussion Options which determine the run-time processing of the system
-               configuration framework functions.
-       @constant kSCDOptionDebug Enable debugging
-       @constant kSCDOptionVerbose Enable verbose logging
-       @constant kSCDOptionUseSyslog Use syslog(3) for log messages
-       @constant kSCDOptionUseCFRunLoop Calling application is CFRunLoop() based
- */
-typedef enum {
-       kSCDOptionDebug         = 0,    /* Enable debugging */
-       kSCDOptionVerbose       = 1,    /* Enable verbose logging */
-       kSCDOptionUseSyslog     = 2,    /* Use syslog(3) for log messages */
-       kSCDOptionUseCFRunLoop  = 3,    /* Calling application is CFRunLoop() based */
-} SCDOption;
-
-
-/*
- * "configd" loadable bundle / plug-in options
- */
-
-/*!
-       @typedef SCDBundleStartRoutine_t
-       @discussion Type of the start() initializatioin function which will be called
-               after all plug-ins have been loaded.  This function should initialize any
-               variables, open any sessions with "configd", and register any needed
-               notifications.
-       @param bundlePath The path name associated with the plug-in / bundle.
-       @param bundleName The name of the plug-in / bundle.
- */
-typedef void (*SCDBundleStartRoutine_t) (const char *bundlePath,
-                                        const char *bundleName);
-
-/*!
-       @typedef SCDBundlePrimeRoutine_t
-       @discussion Type of the prime() initializatioin function which will be
-               called after all plug-ins have executed their start() function but
-               before the main plug-in run loop is started.  This function should
-               be used to initialize any configuration information and/or state
-               in the cache.
- */
-typedef void (*SCDBundlePrimeRoutine_t) ();
-
-#define        BUNDLE_DIRECTORY        "/SystemConfiguration"  /* [/System/Library]/... */
-#define BUNDLE_OLD_SUBDIR      "/"
-#define BUNDLE_NEW_SUBDIR      "/Contents/MacOS/"
-#define BUNDLE_DIR_EXTENSION   ".bundle"
-#define BUNDLE_DEBUG_EXTENSION "_debug"
-#define BUNDLE_ENTRY_POINT     "_start"
-#define BUNDLE_ENTRY_POINT2    "_prime"
-
-
-__BEGIN_DECLS
-
-/*!
-       @function SCDHandleInit
-       @discussion Creates a new handle used to access the cached configuration
-               dictionary data.
-       @result A new "cache" data handle.
- */
-SCDHandleRef   SCDHandleInit                   ();
-
-/*!
-       @function SCDHandleRelease
-       @discussion Releases the specified configuration data handle. The dictionary
-               (or other CFType) associated with this handle will also be released
-               unless a call was previously made to CFRetain().
-       @param handle The cache data handle to be released.
- */
-void           SCDHandleRelease                (SCDHandleRef           handle);
-
-/*!
-       @function SCDHandleGetInstance
-       @discussion Returns the instance number associated with the specified
-               configuration handle.
-       @param handle The cache data handle.
-       @result The instance number associated with the specified handle.
- */
-int            SCDHandleGetInstance            (SCDHandleRef           handle);
-
-/*!
-       @function SCDHandleGetData
-       @discussion Returns a reference to the data associated with the specified
-               configuration handle.
-       @param handle The cache data handle.
-       @result The CFType data associated with the specified handle.
- */
-CFPropertyListRef SCDHandleGetData             (SCDHandleRef           handle);
-
-/*!
-       @function SCDHandleSetData
-       @discussion Returns a reference to the data associated with the specified
-               configuration handle.
-       @param handle The cache data handle.
-       @param data The CFType data to be associated with the handle.
- */
-void           SCDHandleSetData                (SCDHandleRef           handle,
-                                                CFPropertyListRef      data);
-/*!
-       @function SCDOpen
-       @discussion Initiates a connection with the configuration daemon.
-       @param session A pointer to memory which will be filled with an SCDSessionRef
-               handle to be used for all subsequent requests to the server.
-               If a session cannot be established with the server, the contents of
-               memory pointed to by this parameter are undefined.
-       @param name Pass a string which describes the name of the calling process or
-               plug-in name of the caller.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDOpen                         (SCDSessionRef          *session,
-                                                CFStringRef            name);
-
-/*!
-       @function SCDClose
-       @discussion Closes the specified session to the configuration daemon.  All
-               outstanding notification requests will be cancelled.
-       @param session Pass a pointer to an SCDSessionRef handle which should be closed.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDClose                        (SCDSessionRef          *session);
-
-/*!
-       @function SCDLock
-       @discussion Locks access to the configuration "cache".  All other clients
-               attempting to access the "cache" will block. All change notifications
-               will be deferred until the lock is released.
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDLock                         (SCDSessionRef          session);
-
-/*!
-       @function SCDUnlock
-       @discussion Unlocks access to the configuration "cache".  Other clients will
-               be able to access the "cache". Any change notifications will be delivered.
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDUnlock                       (SCDSessionRef          session);
-
-/*!
-       @function SCDList
-       @discussion Returns an array of CFStringRefs representing the configuration "cache"
-               entries which match the specified pattern key.
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param key The string which must prefix those keys in the configuration "cache"
-               (if regexOptions is zero) or a regex(3) regular expression string which
-               will be used to match configuration "cache" (if regexOptions is kSCDRegexKey).
-       @param regexOptions Pass a bitfield of type SCDKeyOption containing one or more
-               flags describing the pattern key.
-       @param subKeys Pass a pointer to a CFArrayRef which will be set to a new
-               array of CFStringRefs's matching the provided key.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDList                         (SCDSessionRef          session,
-                                                CFStringRef            key,
-                                                int                    regexOptions,
-                                                CFArrayRef             *subKeys);
-
-/*!
-       @function SCDAdd
-       @discussion Creates a new entry in the configuration "cache" using the
-               specified key and data.  An error is returned if the key is already
-               defined in the dictionary.
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param key Pass a reference to the CFStringRef object to be created.
-       @param handle Pass a reference to the SCDHandle object containing the data
-               to be associated with the specified key.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDAdd                          (SCDSessionRef          session,
-                                                CFStringRef            key,
-                                                SCDHandleRef           handle);
-
-/*!
-       @function SCDAddSession
-       @discussion Creates a new entry in the configuration "cache" using the
-       specified key and data.  This entry will, unless updated by another
-       session, automatically be removed when the session is closed.  An
-       error is returned if the key is already defined in the dictionary.
-
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param key Pass a reference to the CFStringRef object to be created.
-       @param handle Pass a reference to the SCDHandle object containing the data
-               to be associated with the specified key.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDAddSession                   (SCDSessionRef          session,
-                                                CFStringRef            key,
-                                                SCDHandleRef           handle);
-
-/*!
-       @function SCDGet
-       @discussion Returns a handle to the configuration "cache" data that corresponds
-               to the specified key.
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param key Pass a reference to the CFStringRef object to be returned.
-       @param handle Pass a pointer to a SCDHandleRef which will be set to a
-               new object containing the data associated with the specified key.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDGet                          (SCDSessionRef          session,
-                                                CFStringRef            key,
-                                                SCDHandleRef           *handle);
-
-/*!
-       @function SCDSet
-       @discussion Updates the entry in the configuration "cache" that corresponds to
-               the specified key with the provided data.  An error will be returned if
-               the data in the "cache" has been updated since the data handle was last
-               updated.
-       @param session Pass the SCDSessionRef handle which should be used to communicate
-               with the server.
-       @param key Pass a reference to the CFStringRef object to be updated.
-       @param handle Pass a reference to the SCDHandle object containing the data
-               to be associated with the specified key.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDSet                          (SCDSessionRef          session,
-                                                CFStringRef            key,
-                                                SCDHandleRef           handle);
-
-/*!
-       @function SCDRemove
-       @discussion Removes the data from the configuration "cache" data which corresponds
-               to the specified key.
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param key Pass a reference to the CFStringRef object to be removed.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDRemove                       (SCDSessionRef          session,
-                                                CFStringRef            key);
-
-/*!
-       @function SCDTouch
-       @discussion Updates the instance number for the data in the configuration "cache"
-               associated with the specified key.  If the specified key does not exist
-               then a CFDate object will be associated with the key.  If the associated
-               data is already a CFDate object then the value will be updated.
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param key Pass a reference to the CFStringRef object to be updated.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDTouch                        (SCDSessionRef          session,
-                                               CFStringRef             key);
-
-/*
-       @function SCDSnapshot
-       @discussion Records the current state of configd's cache dictionary into the
-               /var/tmp/configd-cache file and configd's session dictionary into the
-               /var/tmp/configd-session file.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDSnapshot                     (SCDSessionRef          session);
-
-/*!
-       @function SCDNotifierList
-       @discussion Returns an array of CFStringRefs representing the system configuration
-               data entries being monitored for changes.
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param regexOptions Pass a bitfield of type SCDKeyOption which specifies whether
-               the specific configuration cache key patterns are to be returned or those
-               based on regex(3) pattern strings.
-       @param notifierKeys Pass a pointer to a CFArrayRef which will be set to a new
-               array of CFStringRef's being monitored.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDNotifierList                 (SCDSessionRef          session,
-                                                int                    regexOptions,
-                                                CFArrayRef             *notifierKeys);
-
-/*!
-       @function SCDNotifierAdd
-       @discussion Adds the specified key to the list of system configuration
-               data entries which are being monitored for changes.
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param key Pass a reference to the CFStringRef object to be monitored.
-       @param regexOptions Pass a bitfield of type SCDKeyOption which specifies whether
-               the key is for a specific configuration cache key or if it consists
-               of a regex(3) pattern string.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDNotifierAdd                  (SCDSessionRef          session,
-                                                CFStringRef            key,
-                                                int                    regexOptions);
-
-/*!
-       @function SCDNotifierRemove
-       @discussion Removes the specified key from the list of system configuration
-               data entries which are being monitored for changes.
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param key Pass a reference to the CFStringRef object which should not be monitored.
-       @param regexOptions Pass a bitfield of type SCDKeyOption which specifies whether
-               the key is for a specific configuration cache key or if it consists
-               of a regex(3) pattern string.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDNotifierRemove               (SCDSessionRef          session,
-                                                CFStringRef            key,
-                                                int                    regexOptions);
-
-/*!
-       @function SCDNotifierGetChanges
-       @discussion Returns an array of CFStringRefs representing the monitored system
-               configuration data entries which have changed since this function
-               was last called.
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param notifierKeys Pass a pointer to a CFArrayRef which will be set to a new
-               array of CFStringRef's being monitored.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDNotifierGetChanges           (SCDSessionRef          session,
-                                                CFArrayRef             *notifierKeys);
-
-/*!
-       @function SCDNotifierWait
-       @discussion Waits for a change to be made to a system configuration data
-               entry associated with the current sessions notifier keys.
-
-       Note: this function is not valid for "configd" plug-ins.
-
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDNotifierWait                 (SCDSessionRef          session);
-
-/*!
-       @function SCDNotifierInformViaCallback
-       @discussion Requests that the specified function be called whenever a change
-               has been detected to one of the system configuration data entries
-               associated with the current sessions notifier keys.
-
-       The callback function will be called with two arguments, session and arg, which
-       correspond to the current session and the provided argument.
-       The function should return a boolean value indicating whether an
-       error occurred during execution of the callback.
-
-       Note: if the calling application is based on the CFRunLoop() then an additional
-       run loop source will be added for the notification.
-       Applications which are not based on the CFRunLoop() will have a separate thread
-       started to wait for changes.
-       In either case, the additional run loop source and/or thread will terminate if
-       the notification is cancelled or if the callback indicates that an error was
-       detected.
-
-       Note: this function is not valid for "configd" plug-ins.
-
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param func Pass a pointer to the callback applier function to call when a
-               monitored cache entry is changed.  If this parameter is not a pointer to
-               a function of the correct prototype (SCDCallbackRoutine_t), the behavior
-               is undefined.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDNotifierInformViaCallback    (SCDSessionRef          session,
-                                                SCDCallbackRoutine_t   func,
-                                                void                   *arg);
-
-/*!
-       @function SCDNotifierInformViaMachPort
-       @discussion Allocates a mach port which can be used to detect changes to
-               one of the system configuration data entries associated with the
-               current sessions notifier keys. When a change is detected, an
-               empty (no data) mach message with the specified identifier will
-               be delivered to the calling application via the allocated port.
-
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param msgid Pass a mach message ID to be included with any notifications.
-       @param port Pass a pointer to a mach port.  Upon return, port will be filled
-               with the mach port which will be used for any notifications.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDNotifierInformViaMachPort    (SCDSessionRef          session,
-                                                mach_msg_id_t          msgid,
-                                                mach_port_t            *port);
-
-/*!
-       @function SCDNotifierInformViaFD
-       @discussion Allocates a file descriptor which can be used to detect changes
-               to one of the system configuration data entries associated with the
-               current sessions notifier keys. When a change is detected, the
-               specified identifier (4 bytes) will be delivered to the calling
-               application via the allocated file descriptor.
-
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param identifier Pass an (4 byte) integer identifer which be used for any
-               notifications.
-       @param fd Pass a pointer to a file descriptor.  Upon return, fd will be filled
-               with the file descriptor which will be used for any notifications.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDNotifierInformViaFD          (SCDSessionRef          session,
-                                                int32_t                identifier,
-                                                int                    *fd);
-
-/*!
-       @function SCDNotifierInformViaSignal
-       @discussion Requests that the specified BSD signal be sent to the process
-               with the indicated process id whenever a change has been detected
-               to one of the system configuration data entries associated with the
-               current sessions notifier keys.
-
-               Note: this function is not valid for "configd" plug-ins.
-
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @param pid Pass a UNIX proces ID which should be signalled for any notifications.
-       @param sig Pass a signal number to be used.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDNotifierInformViaSignal      (SCDSessionRef          session,
-                                                pid_t                  pid,
-                                                int                    sig);
-
-/*!
-       @function SCDNotifierCancel
-       @discussion Cancels all outstanding notification delivery request for this
-               session.
-
-       @param session Pass a SCDSessionRef handle which should be used for
-               communication with the server.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDNotifierCancel               (SCDSessionRef          session);
-
-/*!
-       @function SCDOptionGet
-       @discussion Returns the value associated with the specified option.
-       @param session Pass a SCDSessionRef handle of the option of interest (or
-               NULL for the global option setting).
-       @param option Pass the SCDOption of interest.
-       @result The current value of the specified option.
- */
-int            SCDOptionGet                    (SCDSessionRef          session,
-                                                int                    option);
-
-/*!
-       @function SCDOptionSet
-       @discussion Sets the value associated with the specified option.
-       @param session Pass a SCDSessionRef handle for the option to be set (or
-               NULL for the global option settings).
-       @param option Pass the SCDOption to be updated.
-       @param value Pass the new value for the option.
-       @result The current value of the specified option.
- */
-void           SCDOptionSet                    (SCDSessionRef          session,
-                                                int                    option,
-                                                int                    value);
-
-/*!
-       @function SCDSessionLog
-       @discussion Issues a log and/or debug message.
-       @param session Pass a SCDSessionRef handle for the current session..
-       @param level Pass a syslog(3) logging priority.
-
-       Note: LOG_DEBUG messages will not be issued if the verbose option has not been enabled.
-       @param formatString Pass the CF format string
-       @result The specified message will be logged.
- */
-void           SCDSessionLog                   (SCDSessionRef          session,
-                                                int                    level,
-                                                CFStringRef            formatString,
-                                                ...);
-
-/*!
-       @function SCDLog
-       @discussion Issues a log and/or debug message.
-       @param level Pass a syslog(3) logging priority.
-       @param formatString Pass the CF format string
-       @result The specified message will be logged.
- */
-void           SCDLog                          (int                    level,
-                                                CFStringRef            formatString,
-                                                ...);
-
-const char *   SCDError                        (SCDStatus              status);
-
-__END_DECLS
+#ifndef _SYSTEMCONFIGURATION_H
+#warning Your code has directly included the (old) <SystemConfiguration/SCD.h>
+#warning header file.  Please dont do that.  Use the top-level header file:
+#warning
+#warning   <SystemConfiguration/SystemConfiguration.h>
+#warning
+#warning Note: the dynamic store APIs have been moved out of the SCD.h header.
+#include <SystemConfiguration/SystemConfiguration.h>    /* ...and try to keep everyone happy */
+#endif
 
 #endif /* _SCD_H */
index 382249e521f74409cfc67af12a6676fdfb53879a..c1e5cc3d0c54b41cdf79feac7c28676183f4f514 100644 (file)
  * @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 <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
-
 
-SCDStatus
-SCDAdd(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
+Boolean
+SCDynamicStoreAddValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       CFDataRef               xmlKey;         /* serialized key */
-       xmlData_t               myKeyRef;
-       CFIndex                 myKeyLen;
-       CFDataRef               xmlData;        /* serialized data */
-       xmlData_t               myDataRef;
-       CFIndex                 myDataLen;
-       int                     newInstance;
-       SCDStatus               scd_status;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlKey;         /* serialized key */
+       xmlData_t                       myKeyRef;
+       CFIndex                         myKeyLen;
+       CFDataRef                       xmlData;        /* serialized data */
+       xmlData_t                       myDataRef;
+       CFIndex                         myDataLen;
+       int                             newInstance;
+       int                             sc_status;
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDAdd:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key          = %@"), key);
-       SCDLog(LOG_DEBUG, CFSTR("  data         = %@"), SCDHandleGetData(handle));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreAddValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key          = %@"), key);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  value        = %@"), value);
 
-       if (key == NULL) {
-               return SCD_INVALIDARGUMENT;     /* no key specified */
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
        }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
        /* serialize the key and data */
@@ -59,18 +73,18 @@ SCDAdd(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
        myKeyRef = (xmlData_t)CFDataGetBytePtr(xmlKey);
        myKeyLen = CFDataGetLength(xmlKey);
 
-       xmlData = CFPropertyListCreateXMLData(NULL, SCDHandleGetData(handle));
+       xmlData = CFPropertyListCreateXMLData(NULL, value);
        myDataRef = (xmlData_t)CFDataGetBytePtr(xmlData);
        myDataLen = CFDataGetLength(xmlData);
 
        /* send the key & data to the server */
-       status = configadd(sessionPrivate->server,
+       status = configadd(storePrivate->server,
                           myKeyRef,
                           myKeyLen,
                           myDataRef,
                           myDataLen,
                           &newInstance,
-                          (int *)&scd_status);
+                          (int *)&sc_status);
 
        /* clean up */
        CFRelease(xmlKey);
@@ -78,17 +92,17 @@ SCDAdd(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("configadd(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configadd(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
        }
 
-       if (scd_status == SCD_OK) {
-               _SCDHandleSetInstance(handle, newInstance);
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
-       SCDLog(LOG_DEBUG, CFSTR("  new instance = %d"), SCDHandleGetInstance(handle));
-
-       return scd_status;
+       return TRUE;
 }
index b19ae0e04b09d242c4f76ceb58a9e0e2f5688568..d470876c4fae3725f40ebb762c4ed39240956b75 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * October 17, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
-
 
-SCDStatus
-SCDAddSession(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
+Boolean
+SCDynamicStoreAddTemporaryValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       CFDataRef               xmlKey;         /* serialized key */
-       xmlData_t               myKeyRef;
-       CFIndex                 myKeyLen;
-       CFDataRef               xmlData;        /* serialized data */
-       xmlData_t               myDataRef;
-       CFIndex                 myDataLen;
-       int                     newInstance;
-       SCDStatus               scd_status;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlKey;         /* serialized key */
+       xmlData_t                       myKeyRef;
+       CFIndex                         myKeyLen;
+       CFDataRef                       xmlData;        /* serialized data */
+       xmlData_t                       myDataRef;
+       CFIndex                         myDataLen;
+       int                             newInstance;
+       int                             sc_status;
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDAddSession:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key          = %@"), key);
-       SCDLog(LOG_DEBUG, CFSTR("  data         = %@"), SCDHandleGetData(handle));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreAddTemporaryValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key          = %@"), key);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  value        = %@"), value);
 
-       if (key == NULL) {
-               return SCD_INVALIDARGUMENT;     /* no key specified */
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
        }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
        /* serialize the key and data */
@@ -59,18 +73,18 @@ SCDAddSession(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
        myKeyRef = (xmlData_t)CFDataGetBytePtr(xmlKey);
        myKeyLen = CFDataGetLength(xmlKey);
 
-       xmlData = CFPropertyListCreateXMLData(NULL, SCDHandleGetData(handle));
+       xmlData = CFPropertyListCreateXMLData(NULL, value);
        myDataRef = (xmlData_t)CFDataGetBytePtr(xmlData);
        myDataLen = CFDataGetLength(xmlData);
 
        /* send the key & data to the server */
-       status = configadd_s(sessionPrivate->server,
+       status = configadd_s(storePrivate->server,
                            myKeyRef,
                            myKeyLen,
                            myDataRef,
                            myDataLen,
                            &newInstance,
-                           (int *)&scd_status);
+                           (int *)&sc_status);
 
        /* clean up */
        CFRelease(xmlKey);
@@ -78,17 +92,17 @@ SCDAddSession(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("configadd_s(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configadd_s(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
        }
 
-       if (scd_status == SCD_OK) {
-               _SCDHandleSetInstance(handle, newInstance);
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
-       SCDLog(LOG_DEBUG, CFSTR("  new instance = %d"), SCDHandleGetInstance(handle));
-
-       return scd_status;
+       return TRUE;
 }
diff --git a/SystemConfiguration.fproj/SCDClose.c b/SystemConfiguration.fproj/SCDClose.c
deleted file mode 100644 (file)
index 86aeb3c..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2000 Apple Computer, 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 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.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <unistd.h>
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-
-#include <SystemConfiguration/SCD.h>
-#include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
-
-
-SCDStatus
-SCDClose(SCDSessionRef *session)
-{
-       SCDSessionPrivateRef    sessionPrivate;
-       int                     oldThreadState;
-       kern_return_t           status;
-       SCDStatus               scd_status;
-       CFIndex                 keyCnt;
-
-       SCDLog(LOG_DEBUG, CFSTR("SCDClose:"));
-
-       if ((session == NULL) || (*session == NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
-       }
-       sessionPrivate = (SCDSessionPrivateRef)*session;
-
-       (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldThreadState);
-
-       scd_status = (sessionPrivate->server == MACH_PORT_NULL) ? SCD_NOSESSION : SCD_OK;
-
-       /* Remove notification keys */
-       if ((keyCnt = CFSetGetCount(sessionPrivate->keys)) > 0) {
-               void            **watchedKeys;
-               CFArrayRef      keysToRemove;
-               CFIndex i;
-
-               watchedKeys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
-               CFSetGetValues(sessionPrivate->keys, watchedKeys);
-               keysToRemove = CFArrayCreate(NULL, watchedKeys, keyCnt, &kCFTypeArrayCallBacks);
-               CFAllocatorDeallocate(NULL, watchedKeys);
-               for (i=0; i<keyCnt; i++) {
-                       if (scd_status == SCD_OK) {
-                               scd_status = SCDNotifierRemove(*session,
-                                                              CFArrayGetValueAtIndex(keysToRemove, i),
-                                                              0);
-                       }
-               }
-               CFRelease(keysToRemove);
-       }
-
-       /* Remove regex notification keys */
-       if ((keyCnt = CFSetGetCount(sessionPrivate->reKeys)) > 0) {
-               void            **watchedKeys;
-               CFArrayRef      keysToRemove;
-               CFIndex i;
-
-               watchedKeys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
-               CFSetGetValues(sessionPrivate->reKeys, watchedKeys);
-               keysToRemove = CFArrayCreate(NULL, watchedKeys, keyCnt, &kCFTypeArrayCallBacks);
-               CFAllocatorDeallocate(NULL, watchedKeys);
-               for (i=0; i<keyCnt; i++) {
-                       if (scd_status == SCD_OK) {
-                               scd_status = SCDNotifierRemove(*session,
-                                                              CFArrayGetValueAtIndex(keysToRemove, i),
-                                                              kSCDRegexKey);
-                       }
-               }
-               CFRelease(keysToRemove);
-       }
-
-       /* Remove/cancel any outstanding notification requests. */
-       (void) SCDNotifierCancel(*session);
-
-       if (SCDOptionGet(*session, kSCDOptionIsLocked) && (scd_status == SCD_OK)) {
-               scd_status = SCDUnlock(*session);       /* release the lock */
-       }
-
-       if (scd_status == SCD_OK) {
-               status = configclose(sessionPrivate->server, (int *)&scd_status);
-               if (status != KERN_SUCCESS) {
-                       if (status != MACH_SEND_INVALID_DEST)
-                               SCDLog(LOG_DEBUG, CFSTR("configclose(): %s"), mach_error_string(status));
-                       scd_status = SCD_NOSERVER;
-               }
-
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-       }
-
-       CFAllocatorDeallocate(NULL, sessionPrivate);
-       *session = NULL;
-
-       (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldThreadState);
-       pthread_testcancel();
-
-       return scd_status;
-}
index a607b93e57a489ce08f5737e5a5b8910e8777da7..900db519c82baf000154af18b9d39500ceabde1b 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SystemConfiguration.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * January 2, 2001             Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include <SystemConfiguration/SCValidation.h>
 
 CFStringRef
-SCDKeyCreateConsoleUser()
+SCDynamicStoreKeyCreateConsoleUser(CFAllocatorRef allocator)
 {
-       return SCDKeyCreate(CFSTR("%@/%@/%@"),
-                           CFSTR("state:"),    // FIXME!!! (should be kSCCacheDomainState)
-                           kSCCompUsers,
-                           kSCEntUsersConsoleUser);
+       return SCDynamicStoreKeyCreate(allocator,
+                                      CFSTR("%@/%@/%@"),
+                                      kSCDynamicStoreDomainState,
+                                      kSCCompUsers,
+                                      kSCEntUsersConsoleUser);
 }
 
 
-SCDStatus
-SCDConsoleUserGet(char *user, int userlen, uid_t *uid, gid_t *gid)
+CFStringRef
+SCDynamicStoreCopyConsoleUser(SCDynamicStoreRef        store,
+                             uid_t             *uid,
+                             gid_t             *gid)
 {
-       CFDictionaryRef dict;
-       SCDHandleRef    handle  = NULL;
-       CFStringRef     key;
-       SCDSessionRef   session = NULL;
-       SCDStatus       status;
-
-       /* get current user */
-       status = SCDOpen(&session, CFSTR("SCDConsoleUserGet"));
-       if (status != SCD_OK) {
-               goto done;
+       CFStringRef             consoleUser     = NULL;
+       CFDictionaryRef         dict            = NULL;
+       CFStringRef             key;
+       SCDynamicStoreRef       mySession       = store;
+
+       if (!store) {
+               mySession = SCDynamicStoreCreate(NULL,
+                                                CFSTR("SCDynamicStoreCopyConsoleUser"),
+                                                NULL,
+                                                NULL);
+               if (!mySession) {
+                       SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+                       return NULL;
+               }
        }
 
-       key = SCDKeyCreateConsoleUser();
-       status = SCDGet(session, key, &handle);
+       key  = SCDynamicStoreKeyCreateConsoleUser(NULL);
+       dict = SCDynamicStoreCopyValue(mySession, key);
        CFRelease(key);
-       if (status != SCD_OK) {
+       if (!isA_CFDictionary(dict)) {
+               _SCErrorSet(kSCStatusNoKey);
                goto done;
        }
 
-       dict = SCDHandleGetData(handle);
-
-       if (user && (userlen > 0)) {
-               CFStringRef     consoleUser;
-
-               bzero(user, userlen);
-               if (CFDictionaryGetValueIfPresent(dict,
-                                                 kSCPropUsersConsoleUserName,
-                                                 (void **)&consoleUser)) {
-                       CFIndex         len;
-                       CFRange         range;
-
-                       range = CFRangeMake(0, CFStringGetLength(consoleUser));
-                       (void)CFStringGetBytes(consoleUser,
-                                              range,
-                                              kCFStringEncodingMacRoman,
-                                              0,
-                                              FALSE,
-                                              user,
-                                              userlen,
-                                              &len);
-               }
+       consoleUser = CFDictionaryGetValue(dict, kSCPropUsersConsoleUserName);
+       consoleUser = isA_CFString(consoleUser);
+       if (!consoleUser) {
+               _SCErrorSet(kSCStatusNoKey);
+               goto done;
        }
 
+       CFRetain(consoleUser);
+
        if (uid) {
                CFNumberRef     num;
                SInt32          val;
 
-               if (CFDictionaryGetValueIfPresent(dict,
-                                                 kSCPropUsersConsoleUserUID,
-                                                 (void **)&num)) {
+               num = CFDictionaryGetValue(dict, kSCPropUsersConsoleUserUID);
+               if (isA_CFNumber(num)) {
                        if (CFNumberGetValue(num, kCFNumberSInt32Type, &val)) {
                                *uid = (uid_t)val;
                        }
@@ -96,9 +99,8 @@ SCDConsoleUserGet(char *user, int userlen, uid_t *uid, gid_t *gid)
                CFNumberRef     num;
                SInt32          val;
 
-               if (CFDictionaryGetValueIfPresent(dict,
-                                                 kSCPropUsersConsoleUserGID,
-                                                 (void **)&num)) {
+               num = CFDictionaryGetValue(dict, kSCPropUsersConsoleUserGID);
+               if (isA_CFNumber(num)) {
                        if (CFNumberGetValue(num, kCFNumberSInt32Type, &val)) {
                                *gid = (gid_t)val;
                        }
@@ -107,30 +109,39 @@ SCDConsoleUserGet(char *user, int userlen, uid_t *uid, gid_t *gid)
 
     done :
 
-       if (handle)     SCDHandleRelease(handle);
-       if (session)    (void) SCDClose(&session);
-       return status;
+       if (!store && mySession)        CFRelease(mySession);
+       if (dict)                       CFRelease(dict);
+       return consoleUser;
+
 }
 
 
-SCDStatus
-SCDConsoleUserSet(const char *user, uid_t uid, gid_t gid)
+Boolean
+SCDynamicStoreSetConsoleUser(SCDynamicStoreRef store,
+                            const char         *user,
+                            uid_t              uid,
+                            gid_t              gid)
 {
        CFStringRef             consoleUser;
-       CFMutableDictionaryRef  dict    = NULL;
-       SCDHandleRef            handle  = NULL;
-       CFStringRef             key     = SCDKeyCreateConsoleUser();
+       CFMutableDictionaryRef  dict            = NULL;
+       CFStringRef             key             = SCDynamicStoreKeyCreateConsoleUser(NULL);
+       SCDynamicStoreRef       mySession       = store;
        CFNumberRef             num;
-       SCDSessionRef           session = NULL;
-       SCDStatus               status;
-
-       status = SCDOpen(&session, CFSTR("SCDConsoleUserSet"));
-       if (status != SCD_OK) {
-               goto done;
+       Boolean                 ok              = TRUE;
+
+       if (!store) {
+               mySession = SCDynamicStoreCreate(NULL,
+                                                CFSTR("SCDynamicStoreSetConsoleUser"),
+                                                NULL,
+                                                NULL);
+               if (!mySession) {
+                       SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+                       return FALSE;
+               }
        }
 
        if (user == NULL) {
-               (void)SCDRemove(session, key);
+               ok = SCDynamicStoreRemoveValue(mySession, key);
                goto done;
        }
 
@@ -151,22 +162,12 @@ SCDConsoleUserSet(const char *user, uid_t uid, gid_t gid)
        CFDictionarySetValue(dict, kSCPropUsersConsoleUserGID, num);
        CFRelease(num);
 
-       handle = SCDHandleInit();
-       SCDHandleSetData(handle, dict);
-
-       status = SCDLock(session);
-       if (status != SCD_OK) {
-               goto done;
-       }
-       (void)SCDRemove(session, key);
-       (void)SCDAdd   (session, key, handle);
-       status = SCDUnlock(session);
+       ok = SCDynamicStoreSetValue(mySession, key, dict);
 
     done :
 
-       if (dict)       CFRelease(dict);
-       if (handle)     SCDHandleRelease(handle);
-       if (key)        CFRelease(key);
-       if (session)    (void) SCDClose(&session);
-       return status;
+       if (dict)                       CFRelease(dict);
+       if (key)                        CFRelease(key);
+       if (!store && mySession)        CFRelease(mySession);
+       return ok;
 }
index e1647991c15aedd3e732fabaccedba0c259c0bd6..ded9eb569ed68752d31c882f952c6e79632a9742 100644 (file)
 #ifndef _SCDCONSOLEUSER_H
 #define _SCDCONSOLEUSER_H
 
-#include <sys/cdefs.h>
-
-/*!
-       @header SCDConsoleUser.h
-       The SystemConfiguration framework provides access to the data used
-               to configure a running system.
-
-       Specifically, the SCDConsoleUserXXX() API's allow an application
-               to determine (or set) the login/user currently using the
-               console.
-
-       The APIs provided by this framework communicate with the "configd"
-               daemon to obtain information regarding the systems current
-               configuration.
- */
-
-
-__BEGIN_DECLS
-
-/*!
-       @function SCDKeyCreateConsoleUser
-       @discussion Creates a key which can be used by the SCDNotifierAdd()
-               function to receive notifications when the current "Console"
-               user changes.
-       @result A notification string for the current "Console" user.
-*/
-CFStringRef    SCDKeyCreateConsoleUser ();
-
-/*!
-       @function SCDConsoleUserGet
-       @discussion Gets the name, user ID, and group ID of the currently
-               logged in user.
-       @param user A pointer to a character buffer of at least size
-               userlen. The returned name is null-terminated unless
-               in-sufficient space is provided.If NULL, this value
-               will not be returned.
-       @param userlen Pass an integer specifying the maximum size of the
-               user buffer.
-       @param uid A pointer to memory which will be filled with the user ID
-               of the current "Console" user. If NULL, this value will not
-               be returned.
-       @param gid A pointer to memory which will be filled with the group ID
-               of the current "Console" user. If NULL, this value will not be
-               returned.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDConsoleUserGet       (char           *user,
-                                        int            userlen,
-                                        uid_t          *uid,
-                                        gid_t          *gid);
-
-/*!
-       @function SCDConsoleUserSet
-       @discussion Sets the name, user ID, and group ID of the currently
-               logged in user.
-       @param user A pointer to a character buffer containing the name of
-               the current "Console" user. If NULL, any current "Console"
-               user information will be reset.
-       @param uid The user ID of the current "Console" user.
-       @param gid The group ID of the current "Console" user.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-        the call.
- */
-SCDStatus      SCDConsoleUserSet       (const char     *user,
-                                        uid_t          uid,
-                                        gid_t          gid);
-
-__END_DECLS
+#ifndef _SYSTEMCONFIGURATION_H
+#warning Your code has directly included the (old) <SystemConfiguration/SCDConsoleUser.h>
+#warning header file.  Please dont do that.  Use the top-level header file:
+#warning
+#warning   <SystemConfiguration/SystemConfiguration.h>
+#warning
+#warning Note: the console user access APIs have been moved out of
+#warning       the SCDConsoleUser.h header file.
+#include <SystemConfiguration/SystemConfiguration.h>    /* ...and try to keep everyone happy */
+#endif
 
 #endif /* _SCDCONSOLEUSER_H */
index d59a46aa28b1777bee287773ae01d66ac7016a4f..7cccb61e36fc18072b48d773aa195aed4320d66e 100644 (file)
  * @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 <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
 
 
-SCDStatus
-SCDGet(SCDSessionRef session, CFStringRef key, SCDHandleRef *handle)
+CFDictionaryRef
+SCDynamicStoreCopyMultiple(SCDynamicStoreRef   store,
+                          CFArrayRef           keys,
+                          CFArrayRef           patterns)
+{
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlKeys         = NULL; /* keys (XML serialized) */
+       xmlData_t                       myKeysRef       = NULL; /* keys (serialized) */
+       CFIndex                         myKeysLen       = 0;
+       CFDataRef                       xmlPatterns     = NULL; /* patterns (XML serialized) */
+       xmlData_t                       myPatternsRef   = NULL; /* patterns (serialized) */
+       CFIndex                         myPatternsLen   = 0;
+       xmlDataOut_t                    xmlDictRef;             /* dict (serialized) */
+       CFIndex                         xmlDictLen;
+       CFDataRef                       xmlDict;                /* dict (XML serialized) */
+       CFDictionaryRef                 dict;                   /* dict (un-serialized) */
+       int                             sc_status;
+       CFStringRef                     xmlError;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreCopyMultiple:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  keys     = %@"), keys);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  patterns = %@"), patterns);
+
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return NULL;
+       }
+
+       if (storePrivate->server == MACH_PORT_NULL) {
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return NULL;    /* you must have an open session to play */
+       }
+
+       /* serialize the keys */
+       if (keys) {
+               xmlKeys = CFPropertyListCreateXMLData(NULL, keys);
+               myKeysRef = (xmlData_t)CFDataGetBytePtr(xmlKeys);
+               myKeysLen = CFDataGetLength(xmlKeys);
+       }
+
+       /* serialize the patterns */
+       if (patterns) {
+               xmlPatterns = CFPropertyListCreateXMLData(NULL, patterns);
+               myPatternsRef = (xmlData_t)CFDataGetBytePtr(xmlPatterns);
+               myPatternsLen = CFDataGetLength(xmlPatterns);
+       }
+
+       /* send the keys and patterns, fetch the associated result from the server */
+       status = configget_m(storePrivate->server,
+                            myKeysRef,
+                            myKeysLen,
+                            myPatternsRef,
+                            myPatternsLen,
+                            &xmlDictRef,
+                            (int *)&xmlDictLen,
+                            (int *)&sc_status);
+
+       /* clean up */
+       if (xmlKeys)            CFRelease(xmlKeys);
+       if (xmlPatterns)        CFRelease(xmlPatterns);
+
+       if (status != KERN_SUCCESS) {
+               if (status != MACH_SEND_INVALID_DEST)
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configget_m(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return NULL;
+       }
+
+       if (sc_status != kSCStatusOK) {
+               status = vm_deallocate(mach_task_self(), (vm_address_t)xmlDictRef, xmlDictLen);
+               if (status != KERN_SUCCESS) {
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+                       /* non-fatal???, proceed */
+               }
+               _SCErrorSet(sc_status);
+               return NULL;
+       }
+
+       /* un-serialize the dict, return a value associated with the key */
+       xmlDict = CFDataCreate(NULL, xmlDictRef, xmlDictLen);
+       status = vm_deallocate(mach_task_self(), (vm_address_t)xmlDictRef, xmlDictLen);
+       if (status != KERN_SUCCESS) {
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+               /* non-fatal???, proceed */
+       }
+       dict = CFPropertyListCreateFromXMLData(NULL,
+                                              xmlDict,
+                                              kCFPropertyListImmutable,
+                                              &xmlError);
+       CFRelease(xmlDict);
+       if (!dict) {
+               if (xmlError) {
+                       SCLog(_sc_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() dict: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               _SCErrorSet(kSCStatusFailed);
+               return NULL;
+       }
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  value    = %@"), dict);
+
+       return dict;
+}
+
+
+CFPropertyListRef
+SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       CFDataRef               xmlKey;         /* key (XML serialized) */
-       xmlData_t               myKeyRef;       /* key (serialized) */
-       CFIndex                 myKeyLen;
-       xmlDataOut_t            xmlDataRef;     /* data (serialized) */
-       CFIndex                 xmlDataLen;
-       CFDataRef               xmlData;        /* data (XML serialized) */
-       CFPropertyListRef       data;           /* data (un-serialized) */
-       int                     newInstance;
-       SCDStatus               scd_status;
-       CFStringRef             xmlError;
-
-       SCDLog(LOG_DEBUG, CFSTR("SCDGet:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key      = %@"), key);
-
-       if (key == NULL) {
-               return SCD_INVALIDARGUMENT;     /* no key specified */
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlKey;         /* key (XML serialized) */
+       xmlData_t                       myKeyRef;       /* key (serialized) */
+       CFIndex                         myKeyLen;
+       xmlDataOut_t                    xmlDataRef;     /* data (serialized) */
+       CFIndex                         xmlDataLen;
+       CFDataRef                       xmlData;        /* data (XML serialized) */
+       CFPropertyListRef               data;           /* data (un-serialized) */
+       int                             newInstance;
+       int                             sc_status;
+       CFStringRef                     xmlError;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreCopyValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key      = %@"), key);
+
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return NULL;
        }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;
+       if (storePrivate->server == MACH_PORT_NULL) {
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return NULL;    /* you must have an open session to play */
        }
 
        /* serialize the key */
@@ -61,41 +186,41 @@ SCDGet(SCDSessionRef session, CFStringRef key, SCDHandleRef *handle)
        myKeyLen = CFDataGetLength(xmlKey);
 
        /* send the key & fetch the associated data from the server */
-       status = configget(sessionPrivate->server,
+       status = configget(storePrivate->server,
                           myKeyRef,
                           myKeyLen,
                           &xmlDataRef,
                           (int *)&xmlDataLen,
                           &newInstance,
-                          (int *)&scd_status);
+                          (int *)&sc_status);
 
        /* clean up */
        CFRelease(xmlKey);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("configget(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configget(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return NULL;
        }
 
-       if (scd_status != SCD_OK) {
+       if (sc_status != kSCStatusOK) {
                status = vm_deallocate(mach_task_self(), (vm_address_t)xmlDataRef, xmlDataLen);
                if (status != KERN_SUCCESS) {
-                       SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                        /* non-fatal???, proceed */
                }
-               *handle = NULL;
-               return scd_status;
+               _SCErrorSet(sc_status);
+               return NULL;
        }
 
-       /* un-serialize the data, return a handle associated with the key */
-       *handle = SCDHandleInit();
+       /* un-serialize the data, return a value associated with the key */
        xmlData = CFDataCreate(NULL, xmlDataRef, xmlDataLen);
        status = vm_deallocate(mach_task_self(), (vm_address_t)xmlDataRef, xmlDataLen);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        data = CFPropertyListCreateFromXMLData(NULL,
@@ -103,18 +228,18 @@ SCDGet(SCDSessionRef session, CFStringRef key, SCDHandleRef *handle)
                                               kCFPropertyListImmutable,
                                               &xmlError);
        CFRelease(xmlData);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() data: %s"), xmlError);
-               SCDHandleRelease(*handle);
-               return SCD_FAILED;
+       if (!data) {
+               if (xmlError) {
+                       SCLog(_sc_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() data: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               _SCErrorSet(kSCStatusFailed);
+               return NULL;
        }
-       SCDHandleSetData(*handle, data);
-       CFRelease(data);
-
-       _SCDHandleSetInstance(*handle, newInstance);
 
-       SCDLog(LOG_DEBUG, CFSTR("  data     = %@"), SCDHandleGetData(*handle));
-       SCDLog(LOG_DEBUG, CFSTR("  instance = %d"), SCDHandleGetInstance(*handle));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  value    = %@"), data);
 
-       return scd_status;
+       return data;
 }
diff --git a/SystemConfiguration.fproj/SCDHandle.c b/SystemConfiguration.fproj/SCDHandle.c
deleted file mode 100644 (file)
index 5e4ab8e..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (c) 2000 Apple Computer, 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 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.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <SystemConfiguration/SCD.h>
-#include "SCDPrivate.h"
-
-
-SCDHandleRef
-SCDHandleInit()
-{
-       SCDHandlePrivateRef privateHandle = CFAllocatorAllocate(NULL, sizeof(SCDHandlePrivate), 0);
-
-       /* set data */
-       privateHandle->data = NULL;
-
-       /* set instance */
-       privateHandle->instance = 0;
-
-       return (SCDHandleRef)privateHandle;
-}
-
-
-void
-SCDHandleRelease(SCDHandleRef handle)
-{
-       SCDHandlePrivateRef privateHandle = (SCDHandlePrivateRef)handle;
-
-       if (privateHandle->data)
-               CFRelease(privateHandle->data);
-
-       CFAllocatorDeallocate(NULL, privateHandle);
-       return;
-}
-
-
-int
-SCDHandleGetInstance(SCDHandleRef handle)
-{
-       SCDHandlePrivateRef privateHandle = (SCDHandlePrivateRef)handle;
-
-       return privateHandle->instance;
-}
-
-
-void
-_SCDHandleSetInstance(SCDHandleRef handle, int instance)
-{
-       SCDHandlePrivateRef privateHandle = (SCDHandlePrivateRef)handle;
-
-       privateHandle->instance = instance;
-       return;
-}
-
-
-CFPropertyListRef
-SCDHandleGetData(SCDHandleRef handle)
-{
-       SCDHandlePrivateRef privateHandle = (SCDHandlePrivateRef)handle;
-
-       if (privateHandle->data == NULL) {
-               return CFSTR("SCDHandleRef not initialized.");
-       }
-
-       return privateHandle->data;
-}
-
-
-void
-SCDHandleSetData(SCDHandleRef handle, CFPropertyListRef data)
-{
-       SCDHandlePrivateRef privateHandle = (SCDHandlePrivateRef)handle;
-
-       /* remove reference to data previously associated with handle */
-       if (privateHandle->data)
-               CFRelease(privateHandle->data);
-
-       /* associate new data with handle, keep a reference as needed */
-       privateHandle->data = data;
-       if (privateHandle->data)
-               CFRetain(privateHandle->data);
-
-       return;
-}
index c127f7f633c9b6ea1ca1e988fc0cce9593e42519..b4ad8264495278d244d77a58e082052069ba9225 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SystemConfiguration.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * January 8, 2001             Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCValidation.h>
+#include <SystemConfiguration/SCPrivate.h>
 
 CFStringRef
-SCDKeyCreateHostName()
+SCDynamicStoreKeyCreateComputerName(CFAllocatorRef allocator)
 {
-       return SCDKeyCreate(CFSTR("%@/%@"),
-                           kSCCacheDomainSetup,
-                           kSCCompSystem);
+       return SCDynamicStoreKeyCreate(allocator,
+                                      CFSTR("%@/%@"),
+                                      kSCDynamicStoreDomainSetup,
+                                      kSCCompSystem);
 }
 
 
-SCDStatus
-SCDHostNameGet(CFStringRef *name, CFStringEncoding *nameEncoding)
+CFStringRef
+SCDynamicStoreCopyComputerName(SCDynamicStoreRef       store,
+                              CFStringEncoding         *nameEncoding)
 {
-       CFDictionaryRef dict;
-       SCDHandleRef    handle  = NULL;
-       CFStringRef     key;
-       SCDSessionRef   session = NULL;
-       SCDStatus       status;
-
-       if (name == NULL) {
-               return SCD_FAILED;
-       }
+       CFDictionaryRef         dict            = NULL;
+       CFStringRef             key;
+       CFStringRef             name            = NULL;
+       SCDynamicStoreRef       mySession       = store;
 
-       /* get current user */
-       status = SCDOpen(&session, CFSTR("SCDHostNameGet"));
-       if (status != SCD_OK) {
-               goto done;
+       if (!store) {
+               mySession = SCDynamicStoreCreate(NULL,
+                                                CFSTR("SCDynamicStoreCopyComputerName"),
+                                                NULL,
+                                                NULL);
+               if (!mySession) {
+                       SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+                       return NULL;
+               }
        }
 
-       key = SCDKeyCreateHostName();
-       status = SCDGet(session, key, &handle);
+       key  = SCDynamicStoreKeyCreateComputerName(NULL);
+       dict = SCDynamicStoreCopyValue(mySession, key);
        CFRelease(key);
-       if (status != SCD_OK) {
+       if (!dict) {
+               goto done;
+       }
+       if (!isA_CFDictionary(dict)) {
+               _SCErrorSet(kSCStatusNoKey);
                goto done;
        }
 
-       dict = SCDHandleGetData(handle);
-
-       *name = CFDictionaryGetValue(dict, kSCPropSystemComputerName);
-       if (*name == NULL) {
+       name = isA_CFString(CFDictionaryGetValue(dict, kSCPropSystemComputerName));
+       if (!name) {
+               _SCErrorSet(kSCStatusNoKey);
                goto done;
        }
-       CFRetain(*name);
+       CFRetain(name);
 
        if (nameEncoding) {
                CFNumberRef     num;
 
                num = CFDictionaryGetValue(dict,
                                           kSCPropSystemComputerNameEncoding);
-               if (num) {
+               if (isA_CFNumber(num)) {
                        CFNumberGetValue(num, kCFNumberIntType, nameEncoding);
                } else {
                        *nameEncoding = CFStringGetSystemEncoding();
@@ -80,7 +96,57 @@ SCDHostNameGet(CFStringRef *name, CFStringEncoding *nameEncoding)
 
     done :
 
-       if (handle)     SCDHandleRelease(handle);
-       if (session)    (void) SCDClose(&session);
-       return status;
+       if (!store && mySession)        CFRelease(mySession);
+       if (dict)                       CFRelease(dict);
+       return name;
+}
+
+
+Boolean
+SCPreferencesSetComputerName(SCPreferencesRef  session,
+                            CFStringRef        name,
+                            CFStringEncoding   encoding)
+{
+       CFDictionaryRef         dict;
+       CFMutableDictionaryRef  newDict = NULL;
+       CFNumberRef             num;
+       Boolean                 ok      = FALSE;
+       CFStringRef             path    = NULL;
+
+       if (CFGetTypeID(name) != CFStringGetTypeID()) {
+               _SCErrorSet(kSCStatusInvalidArgument);
+               return FALSE;
+       }
+
+       path = CFStringCreateWithFormat(NULL,
+                                       NULL,
+                                       CFSTR("/%@/%@"),
+                                       kSCPrefSystem,
+                                       kSCCompSystem);
+
+       dict = SCPreferencesPathGetValue(session, path);
+       if (dict) {
+               newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
+       } else {
+               newDict = CFDictionaryCreateMutable(NULL,
+                                                   0,
+                                                   &kCFTypeDictionaryKeyCallBacks,
+                                                   &kCFTypeDictionaryValueCallBacks);
+       }
+
+       CFDictionarySetValue(newDict, kSCPropSystemComputerName, name);
+
+       num = CFNumberCreate(NULL, kCFNumberIntType, &encoding);
+       CFDictionarySetValue(newDict, kSCPropSystemComputerNameEncoding, num);
+       CFRelease(num);
+
+       ok = SCPreferencesPathSetValue(session, path, newDict);
+       if (!ok) {
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("SCPreferencesPathSetValue() failed"));
+       }
+
+       if (path)       CFRelease(path);
+       if (newDict)    CFRelease(newDict);
+
+       return ok;
 }
index 2ce1cadd868e6c395227b2980eb9a6cc447aea8f..ac0440a500d8b8933521543db96763e60f479338 100644 (file)
 #ifndef _SCDHOSTNAME_H
 #define _SCDHOSTNAME_H
 
-#include <sys/cdefs.h>
-
-/*!
-       @header SCDHostName.h
-       The SystemConfiguration framework provides access to the data used
-               to configure a running system.
-
-       Specifically, the SCDHostNameXXX() API's allow an application
-               to determine (or set) the login/user currently using the
-               console.
-
-       The APIs provided by this framework communicate with the "configd"
-               daemon to obtain information regarding the systems current
-               configuration.
- */
-
-
-__BEGIN_DECLS
-
-/*!
-       @function SCDKeyCreateHostName
-       @discussion Creates a key which can be used by the SCDNotifierAdd()
-               function to receive notifications when the current
-               computer/host name changes.
-       @result A notification string for the current computer/host name".
-*/
-CFStringRef    SCDKeyCreateHostName    ();
-
-/*!
-       @function SCDHostNameGet
-       @discussion Gets the current computer/host name.
-       @param name A pointer to memory which will be filled with the current
-               computer/host name.
-       @param nameEncoding A pointer to memory which, if non-NULL, will be
-               filled with the encoding associated with the computer/host name.
-       @result A constant of type SCDStatus indicating the success (or failure) of
-               the call.
- */
-SCDStatus      SCDHostNameGet          (CFStringRef            *name,
-                                        CFStringEncoding       *nameEncoding);
-
-__END_DECLS
+#ifndef _SYSTEMCONFIGURATION_H
+#warning Your code has directly included the (old) <SystemConfiguration/SCDHostName.h>
+#warning header file.  Please dont do that.  Use the top-level header file:
+#warning
+#warning   <SystemConfiguration/SystemConfiguration.h>
+#warning 
+#warning Note: the computer name access APIs have been moved out of
+#warning       the SCDHostName.h header file.
+
+#include <SystemConfiguration/SystemConfiguration.h>    /* ...and try to keep everyone happy */
+#endif
 
 #endif /* _SCDHOSTNAME_H */
index e2a51c764f4944275eed59f816a3ac6b7bb3dee2..1070ba43f7580f0c5950293733bd9d5f8dd2dd2e 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * December 11, 2000           Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <SystemConfiguration/SystemConfiguration.h>
 
 #include <stdarg.h>
 
 /*
- * SCDKeyCreate*
- * - convenience routines that create a CFString key for an item in the cache
+ * SCDynamicStoreKeyCreate*
+ * - convenience routines that create a CFString key for an item in the store
  */
 
 /*
- * Function: SCDKeyCreate
+ * Function: SCDynamicStoreKeyCreate
  * Purpose:
- *    Creates a cache key using the given format.
+ *    Creates a store key using the given format.
  */
 CFStringRef
-SCDKeyCreate(CFStringRef fmt, ...)
+SCDynamicStoreKeyCreate(CFAllocatorRef allocator,
+                       CFStringRef     fmt,
+                       ...)
 {
        va_list args;
        va_start(args, fmt);
-       return (CFStringCreateWithFormatAndArguments(NULL,
+       return (CFStringCreateWithFormatAndArguments(allocator,
                                                     NULL,
                                                     fmt,
                                                     args));
 }
 
 CFStringRef
-SCDKeyCreateNetworkGlobalEntity(CFStringRef domain, CFStringRef entity)
+SCDynamicStoreKeyCreateNetworkGlobalEntity(CFAllocatorRef      allocator,
+                                          CFStringRef          domain,
+                                          CFStringRef          entity)
 {
-       return (CFStringCreateWithFormat(NULL,
+       return (CFStringCreateWithFormat(allocator,
                                         NULL,
                                         CFSTR("%@/%@/%@/%@"),
                                         domain,
@@ -58,9 +72,10 @@ SCDKeyCreateNetworkGlobalEntity(CFStringRef domain, CFStringRef entity)
 }
 
 CFStringRef
-SCDKeyCreateNetworkInterface(CFStringRef domain)
+SCDynamicStoreKeyCreateNetworkInterface(CFAllocatorRef allocator,
+                                       CFStringRef     domain)
 {
-       return (CFStringCreateWithFormat(NULL,
+       return (CFStringCreateWithFormat(allocator,
                                         NULL,
                                         CFSTR("%@/%@/%@"),
                                         domain,
@@ -69,12 +84,13 @@ SCDKeyCreateNetworkInterface(CFStringRef domain)
 }
 
 CFStringRef
-SCDKeyCreateNetworkInterfaceEntity(CFStringRef domain,
-                                  CFStringRef ifname,
-                                  CFStringRef entity)
+SCDynamicStoreKeyCreateNetworkInterfaceEntity(CFAllocatorRef   allocator,
+                                             CFStringRef       domain,
+                                             CFStringRef       ifname,
+                                             CFStringRef       entity)
 {
        if (entity == NULL) {
-               return (CFStringCreateWithFormat(NULL,
+               return (CFStringCreateWithFormat(allocator,
                                                 NULL,
                                                 CFSTR("%@/%@/%@/%@"),
                                                 domain,
@@ -82,7 +98,7 @@ SCDKeyCreateNetworkInterfaceEntity(CFStringRef domain,
                                                 kSCCompInterface,
                                                 ifname));
        } else {
-               return (CFStringCreateWithFormat(NULL,
+               return (CFStringCreateWithFormat(allocator,
                                                 NULL,
                                                 CFSTR("%@/%@/%@/%@/%@"),
                                                 domain,
@@ -94,12 +110,13 @@ SCDKeyCreateNetworkInterfaceEntity(CFStringRef domain,
 }
 
 CFStringRef
-SCDKeyCreateNetworkServiceEntity(CFStringRef domain,
-                                CFStringRef serviceID,
-                                CFStringRef entity)
+SCDynamicStoreKeyCreateNetworkServiceEntity(CFAllocatorRef     allocator,
+                                           CFStringRef         domain,
+                                           CFStringRef         serviceID,
+                                           CFStringRef         entity)
 {
        if (entity == NULL) {
-               return (CFStringCreateWithFormat(NULL,
+               return (CFStringCreateWithFormat(allocator,
                                                 NULL,
                                                 CFSTR("%@/%@/%@/%@"),
                                                 domain,
@@ -107,7 +124,7 @@ SCDKeyCreateNetworkServiceEntity(CFStringRef domain,
                                                 kSCCompService,
                                                 serviceID));
        } else {
-               return (CFStringCreateWithFormat(NULL,
+               return (CFStringCreateWithFormat(allocator,
                                                 NULL,
                                                 CFSTR("%@/%@/%@/%@/%@"),
                                                 domain,
index 4c1f2b611fbb21e27ad2267c9ef0356bc96f9f4b..b2ee9d7718c7243d7c20e660de0c997d46ff948c 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-/*
- * SCDKeys.h
- */
-
 #ifndef _SCDKEYS_H
 #define _SCDKEYS_H
 
-#include <CoreFoundation/CoreFoundation.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-
-/*
- * SCDKeyCreate*
- * - convenience routines that create a CFString key for an item in the cache
- */
-
-/*
- * Function: SCDKeyCreate
- * Purpose:
- *    Creates a cache key using the given format.
- */
-CFStringRef    SCDKeyCreate                            (CFStringRef    fmt,
-                                                        ...);
-
-CFStringRef    SCDKeyCreateNetworkGlobalEntity         (CFStringRef    domain,
-                                                        CFStringRef    entity);
-
-CFStringRef    SCDKeyCreateNetworkInterface            (CFStringRef    domain);
-
-CFStringRef    SCDKeyCreateNetworkInterfaceEntity      (CFStringRef    domain,
-                                                        CFStringRef    ifname,
-                                                        CFStringRef    entity);
-
-CFStringRef    SCDKeyCreateNetworkServiceEntity        (CFStringRef    domain,
-                                                        CFStringRef    serviceID,
-                                                        CFStringRef    entity);
-
-__END_DECLS
+#ifndef _SYSTEMCONFIGURATION_H
+#warning Your code has directly included the (old) <SystemConfiguration/SCDKeys.h>
+#warning header file.  Please dont do that.  Use the top-level header file:
+#warning
+#warning   <SystemConfiguration/SystemConfiguration.h>
+#warning
+#warning Note: the dynamic store key creation APIs have been moved out of
+#warning       the SCDKeys.h header file.
+#include <SystemConfiguration/SystemConfiguration.h>    /* ...and try to keep everyone happy */
+#endif
 
 #endif /* _SCDKEYS_H */
index 1efabf3a923de9c46b6017808600ec781f78a14e..85055cd38e3ed46cebcdf84ff0ca49024ded8240 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <sys/types.h>
-#include <regex.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 24, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
-
-
-static CFComparisonResult
-sort_keys(const void *p1, const void *p2, void *context) {
-       CFStringRef key1 = (CFStringRef)p1;
-       CFStringRef key2 = (CFStringRef)p2;
-       return CFStringCompare(key1, key2, 0);
-}
-
 
-SCDStatus
-SCDList(SCDSessionRef session, CFStringRef key, int regexOptions, CFArrayRef *subKeys)
+CFArrayRef
+SCDynamicStoreCopyKeyList(SCDynamicStoreRef store, CFStringRef pattern)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       CFDataRef               xmlKey;         /* serialized key */
-       xmlData_t               myKeyRef;
-       CFIndex                 myKeyLen;
-       CFDataRef               xmlData;        /* data (XML serialized) */
-       xmlDataOut_t            xmlDataRef;     /* serialized data */
-       int                     xmlDataLen;
-       SCDStatus               scd_status;
-       CFArrayRef              allKeys;
-       CFMutableArrayRef       sortedKeys;
-       CFStringRef             xmlError;
-
-       SCDLog(LOG_DEBUG, CFSTR("SCDList:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key          = %@"), key);
-       SCDLog(LOG_DEBUG, CFSTR("  regexOptions = %0o"), regexOptions);
-
-       if (key == NULL) {
-               return SCD_INVALIDARGUMENT;     /* no key specified */
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlPattern;     /* serialized pattern */
+       xmlData_t                       myPatternRef;
+       CFIndex                         myPatternLen;
+       CFDataRef                       xmlData;        /* data (XML serialized) */
+       xmlDataOut_t                    xmlDataRef;     /* serialized data */
+       int                             xmlDataLen;
+       int                             sc_status;
+       CFArrayRef                      allKeys;
+       CFStringRef                     xmlError;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreCopyKeyList:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  pattern = %@"), pattern);
+
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return NULL;
        }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;
+       if (storePrivate->server == MACH_PORT_NULL) {
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return NULL;
        }
 
-       /* serialize the key */
-       xmlKey = CFPropertyListCreateXMLData(NULL, key);
-       myKeyRef = (xmlData_t)CFDataGetBytePtr(xmlKey);
-       myKeyLen = CFDataGetLength(xmlKey);
+       /* serialize the pattern */
+       xmlPattern = CFPropertyListCreateXMLData(NULL, pattern);
+       myPatternRef = (xmlData_t)CFDataGetBytePtr(xmlPattern);
+       myPatternLen = CFDataGetLength(xmlPattern);
 
-       /* send the key & fetch the associated data from the server */
-       status = configlist(sessionPrivate->server,
-                           myKeyRef,
-                           myKeyLen,
-                           regexOptions,
+       /* send the pattern & fetch the associated data from the server */
+       status = configlist(storePrivate->server,
+                           myPatternRef,
+                           myPatternLen,
+                           TRUE,               /* isRegex == TRUE */
                            &xmlDataRef,
                            &xmlDataLen,
-                           (int *)&scd_status);
+                           (int *)&sc_status);
 
        /* clean up */
-       CFRelease(xmlKey);
+       CFRelease(xmlPattern);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("configlist(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configlist(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return NULL;
        }
 
-       if (scd_status != SCD_OK) {
+       if (sc_status != kSCStatusOK) {
                status = vm_deallocate(mach_task_self(), (vm_address_t)xmlDataRef, xmlDataLen);
                if (status != KERN_SUCCESS) {
-                       SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                        /* non-fatal???, proceed */
                }
-               *subKeys = NULL;
-               return scd_status;
+               _SCErrorSet(sc_status);
+               return NULL;
        }
 
        /* un-serialize the list of keys */
        xmlData = CFDataCreate(NULL, xmlDataRef, xmlDataLen);
        status = vm_deallocate(mach_task_self(), (vm_address_t)xmlDataRef, xmlDataLen);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        allKeys = CFPropertyListCreateFromXMLData(NULL,
@@ -114,19 +115,16 @@ SCDList(SCDSessionRef session, CFStringRef key, int regexOptions, CFArrayRef *su
                                                  kCFPropertyListImmutable,
                                                  &xmlError);
        CFRelease(xmlData);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() list: %s"), xmlError);
-               return SCD_FAILED;
+       if (!allKeys) {
+               if (xmlError) {
+                       SCLog(_sc_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() list: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               _SCErrorSet(kSCStatusFailed);
+               return NULL;
        }
 
-       myKeyLen = CFArrayGetCount(allKeys);
-       sortedKeys = CFArrayCreateMutableCopy(NULL, myKeyLen, allKeys);
-       CFRelease(allKeys);
-       CFArraySortValues(sortedKeys,
-                         CFRangeMake(0, myKeyLen),
-                         sort_keys,
-                         NULL);
-
-       *subKeys = sortedKeys;
-       return scd_status;
+       return allKeys;
 }
index ff1a1d4ce700ffc3a4ecb798b6ea8605bbad94e4..227c583087f6214dd30774f96802e506d2b9fe67 100644 (file)
  * @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 <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
 
-
-SCDStatus
-SCDLock(SCDSessionRef session)
+Boolean
+SCDynamicStoreLock(SCDynamicStoreRef store)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       SCDStatus               scd_status;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       int                             sc_status;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreLock:"));
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDLock:"));
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
+       }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;   /* you must have an open session to play */
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
        /* get the lock from the server */
-       status = configlock(sessionPrivate->server, (int *)&scd_status);
+       status = configlock(storePrivate->server, (int *)&sc_status);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("configlock(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configlock(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
+       }
+
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
-       return scd_status;
+       return TRUE;
 }
index 689cb2e357c9c2f9f31382d404ced2f56e779b14..392ca2748d7491e81f21bcd7d31d0752b8889085 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <sys/types.h>
-#include <regex.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 24, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
 
-
-SCDStatus
-SCDNotifierAdd(SCDSessionRef session, CFStringRef key, int regexOptions)
+Boolean
+SCDynamicStoreAddWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       CFDataRef               xmlKey;         /* serialized key */
-       xmlData_t               myKeyRef;
-       CFIndex                 myKeyLen;
-       SCDStatus               scd_status;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlKey;         /* serialized key */
+       xmlData_t                       myKeyRef;
+       CFIndex                         myKeyLen;
+       int                             sc_status;
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDNotifierAdd:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key          = %@"), key);
-       SCDLog(LOG_DEBUG, CFSTR("  regexOptions = %0o"), regexOptions);
+       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 (key == NULL) {
-               return SCD_INVALIDARGUMENT;     /* no key specified */
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
        }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
        /*
         * add new key after checking if key has already been defined
         */
-       if (regexOptions & kSCDRegexKey) {
-               if (CFSetContainsValue(sessionPrivate->reKeys, key))
-                       return SCD_EXISTS;              /* sorry, key already exists in notifier list */
-               CFSetAddValue(sessionPrivate->reKeys, key);     /* add key to this sessions notifier list */
+       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(sessionPrivate->keys, key))
-                       return SCD_EXISTS;              /* sorry, key already exists in notifier list */
-               CFSetAddValue(sessionPrivate->keys, key);       /* add key to this sessions notifier list */
+               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 */
@@ -72,22 +89,28 @@ SCDNotifierAdd(SCDSessionRef session, CFStringRef key, int regexOptions)
        myKeyLen = CFDataGetLength(xmlKey);
 
        /* send the key & data to the server */
-       status = notifyadd(sessionPrivate->server,
+       status = notifyadd(storePrivate->server,
                           myKeyRef,
                           myKeyLen,
-                          regexOptions,
-                          (int *)&scd_status);
+                          isRegex,
+                          (int *)&sc_status);
 
        /* clean up */
        CFRelease(xmlKey);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("notifyadd(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       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 (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
-       return scd_status;
+       return TRUE;
 }
index 3ee6d14a363acff1d3da96cd0a4503628deded49..e1a236b35dee651432df89b8f3de4c636c178bd7 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 31, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
-
 
-SCDStatus
-SCDNotifierCancel(SCDSessionRef session)
+Boolean
+SCDynamicStoreNotifyCancel(SCDynamicStoreRef store)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       SCDStatus               scd_status;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       int                             sc_status;
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDNotifierCancel:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreNotifyCancel:"));
 
-       if (session == NULL) {
-               return SCD_NOSESSION;           /* you can't do anything without a session */
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
        }
 
-       if (sessionPrivate->notifyStatus == NotifierNotRegistered) {
-               /* nothing to do, no notifications have been registered */
-               return SCD_OK;
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
-       /*  if SCDNotifierInformViaCallback() active, stop the background thread  */
-       if (sessionPrivate->callbackFunction != NULL) {
-
-               if (SCDOptionGet(session, kSCDOptionUseCFRunLoop)) {
-                       SCDLog(LOG_DEBUG, CFSTR("  cancel callback runloop source"));
-
-                       /* XXX invalidating the port is not sufficient, remove the run loop source */
-                       CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
-                                             sessionPrivate->callbackRunLoopSource,
+       switch (storePrivate->notifyStatus) {
+               case NotifierNotRegistered :
+                       /* if no notifications have been registered */
+                       return TRUE;
+               case Using_NotifierInformViaRunLoop :
+                       /* once activated, a RunLoop notifier cannot be cancelled */
+                       _SCErrorSet(kSCStatusNotifierActive);
+                       return FALSE;
+               case Using_NotifierInformViaCallback :
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  cancel callback runloop source"));
+
+                       /* remove the run loop source */
+                       CFRunLoopRemoveSource(storePrivate->callbackRunLoop,
+                                             storePrivate->callbackRunLoopSource,
                                              kCFRunLoopDefaultMode);
-                       CFRelease(sessionPrivate->callbackRunLoopSource);
+                       CFRelease(storePrivate->callbackRunLoopSource);
 
                        /* invalidate port */
-                       CFMachPortInvalidate(sessionPrivate->callbackPort);
-                       CFRelease(sessionPrivate->callbackPort);
-               } else {
-                       int             ts;
-
-                       SCDLog(LOG_DEBUG, CFSTR("  cancel callback thread"));
-                       ts = pthread_cancel(sessionPrivate->callbackHelper);
-                       if (ts != 0) {
-                               SCDLog(LOG_DEBUG, CFSTR("  pthread_cancel(): %s"), strerror(ts));
-                       }
-               }
-
-               sessionPrivate->callbackFunction        = NULL;
-               sessionPrivate->callbackArgument        = NULL;
-               sessionPrivate->callbackPort            = NULL;
-               sessionPrivate->callbackRunLoopSource   = NULL; /* XXX */
-               sessionPrivate->callbackHelper          = NULL;
-       }
-
-       if (sessionPrivate->server == MACH_PORT_NULL) {
-               return SCD_NOSESSION;           /* you must have an open session to play */
+                       CFMachPortInvalidate(storePrivate->callbackPort);
+                       CFRelease(storePrivate->callbackPort);
+
+                       storePrivate->callbackArgument          = NULL;
+                       storePrivate->callbackFunction          = NULL;
+                       storePrivate->callbackRunLoop           = NULL;
+                       storePrivate->callbackRunLoopSource     = NULL;
+                       storePrivate->callbackPort              = NULL;
+                       break;
+               default :
+                       break;
        }
 
-       status = notifycancel(sessionPrivate->server, (int *)&scd_status);
+       status = notifycancel(storePrivate->server, (int *)&sc_status);
 
        /* set notifier inactive */
-       sessionPrivate->notifyStatus = NotifierNotRegistered;
+       storePrivate->notifyStatus = NotifierNotRegistered;
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("notifycancel(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifycancel(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
+       }
+
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
-       return scd_status;
+       return TRUE;
 }
index 1fbf028191405e7017b4098ff9f168ebce764822..71ecfb24d91242ea8a04e7dfbe84069c467f3a32 100644 (file)
  * @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 <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
-
 
-static CFComparisonResult
-sort_keys(const void *p1, const void *p2, void *context) {
-       CFStringRef key1 = (CFStringRef)p1;
-       CFStringRef key2 = (CFStringRef)p2;
-       return CFStringCompare(key1, key2, 0);
-}
-
-
-SCDStatus
-SCDNotifierGetChanges(SCDSessionRef session, CFArrayRef *notifierKeys)
+CFArrayRef
+SCDynamicStoreCopyNotifiedKeys(SCDynamicStoreRef store)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       CFDataRef               xmlData;        /* data (XML serialized) */
-       xmlDataOut_t            xmlDataRef;     /* serialized data */
-       int                     xmlDataLen;
-       SCDStatus               scd_status;
-       CFArrayRef              allKeys;
-       CFStringRef             xmlError;
-       CFIndex                 keyCnt;
-       CFMutableArrayRef       sortedKeys;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlData;        /* data (XML serialized) */
+       xmlDataOut_t                    xmlDataRef;     /* serialized data */
+       int                             xmlDataLen;
+       int                             sc_status;
+       CFArrayRef                      allKeys;
+       CFStringRef                     xmlError;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreCopyNotifiedKeys:"));
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDNotifierGetChanges:"));
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return NULL;
+       }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;
+       if (storePrivate->server == MACH_PORT_NULL) {
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return NULL;
        }
 
        /* send the key & fetch the associated data from the server */
-       status = notifychanges(sessionPrivate->server,
+       status = notifychanges(storePrivate->server,
                               &xmlDataRef,
                               &xmlDataLen,
-                              (int *)&scd_status);
+                              (int *)&sc_status);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("notifychanges(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifychanges(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return NULL;
        }
 
-       if (scd_status != SCD_OK) {
+       if (sc_status != kSCStatusOK) {
                status = vm_deallocate(mach_task_self(), (vm_address_t)xmlDataRef, xmlDataLen);
                if (status != KERN_SUCCESS) {
-                       SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                        /* non-fatal???, proceed */
                }
-               *notifierKeys = NULL;
-               return scd_status;
+               _SCErrorSet(sc_status);
+               return NULL;
        }
 
        /* un-serialize the list of keys which have changed */
        xmlData = CFDataCreate(NULL, xmlDataRef, xmlDataLen);
        status = vm_deallocate(mach_task_self(), (vm_address_t)xmlDataRef, xmlDataLen);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        allKeys = CFPropertyListCreateFromXMLData(NULL,
@@ -92,19 +100,16 @@ SCDNotifierGetChanges(SCDSessionRef session, CFArrayRef *notifierKeys)
                                                  kCFPropertyListImmutable,
                                                  &xmlError);
        CFRelease(xmlData);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() list: %s"), xmlError);
-               return SCD_FAILED;
+       if (!allKeys) {
+               if (xmlError) {
+                       SCLog(_sc_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() list: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               _SCErrorSet(kSCStatusFailed);
+               return NULL;
        }
 
-       keyCnt = CFArrayGetCount(allKeys);
-       sortedKeys = CFArrayCreateMutableCopy(NULL, keyCnt, allKeys);
-       CFRelease(allKeys);
-       CFArraySortValues(sortedKeys,
-                         CFRangeMake(0, keyCnt),
-                         sort_keys,
-                         NULL);
-
-       *notifierKeys = sortedKeys;
-       return scd_status;
+       return allKeys;
 }
index 481d5b1e62d3dea93868fe4346aa5dee86e9e97c..9b1cf56f3ad09c5cccd073aee3812249b7988ab7 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 31, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
 
+#include "v1Compatibility.h"
 
 static void
 informCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
 {
-       SCDSessionRef           session        = (SCDSessionRef)info;
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       mach_msg_empty_rcv_t    *buf           = msg;
-       mach_msg_id_t           msgid          = buf->header.msgh_id;
-       SCDCallbackRoutine_t    cbFunc         = sessionPrivate->callbackFunction;
-       void                    *cbArg         = sessionPrivate->callbackArgument;
+       SCDynamicStoreRef               store           = (SCDynamicStoreRef)info;
+       SCDynamicStorePrivateRef        storePrivate    = (SCDynamicStorePrivateRef)store;
+       mach_msg_empty_rcv_t            *buf            = msg;
+       mach_msg_id_t                   msgid           = buf->header.msgh_id;
+       SCDynamicStoreCallBack_v1       cbFunc          = storePrivate->callbackFunction;
+       void                            *cbArg          = storePrivate->callbackArgument;
 
        if (msgid == MACH_NOTIFY_NO_SENDERS) {
                /* the server died, disable additional callbacks */
-               SCDLog(LOG_DEBUG, CFSTR("  notifier port closed, disabling notifier"));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  notifier port closed, disabling notifier"));
        } else if (cbFunc == NULL) {
                /* there is no (longer) a callback function, disable additional callbacks */
-               SCDLog(LOG_DEBUG, CFSTR("  no callback function, disabling notifier"));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  no callback function, disabling notifier"));
        } else {
-               SCDLog(LOG_DEBUG, CFSTR("  executing notifiction function"));
-               if ((*cbFunc)(session, cbArg)) {
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  executing notifiction function"));
+               if ((*cbFunc)(store, cbArg)) {
                        /*
                         * callback function returned success.
                         */
                        return;
                } else {
-                       SCDLog(LOG_DEBUG, CFSTR("  callback returned error, disabling notifier"));
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  callback returned error, disabling notifier"));
                }
        }
 
 #ifdef DEBUG
-       if (port != sessionPrivate->callbackPort) {
-               SCDLog(LOG_DEBUG, CFSTR("informCallback, why is port != callbackPort?"));
+       if (port != storePrivate->callbackPort) {
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("informCallback, why is port != callbackPort?"));
        }
 #endif /* DEBUG */
 
-       /* we have encountered some type of error, disable additional callbacks */
-
-       /* XXX invalidating the port is not sufficient, remove the run loop source */
+       /* remove the run loop source */
        CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
-                             sessionPrivate->callbackRunLoopSource,
+                             storePrivate->callbackRunLoopSource,
                              kCFRunLoopDefaultMode);
-       CFRelease(sessionPrivate->callbackRunLoopSource);
+       CFRelease(storePrivate->callbackRunLoopSource);
 
        /* invalidate port */
-       CFMachPortInvalidate(port);
-       CFRelease(port);
+       CFMachPortInvalidate(storePrivate->callbackPort);
+       CFRelease(storePrivate->callbackPort);
 
-       sessionPrivate->notifyStatus            = NotifierNotRegistered;
-       sessionPrivate->callbackFunction        = NULL;
-       sessionPrivate->callbackArgument        = NULL;
-       sessionPrivate->callbackPort            = NULL;
-       sessionPrivate->callbackRunLoopSource   = NULL; /* XXX */
+       /* disable notifier */
+       storePrivate->notifyStatus              = NotifierNotRegistered;
+       storePrivate->callbackArgument          = NULL;
+       storePrivate->callbackFunction          = NULL;
+       storePrivate->callbackPort              = NULL;
+       storePrivate->callbackRunLoop           = NULL;
+       storePrivate->callbackRunLoopSource     = NULL;
 
        return;
 }
 
 
-static void
-cleanupMachPort(void *ptr)
+Boolean
+SCDynamicStoreNotifyCallback(SCDynamicStoreRef         store,
+                            CFRunLoopRef               runLoop,
+                            SCDynamicStoreCallBack_v1  func,
+                            void                       *arg)
 {
-       mach_port_t     *port = (mach_port_t *)ptr;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       mach_port_t                     port;
+       mach_port_t                     oldNotify;
+       int                             sc_status;
+       CFMachPortContext               context = { 0, (void *)store, NULL, NULL, NULL };
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreNotifyCallback:"));
+
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
+       }
 
-       SCDLog(LOG_DEBUG, CFSTR("  cleaning up notification port %d"), *port);
-       if (*port != MACH_PORT_NULL) {
-               (void) mach_port_destroy(mach_task_self(), *port);
-               free(port);
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
-       return;
+       if (storePrivate->notifyStatus != NotifierNotRegistered) {
+               /* sorry, you can only have one notification registered at once */
+               _SCErrorSet(kSCStatusNotifierActive);
+               return FALSE;
+       }
+
+       /* Allocating port (for server response) */
+       storePrivate->callbackPort = CFMachPortCreate(NULL,
+                                                     informCallback,
+                                                     &context,
+                                                     NULL);
+
+       /* Request a notification when/if the server dies */
+       port = CFMachPortGetPort(storePrivate->callbackPort);
+       status = mach_port_request_notification(mach_task_self(),
+                                               port,
+                                               MACH_NOTIFY_NO_SENDERS,
+                                               1,
+                                               port,
+                                               MACH_MSG_TYPE_MAKE_SEND_ONCE,
+                                               &oldNotify);
+       if (status != KERN_SUCCESS) {
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
+               CFMachPortInvalidate(storePrivate->callbackPort);
+               CFRelease(storePrivate->callbackPort);
+               _SCErrorSet(status);
+               return FALSE;
+       }
+
+       if (oldNotify != MACH_PORT_NULL) {
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("SCDynamicStoreNotifyCallback(): why is oldNotify != MACH_PORT_NULL?"));
+       }
+
+       /* Requesting notification via mach port */
+       status = notifyviaport(storePrivate->server,
+                              port,
+                              0,
+                              (int *)&sc_status);
+
+       if (status != KERN_SUCCESS) {
+               if (status != MACH_SEND_INVALID_DEST)
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifyviaport(): %s"), mach_error_string(status));
+               CFMachPortInvalidate(storePrivate->callbackPort);
+               CFRelease(storePrivate->callbackPort);
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
+       }
+
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
+       }
+
+       /* set notifier active */
+       storePrivate->notifyStatus              = Using_NotifierInformViaCallback;
+
+       /* Creating/adding a run loop source for the port */
+       storePrivate->callbackArgument          = arg;
+       storePrivate->callbackFunction          = func;
+       storePrivate->callbackRunLoop           = runLoop;
+       storePrivate->callbackRunLoopSource =
+               CFMachPortCreateRunLoopSource(NULL, storePrivate->callbackPort, 0);
+
+       CFRunLoopAddSource(storePrivate->callbackRunLoop,
+                          storePrivate->callbackRunLoopSource,
+                          kCFRunLoopDefaultMode);
+
+       return TRUE;
 }
 
 
-static void *
-watcherThread(void *arg)
+static void
+rlsCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
 {
-       SCDSessionRef           session        = (SCDSessionRef)arg;
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       SCDCallbackRoutine_t    cbFunc         = sessionPrivate->callbackFunction;
-       void                    *cbArg         = sessionPrivate->callbackArgument;
-       mach_port_t             *port          = malloc(sizeof(mach_port_t));
+       mach_msg_empty_rcv_t            *buf            = msg;
+       mach_msg_id_t                   msgid           = buf->header.msgh_id;
+       SCDynamicStoreRef               store           = (SCDynamicStoreRef)info;
+       SCDynamicStorePrivateRef        storePrivate    = (SCDynamicStorePrivateRef)store;
+
+       if (msgid == MACH_NOTIFY_NO_SENDERS) {
+               /* the server died, disable additional callbacks */
+               SCLog(_sc_verbose, LOG_INFO, CFSTR("  rlsCallback(), notifier port closed"));
 
-       *port = CFMachPortGetPort(sessionPrivate->callbackPort);
-       pthread_cleanup_push(cleanupMachPort, (void *)port);
+#ifdef DEBUG
+               if (port != storePrivate->callbackPort) {
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("rlsCallback(), why is port != callbackPort?"));
+               }
+#endif /* DEBUG */
 
-       while (TRUE) {
-               mach_msg_id_t   msgid;
+               /* remove the run loop source(s) */
+               CFRunLoopSourceInvalidate(storePrivate->callbackRunLoopSource);
+               CFRelease(storePrivate->callbackRunLoopSource);
 
-               SCDLog(LOG_DEBUG, CFSTR("Callback thread waiting, port=%d, tid=0x%08x"),
-                      *port, pthread_self());
+               /* invalidate port */
+               CFMachPortInvalidate(storePrivate->callbackPort);
+               CFRelease(storePrivate->callbackPort);
 
-               msgid = _waitForMachMessage(*port);
+               return;
+       }
 
-               if (msgid == MACH_NOTIFY_NO_SENDERS) {
-                       /* the server closed the notifier port, disable additional callbacks */
-                       SCDLog(LOG_DEBUG, CFSTR("  notifier port closed, disabling notifier"));
-                       break;
-               }
+       /* signal the real runloop source */
+       CFRunLoopSourceSignal(storePrivate->rls);
+       return;
+}
 
-               if (msgid == -1) {
-                       mach_port_type_t        pt;
 
-                       /* an error was detected, disable additional callbacks */
-                       SCDLog(LOG_DEBUG, CFSTR("  server failure, disabling notifier"));
+static void
+rlsSchedule(void *info, CFRunLoopRef rl, CFStringRef mode)
+{
+       SCDynamicStoreRef               store           = (SCDynamicStoreRef)info;
+       SCDynamicStorePrivateRef        storePrivate    = (SCDynamicStorePrivateRef)store;
 
-                       /* check if the server connection is not valid, close if necessary */
-                       if ((mach_port_type(mach_task_self(), sessionPrivate->server, &pt) == KERN_SUCCESS) &&
-                           (pt & MACH_PORT_TYPE_DEAD_NAME)) {
-                               SCDLog(LOG_DEBUG, CFSTR("  server process died, destroying (dead) port"));
-                               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-                               sessionPrivate->server = MACH_PORT_NULL;
-                       }
-                       break;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("schedule notifications for mode %@"), mode);
+
+       if (storePrivate->rlsRefs++ == 0) {
+               CFMachPortContext       context = { 0, (void *)store, NULL, NULL, NULL };
+               mach_port_t             oldNotify;
+               mach_port_t             port;
+               int                     sc_status;
+               kern_return_t           status;
+
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  activate callback runloop source"));
+
+               /* Allocating port (for server response) */
+               status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
+               if (status != KERN_SUCCESS) {
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_port_allocate(): %s"), mach_error_string(status));
+                       return;
                }
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  port = %d"), port);
 
-               if (cbFunc == NULL) {
-                       /* there is no (longer) a callback function, disable additional callbacks */
-                       SCDLog(LOG_DEBUG, CFSTR("  no callback function, disabling notifier"));
-                       break;
+               status = mach_port_insert_right(mach_task_self(),
+                                               port,
+                                               port,
+                                               MACH_MSG_TYPE_MAKE_SEND);
+               if (status != KERN_SUCCESS) {
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_port_insert_right(): %s"), mach_error_string(status));
+                       (void) mach_port_destroy(mach_task_self(), port);
+                       return;
                }
 
-               SCDLog(LOG_DEBUG, CFSTR("  executing notifiction function"));
+               /* Request a notification when/if the server dies */
+               status = mach_port_request_notification(mach_task_self(),
+                                                       port,
+                                                       MACH_NOTIFY_NO_SENDERS,
+                                                       1,
+                                                       port,
+                                                       MACH_MSG_TYPE_MAKE_SEND_ONCE,
+                                                       &oldNotify);
+               if (status != KERN_SUCCESS) {
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
+                       (void) mach_port_destroy(mach_task_self(), port);
+                       return;
+               }
 
-               if (!(*cbFunc)(session, cbArg)) {
-                       /*
-                        * callback function returned an error, exit the thread
-                        */
-                       break;
+               if (oldNotify != MACH_PORT_NULL) {
+                       SCLog(_sc_verbose, LOG_ERR, CFSTR("rlsSchedule(): why is oldNotify != MACH_PORT_NULL?"));
                }
 
-       }
+               status = notifyviaport(storePrivate->server, port, 0, (int *)&sc_status);
+               if (status != KERN_SUCCESS) {
+                       if (status != MACH_SEND_INVALID_DEST)
+                               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifyviaport(): %s"), mach_error_string(status));
+                       (void) mach_port_destroy(mach_task_self(), port);
+                       port = MACH_PORT_NULL;
+                       (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+                       storePrivate->server = MACH_PORT_NULL;
+                       return;
+               }
 
-       /*
-        * pop the cleanup routine for the "port" mach port. We end up calling
-        * mach_port_destroy() in the process.
-        */
-       pthread_cleanup_pop(1);
+               storePrivate->callbackPort = CFMachPortCreateWithPort(NULL, port, rlsCallback, &context, NULL);
+               storePrivate->callbackRunLoopSource = CFMachPortCreateRunLoopSource(NULL, storePrivate->callbackPort, 0);
+       }
 
-       pthread_exit (NULL);
-       return NULL;
+       CFRunLoopAddSource(rl, storePrivate->callbackRunLoopSource, mode);
+       return;
 }
 
 
-SCDStatus
-SCDNotifierInformViaCallback(SCDSessionRef session, SCDCallbackRoutine_t func, void *arg)
+static void
+rlsCancel(void *info, CFRunLoopRef rl, CFStringRef mode)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       mach_port_t             port;
-       mach_port_t             oldNotify;
-       SCDStatus               scd_status;
-       CFMachPortContext       context = { 0, (void *)session, NULL, NULL, NULL };
+       SCDynamicStoreRef               store           = (SCDynamicStoreRef)info;
+       SCDynamicStorePrivateRef        storePrivate    = (SCDynamicStorePrivateRef)store;
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDNotifierInformViaCallback:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("cancel notifications for mode %@"), mode);
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;   /* you must have an open session to play */
-       }
+       CFRunLoopRemoveSource(rl, storePrivate->callbackRunLoopSource, mode);
+       if (--storePrivate->rlsRefs == 0) {
+               int             sc_status;
+               kern_return_t   status;
 
-       if (sessionPrivate->notifyStatus != NotifierNotRegistered) {
-               /* sorry, you can only have one notification registered at once */
-               return SCD_NOTIFIERACTIVE;
-       }
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  cancel callback runloop source"));
 
-       if (func == NULL) {
-               /* sorry, you must specify a callback function */
-               return SCD_INVALIDARGUMENT;
-       }
+               /* remove the run loop source */
+               CFRelease(storePrivate->callbackRunLoopSource);
 
-       /* Allocating port (for server response) */
-       sessionPrivate->callbackPort = CFMachPortCreate(NULL,
-                                                       informCallback,
-                                                       &context,
-                                                       NULL);
+               /* invalidate port */
+               CFMachPortInvalidate(storePrivate->callbackPort);
+               CFRelease(storePrivate->callbackPort);
 
-       /* Request a notification when/if the server dies */
-       port = CFMachPortGetPort(sessionPrivate->callbackPort);
-       status = mach_port_request_notification(mach_task_self(),
-                                               port,
-                                               MACH_NOTIFY_NO_SENDERS,
-                                               1,
-                                               port,
-                                               MACH_MSG_TYPE_MAKE_SEND_ONCE,
-                                               &oldNotify);
-       if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
-               CFMachPortInvalidate(sessionPrivate->callbackPort);
-               CFRelease(sessionPrivate->callbackPort);
-               return SCD_FAILED;
+               status = notifycancel(storePrivate->server, (int *)&sc_status);
+               if (status != KERN_SUCCESS) {
+                       if (status != MACH_SEND_INVALID_DEST)
+                               SCLog(_sc_verbose, LOG_INFO, CFSTR("notifycancel(): %s"), mach_error_string(status));
+                       (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+                       storePrivate->server = MACH_PORT_NULL;
+                       return;
+               }
        }
+       return;
+}
 
-#ifdef DEBUG
-       if (oldNotify != MACH_PORT_NULL) {
-               SCDLog(LOG_DEBUG, CFSTR("SCDNotifierInformViaCallback(): why is oldNotify != MACH_PORT_NULL?"));
+static void
+rlsPerform(void *info)
+{
+       CFArrayRef                      changedKeys;
+       void                            *context_info;
+       void                            (*context_release)(const void *);
+       SCDynamicStoreCallBack          rlsFunction;
+       SCDynamicStoreRef               store           = (SCDynamicStoreRef)info;
+       SCDynamicStorePrivateRef        storePrivate    = (SCDynamicStorePrivateRef)store;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  executing notifiction function"));
+
+       changedKeys = SCDynamicStoreCopyNotifiedKeys(store);
+       rlsFunction = storePrivate->rlsFunction;
+
+       if (NULL != storePrivate->rlsContext.retain) {
+               context_info    = (void *)storePrivate->rlsContext.retain(storePrivate->rlsContext.info);
+               context_release = storePrivate->rlsContext.release;
+       } else {
+               context_info    = storePrivate->rlsContext.info;
+               context_release = NULL;
+       }
+       (*rlsFunction)(store, changedKeys, storePrivate->rlsContext.info);
+       if (context_release) {
+               context_release(context_info);
        }
-#endif /* DEBUG */
 
-       /* Requesting notification via mach port */
-       status = notifyviaport(sessionPrivate->server,
-                              port,
-                              0,
-                              (int *)&scd_status);
+       CFRelease(changedKeys);
+       return;
+}
 
-       if (status != KERN_SUCCESS) {
-               if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("notifyviaport(): %s"), mach_error_string(status));
-               CFMachPortInvalidate(sessionPrivate->callbackPort);
-               CFRelease(sessionPrivate->callbackPort);
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+
+CFRunLoopSourceRef
+SCDynamicStoreCreateRunLoopSource(CFAllocatorRef       allocator,
+                                 SCDynamicStoreRef     store,
+                                 CFIndex               order)
+{
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreCreateRunLoopSource:"));
+
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return NULL;
        }
 
-       if (scd_status != SCD_OK) {
-               return scd_status;
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return NULL;
        }
 
-       /* set notifier active */
-       sessionPrivate->notifyStatus     = Using_NotifierInformViaCallback;
-       sessionPrivate->callbackFunction = func;
-       sessionPrivate->callbackArgument = arg;
-
-       if (SCDOptionGet(session, kSCDOptionUseCFRunLoop)) {
-               /* Creating/adding a run loop source for the port */
-               sessionPrivate->callbackRunLoopSource =
-                       CFMachPortCreateRunLoopSource(NULL, sessionPrivate->callbackPort, 0);
-               CFRunLoopAddSource(CFRunLoopGetCurrent(),
-                                  sessionPrivate->callbackRunLoopSource,
-                                  kCFRunLoopDefaultMode);
-       } else {
-               pthread_attr_t          tattr;
-
-               SCDLog(LOG_DEBUG, CFSTR("Starting background thread to watch for notifications..."));
-               pthread_attr_init(&tattr);
-               pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM);
-               pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
-               pthread_attr_setstacksize(&tattr, 96 * 1024); // each thread gets a 96K stack
-               pthread_create(&sessionPrivate->callbackHelper,
-                              &tattr,
-                              watcherThread,
-                              (void *)session);
-               pthread_attr_destroy(&tattr);
-               SCDLog(LOG_DEBUG, CFSTR("  thread id=0x%08x"), sessionPrivate->callbackHelper);
+       switch (storePrivate->notifyStatus) {
+               case NotifierNotRegistered :
+               case Using_NotifierInformViaRunLoop :
+                       /* set notifier active */
+                       storePrivate->notifyStatus = Using_NotifierInformViaRunLoop;
+                       break;
+               default :
+                       /* sorry, you can only have one notification registered at once */
+                       _SCErrorSet(kSCStatusNotifierActive);
+                       return NULL;
        }
 
-       return SCD_OK;
+       if (!storePrivate->rls) {
+               CFRunLoopSourceContext context;
+
+               context.version         = 0;
+               context.info            = (void *)store;
+               context.retain          = (const void *(*)(const void *))CFRetain;
+               context.release         = (void (*)(const void *))CFRelease;
+               context.copyDescription = (CFStringRef (*)(const void *))CFCopyDescription;
+               context.equal           = (Boolean (*)(const void *, const void *))CFEqual;
+               context.hash            = (CFHashCode (*)(const void *))CFHash;
+               context.schedule        = rlsSchedule;
+               context.cancel          = rlsCancel;
+               context.perform         = rlsPerform;
+
+               storePrivate->rls = CFRunLoopSourceCreate(allocator, order, &context);
+       }
+
+       return (CFRunLoopSourceRef)CFRetain(storePrivate->rls);
 }
+
index 48ba04fd331f90f0a5ac11b3bdc1272ea751f104..88f5de0a82fba5dbc60345b1e4f9844807267cf2 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <paths.h>
-#include <unistd.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * April 5, 2000               Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <mach/mach.h>
 #include <mach/mach_error.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
 
+#include <paths.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
 
-SCDStatus
-SCDNotifierInformViaFD(SCDSessionRef   session,
-                      int32_t          identifier,
-                      int              *fd)
+Boolean
+SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef   store,
+                                  int32_t              identifier,
+                                  int                  *fd)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       SCDStatus               scd_status;
-       struct sockaddr_un      un;
-       int                     sock;
-
-       SCDLog(LOG_DEBUG, CFSTR("SCDNotifierInformViaFD:"));
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       int                             sc_status;
+       struct sockaddr_un              un;
+       int                             sock;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreNotifyFileDescriptor:"));
+
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
+       }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;   /* you must have an open session to play */
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
-       if (sessionPrivate->notifyStatus != NotifierNotRegistered) {
+       if (storePrivate->notifyStatus != NotifierNotRegistered) {
                /* sorry, you can only have one notification registered at once */
-               return SCD_NOTIFIERACTIVE;
+               _SCErrorSet(kSCStatusNotifierActive);
+               return FALSE;
        }
 
        if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
-               SCDLog(LOG_NOTICE, CFSTR("socket: %s"), strerror(errno));
-               return SCD_FAILED;
+               _SCErrorSet(errno);
+               SCLog(_sc_verbose, LOG_NOTICE, CFSTR("socket: %s"), strerror(errno));
+               return FALSE;
        }
 
        /* establish a UNIX domain socket for server->client notification */
@@ -67,45 +88,49 @@ SCDNotifierInformViaFD(SCDSessionRef        session,
                 sizeof(un.sun_path)-1,
                 "%s%s-%d",
                 _PATH_VARTMP,
-                "SCDNotifierInformViaFD",
-                sessionPrivate->server);
+                "SCDynamicStoreNotifyFileDescriptor",
+                storePrivate->server);
 
        if (bind(sock, (struct sockaddr *)&un, sizeof(un)) == -1) {
-               SCDLog(LOG_NOTICE, CFSTR("bind: %s"), strerror(errno));
+               _SCErrorSet(errno);
+               SCLog(_sc_verbose, LOG_NOTICE, CFSTR("bind: %s"), strerror(errno));
                (void) close(sock);
-               return SCD_FAILED;
+               return FALSE;
        }
 
        if (listen(sock, 0) == -1) {
-               SCDLog(LOG_NOTICE, CFSTR("listen: %s"), strerror(errno));
+               _SCErrorSet(errno);
+               SCLog(_sc_verbose, LOG_NOTICE, CFSTR("listen: %s"), strerror(errno));
                (void) close(sock);
-               return SCD_FAILED;
+               return FALSE;
        }
 
-       status = notifyviafd(sessionPrivate->server,
+       status = notifyviafd(storePrivate->server,
                             un.sun_path,
                             strlen(un.sun_path),
                             identifier,
-                            (int *)&scd_status);
+                            (int *)&sc_status);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("notifyviafd(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifyviafd(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
        }
 
        *fd = accept(sock, 0, 0);
        if (*fd == -1) {
-               SCDLog(LOG_NOTICE, CFSTR("accept: %s"), strerror(errno));
+               _SCErrorSet(errno);
+               SCLog(_sc_verbose, LOG_NOTICE, CFSTR("accept: %s"), strerror(errno));
                (void) close(sock);
-               return SCD_FAILED;
+               return FALSE;
        }
        (void) close(sock);
 
        /* set notifier active */
-       sessionPrivate->notifyStatus = Using_NotifierInformViaFD;
+       storePrivate->notifyStatus = Using_NotifierInformViaFD;
 
-       return scd_status;
+       return TRUE;
 }
index 848579f8a0d1427656d2b717e7b680cb008c9791..63ce3d39c5194ba36dda426845df787856fe0a65 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 31, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
-
 
-SCDStatus
-SCDNotifierInformViaMachPort(SCDSessionRef session, mach_msg_id_t identifier, mach_port_t *port)
+Boolean
+SCDynamicStoreNotifyMachPort(SCDynamicStoreRef store, mach_msg_id_t identifier, mach_port_t *port)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       mach_port_t             oldNotify;
-       SCDStatus               scd_status;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       mach_port_t                     oldNotify;
+       int                             sc_status;
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDNotifierInformViaMachPort:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreNotifyMachPort:"));
+
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
+       }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;   /* you must have an open session to play */
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
-       if (sessionPrivate->notifyStatus != NotifierNotRegistered) {
+       if (storePrivate->notifyStatus != NotifierNotRegistered) {
                /* sorry, you can only have one notification registered at once */
-               return SCD_NOTIFIERACTIVE;
+               _SCErrorSet(kSCStatusNotifierActive);
+               return FALSE;
        }
 
-       SCDLog(LOG_DEBUG, CFSTR("Allocating port (for server response)"));
+       /* Allocating port (for server response) */
        status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, port);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("mach_port_allocate(): %s"), mach_error_string(status));
-               return SCD_FAILED;
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_port_allocate(): %s"), mach_error_string(status));
+               _SCErrorSet(status);
+               return FALSE;
        }
-       SCDLog(LOG_DEBUG, CFSTR("  port = %d"), *port);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  port = %d"), *port);
 
        status = mach_port_insert_right(mach_task_self(),
                                        *port,
                                        *port,
                                        MACH_MSG_TYPE_MAKE_SEND);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("mach_port_insert_right(): %s"), mach_error_string(status));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_port_insert_right(): %s"), mach_error_string(status));
                (void) mach_port_destroy(mach_task_self(), *port);
                *port = MACH_PORT_NULL;
-               return SCD_FAILED;
+               _SCErrorSet(status);
+               return FALSE;
        }
 
        /* Request a notification when/if the server dies */
@@ -75,35 +96,35 @@ SCDNotifierInformViaMachPort(SCDSessionRef session, mach_msg_id_t identifier, ma
                                                MACH_MSG_TYPE_MAKE_SEND_ONCE,
                                                &oldNotify);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
                (void) mach_port_destroy(mach_task_self(), *port);
                *port = MACH_PORT_NULL;
-               return SCD_FAILED;
+               _SCErrorSet(status);
+               return FALSE;
        }
 
-#ifdef DEBUG
        if (oldNotify != MACH_PORT_NULL) {
-               SCDLog(LOG_DEBUG, CFSTR("SCDNotifierInformViaMachPort(): why is oldNotify != MACH_PORT_NULL?"));
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("SCDynamicStoreNotifyMachPort(): why is oldNotify != MACH_PORT_NULL?"));
        }
-#endif /* DEBUG */
 
-       status = notifyviaport(sessionPrivate->server,
+       status = notifyviaport(storePrivate->server,
                               *port,
                               identifier,
-                              (int *)&scd_status);
+                              (int *)&sc_status);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("notifyviaport(): %s"), mach_error_string(status));
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifyviaport(): %s"), mach_error_string(status));
                (void) mach_port_destroy(mach_task_self(), *port);
                *port = MACH_PORT_NULL;
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
        }
 
        /* set notifier active */
-       sessionPrivate->notifyStatus = Using_NotifierInformViaMachPort;
+       storePrivate->notifyStatus = Using_NotifierInformViaMachPort;
 
-       return scd_status;
+       return TRUE;
 }
index 01e0c1464f08c8b8630766f4727a17f2e65ba53b..7036a90929260d1b20e13aac05c2fd806a81eefa 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 31, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
 
-
-SCDStatus
-SCDNotifierInformViaSignal(SCDSessionRef session, pid_t pid, int sig)
+Boolean
+SCDynamicStoreNotifySignal(SCDynamicStoreRef store, pid_t pid, int sig)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-
-       kern_return_t   status;
-       SCDStatus       scd_status;
-       task_t          task;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       int                             sc_status;
+       task_t                          task;
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDNotifierInformViaSignal:"));
-       SCDLog(LOG_DEBUG, CFSTR("  pid = %d"), pid);
-       SCDLog(LOG_DEBUG, CFSTR("  sig = %d"), sig);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreNotifySignal:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  pid = %d"), pid);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  sig = %d"), sig);
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;   /* you must have an open session to play */
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
        }
 
-       if (SCDOptionGet(NULL, kSCDOptionIsServer)) {
-               /* sorry, neither the server nor any plug-ins can "wait" */
-               return SCD_FAILED;
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
-       if (sessionPrivate->notifyStatus != NotifierNotRegistered) {
+       if (storePrivate->notifyStatus != NotifierNotRegistered) {
                /* sorry, you can only have one notification registered at once */
-               return SCD_NOTIFIERACTIVE;
-       }
-
-       if ((sig <= 0) || (sig > NSIG)) {
-               /* sorry, you must specify a valid signal */
-               return SCD_INVALIDARGUMENT;
+               _SCErrorSet(kSCStatusNotifierActive);
+               return FALSE;
        }
 
        status = task_for_pid(mach_task_self(), pid, &task);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("task_for_pid(): %s"), mach_error_string(status));
-               return SCD_FAILED;
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("task_for_pid(): %s"), mach_error_string(status));
+               _SCErrorSet(status);
+               return FALSE;
        }
 
-       status = notifyviasignal(sessionPrivate->server, task, sig, (int *)&scd_status);
+       status = notifyviasignal(storePrivate->server, task, sig, (int *)&sc_status);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("notifyviasignal(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifyviasignal(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
        }
 
        /* set notifier active */
-       sessionPrivate->notifyStatus = Using_NotifierInformViaSignal;
+       storePrivate->notifyStatus = Using_NotifierInformViaSignal;
 
-       return scd_status;
+       return TRUE;
 }
index e82123244c5112b86655ab31e881fcd0e2cfd45a..2e006d339a9b77828c6fe65abfc141625f164f78 100644 (file)
  * @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 <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
-#include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 
-static CFComparisonResult
-sort_keys(const void *p1, const void *p2, void *context) {
-       CFStringRef key1 = (CFStringRef)p1;
-       CFStringRef key2 = (CFStringRef)p2;
-       return CFStringCompare(key1, key2, 0);
-}
-
-
-SCDStatus
-SCDNotifierList(SCDSessionRef session, int regexOptions, CFArrayRef *notifierKeys)
+CFArrayRef
+SCDynamicStoreCopyWatchedKeyList(SCDynamicStoreRef store, Boolean isRegex)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       CFIndex                 keyCnt;
-       void                    **keyRefs;
-       CFArrayRef              keys;
-       CFMutableArrayRef       sortedKeys;
+       SCDynamicStorePrivateRef        storePrivate    = (SCDynamicStorePrivateRef)store;
+       CFIndex                         keyCnt;
+       void                            **keyRefs;
+       CFArrayRef                      watchedKeys     = NULL;
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDNotifierList:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreCopyWatchedKeyList:"));
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;
-       }
-
-       if (regexOptions & kSCDRegexKey) {
-               keyCnt  = CFSetGetCount(sessionPrivate->reKeys);
+       if (isRegex) {
+               keyCnt  = CFSetGetCount(storePrivate->reKeys);
                keyRefs = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
-               CFSetGetValues(sessionPrivate->reKeys, keyRefs);
-               keys = CFArrayCreate(NULL, keyRefs, keyCnt, &kCFTypeArrayCallBacks);
+               CFSetGetValues(storePrivate->reKeys, keyRefs);
+               watchedKeys = CFArrayCreate(NULL, keyRefs, keyCnt, &kCFTypeArrayCallBacks);
                CFAllocatorDeallocate(NULL, keyRefs);
        } else {
-               keyCnt  = CFSetGetCount(sessionPrivate->keys);
+               keyCnt  = CFSetGetCount(storePrivate->keys);
                keyRefs = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
-               CFSetGetValues(sessionPrivate->keys, keyRefs);
-               keys = CFArrayCreate(NULL, keyRefs, keyCnt, &kCFTypeArrayCallBacks);
+               CFSetGetValues(storePrivate->keys, keyRefs);
+               watchedKeys = CFArrayCreate(NULL, keyRefs, keyCnt, &kCFTypeArrayCallBacks);
                CFAllocatorDeallocate(NULL, keyRefs);
        }
 
-       sortedKeys = CFArrayCreateMutableCopy(NULL, keyCnt, keys);
-       CFRelease(keys);
-       CFArraySortValues(sortedKeys, CFRangeMake(0, keyCnt), sort_keys, NULL);
-
-       *notifierKeys = sortedKeys;
-       return SCD_OK;
+       return watchedKeys;
 }
index e0626006298c9c41741fe1622a1d603f6c84db34..7cc92a9ee1b9042567bbde9a9e89bb4fd76e136b 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <sys/types.h>
-#include <regex.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 24, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
-
 
-SCDStatus
-SCDNotifierRemove(SCDSessionRef session, CFStringRef key, int regexOptions)
+Boolean
+SCDynamicStoreRemoveWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       CFDataRef               xmlKey;         /* serialized key */
-       xmlData_t               myKeyRef;
-       CFIndex                 myKeyLen;
-       SCDStatus               scd_status;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlKey;         /* serialized key */
+       xmlData_t                       myKeyRef;
+       CFIndex                         myKeyLen;
+       int                             sc_status;
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDNotifierRemove:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key          = %@"), key);
-       SCDLog(LOG_DEBUG, CFSTR("  regexOptions = %0o"), regexOptions);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreRemoveWatchedKey:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key     = %@"), key);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  isRegex = %s"), isRegex ? "TRUE" : "FALSE");
 
-       if (key == NULL) {
-               return SCD_INVALIDARGUMENT;     /* no key specified */
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
        }
 
-       if (session == NULL) {
-               return SCD_NOSESSION;           /* you can't do anything without a session */
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
        /*
         * remove key from this sessions notifier list after checking that
         * it was previously defined.
         */
-       if (regexOptions & kSCDRegexKey) {
-               if (!CFSetContainsValue(sessionPrivate->reKeys, key))
-                       return SCD_NOKEY;               /* sorry, key does not exist in notifier list */
-               CFSetRemoveValue(sessionPrivate->reKeys, key);  /* remove key from this sessions notifier list */
+       if (isRegex) {
+               if (!CFSetContainsValue(storePrivate->reKeys, key)) {
+                       /* sorry, key does not exist in notifier list */
+                       _SCErrorSet(kSCStatusNoKey);
+                       return FALSE;
+               }
+               CFSetRemoveValue(storePrivate->reKeys, key);    /* remove key from this sessions notifier list */
        } else {
-               if (!CFSetContainsValue(sessionPrivate->keys, key))
-                       return SCD_NOKEY;               /* sorry, key does not exist in notifier list */
-               CFSetRemoveValue(sessionPrivate->keys, key);    /* remove key from this sessions notifier list */
-       }
-
-       if (sessionPrivate->server == MACH_PORT_NULL) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+               if (!CFSetContainsValue(storePrivate->keys, key)) {
+                       /* sorry, key does not exist in notifier list */
+                       _SCErrorSet(kSCStatusNoKey);
+                       return FALSE;
+               }
+               CFSetRemoveValue(storePrivate->keys, key);      /* remove key from this sessions notifier list */
        }
 
        /* serialize the key */
@@ -77,22 +90,28 @@ SCDNotifierRemove(SCDSessionRef session, CFStringRef key, int regexOptions)
        myKeyLen = CFDataGetLength(xmlKey);
 
        /* send the key to the server */
-       status = notifyremove(sessionPrivate->server,
+       status = notifyremove(storePrivate->server,
                              myKeyRef,
                              myKeyLen,
-                             regexOptions,
-                             (int *)&scd_status);
+                             isRegex,
+                             (int *)&sc_status);
 
        /* clean up */
        CFRelease(xmlKey);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("notifyremove(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifyremove(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
+       }
+
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
-       return scd_status;
+       return TRUE;
 }
diff --git a/SystemConfiguration.fproj/SCDNotifierSetKeys.c b/SystemConfiguration.fproj/SCDNotifierSetKeys.c
new file mode 100644 (file)
index 0000000..f504f7c
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - 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 __inline__ void
+my_CFSetApplyFunction(CFSetRef                 theSet,
+                     CFSetApplierFunction      applier,
+                     void                      *context)
+{
+       CFAllocatorRef  myAllocator;
+       CFSetRef        mySet;
+
+       myAllocator = CFGetAllocator(theSet);
+       mySet       = CFSetCreateCopy(myAllocator, theSet);
+       CFSetApplyFunction(mySet, applier, context);
+       CFRelease(mySet);
+       return;
+}
+
+
+/*
+ * "context" argument for removeOldKey() and addNewKey()
+ */
+typedef struct {
+       SCDynamicStoreRef       store;
+       CFArrayRef              newKeys;        /* for removeOldKey */
+       Boolean                 isRegex;
+       Boolean                 ok;
+} updateKeysContext, *updateKeysContextRef;
+
+
+static void
+removeOldKey(const void *value, void *context)
+{
+       CFStringRef                     oldKey          = (CFStringRef)value;
+       updateKeysContextRef            myContextRef    = (updateKeysContextRef)context;
+
+       if (!myContextRef->ok) {
+               return;
+       }
+
+       if (!myContextRef->newKeys ||
+           !CFArrayContainsValue(myContextRef->newKeys,
+                                 CFRangeMake(0, CFArrayGetCount(myContextRef->newKeys)),
+                                 oldKey)) {
+               /* the old notification key is not being retained, remove it */
+               myContextRef->ok = SCDynamicStoreRemoveWatchedKey(myContextRef->store,
+                                                                 oldKey,
+                                                                 myContextRef->isRegex);
+       }
+
+       return;
+}
+
+
+static void
+addNewKey(const void *value, void *context)
+{
+       CFStringRef                     newKey          = (CFStringRef)value;
+       updateKeysContextRef            myContextRef    = (updateKeysContextRef)context;
+       SCDynamicStorePrivateRef        storePrivate    = (SCDynamicStorePrivateRef)myContextRef->store;
+
+       if (!myContextRef->ok) {
+               return;
+       }
+
+       if (myContextRef->isRegex) {
+               if (!CFSetContainsValue(storePrivate->reKeys, newKey)) {
+                       /* add pattern to this sessions notifier list */
+                       myContextRef->ok = SCDynamicStoreAddWatchedKey(myContextRef->store, newKey, TRUE);
+               }
+       } else {
+               if (!CFSetContainsValue(storePrivate->keys, newKey)) {
+                       /* add key to this sessions notifier list */
+                       myContextRef->ok = SCDynamicStoreAddWatchedKey(myContextRef->store, newKey, FALSE);
+               }
+       }
+
+       return;
+}
+
+Boolean
+SCDynamicStoreSetNotificationKeys(SCDynamicStoreRef    store,
+                                 CFArrayRef            keys,
+                                 CFArrayRef            patterns)
+{
+       updateKeysContext               myContext;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreSetNotificationKeys:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  keys     = %@"), keys);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  patterns = %@"), patterns);
+
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
+       }
+
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
+       }
+
+       myContext.ok      = TRUE;
+       myContext.store   = store;
+
+       /* remove any previously registered keys */
+       myContext.newKeys = keys;
+       myContext.isRegex = FALSE;
+       my_CFSetApplyFunction(storePrivate->keys, removeOldKey, &myContext);
+
+       /* register any new keys */
+       if (keys) {
+               CFArrayApplyFunction(keys,
+                                    CFRangeMake(0, CFArrayGetCount(keys)),
+                                    addNewKey,
+                                    &myContext);
+       }
+
+       /* remove any previously registered patterns */
+       myContext.newKeys = patterns;
+       myContext.isRegex = TRUE;
+       my_CFSetApplyFunction(storePrivate->reKeys, removeOldKey, &myContext);
+
+       /* register any new patterns */
+       if (patterns) {
+               CFArrayApplyFunction(patterns,
+                                    CFRangeMake(0, CFArrayGetCount(patterns)),
+                                    addNewKey,
+                                    &myContext);
+       }
+
+       return myContext.ok;
+}
index 67cf1d9411b2856939199a5a4aadf9ce45a5dcfe..fa59f2ba979b78dc88e844f0b568e44ef5e55597 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 31, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
-
 
-SCDStatus
-SCDNotifierWait(SCDSessionRef session)
+static mach_msg_id_t
+waitForMachMessage(mach_port_t port)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       mach_port_t             port;
-       mach_port_t             oldNotify;
-       SCDStatus               scd_status;
-       mach_msg_id_t           msgid;
+       kern_return_t           status;
+       mach_msg_empty_rcv_t    *buf;
+
+       mach_msg_size_t         size = sizeof(mach_msg_empty_t) + MAX_TRAILER_SIZE;
+
+       status = vm_allocate(mach_task_self(), (vm_address_t *)&buf, size, TRUE);
+       if (status != KERN_SUCCESS) {
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
+               return -1;
+       }
+
+       status = mach_msg(&buf->header,                 /* msg */
+                         MACH_RCV_MSG,                 /* options */
+                         0,                            /* send_size */
+                         size,                         /* rcv_size */
+                         port,                         /* rcv_name */
+                         MACH_MSG_TIMEOUT_NONE,        /* timeout */
+                         MACH_PORT_NULL);              /* notify */
+       if (status != KERN_SUCCESS) {
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_msg(): %s"), mach_error_string(status));
+               return -1;
+       }
+
+       return buf->header.msgh_id;
+}
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDNotifierWait:"));
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;   /* you must have an open session to play */
+Boolean
+SCDynamicStoreNotifyWait(SCDynamicStoreRef store)
+{
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       mach_port_t                     port;
+       mach_port_t                     oldNotify;
+       int                             sc_status;
+       mach_msg_id_t                   msgid;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreNotifyWait:"));
+
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
        }
 
-       if (SCDOptionGet(NULL, kSCDOptionIsServer)) {
-               /* sorry, neither the server nor any plug-ins can "wait" */
-               return SCD_FAILED;
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
-       if (sessionPrivate->notifyStatus != NotifierNotRegistered) {
+       if (storePrivate->notifyStatus != NotifierNotRegistered) {
                /* sorry, you can only have one notification registered at once */
-               return SCD_NOTIFIERACTIVE;
+               _SCErrorSet(kSCStatusNotifierActive);
+               return FALSE;
        }
 
-       SCDLog(LOG_DEBUG, CFSTR("Allocating port (for server response)"));
+       /* Allocating port (for server response) */
        status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &port);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("mach_port_allocate(): %s"), mach_error_string(status));
-               return SCD_FAILED;
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_port_allocate(): %s"), mach_error_string(status));
+               _SCErrorSet(status);
+               return FALSE;
        }
-       SCDLog(LOG_DEBUG, CFSTR("  port = %d"), port);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  port = %d"), port);
 
        status = mach_port_insert_right(mach_task_self(),
                                        port,
                                        port,
                                        MACH_MSG_TYPE_MAKE_SEND);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("mach_port_insert_right(): %s"), mach_error_string(status));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_port_insert_right(): %s"), mach_error_string(status));
                (void) mach_port_destroy(mach_task_self(), port);
-               return SCD_FAILED;
+               _SCErrorSet(status);
+               return FALSE;
        }
 
        /* Request a notification when/if the server dies */
@@ -81,71 +127,75 @@ SCDNotifierWait(SCDSessionRef session)
                                                MACH_MSG_TYPE_MAKE_SEND_ONCE,
                                                &oldNotify);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
                (void) mach_port_destroy(mach_task_self(), port);
-               return SCD_FAILED;
+               _SCErrorSet(status);
+               return FALSE;
        }
 
-#ifdef DEBUG
        if (oldNotify != MACH_PORT_NULL) {
-               SCDLog(LOG_DEBUG, CFSTR("SCDNotifierWait(): why is oldNotify != MACH_PORT_NULL?"));
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("SCDynamicStoreNotifyWait(): why is oldNotify != MACH_PORT_NULL?"));
        }
-#endif /* DEBUG */
 
-       SCDLog(LOG_DEBUG, CFSTR("Requesting notification via mach port %d"), port);
-       status = notifyviaport(sessionPrivate->server,
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("Requesting notification via mach port %d"), port);
+       status = notifyviaport(storePrivate->server,
                               port,
                               0,
-                              (int *)&scd_status);
+                              (int *)&sc_status);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("notifyviaport(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifyviaport(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
        }
 
-       if (scd_status != SCD_OK) {
-               return scd_status;
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
        /* set notifier active */
-       sessionPrivate->notifyStatus = Using_NotifierWait;
+       storePrivate->notifyStatus = Using_NotifierWait;
 
-       SCDLog(LOG_DEBUG, CFSTR("Waiting..."));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("Waiting..."));
 
-       msgid = _waitForMachMessage(port);
+       msgid = waitForMachMessage(port);
 
        /* set notifier inactive */
-       sessionPrivate->notifyStatus = NotifierNotRegistered;
+       storePrivate->notifyStatus = NotifierNotRegistered;
 
        if (msgid == MACH_NOTIFY_NO_SENDERS) {
                /* the server closed the notifier port */
-               SCDLog(LOG_DEBUG, CFSTR("  notifier port closed, destroying port %d"), port);
-               return SCD_NOSERVER;
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  notifier port closed, destroying port %d"), port);
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
        if (msgid == -1) {
                /* one of the mach routines returned an error */
-               SCDLog(LOG_DEBUG, CFSTR("  communication with server failed, destroying port %d"), port);
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  communication with server failed, destroying port %d"), port);
                (void) mach_port_destroy(mach_task_self(), port);
-               return SCD_NOSERVER;
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
-       SCDLog(LOG_DEBUG, CFSTR("Something changed, cancelling notification request"));
-       status = notifycancel(sessionPrivate->server,
-                             (int *)&scd_status);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("Something changed, cancelling notification request"));
+       status = notifycancel(storePrivate->server,
+                             (int *)&sc_status);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("notifycancel(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               scd_status = SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("notifycancel(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
        }
 
        (void) mach_port_destroy(mach_task_self(), port);
 
-       return scd_status;
+       return TRUE;
 }
diff --git a/SystemConfiguration.fproj/SCDNotify.c b/SystemConfiguration.fproj/SCDNotify.c
new file mode 100644 (file)
index 0000000..e16481c
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Modification History
+ *
+ * May 19, 2001                Allan Nathanson <ajn@apple.com>
+ * - 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 */
+
+Boolean
+SCDynamicStoreNotifyValue(SCDynamicStoreRef    store,
+                         CFStringRef           key)
+{
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlKey;         /* serialized key */
+       xmlData_t                       myKeyRef;
+       CFIndex                         myKeyLen;
+       int                             sc_status;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreNotifyValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key = %@"), key);
+
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
+       }
+
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
+       }
+
+       /* serialize the key */
+       xmlKey = CFPropertyListCreateXMLData(NULL, key);
+       myKeyRef = (xmlData_t)CFDataGetBytePtr(xmlKey);
+       myKeyLen = CFDataGetLength(xmlKey);
+
+       /* send the key to the server */
+       status = confignotify(storePrivate->server,
+                             myKeyRef,
+                             myKeyLen,
+                             (int *)&sc_status);
+
+       /* clean up */
+       CFRelease(xmlKey);
+
+       if (status != KERN_SUCCESS) {
+               if (status != MACH_SEND_INVALID_DEST)
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("confignotify(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
+       }
+
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
+       }
+
+       return TRUE;
+}
index 7e1f7206f4275f4c2e6473ef08a7ba09472d785c..ce71d423a3fe2d26abed2eaa805624bb9d538d5e 100644 (file)
  * @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 <mach/mach.h>
 #include <mach/mach_error.h>
 #include <servers/bootstrap.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
 
+static CFStringRef
+__SCDynamicStoreCopyDescription(CFTypeRef cf) {
+       CFAllocatorRef          allocator       = CFGetAllocator(cf);
+       CFMutableStringRef      result;
+
+       result = CFStringCreateMutable(allocator, 0);
+       CFStringAppendFormat(result, NULL, CFSTR("<SCDynamicStore %p [%p]> {\n"), cf, allocator);
+       CFStringAppendFormat(result, NULL, CFSTR("}"));
 
-SCDSessionRef
-_SCDSessionCreatePrivate()
+       return result;
+}
+
+
+static void
+__SCDynamicStoreDeallocate(CFTypeRef cf)
 {
-       SCDSessionRef           newSession;
-       SCDSessionPrivateRef    newPrivate;
+       CFIndex                         keyCnt;
+       int                             oldThreadState;
+       int                             sc_status;
+       kern_return_t                   status;
+       SCDynamicStoreRef               store           = (SCDynamicStoreRef)cf;
+       SCDynamicStorePrivateRef        storePrivate    = (SCDynamicStorePrivateRef)store;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreDeallocate:"));
+
+       (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldThreadState);
+
+       /* Remove notification keys */
+       if ((keyCnt = CFSetGetCount(storePrivate->keys)) > 0) {
+               void            **watchedKeys;
+               CFArrayRef      keysToRemove;
+               CFIndex i;
+
+               watchedKeys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
+               CFSetGetValues(storePrivate->keys, watchedKeys);
+               keysToRemove = CFArrayCreate(NULL, watchedKeys, keyCnt, &kCFTypeArrayCallBacks);
+               CFAllocatorDeallocate(NULL, watchedKeys);
+               for (i=0; i<keyCnt; i++) {
+                       (void) SCDynamicStoreRemoveWatchedKey(store,
+                                                             CFArrayGetValueAtIndex(keysToRemove, i),
+                                                             FALSE);
+               }
+               CFRelease(keysToRemove);
+       }
+
+       /* Remove regex notification keys */
+       if ((keyCnt = CFSetGetCount(storePrivate->reKeys)) > 0) {
+               void            **watchedKeys;
+               CFArrayRef      keysToRemove;
+               CFIndex i;
+
+               watchedKeys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
+               CFSetGetValues(storePrivate->reKeys, watchedKeys);
+               keysToRemove = CFArrayCreate(NULL, watchedKeys, keyCnt, &kCFTypeArrayCallBacks);
+               CFAllocatorDeallocate(NULL, watchedKeys);
+               for (i=0; i<keyCnt; i++) {
+                      (void) SCDynamicStoreRemoveWatchedKey(store,
+                                                            CFArrayGetValueAtIndex(keysToRemove, i),
+                                                            TRUE);
+               }
+               CFRelease(keysToRemove);
+       }
+
+       /* Remove/cancel any outstanding notification requests. */
+       (void) SCDynamicStoreNotifyCancel(store);
+
+       if (storePrivate->server && storePrivate->locked) {
+               (void) SCDynamicStoreUnlock(store);     /* release the lock */
+       }
+
+       if (storePrivate->server != MACH_PORT_NULL) {
+               status = configclose(storePrivate->server, (int *)&sc_status);
+               if (status != KERN_SUCCESS) {
+                       if (status != MACH_SEND_INVALID_DEST)
+                               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configclose(): %s"), mach_error_string(status));
+               }
+
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+       }
+
+       (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldThreadState);
+       pthread_testcancel();
+
+       /* release any callback context info */
+       if (storePrivate->rlsContext.release) {
+               storePrivate->rlsContext.release(storePrivate->rlsContext.info);
+       }
 
-       /* allocate space */
-       newSession = (SCDSessionRef)CFAllocatorAllocate(NULL, sizeof(SCDSessionPrivate), 0);
-       newPrivate = (SCDSessionPrivateRef)newSession;
+       /* release any keys being watched */
+       CFRelease(storePrivate->keys);
+       CFRelease(storePrivate->reKeys);
+
+       return;
+}
+
+
+static CFTypeID __kSCDynamicStoreTypeID = _kCFRuntimeNotATypeID;
+
+
+static const CFRuntimeClass __SCDynamicStoreClass = {
+       0,                              // version
+       "SCDynamicStore",                       // className
+       NULL,                           // init
+       NULL,                           // copy
+       __SCDynamicStoreDeallocate,             // dealloc
+       NULL,                           // equal
+       NULL,                           // hash
+       NULL,                           // copyFormattingDesc
+       __SCDynamicStoreCopyDescription // copyDebugDesc
+};
+
+
+static pthread_once_t initialized      = PTHREAD_ONCE_INIT;
+
+
+static void
+__SCDynamicStoreInitialize(void) {
+       __kSCDynamicStoreTypeID = _CFRuntimeRegisterClass(&__SCDynamicStoreClass);
+       return;
+}
+
+
+SCDynamicStoreRef
+__SCDynamicStoreCreatePrivate(CFAllocatorRef           allocator,
+                            const CFStringRef          name,
+                            SCDynamicStoreCallBack     callout,
+                            SCDynamicStoreContext      *context)
+{
+       SCDynamicStorePrivateRef        store;
+       UInt32                          size;
+
+       /* initialize runtime */
+       pthread_once(&initialized, __SCDynamicStoreInitialize);
+
+       /* allocate session */
+       size  = sizeof(SCDynamicStorePrivate) - sizeof(CFRuntimeBase);
+       store = (SCDynamicStorePrivateRef)_CFRuntimeCreateInstance(allocator,
+                                                                  __kSCDynamicStoreTypeID,
+                                                                  size,
+                                                                  NULL);
+       if (!store) {
+               return NULL;
+       }
 
        /* server side of the "configd" session */
-       newPrivate->server         = MACH_PORT_NULL;
+       store->server = MACH_PORT_NULL;
 
-       /* per-session flags */
-       SCDOptionSet(newSession, kSCDOptionDebug,        SCDOptionGet(NULL, kSCDOptionDebug       ));
-       SCDOptionSet(newSession, kSCDOptionVerbose,      SCDOptionGet(NULL, kSCDOptionVerbose     ));
-       SCDOptionSet(newSession, kSCDOptionIsLocked,     FALSE);
-       SCDOptionSet(newSession, kSCDOptionUseSyslog,    SCDOptionGet(NULL, kSCDOptionUseSyslog   ));
-       SCDOptionSet(newSession, kSCDOptionUseCFRunLoop, SCDOptionGet(NULL, kSCDOptionUseCFRunLoop));
+       /* flags */
+       store->locked = FALSE;
 
        /* SCDKeys being watched */
-       newPrivate->keys   = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
-       newPrivate->reKeys = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+       store->keys   = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+       store->reKeys = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+
+       /* Notification status */
+       store->notifyStatus             = NotifierNotRegistered;
 
-       /* No notifications pending */
-       newPrivate->notifyStatus                = NotifierNotRegistered;
+       /* "client" information associated with SCDynamicStoreCreateRunLoopSource() */
+       store->rlsRefs                          = 0;
+       store->rls                              = NULL;
+       store->rlsFunction                      = callout;
+       store->rlsContext.info                  = NULL;
+       store->rlsContext.retain                = NULL;
+       store->rlsContext.release               = NULL;
+       store->rlsContext.copyDescription       = NULL;
+       if (context) {
+               bcopy(context, &store->rlsContext, sizeof(SCDynamicStoreContext));
+               if (context->retain) {
+                       store->rlsContext.info = (void *)context->retain(context->info);
+               }
+       }
 
-       /* "client" information about active (notification) callback */
-       newPrivate->callbackFunction            = NULL;
-       newPrivate->callbackArgument            = NULL;
-       newPrivate->callbackPort                = NULL;
-       newPrivate->callbackRunLoopSource       = NULL; /* XXX */
-       newPrivate->callbackHelper              = NULL;
+       /* "client" information associated with SCDynamicStoreNotifyCallback() */
+       store->callbackFunction         = NULL;
+       store->callbackArgument         = NULL;
+       store->callbackPort             = NULL;
+       store->callbackRunLoop          = NULL;
+       store->callbackRunLoopSource    = NULL;
 
-       /* "server" information associated with SCDNotifierInformViaMachPort(); */
-       newPrivate->notifyPort                  = MACH_PORT_NULL;
-       newPrivate->notifyPortIdentifier        = 0;
+       /* "server" information associated with SCDynamicStoreNotifyMachPort(); */
+       store->notifyPort               = MACH_PORT_NULL;
+       store->notifyPortIdentifier     = 0;
 
-       /* "server" information associated with SCDNotifierInformViaFD(); */
-       newPrivate->notifyFile                  = -1;
-       newPrivate->notifyFileIdentifier        = 0;
+       /* "server" information associated with SCDynamicStoreNotifyFileDescriptor(); */
+       store->notifyFile               = -1;
+       store->notifyFileIdentifier     = 0;
 
-       /* "server" information associated with SCDNotifierInformViaSignal(); */
-       newPrivate->notifySignal                = 0;
-       newPrivate->notifySignalTask            = TASK_NULL;
+       /* "server" information associated with SCDynamicStoreNotifySignal(); */
+       store->notifySignal             = 0;
+       store->notifySignalTask         = TASK_NULL;
 
-       return newSession;
+       return (SCDynamicStoreRef)store;
 }
 
 
-SCDStatus
-SCDOpen(SCDSessionRef *session, CFStringRef name)
+SCDynamicStoreRef
+SCDynamicStoreCreate(CFAllocatorRef            allocator,
+                    CFStringRef                name,
+                    SCDynamicStoreCallBack     callout,
+                    SCDynamicStoreContext      *context)
 {
-       SCDSessionPrivateRef    sessionPrivate;
-       kern_return_t           status;
-       mach_port_t             bootstrap_port;
-       mach_port_t             server;
-       CFDataRef               xmlName;                /* serialized name */
-       xmlData_t               myNameRef;
-       CFIndex                 myNameLen;
-       SCDStatus               scd_status;
-
-       SCDLog(LOG_DEBUG, CFSTR("SCDOpen:"));
-       SCDLog(LOG_DEBUG, CFSTR("  name = %@"), name);
+       SCDynamicStoreRef               store;
+       SCDynamicStorePrivateRef        storePrivate;
+       kern_return_t                   status;
+       mach_port_t                     bootstrap_port;
+       mach_port_t                     server;
+       CFDataRef                       xmlName;                /* serialized name */
+       xmlData_t                       myNameRef;
+       CFIndex                         myNameLen;
+       int                             sc_status;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreCreate:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  name = %@"), name);
 
        /*
         * allocate and initialize a new session
         */
-       sessionPrivate = (SCDSessionPrivateRef)_SCDSessionCreatePrivate();
-       *session       = (SCDSessionRef)sessionPrivate;
+       store        = __SCDynamicStoreCreatePrivate(allocator, name, callout, context);
+       storePrivate = (SCDynamicStorePrivateRef)store;
 
        status = task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("task_get_bootstrap_port(): %s"), mach_error_string(status));
-               CFAllocatorDeallocate(NULL, sessionPrivate);
-               *session = NULL;
-               return SCD_NOSERVER;
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("task_get_bootstrap_port(): %s"), mach_error_string(status));
+               CFRelease(store);
+               _SCErrorSet(status);
+               return NULL;
        }
 
        status = bootstrap_look_up(bootstrap_port, SCD_SERVER, &server);
@@ -115,17 +275,17 @@ SCDOpen(SCDSessionRef *session, CFStringRef name)
                        break;
                case BOOTSTRAP_UNKNOWN_SERVICE :
                        /* service not currently registered, try again later */
-                       CFAllocatorDeallocate(NULL, sessionPrivate);
-                       *session = NULL;
-                       return SCD_NOSERVER;
+                       CFRelease(store);
+                       _SCErrorSet(status);
+                       return NULL;
                        break;
                default :
 #ifdef DEBUG
-                       SCDLog(LOG_DEBUG, CFSTR("bootstrap_status: %s"), mach_error_string(status));
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("bootstrap_status: %s"), mach_error_string(status));
 #endif /* DEBUG */
-                       CFAllocatorDeallocate(NULL, sessionPrivate);
-                       *session = NULL;
-                       return SCD_NOSERVER;
+                       CFRelease(store);
+                       _SCErrorSet(status);
+                       return NULL;
        }
 
        /* serialize the name */
@@ -134,19 +294,31 @@ SCDOpen(SCDSessionRef *session, CFStringRef name)
        myNameLen = CFDataGetLength(xmlName);
 
        /* open a new session with the server */
-       status = configopen(server, myNameRef, myNameLen, &sessionPrivate->server, (int *)&scd_status);
+       status = configopen(server, myNameRef, myNameLen, &storePrivate->server, (int *)&sc_status);
 
        /* clean up */
        CFRelease(xmlName);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("configopen(): %s"), mach_error_string(status));
-               CFAllocatorDeallocate(NULL, sessionPrivate);
-               *session = NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configopen(): %s"), mach_error_string(status));
+               CFRelease(store);
+               _SCErrorSet(status);
+               return NULL;
+       }
+
+       if (sc_status != kSCStatusOK) {
+               CFRelease(store);
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
-       SCDLog(LOG_DEBUG, CFSTR("  server port = %d"), sessionPrivate->server);
-       return scd_status;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  server port = %d"), storePrivate->server);
+       return store;
+}
+
+
+CFTypeID
+SCDynamicStoreGetTypeID(void) {
+       return __kSCDynamicStoreTypeID;
 }
diff --git a/SystemConfiguration.fproj/SCDPlugin.h b/SystemConfiguration.fproj/SCDPlugin.h
new file mode 100644 (file)
index 0000000..e0cf531
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCDPLUGIN_H
+#define _SCDPLUGIN_H
+
+#include <sys/cdefs.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+
+/*!
+       @header SCDPlugin
+ */
+
+
+/*
+       @define kSCBundleRequires
+ */
+#define kSCBundleRequires      CFSTR("Requires")
+
+
+/*
+       @define kSCBundleVerbose
+ */
+#define kSCBundleVerbose       CFSTR("Verbose")
+
+
+/*!
+       @typedef SCDynamicStoreBundleLoadFunction
+       @discussion Type of the load() initialization function that will be
+               called when a plug-in is loaded.  This function is called
+               before calling the start() function and can be uesd to
+               initialize any variables, open any sessions with "configd",
+               and register any needed notifications.
+       @param bundle The CFBundle being loaded.
+       @param verbose A boolean value indicating whether verbose logging has
+               been enabled for this bundle.
+ */
+typedef void   (*SCDynamicStoreBundleLoadFunction)     (CFBundleRef    bundle,
+                                                        Boolean        bundleVerbose);
+
+/*!
+       @typedef SCDynamicStoreBundleStartFunction
+       @discussion Type of the start() initialization function that will be
+               called after all plug-ins have been loaded and their load()
+               functions have been called.  This function can initialize
+               variables, open sessions with "configd", and register any
+               needed notifications.
+       @param bundleName The name of the plug-in / bundle.
+       @param bundlePath The path name associated with the plug-in / bundle.
+ */
+typedef void   (*SCDynamicStoreBundleStartFunction)    (const char     *bundleName,
+                                                        const char     *bundlePath);
+
+/*!
+       @typedef SCDynamicStoreBundlePrimeFunction
+       @discussion Type of the prime() initialization function that will be
+               called after all plug-ins have executed their start() function but
+               before the main plug-in run loop is started.  This function should
+               be used to initialize any configuration information and/or state
+               in the store.
+ */
+typedef void   (*SCDynamicStoreBundlePrimeFunction)    ();
+
+
+__BEGIN_DECLS
+
+__END_DECLS
+
+#endif /* _SCDPLUGIN_H */
index 86a6f03f5333d596956c663c92d8cf5bf460b2c8..8e0b6ba4141e903558389ce7ad67e6aa91b1003c 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+
 #include <mach/mach.h>
 #include <mach/notify.h>
 #include <mach/mach_error.h>
 #include <pthread.h>
 
-#include "SCDPrivate.h"
-
-
-__private_extern__ mach_msg_id_t
-_waitForMachMessage(mach_port_t port)
-{
-       kern_return_t           status;
-       mach_msg_empty_rcv_t    *buf;
-
-       mach_msg_size_t         size = sizeof(mach_msg_empty_t) + MAX_TRAILER_SIZE;
-
-       status = vm_allocate(mach_task_self(), (vm_address_t *)&buf, size, TRUE);
-       if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
-               return -1;
-       }
-
-       status = mach_msg(&buf->header,                 /* msg */
-                         MACH_RCV_MSG,                 /* options */
-                         0,                            /* send_size */
-                         size,                         /* rcv_size */
-                         port,                         /* rcv_name */
-                         MACH_MSG_TIMEOUT_NONE,        /* timeout */
-                         MACH_PORT_NULL);              /* notify */
-       if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("mach_msg(): %s"), mach_error_string(status));
-               return -1;
-       }
-
-       return buf->header.msgh_id;
-}
-
-
 void
-_showMachPortStatus()
+__showMachPortStatus()
 {
 #ifdef DEBUG
        /* print status of in-use mach ports */
-       if (SCDOptionGet(NULL, kSCDOptionDebug) && SCDOptionGet(NULL, kSCDOptionVerbose)) {
+       if (_sc_debug) {
                kern_return_t           status;
                mach_port_name_array_t  ports;
                mach_port_type_array_t  types;
                int                     pi, pn, tn;
                CFMutableStringRef      str;
 
-               SCDLog(LOG_DEBUG, CFSTR("----------"));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("----------"));
 
                /* report on ALL mach ports associated with this task */
                status = mach_port_names(mach_task_self(), &ports, &pn, &types, &tn);
@@ -97,11 +77,11 @@ _showMachPortStatus()
                                *rp = '\0';
                                CFStringAppendFormat(str, NULL, CFSTR(" %d%s"), ports[pi], rights);
                        }
-                       SCDLog(LOG_DEBUG, CFSTR("Task ports (n=%d):%@"), pn, str);
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("Task ports (n=%d):%@"), pn, str);
                        CFRelease(str);
                } else {
                        /* log (but ignore) errors */
-                       SCDLog(LOG_DEBUG, CFSTR("mach_port_names(): %s"), mach_error_string(status));
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("mach_port_names(): %s"), mach_error_string(status));
                }
        }
 #endif /* DEBUG */
@@ -110,7 +90,7 @@ _showMachPortStatus()
 
 
 void
-_showMachPortReferences(mach_port_t port)
+__showMachPortReferences(mach_port_t port)
 {
 #ifdef DEBUG
        kern_return_t           status;
@@ -120,39 +100,39 @@ _showMachPortReferences(mach_port_t port)
        mach_port_urefs_t       refs_pset       = 0;
        mach_port_urefs_t       refs_dead       = 0;
 
-       SCDLog(LOG_DEBUG, CFSTR("user references for mach port %d"), port);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("user references for mach port %d"), port);
 
        status = mach_port_get_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND,      &refs_send);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("  mach_port_get_refs(MACH_PORT_RIGHT_SEND): %s"), mach_error_string(status));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  mach_port_get_refs(MACH_PORT_RIGHT_SEND): %s"), mach_error_string(status));
                return;
        }
 
        status = mach_port_get_refs(mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE,   &refs_recv);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("  mach_port_get_refs(MACH_PORT_RIGHT_RECEIVE): %s"), mach_error_string(status));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  mach_port_get_refs(MACH_PORT_RIGHT_RECEIVE): %s"), mach_error_string(status));
                return;
        }
 
        status = mach_port_get_refs(mach_task_self(), port, MACH_PORT_RIGHT_SEND_ONCE, &refs_once);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("  mach_port_get_refs(MACH_PORT_RIGHT_SEND_ONCE): %s"), mach_error_string(status));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  mach_port_get_refs(MACH_PORT_RIGHT_SEND_ONCE): %s"), mach_error_string(status));
                return;
        }
 
        status = mach_port_get_refs(mach_task_self(), port, MACH_PORT_RIGHT_PORT_SET,  &refs_pset);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("  mach_port_get_refs(MACH_PORT_RIGHT_PORT_SET): %s"), mach_error_string(status));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  mach_port_get_refs(MACH_PORT_RIGHT_PORT_SET): %s"), mach_error_string(status));
                return;
        }
 
        status = mach_port_get_refs(mach_task_self(), port, MACH_PORT_RIGHT_DEAD_NAME, &refs_dead);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("  mach_port_get_refs(MACH_PORT_RIGHT_DEAD_NAME): %s"), mach_error_string(status));
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  mach_port_get_refs(MACH_PORT_RIGHT_DEAD_NAME): %s"), mach_error_string(status));
                return;
        }
 
-       SCDLog(LOG_DEBUG,
+       SCLog(_sc_verbose, LOG_DEBUG,
               CFSTR("  send = %d, receive = %d, send once = %d, port set = %d, dead name = %d"),
               refs_send,
               refs_recv,
diff --git a/SystemConfiguration.fproj/SCDPrivate.h b/SystemConfiguration.fproj/SCDPrivate.h
deleted file mode 100644 (file)
index 3601d35..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2000 Apple Computer, 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 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.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef _SCDPRIVATE_H
-#define _SCDPRIVATE_H
-
-#include <SystemConfiguration/SCD.h>
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <regex.h>
-#include <pthread.h>
-#include <CoreFoundation/CFMachPort.h>
-
-
-/* Define the per-session (and global) flags */
-typedef struct {
-       int                     debug;
-       int                     verbose;
-       boolean_t               isLocked;
-       boolean_t               useSyslog;
-       boolean_t               useCFRunLoop;
-} _SCDFlags;
-
-
-/* Define the status of any registered notification. */
-typedef enum {
-       NotifierNotRegistered = 0,
-       Using_NotifierWait,
-       Using_NotifierInformViaCallback,
-       Using_NotifierInformViaMachPort,
-       Using_NotifierInformViaFD,
-       Using_NotifierInformViaSignal,
-} _SCDNotificationStatus;
-
-
-typedef struct {
-
-       /* server side of the "configd" session */
-       mach_port_t             server;
-
-       /* per-session flags */
-       _SCDFlags               flags;
-
-       /* SCDKeys being watched */
-       CFMutableSetRef         keys;
-       CFMutableSetRef         reKeys;
-
-       /* current status of notification requests */
-       _SCDNotificationStatus  notifyStatus;
-
-       /* "client" information associated with SCDNotifierInformViaCallback() */
-       SCDCallbackRoutine_t    callbackFunction;
-       void                    *callbackArgument;
-       CFMachPortRef           callbackPort;
-       CFRunLoopSourceRef      callbackRunLoopSource;  /* XXX CFMachPortInvalidate() doesn't work */
-       pthread_t               callbackHelper;
-
-       /* "server" information associated with SCDNotifierInformViaMachPort() */
-       mach_port_t             notifyPort;
-       mach_msg_id_t           notifyPortIdentifier;
-
-       /* "server" information associated with SCDNotifierInformViaFD() */
-       int                     notifyFile;
-       int                     notifyFileIdentifier;
-
-       /* "server" information associated with SCDNotifierInformViaSignal() */
-       int                     notifySignal;
-       task_t                  notifySignalTask;
-
-} SCDSessionPrivate, *SCDSessionPrivateRef;
-
-
-typedef struct {
-
-       /* configuration data associated with key */
-       CFPropertyListRef       data;
-
-       /* instance value of last fetched data */
-       int                     instance;
-
-} SCDHandlePrivate, *SCDHandlePrivateRef;
-
-
-/* per-session options */
-typedef enum {
-       kSCDOptionIsLocked = 1024,
-} SCDServerSessionOptions;
-
-
-/* global options */
-typedef enum {
-       kSCDOptionIsServer = 2048,
-} SCDServerGlobalOptions;
-
-
-__BEGIN_DECLS
-
-SCDSessionRef  _SCDSessionCreatePrivate        ();
-
-void           _SCDHandleSetInstance           (SCDHandleRef   handle,
-                                                int            instance);
-
-mach_msg_id_t  _waitForMachMessage             (mach_port_t    port);
-
-void           _showMachPortStatus             ();
-void           _showMachPortReferences         (mach_port_t    port);
-
-__END_DECLS
-
-#endif /* !_SCDPRIVATE_H */
index 30cc8b1016314c359da7b3b3149dc8e461fb893e..0f08ccc6ee16755033997d359bd4b3e2c25b8e91 100644 (file)
  * @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 <mach/mach.h>
 #include <mach/mach_error.h>
-
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
 
 
-SCDStatus
-SCDRemove(SCDSessionRef session, CFStringRef key)
+Boolean
+SCDynamicStoreRemoveValue(SCDynamicStoreRef store, CFStringRef key)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       CFDataRef               xmlKey;         /* serialized key */
-       xmlData_t               myKeyRef;
-       CFIndex                 myKeyLen;
-       SCDStatus               scd_status;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlKey;         /* serialized key */
+       xmlData_t                       myKeyRef;
+       CFIndex                         myKeyLen;
+       int                             sc_status;
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDRemove:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key      = %@"), key);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreRemoveValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key      = %@"), key);
 
-       if (key == NULL) {
-               return SCD_INVALIDARGUMENT;     /* no key specified */
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
        }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
        /* serialize the key */
@@ -55,21 +69,27 @@ SCDRemove(SCDSessionRef session, CFStringRef key)
        myKeyLen = CFDataGetLength(xmlKey);
 
        /* send the key to the server */
-       status = configremove(sessionPrivate->server,
+       status = configremove(storePrivate->server,
                              myKeyRef,
                              myKeyLen,
-                             (int *)&scd_status);
+                             (int *)&sc_status);
 
        /* clean up */
        CFRelease(xmlKey);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("configremove(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configremove(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
+       }
+
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
-       return scd_status;
+       return TRUE;
 }
index 1cb79ad34c88d576b6c54662886850b61149c76a..da4fd4c83080f2a318e96c656fb6b5a8c00bd86a 100644 (file)
  * @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 <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
 
+Boolean
+SCDynamicStoreSetMultiple(SCDynamicStoreRef    store,
+                         CFDictionaryRef       keysToSet,
+                         CFArrayRef            keysToRemove,
+                         CFArrayRef            keysToNotify)
+{
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlSet          = NULL; /* key/value pairs to set (XML serialized) */
+       xmlData_t                       mySetRef        = NULL; /* key/value pairs to set (serialized) */
+       CFIndex                         mySetLen        = 0;
+       CFDataRef                       xmlRemove       = NULL; /* keys to remove (XML serialized) */
+       xmlData_t                       myRemoveRef     = NULL; /* keys to remove (serialized) */
+       CFIndex                         myRemoveLen     = 0;
+       CFDataRef                       xmlNotify       = NULL; /* keys to notify (XML serialized) */
+       xmlData_t                       myNotifyRef     = NULL; /* keys to notify (serialized) */
+       CFIndex                         myNotifyLen     = 0;
+       int                             sc_status;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreSetMultiple:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  keysToSet    = %@"), keysToSet);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  keysToRemove = %@"), keysToRemove);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  keysToNotify = %@"), keysToNotify);
+
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return NULL;
+       }
+
+       if (storePrivate->server == MACH_PORT_NULL) {
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return NULL;    /* you must have an open session to play */
+       }
+
+       /* serialize the key/value pairs to set*/
+       if (keysToSet) {
+               xmlSet   = CFPropertyListCreateXMLData(NULL, keysToSet);
+               mySetRef = (xmlData_t)CFDataGetBytePtr(xmlSet);
+               mySetLen = CFDataGetLength(xmlSet);
+       }
+
+       /* serialize the keys to remove */
+       if (keysToRemove) {
+               xmlRemove   = CFPropertyListCreateXMLData(NULL, keysToRemove);
+               myRemoveRef = (xmlData_t)CFDataGetBytePtr(xmlRemove);
+               myRemoveLen = CFDataGetLength(xmlRemove);
+       }
 
-SCDStatus
-SCDSet(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
+       /* serialize the keys to notify */
+       if (keysToNotify) {
+               xmlNotify   = CFPropertyListCreateXMLData(NULL, keysToNotify);
+               myNotifyRef = (xmlData_t)CFDataGetBytePtr(xmlNotify);
+               myNotifyLen = CFDataGetLength(xmlNotify);
+       }
+
+       /* send the keys and patterns, fetch the associated result from the server */
+       status = configset_m(storePrivate->server,
+                            mySetRef,
+                            mySetLen,
+                            myRemoveRef,
+                            myRemoveLen,
+                            myNotifyRef,
+                            myNotifyLen,
+                            (int *)&sc_status);
+
+       /* clean up */
+       if (xmlSet)     CFRelease(xmlSet);
+       if (xmlRemove)  CFRelease(xmlRemove);
+       if (xmlNotify)  CFRelease(xmlNotify);
+
+       if (status != KERN_SUCCESS) {
+               if (status != MACH_SEND_INVALID_DEST)
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configset_m(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
+       }
+
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+Boolean
+SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       CFDataRef               xmlKey;         /* serialized key */
-       xmlData_t               myKeyRef;
-       CFIndex                 myKeyLen;
-       CFDataRef               xmlData;        /* serialized data */
-       xmlData_t               myDataRef;
-       CFIndex                 myDataLen;
-       SCDStatus               scd_status;
-       int                     newInstance;
-
-       SCDLog(LOG_DEBUG, CFSTR("SCDSet:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key          = %@"), key);
-       SCDLog(LOG_DEBUG, CFSTR("  data         = %@"), SCDHandleGetData(handle));
-       SCDLog(LOG_DEBUG, CFSTR("  instance     = %d"), SCDHandleGetInstance(handle));
-
-       if (key == NULL) {
-               return SCD_INVALIDARGUMENT;     /* no key specified */
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlKey;         /* serialized key */
+       xmlData_t                       myKeyRef;
+       CFIndex                         myKeyLen;
+       CFDataRef                       xmlData;        /* serialized data */
+       xmlData_t                       myDataRef;
+       CFIndex                         myDataLen;
+       int                             sc_status;
+       int                             newInstance;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreSetValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key          = %@"), key);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  value        = %@"), value);
+
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
        }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
        /* serialize the key and data */
@@ -60,19 +161,19 @@ SCDSet(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
        myKeyRef = (xmlData_t)CFDataGetBytePtr(xmlKey);
        myKeyLen = CFDataGetLength(xmlKey);
 
-       xmlData = CFPropertyListCreateXMLData(NULL, SCDHandleGetData(handle));
+       xmlData = CFPropertyListCreateXMLData(NULL, value);
        myDataRef = (xmlData_t)CFDataGetBytePtr(xmlData);
        myDataLen = CFDataGetLength(xmlData);
 
        /* send the key & data to the server, get new instance id */
-       status = configset(sessionPrivate->server,
+       status = configset(storePrivate->server,
                           myKeyRef,
                           myKeyLen,
                           myDataRef,
                           myDataLen,
-                          SCDHandleGetInstance(handle),
+                          0,
                           &newInstance,
-                          (int *)&scd_status);
+                          (int *)&sc_status);
 
        /* clean up */
        CFRelease(xmlKey);
@@ -80,17 +181,17 @@ SCDSet(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("configset(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configset(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
        }
 
-       if (scd_status == SCD_OK) {
-               _SCDHandleSetInstance(handle, newInstance);
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
-       SCDLog(LOG_DEBUG, CFSTR("  new instance = %d"), SCDHandleGetInstance(handle));
-
-       return scd_status;
+       return TRUE;
 }
index 1339cdab0ea1257d1786de22128af2e6ace2f900..03bbffc4d6a7fddbddb9770856d68d52d5c418be 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * April 14, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
 
-
-SCDStatus
-SCDSnapshot(SCDSessionRef session)
+Boolean
+SCDynamicStoreSnapshot(SCDynamicStoreRef store)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       SCDStatus               scd_status;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       int                             sc_status;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreSnapshot:"));
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDSnapshot:"));
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
+       }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;   /* you must have an open session to play */
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
-       status = snapshot(sessionPrivate->server, (int *)&scd_status);
+       status = snapshot(storePrivate->server, (int *)&sc_status);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("snapshot(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("snapshot(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
+       }
+
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
-       return scd_status;
+       return TRUE;
 }
index 2e83c37a6a89fd4129fd759165cc36e852df4eaa..ac3d6c497261f298b8dfa310a418ce2f51143dae 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * June 20, 2000               Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
-
 
-SCDStatus
-SCDTouch(SCDSessionRef session, CFStringRef key)
+Boolean
+SCDynamicStoreTouchValue(SCDynamicStoreRef store, CFStringRef key)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       CFDataRef               xmlKey;         /* serialized key */
-       xmlData_t               myKeyRef;
-       CFIndex                 myKeyLen;
-       SCDStatus               scd_status;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       CFDataRef                       xmlKey;         /* serialized key */
+       xmlData_t                       myKeyRef;
+       CFIndex                         myKeyLen;
+       int                             sc_status;
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDTouch:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key = %@"), key);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreTouchValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key = %@"), key);
 
-       if (key == NULL) {
-               return SCD_INVALIDARGUMENT;     /* no key specified */
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
        }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
        }
 
        /* serialize the key */
@@ -55,21 +69,27 @@ SCDTouch(SCDSessionRef session, CFStringRef key)
        myKeyLen = CFDataGetLength(xmlKey);
 
        /* send the key to the server */
-       status = configtouch(sessionPrivate->server,
+       status = configtouch(storePrivate->server,
                             myKeyRef,
                             myKeyLen,
-                            (int *)&scd_status);
+                            (int *)&sc_status);
 
        /* clean up */
        CFRelease(xmlKey);
 
        if (status != KERN_SUCCESS) {
                if (status != MACH_SEND_INVALID_DEST)
-                       SCDLog(LOG_DEBUG, CFSTR("configtouch(): %s"), mach_error_string(status));
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-               sessionPrivate->server = MACH_PORT_NULL;
-               return SCD_NOSERVER;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configtouch(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
+       }
+
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
-       return scd_status;
+       return TRUE;
 }
index c1540b9fc4cb10fbefdfebf7faa794866b287ea5..38e7745fb1df67c1b7d94bffb00eb7823cc4e93a 100644 (file)
  * @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 <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
 #include "config.h"            /* MiG generated file */
-#include "SCDPrivate.h"
-
 
-SCDStatus
-SCDUnlock(SCDSessionRef session)
+Boolean
+SCDynamicStoreUnlock(SCDynamicStoreRef store)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       kern_return_t           status;
-       SCDStatus               scd_status;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       kern_return_t                   status;
+       int                             sc_status;
 
-       SCDLog(LOG_DEBUG, CFSTR("SCDUnlock:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreUnlock:"));
 
-       if (session == NULL) {
-               return SCD_NOSESSION;           /* you can't do anything without closed session */
+       if (!store) {
+               /* sorry, you must provide a session */
+               _SCErrorSet(kSCStatusNoStoreSession);
+               return FALSE;
        }
 
-       scd_status = (sessionPrivate->server == MACH_PORT_NULL) ? SCD_NOSESSION : SCD_OK;
+       if (storePrivate->server == MACH_PORT_NULL) {
+               /* sorry, you must have an open session to play */
+               _SCErrorSet(kSCStatusNoStoreServer);
+               return FALSE;
+       }
 
-       if (scd_status == SCD_OK) {
-               /* (attempt to) release the servers lock */
-               status = configunlock(sessionPrivate->server, (int *)&scd_status);
+       /* (attempt to) release the servers lock */
+       status = configunlock(storePrivate->server, (int *)&sc_status);
+       if (status != KERN_SUCCESS) {
+               if (status != MACH_SEND_INVALID_DEST)
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configunlock(): %s"), mach_error_string(status));
+               (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+               storePrivate->server = MACH_PORT_NULL;
+               _SCErrorSet(status);
+               return FALSE;
+       }
 
-               if (status != KERN_SUCCESS) {
-                       if (status != MACH_SEND_INVALID_DEST)
-                               SCDLog(LOG_DEBUG, CFSTR("configunlock(): %s"), mach_error_string(status));
-                       (void) mach_port_destroy(mach_task_self(), sessionPrivate->server);
-                       sessionPrivate->server = MACH_PORT_NULL;
-                       return SCD_NOSERVER;
-               }
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
        }
 
-       return scd_status;
+       return TRUE;
 }
diff --git a/SystemConfiguration.fproj/SCDynamicStore.h b/SystemConfiguration.fproj/SCDynamicStore.h
new file mode 100644 (file)
index 0000000..9347352
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCDYNAMICSTORE_H
+#define _SCDYNAMICSTORE_H
+
+#include <sys/cdefs.h>
+#include <sys/syslog.h>
+#include <mach/message.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+
+/*!
+       @header SCDynamicStore
+       The SystemConfiguration framework provides access to the
+       data used to configure a running system.  The APIs provided
+       by this framework communicate with the "configd" daemon.
+
+       The "configd" daemon manages a "dynamic store" reflecting the
+       desired configuration settings as well as the current state
+       of the system.  The daemon provides a notification mechanism
+       for user-level processes that need to be aware of changes
+       made to the data.  Lastly, the daemon loads a number of
+       bundles (or plug-ins) that monitor low-level kernel events
+       and, via a set of policy modules, keep the state data up
+       to date.
+ */
+
+
+/*!
+       @typedef SCDynamicStoreRef
+       @discussion This is the handle to an open "dynamic store" session
+               with the system configuration daemon.
+ */
+typedef const struct __SCDynamicStore *        SCDynamicStoreRef;
+
+/*!
+       @typedef SCDynamicStoreContext
+ */
+typedef struct {
+       CFIndex         version;
+       void *          info;
+       const void      *(*retain)(const void *info);
+       void            (*release)(const void *info);
+       CFStringRef     (*copyDescription)(const void *info);
+} SCDynamicStoreContext;
+
+/*!
+       @typedef SCDynamicStoreCallBack
+       @discussion Type of the callback function used when a
+               dynamic store change is delivered.
+       @param store The "dynamic store" session.
+       @param changedKeys The list of changed keys.
+       @param info ....
+ */
+typedef void (*SCDynamicStoreCallBack) (
+                                       SCDynamicStoreRef       store,
+                                       CFArrayRef              changedKeys,
+                                       void                    *info
+                                       );
+
+
+__BEGIN_DECLS
+
+/*!
+       @function SCDynamicStoreGetTypeID
+       Returns the type identifier of all SCDynamicStore instances.
+ */
+CFTypeID
+SCDynamicStoreGetTypeID                        (void);
+
+
+/*!
+       @function SCDynamicStoreCreate
+       @discussion Creates a new session used to interact with the dynamic
+               store maintained by the SystemConfiguration server.
+       @param allocator The CFAllocator which should be used to allocate
+               memory for the local "dynamic store" and its storage for
+               values.
+               This parameter may be NULL in which case the current
+               default CFAllocator is used. If this reference is not
+               a valid CFAllocator, the behavior is undefined.
+       @param name A string that describes the name of the calling
+               process or plug-in of the caller.
+       @param callout The function to be called when a watched value
+               in the "dynamic store" is changed.
+               A NULL value can be specified if no callouts are
+               desired.
+       @param context The SCDynamicStoreContext associated with the callout.
+       @result A reference to the new SCDynamicStore.
+ */
+SCDynamicStoreRef
+SCDynamicStoreCreate                   (
+                                       CFAllocatorRef                  allocator,
+                                       CFStringRef                     name,
+                                       SCDynamicStoreCallBack          callout,
+                                       SCDynamicStoreContext           *context
+                                       );
+
+/*!
+       @function SCDynamicStoreCreateRunLoopSource
+       @discussion Creates a new session used to interact with the dynamic
+               store maintained by the SystemConfiguration server.
+       @param allocator The CFAllocator which should be used to allocate
+               memory for the local "dynamic store" and its storage for
+               values.
+               This parameter may be NULL in which case the current
+               default CFAllocator is used. If this reference is not
+               a valid CFAllocator, the behavior is undefined.
+       @param store The "dynamic store" session.
+       @param order On platforms which support it, this parameter
+               determines the order in which the sources which are
+               ready to be processed are handled.  A lower order
+               number causes processing before higher order number
+               sources. It is inadvisable to depend on the order
+               number for any architectural or design aspect of
+               code. In the absence of any reason to do otherwise,
+               zero should be used.
+       @result A reference to the new CFRunLoopSource.
+               You must release the returned value.
+
+ */
+CFRunLoopSourceRef
+SCDynamicStoreCreateRunLoopSource      (
+                                       CFAllocatorRef                  allocator,
+                                       SCDynamicStoreRef               store,
+                                       CFIndex                         order
+                                       );
+
+/*!
+       @function SCDynamicStoreCopyKeyList
+       @discussion Returns an array of CFString keys representing the
+               configuration "dynamic store" entries that match a
+               specified pattern.
+       @param store The "dynamic store" session.
+       @param pattern A regex(3) regular expression pattern that
+               will be used to match the "dynamic store" keys.
+       @result The list of matching keys.
+               You must release the returned value.
+               A NULL value will be returned if the list could not be obtained.
+ */
+CFArrayRef
+SCDynamicStoreCopyKeyList              (
+                                       SCDynamicStoreRef               store,
+                                       CFStringRef                     pattern
+                                       );
+
+/*!
+       @function SCDynamicStoreAddValue
+       @discussion Adds the key-value pair to the "dynamic store" if no
+               such key already exists.
+       @param store The "dynamic store" session.
+       @param key The key of the value to add to the "dynamic store".
+       @param value The value to add to the "dynamic store".
+       @result TRUE if the key was added; FALSE if the key was already
+               present in the "dynamic store" or if an error was encountered.
+ */
+Boolean
+SCDynamicStoreAddValue                 (
+                                       SCDynamicStoreRef               store,
+                                       CFStringRef                     key,
+                                       CFPropertyListRef               value
+                                       );
+
+/*!
+       @function SCDynamicStoreAddTemporaryValue
+       @discussion Adds the key-value pair on a temporary basis to the
+               "dynamic store" if no such key already exists.  This entry
+               will, unless updated by another session, automatically be
+               removed when the session is closed.
+       @param store The "dynamic store" session.
+       @param key The key of the value to add to the "dynamic store".
+       @param value The value to add to the "dynamic store".
+       @result TRUE if the key was added; FALSE if the key was already
+               present in the "dynamic store" or if an error was encountered.
+ */
+Boolean
+SCDynamicStoreAddTemporaryValue                (
+                                       SCDynamicStoreRef               store,
+                                       CFStringRef                     key,
+                                       CFPropertyListRef               value
+                                       );
+
+/*!
+       @function SCDynamicStoreCopyValue
+       @discussion Obtains a value from the "dynamic store" for the
+               specified key.
+       @param store The "dynamic store" session.
+       @param key The key you wish to obtain.
+       @result The value from the store that is associated with the
+               given key.  The value is returned as a Core Foundation
+               Property List data type.
+               You must release the returned value.
+               If no value was located, NULL is returned.
+ */
+CFPropertyListRef
+SCDynamicStoreCopyValue                        (
+                                       SCDynamicStoreRef               store,
+                                       CFStringRef                     key
+                                       );
+
+/*!
+       @function SCDynamicStoreCopyMultiple
+       @discussion Fetches multiple values in the "dynamic store".
+       @param store The "dynamic store" session.
+       @param keys The keys to be fetched; NULL if no specific keys
+               are requested.
+       @param patterns The regex(3) pattern strings to be fetched; NULL
+               if no key patterns are requested.
+       @result A dictionary containing the specific keys which were found
+               in the "dynamic store" and any keys which matched the specified
+               patterns; NULL is returned if an error was encountered.
+               You must release the returned value.
+ */
+CFDictionaryRef
+SCDynamicStoreCopyMultiple             (
+                                       SCDynamicStoreRef               store,
+                                       CFArrayRef                      keys,
+                                       CFArrayRef                      patterns
+                                       );
+
+/*!
+       @function SCDynamicStoreSetValue
+       @discussion Adds or replaces a value in the "dynamic store" for
+               the specified key.
+       @param store The "dynamic store" session.
+       @param key The key you wish to set.
+       @param value The value to add to or replace in the "dynamic store".
+       @result TRUE if the key was updated; FALSE if an error was encountered.
+ */
+Boolean
+SCDynamicStoreSetValue                 (
+                                       SCDynamicStoreRef               store,
+                                       CFStringRef                     key,
+                                       CFPropertyListRef               value
+                                       );
+
+/*!
+       @function SCDynamicStoreSetMultiple
+       @discussion Updates multiple values in the "dynamic store".
+       @param store The "dynamic store" session.
+       @param keysToSet Key/value pairs you wish to set into the "dynamic store".
+       @param keysToRemove A list of keys you wish to remove from the "dynamic store".
+       @param keysToNotify A list of keys to flag as changed (without actually changing the data).
+       @result TRUE if the dynamic store updates were successful; FALSE if an error was encountered.
+ */
+Boolean
+SCDynamicStoreSetMultiple              (
+                                       SCDynamicStoreRef               store,
+                                       CFDictionaryRef                 keysToSet,
+                                       CFArrayRef                      keysToRemove,
+                                       CFArrayRef                      keysToNotify
+                                       );
+
+/*!
+       @function SCDynamicStoreRemoveValue
+       @discussion Removes the value of the specified key from the
+               "dynamic store".
+       @param store The "dynamic store" session.
+       @param key The key of the value you wish to remove.
+       @result TRUE if the key was removed; FALSE if no value was
+               located or an error was encountered.
+ */
+Boolean
+SCDynamicStoreRemoveValue              (
+                                       SCDynamicStoreRef               store,
+                                       CFStringRef                     key
+                                       );
+
+/*!
+       @function SCDynamicStoreNotifyValue
+       @discussion Triggers a notification to be delivered for the
+               specified key in the dynamic store.
+       @param store The "dynamic store" session.
+       @param key The key which should be flagged as changed (without actually changing the data).
+       @result TRUE if the value was updated; FALSE if an error was encountered.
+ */
+Boolean
+SCDynamicStoreNotifyValue              (
+                                       SCDynamicStoreRef               store,
+                                       CFStringRef                     key
+                                       );
+
+/*!
+       @function SCDynamicStoreSetNotificationKeys
+       @discussion Specifies a set of specific keys and key patterns
+               which should be monitored for changes.
+       @param store The "dynamic store" session being watched.
+       @param keys The keys to be monitored; NULL if no specific keys
+               are to be monitored.
+       @param patterns The regex(3) pattern strings to be monitored; NULL
+               if no key patterns are to be monitored.
+       @result TRUE if the monitored keys were set; FALSE if an error
+               was encountered.
+ */
+Boolean
+SCDynamicStoreSetNotificationKeys      (
+                                       SCDynamicStoreRef               store,
+                                       CFArrayRef                      keys,
+                                       CFArrayRef                      patterns
+                                       );
+
+/*!
+       @function SCDynamicStoreCopyNotifiedKeys
+       @discussion Returns an array of CFString keys representing the
+               "dynamic store" entries that have changed since this
+               function was last called.
+       @param store The "dynamic store" session.
+       @result The list of changed keys.
+               You must release the returned value.
+               A NULL value will be returned if the list could not be obtained.
+ */
+CFArrayRef
+SCDynamicStoreCopyNotifiedKeys         (
+                                       SCDynamicStoreRef               store
+                                       );
+
+__END_DECLS
+
+#endif /* _SCDYNAMICSTORE_H */
diff --git a/SystemConfiguration.fproj/SCDynamicStoreCopyDHCPInfo.h b/SystemConfiguration.fproj/SCDynamicStoreCopyDHCPInfo.h
new file mode 100644 (file)
index 0000000..fa34138
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2001 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCDYNAMICSTORECOPYDHCPINFO_H
+#define _SCDYNAMICSTORECOPYDHCPINFO_H
+
+#include <sys/cdefs.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SCDynamicStore.h>
+
+
+/*!
+       @header SCDynamicStoreCopyDHCPInfo.h
+       The following APIs allow an application to retrieve DHCP/BOOTP
+       information, in particular DHCP/BOOTP options.
+ */
+
+
+__BEGIN_DECLS
+
+/*!
+       @function SCDynamicStoreCopyDHCPInfo
+       @discussion Copies the DHCP/BOOTP information dictionary for the
+               requested serviceID, or the primary service if
+               serviceID == NULL.
+       @param store An SCDynamicStoreRef that should be used for communication
+               with the server.
+               If NULL, a temporary session will be used.
+       @param serviceID A CFStringRef containing the requested service.
+               If NULL, returns information for the primary service.
+       @result A dictionary containing DHCP/BOOTP information if successful,
+               NULL otherwise.
+               Use the DHCPInfoGetOption() to retrieve
+               individual options from the returned dictionary.
+
+               A non-NULL return value must be released using CFRelease().
+ */
+CFDictionaryRef
+SCDynamicStoreCopyDHCPInfo(SCDynamicStoreRef store, CFStringRef serviceID);
+
+/*!
+       @function DHCPInfoGetOptionData
+       @discussion Returns a non-NULL CFDataRef containing the BOOTP/DHCP
+               option data if present, NULL otherwise.
+       @param info The non-NULL DHCP information dictionary returned by
+               calling SCDynamicStoreCopyDHCPInfo.
+       @param code The DHCP/BOOTP option code (see RFC 2132) to return
+               data for.
+       @result A non-NULL CFDataRef containing the option data,
+               NULL otherwise.
+               
+               The return value must NOT be released.
+ */
+CFDataRef
+DHCPInfoGetOptionData(CFDictionaryRef info, UInt8 code);
+
+/*!
+       @function DHCPInfoGetLeaseStartTime
+       @discussion Returns a CFDateRef corresponding to the lease start time,
+               if present, NULL otherwise.  A NULL return value is returned
+               if the configuration method is BOOTP.
+       @param info The non-NULL DHCP information dictionary returned by
+               calling SCDynamicStoreCopyDHCPInfo.
+       @result A non-NULL CFDateRef if present, NULL otherwise.
+
+               The return value must NOT be released.
+ */
+CFDateRef
+DHCPInfoGetLeaseStartTime(CFDictionaryRef info);
+
+__END_DECLS
+
+#endif /* _SCDYNAMICSTORECOPYDHCPINFO_H */
diff --git a/SystemConfiguration.fproj/SCDynamicStoreCopySpecific.h b/SystemConfiguration.fproj/SCDynamicStoreCopySpecific.h
new file mode 100644 (file)
index 0000000..89ab3bf
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCDYNAMICSTORECOPYSPECIFIC_H
+#define _SCDYNAMICSTORECOPYSPECIFIC_H
+
+#include <sys/cdefs.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SCDynamicStore.h>
+
+
+/*!
+       @header SCDynamicStoreCopySpecific
+       The following APIs allow an application to determine specific
+       configuration information about the current system (e.g. the
+       computer/sharing name, the currently logged in user, etc).
+ */
+
+
+__BEGIN_DECLS
+
+/*!
+       @function SCDynamicStoreCopyComputerName
+       @discussion Gets the current computer/host name.
+       @param store An SCDynamicStoreRef that should be used for communication
+               with the server.
+               If NULL, a temporary session will be used.
+       @param nameEncoding A pointer to memory that, if non-NULL, will be
+               filled with the encoding associated with the computer/host name.
+       @result The current computer/host name;
+               NULL if the name has not been set or if an error was encountered.
+               You must release the returned value.
+ */
+CFStringRef
+SCDynamicStoreCopyComputerName         (
+                                       SCDynamicStoreRef       store,
+                                       CFStringEncoding        *nameEncoding
+                                       );
+
+/*!
+       @function SCDynamicStoreCopyConsoleUser
+       @discussion Gets the name, user ID, and group ID of the currently
+               logged in user.
+       @param store An SCDynamicStoreRef that should be used for communication
+               with the server.
+               If NULL, a temporary session will be used.
+       @param uid A pointer to memory that will be filled with the user ID
+               of the current "Console" user. If NULL, this value will not
+               be returned.
+       @param gid A pointer to memory that will be filled with the group ID
+               of the current "Console" user. If NULL, this value will not be
+               returned.
+       @result The current user logged into the system;
+               NULL if no user is logged in or if an error was encountered.
+               You must release the returned value.
+ */
+CFStringRef
+SCDynamicStoreCopyConsoleUser          (
+                                       SCDynamicStoreRef       session,
+                                       uid_t                   *uid,
+                                       gid_t                   *gid
+                                       );
+
+/*!
+       @function SCDynamicStoreCopyProxies
+       @discussion Gets the current internet proxy settings.
+       @param store An SCDynamicStoreRef that should be used for communication
+               with the server.
+               If NULL, a temporary session will be used.
+       @result A dictionary with key/value pairs representing the current
+               internet proxy settings (HTTP, FTP, etc);
+               NULL if no proxy settings have been defined or if an error was encountered.
+               You must release the returned value.
+ */
+CFDictionaryRef
+SCDynamicStoreCopyProxies              (
+                                       SCDynamicStoreRef       store
+                                       );
+
+__END_DECLS
+
+#endif /* _SCDYNAMICSTORECOPYSPECIFIC_H */
diff --git a/SystemConfiguration.fproj/SCDynamicStoreInternal.h b/SystemConfiguration.fproj/SCDynamicStoreInternal.h
new file mode 100644 (file)
index 0000000..f007b53
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCDYNAMICSTOREINTERNAL_H
+#define _SCDYNAMICSTOREINTERNAL_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <mach/mach.h>
+#include <pthread.h>
+#include <regex.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFRuntime.h>
+#include <SystemConfiguration/SCDynamicStore.h>
+
+
+/* Define the status of any registered notification. */
+typedef enum {
+       NotifierNotRegistered = 0,
+       Using_NotifierWait,
+       Using_NotifierInformViaCallback,
+       Using_NotifierInformViaMachPort,
+       Using_NotifierInformViaFD,
+       Using_NotifierInformViaSignal,
+       Using_NotifierInformViaRunLoop,
+} __SCDynamicStoreNotificationStatus;
+
+
+typedef struct {
+
+       /* base CFType information */
+       CFRuntimeBase                   cfBase;
+
+       /* server side of the "configd" session */
+       mach_port_t                     server;
+
+       /* per-session flags */
+       Boolean                         locked;
+
+       /* SCDynamicStoreKeys being watched */
+       CFMutableSetRef                 keys;
+       CFMutableSetRef                 reKeys;
+
+       /* current status of notification requests */
+       __SCDynamicStoreNotificationStatus      notifyStatus;
+
+       /* "client" information associated with SCDynamicStoreCreateRunLoopSource() */
+       CFIndex                         rlsRefs;
+       CFRunLoopSourceRef              rls;
+       SCDynamicStoreCallBack          rlsFunction;
+       SCDynamicStoreContext           rlsContext;
+
+       /* "client" information associated with SCDynamicStoreNotifyCallback() */
+       SCDynamicStoreCallBack_v1       callbackFunction;
+       void                            *callbackArgument;
+       CFMachPortRef                   callbackPort;
+       CFRunLoopRef                    callbackRunLoop;
+       CFRunLoopSourceRef              callbackRunLoopSource;
+
+       /* "server" information associated with SCDynamicStoreNotifyMachPort() */
+       mach_port_t                     notifyPort;
+       mach_msg_id_t                   notifyPortIdentifier;
+
+       /* "server" information associated with SCDynamicStoreNotifyFileDescriptor() */
+       int                             notifyFile;
+       int                             notifyFileIdentifier;
+
+       /* "server" information associated with SCDynamicStoreNotifySignal() */
+       int                             notifySignal;
+       task_t                          notifySignalTask;
+
+} SCDynamicStorePrivate, *SCDynamicStorePrivateRef;
+
+
+__BEGIN_DECLS
+
+SCDynamicStoreRef
+__SCDynamicStoreCreatePrivate          (CFAllocatorRef                 allocator,
+                                        const CFStringRef              name,
+                                        SCDynamicStoreCallBack         callout,
+                                        SCDynamicStoreContext          *context);
+
+void
+__SCLog                                        (int                            level,
+                                        CFStringRef                    str);
+
+void
+__SCPrint                              (FILE                           *stream,
+                                        CFStringRef                    str);
+
+void
+__showMachPortStatus                   ();
+
+void
+__showMachPortReferences               (mach_port_t                    port);
+
+__END_DECLS
+
+#endif /* _SCDYNAMICSTOREINTERNAL_H */
diff --git a/SystemConfiguration.fproj/SCDynamicStoreKey.h b/SystemConfiguration.fproj/SCDynamicStoreKey.h
new file mode 100644 (file)
index 0000000..aa76284
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCDYNAMICSTOREKEY_H
+#define _SCDYNAMICSTOREKEY_H
+
+#include <sys/cdefs.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+
+/*!
+       @header SCDynamicStoreKey
+ */
+
+
+__BEGIN_DECLS
+
+/*
+ * SCDynamicStoreKeyCreate*
+ * - convenience routines that create a CFString key for an item in the store
+ */
+
+/*!
+       @function SCDynamicStoreKeyCreate
+       @discussion Creates a store key using the given format.
+ */
+CFStringRef
+SCDynamicStoreKeyCreate                                (
+                                               CFAllocatorRef  allocator,
+                                               CFStringRef     fmt,
+                                               ...
+                                               );
+
+/*!
+       @function SCDynamicStoreKeyCreateNetworkGlobalEntity
+ */
+CFStringRef
+SCDynamicStoreKeyCreateNetworkGlobalEntity     (
+                                               CFAllocatorRef  allocator,
+                                               CFStringRef     domain,
+                                               CFStringRef     entity
+                                               );
+
+/*!
+       @function SCDynamicStoreKeyCreateNetworkInterface
+ */
+CFStringRef
+SCDynamicStoreKeyCreateNetworkInterface                (
+                                               CFAllocatorRef  allocator,
+                                               CFStringRef     domain
+                                               );
+
+/*!
+       @function SCDynamicStoreKeyCreateNetworkInterfaceEntity
+ */
+CFStringRef
+SCDynamicStoreKeyCreateNetworkInterfaceEntity  (
+                                               CFAllocatorRef  allocator,
+                                               CFStringRef     domain,
+                                               CFStringRef     ifname,
+                                               CFStringRef     entity
+                                               );
+
+/*!
+       @function SCDynamicStoreKeyCreateNetworkServiceEntity
+ */
+CFStringRef
+SCDynamicStoreKeyCreateNetworkServiceEntity    (
+                                               CFAllocatorRef  allocator,
+                                               CFStringRef     domain,
+                                               CFStringRef     serviceID,
+                                               CFStringRef     entity
+                                               );
+
+/*!
+       @function SCDynamicStoreKeyCreateComputerName
+       @discussion Creates a key that can be used by the SCDynamicStoreSetNotificationKeys()
+               function to receive notifications when the current
+               computer/host name changes.
+       @result A notification string for the current computer/host name.
+*/
+CFStringRef
+SCDynamicStoreKeyCreateComputerName            (
+                                               CFAllocatorRef          allocator
+                                               );
+
+/*!
+       @function SCDynamicStoreKeyCreateConsoleUser
+       @discussion Creates a key that can be used by the SCDynamicStoreSetNotificationKeys()
+               function to receive notifications when the current "Console"
+               user changes.
+       @result A notification string for the current "Console" user.
+*/
+CFStringRef
+SCDynamicStoreKeyCreateConsoleUser             (
+                                               CFAllocatorRef          allocator
+                                               );
+
+/*!
+       @function SCDynamicStoreKeyCreateProxies
+       @discussion Creates a key that can be used by the SCDynamicStoreSetNotificationKeys()
+               function to receive notifications when the current network proxy
+               settings (HTTP, FTP, ...) are changed.
+       @result A notification string for the current proxy settings.
+*/
+CFStringRef
+SCDynamicStoreKeyCreateProxies                 (
+                                               CFAllocatorRef          allocator
+                                               );
+
+__END_DECLS
+
+#endif /* _SCDYNAMICSTOREKEY_H */
diff --git a/SystemConfiguration.fproj/SCDynamicStorePrivate.h b/SystemConfiguration.fproj/SCDynamicStorePrivate.h
new file mode 100644 (file)
index 0000000..03d43e1
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCDYNAMICSTOREPRIVATE_H
+#define _SCDYNAMICSTOREPRIVATE_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <regex.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SCDynamicStore.h>
+
+/*!
+       @typedef SCDynamicStoreCallBack
+       @discussion Type of the callback function used when a
+               dynamic store change is delivered.
+       @param store The "dynamic store" session.
+       @param changedKeys The list of changed keys.
+       @param info ....
+ */
+typedef boolean_t (*SCDynamicStoreCallBack_v1) (
+                                               SCDynamicStoreRef       store,
+                                               void                    *info
+                                               );
+
+
+__BEGIN_DECLS
+
+/*!
+       @function SCDynamicStoreLock
+       @discussion Locks access to the configuration "dynamic store".  All
+               other clients attempting to access the "dynamic store" will
+               block. All change notifications will be deferred until the
+               lock is released.
+       @param store The "dynamic store" session that should be locked.
+       @result TRUE if the lock was obtained; FALSE if an error was encountered.
+ */
+Boolean
+SCDynamicStoreLock                     (SCDynamicStoreRef              store);
+
+/*!
+       @function SCDynamicStoreUnlock
+       @discussion Unlocks access to the configuration "dynamic store".  Other
+               clients will be able to access the "dynamic store". Any change
+               notifications will be delivered.
+       @param store The "dynamic store" session that should be unlocked.
+       @result TRUE if the lock was released; FALSE if an error was encountered.
+ */
+Boolean
+SCDynamicStoreUnlock                   (SCDynamicStoreRef              store);
+
+/*!
+       @function SCDynamicStoreTouchValue
+       @discussion Updates the value of the specified key in the
+               "dynamic store".
+               If the value does not exist then a CFDate object
+               will be associated with the key.
+               If the associated data is already a CFDate object
+               then it will be updated with the current time.
+       @param store The "dynamic store" session.
+       @param key The key of the value to updated.
+       @result TRUE if the value was updated; FALSE if an error was encountered.
+ */
+Boolean
+SCDynamicStoreTouchValue               (SCDynamicStoreRef              store,
+                                        CFStringRef                    key);
+
+/*!
+       @function SCDynamicStoreAddWatchedKey
+       @discussion Adds the specified key to the list of "dynamic store"
+               values that are being monitored for changes.
+       @param store The "dynamic store" session being watched.
+       @param key The key to be monitored.
+       @param isRegex A booolean indicating whether a specific key should
+               be monitored or if it consists of a regex(3) pattern string
+               of keys.
+       @result TRUE if the key was successfully added to the "watch"
+               list; FALSE if an error was encountered.
+ */
+Boolean
+SCDynamicStoreAddWatchedKey            (SCDynamicStoreRef              store,
+                                        CFStringRef                    key,
+                                        Boolean                        isRegex);
+
+/*!
+       @function SCDynamicStoreRemoveWatchedKey
+       @discussion Removes the specified key from the list of "dynamic store"
+               values that are being monitored for changes.
+       @param store The "dynamic store" session being watched.
+       @param key The key that should no longer be monitored.
+       @param isRegex A booolean indicating whether a specific key should
+               be monitored or if it consists of a regex(3) pattern string
+               of keys.
+       @result TRUE if the key was successfully removed from the "watch"
+               list; FALSE if an error was encountered.
+ */
+Boolean
+SCDynamicStoreRemoveWatchedKey         (SCDynamicStoreRef              store,
+                                        CFStringRef                    key,
+                                        Boolean                        isRegex);
+
+CFArrayRef
+SCDynamicStoreCopyWatchedKeyList       (SCDynamicStoreRef              store,
+                                        Boolean                        isRegex);
+
+/*!
+       @function SCDynamicStoreNotifyCallback
+       @discussion Requests that the specified function be called whenever a
+               change has been detected to one of the "dynamic store" values
+               being monitored.
+
+       The callback function will be called with two arguments, store and
+       context, that correspond to the current "dynamic store" session and
+       the provided context argument.
+
+       The callback function should return a Boolean value indicating
+       whether an error occurred during execution of the callback.
+
+       Note: An additional run loop source will be added for the notification.
+       This additional source will be removed if the notification is cancelled
+       or if the callback indicates that an error was detected.
+
+       @param store The "dynamic store" session.
+       @param runLoop A pointer to the run loop.
+       @param funct The callback function to call for each notification.
+               If this parameter is not a pointer to a function of the
+               correct prototype, the behavior is undefined.
+       @param context A pointer-sized user-defined value, that is passed as
+               the second parameter to the notification callback function,
+               but is otherwise unused by this function.  If the context
+               is not what is expected by the notification function, the
+               behavior is undefined.
+       @result TRUE if the notification callback runloop source was
+               successfully added; FALSE if an error was encountered.
+ */
+Boolean
+SCDynamicStoreNotifyCallback           (SCDynamicStoreRef              store,
+                                        CFRunLoopRef                   runLoop,
+                                        SCDynamicStoreCallBack_v1      func,
+                                        void                           *context);
+
+/*!
+       @function SCDynamicStoreNotifyMachPort
+       @discussion Allocates a mach port that can be used to detect changes to
+               one of the system configuration data entries associated with the
+               current session's notifier keys. When a change is detected, an
+               empty (no data) mach message with the specified identifier will
+               be delivered to the calling application via the allocated port.
+
+       @param store An SCDynamicStoreRef that should be used for communication with the server.
+       @param msgid A mach message ID to be included with any notifications.
+       @param port A pointer to a mach port.  Upon return, port will be filled
+               with the mach port that will be used for any notifications.
+       @result A boolean indicating the success (or failure) of the call.
+ */
+Boolean
+SCDynamicStoreNotifyMachPort           (SCDynamicStoreRef              store,
+                                        mach_msg_id_t                  msgid,
+                                        mach_port_t                    *port);
+
+/*!
+       @function SCDynamicStoreNotifyFileDescriptor
+       @discussion Allocates a file descriptor that can be used to detect changes
+               to one of the system configuration data entries associated with the
+               current session's notifier keys. When a change is detected, the
+               specified identifier (4 bytes) will be delivered to the calling
+               application via the allocated file descriptor.
+
+       @param store An SCDynamicStoreRef that should be used for communication with the server.
+       @param identifier A (4 byte) integer that can be used to identify this
+               notification.
+       @param fd A pointer to a file descriptor.  Upon return, fd will
+               contain the file descriptor that will be used for any notifications.
+       @result A boolean indicating the success (or failure) of the call.
+ */
+Boolean
+SCDynamicStoreNotifyFileDescriptor     (SCDynamicStoreRef              store,
+                                        int32_t                        identifier,
+                                        int                            *fd);
+
+/*!
+       @function SCDynamicStoreNotifySignal
+       @discussion Requests that the specified BSD signal be sent to the process
+               with the indicated process id whenever a change has been detected
+               to one of the system configuration data entries associated with the
+               current session's notifier keys.
+
+               Note: this function is not valid for "configd" plug-ins.
+
+       @param store An SCDynamicStoreRef that should be used for communication with the server.
+       @param pid A UNIX process ID that should be signalled for any notifications.
+       @param sig A signal number to be used.
+       @result A boolean indicating the success (or failure) of the call.
+ */
+Boolean
+SCDynamicStoreNotifySignal             (SCDynamicStoreRef              store,
+                                        pid_t                          pid,
+                                        int                            sig);
+
+/*!
+       @function SCDynamicStoreNotifyWait
+       @discussion Waits for a change to be made to a value in the
+               "dynamic store" that is being monitored.
+       @param store The "dynamic store" session.
+       @result TRUE if a change has been detected; FALSE if an error was encountered.
+ */
+Boolean
+SCDynamicStoreNotifyWait               (SCDynamicStoreRef              store);
+
+/*!
+       @function SCDynamicStoreNotifyCancel
+       @discussion Cancels any outstanding notification requests for
+               this "dynamic store" session.
+
+       @param store The "dynamic store" session.
+       @result TRUE if all notifications have been cancelled; FALSE if an
+               error was encountered.
+ */
+Boolean
+SCDynamicStoreNotifyCancel             (SCDynamicStoreRef              store);
+
+Boolean
+SCDynamicStoreSnapshot                 (SCDynamicStoreRef              store);
+
+__END_DECLS
+
+#endif /* _SCDYNAMICSTOREPRIVATE_H */
diff --git a/SystemConfiguration.fproj/SCDynamicStoreSetSpecificPrivate.h b/SystemConfiguration.fproj/SCDynamicStoreSetSpecificPrivate.h
new file mode 100644 (file)
index 0000000..eb58171
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2001 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCDYNAMICSTORESETSPECIFICPRIVATE_H
+#define _SCDYNAMICSTORESETSPECIFICPRIVATE_H
+
+#include <sys/cdefs.h>
+#include <SystemConfiguration/SCDynamicStore.h>
+
+
+__BEGIN_DECLS
+
+/*!
+       @function SCDynamicStoreSetConsoleUser
+       @discussion Sets the name, user ID, and group ID of the currently
+               logged in user.
+       @param session An SCDynamicStoreRef that should be used for communication
+               with the server.
+               If NULL, a temporary session will be used.
+       @param user A pointer to a character buffer containing the name of
+               the current "Console" user. If NULL, any current "Console"
+               user information will be reset.
+       @param uid The user ID of the current "Console" user.
+       @param gid The group ID of the current "Console" user.
+       @result A boolean indicating the success (or failure) of the call.
+ */
+Boolean
+SCDynamicStoreSetConsoleUser           (
+                                       SCDynamicStoreRef       session,
+                                       const char              *user,
+                                       uid_t                   uid,
+                                       gid_t                   gid
+                                       );
+
+__END_DECLS
+
+#endif /* _SCDYNAMICSTORESETSPECIFICPRIVATE_H */
index 18289842808c8bab021c57362232a92d55953fbd..b413ec80add253193e440d6dbe099b36983d404f 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 10, 2001               Allan Nathanson <ajn@apple.com>
+ * - updated to use service-based "State:" information
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * January 30, 2001            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include <SystemConfiguration/SCValidation.h>
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -34,7 +49,6 @@
 
 #include "ppp.h"
 
-
 static int
 inet_atonCF(CFStringRef cfStr, struct in_addr *addr)
 {
@@ -82,405 +96,452 @@ parse_component(CFStringRef key, CFStringRef prefix)
 }
 
 
-/*
- * return a dictionary of configured services.
- */
-static CFDictionaryRef
-getServices(SCDSessionRef session)
+typedef struct {
+       CFMutableDictionaryRef  aDict;          /* active services */
+       CFStringRef             aPrefix;        /* prefix for active services */
+       CFMutableDictionaryRef  cDict;          /* configured services */
+       CFStringRef             cPrefix;        /* prefix for configured services */
+       CFMutableDictionaryRef  iDict;          /* active interfaces */
+       CFStringRef             iPrefix;        /* prefix for active interfaces */
+       CFMutableArrayRef       order;          /* service order */
+} initContext, *initContextRef;
+
+
+static void
+collectInfo(const void *key, const void *value, void *context)
 {
-       CFArrayRef              defined         = NULL;
-       int                     i;
-       CFStringRef             key;
-       CFStringRef             prefix;
-       CFMutableDictionaryRef  services;
-       SCDStatus               status;
-
-       prefix = SCDKeyCreate(CFSTR("%@/%@/%@/"),
-                             kSCCacheDomainSetup,
-                             kSCCompNetwork,
-                             kSCCompService);
-
-       services = CFDictionaryCreateMutable(NULL,
-                                            0,
-                                            &kCFTypeDictionaryKeyCallBacks,
-                                            &kCFTypeDictionaryValueCallBacks);
-
-       key = SCDKeyCreateNetworkServiceEntity(kSCCacheDomainSetup,
-                                              kSCCompAnyRegex,
-                                              kSCEntNetIPv4);
-       status = SCDList(session, key, kSCDRegexKey, &defined);
-       CFRelease(key);
-       if (status != SCD_OK) {
-               goto done;
+       initContextRef          info            = (initContextRef)context;
+       CFStringRef             interface;
+       CFStringRef             interfaceKey;
+       CFStringRef             service;
+       CFStringRef             serviceKey;
+
+       if (!isA_CFString(key) || !isA_CFDictionary(value)) {
+               return;
        }
 
-       for (i = 0; i < CFArrayGetCount(defined); i++) {
-               CFDictionaryRef         if_dict;
-               SCDHandleRef            if_handle       = NULL;
-               CFDictionaryRef         ip_dict;
-               SCDHandleRef            ip_handle       = NULL;
-               boolean_t               isPPP           = FALSE;
-               CFDictionaryRef         ppp_dict;
-               SCDHandleRef            ppp_handle      = NULL;
-               CFMutableDictionaryRef  sDict           = NULL;
-               CFStringRef             sid             = NULL;
-
-               key  = CFArrayGetValueAtIndex(defined, i);
-
-               /* get IPv4 dictionary for service */
-               status = SCDGet(session, key, &ip_handle);
-               if (status != SCD_OK) {
-                       /* if service was removed behind our back */
-                       goto nextService;
+       service = parse_component((CFStringRef)key, info->cPrefix);
+       if (service) {
+               serviceKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                        kSCDynamicStoreDomainSetup,
+                                                                        service,
+                                                                        kSCEntNetIPv4);
+               if (CFEqual((CFStringRef)key, serviceKey)) {
+                       CFMutableDictionaryRef  dict;
+
+                       dict = CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef)value);
+                       CFDictionaryAddValue(info->cDict, service, dict);
+                       CFRelease(dict);
                }
-               ip_dict = SCDHandleGetData(ip_handle);
-
-               sDict = CFDictionaryCreateMutableCopy(NULL, 0, ip_dict);
+               CFRelease(serviceKey);
 
-               /* add keys from the service's Interface dictionary */
-               sid = parse_component(key, prefix);
-               if (sid == NULL) {
-                       goto nextService;
+               if (!CFArrayContainsValue(info->order, CFRangeMake(0, CFArrayGetCount(info->order)), service)) {
+                       CFArrayAppendValue(info->order, service);
                }
 
-               key = SCDKeyCreateNetworkServiceEntity(kSCCacheDomainSetup,
-                                                      sid,
-                                                      kSCEntNetInterface);
-               status = SCDGet(session, key, &if_handle);
-               CFRelease(key);
-               if (status != SCD_OK) {
-                       goto nextService;
-               }
-               if_dict = SCDHandleGetData(if_handle);
-
-               /* check the interface "Type", "SubType", and "DeviceName" */
-               if (CFDictionaryGetValueIfPresent(if_dict,
-                                                 kSCPropNetInterfaceType,
-                                                 (void **)&key)) {
-                       CFDictionaryAddValue(sDict, kSCPropNetInterfaceType, key);
-                       isPPP = CFEqual(key, kSCValNetInterfaceTypePPP);
+               CFRelease(service);
+               return;
+       }
+
+       service = parse_component((CFStringRef)key, info->aPrefix);
+       if (service) {
+               serviceKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                        kSCDynamicStoreDomainState,
+                                                                        service,
+                                                                        kSCEntNetIPv4);
+               if (CFEqual((CFStringRef)key, serviceKey)) {
+                       CFMutableDictionaryRef  dict;
+
+                       dict = CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef)value);
+                       CFDictionaryAddValue(info->aDict, service, dict);
+                       CFRelease(dict);
                }
-               if (CFDictionaryGetValueIfPresent(if_dict,
-                                                 kSCPropNetInterfaceSubType,
-                                                 (void **)&key)) {
-                       CFDictionaryAddValue(sDict, kSCPropNetInterfaceSubType, key);
+               CFRelease(serviceKey);
+
+               if (!CFArrayContainsValue(info->order, CFRangeMake(0, CFArrayGetCount(info->order)), service)) {
+                       CFArrayAppendValue(info->order, service);
                }
 
-               if (isPPP) {
-                       key = SCDKeyCreateNetworkServiceEntity(kSCCacheDomainSetup,
-                                                              sid,
-                                                              kSCEntNetPPP);
-                       status = SCDGet(session, key, &ppp_handle);
-                       CFRelease(key);
-                       if (status != SCD_OK) {
-                               goto nextService;
-                       }
-                       ppp_dict = SCDHandleGetData(ppp_handle);
+               CFRelease(service);
+               return;
+       }
 
-                       /* get Dial-on-Traffic flag */
-                       if (CFDictionaryGetValueIfPresent(ppp_dict,
-                                                         kSCPropNetPPPDialOnDemand,
-                                                         (void **)&key)) {
-                               CFDictionaryAddValue(sDict, kSCPropNetPPPDialOnDemand, key);
-                       }
+       interface = parse_component((CFStringRef)key, info->iPrefix);
+       if (interface) {
+               interfaceKey = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
+                                                                            kSCDynamicStoreDomainState,
+                                                                            interface,
+                                                                            kSCEntNetIPv4);
+               if (CFEqual((CFStringRef)key, interfaceKey)) {
+                       CFMutableDictionaryRef  dict;
+
+                       dict = CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef)value);
+                       CFDictionaryAddValue(info->iDict, interface, dict);
+                       CFRelease(dict);
                }
+               CFRelease(interfaceKey);
+               CFRelease(interface);
+               return;
+       }
+
+       return;
+}
 
-               CFDictionaryAddValue(services, sid, sDict);
 
-       nextService:
+static void
+collectExtraInfo(const void *key, const void *value, void *context)
+{
+       CFStringRef             interfaceKey;
+       initContextRef          info    = (initContextRef)context;
+       CFMutableDictionaryRef  dict;
+       Boolean                 match;
+       CFStringRef             pppKey;
+       CFStringRef             service;
+
+       if (!isA_CFString(key) || !isA_CFDictionary(value)) {
+               return;
+       }
+
+       service = parse_component((CFStringRef)key, info->cPrefix);
+       if (!service) {
+               /* this key/value pair contains supplemental information */
+               return;
+       }
+
+       dict = (CFMutableDictionaryRef)CFDictionaryGetValue(info->cDict, service);
+       if (!dict) {
+               /*  we don't have any IPv4 information for this service */
+               goto done;
+       }
 
-               if (sid)        CFRelease(sid);
-               if (if_handle)  SCDHandleRelease(if_handle);
-               if (ip_handle)  SCDHandleRelease(ip_handle);
-               if (ppp_handle) SCDHandleRelease(ppp_handle);
-               if (sDict)      CFRelease(sDict);
+       interfaceKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                                  kSCDynamicStoreDomainSetup,
+                                                                  service,
+                                                                  kSCEntNetInterface);
+       match = CFEqual((CFStringRef)key, interfaceKey);
+       CFRelease(interfaceKey);
+       if (match) {
+               CFStringRef     interface;
+
+               interface = CFDictionaryGetValue((CFDictionaryRef)value,
+                                                kSCPropNetInterfaceType);
+               if (isA_CFString(interface)) {
+                       /* if "InterfaceType" available */
+                       CFDictionaryAddValue(dict, kSCPropNetInterfaceType, interface);
+                       CFDictionarySetValue(info->cDict, service, dict);
+               }
+               goto done;
        }
 
-    done:
+       pppKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                            kSCDynamicStoreDomainSetup,
+                                                            service,
+                                                            kSCEntNetPPP);
+       match = CFEqual((CFStringRef)key, pppKey);
+       CFRelease(pppKey);
+       if (match) {
+               CFNumberRef     dialOnDemand;
+
+               dialOnDemand = CFDictionaryGetValue((CFDictionaryRef)value,
+                                                   kSCPropNetPPPDialOnDemand);
+               if (isA_CFNumber(dialOnDemand)) {
+                       /* if "DialOnDemand" information not available */
+                       CFDictionaryAddValue(dict, kSCPropNetPPPDialOnDemand, dialOnDemand);
+                       CFDictionarySetValue(info->cDict, service, dict);
+               }
+               goto done;
+       }
 
-       if (defined)    CFRelease(defined);
-       CFRelease(prefix);
+    done :
 
-       return services;
+       CFRelease(service);
+       return;
 }
 
 
-/*
- * return a dictionary of configured interfaces.
- */
-static CFDictionaryRef
-getInterfaces(SCDSessionRef session)
+static void
+removeKnownAddresses(const void *key, const void *value, void *context)
 {
-       CFMutableArrayRef       defined         = NULL;
-       int                     i;
-       CFStringRef             key;
-       CFMutableDictionaryRef  interfaces;
-       CFStringRef             prefix;
-       SCDStatus               status;
-
-       prefix = SCDKeyCreate(CFSTR("%@/%@/%@/"),
-                             kSCCacheDomainState,
-                             kSCCompNetwork,
-                             kSCCompInterface);
+       CFMutableDictionaryRef  ifDict;
+       CFStringRef             ifName;
+       CFMutableDictionaryRef  interfaces      = (CFMutableDictionaryRef)context;
+       CFMutableDictionaryRef  serviceDict     = (CFMutableDictionaryRef)value;
+       Boolean                 updated         = FALSE;
 
-       interfaces = CFDictionaryCreateMutable(NULL,
-                                              0,
-                                              &kCFTypeDictionaryKeyCallBacks,
-                                              &kCFTypeDictionaryValueCallBacks);
+       CFIndex                 i;
+       CFArrayRef              iAddrs;
+       CFArrayRef              iDests;
+       CFArrayRef              iMasks;
+       CFIndex                 n;
+       CFMutableArrayRef       nAddrs          = NULL;
+       CFMutableArrayRef       nDests          = NULL;
+       CFMutableArrayRef       nMasks          = NULL;
+       CFIndex                 s;
+       CFArrayRef              sAddrs;
+       CFArrayRef              sDests;
+       CFArrayRef              sMasks;
+
+       ifName = CFDictionaryGetValue(serviceDict, kSCPropInterfaceName);
+       if (!ifName) {
+               /* if no "InterfaceName" for this service */
+               return;
+       }
 
-       key = SCDKeyCreateNetworkInterfaceEntity(kSCCacheDomainState,
-                                                kSCCompAnyRegex,
-                                                kSCEntNetIPv4);
-       status = SCDList(session, key, kSCDRegexKey, &defined);
-       CFRelease(key);
-       if (status != SCD_OK) {
-               goto done;
+       ifDict = (CFMutableDictionaryRef)CFDictionaryGetValue(interfaces, ifName);
+       if (!ifDict) {
+               /* if the indicated interface is not active */
+               return;
        }
 
-       for (i=0; i<CFArrayGetCount(defined); i++) {
-               CFStringRef             iid             = NULL;
-               CFDictionaryRef         ip_dict;
-               SCDHandleRef            ip_handle       = NULL;
+       sAddrs = isA_CFArray(CFDictionaryGetValue(serviceDict,
+                                                 kSCPropNetIPv4Addresses));
+       sDests = isA_CFArray(CFDictionaryGetValue(serviceDict,
+                                                 kSCPropNetIPv4DestAddresses));
+       sMasks = isA_CFArray(CFDictionaryGetValue(serviceDict,
+                                                 kSCPropNetIPv4SubnetMasks));
 
-               key  = CFArrayGetValueAtIndex(defined, i);
+       if (!sAddrs || ((n = CFArrayGetCount(sAddrs)) == 0)) {
+               /* if no addresses */
+               return;
+       }
 
-               /* get IPv4 dictionary for service */
-               status = SCDGet(session, key, &ip_handle);
-               if (status != SCD_OK) {
-                       /* if interface was removed behind our back */
-                       goto nextIF;
-               }
-               ip_dict = SCDHandleGetData(ip_handle);
+       if (((sMasks == NULL) && (sDests == NULL)) ||
+           ((sMasks != NULL) && (sDests != NULL))) {
+               /*
+                * sorry, we expect to have "SubnetMasks" or
+                * "DestAddresses" (not both).
+                */
+               return;
+       }
 
-               iid = parse_component(key, prefix);
-               if (iid == NULL) {
-                       goto nextIF;
-               }
+       if (sMasks && (n != CFArrayGetCount(sMasks))) {
+               /* if we don't like the "SubnetMasks" */
+               return;
+       }
 
-               CFDictionaryAddValue(interfaces, iid, ip_dict);
+       if (sDests &&  (n != CFArrayGetCount(sDests))) {
+               /* if we don't like the "DestAddresses" */
+               return;
+       }
 
-           nextIF :
+       iAddrs = isA_CFArray(CFDictionaryGetValue(ifDict,
+                                                 kSCPropNetIPv4Addresses));
+       iDests = isA_CFArray(CFDictionaryGetValue(ifDict,
+                                                 kSCPropNetIPv4DestAddresses));
+       iMasks = isA_CFArray(CFDictionaryGetValue(ifDict,
+                                                 kSCPropNetIPv4SubnetMasks));
 
-               if (iid)        CFRelease(iid);
-               if (ip_handle)  SCDHandleRelease(ip_handle);
+       if (((iMasks == NULL) && (iDests == NULL)) ||
+           ((iMasks != NULL) && (iDests != NULL))) {
+               /*
+                * sorry, we expect to have "SubnetMasks" or
+                * "DestAddresses" (not both).
+                */
+               return;
        }
 
-    done:
+       if (!iAddrs || ((i = CFArrayGetCount(iAddrs)) == 0)) {
+               /* if no addresses */
+               return;
+       }
 
-       if (defined)    CFRelease(defined);
-       CFRelease(prefix);
-       return interfaces;
-}
+       if (iMasks && (i != CFArrayGetCount(iMasks))) {
+               /* if we don't like the "SubnetMasks" */
+               return;
+       }
 
+       if (iDests && (i != CFArrayGetCount(iDests))) {
+               /* if we don't like the "DestAddresses" */
+               return;
+       }
 
-/*
- * return an array of interface names based on a specified service order.
- */
-static CFArrayRef
-getInterfaceOrder(CFDictionaryRef      interfaces,
-                 CFArrayRef            serviceOrder,
-                 CFNumberRef           pppOverridePrimary)
-{
-       CFIndex                 i;
-       CFIndex                 iCnt;
-       CFMutableArrayRef       iKeys;
-       void                    **keys;
-       CFMutableArrayRef       order   = NULL;
-       CFArrayRef              tKeys;
-
-       order = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-
-       iCnt = CFDictionaryGetCount(interfaces);
-       keys = CFAllocatorAllocate(NULL, iCnt * sizeof(CFStringRef), 0);
-       CFDictionaryGetKeysAndValues(interfaces, keys, NULL);
-       tKeys = CFArrayCreate(NULL, keys, iCnt, &kCFTypeArrayCallBacks);
-       CFAllocatorDeallocate(NULL, keys);
-       iKeys = CFArrayCreateMutableCopy(NULL, 0, tKeys);
-       CFRelease(tKeys);
-
-       for (i = 0; serviceOrder && i < CFArrayGetCount(serviceOrder); i++) {
-               CFIndex         j;
-               CFStringRef     oSID;
-
-               oSID = CFArrayGetValueAtIndex(serviceOrder, i);
-               for (j=0; j<CFArrayGetCount(iKeys); j++) {
-                       CFDictionaryRef iDict;
-                       CFStringRef     iKey;
-                       CFStringRef     iSID;
-                       CFArrayRef      iSIDs;
-                       CFIndex         k;
-                       boolean_t       match   = FALSE;
-
-                       iKey  = CFArrayGetValueAtIndex(iKeys, j);
-                       iDict = CFDictionaryGetValue(interfaces, iKey);
-
-                       iSIDs = CFDictionaryGetValue(iDict, kSCCachePropNetServiceIDs);
-                       for (k = 0; iSIDs && k < CFArrayGetCount(iSIDs); k++) {
-                               iSID = CFArrayGetValueAtIndex(iSIDs, k);
-                               if (CFEqual(oSID, iSID)) {
-                                       match = TRUE;
-                                       break;
-                               }
-                       }
+       if (((sMasks == NULL) && (iMasks != NULL)) ||
+           ((sDests == NULL) && (iDests != NULL))) {
+               /* if our addressing schemes are in conflict */
+               return;
+       }
 
-                       if (match) {
-                               /* if order ServiceID is associated with this interface */
-                               CFArrayAppendValue(order, iKey);
-                               CFArrayRemoveValueAtIndex(iKeys, j);
-                               break;
+       nAddrs = CFArrayCreateMutableCopy(NULL, 0, iAddrs);
+       if (iMasks) nMasks = CFArrayCreateMutableCopy(NULL, 0, iMasks);
+       if (iDests) nDests = CFArrayCreateMutableCopy(NULL, 0, iDests);
+       for (s=0; s<n; s++) {
+               i = CFArrayGetCount(nAddrs);
+               while (--i >= 0) {
+                       if (sMasks &&
+                           CFEqual(CFArrayGetValueAtIndex(sAddrs, s),
+                                   CFArrayGetValueAtIndex(nAddrs, i)) &&
+                           CFEqual(CFArrayGetValueAtIndex(sMasks, s),
+                                   CFArrayGetValueAtIndex(nMasks, i))
+                           ) {
+                               /* we have a match */
+                               CFArrayRemoveValueAtIndex(nAddrs, i);
+                               CFArrayRemoveValueAtIndex(nMasks, i);
+                               updated = TRUE;
+                       } else if (sDests &&
+                                  CFEqual(CFArrayGetValueAtIndex(sAddrs, s),
+                                          CFArrayGetValueAtIndex(nAddrs, i)) &&
+                                  CFEqual(CFArrayGetValueAtIndex(sDests, s),
+                                          CFArrayGetValueAtIndex(nDests, i))
+                                  ) {
+                               /* we have a match */
+                               CFArrayRemoveValueAtIndex(nAddrs, i);
+                               CFArrayRemoveValueAtIndex(nDests, i);
+                               updated = TRUE;
                        }
                }
        }
 
-       for (i = 0; i < CFArrayGetCount(iKeys); i++) {
-               CFStringRef     iKey;
+       if (updated) {
+               if (nAddrs) {
+                       CFDictionarySetValue(ifDict,
+                                            kSCPropNetIPv4Addresses,
+                                            nAddrs);
+               }
+               if (nMasks) {
+                       CFDictionarySetValue(ifDict,
+                                            kSCPropNetIPv4SubnetMasks,
+                                            nMasks);
+               } else {
+                       CFDictionarySetValue(ifDict,
+                                            kSCPropNetIPv4DestAddresses,
+                                            nDests);
+               }
+               CFDictionarySetValue(interfaces, ifName, ifDict);
+       }
+       CFRelease(nAddrs);
+       if (nMasks) CFRelease(nMasks);
+       if (nDests) CFRelease(nDests);
+
+       return;
+}
 
-               iKey = CFArrayGetValueAtIndex(iKeys, i);
-               CFArrayAppendValue(order, iKey);
+
+static void
+addUnknownService(const void *key, const void *value, void *context)
+{
+       CFArrayRef              addrs;
+       CFMutableDictionaryRef  ifDict          = (CFMutableDictionaryRef)value;
+       initContextRef          info            = (initContextRef)context;
+       CFStringRef             service;
+       CFUUIDRef               uuid;
+
+       addrs = CFDictionaryGetValue(ifDict, kSCPropNetIPv4Addresses);
+       if (!addrs || (CFArrayGetCount(addrs) == 0)) {
+               /* if no addresses */
+               return;
        }
 
-       CFRelease(iKeys);
-       return order;
+       /* add the "InterfaceName" to the (new/fake) service dictionary */
+       CFDictionaryAddValue(ifDict, kSCPropInterfaceName, (CFStringRef)key);
+
+       /* create a (new/fake) service to hold any remaining addresses */
+       uuid    = CFUUIDCreate(NULL);
+       service = CFUUIDCreateString(NULL, uuid);
+       CFDictionaryAddValue(info->aDict, service, ifDict);
+       CFArrayAppendValue(info->order, service);
+       CFRelease(service);
+       CFRelease(uuid);
+
+       return;
 }
 
 
-static boolean_t
+static Boolean
 getAddresses(CFDictionaryRef   iDict,
             CFIndex            *nAddrs,
             CFArrayRef         *addrs,
             CFArrayRef         *masks,
             CFArrayRef         *dests)
 {
-       *addrs = CFDictionaryGetValue(iDict, kSCPropNetIPv4Addresses);
-       *masks = CFDictionaryGetValue(iDict, kSCPropNetIPv4SubnetMasks);
-       *dests = CFDictionaryGetValue(iDict, kSCPropNetIPv4DestAddresses);
+       *addrs = isA_CFArray(CFDictionaryGetValue(iDict,
+                                                 kSCPropNetIPv4Addresses));
+       *masks = isA_CFArray(CFDictionaryGetValue(iDict,
+                                                 kSCPropNetIPv4SubnetMasks));
+       *dests = isA_CFArray(CFDictionaryGetValue(iDict,
+                                                 kSCPropNetIPv4DestAddresses));
 
        if ((*addrs == NULL) ||
            ((*nAddrs = CFArrayGetCount(*addrs)) == 0)) {
                /* sorry, no addresses */
+               _SCErrorSet(kSCStatusReachabilityUnknown);
                return FALSE;
        }
 
-       if ((*masks && *dests) ||
-           (*masks == NULL) && (*dests == NULL)) {
+       if (((*masks == NULL) && (*dests == NULL)) ||
+           ((*masks != NULL) && (*dests != NULL))) {
                /*
                 * sorry, we expect to have "SubnetMasks" or
-                * "DestAddresses" (not both) and if the count
+                * "DestAddresses" (not both) and the count
                 * must match the number of "Addresses".
                 */
+               _SCErrorSet(kSCStatusReachabilityUnknown);
                return FALSE;
        }
 
        if (*masks && (*nAddrs != CFArrayGetCount(*masks))) {
                /* if we don't like the netmasks */
+               _SCErrorSet(kSCStatusReachabilityUnknown);
                return FALSE;
        }
 
        if (*dests &&  (*nAddrs != CFArrayGetCount(*dests))) {
                /* if we don't like the destaddresses */
+               _SCErrorSet(kSCStatusReachabilityUnknown);
                return FALSE;
        }
 
        return TRUE;
 }
 
-static SCNStatus
-checkAddress(SCDSessionRef             session,
+static Boolean
+checkAddress(SCDynamicStoreRef         store,
             const struct sockaddr      *address,
             const int                  addrlen,
-            CFDictionaryRef            services,
-            CFDictionaryRef            interfaces,
-            CFArrayRef                 interfaceOrder,
+            CFDictionaryRef            config,
+            CFDictionaryRef            active,
+            CFArrayRef                 serviceOrder,
             struct in_addr             *defaultRoute,
-            int                        *flags,
-            const char                 **errorMessage)
+            SCNetworkConnectionFlags   *flags)
 {
+       CFIndex                 aCnt;
+       CFStringRef             aType           = NULL;
+       CFDictionaryRef         cDict           = NULL;
        CFIndex                 i;
-       struct ifreq            ifr;
-       CFIndex                 iCnt;
-       CFStringRef             iKey            = NULL;
-       CFStringRef             iType           = NULL;
-       void                    **keys;
+       CFStringRef             key             = NULL;
        int                     pppRef          = -1;
-       SCNStatus               scn_status      = SCN_REACHABLE_UNKNOWN;
-       CFIndex                 sCnt;
-       CFMutableArrayRef       sKeys           = NULL;
-       CFStringRef             sID             = NULL;
-       CFArrayRef              sIDs            = NULL;
-       CFArrayRef              sList           = NULL;
-       int                     sock            = -1;
-       CFStringRef             sKey            = NULL;
-       CFDictionaryRef         sDict           = NULL;
-       CFArrayRef              tKeys;
-
-       if (flags != NULL) {
-               *flags = 0;
-       }
+       int                     sc_status       = kSCStatusReachabilityUnknown;
+       char                    *statusMessage  = NULL;
 
-       if (address == NULL) {
-               return SCN_REACHABLE_NO;
+       if (!address || !flags) {
+               sc_status = kSCStatusInvalidArgument;
+               goto done;
        }
 
-       sCnt = CFDictionaryGetCount(services);
-       keys = CFAllocatorAllocate(NULL, sCnt * sizeof(CFStringRef), 0);
-       CFDictionaryGetKeysAndValues(services, keys, NULL);
-       tKeys = CFArrayCreate(NULL, keys, sCnt, &kCFTypeArrayCallBacks);
-       CFAllocatorDeallocate(NULL, keys);
-       sKeys = CFArrayCreateMutableCopy(NULL, 0, tKeys);
-       CFRelease(tKeys);
+       *flags = 0;
 
        if (address->sa_family == AF_INET) {
                struct sockaddr_in      *sin = (struct sockaddr_in *)address;
 
-#ifdef DEBUG
-               if (SCDOptionGet(session, kSCDOptionDebug))
-                       SCDLog(LOG_INFO, CFSTR("checkAddress(%s)"), inet_ntoa(sin->sin_addr));
-#endif /* DEBUG */
-               /*
-                * Check for loopback address
-                */
-               if (ntohl(sin->sin_addr.s_addr) == ntohl(INADDR_LOOPBACK)) {
-                       /* if asking about the loopback address */
-#ifdef DEBUG
-                       if (SCDOptionGet(session, kSCDOptionDebug))
-                               SCDLog(LOG_INFO, CFSTR("  isReachable via loopback"));
-#endif /* DEBUG */
-                       scn_status = SCN_REACHABLE_YES;
-                       goto done;
-               }
+               SCLog(_sc_debug, LOG_INFO, CFSTR("checkAddress(%s)"), inet_ntoa(sin->sin_addr));
 
                /*
                 * Check if the address is on one of the subnets
                 * associated with our active IPv4 interfaces
                 */
-               iCnt = CFArrayGetCount(interfaceOrder);
-               for (i=0; i<iCnt; i++) {
+               aCnt = CFArrayGetCount(serviceOrder);
+               for (i=0; i<aCnt; i++) {
+                       CFDictionaryRef         aDict;
                        CFArrayRef              addrs;
                        CFArrayRef              dests;
-                       CFDictionaryRef         iDict;
                        CFIndex                 j;
                        CFArrayRef              masks;
                        CFIndex                 nAddrs  = 0;
 
-                       iKey  = CFArrayGetValueAtIndex(interfaceOrder, i);
-                       iDict = CFDictionaryGetValue(interfaces, iKey);
-
-                       /* remove active services */
-                       sIDs = CFDictionaryGetValue(iDict, kSCCachePropNetServiceIDs);
-                       for (j = 0; sIDs && j < CFArrayGetCount(sIDs); j++) {
-                               CFIndex         k;
-                               CFStringRef     sID;
-
-                               sID = CFArrayGetValueAtIndex(sIDs, j);
-                               k   = CFArrayGetFirstIndexOfValue(sKeys,
-                                                                 CFRangeMake(0, CFArrayGetCount(sKeys)),
-                                                                 sID);
-                               if (k != -1) {
-                                       CFArrayRemoveValueAtIndex(sKeys, k);
-                               }
-                       }
+                       key   = CFArrayGetValueAtIndex(serviceOrder, i);
+                       aDict = CFDictionaryGetValue(active, key);
 
-                       if (!getAddresses(iDict, &nAddrs, &addrs, &masks, &dests)) {
+                       if (!aDict ||
+                           !getAddresses(aDict, &nAddrs, &addrs, &masks, &dests)) {
                                /* if no addresses to check */
                                continue;
                        }
@@ -506,11 +567,8 @@ checkAddress(SCDSessionRef         session,
                                        if ((ntohl(ifAddr.s_addr)        & ntohl(ifMask.s_addr)) ==
                                            (ntohl(sin->sin_addr.s_addr) & ntohl(ifMask.s_addr))) {
                                                /* the requested address is on this subnet */
-#ifdef DEBUG
-                                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                                       SCDLog(LOG_INFO, CFSTR("  isReachable (my subnet)"));
-#endif /* DEBUG */
-                                               scn_status = SCN_REACHABLE_YES;
+                                               statusMessage = "isReachable (my subnet)";
+                                               *flags |= kSCNetworkFlagsReachable;
                                                goto checkInterface;
                                        }
                                } else {
@@ -526,21 +584,15 @@ checkAddress(SCDSessionRef                session,
                                        /* check local address */
                                        if (ntohl(sin->sin_addr.s_addr) == ntohl(ifAddr.s_addr)) {
                                                /* the address is our side of the link */
-#ifdef DEBUG
-                                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                                       SCDLog(LOG_INFO, CFSTR("  isReachable (my local address)"));
-#endif /* DEBUG */
-                                               scn_status = SCN_REACHABLE_YES;
+                                               statusMessage = "isReachable (my local address)";
+                                               *flags |= kSCNetworkFlagsReachable;
                                                goto checkInterface;
                                        }
 
                                        if (ntohl(sin->sin_addr.s_addr) == ntohl(destAddr.s_addr)) {
                                                /* the address is the other side of the link */
-#ifdef DEBUG
-                                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                                       SCDLog(LOG_INFO, CFSTR("  isReachable (my remote address)"));
-#endif /* DEBUG */
-                                               scn_status = SCN_REACHABLE_YES;
+                                               statusMessage = "isReachable (my remote address)";
+                                               *flags |= kSCNetworkFlagsReachable;
                                                goto checkInterface;
                                        }
                                }
@@ -550,18 +602,21 @@ checkAddress(SCDSessionRef                session,
                /*
                 * Check if the address is accessible via the "default" route.
                 */
-               for (i=0; i<iCnt; i++) {
+               for (i=0; i<aCnt; i++) {
+                       CFDictionaryRef         aDict;
                        CFArrayRef              addrs;
                        CFArrayRef              dests;
-                       CFDictionaryRef         iDict;
                        CFIndex                 j;
                        CFArrayRef              masks;
                        CFIndex                 nAddrs  = 0;
 
-                       iKey  = CFArrayGetValueAtIndex(interfaceOrder, i);
-                       iDict = CFDictionaryGetValue(interfaces, iKey);
+                       key   = CFArrayGetValueAtIndex(serviceOrder, i);
+                       aDict = CFDictionaryGetValue(active, key);
 
-                       if (!getAddresses(iDict, &nAddrs, &addrs, &masks, &dests)) {
+                       if (!sin->sin_addr.s_addr ||
+                           !defaultRoute ||
+                           !aDict ||
+                           !getAddresses(aDict, &nAddrs, &addrs, &masks, &dests)) {
                                /* if no addresses to check */
                                continue;
                        }
@@ -586,11 +641,8 @@ checkAddress(SCDSessionRef         session,
                                        if ((ntohl(ifAddr.s_addr)        & ntohl(ifMask.s_addr)) ==
                                            (ntohl(defaultRoute->s_addr) & ntohl(ifMask.s_addr))) {
                                                /* the requested address is on this subnet */
-#ifdef DEBUG
-                                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                                       SCDLog(LOG_INFO, CFSTR("  isReachable via default route (my subnet)"));
-#endif /* DEBUG */
-                                               scn_status = SCN_REACHABLE_YES;
+                                               statusMessage = "isReachable via default route (my subnet)";
+                                               *flags |= kSCNetworkFlagsReachable;
                                                goto checkInterface;
                                        }
                                } else {
@@ -605,11 +657,8 @@ checkAddress(SCDSessionRef         session,
 
                                        if (ntohl(destAddr.s_addr) == ntohl(defaultRoute->s_addr)) {
                                                /* the address is the other side of the link */
-#ifdef DEBUG
-                                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                                       SCDLog(LOG_INFO, CFSTR("  isReachable via default route (my remote address)"));
-#endif /* DEBUG */
-                                               scn_status = SCN_REACHABLE_YES;
+                                               statusMessage = "isReachable via default route (my remote address)";
+                                               *flags |= kSCNetworkFlagsReachable;
                                                goto checkInterface;
                                        }
                                }
@@ -619,115 +668,58 @@ checkAddress(SCDSessionRef               session,
                /*
                 * Check the not active (but configured) IPv4 services
                 */
-               sCnt = CFArrayGetCount(sKeys);
-               for (i=0; i<sCnt; i++) {
-                       CFArrayRef              addrs;
-                       CFStringRef             configMethod    = NULL;
-                       CFArrayRef              dests;
-                       CFIndex                 j;
-                       CFArrayRef              masks;
-                       CFIndex                 nAddrs          = 0;
+               for (i=0; i<aCnt; i++) {
+                       key = CFArrayGetValueAtIndex(serviceOrder, i);
 
-                       sKey  = CFArrayGetValueAtIndex(sKeys, i);
-                       sDict = CFDictionaryGetValue(services, sKey);
+                       if (CFDictionaryContainsKey(active, key)) {
+                               /* if this service is active */
+                               continue;
+                       }
+
+                       cDict = CFDictionaryGetValue(config, key);
+                       if (!cDict) {
+                               /* if no configuration for this service */
+                               continue;
+                       }
 
                        /*
-                        * check configured network addresses
+                        * We have a service which "claims" to be a potential path
+                        * off of the system.  Check to make sure that this is a
+                        * type of PPP link before claiming it's viable.
                         */
-                       for (j=0; j<nAddrs; j++) {
-                               struct in_addr  ifAddr;
-
-                               if (inet_atonCF(CFArrayGetValueAtIndex(addrs, j),
-                                               &ifAddr) == 0) {
-                                       /* if Addresses string is invalid */
-                                       break;
-                               }
-
-                               if (masks) {
-                                       struct in_addr  ifMask;
-
-                                       /* check address/netmask */
-                                       if (inet_atonCF(CFArrayGetValueAtIndex(masks, j),
-                                                       &ifMask) == 0) {
-                                               /* if SubnetMasks string is invalid */
-                                               break;
-                                       }
-
-                                       if ((ntohl(ifAddr.s_addr)        & ntohl(ifMask.s_addr)) !=
-                                           (ntohl(sin->sin_addr.s_addr) & ntohl(ifMask.s_addr))) {
-                                               /* the requested address is on this subnet */
-#ifdef DEBUG
-                                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                                       SCDLog(LOG_INFO, CFSTR("  is configured w/static info (my subnet)"));
-#endif /* DEBUG */
-                                               goto checkService;
-                                       }
-                               } else {
-                                       struct in_addr  destAddr;
+                       aType = CFDictionaryGetValue(cDict, kSCPropNetInterfaceType);
+                       if (!aType || !CFEqual(aType, kSCValNetInterfaceTypePPP)) {
+                               /* if we can't get a connection on this service */
+                               sc_status = kSCStatusOK;
+                               goto done;
+                       }
 
-                                       /* check remote address */
-                                       if (inet_atonCF(CFArrayGetValueAtIndex(dests, j),
-                                                       &destAddr) == 0) {
-                                               /* if DestAddresses string is invalid */
-                                               break;
-                                       }
+                       statusMessage = "is configured w/dynamic addressing";
+                       *flags |= kSCNetworkFlagsTransientConnection;
+                       *flags |= kSCNetworkFlagsReachable;
+                       *flags |= kSCNetworkFlagsConnectionRequired;
 
-                                       /* check local address */
-                                       if (ntohl(sin->sin_addr.s_addr) == ntohl(ifAddr.s_addr)) {
-                                               /* the address is our side of the link */
-#ifdef DEBUG
-                                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                                       SCDLog(LOG_INFO, CFSTR("  is configured w/static info (my local address)"));
-#endif /* DEBUG */
-                                               goto checkService;
-                                       }
-
-                                       if (ntohl(sin->sin_addr.s_addr) == ntohl(destAddr.s_addr)) {
-                                               /* the address is the other side of the link */
-#ifdef DEBUG
-                                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                                       SCDLog(LOG_INFO, CFSTR("  is configured w/static info (my remote address)"));
-#endif /* DEBUG */
-                                               goto checkService;
-                                       }
-                               }
+                       if (_sc_debug) {
+                               SCLog(TRUE, LOG_INFO, CFSTR("  status     = %s"), statusMessage);
+                               SCLog(TRUE, LOG_INFO, CFSTR("  service id = %@"), key);
                        }
 
-                       /*
-                        * check for dynamic (i.e. not manual) configuration
-                        * method.
-                        */
-                       if (CFDictionaryGetValueIfPresent(sDict,
-                                                         kSCPropNetIPv4ConfigMethod,
-                                                         (void **)&configMethod) &&
-                           !CFEqual(configMethod, kSCValNetIPv4ConfigMethodManual)) {
-                               /* if only we were "connected" */
-#ifdef DEBUG
-                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                       SCDLog(LOG_INFO, CFSTR("  is configured w/dynamic addressing"));
-#endif /* DEBUG */
-                               goto checkService;
-                       }
+                       sc_status = kSCStatusOK;
+                       goto done;
                }
 
-#ifdef DEBUG
-               if (SCDOptionGet(session, kSCDOptionDebug))
-                       SCDLog(LOG_INFO, CFSTR("  cannot be reached"));
-#endif /* DEBUG */
-               scn_status = SCN_REACHABLE_NO;
+               SCLog(_sc_debug, LOG_INFO, CFSTR("  cannot be reached"));
+               sc_status = kSCStatusOK;
                goto done;
 
        } else {
                /*
                 * if no code for this address family (yet)
                 */
-               SCDSessionLog(session,
-                             LOG_ERR,
-                             CFSTR("checkAddress(): unexpected address family %d"),
-                             address->sa_family);
-               if (errorMessage != NULL) {
-                       *errorMessage = "unexpected address family";
-               }
+               SCLog(_sc_verbose, LOG_ERR,
+                     CFSTR("checkAddress(): unexpected address family %d"),
+                     address->sa_family);
+               sc_status = kSCStatusInvalidArgument;
                goto done;
        }
 
@@ -735,52 +727,61 @@ checkAddress(SCDSessionRef                session,
 
     checkInterface :
 
+       if (_sc_debug) {
+               CFDictionaryRef aDict;
+               CFStringRef     interface       = NULL;
+
+               /* attempt to get the interface type from the config info */
+               aDict = CFDictionaryGetValue(active, key);
+               if (aDict) {
+                       interface = CFDictionaryGetValue(aDict, kSCPropInterfaceName);
+               }
+
+               SCLog(TRUE, LOG_INFO, CFSTR("  status     = %s"), statusMessage);
+               SCLog(TRUE, LOG_INFO, CFSTR("  service id = %@"), key);
+               SCLog(TRUE, LOG_INFO, CFSTR("  device     = %@"), interface ? interface : CFSTR("?"));
+       }
+
+       sc_status = kSCStatusOK;
+
        /*
         * We have an interface which "claims" to be a valid path
         * off of the system.  Check to make sure that this isn't
         * a dial-on-demand PPP link that isn't connected yet.
         */
-       if (sIDs) {
+       {
                CFNumberRef     num;
-               CFDictionaryRef sDict;
-
-               /* attempt to get the interface type from the first service */
-               sID   = CFArrayGetValueAtIndex(sIDs, 0);
-               sDict = CFDictionaryGetValue(services, sID);
-               if (sDict) {
-                       iType = CFDictionaryGetValue(sDict, kSCPropNetInterfaceType);
-               }
+               CFDictionaryRef cDict;
 
-               if (!iType) {
-                       /* if we don't know the interface type */
-                       goto done;
+               /* attempt to get the interface type from the config info */
+               cDict = CFDictionaryGetValue(config, key);
+               if (cDict) {
+                       aType = CFDictionaryGetValue(cDict, kSCPropNetInterfaceType);
                }
 
-               if (!CFEqual(iType, kSCValNetInterfaceTypePPP)) {
-                       /* if not a ppp interface */
+               if (!aType || !CFEqual(aType, kSCValNetInterfaceTypePPP)) {
+                       /*
+                        * if we don't know the interface type or if
+                        * it is not a ppp interface
+                        */
                        goto done;
                }
 
-               num = CFDictionaryGetValue(sDict, kSCPropNetPPPDialOnDemand);
+               num = CFDictionaryGetValue(cDict, kSCPropNetPPPDialOnDemand);
                if (num) {
                        int     dialOnDemand;
 
-                       CFNumberGetValue(num, kCFNumberIntType, &dialOnDemand); 
-                       if (flags && (dialOnDemand != 0)) {
-                               *flags |= kSCNFlagsConnectionAutomatic;
+                       CFNumberGetValue(num, kCFNumberIntType, &dialOnDemand);
+                       if (dialOnDemand != 0) {
+                               *flags |= kSCNetworkFlagsConnectionAutomatic;
                        }
-                       
+
                }
-       } else if (!CFStringHasPrefix(iKey, CFSTR("ppp"))) {
-               /* if not a ppp interface */
-               goto done;
        }
 
-       if (flags != NULL) {
-               *flags |= kSCNFlagsTransientConnection;
-       }
+       *flags |= kSCNetworkFlagsTransientConnection;
 
-       if (sID) {
+       {
                u_int32_t               pppLink;
                struct ppp_status       *pppLinkStatus;
                int                     pppStatus;
@@ -791,45 +792,26 @@ checkAddress(SCDSessionRef                session,
                 */
                pppStatus = PPPInit(&pppRef);
                if (pppStatus != 0) {
-#ifdef DEBUG
-                       if (SCDOptionGet(session, kSCDOptionDebug))
-                               SCDLog(LOG_DEBUG, CFSTR("  PPPInit() failed: status=%d"), pppStatus);
-#endif /* DEBUG */
-                       scn_status = SCN_REACHABLE_UNKNOWN;
-                       if (errorMessage != NULL) {
-                               *errorMessage = "PPPInit() failed";
-                       }
+                       SCLog(_sc_debug, LOG_DEBUG, CFSTR("  PPPInit() failed: status=%d"), pppStatus);
+                       sc_status = kSCStatusReachabilityUnknown;
                        goto done;
                }
 
-               pppStatus = PPPGetLinkByServiceID(pppRef, sID, &pppLink);
+               pppStatus = PPPGetLinkByServiceID(pppRef, key, &pppLink);
                if (pppStatus != 0) {
-#ifdef DEBUG
-                       if (SCDOptionGet(session, kSCDOptionDebug))
-                               SCDLog(LOG_DEBUG, CFSTR("  PPPGetLinkByServiceID() failed: status=%d"), pppStatus);
-#endif /* DEBUG */
-                       scn_status = SCN_REACHABLE_UNKNOWN;
-                       if (errorMessage != NULL) {
-                               *errorMessage = "PPPGetLinkByServiceID() failed";
-                       }
+                       SCLog(_sc_debug, LOG_DEBUG, CFSTR("  PPPGetLinkByServiceID() failed: status=%d"), pppStatus);
+                       sc_status = kSCStatusReachabilityUnknown;
                        goto done;
                }
 
                pppStatus = PPPStatus(pppRef, pppLink, &pppLinkStatus);
                if (pppStatus != 0) {
-#ifdef DEBUG
-                       if (SCDOptionGet(session, kSCDOptionDebug))
-                               SCDLog(LOG_DEBUG, CFSTR("  PPPStatus() failed: status=%d"), pppStatus);
-#endif /* DEBUG */
-                       scn_status = SCN_REACHABLE_UNKNOWN;
-                       if (errorMessage != NULL) {
-                               *errorMessage = "PPPStatus() failed";
-                       }
+                       SCLog(_sc_debug, LOG_DEBUG, CFSTR("  PPPStatus() failed: status=%d"), pppStatus);
+                       sc_status = kSCStatusReachabilityUnknown;
                        goto done;
                }
 #ifdef DEBUG
-               if (SCDOptionGet(session, kSCDOptionDebug))
-                       SCDLog(LOG_DEBUG, CFSTR("  PPP link status = %d"), pppLinkStatus->status);
+               SCLog(_sc_debug, LOG_DEBUG, CFSTR("  PPP link status = %d"), pppLinkStatus->status);
 #endif /* DEBUG */
                switch (pppLinkStatus->status) {
                        case PPP_RUNNING :
@@ -837,389 +819,460 @@ checkAddress(SCDSessionRef              session,
                                break;
                        case PPP_IDLE :
                                /* if we're not connected at all */
-#ifdef DEBUG
-                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                       SCDLog(LOG_INFO, CFSTR("  PPP link idle, dial-on-traffic to connect"));
-#endif /* DEBUG */
-                               scn_status = SCN_REACHABLE_CONNECTION_REQUIRED;
+                               SCLog(_sc_debug, LOG_INFO, CFSTR("  PPP link idle, dial-on-traffic to connect"));
+                               *flags |= kSCNetworkFlagsReachable;
+                               *flags |= kSCNetworkFlagsConnectionRequired;
+                               sc_status = kSCStatusOK;
                                break;
                        default :
                                /* if we're in the process of [dis]connecting */
-#ifdef DEBUG
-                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                       SCDLog(LOG_INFO, CFSTR("  PPP link, connection in progress"));
-#endif /* DEBUG */
-                               scn_status = SCN_REACHABLE_CONNECTION_REQUIRED;
+                               SCLog(_sc_debug, LOG_INFO, CFSTR("  PPP link, connection in progress"));
+                               *flags |= kSCNetworkFlagsReachable;
+                               *flags |= kSCNetworkFlagsConnectionRequired;
+                               sc_status = kSCStatusOK;
                                break;
                }
                CFAllocatorDeallocate(NULL, pppLinkStatus);
-       } else {
-               /*
-                * The service ID is not available, check the interfaces
-                * UP and RUNNING flags.
-                */
-               bzero(&ifr, sizeof(ifr));
-               if (!CFStringGetCString(iKey,
-                                       (char *)&ifr.ifr_name,
-                                       sizeof(ifr.ifr_name),
-                                       kCFStringEncodingMacRoman)) {
-                       scn_status = SCN_REACHABLE_UNKNOWN;
-                       if (errorMessage != NULL) {
-                               *errorMessage = "could not convert interface name to C string";
-                       }
-                       goto done;
-               }
-
-               sock = socket(AF_INET, SOCK_DGRAM, 0);
-               if (sock == -1) {
-                       scn_status = SCN_REACHABLE_UNKNOWN;
-                       if (errorMessage != NULL) {
-                               *errorMessage = strerror(errno);
-                       }
-                       goto done;
-               }
-
-               if (ioctl(sock, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
-                       scn_status = SCN_REACHABLE_UNKNOWN;
-                       if (errorMessage != NULL) {
-                               *errorMessage = strerror(errno);
-                       }
-                       goto done;
-               }
-
-#ifdef DEBUG
-               if (SCDOptionGet(session, kSCDOptionDebug))
-                       SCDLog(LOG_INFO, CFSTR("  flags for %s == 0x%hx"), ifr.ifr_name, ifr.ifr_flags);
-#endif /* DEBUG */
-               if ((ifr.ifr_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
-                       if ((ifr.ifr_flags & IFF_UP) == IFF_UP) {
-                               /* if we're "up" but not "running" */
-#ifdef DEBUG
-                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                       SCDLog(LOG_INFO, CFSTR("  up & not running, dial-on-traffic to connect"));
-#endif /* DEBUG */
-                               scn_status = SCN_REACHABLE_CONNECTION_REQUIRED;
-                               if (flags != NULL) {
-                                       *flags |= kSCNFlagsConnectionAutomatic;
-                               }
-                       } else {
-                               /* if we're not "up" and "running" */
-#ifdef DEBUG
-                               if (SCDOptionGet(session, kSCDOptionDebug))
-                                       SCDLog(LOG_INFO, CFSTR("  not up & running, connection required"));
-#endif /* DEBUG */
-                               scn_status = SCN_REACHABLE_CONNECTION_REQUIRED;
-                       }
-                       goto done;
-               }
        }
 
        goto done;
 
-    checkService :
-
-       /*
-        * We have a service which "claims" to be a potential path
-        * off of the system.  Check to make sure that this is a
-        * type of PPP link before claiming it's viable.
-        */
-       if (sDict &&
-           CFDictionaryGetValueIfPresent(sDict,
-                                         kSCPropNetInterfaceType,
-                                         (void **)&iType) &&
-           !CFEqual(iType, kSCValNetInterfaceTypePPP)) {
-               /* no path if this not a ppp interface */
-#ifdef DEBUG
-               if (SCDOptionGet(session, kSCDOptionDebug))
-                       SCDLog(LOG_INFO, CFSTR("  cannot be reached"));
-#endif /* DEBUG */
-               scn_status = SCN_REACHABLE_NO;
-               goto done;
-       }
-
-       scn_status = SCN_REACHABLE_CONNECTION_REQUIRED;
-       if (flags != NULL) {
-               *flags |= kSCNFlagsTransientConnection;
-       }
-
     done :
 
-       if (sKeys)              CFRelease(sKeys);
-       if (sList)              CFRelease(sList);
        if (pppRef != -1)       (void) PPPDispose(pppRef);
-       if (sock != -1)         (void)close(sock);
 
-       return scn_status;
+       if (sc_status != kSCStatusOK) {
+               _SCErrorSet(sc_status);
+               return FALSE;
+       }
+
+       return TRUE;
 }
 
 
 static void
-_IsReachableInit(SCDSessionRef session,
-       CFDictionaryRef *services,
-       CFDictionaryRef *interfaces,
-       CFArrayRef      *interfaceOrder,
-       struct in_addr  **defaultRoute)
+_CheckReachabilityInit(SCDynamicStoreRef       store,
+                      CFDictionaryRef          *config,
+                      CFDictionaryRef          *active,
+                      CFArrayRef               *serviceOrder,
+                      struct in_addr           **defaultRoute)
 {
-       CFStringRef     addr;
-       CFDictionaryRef dict;
-       CFStringRef     key;
-       SCDHandleRef    handle;
-       CFNumberRef     pppOverridePrimary      = NULL;
-       CFArrayRef      serviceOrder            = NULL;
-       struct in_addr  *route                  = NULL;
-       SCDStatus       status;
+       CFMutableDictionaryRef  activeDict;
+       CFMutableDictionaryRef  configDict;
+       initContext             context;
+       CFDictionaryRef         dict;
+       CFMutableDictionaryRef  interfaces;
+       CFMutableArrayRef       keys;
+       CFMutableArrayRef       orderArray;
+       CFDictionaryRef         orderDict;
+       CFStringRef             orderKey;
+       CFStringRef             pattern;
+       CFMutableArrayRef       patterns;
+       CFStringRef             routeKey;
+       CFDictionaryRef         routeDict;
+
+       configDict = CFDictionaryCreateMutable(NULL,
+                                              0,
+                                              &kCFTypeDictionaryKeyCallBacks,
+                                              &kCFTypeDictionaryValueCallBacks);
+       *config = configDict;
+
+       activeDict = CFDictionaryCreateMutable(NULL,
+                                              0,
+                                              &kCFTypeDictionaryKeyCallBacks,
+                                              &kCFTypeDictionaryValueCallBacks);
+       *active = activeDict;
+
+       orderArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       *serviceOrder = orderArray;
+
+       *defaultRoute = NULL;
+
+       interfaces = CFDictionaryCreateMutable(NULL,
+                                              0,
+                                              &kCFTypeDictionaryKeyCallBacks,
+                                              &kCFTypeDictionaryValueCallBacks);
 
        /*
-        * get the ServiceOrder and PPPOverridePrimary keys
-        * from the global settings.
+        * collect information on the configured services and their
+        * associated interface type.
         */
-       key = SCDKeyCreateNetworkGlobalEntity(kSCCacheDomainSetup, kSCEntNetIPv4);
-       status = SCDGet(session, key, &handle);
-       CFRelease(key);
-       switch (status) {
-               case SCD_OK :
-                       /* if global settings are available */
-                       dict = SCDHandleGetData(handle);
-
-                       /* get service order */
-                       if ((CFDictionaryGetValueIfPresent(dict,
-                                                          kSCPropNetServiceOrder,
-                                                          (void **)&serviceOrder) == TRUE)) {
-                               CFRetain(serviceOrder);
-                       }
+       keys     = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
-                       /* get PPP overrides primary flag */
-                       if ((CFDictionaryGetValueIfPresent(dict,
-                                                          kSCPropNetPPPOverridePrimary,
-                                                          (void **)&pppOverridePrimary) == TRUE)) {
-                               CFRetain(pppOverridePrimary);
-                       }
+       /*
+        * Setup:/Network/Global/IPv4 (for the ServiceOrder)
+        */
+       orderKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                             kSCDynamicStoreDomainSetup,
+                                                             kSCEntNetIPv4);
+       CFArrayAppendValue(keys, orderKey);
 
-                       SCDHandleRelease(handle);
-                       break;
-               case SCD_NOKEY :
-                       /* if no global settings */
-                       break;
-               default :
-                       SCDLog(LOG_ERR, CFSTR("SCDGet() failed: %s"), SCDError(status));
-                       /* XXX need to do something more with this FATAL error XXXX */
-                       goto error;
+       /*
+        * State:/Network/Global/IPv4 (for the DefaultRoute)
+        */
+       routeKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+                                                             kSCDynamicStoreDomainState,
+                                                             kSCEntNetIPv4);
+       CFArrayAppendValue(keys, routeKey);
+
+       /* Setup: per-service IPv4 info */
+       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                             kSCDynamicStoreDomainSetup,
+                                                             kSCCompAnyRegex,
+                                                             kSCEntNetIPv4);
+       CFArrayAppendValue(patterns, pattern);
+       CFRelease(pattern);
+
+       /* Setup: per-service Interface info */
+       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                             kSCDynamicStoreDomainSetup,
+                                                             kSCCompAnyRegex,
+                                                             kSCEntNetInterface);
+       CFArrayAppendValue(patterns, pattern);
+       CFRelease(pattern);
+
+       /* Setup: per-service PPP info */
+       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                             kSCDynamicStoreDomainSetup,
+                                                             kSCCompAnyRegex,
+                                                             kSCEntNetPPP);
+       CFArrayAppendValue(patterns, pattern);
+       CFRelease(pattern);
+
+       /* State: per-service IPv4 info */
+       pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+                                                             kSCDynamicStoreDomainState,
+                                                             kSCCompAnyRegex,
+                                                             kSCEntNetIPv4);
+       CFArrayAppendValue(patterns, pattern);
+       CFRelease(pattern);
+
+       /* State: per-interface IPv4 info */
+       pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
+                                                               kSCDynamicStoreDomainState,
+                                                               kSCCompAnyRegex,
+                                                               kSCEntNetIPv4);
+       CFArrayAppendValue(patterns, pattern);
+       CFRelease(pattern);
+
+       /* fetch the configuration information */
+       dict = SCDynamicStoreCopyMultiple(store, keys, patterns);
+       CFRelease(keys);
+       CFRelease(patterns);
+       if (!dict) {
+               goto done;
        }
 
        /*
-        * Get default route
+        * get the ServiceOrder key from the global settings.
         */
-       key = SCDKeyCreateNetworkGlobalEntity(kSCCacheDomainState,
-                                             kSCEntNetIPv4);
-       status = SCDGet(session, key, &handle);
-       CFRelease(key);
-       switch (status) {
-               case SCD_OK :
-                       dict = SCDHandleGetData(handle);
-                       addr = CFDictionaryGetValue(dict, kSCPropNetIPv4Router);
-                       if (addr == NULL) {
-                               /* if no default route */
-                               break;
-                       }
+       orderDict = CFDictionaryGetValue(dict, orderKey);
+       if (isA_CFDictionary(orderDict)) {
+               CFArrayRef      array;
+
+               /* global settings are available */
+               array = (CFMutableArrayRef)CFDictionaryGetValue(orderDict, kSCPropNetServiceOrder);
+               if (isA_CFArray(array)) {
+                       CFArrayAppendArray(orderArray,
+                                          array,
+                                          CFRangeMake(0, CFArrayGetCount(array)));
+               }
+       }
+
+       /*
+        * get the DefaultRoute
+        */
+       routeDict = CFDictionaryGetValue(dict, routeKey);
+       if (isA_CFDictionary(routeDict)) {
+               CFStringRef     addr;
+
+               /* global state is available, get default route */
+               addr = CFDictionaryGetValue(routeDict, kSCPropNetIPv4Router);
+               if (isA_CFString(addr)) {
+                       struct in_addr  *route;
 
                        route = CFAllocatorAllocate(NULL, sizeof(struct in_addr), 0);
                        if (inet_atonCF(addr, route) == 0) {
                                /* if address string is invalid */
                                CFAllocatorDeallocate(NULL, route);
                                route = NULL;
-                               break;
+                       } else {
+                               *defaultRoute = route;
                        }
-                       *defaultRoute = route;
-
-                       break;
-               case SCD_NOKEY :
-                       /* if no default route */
-                       break;
-               default :
-                       SCDSessionLog(session,
-                                     LOG_ERR,
-                                     CFSTR("SCDGet() failed: %s"),
-                                     SCDError(status));
-                       goto error;
-       }
-       if (handle) {
-               SCDHandleRelease(handle);
-               handle = NULL;
+               }
        }
 
        /*
-        * get the configured services and interfaces
+        * collect the configured services, the active services, and
+        * the active interfaces.
         */
-       *services       = getServices  (session);
-       *interfaces     = getInterfaces(session);
-       *interfaceOrder = getInterfaceOrder(*interfaces,
-                                           serviceOrder,
-                                           pppOverridePrimary);
+       context.cDict   = configDict;
+       context.cPrefix = SCDynamicStoreKeyCreate(NULL,
+                                                 CFSTR("%@/%@/%@/"),
+                                                 kSCDynamicStoreDomainSetup,
+                                                 kSCCompNetwork,
+                                                 kSCCompService);
+       context.aDict   = activeDict;
+       context.aPrefix = SCDynamicStoreKeyCreate(NULL,
+                                                 CFSTR("%@/%@/%@/"),
+                                                 kSCDynamicStoreDomainState,
+                                                 kSCCompNetwork,
+                                                 kSCCompService);
+       context.iDict   = interfaces;
+       context.iPrefix = SCDynamicStoreKeyCreate(NULL,
+                                                 CFSTR("%@/%@/%@/"),
+                                                 kSCDynamicStoreDomainState,
+                                                 kSCCompNetwork,
+                                                 kSCCompInterface);
+       context.order = orderArray;
+
+       CFDictionaryApplyFunction(dict, collectInfo, &context);
 
-    error :
+       /*
+        * add additional information for the configured services
+        */
+       CFDictionaryApplyFunction(dict, collectExtraInfo, &context);
 
-       if (serviceOrder)       CFRelease(serviceOrder);
-       if (pppOverridePrimary) CFRelease(pppOverridePrimary);
+       /*
+        * remove any addresses associated with known services
+        */
+       CFDictionaryApplyFunction(activeDict, removeKnownAddresses, interfaces);
+
+       /*
+        * create new services for any remaining addresses
+        */
+       CFDictionaryApplyFunction(interfaces, addUnknownService, &context);
+
+       CFRelease(context.cPrefix);
+       CFRelease(context.aPrefix);
+       CFRelease(context.iPrefix);
+       CFRelease(dict);
+
+    done :
+
+       CFRelease(interfaces);
+       CFRelease(orderKey);
+       CFRelease(routeKey);
 
 #ifdef DEBUG
-       if (SCDOptionGet(session, kSCDOptionDebug)) {
-               SCDLog(LOG_NOTICE, CFSTR("interfaces     = %@"), *interfaces);
-               SCDLog(LOG_NOTICE, CFSTR("services       = %@"), *services);
-               SCDLog(LOG_NOTICE, CFSTR("interfaceOrder = %@"), *interfaceOrder);
-               SCDLog(LOG_NOTICE, CFSTR("defaultRoute   = %s"), *defaultRoute?inet_ntoa(**defaultRoute):"None");
-       }
+       SCLog(_sc_debug, LOG_NOTICE, CFSTR("config = %@"), *config);
+       SCLog(_sc_debug, LOG_NOTICE, CFSTR("active = %@"), *active);
+       SCLog(_sc_debug, LOG_NOTICE, CFSTR("serviceOrder = %@"), *serviceOrder);
+       SCLog(_sc_debug, LOG_NOTICE, CFSTR("defaultRoute = %s"), *defaultRoute?inet_ntoa(**defaultRoute):"None");
 #endif /* DEBUG */
        return;
-
 }
 
 
 static void
-_IsReachableFree(CFDictionaryRef       services,
-                CFDictionaryRef        interfaces,
-                CFArrayRef             interfaceOrder,
-                struct in_addr         *defaultRoute)
+_CheckReachabilityFree(CFDictionaryRef config,
+                      CFDictionaryRef  active,
+                      CFArrayRef       serviceOrder,
+                      struct in_addr   *defaultRoute)
 {
-       if (services)           CFRelease(services);
-       if (interfaces)         CFRelease(interfaces);
-       if (interfaceOrder)     CFRelease(interfaceOrder);
+       if (config)             CFRelease(config);
+       if (active)             CFRelease(active);
+       if (serviceOrder)       CFRelease(serviceOrder);
        if (defaultRoute)       CFAllocatorDeallocate(NULL, defaultRoute);
        return;
 }
 
 
-SCNStatus
-SCNIsReachableByAddress(const struct sockaddr  *address,
-                       const int               addrlen,
-                       int                     *flags,
-                       const char              **errorMessage)
+Boolean
+SCNetworkCheckReachabilityByAddress(const struct sockaddr      *address,
+                                   const int                   addrlen,
+                                   SCNetworkConnectionFlags    *flags)
 {
-       struct in_addr  *defaultRoute   = NULL;
-       CFDictionaryRef interfaces      = NULL;
-       CFArrayRef      interfaceOrder  = NULL;
-       CFDictionaryRef services        = NULL;
-       SCDSessionRef   session         = NULL;
-       SCDStatus       scd_status;
-       SCNStatus       scn_status;
-
-       scd_status = SCDOpen(&session, CFSTR("SCNIsReachableByAddress"));
-       if (scd_status != SCD_OK) {
-               if (errorMessage != NULL) {
-                       *errorMessage = SCDError(scd_status);
+       CFDictionaryRef         active          = NULL;
+       CFDictionaryRef         config          = NULL;
+       struct in_addr          *defaultRoute   = NULL;
+       Boolean                 ok;
+       CFArrayRef              serviceOrder    = NULL;
+       SCDynamicStoreRef       store           = NULL;
+
+       *flags = 0;
+
+       /*
+        * Check if 0.0.0.0
+        */
+       if (address->sa_family == AF_INET) {
+               struct sockaddr_in      *sin = (struct sockaddr_in *)address;
+
+               if (sin->sin_addr.s_addr == 0) {
+                       SCLog(_sc_debug, LOG_INFO, CFSTR("checkAddress(0.0.0.0)"));
+                       SCLog(_sc_debug, LOG_INFO, CFSTR("  status     = isReachable (this host)"));
+                       *flags |= kSCNetworkFlagsReachable;
+                       return TRUE;
                }
-               return SCN_REACHABLE_UNKNOWN;
        }
 
-       _IsReachableInit(session, &services, &interfaces, &interfaceOrder, &defaultRoute);
-       scn_status = checkAddress(session,
-                                 address,
-                                 addrlen,
-                                 services,
-                                 interfaces,
-                                 interfaceOrder,
-                                 defaultRoute,
-                                 flags,
-                                 errorMessage);
-       _IsReachableFree(services, interfaces, interfaceOrder, defaultRoute);
+       store = SCDynamicStoreCreate(NULL,
+                                    CFSTR("SCNetworkCheckReachabilityByAddress"),
+                                    NULL,
+                                    NULL);
+       if (!store) {
+               SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+               return FALSE;
+       }
 
-       (void) SCDClose(&session);
-       return scn_status;
+       _CheckReachabilityInit(store, &config, &active, &serviceOrder, &defaultRoute);
+       ok = checkAddress(store,
+                         address,
+                         addrlen,
+                         config,
+                         active,
+                         serviceOrder,
+                         defaultRoute,
+                         flags);
+       _CheckReachabilityFree(config, active, serviceOrder, defaultRoute);
+
+       CFRelease(store);
+       return ok;
 }
 
 
-SCNStatus
-SCNIsReachableByName(const char                *nodename,
-                    int                *flags,
-                    const char         **errorMessage)
+/*
+ * rankReachability()
+ *   Not reachable       == 0
+ *   Connection Required == 1
+ *   Reachable           == 2
+ */
+static int
+rankReachability(int flags)
 {
-       struct in_addr  *defaultRoute   = NULL;
-       struct hostent  *h;
-       int             i;
-       CFDictionaryRef interfaces      = NULL;
-       CFArrayRef      interfaceOrder  = NULL;
-       SCDStatus       scd_status      = SCD_OK;
-       SCNStatus       ns_status       = SCN_REACHABLE_YES;
-       struct addrinfo *res            = NULL;
-       struct addrinfo *resP;
-       CFDictionaryRef services        = NULL;
-       SCDSessionRef   session         = NULL;
-       SCNStatus       scn_status      = SCN_REACHABLE_YES;
-
-       scd_status = SCDOpen(&session, CFSTR("SCNIsReachableByName"));
-       if (scd_status != SCD_OK) {
-               scn_status = SCN_REACHABLE_UNKNOWN;
-               if (errorMessage != NULL) {
-                       *errorMessage = SCDError(scd_status);
-               }
-               goto done;
+       int     rank = 0;
+
+       if (flags & kSCNetworkFlagsReachable)           rank = 2;
+       if (flags & kSCNetworkFlagsConnectionRequired)  rank = 1;
+       return rank;
+}
+
+
+Boolean
+SCNetworkCheckReachabilityByName(const char                    *nodename,
+                                SCNetworkConnectionFlags       *flags)
+{
+       CFDictionaryRef         active          = NULL;
+       CFDictionaryRef         config          = NULL;
+       struct in_addr          *defaultRoute   = NULL;
+       struct hostent          *h;
+       Boolean                 haveDNS         = FALSE;
+       int                     i;
+       Boolean                 ok              = TRUE;
+       struct addrinfo         *res            = NULL;
+       struct addrinfo         *resP;
+       CFArrayRef              serviceOrder    = NULL;
+       SCDynamicStoreRef       store           = NULL;
+
+       store = SCDynamicStoreCreate(NULL,
+                                    CFSTR("SCNetworkCheckReachabilityByName"),
+                                    NULL,
+                                    NULL);
+       if (!store) {
+               SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+               return FALSE;
        }
 
-       _IsReachableInit(session, &services, &interfaces, &interfaceOrder, &defaultRoute);
+       _CheckReachabilityInit(store, &config, &active, &serviceOrder, &defaultRoute);
 
        /*
-        * since we don't know which name server will be consulted
-        * to resolve the specified nodename we need to check the
-        * availability of ALL name servers.
+        * We first assume that all of the configured DNS servers
+        * are available.  Since we don't know which name server will
+        * be consulted to resolve the specified nodename we need to
+        * check the availability of ALL name servers.  We can only
+        * proceed if we know that our query can be answered.
         */
+
+       *flags = kSCNetworkFlagsReachable;
+
        res_init();
        for (i=0; i<_res.nscount; i++) {
-               ns_status = checkAddress(session,
-                                        (struct sockaddr *)&_res.nsaddr_list[i],
-                                        _res.nsaddr_list[i].sin_len,
-                                        services,
-                                        interfaces,
-                                        interfaceOrder,
-                                        defaultRoute,
-                                        flags,
-                                        errorMessage);
-               if (ns_status < scn_status) {
+               SCNetworkConnectionFlags        ns_flags        = 0;
+
+               if (_res.nsaddr_list[i].sin_addr.s_addr == 0) {
+                       continue;
+               }
+
+               haveDNS = TRUE;
+
+               if (_res.nsaddr_list[i].sin_len == 0) {
+                       _res.nsaddr_list[i].sin_len = sizeof(_res.nsaddr_list[i]);
+               }
+
+               ok = checkAddress(store,
+                                 (struct sockaddr *)&_res.nsaddr_list[i],
+                                 _res.nsaddr_list[i].sin_len,
+                                 config,
+                                 active,
+                                 serviceOrder,
+                                 defaultRoute,
+                                 &ns_flags);
+               if (!ok) {
+                       /* not today */
+                       break;
+               }
+               if (rankReachability(ns_flags) < rankReachability(*flags)) {
                        /* return the worst case result */
-                       scn_status = ns_status;
-                       if (ns_status == SCN_REACHABLE_UNKNOWN) {
-                               /* not today */
-                               break;
-                       }
+                       *flags = ns_flags;
                }
        }
 
-       if (ns_status < SCN_REACHABLE_YES) {
+       if (!ok || (rankReachability(*flags) < 2)) {
                goto done;
        }
 
+       SCLog(_sc_debug, LOG_INFO, CFSTR("check DNS for \"%s\""), nodename);
+
        /*
         * OK, all of the DNS name servers are available.  Let's
         * first assume that the requested host is NOT available,
         * resolve the nodename, and check its address for
         * accessibility. We return the best status available.
         */
-       scn_status = SCN_REACHABLE_UNKNOWN;
+       *flags = 0;
 
        /*
         * resolve the nodename into an address
         */
        i = getaddrinfo(nodename, NULL, NULL, &res);
        if (i != 0) {
-               SCDSessionLog(session,
-                             LOG_ERR,
-                             CFSTR("getaddrinfo() failed: %s"),
-                             gai_strerror(i));
+               SCLog(_sc_verbose, LOG_ERR,
+                     CFSTR("getaddrinfo() failed: %s"),
+                     gai_strerror(i));
                goto done;
        }
 
        for (resP=res; resP!=NULL; resP=resP->ai_next) {
-               ns_status = checkAddress(session,
-                                        resP->ai_addr,
-                                        resP->ai_addrlen,
-                                        services,
-                                        interfaces,
-                                        interfaceOrder,
-                                        defaultRoute,
-                                        flags,
-                                        errorMessage);
-               if (ns_status > scn_status) {
+               SCNetworkConnectionFlags        ns_flags        = 0;
+
+               if (resP->ai_addr->sa_family == AF_INET) {
+                       struct sockaddr_in      *sin = (struct sockaddr_in *)resP->ai_addr;
+
+                       if (sin->sin_addr.s_addr == 0) {
+                               SCLog(_sc_debug, LOG_INFO, CFSTR("checkAddress(0.0.0.0)"));
+                               SCLog(_sc_debug, LOG_INFO, CFSTR("  status     = isReachable (this host)"));
+                               *flags |= kSCNetworkFlagsReachable;
+                               break;
+                       }
+               }
+
+               ok = checkAddress(store,
+                                 resP->ai_addr,
+                                 resP->ai_addrlen,
+                                 config,
+                                 active,
+                                 serviceOrder,
+                                 defaultRoute,
+                                 &ns_flags);
+               if (!ok) {
+                       /* not today */
+                       break;
+               }
+               if (rankReachability(ns_flags) > rankReachability(*flags)) {
                        /* return the best case result */
-                       scn_status = ns_status;
-                       if (ns_status == SCN_REACHABLE_YES) {
+                       *flags = ns_flags;
+                       if (rankReachability(*flags) == 2) {
                                /* we're in luck */
                                break;
                        }
@@ -1240,35 +1293,47 @@ SCNIsReachableByName(const char         *nodename,
         */
 
 #ifdef DEBUG
-       if (SCDOptionGet(session, kSCDOptionDebug))
-               SCDLog(LOG_INFO, CFSTR("getaddrinfo() returned no addresses, try gethostbyname()"));
+       SCLog(_sc_debug,
+             LOG_INFO,
+             CFSTR("getaddrinfo() returned no addresses, try gethostbyname()"));
 #endif /* DEBUG */
 
        h = gethostbyname(nodename);
        if (h && h->h_length) {
                struct in_addr **s      = (struct in_addr **)h->h_addr_list;
 
-               while (*s) {   
-                       struct sockaddr_in      sa;
+               while (*s) {
+                       SCNetworkConnectionFlags        ns_flags        = 0;
+                       struct sockaddr_in              sa;
 
                        bzero(&sa, sizeof(sa));
                        sa.sin_len    = sizeof(sa);
                        sa.sin_family = AF_INET;
                        sa.sin_addr   = **s;
 
-                       ns_status = checkAddress(session,
-                                                (struct sockaddr *)&sa,
-                                                sizeof(sa),
-                                                services,
-                                                interfaces,
-                                                interfaceOrder,
-                                                defaultRoute,
-                                                flags,
-                                                errorMessage);
-                       if (ns_status > scn_status) {
+                       if (sa.sin_addr.s_addr == 0) {
+                               SCLog(_sc_debug, LOG_INFO, CFSTR("checkAddress(0.0.0.0)"));
+                               SCLog(_sc_debug, LOG_INFO, CFSTR("  status     = isReachable (this host)"));
+                               *flags |= kSCNetworkFlagsReachable;
+                               break;
+                       }
+
+                       ok = checkAddress(store,
+                                         (struct sockaddr *)&sa,
+                                         sizeof(sa),
+                                         config,
+                                         active,
+                                         serviceOrder,
+                                         defaultRoute,
+                                         &ns_flags);
+                       if (!ok) {
+                               /* not today */
+                               break;
+                       }
+                       if (rankReachability(ns_flags) > rankReachability(*flags)) {
                                /* return the best case result */
-                               scn_status = ns_status;
-                               if (ns_status == SCN_REACHABLE_YES) {
+                               *flags = ns_flags;
+                               if (rankReachability(*flags) == 2) {
                                        /* we're in luck */
                                        break;
                                }
@@ -1276,13 +1341,69 @@ SCNIsReachableByName(const char         *nodename,
 
                        s++;
                }
+       } else {
+               char    *msg;
+
+               switch(h_errno) {
+                       case NETDB_INTERNAL :
+                               msg = strerror(errno);
+                               break;
+                       case HOST_NOT_FOUND :
+                               msg = "Host not found.";
+                               if (!haveDNS) {
+                                       /*
+                                        * No DNS servers are defined. Set flags based on
+                                        * the availability of configured (but not active)
+                                        * services.
+                                        */
+                                       struct sockaddr_in      sa;
+
+                                       bzero(&sa, sizeof(sa));
+                                       sa.sin_len         = sizeof(sa);
+                                       sa.sin_family      = AF_INET;
+                                       sa.sin_addr.s_addr = 0;
+                                       ok = checkAddress(store,
+                                                         (struct sockaddr *)&sa,
+                                                         sizeof(sa),
+                                                         config,
+                                                         active,
+                                                         serviceOrder,
+                                                         defaultRoute,
+                                                         flags);
+                                       if (ok &&
+                                           (*flags & kSCNetworkFlagsReachable) &&
+                                           (*flags & kSCNetworkFlagsConnectionRequired)) {
+                                               /*
+                                                * We might pick up a set of DNS servers
+                                                * from this connection, don't reply with
+                                                * "Host not found." just yet.
+                                                */
+                                               goto done;
+                                       }
+                                       *flags = 0;
+                               }
+                               break;
+                       case TRY_AGAIN :
+                               msg = "Try again.";
+                               break;
+                       case NO_RECOVERY :
+                               msg = "No recovery.";
+                               break;
+                       case NO_DATA :
+                               msg = "No data available.";
+                               break;
+                       default :
+                               msg = "Unknown";
+                               break;
+               }
+               SCLog(_sc_debug, LOG_INFO, CFSTR("gethostbyname() failed: %s"), msg);
        }
 
     done :
 
-       _IsReachableFree(services, interfaces, interfaceOrder, defaultRoute);
-       if (session)    (void)SCDClose(&session);
+       _CheckReachabilityFree(config, active, serviceOrder, defaultRoute);
+       if (store)      CFRelease(store);
        if (res)        freeaddrinfo(res);
 
-       return scn_status;
+       return ok;
 }
index 2f22ca11de84efa9c72a17e1c24b7e941e94677a..c48e3422dd3aef1c532aa34aa75b9c956418a389 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#ifndef _SCPNETWORK_H
-#define _SCPNETWORK_H
+#ifndef _SCNETWORK_H
+#define _SCNETWORK_H
 
 #include <sys/cdefs.h>
+#include <sys/types.h>
 #include <sys/socket.h>
+#include <CoreFoundation/CoreFoundation.h>
+
 
 /*!
-       @header SCPNetwork.h
-       The SystemConfiguration framework provides access to the data used
-               to configure a running system.
+       @header SCNetwork
+       The SCNetworkCheckReachabilityXXX() APIs allow an application to
+       determine the status of the system's current network configuration.
+
+       The term "reachable" reflects whether a data packet, sent by
+       an application into the network stack, will be able to reach
+       the destination host.
 
-       Specifically, the SCPNetworkXXX() API's allow an application
-               to determine the status of the systems current network
-               configuration.
+       Please note that being able to reach the destination host
+       does not guarantee that the data packet will reach the
+       host.
 
        The APIs provided by this framework communicate with the "configd"
-               daemon to obtain information regarding the systems current
-               configuration.
+       daemon to obtain information regarding the system's current
+       configuration.
  */
 
 /*!
-       @enum SCNStatus
-       @discussion Returned status codes from the SCNIsReachableByAddress()
-               and SCNIsReachableByName() functions.
-
-               The term "reachable" in these status codes reflects whether
-               a data packet, sent by an application into the network stack,
-               will be able to reach the destination host.
-
-               Please not that being "able" to reach the destination host
-               does not guarantee that the data packet "will" reach the
-               host.
-
-       @constant SCN_REACHABLE_UNKNOWN
-               A determination could not be made regarding the reachability
-               of the specified nodename/address.
-
-       @constant SCN_REACHABLE_NO
-               The specified nodename/address can not be reached using the
-               current network configuration.
-
-       @constant SCN_REACHABLE_CONNECTION_REQUIRED
-               The specified nodename/address can be reached using the
-               current network configuration but a connection must first
-               be established.
-
-               This status would be returned for a dialup connection which
-               was not currently active but could handle network traffic for
-               the target system.
-
-       @constant SCN_REACHABLE_YES
-               The specified nodename/address can be reached using the
-               current network configuration.
- */
-typedef enum {
-       SCN_REACHABLE_UNKNOWN                   = -1,
-       SCN_REACHABLE_NO                        =  0,
-       SCN_REACHABLE_CONNECTION_REQUIRED       =  1,
-       SCN_REACHABLE_YES                       =  2,
-} SCNStatus;
+       @enum SCNetworkConnectionFlags
+       @discussion Flags that indicate whether the specified network
+               nodename/address is reachable, requires a connection,
+               requires some user intervention in establishing the
+               connection, and whether the calling application must
+               initiate the connection using the (TBD???) API.
+
+       @constant kSCNetworkFlagsTransientConnection
+               This flag indicates that the specified nodename/address can
+               be reached via a transient (e.g. PPP) connection.
 
+       @constant kSCNetworkFlagsReachable
+               This flag indicates that the specified nodename/address can
+               be reached using the current network configuration.
 
-/*!
-       @enum SCNConnectionFlags
-       @discussion Additional flags which reflect whether a network connection
-               to the specified nodename/address is reachable, requires a
-               connection, requires some user intervention in establishing
-               the connection, and whether the calling application must initiate
-               the connection using the SCNEstablishConnection() API.
-
-       @constant kSCNFlagsTransientConnection
+       @constant kSCNetworkFlagsConnectionRequired
                This flag indicates that the specified nodename/address can
-               be reached via a transient (e.g. PPP) connection.
+               be reached using the current network configuration but a
+               connection must first be established.
+
+               As an example, this status would be returned for a dialup
+               connection that was not currently active but could handle
+               network traffic for the target system.
+
+       @constant kSCNetworkFlagsConnectionAutomatic
+               This flag indicates that the specified nodename/address can
+               be reached using the current network configuration but a
+               connection must first be established.  Any traffic directed
+               to the specified name/address will initiate the connection.
 
-       @constant kSCNFlagsConnectionAutomatic
-               The specified nodename/address can be reached using the
-               current network configuration but a connection must first
-               be established.  Any traffic directed to the specified
-               name/address will initiate the connection.
-
-       @constant kSCNFlagsInterventionRequired
-               The specified nodename/address can be reached using the
-               current network configuration but a connection must first
-               be established.  In addition, some form of user intervention
-               will be required to establish this connection (e.g. providing
-               a password, authentication token, etc.).
+       @constant kSCNetworkFlagsInterventionRequired
+               This flag indicates that the specified nodename/address can
+               be reached using the current network configuration but a
+               connection must first be established.  In addition, some
+               form of user intervention will be required to establish
+               this connection (e.g. providing a password, authentication
+               token, etc.).
  */
 typedef enum {
-       kSCNFlagsTransientConnection    =  1<<0,
-       kSCNFlagsConnectionAutomatic    =  1<<1,
-       kSCNFlagsInterventionRequired   =  1<<2,
-} SCNConnectionFlags;
+       kSCNetworkFlagsTransientConnection      =  1<<0,
+       kSCNetworkFlagsReachable                =  1<<1,
+       kSCNetworkFlagsConnectionRequired       =  1<<2,
+       kSCNetworkFlagsConnectionAutomatic      =  1<<3,
+       kSCNetworkFlagsInterventionRequired     =  1<<4,
+} SCNetworkConnectionFlags;
 
 
 __BEGIN_DECLS
 
 /*!
-       @function SCNIsReachableByAddress
+       @function SCNetworkCheckReachabilityByAddress
        @discussion Determines if the given network address is
                reachable using the current network configuration.
 
                Note: This API is not thread safe.
-       @param address Pass the network address of the desired host.
-       @param addrlen Pass the length, in bytes, of the address.
-       @param flags A pointer to memory which will be filled with a
-               set of SCNConnectionFlags related to the reachability
-               of the specified address.  If NULL, no flags will be
-               returned.
-       @param status A pointer to memory which will be filled with the
-               error status associated with any error communicating with
-               the system configuration daemon.
-       @result A constant of type SCNStatus indicating the reachability
-               of the specified node address.
+       @param address The network address of the desired host.
+       @param addrlen The length, in bytes, of the address.
+       @param flags A pointer to memory that will be filled with a
+               set of SCNetworkConnectionFlags detailing the reachability
+               of the specified address.
+       @result TRUE if the network connection flags are valid; FALSE if the
+               status could not be determined.
  */
-SCNStatus      SCNIsReachableByAddress (const struct sockaddr  *address,
-                                        const int              addrlen,
-                                        int                    *flags,
-                                        const char             **errorMessage);
+Boolean
+SCNetworkCheckReachabilityByAddress    (
+                                       const struct sockaddr           *address,
+                                       const int                       addrlen,
+                                       SCNetworkConnectionFlags        *flags
+                                       );
 
 /*!
-       @function SCNIsReachableByName
+       @function SCNetworkCheckReachabilityByName
        @discussion Determines if the given network host/node name is
                reachable using the current network configuration.
-       @param nodename Pass a node name of the desired host. This name would
+
+               Note: This API is not thread safe.
+
+       @param nodename The node name of the desired host. This name would
                be the same as that passed to gethostbyname() or getaddrinfo().
-       @param flags A pointer to memory which will be filled with a
-               set of SCNConnectionFlags related to the reachability
-               of the specified address.  If NULL, no flags will be
-               returned.
-       @param status A pointer to memory which will be filled with the
-               error status associated with any error communicating with
-               the system configuration daemon.
-       @result A constant of type SCNStatus indicating the reachability
-               of the specified node address.
+       @param flags A pointer to memory that will be filled with a
+               set of SCNetworkConnectionFlags detailing the reachability
+               of the specified node name.
+       @result TRUE if the network connection flags are valid; FALSE if the
+               status could not be determined.
  */
-SCNStatus      SCNIsReachableByName    (const char             *nodename,
-                                        int                    *flags,
-                                        const char             **errorMessage);
+Boolean
+SCNetworkCheckReachabilityByName       (
+                                       const char                      *nodename,
+                                       SCNetworkConnectionFlags        *flags
+                                       );
 
 __END_DECLS
 
-#endif /* _SCPNETWORK_H */
+#endif /* _SCNETWORK_H */
index 15d39f3d6140fc6e3fab14e2129333191a20e61a..9252a152ec8d6bf4eba33817e7480f09863571d6 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <SystemConfiguration/SystemConfiguration.h>
-#include "SCPPrivate.h"
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCPreferencesInternal.h"
 
 #include <fcntl.h>
 #include <pwd.h>
 #include <sys/errno.h>
 #include <sys/param.h>
 
-
-static const struct scp_errmsg {
-       SCPStatus       status;
-       char            *message;
-} scp_errmsgs[] = {
-       { SCP_OK,               "Success!" },
-       { SCP_BUSY,             "Configuration daemon busy" },
-       { SCP_NEEDLOCK,         "Lock required for this operation" },
-       { SCP_EACCESS,          "Permission denied (must be root to obtain lock)" },
-       { SCP_ENOENT,           "Configuration file not found" },
-       { SCP_BADCF,            "Configuration file corrupt" },
-       { SCP_NOKEY,            "No such key" },
-       { SCP_NOLINK,           "No such link" },
-       { SCP_EXISTS,           "Key already defined" },
-       { SCP_STALE,            "Write attempted on stale version of object" },
-       { SCP_INVALIDARGUMENT,  "Invalid argument" },
-       { SCP_FAILED,           "Failed!" }
-};
-#define nSCP_ERRMSGS (sizeof(scp_errmsgs)/sizeof(struct scp_errmsg))
-
-
 __private_extern__ CFDataRef
-_SCPSignatureFromStatbuf(const struct stat *statBuf)
+__SCPSignatureFromStatbuf(const struct stat *statBuf)
 {
        CFMutableDataRef        signature;
        SCPSignatureDataRef     sig;
@@ -68,7 +58,10 @@ _SCPSignatureFromStatbuf(const struct stat *statBuf)
 
 
 __private_extern__ char *
-_SCPPrefsPath(CFStringRef prefsID, boolean_t perUser, CFStringRef user)
+__SCPreferencesPath(CFAllocatorRef     allocator,
+                   CFStringRef         prefsID,
+                   Boolean             perUser,
+                   CFStringRef         user)
 {
        CFStringRef     path            = NULL;
        int             pathLen;
@@ -90,24 +83,33 @@ _SCPPrefsPath(CFStringRef prefsID, boolean_t perUser, CFStringRef user)
 
                        bzero(&login, sizeof(login));
                        if (user == NULL) {
+                               CFStringRef     u;
+
                                /* get current console user */
-                               if (SCDConsoleUserGet(login,
-                                                     MAXLOGNAME,
-                                                     NULL,
-                                                     NULL) != SCD_OK) {
+                               u = SCDynamicStoreCopyConsoleUser(NULL, NULL, NULL);
+                               if (!u) {
                                        /* if could not get console user */
                                        return NULL;
                                }
+                               (void) CFStringGetBytes(u,
+                                                       CFRangeMake(0, CFStringGetLength(u)),
+                                                       kCFStringEncodingMacRoman,
+                                                       0,
+                                                       FALSE,
+                                                       login,
+                                                       MAXLOGNAME,
+                                                       NULL);
+                               CFRelease(u);
                        } else {
                                /* use specified user */
-                               (void)CFStringGetBytes(user,
-                                                      CFRangeMake(0, CFStringGetLength(user)),
-                                                      kCFStringEncodingMacRoman,
-                                                      0,
-                                                      FALSE,
-                                                      login,
-                                                      MAXLOGNAME,
-                                                      NULL);
+                               (void) CFStringGetBytes(user,
+                                                       CFRangeMake(0, CFStringGetLength(user)),
+                                                       kCFStringEncodingMacRoman,
+                                                       0,
+                                                       FALSE,
+                                                       login,
+                                                       MAXLOGNAME,
+                                                       NULL);
                        }
 
                        /* get password entry for user */
@@ -118,7 +120,7 @@ _SCPPrefsPath(CFStringRef prefsID, boolean_t perUser, CFStringRef user)
                        }
 
                        /* create prefs ID */
-                       path = CFStringCreateWithFormat(NULL,
+                       path = CFStringCreateWithFormat(allocator,
                                                        NULL,
                                                        CFSTR("%s/%@/%@"),
                                                        pwd->pw_dir,
@@ -128,7 +130,7 @@ _SCPPrefsPath(CFStringRef prefsID, boolean_t perUser, CFStringRef user)
        } else {
                if (prefsID == NULL) {
                        /* default preference ID */
-                       path = CFStringCreateWithFormat(NULL,
+                       path = CFStringCreateWithFormat(allocator,
                                                        NULL,
                                                        CFSTR("%@/%@"),
                                                        PREFS_DEFAULT_DIR,
@@ -138,7 +140,7 @@ _SCPPrefsPath(CFStringRef prefsID, boolean_t perUser, CFStringRef user)
                        path = CFRetain(prefsID);
                } else {
                        /* relative path */
-                       path = CFStringCreateWithFormat(NULL,
+                       path = CFStringCreateWithFormat(allocator,
                                                        NULL,
                                                        CFSTR("%@/%@"),
                                                        PREFS_DEFAULT_DIR,
@@ -150,13 +152,13 @@ _SCPPrefsPath(CFStringRef prefsID, boolean_t perUser, CFStringRef user)
         * convert CFStringRef path to C-string path
         */
        pathLen = CFStringGetLength(path) + 1;
-       pathStr = CFAllocatorAllocate(NULL, pathLen, 0);
+       pathStr = CFAllocatorAllocate(allocator, pathLen, 0);
        if (!CFStringGetCString(path,
                                pathStr,
                                pathLen,
                                kCFStringEncodingMacRoman)) {
-               SCDLog(LOG_DEBUG, CFSTR("could not convert path to C string"));
-               CFAllocatorDeallocate(NULL, pathStr);
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("could not convert path to C string"));
+               CFAllocatorDeallocate(allocator, pathStr);
                pathStr = NULL;
        }
 
@@ -165,86 +167,75 @@ _SCPPrefsPath(CFStringRef prefsID, boolean_t perUser, CFStringRef user)
 }
 
 
-SCPStatus
-SCPGetSignature(SCPSessionRef session, CFDataRef *signature)
+CFDataRef
+SCPreferencesGetSignature(SCPreferencesRef session)
 {
-       SCPSessionPrivateRef    sessionPrivate;
+       SCPreferencesPrivateRef sessionPrivate  = (SCPreferencesPrivateRef)session;
 
-       if (session == NULL) {
-               return SCP_FAILED;           /* you can't do anything with a closed session */
-       }
-       sessionPrivate = (SCPSessionPrivateRef)session;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesGetSignature:"));
 
-       *signature = sessionPrivate->signature;
-       return SCP_OK;
+       sessionPrivate->accessed = TRUE;
+       return sessionPrivate->signature;
 }
 
 
 __private_extern__ CFStringRef
-_SCPNotificationKey(CFStringRef        prefsID,
-                   boolean_t   perUser,
-                   CFStringRef user,
-                   int         keyType)
+_SCPNotificationKey(CFAllocatorRef     allocator,
+                   CFStringRef         prefsID,
+                   Boolean             perUser,
+                   CFStringRef         user,
+                   int                 keyType)
 {
        CFStringRef     key             = NULL;
        char            *pathStr;
        char            *typeStr;
 
-       pathStr = _SCPPrefsPath(prefsID, perUser, user);
+       pathStr = __SCPreferencesPath(allocator, prefsID, perUser, user);
        if (pathStr == NULL) {
                return NULL;
        }
 
        /* create notification key */
        switch (keyType) {
-               case kSCPKeyLock :
+               case kSCPreferencesKeyLock :
                        typeStr = "lock";
                        break;
-               case kSCPKeyCommit :
+               case kSCPreferencesKeyCommit :
                        typeStr = "commit";
                        break;
-               case kSCPKeyApply :
+               case kSCPreferencesKeyApply :
                        typeStr = "apply";
                        break;
                default :
                        typeStr = "?";
        }
 
-       key = CFStringCreateWithFormat(NULL,
+       key = CFStringCreateWithFormat(allocator,
                                       NULL,
                                       CFSTR("%@%s:%s"),
-                                      kSCCacheDomainPrefs,
+                                      kSCDynamicStoreDomainPrefs,
                                       typeStr,
                                       pathStr);
 
-       CFAllocatorDeallocate(NULL, pathStr);
+       CFAllocatorDeallocate(allocator, pathStr);
        return key;
 }
 
 
 CFStringRef
-SCPNotificationKeyCreate(CFStringRef prefsID, int keyType)
+SCDynamicStoreKeyCreatePreferences(CFAllocatorRef      allocator,
+                                  CFStringRef          prefsID,
+                                  int                  keyType)
 {
-       return _SCPNotificationKey(prefsID, FALSE, NULL, keyType);
+       return _SCPNotificationKey(allocator, prefsID, FALSE, NULL, keyType);
 }
 
 
 CFStringRef
-SCPUserNotificationKeyCreate(CFStringRef prefsID, CFStringRef user, int keyType)
-{
-       return _SCPNotificationKey(prefsID, TRUE, user, keyType);
-}
-
-
-const char *
-SCPError(SCPStatus status)
+SCDynamicStoreKeyCreateUserPreferences(CFAllocatorRef  allocator,
+                                      CFStringRef      prefsID,
+                                      CFStringRef      user,
+                                      int              keyType)
 {
-       int i;
-
-       for (i = 0; i < nSCP_ERRMSGS; i++) {
-               if (scp_errmsgs[i].status == status) {
-                       return scp_errmsgs[i].message;
-               }
-       }
-       return "(unknown error)";
+       return _SCPNotificationKey(allocator, prefsID, TRUE, user, keyType);
 }
index 3c210c4dc107f30ea2aa77f597f7b44b71dda2a9..ab6957aa1eb8b369318962a674e1a6dd7978fe9c 100644 (file)
 #ifndef _SCP_H
 #define _SCP_H
 
-#include <CoreFoundation/CoreFoundation.h>
-#include <sys/cdefs.h>
-
-/*!
-       @header SCP.h
-       The SystemConfiguration framework provides access to the data used
-               to configure a running system.
-
-       Specifically, the SCPxxx() API's allow an application to load and
-               store XML configuration data in a controlled manner
-               and provides the necessary notifications to other
-               applications which need to be aware of configuration
-               changes.
-
-       The APIs provided by this framework communicate with the "configd"
-               daemon for any tasks requiring synchronization and/or
-               notification.
- */
-
-
-/*!
-       @enum SCPStatus
-       @discussion Returned status codes.
-       @constant SCP_OK                Success
-       @constant SCP_NOSESSION         Preference session not active
-       @constant SCP_BUSY              Configuration daemon busy
-       @constant SCD_NEEDLOCK          Lock required for this operation
-       @constant SCP_EACCESS           Permission denied (must be root to obtain lock)
-       @constant SCP_ENOENT            Configuration file not found
-       @constant SCP_BADCF             Configuration file corrupt
-       @constant SCD_NOKEY             No such key
-       @constant SCD_NOLINK            No such link
-       @constant SCP_EXISTS            Key already defined
-       @constant SCP_STALE             Write attempted on stale version of object
-       @constant SCP_INVALIDARGUMENT   Invalid argument
-       @constant SCP_FAILED            Generic error
- */
-typedef enum {
-       SCP_OK                  = 0,    /* Success */
-       SCP_NOSESSION           = 1024, /* Preference session not active */
-       SCP_BUSY                = 1025, /* Preferences update currently in progress */
-       SCP_NEEDLOCK            = 1026, /* Lock required for this operation */
-       SCP_EACCESS             = 1027, /* Permission denied */
-       SCP_ENOENT              = 1028, /* Configuration file not found */
-       SCP_BADCF               = 1029, /* Configuration file corrupt */
-       SCP_NOKEY               = 1030, /* No such key */
-       SCP_NOLINK              = 1031, /* No such link */
-       SCP_EXISTS              = 1032, /* No such key */
-       SCP_STALE               = 1033, /* Write attempted on stale version of object */
-       SCP_INVALIDARGUMENT     = 1034, /* Invalid argument */
-       SCP_FAILED              = 9999  /* Generic error */
-} SCPStatus;
-
-
-/*!
-       @enum SCPOption
-       @discussion Used with the SCP[User]Open() and SCP[User]NotificationKeyCreate()
-               to describe the prefsID CFStringRef argument.
-       @constant kSCPOptionCreatePrefs Specifies that the preferences file should
-               be created if it does not exist.
- */
-typedef enum {
-       kSCPOpenCreatePrefs     = 1,    /* create preferences file if not found */
-} SCPOption;
-
-
-/*!
-       @enum SCPKeyType
-       @discussion Used with the SCDList() and SCDNotifierAdd() functions to describe
-               the CFStringRef argument.
-       @constant kSCDKeyLock   key used when exclusive access to the stored preferences
-               is obtained or released.
-       @constant kSCDKeyCommit key used when new preferences are committed to the store
-       @constant kSCDKeyApply  key used when new preferences are to be applied to the
-               active system configuration.
- */
-typedef enum {
-       kSCPKeyLock     = 1,
-       kSCPKeyCommit   = 2,
-       kSCPKeyApply    = 3,
-} SCPKeyType;
-
-
-/*!
-       @typedef SCPSessionRef
-       @discussion This is the type of a handle to an open "session" for
-               accessing system configuration preferences.
- */
-typedef void *         SCPSessionRef;
-
-
-__BEGIN_DECLS
-
-/*!
-       @function SCPOpen
-       @discussion Initiates access to the per-system set of configuration
-               preferences.
-
-       This function will ensure that the current state of the prefsID is
-       retrieved (by reading the whole thing into memory, or at least,
-       open()'ing the file and keeping it open)
-       @param session A pointer to memory which will be filled with an
-               SCPSessionRef handle to be used for all subsequent requests.
-               If a session cannot be established, the contents of
-               memory pointed to by this parameter are undefined.
-       @param name Pass a string which describes the name of the calling
-               process.
-       @param prefsID Pass a string which identifies the name of the
-               group of preferences to be accessed/updated. A NULL value
-               specifies the default system configuration preferences.
-       @param options Pass a bitfield of type SCPOpenOption containing
-               one or more flags describing how the preferences should
-               be accessed.
-
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call.
- */
-SCPStatus      SCPOpen                         (SCPSessionRef          *session,
-                                                CFStringRef            name,
-                                                CFStringRef            prefsID,
-                                                int                    options);
-
-/*!
-       @function SCPUserOpen
-       @discussion Initiates access to the per-user set of configuration
-               preferences.
-
-       This function will ensure that the current state of the prefsID is
-       retrieved (by reading the whole thing into memory, or at least,
-       open()'ing the file and keeping it open)
-       @param session A pointer to memory which will be filled with an
-               SCPSessionRef handle to be used for all subsequent requests.
-               If a session cannot be established, the contents of
-               memory pointed to by this parameter are undefined.
-       @param name Pass a string which describes the name of the calling
-               process.
-       @param prefsID Pass a string which identifies the name of the
-               group of preferences to be accessed/updated.
-       @param user Pass a string which identifies the user/login who's
-               preferences should be accessed.  A NULL value specifies
-               the current console user.
-       @param options Pass a bitfield of type SCPOpenOption containing
-               one or more flags describing how the preferences should
-               be accessed.
-
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call.
- */
-SCPStatus      SCPUserOpen                     (SCPSessionRef          *session,
-                                                CFStringRef            name,
-                                                CFStringRef            prefsID,
-                                                CFStringRef            user,
-                                                int                    options);
-
-/*!
-       @function SCPClose
-       @discussion Terminates access to a set of configuration preferences.
-
-       This function frees/closes all allocated/opened resources. Any
-       uncommitted changes are NOT written.
-       @param session Pass a pointer to the SCPSessionRef handle which should
-               be closed.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call.
- */
-SCPStatus      SCPClose                        (SCPSessionRef          *session);
-
-/*!
-       @function SCPLock
-       @discussion Locks access to the configuration preferences.
-
-       This function obtains exclusive access to the configuration
-       preferences associated with this prefsID. Clients attempting
-       to obtain exclusive access the preferences will either receive
-       an SCP_BUSY error or block waiting for the lock to be released.
-       @param session Pass an SCPSessionRef handle which should be used for
-               all API calls.
-       @param wait Pass a boolean flag indicating whether the calling process
-               should block waiting for another process to complete its update
-               operation and release its lock.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK,
-               SCP_BUSY, SCP_EACCESS, SCP_STALE.
- */
-SCPStatus      SCPLock                         (SCPSessionRef          session,
-                                                boolean_t              wait);
-
-/*!
-       @function SCPCommit
-       @discussion Commits changes made to the configuration preferences to
-               persitent storage.
-
-       This function commits the any changes to permanent storage. An
-       implicit call to SCPLock/SCPUnlock will be made if exclusive
-       access had not been established.
-       @param session Pass an SCPSessionRef handle which should be used for
-               all API calls.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK,
-               SCP_BUSY, SCP_EACCESS, SCP_STALE.
- */
-SCPStatus      SCPCommit                       (SCPSessionRef          session);
-
-/*!
-       @function SCPApply
-       @discussion Requests that the currently stored configuration
-               preferences be applied to the active configuration.
-       @param session Pass an SCPSessionRef handle which should be used for
-               all API calls.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK,
-               SCP_EACCESS.
- */
-SCPStatus      SCPApply                        (SCPSessionRef          session);
-
-/*!
-       @function SCPUnlock
-       @discussion Releases exclusive access to the configuration preferences.
-
-       This function releases the exclusive access "lock" fr this prefsID.
-       Other clients will be now be able to establish exclusive access to
-       the preferences.
-       @param session Pass an SCPSessionRef handle which should be used for
-               all API calls.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call.
- */
-SCPStatus      SCPUnlock                       (SCPSessionRef          session);
-
-/*!
-       @function SCPGetSignature
-       @discussion Returns an sequence of bytes which can be used to determine
-               if the saved configuration preferences have changed.
-       @param session Pass an SCPSessionRef handle which should be used for
-               all API calls.
-       @param signature Pass a pointer to a CFDataRef which will be reflect
-               the signature of the configuration preferences at the time
-               of the call to SCPOpen().
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call.
- */
-SCPStatus      SCPGetSignature                 (SCPSessionRef          session,
-                                                CFDataRef              *signature);
-
-/*!
-       @function SCPList
-       @discussion Returns an array of currently defined preference keys.
-       @param session Pass an SCPSessionRef handle which should be used for
-               all API calls.
-       @param keys Pass a pointer to a CFArrayRef which will be set to a new
-               array of currently defined preference keys.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call.
- */
-SCPStatus      SCPList                         (SCPSessionRef          session,
-                                                CFArrayRef             *keys);
-
-/*!
-       @function SCPGet
-       @discussion Returns the data associated with a preference key.
-
-       This function retrieves data associated with a key for the prefsID.
-       You "could" read stale data and not know it, unless you first call
-       SCPLock().
-       @param session Pass an SCPSessionRef handle which should be used for
-               all API calls.
-       @param key Pass a reference to the preference key to be returned.
-       @param data Pass a pointer to a CFPropertyListRef which will be set to a
-               new object containing the data associated with the
-               configuration preference.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK,
-               SCP_NOKEY.
- */
-SCPStatus      SCPGet                          (SCPSessionRef          session,
-                                                CFStringRef            key,
-                                                CFPropertyListRef      *data);
-
-/*!
-       @function SCPAdd
-       @discussion Adds data for a preference key.
-
-       This function associates new data with the specified key. In order
-       to commit these changes to permanent storage a call must be made to
-       SCDPCommit().
-       @param session Pass the SCPSessionRef handle which should be used to
-               communicate with the APIs.
-       @param key Pass a reference to the preference key to be updated.
-       @param data Pass a reference to the CFPropertyListRef object containing the
-               data to be associated with the configuration preference.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK,
-               SCP_EXISTS.
- */
-SCPStatus      SCPAdd                          (SCPSessionRef          session,
-                                                CFStringRef            key,
-                                                CFPropertyListRef      data);
-
-/*!
-       @function SCPSet
-       @discussion Updates the data associated with a preference key.
-
-       This function creates (or updates) the data associated with the
-       specified key. In order to commit these changes to permanent
-       storage a call must be made to SCDPCommit().
-       @param session Pass the SCPSessionRef handle which should be used to
-               communicate with the APIs.
-       @param key Pass a reference to the preference key to be updated.
-       @param data Pass a reference to the CFPropertyListRef object containing the
-               data to be associated with the configuration preference.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK.
- */
-SCPStatus      SCPSet                          (SCPSessionRef          session,
-                                                CFStringRef            key,
-                                                CFPropertyListRef      data);
-
-/*!
-       @function SCPRemove
-       @discussion Removes the data associated with a preference key.
-
-       This function removes the data associated with the specified
-       key. In order to commit these changes to permanent storage a
-       call must be made to SCDPCommit().
-       @param session Pass the SCPSessionRef handle which should be used to
-               communicate with the APIs.
-       @param key Pass a reference to the preference key to be removed.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK,
-               SCP_NOKEY.
- */
-SCPStatus      SCPRemove                       (SCPSessionRef          session,
-                                                CFStringRef            key);
-
-/*!
-       @function SCPNotificationKeyCreate
-       @discussion Creates a key which can be used by the SCDNotifierAdd()
-               function to receive notifications of changes to the saved
-               preferences.
-       @param prefsID Pass a string which identifies the name of the
-               preferences to be accessed/updated. A NULL value specifies
-               the default system configuration preferences.
-       @param keyType Pass a kSCPKeyType indicating the type a notification
-               key to be returned.
-       @result A notification string for the specified preference identifier.
- */
-CFStringRef    SCPNotificationKeyCreate        (CFStringRef            prefsID,
-                                                int                    keyType);
-
-/*!
-       @function SCPUserNotificationKeyCreate
-       @discussion Creates a key which can be used by the SCDNotifierAdd()
-               function to receive notifications of changes to the saved
-               preferences.
-       @param prefsID Pass a string which identifies the name of the
-               preferences to be accessed/updated. A NULL value specifies
-               the default system configuration preferences.
-       @param user Pass a string which identifies the user/login who's
-               preferences should be accessed.  A NULL value specifies
-               the current console user.
-       @param keyType Pass a kSCPKeyType indicating the type a notification
-               key to be returned.
-       @result A notification string for the specified preference identifier.
- */
-CFStringRef    SCPUserNotificationKeyCreate    (CFStringRef            prefsID,
-                                                CFStringRef            user,
-                                                int                    keyType);
-
-/*!
-       @function SCPError
-       @discussion
-       @param status
-       @result
- */
-const char *   SCPError                        (SCPStatus              status);
-
-__END_DECLS
+#ifndef _SYSTEMCONFIGURATION_H
+#warning Your code has directly included the (old) <SystemConfiguration/SCP.h>
+#warning header file.  Please dont do that.  Use the top-level header file:
+#warning
+#warning   <SystemConfiguration/SystemConfiguration.h>
+#warning
+#warning Note: the configuration preference APIs have been moved out of
+#warning       the SCP.h header file.
+#include <SystemConfiguration/SystemConfiguration.h>    /* ...and try to keep everyone happy */
+#endif
 
 #endif /* _SCP_H */
index eaba463e2882821e3223409988b53a6cdae1f80e..70bc7a7084d344f6e9e5bcaffca96f64716820fa 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SCP.h>
-#include "SCPPrivate.h"
-
-#include <SystemConfiguration/SCD.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/errno.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCPreferencesInternal.h"
 
-SCPStatus
-SCPAdd(SCPSessionRef session, CFStringRef key, CFPropertyListRef data)
+Boolean
+SCPreferencesAddValue(SCPreferencesRef session, CFStringRef key, CFPropertyListRef value)
 {
-       SCPSessionPrivateRef    sessionPrivate;
+       SCPreferencesPrivateRef sessionPrivate  = (SCPreferencesPrivateRef)session;
 
-       if (session == NULL) {
-               return SCP_FAILED;           /* you can't do anything with a closed session */
-       }
-       sessionPrivate = (SCPSessionPrivateRef)session;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesAddValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key   = %@"), key);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  value = %@"), value);
+
+       sessionPrivate->accessed = TRUE;
 
        if (CFDictionaryContainsKey(sessionPrivate->prefs, key)) {
-               return SCP_EXISTS;
+               _SCErrorSet(kSCStatusKeyExists);
+               return FALSE;
        }
 
-       CFDictionaryAddValue(sessionPrivate->prefs, key, data);
-       sessionPrivate->changed = TRUE;
-       return SCP_OK;
+       CFDictionaryAddValue(sessionPrivate->prefs, key, value);
+       sessionPrivate->changed  = TRUE;
+       return TRUE;
 }
index 8c42762cda560161c44d1ecfaaacee4571b0137b..c0b9695077e3860c5f0a5ac605b06a16b9dacdec 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SCP.h>
-#include "SCPPrivate.h"
-
-#include <SystemConfiguration/SCD.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/errno.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCPreferencesInternal.h"
 
-SCPStatus
-SCPApply(SCPSessionRef session)
+Boolean
+SCPreferencesApplyChanges(SCPreferencesRef session)
 {
-       SCPSessionPrivateRef    sessionPrivate;
-       SCPStatus               scp_status = SCP_OK;
-       SCDStatus               scd_status;
-       boolean_t               wasLocked;
+       SCPreferencesPrivateRef sessionPrivate  = (SCPreferencesPrivateRef)session;
+       Boolean                 wasLocked;
 
-       if (session == NULL) {
-               return SCP_FAILED;           /* you can't do anything with a closed session */
-       }
-       sessionPrivate = (SCPSessionPrivateRef)session;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesApplyChanges:"));
 
        /*
         * Determine if the we have exclusive access to the preferences
@@ -49,41 +48,41 @@ SCPApply(SCPSessionRef session)
         */
        wasLocked = sessionPrivate->locked;
        if (!wasLocked) {
-               scp_status = SCPLock(session, TRUE);
-               if (scp_status != SCD_OK) {
-                       SCDLog(LOG_DEBUG, CFSTR("  SCPLock(): %s"), SCPError(scp_status));
-                       return scp_status;
+               if (!SCPreferencesLock(session, TRUE)) {
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  SCPreferencesLock() failed"));
+                       return FALSE;
                }
        }
 
        if (!sessionPrivate->isRoot) {
                /* CONFIGD REALLY NEEDS NON-ROOT WRITE ACCESS */
-               goto notRoot;
+               goto perUser;
        }
 
        /* if necessary, create the session "apply" key */
        if (sessionPrivate->sessionKeyApply == NULL) {
-               sessionPrivate->sessionKeyApply = _SCPNotificationKey(sessionPrivate->prefsID,
+               sessionPrivate->sessionKeyApply = _SCPNotificationKey(NULL,
+                                                                     sessionPrivate->prefsID,
                                                                      sessionPrivate->perUser,
                                                                      sessionPrivate->user,
-                                                                     kSCPKeyApply);
+                                                                     kSCPreferencesKeyApply);
        }
 
        /* post notification */
-       scd_status = SCDLock(sessionPrivate->session);
-       if (scd_status == SCD_OK) {
-               (void) SCDTouch (sessionPrivate->session, sessionPrivate->sessionKeyApply);
-               (void) SCDRemove(sessionPrivate->session, sessionPrivate->sessionKeyApply);
-               (void) SCDUnlock(sessionPrivate->session);
-       } else {
-               SCDLog(LOG_DEBUG, CFSTR("  SCDLock(): %s"), SCDError(scd_status));
-               scp_status = SCP_FAILED;
+       if (!SCDynamicStoreNotifyValue(sessionPrivate->session,
+                                      sessionPrivate->sessionKeyApply)) {
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  SCDynamicStoreNotifyValue() failed"));
+               _SCErrorSet(kSCStatusFailed);
+               goto error;
        }
 
-    notRoot:
+    perUser :
+
+       if (!wasLocked) (void) SCPreferencesUnlock(session);
+       return TRUE;
 
-       if (!wasLocked)
-               (void) SCPUnlock(session);
+    error :
 
-       return scp_status;
+       if (!wasLocked) (void) SCPreferencesUnlock(session);
+       return FALSE;
 }
diff --git a/SystemConfiguration.fproj/SCPClose.c b/SystemConfiguration.fproj/SCPClose.c
deleted file mode 100644 (file)
index 8ad50cf..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright(c) 2000 Apple Computer, 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 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.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <SystemConfiguration/SCP.h>
-#include "SCPPrivate.h"
-
-#include <SystemConfiguration/SCD.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/errno.h>
-
-
-SCPStatus
-SCPClose(SCPSessionRef *session)
-{
-       SCPSessionPrivateRef    sessionPrivate;
-
-       if ((session == NULL) || (*session == NULL)) {
-               return SCP_FAILED;           /* you can't do anything with a closed session */
-       }
-       sessionPrivate = (SCPSessionPrivateRef)*session;
-
-       /* release resources */
-       if (sessionPrivate->name)               CFRelease(sessionPrivate->name);
-       if (sessionPrivate->prefsID)            CFRelease(sessionPrivate->prefsID);
-       if (sessionPrivate->user)               CFRelease(sessionPrivate->user);
-       if (sessionPrivate->path)               CFAllocatorDeallocate(NULL, sessionPrivate->path);
-       if (sessionPrivate->signature)          CFRelease(sessionPrivate->signature);
-       if (sessionPrivate->session) {
-               SCDStatus       scd_status;
-
-               scd_status = SCDClose(&sessionPrivate->session);
-               if (scd_status != SCD_OK) {
-                       SCDLog(LOG_INFO, CFSTR("SCDClose() failed: %s"), SCDError(scd_status));
-               }
-       }
-       if (sessionPrivate->sessionKeyLock)     CFRelease(sessionPrivate->sessionKeyLock);
-       if (sessionPrivate->sessionKeyCommit)   CFRelease(sessionPrivate->sessionKeyCommit);
-       if (sessionPrivate->sessionKeyApply)    CFRelease(sessionPrivate->sessionKeyApply);
-       if (sessionPrivate->prefs)              CFRelease(sessionPrivate->prefs);
-
-       /* release session */
-       CFAllocatorDeallocate(NULL, sessionPrivate);
-       *session = NULL;
-       return SCP_OK;
-}
index 7ea5a5e8bda8b1c7e4b32c403af9892da48efa26..fe6f435e15a2bb90de306aaf20e1f794ad5aee5d 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SCP.h>
-#include "SCPPrivate.h"
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCPreferencesInternal.h"
 
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/errno.h>
 
-
-SCPStatus
-SCPCommit(SCPSessionRef session)
+Boolean
+SCPreferencesCommitChanges(SCPreferencesRef session)
 {
-       SCPSessionPrivateRef    sessionPrivate;
-       SCPStatus               scp_status = SCP_OK;
-       SCDStatus               scd_status;
-       boolean_t               wasLocked;
+       SCPreferencesPrivateRef sessionPrivate  = (SCPreferencesPrivateRef)session;
+       Boolean                 wasLocked;
 
-       if (session == NULL) {
-               return SCP_FAILED;           /* you can't do anything with a closed session */
-       }
-       sessionPrivate = (SCPSessionPrivateRef)session;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesCommitChanges:"));
 
        /*
         * Determine if the we have exclusive access to the preferences
@@ -49,10 +52,9 @@ SCPCommit(SCPSessionRef session)
         */
        wasLocked = sessionPrivate->locked;
        if (!wasLocked) {
-               scp_status = SCPLock(session, TRUE);
-               if (scp_status != SCD_OK) {
-                       SCDLog(LOG_DEBUG, CFSTR("  SCPLock(): %s"), SCPError(scp_status));
-                       return scp_status;
+               if (!SCPreferencesLock(session, TRUE)) {
+                       SCLog(_sc_verbose, LOG_ERR, CFSTR("  SCPreferencesLock() failed"));
+                       return FALSE;
                }
        }
 
@@ -73,9 +75,8 @@ SCPCommit(SCPSessionRef session)
                                statBuf.st_uid  = geteuid();
                                statBuf.st_gid  = getegid();
                        } else {
-                               SCDLog(LOG_DEBUG, CFSTR("stat() failed: %s"), strerror(errno));
-                               scp_status = SCP_FAILED;
-                               goto done;
+                               SCLog(_sc_verbose, LOG_ERR, CFSTR("stat() failed: %s"), strerror(errno));
+                               goto error;
                        }
                }
 
@@ -104,70 +105,76 @@ SCPCommit(SCPSessionRef session)
                                        }
                                }
                        }
-                       SCDLog(LOG_DEBUG, CFSTR("SCPCommit open() failed: %s"), strerror(errno));
+                       SCLog(_sc_verbose, LOG_ERR, CFSTR("SCPCommit open() failed: %s"), strerror(errno));
                        CFAllocatorDeallocate(NULL, newPath);
-                       scp_status = SCP_FAILED;
-                       goto done;
+                       goto error;
                }
 
                /* preserve permissions */
-               (void)fchown(fd, statBuf.st_uid, statBuf.st_gid);
+               (void) fchown(fd, statBuf.st_uid, statBuf.st_gid);
 
                /* write the new preferences */
                newPrefs = CFPropertyListCreateXMLData(NULL, sessionPrivate->prefs);
+               if (!newPrefs) {
+                       _SCErrorSet(kSCStatusFailed);
+                       SCLog(_sc_verbose, LOG_ERR, CFSTR("  CFPropertyListCreateXMLData() failed"));
+                       CFAllocatorDeallocate(NULL, newPath);
+                       (void) close(fd);
+                       goto error;
+               }
                (void) write(fd, CFDataGetBytePtr(newPrefs), CFDataGetLength(newPrefs));
                (void) close(fd);
                CFRelease(newPrefs);
 
                /* rename new->old */
                if (rename(newPath, sessionPrivate->path) == -1) {
-                       SCDLog(LOG_DEBUG, CFSTR("rename() failed: %s"), strerror(errno));
+                       _SCErrorSet(errno);
+                       SCLog(_sc_verbose, LOG_ERR, CFSTR("rename() failed: %s"), strerror(errno));
                        CFAllocatorDeallocate(NULL, newPath);
-                       scp_status = SCP_FAILED;
-                       goto done;
+                       goto error;
                }
                CFAllocatorDeallocate(NULL, newPath);
 
                /* update signature */
                if (stat(sessionPrivate->path, &statBuf) == -1) {
-                       SCDLog(LOG_DEBUG, CFSTR("stat() failed: %s"), strerror(errno));
-                       scp_status = SCP_FAILED;
-                       goto done;
+                       _SCErrorSet(errno);
+                       SCLog(_sc_verbose, LOG_ERR, CFSTR("stat() failed: %s"), strerror(errno));
+                       goto error;
                }
                CFRelease(sessionPrivate->signature);
-               sessionPrivate->signature = _SCPSignatureFromStatbuf(&statBuf);
+               sessionPrivate->signature = __SCPSignatureFromStatbuf(&statBuf);
        }
 
        if (!sessionPrivate->isRoot) {
                /* CONFIGD REALLY NEEDS NON-ROOT WRITE ACCESS */
-               goto done;
+               goto perUser;
        }
 
        /* if necessary, create the session "commit" key */
        if (sessionPrivate->sessionKeyCommit == NULL) {
-               sessionPrivate->sessionKeyCommit = _SCPNotificationKey(sessionPrivate->prefsID,
+               sessionPrivate->sessionKeyCommit = _SCPNotificationKey(NULL,
+                                                                      sessionPrivate->prefsID,
                                                                       sessionPrivate->perUser,
                                                                       sessionPrivate->user,
-                                                                      kSCPKeyCommit);
+                                                                      kSCPreferencesKeyCommit);
        }
 
        /* post notification */
-       scd_status = SCDLock(sessionPrivate->session);
-       if (scd_status == SCD_OK) {
-               (void) SCDTouch (sessionPrivate->session, sessionPrivate->sessionKeyCommit);
-               (void) SCDRemove(sessionPrivate->session, sessionPrivate->sessionKeyCommit);
-               (void) SCDUnlock(sessionPrivate->session);
-       } else {
-               SCDLog(LOG_DEBUG, CFSTR("  SCDLock(): %s"), SCDError(scd_status));
-               scp_status = SCP_FAILED;
+       if (!SCDynamicStoreNotifyValue(sessionPrivate->session,
+                                      sessionPrivate->sessionKeyCommit)) {
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("  SCDynamicStoreNotifyValue() failed"));
+               _SCErrorSet(kSCStatusFailed);
+               goto error;
        }
 
-    done :
-
-       if (!wasLocked)
-               (void) SCPUnlock(session);
+    perUser :
 
+       if (!wasLocked) (void) SCPreferencesUnlock(session);
        sessionPrivate->changed = FALSE;
+       return TRUE;
+
+    error :
 
-       return scp_status;
+       if (!wasLocked) (void) SCPreferencesUnlock(session);
+       return FALSE;
 }
index bd0a50a2a3998d451cfaf193c2d5e3416b321268..50f7cd4f71f56184253d26196f5be06de8a5bd2c 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SCP.h>
-#include "SCPPrivate.h"
-
-#include <SystemConfiguration/SCD.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/errno.h>
 
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCPreferencesInternal.h"
 
-SCPStatus
-SCPGet(SCPSessionRef session, CFStringRef key, CFPropertyListRef *data)
+CFPropertyListRef
+SCPreferencesGetValue(SCPreferencesRef session, CFStringRef key)
 {
-       SCPSessionPrivateRef    sessionPrivate;
-       CFPropertyListRef       val;
+       SCPreferencesPrivateRef sessionPrivate  = (SCPreferencesPrivateRef)session;
+       CFPropertyListRef       value;
 
-       if (session == NULL) {
-               return SCP_FAILED;           /* you can't do anything with a closed session */
-       }
-       sessionPrivate = (SCPSessionPrivateRef)session;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesGetValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key   = %@"), key);
 
-       val = CFDictionaryGetValue(sessionPrivate->prefs, key);
-       if (val == NULL) {
-               return SCP_NOKEY;
+       sessionPrivate->accessed = TRUE;
+       value = CFDictionaryGetValue(sessionPrivate->prefs, key);
+       if (!value) {
+               _SCErrorSet(kSCStatusNoKey);
        }
 
-       *data = val;
-       return SCP_OK;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  value = %@"), value);
+       return value;
 }
index 3fb1a899ca8e0605b068fac3230d0c1e8f8e47c2..d66ed6ea6af0cb60ee48a6844768702a92764292 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SCP.h>
-#include "SCPPrivate.h"
-
-#include <SystemConfiguration/SCD.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/errno.h>
-
-
-static CFComparisonResult
-sort_keys(const void *p1, const void *p2, void *context) {
-       CFStringRef key1 = (CFStringRef)p1;
-       CFStringRef key2 = (CFStringRef)p2;
-       return CFStringCompare(key1, key2, 0);
-}
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCPreferencesInternal.h"
 
-SCPStatus
-SCPList(SCPSessionRef session, CFArrayRef *keys)
+CFArrayRef
+SCPreferencesCopyKeyList(SCPreferencesRef session)
 {
-       SCPSessionPrivateRef    sessionPrivate;
+       CFAllocatorRef          allocator       = CFGetAllocator(session);
+       CFArrayRef              keys;
+       SCPreferencesPrivateRef sessionPrivate  = (SCPreferencesPrivateRef)session;
        CFIndex                 prefsCnt;
        void                    **prefsKeys;
-       CFArrayRef              allKeys;
-       CFMutableArrayRef       sortedKeys;
 
-       if (session == NULL) {
-               return SCP_FAILED;           /* you can't do anything with a closed session */
-       }
-       sessionPrivate = (SCPSessionPrivateRef)session;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesCopyKeyList:"));
 
        prefsCnt  = CFDictionaryGetCount(sessionPrivate->prefs);
-       prefsKeys = CFAllocatorAllocate(NULL, prefsCnt * sizeof(CFStringRef), 0);
+       prefsKeys = CFAllocatorAllocate(allocator, prefsCnt * sizeof(CFStringRef), 0);
        CFDictionaryGetKeysAndValues(sessionPrivate->prefs, prefsKeys, NULL);
-       allKeys = CFArrayCreate(NULL, prefsKeys, prefsCnt, &kCFTypeArrayCallBacks);
-       CFAllocatorDeallocate(NULL, prefsKeys);
+       keys = CFArrayCreate(allocator, prefsKeys, prefsCnt, &kCFTypeArrayCallBacks);
+       CFAllocatorDeallocate(allocator, prefsKeys);
 
-       sortedKeys = CFArrayCreateMutableCopy(NULL, prefsCnt, allKeys);
-       CFRelease(allKeys);
-       CFArraySortValues(sortedKeys,
-                         CFRangeMake(0, prefsCnt),
-                         sort_keys,
-                         NULL);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  keys = %@"), keys);
 
-       *keys = sortedKeys;
-       return SCP_OK;
+       sessionPrivate->accessed = TRUE;
+       return keys;
 }
index 760de8d3fe057345b732a9128b7f6e0401c6aa64..a153f338b7dac0b0bdf65769c22ff61897dfa940 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SCP.h>
-#include "SCPPrivate.h"
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCPreferencesInternal.h"
 
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/errno.h>
 
-
-SCPStatus
-SCPLock(SCPSessionRef session, boolean_t wait)
+Boolean
+SCPreferencesLock(SCPreferencesRef session, Boolean wait)
 {
-       SCPStatus               scp_status;
-       SCDStatus               scd_status;
-       SCPSessionPrivateRef    sessionPrivate;
-       SCDHandleRef            handle = NULL;
-       CFDateRef               value;
        CFArrayRef              changes;
+       CFDataRef               currentSignature        = NULL;
+       Boolean                 haveLock                = FALSE;
+       SCPreferencesPrivateRef sessionPrivate          = (SCPreferencesPrivateRef)session;
        struct stat             statBuf;
-       CFDataRef               currentSignature;
+       CFDateRef               value                   = NULL;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesLock:"));
 
-       if (session == NULL) {
-               return SCP_FAILED;           /* you can't do anything with a closed session */
+       if (sessionPrivate->locked) {
+               /* sorry, you already have the lock */
+               _SCErrorSet(kSCStatusLocked);
+               return FALSE;
        }
-       sessionPrivate = (SCPSessionPrivateRef)session;
 
        if (!sessionPrivate->isRoot) {
-               /* CONFIGD REALLY NEEDS NON-ROOT WRITE ACCESS */
-               goto notRoot;
+               if (!sessionPrivate->perUser) {
+                       _SCErrorSet(kSCStatusAccessError);
+                       return FALSE;
+               } else {
+                       /* CONFIGD REALLY NEEDS NON-ROOT WRITE ACCESS */
+                       goto perUser;
+               }
        }
 
        if (sessionPrivate->session == NULL) {
                /* open a session */
-               scd_status = SCDOpen(&sessionPrivate->session, sessionPrivate->name);
-               if (scd_status != SCD_OK) {
-                       SCDLog(LOG_INFO, CFSTR("SCDOpen() failed: %s"), SCDError(scd_status));
-                       return SCP_FAILED;
+               sessionPrivate->session = SCDynamicStoreCreate(NULL,
+                                                              CFSTR("SCPreferencesLock"),
+                                                              NULL,
+                                                              NULL);
+               if (!sessionPrivate->session) {
+                       SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+                       return FALSE;
                }
        }
 
        if (sessionPrivate->sessionKeyLock == NULL) {
                /* create the session "lock" key */
-               sessionPrivate->sessionKeyLock = _SCPNotificationKey(sessionPrivate->prefsID,
+               sessionPrivate->sessionKeyLock = _SCPNotificationKey(NULL,
+                                                                    sessionPrivate->prefsID,
                                                                     sessionPrivate->perUser,
                                                                     sessionPrivate->user,
-                                                                    kSCPKeyLock);
+                                                                    kSCPreferencesKeyLock);
        }
 
-       scd_status = SCDNotifierAdd(sessionPrivate->session,
-                                   sessionPrivate->sessionKeyLock,
-                                   0);
-       if (scd_status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDNotifierAdd() failed: %s"), SCDError(scd_status));
-               scp_status = SCP_FAILED;
+       if (!SCDynamicStoreAddWatchedKey(sessionPrivate->session,
+                                        sessionPrivate->sessionKeyLock,
+                                        FALSE)) {
+               SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreAddWatchedKey() failed"));
                goto error;
        }
 
-       handle = SCDHandleInit();
        value  = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
-       SCDHandleSetData(handle, value);
-       CFRelease(value);
 
        while (TRUE) {
+               CFArrayRef      changedKeys;
+
                /*
                 * Attempt to acquire the lock
                 */
-               scd_status = SCDAddSession(sessionPrivate->session,
-                                          sessionPrivate->sessionKeyLock,
-                                          handle);
-               switch (scd_status) {
-                       case SCD_OK :
-                               scp_status = SCP_OK;
-                               goto done;
-                       case SCD_EXISTS :
-                               if (!wait) {
-                                       scp_status = SCP_BUSY;
-                                       goto error;
-                               }
-                               break;
-                       default :
-                               SCDLog(LOG_INFO, CFSTR("SCDAddSession() failed: %s"), SCDError(scd_status));
-                               scp_status = SCP_FAILED;
+               if (SCDynamicStoreAddTemporaryValue(sessionPrivate->session,
+                                                   sessionPrivate->sessionKeyLock,
+                                                   value)) {
+                       haveLock = TRUE;
+                       goto done;
+               } else {
+                       if (!wait) {
+                               _SCErrorSet(kSCStatusPrefsBusy);
                                goto error;
+                       }
                }
 
                /*
                 * Wait for the lock to be released
                 */
-               scd_status = SCDNotifierWait(sessionPrivate->session);
-               if (scd_status != SCD_OK) {
-                       SCDLog(LOG_INFO, CFSTR("SCDAddSession() failed: %s"), SCDError(scd_status));
-                       scp_status = SCP_FAILED;
+               if (!SCDynamicStoreNotifyWait(sessionPrivate->session)) {
+                       SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreNotifyWait() failed"));
                        goto error;
                }
+               changedKeys = SCDynamicStoreCopyNotifiedKeys(sessionPrivate->session);
+               if (!changedKeys) {
+                       SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCopyNotifiedKeys() failed"));
+                       goto error;
+               }
+               CFRelease(changedKeys);
        }
 
     done :
 
-       SCDHandleRelease(handle);
-       handle = NULL;
+       CFRelease(value);
+       value = NULL;
 
-       scd_status = SCDNotifierRemove(sessionPrivate->session,
-                                      sessionPrivate->sessionKeyLock,
-                                      0);
-       if (scd_status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDNotifierRemove() failed: %s"), SCDError(scd_status));
-               scp_status = SCP_FAILED;
+       if (!SCDynamicStoreRemoveWatchedKey(sessionPrivate->session,
+                                           sessionPrivate->sessionKeyLock,
+                                           0)) {
+               SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreRemoveWatchedKey() failed"));
                goto error;
        }
 
-       scd_status = SCDNotifierGetChanges(sessionPrivate->session, &changes);
-       if (scd_status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDNotifierGetChanges() failed: %s"), SCDError(scd_status));
-               scp_status = SCP_FAILED;
+       changes = SCDynamicStoreCopyNotifiedKeys(sessionPrivate->session);
+       if (!changes) {
+               SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCopyNotifiedKeys() failed"));
                goto error;
        }
        CFRelease(changes);
 
-    notRoot:
+    perUser:
 
        /*
         * Check the signature
@@ -148,25 +157,65 @@ SCPLock(SCPSessionRef session, boolean_t wait)
                if (errno == ENOENT) {
                        bzero(&statBuf, sizeof(statBuf));
                } else {
-                       SCDLog(LOG_DEBUG, CFSTR("stat() failed: %s"), strerror(errno));
-                       scp_status = SCP_STALE;
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("stat() failed: %s"), strerror(errno));
+                       _SCErrorSet(kSCStatusStale);
                        goto error;
                }
        }
 
-       currentSignature = _SCPSignatureFromStatbuf(&statBuf);
+       currentSignature = __SCPSignatureFromStatbuf(&statBuf);
        if (!CFEqual(sessionPrivate->signature, currentSignature)) {
-               CFRelease(currentSignature);
-               scp_status = SCP_STALE;
-               goto error;
+               if (sessionPrivate->accessed) {
+                       /*
+                        * the preferences have been accessed since the
+                        * session was created so we've got no choice
+                        * but to deny the lock request.
+                        */
+                       _SCErrorSet(kSCStatusStale);
+                       goto error;
+               } else {
+                       /*
+                        * the file contents have changed but since we
+                        * haven't accessed any of the preferences we
+                        * don't need to return an error.  Simply reload
+                        * the stored data and proceed.
+                        */
+                       SCPreferencesRef        newPrefs;
+                       SCPreferencesPrivateRef newPrivate;
+
+                       newPrefs = __SCPreferencesCreate(NULL,
+                                                        sessionPrivate->name,
+                                                        sessionPrivate->prefsID,
+                                                        sessionPrivate->perUser,
+                                                        sessionPrivate->user);
+                       if (!newPrefs) {
+                               /* if updated preferences could not be loaded */
+                               _SCErrorSet(kSCStatusStale);
+                               goto error;
+                       }
+
+                       /* synchronize this sessions prefs/signature */
+                       newPrivate = (SCPreferencesPrivateRef)newPrefs;
+                       CFRelease(sessionPrivate->prefs);
+                       sessionPrivate->prefs = CFRetain(newPrivate->prefs);
+                       CFRelease(sessionPrivate->signature);
+                       sessionPrivate->signature = CFRetain(newPrivate->signature);
+                       CFRelease(newPrefs);
+               }
        }
        CFRelease(currentSignature);
 
        sessionPrivate->locked = TRUE;
-       return SCD_OK;
+       return TRUE;
 
     error :
 
-       if (handle)     SCDHandleRelease(handle);
-       return scp_status;
+       if (haveLock) {
+               SCDynamicStoreRemoveValue(sessionPrivate->session,
+                                         sessionPrivate->sessionKeyLock);
+       }
+       if (currentSignature)   CFRelease(currentSignature);
+       if (value)              CFRelease(value);
+
+       return FALSE;
 }
index dd3e772bc4c61dbc1ed93341060669503b11a0b9..6a13925b963bf517d086a42832d3eb713cdb6293 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SCP.h>
-#include <SystemConfiguration/SCPPath.h>
-#include "SCPPrivate.h"
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCPreferencesInternal.h"
 
 #include <fcntl.h>
+#include <pthread.h>
 #include <unistd.h>
 #include <sys/errno.h>
 
+static CFStringRef
+__SCPreferencesCopyDescription(CFTypeRef cf) {
+       CFAllocatorRef          allocator       = CFGetAllocator(cf);
+       CFMutableStringRef      result;
+
+       result = CFStringCreateMutable(allocator, 0);
+       CFStringAppendFormat(result, NULL, CFSTR("<SCPreferences %p [%p]> {\n"), cf, allocator);
+       CFStringAppendFormat(result, NULL, CFSTR("}"));
+
+       return result;
+}
+
+
+static void
+__SCPreferencesDeallocate(CFTypeRef cf)
+{
+       SCPreferencesPrivateRef sessionPrivate  = (SCPreferencesPrivateRef)cf;
+
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("__SCPreferencesDeallocate:"));
+
+       /* release resources */
+       if (sessionPrivate->name)               CFRelease(sessionPrivate->name);
+       if (sessionPrivate->prefsID)            CFRelease(sessionPrivate->prefsID);
+       if (sessionPrivate->user)               CFRelease(sessionPrivate->user);
+       if (sessionPrivate->path)               CFAllocatorDeallocate(NULL, sessionPrivate->path);
+       if (sessionPrivate->signature)          CFRelease(sessionPrivate->signature);
+       if (sessionPrivate->session)            CFRelease(sessionPrivate->session);
+       if (sessionPrivate->sessionKeyLock)     CFRelease(sessionPrivate->sessionKeyLock);
+       if (sessionPrivate->sessionKeyCommit)   CFRelease(sessionPrivate->sessionKeyCommit);
+       if (sessionPrivate->sessionKeyApply)    CFRelease(sessionPrivate->sessionKeyApply);
+       if (sessionPrivate->prefs)              CFRelease(sessionPrivate->prefs);
+
+       return;
+}
+
+
+static CFTypeID __kSCPreferencesTypeID = _kCFRuntimeNotATypeID;
+
+
+static const CFRuntimeClass __SCPreferencesClass = {
+       0,                                      // version
+       "SCPreferences",                        // className
+       NULL,                                   // init
+       NULL,                                   // copy
+       __SCPreferencesDeallocate,      // dealloc
+       NULL,                                   // equal
+       NULL,                                   // hash
+       NULL,                                   // copyFormattingDesc
+       __SCPreferencesCopyDescription  // copyDebugDesc
+};
+
+
+static pthread_once_t initialized      = PTHREAD_ONCE_INIT;
+
+
+static void
+__SCPreferencesInitialize(void) {
+       __kSCPreferencesTypeID = _CFRuntimeRegisterClass(&__SCPreferencesClass);
+       return;
+}
+
 
-static SCPStatus
-_SCPOpen(SCPSessionRef *session,
-        CFStringRef    name,
-        CFStringRef    prefsID,
-        boolean_t      perUser,
-        CFStringRef    user,
-        int            options)
+SCPreferencesRef
+__SCPreferencesCreatePrivate(CFAllocatorRef    allocator)
 {
-       SCPStatus               scp_status;
-       SCPSessionPrivateRef    newSession;
-       int                     fd              = -1;
-       struct stat             statBuf;
-       CFMutableDataRef        xmlData;
-       CFStringRef             xmlError;
-
-       newSession = (SCPSessionPrivateRef)CFAllocatorAllocate(NULL, sizeof(SCPSessionPrivate), 0);
-       newSession->name                = NULL;
-       newSession->prefsID             = NULL;
-       newSession->perUser             = perUser;
-       newSession->user                = NULL;
-       newSession->path                = NULL;
-       newSession->signature           = NULL;
-       newSession->session             = NULL;
-       newSession->sessionKeyLock      = NULL;
-       newSession->sessionKeyCommit    = NULL;
-       newSession->sessionKeyApply     = NULL;
-       newSession->prefs               = NULL;
-       newSession->changed             = FALSE;
-       newSession->locked              = FALSE;
-       newSession->isRoot              = (geteuid() == 0);
+       SCPreferencesPrivateRef prefs;
+       UInt32                          size;
+
+       /* initialize runtime */
+       pthread_once(&initialized, __SCPreferencesInitialize);
+
+       /* allocate session */
+       size  = sizeof(SCPreferencesPrivate) - sizeof(CFRuntimeBase);
+       prefs = (SCPreferencesPrivateRef)_CFRuntimeCreateInstance(allocator,
+                                                                        __kSCPreferencesTypeID,
+                                                                        size,
+                                                                        NULL);
+       if (!prefs) {
+               return NULL;
+       }
+
+       prefs->name             = NULL;
+       prefs->prefsID          = NULL;
+       prefs->perUser          = FALSE;
+       prefs->user             = NULL;
+       prefs->path             = NULL;
+       prefs->signature        = NULL;
+       prefs->session          = NULL;
+       prefs->sessionKeyLock   = NULL;
+       prefs->sessionKeyCommit = NULL;
+       prefs->sessionKeyApply  = NULL;
+       prefs->prefs            = NULL;
+       prefs->accessed         = FALSE;
+       prefs->changed          = FALSE;
+       prefs->locked           = FALSE;
+       prefs->isRoot           = (geteuid() == 0);
+
+       return (SCPreferencesRef)prefs;
+}
+
+
+__private_extern__ SCPreferencesRef
+__SCPreferencesCreate(CFAllocatorRef   allocator,
+                     CFStringRef       name,
+                     CFStringRef       prefsID,
+                     Boolean           perUser,
+                     CFStringRef       user)
+{
+       int                             fd              = -1;
+       SCPreferencesRef                prefs;
+       SCPreferencesPrivateRef         prefsPrivate;
+       int                             sc_status       = kSCStatusOK;
+       struct stat                     statBuf;
+       CFMutableDataRef                xmlData;
+       CFStringRef                     xmlError;
+
+       /*
+        * allocate and initialize a new session
+        */
+       prefs = __SCPreferencesCreatePrivate(allocator);
+       if (!prefs) {
+               return NULL;
+       }
+       prefsPrivate = (SCPreferencesPrivateRef)prefs;
 
        /*
         * convert prefsID to path
         */
-       newSession->path = _SCPPrefsPath(prefsID, perUser, user);
-       if (newSession->path == NULL) {
-               scp_status = SCP_FAILED;
+       prefsPrivate->path = __SCPreferencesPath(NULL, prefsID, perUser, user);
+       if (prefsPrivate->path == NULL) {
+               sc_status = kSCStatusFailed;
                goto error;
        }
 
        /*
         * open file
         */
-       fd = open(newSession->path, O_RDONLY, 0644);
+       fd = open(prefsPrivate->path, O_RDONLY, 0644);
        if (fd == -1) {
-               char    *errmsg = strerror(errno);
-
                switch (errno) {
                        case ENOENT :
-                               if (options & kSCPOpenCreatePrefs) {
-                                       bzero(&statBuf, sizeof(statBuf));
-                                       goto create_1;
-                               }
-                               scp_status = SCP_ENOENT;
-                               break;
+                               /* no prefs file, start fresh */
+                               bzero(&statBuf, sizeof(statBuf));
+                               goto create_1;
                        case EACCES :
-                               scp_status = SCP_EACCESS;
+                               sc_status = kSCStatusAccessError;
                                break;
                        default :
-                               scp_status = SCP_FAILED;
+                               sc_status = kSCStatusFailed;
+                               break;
                }
-               SCDLog(LOG_DEBUG, CFSTR("open() failed: %s"), errmsg);
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("open() failed: %s"), strerror(errno));
                goto error;
        }
 
@@ -100,14 +198,14 @@ _SCPOpen(SCPSessionRef    *session,
         * check file, create signature
         */
        if (fstat(fd, &statBuf) == -1) {
-               SCDLog(LOG_DEBUG, CFSTR("fstat() failed: %s"), strerror(errno));
-               scp_status = SCP_FAILED;
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("fstat() failed: %s"), strerror(errno));
+               sc_status = kSCStatusFailed;
                goto error;
        }
 
     create_1 :
 
-       newSession->signature = _SCPSignatureFromStatbuf(&statBuf);
+       prefsPrivate->signature = __SCPSignatureFromStatbuf(&statBuf);
 
        if (statBuf.st_size > 0) {
                /*
@@ -116,46 +214,42 @@ _SCPOpen(SCPSessionRef    *session,
                xmlData = CFDataCreateMutable(NULL, statBuf.st_size);
                CFDataSetLength(xmlData, statBuf.st_size);
                if (read(fd, (void *)CFDataGetBytePtr(xmlData), statBuf.st_size) != statBuf.st_size) {
-                       SCDLog(LOG_DEBUG, CFSTR("_SCPOpen read(): could not load preference data."));
+                       /* corrupt prefs file, start fresh */
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("_SCPOpen read(): could not load preference data."));
                        CFRelease(xmlData);
                        xmlData = NULL;
-                       if (options & kSCPOpenCreatePrefs) {
-                               goto create_2;
-                       }
-                       scp_status = SCP_BADCF;
-                       goto error;
+                       goto create_2;
                }
 
                /*
                 * load preferences
                 */
-               newSession->prefs = (CFMutableDictionaryRef)
+               prefsPrivate->prefs = (CFMutableDictionaryRef)
                                    CFPropertyListCreateFromXMLData(NULL,
                                                                    xmlData,
                                                                    kCFPropertyListMutableContainers,
                                                                    &xmlError);
                CFRelease(xmlData);
-               if (xmlError) {
-                       SCDLog(LOG_DEBUG, CFSTR("_SCPOpen CFPropertyListCreateFromXMLData(): %s"), xmlError);
-                       if (options & kSCPOpenCreatePrefs) {
-                               goto create_2;
+               if (!prefsPrivate->prefs) {
+                       /* corrupt prefs file, start fresh */
+                       if (xmlError) {
+                               SCLog(_sc_verbose, LOG_DEBUG,
+                                      CFSTR("_SCPOpen CFPropertyListCreateFromXMLData(): %@"),
+                                      xmlError);
+                               CFRelease(xmlError);
                        }
-                       scp_status = SCP_BADCF;
-                       goto error;
+                       goto create_2;
                }
 
                /*
                 * make sure that we've got a dictionary
                 */
-               if (CFGetTypeID(newSession->prefs) != CFDictionaryGetTypeID()) {
-                               SCDLog(LOG_DEBUG, CFSTR("_SCPOpen CFGetTypeID(): not a dictionary."));
-                               CFRelease(newSession->prefs);
-                               newSession->prefs = NULL;
-                               if (options & kSCPOpenCreatePrefs) {
-                                       goto create_2;
-                               }
-                       scp_status = SCP_BADCF;
-                       goto error;
+               if (CFGetTypeID(prefsPrivate->prefs) != CFDictionaryGetTypeID()) {
+                       /* corrupt prefs file, start fresh */
+                       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("_SCPOpen CFGetTypeID(): not a dictionary."));
+                       CFRelease(prefsPrivate->prefs);
+                       prefsPrivate->prefs = NULL;
+                       goto create_2;
                }
        }
 
@@ -166,58 +260,71 @@ _SCPOpen(SCPSessionRef    *session,
                fd = -1;
        }
 
-       if (newSession->prefs == NULL) {
+       if (prefsPrivate->prefs == NULL) {
                /*
                 * new file, create empty preferences
                 */
-               SCDLog(LOG_DEBUG, CFSTR("_SCPOpen(): creating new dictionary."));
-               newSession->prefs = CFDictionaryCreateMutable(NULL,
-                                                             0,
-                                                             &kCFTypeDictionaryKeyCallBacks,
-                                                             &kCFTypeDictionaryValueCallBacks);
-               newSession->changed = TRUE;
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("_SCPOpen(): creating new dictionary."));
+               prefsPrivate->prefs = CFDictionaryCreateMutable(NULL,
+                                                               0,
+                                                               &kCFTypeDictionaryKeyCallBacks,
+                                                               &kCFTypeDictionaryValueCallBacks);
+               prefsPrivate->changed = TRUE;
        }
 
        /*
         * all OK
         */
-       newSession->name                = CFRetain(name);
+       prefsPrivate->name = CFRetain(name);
        if (prefsID) {
-               newSession->prefsID     = CFRetain(prefsID);
+               prefsPrivate->prefsID = CFRetain(prefsID);
        }
-       newSession->perUser             = perUser;
+       prefsPrivate->perUser = perUser;
        if (user) {
-               newSession->user        = CFRetain(user);
+               prefsPrivate->user = CFRetain(user);
        }
-       *session   = (SCPSessionRef)newSession;
-       return SCP_OK;
+       return prefs;
 
     error :
 
        if (fd != -1) {
-               (void)close(fd);
+               (void) close(fd);
        }
-       (void) SCPClose((SCPSessionRef *)&newSession);
-       return scp_status;
+       CFRelease(prefs);
+       _SCErrorSet(sc_status);
+       return NULL;
 }
 
 
-SCPStatus
-SCPOpen(SCPSessionRef  *session,
-       CFStringRef     name,
-       CFStringRef     prefsID,
-       int             options)
+SCPreferencesRef
+SCPreferencesCreate(CFAllocatorRef             allocator,
+                   CFStringRef                 name,
+                   CFStringRef                 prefsID)
 {
-       return _SCPOpen(session, name, prefsID, FALSE, NULL, options);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesCreate:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  name    = %@"), name);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  prefsID = %@"), prefsID);
+
+       return __SCPreferencesCreate(allocator, name, prefsID, FALSE, NULL);
 }
 
 
-SCPStatus
-SCPUserOpen(SCPSessionRef      *session,
-           CFStringRef         name,
-           CFStringRef         prefsID,
-           CFStringRef         user,
-           int                 options)
+SCPreferencesRef
+SCUserPreferencesCreate(CFAllocatorRef                 allocator,
+                       CFStringRef                     name,
+                       CFStringRef                     prefsID,
+                       CFStringRef                     user)
 {
-       return _SCPOpen(session, name, prefsID, TRUE, user, options);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCUserPreferencesCreate:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  name    = %@"), name);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  prefsID = %@"), prefsID);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  user    = %@"), user);
+
+       return __SCPreferencesCreate(allocator, name, prefsID, TRUE, user);
+}
+
+
+CFTypeID
+SCPreferencesGetTypeID(void) {
+       return __kSCPreferencesTypeID;
 }
index aee9cf8d36da1ec7d9dbc6ac29084dbecdff17f7..ea2c3f4647323688973c7aeecf2ed2686244a79d 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SCD.h>
-#include <SystemConfiguration/SCP.h>
-#include "SCPPrivate.h"
-#include <SystemConfiguration/SCPreferences.h>
-#include <SystemConfiguration/SCPPath.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 16, 2000           Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
 
 static CFArrayRef
 normalizePath(CFStringRef path)
@@ -64,34 +71,30 @@ normalizePath(CFStringRef path)
 }
 
 
-static SCPStatus
-getPath(SCPSessionRef session, CFStringRef path, CFMutableDictionaryRef *entity)
+static int
+getPath(SCPreferencesRef session, CFStringRef path, CFMutableDictionaryRef *entity)
 {
        CFArrayRef              elements;
        CFIndex                 i;
        CFIndex                 nElements;
-       SCPStatus               status;
+       int                     status          = kSCStatusFailed;
        CFMutableDictionaryRef  value           = NULL;
 
-       if (session == NULL) {
-               return SCP_NOSESSION;   /* you can't do anything with a closed session */
-       }
-
        elements = normalizePath(path);
        if (elements == NULL) {
-               return SCP_NOKEY;
+               return kSCStatusNoKey;
        }
 
        /* get preferences key */
-       status = SCPGet(session,
-                       CFArrayGetValueAtIndex(elements, 0),
-                       (CFPropertyListRef *)&value);
-       if (status != SCP_OK) {
+       value = (CFMutableDictionaryRef)SCPreferencesGetValue(session,
+                                                             CFArrayGetValueAtIndex(elements, 0));
+       if (!value) {
+               status = kSCStatusNoKey;
                goto done;
        }
 
        if (CFGetTypeID(value) != CFDictionaryGetTypeID()) {
-               status = SCP_NOKEY;
+               status = kSCStatusNoKey;
                goto done;
        }
 
@@ -103,19 +106,19 @@ getPath(SCPSessionRef session, CFStringRef path, CFMutableDictionaryRef *entity)
                value   = (CFMutableDictionaryRef)CFDictionaryGetValue(value, element);
                if (value == NULL) {
                        /* if (parent) path component does not exist */
-                       status = SCP_NOKEY;
+                       status = kSCStatusNoKey;
                        goto done;
                }
 
                if (CFGetTypeID(value) != CFDictionaryGetTypeID()) {
-                       status = SCP_NOKEY;
+                       status = kSCStatusNoKey;
                        goto done;
                }
 
        }
 
        *entity = value;
-       status = SCP_OK;
+       status = kSCStatusOK;
 
     done :
 
@@ -124,27 +127,25 @@ getPath(SCPSessionRef session, CFStringRef path, CFMutableDictionaryRef *entity)
 }
 
 
-SCPStatus
-SCPPathCreateUniqueChild(SCPSessionRef session,
-                        CFStringRef    prefix,
-                        CFStringRef    *newPath)
+CFStringRef
+SCPreferencesPathCreateUniqueChild(SCPreferencesRef    session,
+                                  CFStringRef          prefix)
 {
-       SCPStatus               status;
+       int                     status;
        CFMutableDictionaryRef  value;
-       boolean_t               newValue        = FALSE;
+       CFStringRef             newPath         = NULL;
+       Boolean                 newValue        = FALSE;
        CFIndex                 i;
-       CFStringRef             path;
-       CFMutableDictionaryRef  newDict;
+       CFMutableDictionaryRef  newDict         = NULL;
 
-       if (session == NULL) {
-               return SCP_NOSESSION;   /* you can't do anything with a closed session */
-       }
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesPathCreateUniqueChild:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  prefix = %@"), prefix);
 
        status = getPath(session, prefix, &value);
        switch (status) {
-               case SCP_OK :
+               case kSCStatusOK :
                        break;
-               case SCP_NOKEY :
+               case kSCStatusNoKey :
                        value = CFDictionaryCreateMutable(NULL,
                                                          0,
                                                          &kCFTypeDictionaryKeyCallBacks,
@@ -152,19 +153,19 @@ SCPPathCreateUniqueChild(SCPSessionRef    session,
                        newValue = TRUE;
                        break;
                default :
-                       return status;
+                       return NULL;
        }
 
        if (CFGetTypeID(value) != CFDictionaryGetTypeID()) {
                /* if specified path is not a dictionary */
-               status = SCP_NOKEY;
-               goto done;
+               status = kSCStatusNoKey;
+               goto error;
        }
 
        if (CFDictionaryContainsKey(value, kSCResvLink)) {
                /* the path is a link... */
-               status = SCP_FAILED;
-               goto done;
+               status = kSCStatusFailed;
+               goto error;
        }
 
        i = 0;
@@ -178,11 +179,11 @@ SCPPathCreateUniqueChild(SCPSessionRef    session,
 
                if (!found) {
                        /* if we've identified the next unique key */
-                       path = CFStringCreateWithFormat(NULL,
-                                                       NULL,
-                                                       CFSTR("%@/%i"),
-                                                       prefix,
-                                                       i);
+                       newPath = CFStringCreateWithFormat(NULL,
+                                                          NULL,
+                                                          CFSTR("%@/%i"),
+                                                          prefix,
+                                                          i);
                        break;
                }
                i++;
@@ -193,38 +194,38 @@ SCPPathCreateUniqueChild(SCPSessionRef    session,
                                            0,
                                            &kCFTypeDictionaryKeyCallBacks,
                                            &kCFTypeDictionaryValueCallBacks);
-       status = SCPPathSetValue(session, path, newDict);
-       CFRelease(newDict);
-       if (status != SCP_OK) {
-               CFRelease(path);
-               goto done;
+       if (!SCPreferencesPathSetValue(session, newPath, newDict)) {
+               goto error;
        }
+       CFRelease(newDict);
 
-       *newPath = path;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  child  = %@"), newPath);
+       if (newValue)   CFRelease(value);
+       return newPath;
 
-    done :
+    error :
 
+       if (newDict)    CFRelease(newDict);
        if (newValue)   CFRelease(value);
-       return status;
+       if (newPath)    CFRelease(newPath);
+       return NULL;
 }
 
 
-SCPStatus
-SCPPathGetValue(SCPSessionRef  session,
-               CFStringRef     path,
-               CFDictionaryRef *value)
+CFDictionaryRef
+SCPreferencesPathGetValue(SCPreferencesRef     session,
+                         CFStringRef           path)
 {
-       SCPStatus               status;
+       int                     status;
        CFMutableDictionaryRef  entity;
        CFStringRef             entityLink;
 
-       if (session == NULL) {
-               return SCP_NOSESSION;   /* you can't do anything with a closed session */
-       }
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesPathGetValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  path  = %@"), path);
 
        status = getPath(session, path, &entity);
-       if (status != SCP_OK) {
-               return status;
+       if (status != kSCStatusOK) {
+               return NULL;
        }
 
 /* XXXX Add code here to chase multiple links XXXXX */
@@ -233,71 +234,71 @@ SCPPathGetValue(SCPSessionRef     session,
            (CFDictionaryGetValueIfPresent(entity, kSCResvLink, (void **)&entityLink))) {
                    /* if this is a dictionary AND it is a link */
                    status = getPath(session, entityLink, &entity);
-                   if (status != SCP_OK) {
+                   if (status != kSCStatusOK) {
                            /* if it was a bad link */
-                           return status;
+                           return NULL;
                    }
        }
 
-       *value = entity;
-       return status;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  value = %@"), entity);
+       return entity;
 }
 
 
-SCPStatus
-SCPPathGetLink(SCPSessionRef           session,
-              CFStringRef              path,
-              CFStringRef              *link)
+CFStringRef
+SCPreferencesPathGetLink(SCPreferencesRef      session,
+                        CFStringRef            path)
 {
-       SCPStatus               status;
+       int                     status;
        CFMutableDictionaryRef  entity;
        CFStringRef             entityLink;
 
-       if (session == NULL) {
-               return SCP_NOSESSION;   /* you can't do anything with a closed session */
-       }
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesPathGetLink:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  path = %@"), path);
 
        status = getPath(session, path, &entity);
-       if (status != SCP_OK) {
-               return status;
+       if (status != kSCStatusOK) {
+               return NULL;
        }
 
        if ((CFGetTypeID(entity) == CFDictionaryGetTypeID()) &&
            (CFDictionaryGetValueIfPresent(entity, kSCResvLink, (void **)&entityLink))) {
                    /* if this is a dictionary AND it is a link */
-               *link = entityLink;
-               return status;
+               SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  link = %@"), entityLink);
+               return entityLink;
        }
 
-       return SCP_NOKEY;
+       return NULL;
 }
 
 
-SCPStatus
-SCPPathSetValue(SCPSessionRef session, CFStringRef path, CFDictionaryRef value)
+Boolean
+SCPreferencesPathSetValue(SCPreferencesRef     session,
+                         CFStringRef           path,
+                         CFDictionaryRef       value)
 {
        CFMutableDictionaryRef  element;
        CFArrayRef              elements        = NULL;
        CFIndex                 i;
        CFIndex                 nElements;
-       boolean_t               newRoot         = FALSE;
+       Boolean                 newRoot         = FALSE;
+       Boolean                 ok;
        CFMutableDictionaryRef  root            = NULL;
-       SCPStatus               status          = SCP_NOKEY;
 
-       if (session == NULL) {
-               return SCP_NOSESSION;   /* you can't do anything with a closed session */
-       }
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesPathSetValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  path  = %@"), path);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  value = %@"), value);
 
        elements = normalizePath(path);
        if (elements == NULL) {
-               return SCP_NOKEY;
+               _SCErrorSet(kSCStatusNoKey);
+               return FALSE;
        }
 
        /* get preferences key */
-       status = SCPGet(session,
-                       CFArrayGetValueAtIndex(elements, 0),
-                       (CFPropertyListRef *)&root);
-       if (status != SCP_OK) {
+       root = (CFMutableDictionaryRef)SCPreferencesGetValue(session,
+                                                            CFArrayGetValueAtIndex(elements, 0));
+       if (!root) {
                root = CFDictionaryCreateMutable(NULL,
                                                  0,
                                                  &kCFTypeDictionaryKeyCallBacks,
@@ -339,67 +340,68 @@ SCPPathSetValue(SCPSessionRef session, CFStringRef path, CFDictionaryRef value)
                                     CFArrayGetValueAtIndex(elements, nElements-1),
                                     value);
        }
-       status = SCPSet(session, CFArrayGetValueAtIndex(elements, 0), root);
-
+       ok = SCPreferencesSetValue(session, CFArrayGetValueAtIndex(elements, 0), root);
        if (newRoot)    CFRelease(root);
        CFRelease(elements);
-       return status;
+       return ok;
 }
 
 
-SCPStatus
-SCPPathSetLink(SCPSessionRef session, CFStringRef path, CFStringRef link)
+Boolean
+SCPreferencesPathSetLink(SCPreferencesRef      session,
+                        CFStringRef            path,
+                        CFStringRef            link)
 {
        CFMutableDictionaryRef  dict;
-       SCPStatus               status;
+       Boolean                 ok;
 
-       if (session == NULL) {
-               return SCP_NOSESSION;   /* you can't do anything with a closed session */
-       }
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesPathSetLink:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  path = %@"), path);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  link = %@"), link);
 
        dict = CFDictionaryCreateMutable(NULL,
                                         0,
                                         &kCFTypeDictionaryKeyCallBacks,
                                         &kCFTypeDictionaryValueCallBacks);
        CFDictionaryAddValue(dict, kSCResvLink, link);
-       status = SCPPathSetValue(session, path, dict);
+       ok = SCPreferencesPathSetValue(session, path, dict);
        CFRelease(dict);
 
-       return status;
+       return ok;
 }
 
 
-SCPStatus
-SCPPathRemove(SCPSessionRef session, CFStringRef path)
+Boolean
+SCPreferencesPathRemoveValue(SCPreferencesRef  session,
+                            CFStringRef        path)
 {
        CFMutableDictionaryRef  element;
        CFArrayRef              elements        = NULL;
        CFIndex                 i;
        CFIndex                 nElements;
+       Boolean                 ok              = FALSE;
        CFMutableDictionaryRef  root            = NULL;
-       SCPStatus               status          = SCP_NOKEY;
 
-       if (session == NULL) {
-               return SCP_NOSESSION;   /* you can't do anything with a closed session */
-       }
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesPathRemoveValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  path = %@"), path);
 
        elements = normalizePath(path);
        if (elements == NULL) {
-               return SCP_NOKEY;
+               _SCErrorSet(kSCStatusNoKey);
+               return FALSE;
        }
 
        /* get preferences key */
-       status = SCPGet(session,
-                       CFArrayGetValueAtIndex(elements, 0),
-                       (CFPropertyListRef *)&root);
-       if (status != SCP_OK) {
+       root = (CFMutableDictionaryRef)SCPreferencesGetValue(session,
+                                                            CFArrayGetValueAtIndex(elements, 0));
+       if (!root) {
                goto done;
        }
 
        nElements = CFArrayGetCount(elements);
        if (nElements == 1) {
                /* if we are removing the data associated with the preference key */
-               status = SCPRemove(session, CFArrayGetValueAtIndex(elements, 0));
+               ok = SCPreferencesRemoveValue(session, CFArrayGetValueAtIndex(elements, 0));
                goto done;
        }
 
@@ -411,7 +413,6 @@ SCPPathRemove(SCPSessionRef session, CFStringRef path)
                pathComponent = CFArrayGetValueAtIndex(elements, i);
                tmpElement    = (void *)CFDictionaryGetValue(element, pathComponent);
                if (tmpElement == NULL) {
-                       status = SCP_NOKEY;
                        goto done;
                }
                element = tmpElement;
@@ -419,10 +420,10 @@ SCPPathRemove(SCPSessionRef session, CFStringRef path)
 
        CFDictionaryRemoveValue(element,
                                CFArrayGetValueAtIndex(elements, nElements-1));
-       status = SCPSet(session, CFArrayGetValueAtIndex(elements, 0), root);
+       ok = SCPreferencesSetValue(session, CFArrayGetValueAtIndex(elements, 0), root);
 
     done :
 
        CFRelease(elements);
-       return status;
+       return ok;
 }
index f4005184d521e3407f80e72b215101bd335ce2e8..8febc65d0099c444cb4b8bdc3e2221c52e22fdf2 100644 (file)
 #ifndef _SCPPATH_H
 #define _SCPPATH_H
 
-#include <CoreFoundation/CoreFoundation.h>
-#include <sys/cdefs.h>
-
-/*!
-       @header SCPPath.h
-       The SystemConfiguration framework provides access to the data used
-               to configure a running system.
-
-       Specifically, the SCPPathXXX() API's allow an application to
-               load and store XML configuration data in a controlled
-               manner and provides the necessary notifications to other
-               applications which need to be aware of configuration
-               changes.
-
-       The SCPPathXXX() API's make certain assumptions about the layout
-               of the preferences data.  These APIs view the data as a
-               collection of dictionaries of key/value pairs and an
-               associated path name.  The root path ("/") identifies
-               the top-level dictionary.  Additional path components
-               specify the keys for sub-dictionaries.
-
-               For example, the following dictionary can be access via
-               two paths.  The root ("/") path would return a property
-               list with all keys and values.  The path "/path1" would
-               only return the dictionary with the "key3" and "key4"
-               properties.
-
-               <dict>
-                       <key>key1</key>
-                       <string>val1</string>
-                       <key>key2</key>
-                       <string>val2</string>
-                       <key>path1</key>
-                       <dict>
-                               <key>key3</key>
-                               <string>val3</string>
-                               <key>key4</key>
-                               <string>val4</string>
-                       </dict>
-               </dict>
-
-       The APIs provided by this framework communicate with the "configd"
-               daemon for any tasks requiring synchronization and/or
-               notification.
- */
-
-
-__BEGIN_DECLS
-
-/*!
-       @function SCPPathCreateUniqueChild
-       @discussion Creates a new path component within the dictionary
-               hierarchy.
-       @param session Pass the SCPSessionRef handle which should be used to
-        communicate with the APIs.
-       @param prefix Pass a string which represents the parent path.
-       @param newPath A pointer to memory which will be filled with an
-               string representing the new child path.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK,
-               SCP_NOKEY.
- */
-SCPStatus      SCPPathCreateUniqueChild        (SCPSessionRef          session,
-                                                CFStringRef            prefix,
-                                                CFStringRef            *newPath);
-
-/*!
-       @function SCPPathGetValue
-       @discussion Returns the dictionary associated with the specified
-               path.
-       @param session Pass the SCPSessionRef handle which should be used to
-        communicate with the APIs.
-       @param path Pass a string whcih represents the path to be returned.
-       @param value A pointer to memory which will be filled with an
-               dictionary associated with the specified path.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK,
-               SCP_NOKEY.
- */
-SCPStatus      SCPPathGetValue                 (SCPSessionRef          session,
-                                                CFStringRef            path,
-                                                CFDictionaryRef        *value);
-
-/*!
-       @function SCPPathGetLink
-       @discussion Returns the link (if one exists) associatd with the
-               specified path.
-       @param session Pass the SCPSessionRef handle which should be used to
-        communicate with the APIs.
-       @param path Pass a string whcih represents the path to be returned.
-       @param link A pointer to memory which will be filled with a
-               string reflecting the link found at the specified path.
-               If no link was present at the specified path a status
-               value of SCP_NOKEY will be returned.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK,
-               SCP_NOKEY.
- */
-SCPStatus      SCPPathGetLink                  (SCPSessionRef          session,
-                                                CFStringRef            path,
-                                                CFStringRef            *link);
-
-/*!
-       @function SCPPathSetValue
-       @discussion Associates a dictionary with the specified path.
-       @param session Pass the SCPSessionRef handle which should be used to
-        communicate with the APIs.
-       @param path Pass a string whcih represents the path to be returned.
-       @param value Pass a dictionary which represents the data to be
-               stored at the specified path.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK.
- */
-SCPStatus      SCPPathSetValue                 (SCPSessionRef          session,
-                                                CFStringRef            path,
-                                                CFDictionaryRef        value);
-
-/*!
-       @function SCPPathSetLink
-       @discussion Associates a link to a second dictionary at the
-               specified path.
-       @param session Pass the SCPSessionRef handle which should be used to
-        communicate with the APIs.
-       @param path Pass a string whcih represents the path to be returned.
-       @param value Pass a string which represents the path to be stored
-               at the specified path.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK,
-               SCP_NOKEY.
- */
-SCPStatus      SCPPathSetLink                  (SCPSessionRef          session,
-                                                CFStringRef            path,
-                                                CFStringRef            link);
-
-/*!
-       @function SCPPathRemove
-       @discussion Removes the data associated with the specified path.
-       @param session Pass the SCPSessionRef handle which should be used to
-        communicate with the APIs.
-       @param path Pass a string whcih represents the path to be returned.
-       @result A constant of type SCPStatus indicating the success (or
-               failure) of the call. Possible return values include: SCP_OK,
-               SCP_NOKEY.
- */
-SCPStatus      SCPPathRemove                   (SCPSessionRef          session,
-                                                CFStringRef            path);
-
-__END_DECLS
+#ifndef _SYSTEMCONFIGURATION_H
+#warning Your code has directly included the (old) <SystemConfiguration/SCPPath.h>
+#warning header file.  Please dont do that.  Use the top-level header file:
+#warning
+#warning   <SystemConfiguration/SystemConfiguration.h>
+#warning
+#warning Note: the configuration preference APIs have been moved out of the
+#warning       SCPPath.h header file.
+#include <SystemConfiguration/SystemConfiguration.h>    /* ...and try to keep everyone happy */
+#endif
 
 #endif /* _SCPPATH_H */
diff --git a/SystemConfiguration.fproj/SCPPrivate.h b/SystemConfiguration.fproj/SCPPrivate.h
deleted file mode 100644 (file)
index 707279c..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2000 Apple Computer, 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 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.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef _SCPPRIVATE_H
-#define _SCPPRIVATE_H
-
-#include <SystemConfiguration/SCP.h>
-#include <SystemConfiguration/SCD.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-
-#define        PREFS_DEFAULT_DIR       CFSTR("/var/db/SystemConfiguration")
-#define        PREFS_DEFAULT_CONFIG    CFSTR("preferences.xml")
-
-#define        PREFS_DEFAULT_USER_DIR  CFSTR("Library/Preferences")
-
-
-/* Define the per-preference-handle structure */
-typedef struct {
-       /* session name */
-       CFStringRef             name;
-
-       /* preferences ID */
-       CFStringRef             prefsID;
-
-       /* per-user preference info */
-       boolean_t               perUser;
-       CFStringRef             user;
-
-       /* configuration file path */
-       char                    *path;
-
-       /* configuration file signature */
-       CFDataRef               signature;
-
-       /* configd session */
-       SCDSessionRef           session;
-
-       /* configd session keys */
-       CFStringRef             sessionKeyLock;
-       CFStringRef             sessionKeyCommit;
-       CFStringRef             sessionKeyApply;
-
-       /* preferences */
-       CFMutableDictionaryRef  prefs;
-
-       /* flags */
-       boolean_t               changed;
-       boolean_t               locked;
-       boolean_t               isRoot;
-
-} SCPSessionPrivate, *SCPSessionPrivateRef;
-
-
-/* Define signature data */
-typedef struct {
-       dev_t     st_dev;               /* inode's device */
-       ino_t     st_ino;               /* inode's number */
-       struct  timespec st_mtimespec;  /* time of last data modification */
-       off_t     st_size;              /* file size, in bytes */
-} SCPSignatureData, *SCPSignatureDataRef;
-
-
-__BEGIN_DECLS
-
-CFDataRef      _SCPSignatureFromStatbuf        (const struct stat      *statBuf);
-
-char *         _SCPPrefsPath                   (CFStringRef            prefsID,
-                                                boolean_t              perUser,
-                                                CFStringRef            user);
-
-CFStringRef    _SCPNotificationKey             (CFStringRef            prefsID,
-                                                boolean_t              perUser,
-                                                CFStringRef            user,
-                                                int                    keyType);
-
-__END_DECLS
-
-#endif /* _SCPPRIVATE_H */
index a86197398ca971973c247cb98dc4116442b3c232..8532004d2e467fd147cbadf6bca8e03c07d74b40 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SCP.h>
-#include "SCPPrivate.h"
-
-#include <SystemConfiguration/SCD.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/errno.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCPreferencesInternal.h"
 
-SCPStatus
-SCPRemove(SCPSessionRef session, CFStringRef key)
+Boolean
+SCPreferencesRemoveValue(SCPreferencesRef session, CFStringRef key)
 {
-       SCPSessionPrivateRef    sessionPrivate;
+       SCPreferencesPrivateRef sessionPrivate  = (SCPreferencesPrivateRef)session;
 
-       if (session == NULL) {
-               return SCP_FAILED;           /* you can't do anything with a closed session */
-       }
-       sessionPrivate = (SCPSessionPrivateRef)session;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesRemoveValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key = %@"), key);
+
+       sessionPrivate->accessed = TRUE;
 
        if (!CFDictionaryContainsKey(sessionPrivate->prefs, key)) {
-               return SCP_NOKEY;
+               _SCErrorSet(kSCStatusNoKey);
+               return FALSE;
        }
 
        CFDictionaryRemoveValue(sessionPrivate->prefs, key);
-       sessionPrivate->changed = TRUE;
-       return SCP_OK;
+       sessionPrivate->changed  = TRUE;
+       return TRUE;
 }
index 6b875aec342400a4235c87a5e60ceb17c5482541..28d5df59a4f47345129faaf3fd831b1567ebe7fd 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SCP.h>
-#include "SCPPrivate.h"
-
-#include <SystemConfiguration/SCD.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/errno.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCPreferencesInternal.h"
 
-SCPStatus
-SCPSet(SCPSessionRef session, CFStringRef key, CFPropertyListRef data)
+Boolean
+SCPreferencesSetValue(SCPreferencesRef session, CFStringRef key, CFPropertyListRef value)
 {
-       SCPSessionPrivateRef    sessionPrivate;
+       SCPreferencesPrivateRef sessionPrivate  = (SCPreferencesPrivateRef)session;
 
-       if (session == NULL) {
-               return SCP_FAILED;           /* you can't do anything with a closed session */
-       }
-       sessionPrivate = (SCPSessionPrivateRef)session;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesSetValue:"));
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  key   = %@"), key);
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("  value = %@"), value);
 
-       CFDictionarySetValue(sessionPrivate->prefs, key, data);
-       sessionPrivate->changed = TRUE;
-       return SCP_OK;
+       CFDictionarySetValue(sessionPrivate->prefs, key, value);
+       sessionPrivate->accessed = TRUE;
+       sessionPrivate->changed  = TRUE;
+       return TRUE;
 }
index 4d808a8a7f4c4141bd49bef28043f21ad77e7693..112a459d3f878a0580e12baca7248b5357ca1a29 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SCP.h>
-#include "SCPPrivate.h"
-
-#include <SystemConfiguration/SCD.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/errno.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
 
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCPreferencesInternal.h"
 
-SCPStatus
-SCPUnlock(SCPSessionRef session)
+Boolean
+SCPreferencesUnlock(SCPreferencesRef session)
 {
-       SCPSessionPrivateRef    sessionPrivate;
-       SCDStatus               scd_status;
+       SCPreferencesPrivateRef sessionPrivate  = (SCPreferencesPrivateRef)session;
 
-       if (session == NULL) {
-               return SCP_FAILED;           /* you can't do anything with a closed session */
-       }
-       sessionPrivate = (SCPSessionPrivateRef)session;
+       SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesUnlock:"));
 
        if (!sessionPrivate->locked) {
-               return SCP_NEEDLOCK;    /* sorry, you don't have the lock */
+               /* sorry, you don't have the lock */
+               _SCErrorSet(kSCStatusNeedLock);
+               return FALSE;
        }
 
        if (!sessionPrivate->isRoot) {
                /* CONFIGD REALLY NEEDS NON-ROOT WRITE ACCESS */
-               goto notRoot;
+               goto perUser;
        }
 
-       scd_status = SCDRemove(sessionPrivate->session, sessionPrivate->sessionKeyLock);
-       if (scd_status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDRemove() failed: %s"), SCDError(scd_status));
-               return SCP_FAILED;
+       if (!SCDynamicStoreRemoveValue(sessionPrivate->session, sessionPrivate->sessionKeyLock)) {
+               SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreRemoveValue() failed"));
+               return FALSE;
        }
 
-    notRoot:
+    perUser:
 
        sessionPrivate->locked = FALSE;
-       return SCP_OK;
+       return TRUE;
 }
diff --git a/SystemConfiguration.fproj/SCPreferences.h b/SystemConfiguration.fproj/SCPreferences.h
new file mode 100644 (file)
index 0000000..854ed87
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCPREFERENCES_H
+#define _SCPREFERENCES_H
+
+
+#include <sys/cdefs.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SCDynamicStore.h>
+
+
+/*!
+       @header SCPreferences
+       The SCPreferencesXXX() APIs allow an application to load and
+       store XML configuration data in a controlled manner and provide
+       the necessary notifications to other applications that need to
+       be aware of configuration changes.
+
+       The stored XML configuration data is accessed using a prefsID. A
+       NULL value indicates that the default system preferences are to
+       be accessed.
+       A string which starts with a leading "/" character specifies the
+       path to the file containing te preferences to be accessed.
+       A string which does not start with a leading "/" character
+       specifies a file relative to the default system preferences
+       directory.
+
+       The APIs provided by this framework communicate with the "configd"
+       daemon for any tasks requiring synchronization and/or notification.
+ */
+
+
+/*!
+       @typedef SCPreferencesRef
+       @discussion This is the handle to an open "session" for
+               accessing system configuration preferences.
+ */
+typedef const struct __SCPreferences * SCPreferencesRef;
+
+
+__BEGIN_DECLS
+
+/*!
+       @function SCPreferencesGetTypeID
+       Returns the type identifier of all SCPreferences instances.
+ */
+CFTypeID
+SCPreferencesGetTypeID         (void);
+
+
+/*!
+       @function SCPreferencesCreate
+       @discussion Initiates access to the per-system set of configuration
+               preferences.
+       @param allocator ...
+       @param name A string that describes the name of the calling
+               process.
+       @param prefsID A string that identifies the name of the
+               group of preferences to be accessed/updated.
+       @result prefs A pointer to memory that will be filled with an
+               SCPreferencesRef handle to be used for all subsequent requests.
+               If a session cannot be established, the contents of
+               memory pointed to by this parameter are undefined.
+ */
+SCPreferencesRef
+SCPreferencesCreate            (
+                               CFAllocatorRef          allocator,
+                               CFStringRef             name,
+                               CFStringRef             prefsID
+                               );
+
+/*!
+       @function SCPreferencesLock
+       @discussion Locks access to the configuration preferences.
+
+       This function obtains exclusive access to the configuration
+       preferences associated with this prefsID. Clients attempting
+       to obtain exclusive access to the preferences will either receive
+       an kSCStatusPrefsBusy error or block waiting for the lock to be
+       released.
+       @param session An SCPreferencesRef handle that should be used for
+               all API calls.
+       @param wait A boolean flag indicating whether the calling process
+               should block waiting for another process to complete its update
+               operation and release its lock.
+       @result TRUE if the lock was obtained; FALSE if an error occurred.
+
+       XXXXX: old API error codes included kSCStatusPrefsBusy, kSCStatusAccessError, and kSCStatusStale
+ */
+Boolean
+SCPreferencesLock              (
+                               SCPreferencesRef        session,
+                               Boolean                 wait
+                               );
+
+/*!
+       @function SCPreferencesCommitChanges
+       @discussion Commits changes made to the configuration preferences to
+               persitent storage.
+
+               This function commits any changes to permanent storage. An
+               implicit call to SCPreferencesLock/SCPreferencesUnlock will
+               be made if exclusive access has not already been established.
+       @param session An SCPreferencesRef handle that should be used for
+               all API calls.
+       @result TRUE if the lock was obtained; FALSE if an error occurred.
+
+       XXXXX: old API error codes included kSCStatusAccessError, kSCStatusStale
+ */
+Boolean
+SCPreferencesCommitChanges     (
+                               SCPreferencesRef        session
+                               );
+
+/*!
+       @function SCPreferencesApplyChanges
+       @discussion Requests that the currently stored configuration
+               preferences be applied to the active configuration.
+       @param session An SCPreferencesRef handle that should be used for
+               all API calls.
+       @result TRUE if the lock was obtained; FALSE if an error occurred.
+ */
+Boolean
+SCPreferencesApplyChanges      (
+                               SCPreferencesRef        session
+                               );
+
+/*!
+       @function SCPreferencesUnlock
+       @discussion Releases exclusive access to the configuration preferences.
+
+               This function releases the exclusive access "lock" for this prefsID.
+               Other clients will be now be able to establish exclusive access to
+               the preferences.
+       @param session An SCPreferencesRef handle that should be used for
+               all API calls.
+       @result TRUE if the lock was obtained; FALSE if an error occurred.
+ */
+Boolean
+SCPreferencesUnlock            (
+                               SCPreferencesRef        session
+                               );
+
+/*!
+       @function SCPreferencesGetSignature
+       @discussion Returns a sequence of bytes that can be used to determine
+               if the saved configuration preferences have changed.
+       @param session An SCPreferencesRef handle that should be used for
+               all API calls.
+       @param signature A pointer to a CFDataRef that will reflect
+               the signature of the configuration preferences at the time
+               of the call to SCPreferencesCreate().
+       @result A CFDataRef that reflects the signature of the configuration
+               preferences at the time of the call to SCPreferencesCreate().
+ */
+CFDataRef
+SCPreferencesGetSignature      (
+                               SCPreferencesRef        session
+                               );
+
+/*!
+       @function SCPreferencesCopyKeyList
+       @discussion Returns an array of currently defined preference keys.
+       @param session An SCPreferencesRef handle that should be used for
+               all API calls.
+       @result The list of keys.  You must release the returned value.
+ */
+CFArrayRef
+SCPreferencesCopyKeyList       (
+                               SCPreferencesRef        session
+                               );
+
+/*!
+       @function SCPreferencesGetValue
+       @discussion Returns the data associated with a preference key.
+
+               This function retrieves data associated with a key for the prefsID.
+
+               Note:  You could read stale data and not know it, unless you
+               first call SCPreferencesLock().
+       @param session An SCPreferencesRef handle that should be used for
+               all API calls.
+       @param key The preference key to be returned.
+       @result The value associated with the specified preference key; If no
+               value was located, NULL is returned.
+ */
+CFPropertyListRef
+SCPreferencesGetValue          (
+                               SCPreferencesRef        session,
+                               CFStringRef             key
+                               );
+
+/*!
+       @function SCPreferencesAddValue
+       @discussion Adds data for a preference key.
+
+       This function associates new data with the specified key. In order
+       to commit these changes to permanent storage a call must be made to
+       SCPreferencesCommitChanges().
+       @param session The SCPreferencesRef handle that should be used to
+               communicate with the APIs.
+       @param key The preference key to be updated.
+       @param value The CFPropertyListRef object containing the
+               value to be associated with the specified preference key.
+       @result TRUE if the value was added; FALSE if the key already exists or
+               if an error occurred.
+ */
+Boolean
+SCPreferencesAddValue          (
+                               SCPreferencesRef        session,
+                               CFStringRef             key,
+                               CFPropertyListRef       value
+                               );
+
+/*!
+       @function SCPreferencesSetValue
+       @discussion Updates the data associated with a preference key.
+
+       This function adds or replaces the value associated with the
+       specified key. In order to commit these changes to permanent
+       storage a call must be made to SCPreferencesCommitChanges().
+       @param session The SCPreferencesRef handle that should be used to
+               communicate with the APIs.
+       @param key The preference key to be updated.
+       @param value The CFPropertyListRef object containing the
+               data to be associated with the specified preference key.
+       @result TRUE if the value was set; FALSE if an error occurred.
+ */
+Boolean
+SCPreferencesSetValue          (
+                               SCPreferencesRef        session,
+                               CFStringRef             key,
+                               CFPropertyListRef       value
+                               );
+
+/*!
+       @function SCPreferencesRemoveValue
+       @discussion Removes the data associated with a preference key.
+
+       This function removes the data associated with the specified
+       key. In order to commit these changes to permanent storage a
+       call must be made to SCPreferencesCommitChanges().
+       @param session The SCPreferencesRef handle that should be used to
+               communicate with the APIs.
+       @param key The preference key to be removed.
+       @result TRUE if the value was removed; FALSE if the key did not exist or
+               if an error occurred.
+ */
+Boolean
+SCPreferencesRemoveValue       (
+                               SCPreferencesRef        session,
+                               CFStringRef             key
+                               );
+
+__END_DECLS
+
+#endif /* _SCPREFERENCES_H */
diff --git a/SystemConfiguration.fproj/SCPreferencesInternal.h b/SystemConfiguration.fproj/SCPreferencesInternal.h
new file mode 100644 (file)
index 0000000..82e3aa3
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCPREFERENCESINTERNAL_H
+#define _SCPREFERENCESINTERNAL_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFRuntime.h>
+#include <SystemConfiguration/SCPreferences.h>
+#include <SystemConfiguration/SCDynamicStore.h>
+
+
+#define        PREFS_DEFAULT_DIR       CFSTR("/var/db/SystemConfiguration")
+#define        PREFS_DEFAULT_CONFIG    CFSTR("preferences.xml")
+
+#define        PREFS_DEFAULT_USER_DIR  CFSTR("Library/Preferences")
+
+
+/* Define the per-preference-handle structure */
+typedef struct {
+
+       /* base CFType information */
+       CFRuntimeBase           cfBase;
+
+       /* session name */
+       CFStringRef             name;
+
+       /* preferences ID */
+       CFStringRef             prefsID;
+
+       /* per-user preference info */
+       Boolean                 perUser;
+       CFStringRef             user;
+
+       /* configuration file path */
+       char                    *path;
+
+       /* configuration file signature */
+       CFDataRef               signature;
+
+       /* configd session */
+       SCDynamicStoreRef       session;
+
+       /* configd session keys */
+       CFStringRef             sessionKeyLock;
+       CFStringRef             sessionKeyCommit;
+       CFStringRef             sessionKeyApply;
+
+       /* preferences */
+       CFMutableDictionaryRef  prefs;
+
+       /* flags */
+       Boolean                 accessed;
+       Boolean                 changed;
+       Boolean                 locked;
+       Boolean                 isRoot;
+
+} SCPreferencesPrivate, *SCPreferencesPrivateRef;
+
+
+/* Define signature data */
+typedef struct {
+       dev_t                   st_dev;         /* inode's device */
+       ino_t                   st_ino;         /* inode's number */
+       struct  timespec        st_mtimespec;   /* time of last data modification */
+       off_t                   st_size;        /* file size, in bytes */
+} SCPSignatureData, *SCPSignatureDataRef;
+
+
+__BEGIN_DECLS
+
+SCPreferencesRef
+__SCPreferencesCreate                  (CFAllocatorRef         allocator,
+                                        CFStringRef            name,
+                                        CFStringRef            prefsID,
+                                        Boolean                perUser,
+                                        CFStringRef            user);
+
+CFDataRef
+__SCPSignatureFromStatbuf              (const struct stat      *statBuf);
+
+char *
+__SCPreferencesPath                    (CFAllocatorRef         allocator,
+                                        CFStringRef            prefsID,
+                                        Boolean                perUser,
+                                        CFStringRef            user);
+
+CFStringRef
+_SCPNotificationKey                    (CFAllocatorRef         allocator,
+                                        CFStringRef            prefsID,
+                                        Boolean                perUser,
+                                        CFStringRef            user,
+                                        int                    keyType);
+
+__END_DECLS
+
+#endif /* _SCPREFERENCESINTERNAL_H */
diff --git a/SystemConfiguration.fproj/SCPreferencesPath.h b/SystemConfiguration.fproj/SCPreferencesPath.h
new file mode 100644 (file)
index 0000000..3cf71dd
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCPREFERENCESPATH_H
+#define _SCPREFERENCESPATH_H
+
+#include <sys/cdefs.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SCPreferences.h>
+
+
+/*!
+       @header SCPreferencesPath
+       The SCPreferencesPathXXX() APIs allow an application to
+       load and store XML configuration data in a controlled
+       manner and provide the necessary notifications to other
+       applications that need to be aware of configuration
+       changes.
+
+       The SCPreferencesPathXXX() APIs make certain assumptions
+       about the layout of the preferences data.  These APIs view
+       the data as a collection of dictionaries of key/value pairs
+       and an associated path name.  The root path ("/") identifies
+       the top-level dictionary.  Additional path components
+       specify the keys for sub-dictionaries.
+
+       For example, the following dictionary can be accessed via
+       two paths.  The root ("/") path would return a dictionary
+       with all keys and values.  The path "/path1" would only
+       return the dictionary with the "key3" and "key4" properties.
+
+       <PRE>
+       <BR>    &lt;dict&gt;
+       <BR>        &lt;key&gt;key1&lt;/key&gt;
+       <BR>        &lt;string&gt;val1&lt;/string&gt;
+       <BR>        &lt;key&gt;key2&lt;/key&gt;
+       <BR>        &lt;string&gt;val2&lt;/string&gt;
+       <BR>        &lt;key&gt;path1&lt;/key&gt;
+       <BR>        &lt;dict&gt;
+       <BR>            &lt;key&gt;key3&lt;/key&gt;
+       <BR>            &lt;string&gt;val3&lt;/string&gt;
+       <BR>        &lt;key&gt;key4&lt;/key&gt;
+       <BR>        &lt;string&gt;val4&lt;/string&gt;
+       <BR>        &lt;/dict&gt;
+       <BR>    &lt;/dict&gt;
+       </PRE>
+
+       Each dictionary can also include the kSCResvLink key.  The
+       value associated with this key is interpreted as a "link" to
+       another path.  If this key is present, a call to the
+       SCPreferencesPathGetValue() API will return the dictionary
+       specified by the link.
+
+       The APIs provided by this framework communicate with the "configd"
+       daemon for any tasks requiring synchronization and/or notification.
+ */
+
+
+__BEGIN_DECLS
+
+/*!
+       @function SCPreferencesPathCreateUniqueChild
+       @discussion Creates a new path component within the dictionary
+               hierarchy.
+       @param session The SCPreferencesRef handle that should be used to
+        communicate with the APIs.
+       @param prefix A string that represents the parent path.
+       @param newPath A pointer to memory that will be filled with a
+               string representing the new child path.
+       @result A string representing the new (unique) child path; NULL
+               if the specified path does not exist.
+ */
+CFStringRef
+SCPreferencesPathCreateUniqueChild     (
+                                       SCPreferencesRef        session,
+                                       CFStringRef             prefix
+                                       );
+
+/*!
+       @function SCPreferencesPathGetValue
+       @discussion Returns the dictionary associated with the specified
+               path.
+       @param session The SCPreferencesRef handle that should be used to
+               communicate with the APIs.
+       @param path A string that represents the path to be returned.
+       @result The dictionary associated with the specified path; NULL
+               if the path does not exist.
+ */
+CFDictionaryRef
+SCPreferencesPathGetValue              (
+                                       SCPreferencesRef        session,
+                                       CFStringRef             path
+                                       );
+
+/*!
+       @function SCPreferencesPathGetLink
+       @discussion Returns the link (if one exists) associated with the
+               specified path.
+       @param session The SCPreferencesRef handle that should be used to
+        communicate with the APIs.
+       @param path A string that represents the path to be returned.
+       @result The dictionary associated with the specified path; NULL
+               if the path is not a link or does not exist.
+ */
+CFStringRef
+SCPreferencesPathGetLink               (
+                                       SCPreferencesRef        session,
+                                       CFStringRef             path
+                                       );
+
+/*!
+       @function SCPreferencesPathSetValue
+       @discussion Associates a dictionary with the specified path.
+       @param session The SCPreferencesRef handle that should be used to
+        communicate with the APIs.
+       @param path A string that represents the path to be updated.
+       @param value A dictionary that represents the data to be
+               stored at the specified path.
+       @result A boolean indicating the success (or failure) of the call.
+ */
+Boolean
+SCPreferencesPathSetValue              (
+                                       SCPreferencesRef        session,
+                                       CFStringRef             path,
+                                       CFDictionaryRef         value
+                                       );
+
+/*!
+       @function SCPreferencesPathSetLink
+       @discussion Associates a link to a second dictionary at the
+               specified path.
+       @param session The SCPreferencesRef handle that should be used to
+               communicate with the APIs.
+       @param path A string that represents the path to be updated.
+       @param link A string that represents the link to be stored
+               at the specified path.
+       @result A boolean indicating the success (or failure) of the call.
+ */
+Boolean
+SCPreferencesPathSetLink               (
+                                       SCPreferencesRef        session,
+                                       CFStringRef             path,
+                                       CFStringRef             link
+                                       );
+
+/*!
+       @function SCPreferencesPathRemoveValue
+       @discussion Removes the data associated with the specified path.
+       @param session The SCPreferencesRef handle that should be used to
+        communicate with the APIs.
+       @param path A string that represents the path to be returned.
+       @result A boolean indicating the success (or failure) of the call.
+ */
+Boolean
+SCPreferencesPathRemoveValue           (
+                                       SCPreferencesRef        session,
+                                       CFStringRef             path
+                                       );
+
+__END_DECLS
+
+#endif /* _SCPREFERENCESPATH_H */
diff --git a/SystemConfiguration.fproj/SCPreferencesPrivate.h b/SystemConfiguration.fproj/SCPreferencesPrivate.h
new file mode 100644 (file)
index 0000000..5ee8c21
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCPREFERENCESPRIVATE_H
+#define _SCPREFERENCESPRIVATE_H
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SCPreferences.h>
+
+
+/*!
+       @enum SCPreferencesKeyType
+       @discussion Used with the SCDynamicStoreKeyCreatePreferences() function
+               to describe the resulting CFStringRef argument.
+       @constant kSCPreferencesKeyLock Key used when exclusive access to the
+               stored preferences is obtained or released.
+       @constant kSCPreferencesKeyCommit Key used when new preferences are
+               committed to the store
+       @constant kSCPreferencesKeyApply Key used when new preferences are
+               to be applied to the active system configuration.
+ */
+typedef enum {
+       kSCPreferencesKeyLock   = 1,
+       kSCPreferencesKeyCommit = 2,
+       kSCPreferencesKeyApply  = 3,
+} SCPreferencesKeyType;
+
+
+__BEGIN_DECLS
+
+/*!
+       @function SCDynamicStoreKeyCreatePreferences
+       @discussion Creates a key that can be used by the SCDynamicStoreSetNotificationKeys()
+               function to receive notifications of changes to the saved
+               preferences.
+       @param allocator ...
+       @param prefsID A string that identifies the name of the
+               group of preferences to be accessed/updated.
+       @param keyType A kSCPreferencesKeyType indicating the type a notification
+               key to be returned.
+       @result A notification string for the specified preference identifier.
+ */
+CFStringRef
+SCDynamicStoreKeyCreatePreferences     (CFAllocatorRef         allocator,
+                                        CFStringRef            prefsID,
+                                        int                    keyType);
+
+SCPreferencesRef
+SCUserPreferencesCreate                        (CFAllocatorRef         allocator,
+                                        CFStringRef            name,
+                                        CFStringRef            prefsID,
+                                        CFStringRef            user);
+
+CFStringRef
+SCDynamicStoreKeyCreateUserPreferences (CFAllocatorRef         allocator,
+                                        CFStringRef            prefsID,
+                                        CFStringRef            user,
+                                        int                    keyType);
+
+__END_DECLS
+
+#endif /* _SCPREFERENCESPRIVATE_H */
diff --git a/SystemConfiguration.fproj/SCPreferencesSetSpecific.h b/SystemConfiguration.fproj/SCPreferencesSetSpecific.h
new file mode 100644 (file)
index 0000000..a0a6b3d
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCPREFERENCESSETSPECIFIC_H
+#define _SCPREFERENCESSETSPECIFIC_H
+
+#include <sys/cdefs.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SCPreferences.h>
+
+
+/*!
+       @header SCPreferencesSetSpecific
+       The following APIs allow an application to set specific
+       configuration information about the current system (e.g. the
+       computer/sharing name).
+ */
+
+
+__BEGIN_DECLS
+
+/*!
+       @function SCPreferencesSetComputerName
+       @discussion Updates the computer/host name in the system preferences.
+
+       Note: In order to commit these changes to permanent storage a call
+       must be made to SCPreferencesCommitChanges().
+       @param prefs An SCPreferencesRef that should be used for all API calls.
+       @param name The computer/host name to be set.
+       @param nameEncoding The encoding associated with the computer/host name.
+       @result A boolean indicating the success (or failure) of the call.
+ */
+Boolean
+SCPreferencesSetComputerName           (
+                                       SCPreferencesRef        prefs,
+                                       CFStringRef             name,
+                                       CFStringEncoding        nameEncoding
+                                       );
+
+__END_DECLS
+
+#endif /* _SCPREFERENCESSETSPECIFIC_H */
diff --git a/SystemConfiguration.fproj/SCPrivate.h b/SystemConfiguration.fproj/SCPrivate.h
new file mode 100644 (file)
index 0000000..57f2e62
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCPRIVATE_H
+#define _SCPRIVATE_H
+
+#include <sys/cdefs.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#include <SystemConfiguration/SCDynamicStorePrivate.h>
+#include <SystemConfiguration/SCDynamicStoreSetSpecificPrivate.h>
+
+#include <SystemConfiguration/SCPreferencesPrivate.h>
+
+/* framework variables */
+extern Boolean _sc_debug;      /* TRUE if debugging enabled */
+extern Boolean _sc_verbose;    /* TRUE if verbose logging enabled */
+extern Boolean _sc_log;        /* TRUE if SCLog() output goes to syslog */
+
+__BEGIN_DECLS
+
+/*!
+       @function _SCErrorSet
+       @discussion Returns a last SystemConfiguration.framework API error code.
+       @result The last error encountered.
+ */
+void           _SCErrorSet                     (int                    error);
+
+/*
+       @function SCLog
+       @discussion Conditionally issue a log message.
+       @param condition A boolean value indicating if the message should be logged
+       @param level A syslog(3) logging priority.
+       @param formatString The format string
+       @result The specified message will be written to the system message
+               logger (See syslogd(8)).
+ */
+void           SCLog                           (Boolean                condition,
+                                                int                    level,
+                                                CFStringRef            formatString,
+                                                ...);
+
+/*
+       @function SCPrint
+       @discussion Conditionally issue a debug message.
+       @param condition A boolean value indicating if the message should be written
+       @param stream The output stream for the log message.
+       @param formatString The format string
+       @result The specified message will be written to the specified output
+               stream.
+ */
+void           SCPrint                         (Boolean                condition,
+                                                FILE                   *stream,
+                                                CFStringRef            formatString,
+                                                ...);
+
+__END_DECLS
+
+#endif /* _SCPRIVATE_H */
diff --git a/SystemConfiguration.fproj/SCProxies.c b/SystemConfiguration.fproj/SCProxies.c
new file mode 100644 (file)
index 0000000..d31c826
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Modification History
+ *
+ * May 18, 2001                        Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include <SystemConfiguration/SCValidation.h>
+
+CFStringRef
+SCDynamicStoreKeyCreateProxies(CFAllocatorRef allocator)
+{
+       return SCDynamicStoreKeyCreateNetworkGlobalEntity(allocator,
+                                                         kSCDynamicStoreDomainState,
+                                                         kSCEntNetProxies);
+}
+
+
+CFDictionaryRef
+SCDynamicStoreCopyProxies(SCDynamicStoreRef store)
+{
+       CFDictionaryRef         dict            = NULL;
+       CFStringRef             key;
+       SCDynamicStoreRef       mySession       = store;
+       CFDictionaryRef         proxies         = NULL;
+
+       if (!store) {
+               mySession = SCDynamicStoreCreate(NULL,
+                                                CFSTR("SCDynamicStoreCopyConsoleUser"),
+                                                NULL,
+                                                NULL);
+               if (!mySession) {
+                       SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+                       return NULL;
+               }
+       }
+
+       key  = SCDynamicStoreKeyCreateProxies(NULL);
+       dict = SCDynamicStoreCopyValue(mySession, key);
+       CFRelease(key);
+       if (!isA_CFDictionary(dict)) {
+               _SCErrorSet(kSCStatusNoKey);
+               goto done;
+       }
+
+       proxies = CFRetain(dict);
+
+    done :
+
+       if (!store && mySession)        CFRelease(mySession);
+       if (dict)                       CFRelease(dict);
+       return proxies;
+}
diff --git a/SystemConfiguration.fproj/SCValidation.h b/SystemConfiguration.fproj/SCValidation.h
new file mode 100644 (file)
index 0000000..09f1aaf
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2001 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCVALIDATION_H
+#define _SCVALIDATION_H
+
+#include <sys/cdefs.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+__BEGIN_DECLS
+
+static __inline__ CFTypeRef
+isA_CFType(CFTypeRef obj, CFTypeID type)
+{
+       if (obj == NULL)
+               return (NULL);
+
+       if (CFGetTypeID(obj) != type)
+               return (NULL);
+
+       return (obj);
+}
+
+static __inline__ CFTypeRef
+isA_CFArray(CFTypeRef obj)
+{
+       return (isA_CFType(obj, CFArrayGetTypeID()));
+}
+
+static __inline__ CFTypeRef
+isA_CFBoolean(CFTypeRef obj)
+{
+       return (isA_CFType(obj, CFBooleanGetTypeID()));
+}
+
+static __inline__ CFTypeRef
+isA_CFData(CFTypeRef obj)
+{
+       return (isA_CFType(obj, CFDataGetTypeID()));
+}
+
+static __inline__ CFTypeRef
+isA_CFDate(CFTypeRef obj)
+{
+       return (isA_CFType(obj, CFDateGetTypeID()));
+}
+
+static __inline__ CFTypeRef
+isA_CFDictionary(CFTypeRef obj)
+{
+       return (isA_CFType(obj, CFDictionaryGetTypeID()));
+}
+
+static __inline__ CFTypeRef
+isA_CFNumber(CFTypeRef obj)
+{
+       return (isA_CFType(obj, CFNumberGetTypeID()));
+}
+
+static __inline__ CFTypeRef
+isA_CFPropertyList(CFTypeRef obj)
+{
+       CFTypeID        type;
+
+       if (obj == NULL)
+               return (NULL);
+
+       type = CFGetTypeID(obj);
+       if (type == CFArrayGetTypeID()          ||
+           type == CFBooleanGetTypeID()        ||
+           type == CFDataGetTypeID()           ||
+           type == CFDateGetTypeID()           ||
+           type == CFDictionaryGetTypeID()     ||
+           type == CFNumberGetTypeID()         ||
+           type == CFStringGetTypeID())
+               return (obj);
+
+       return (NULL);
+}
+
+
+static __inline__ CFTypeRef
+isA_CFString(CFTypeRef obj)
+{
+       return (isA_CFType(obj, CFStringGetTypeID()));
+}
+
+__END_DECLS
+
+#endif /* _SCVALIDATION_H */
+
index 9d4ef22fb2798fc5898dee87c726dea41a19a170..13b85037f13391d6b3e3dadab9ae44cf896360de 100644 (file)
 #ifndef _SYSTEMCONFIGURATION_H
 #define _SYSTEMCONFIGURATION_H
 
+#include <sys/cdefs.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+
 /*!
        @header SystemConfiguration.h
-       The SystemConfiguration framework provides access to the data used to configure a running system.  The APIs provided by this framework communicate with the "configd" daemon.
+       The SystemConfiguration framework provides access to the
+       data used to configure a running system.  The APIs provided
+       by this framework communicate with the "configd" daemon.
 
-The "configd" daemon manages a "cache" reflecting the desired configuration settings as well as the current state of the system.  The daemon provides a notification mechanism for user-level processes which need to be aware of changes made to the "cache" data.  Lastly, the daemon loads a number of bundles(or plug-ins) which monitor low-level kernel events and, via a set of policy modules, keep this cached data up to date.
+       The "configd" daemon manages a "dynamic store" reflecting the
+       desired configuration settings as well as the current state
+       of the system.  The daemon provides a notification mechanism
+       for user-level processes which need to be aware of changes
+       made to the data.  Lastly, the daemon loads a number of
+       bundles (or plug-ins) that monitor low-level kernel events
+       and, via a set of policy modules, keep the state data up
+       to date.
+ */
 
-The "configd" daemon also provides an address space/task/process which can be used by other CFRunLoop based functions which would otherwise require their own process/daemon for execution.
+/*!
+       @enum
+       @discussion Returned status codes.
+
+       @constant kSCStatusOK                   Success
+       @constant kSCStatusFailed               Non-specific Failure
+       @constant kSCStatusInvalidArgument      Invalid argument
+       @constant kSCStatusAccessError          Permission denied
+       @constant kSCStatusNoKey                No such key
+       @constant kSCStatusKeyExists            Data associated with key already defined
+       @constant kSCStatusLocked               Lock already held
+       @constant kSCStatusNeedLock             Lock required for this operation
+
+       @constant kSCStatusNoStoreSession       Configuration daemon session not active
+       @constant kSCStatusNoStoreServer        Configuration daemon not (no longer) available
+       @constant kSCStatusNotifierActive       Notifier is currently active
+
+       @constant kSCStatusNoPrefsSession       Preference session not active
+       @constant kSCStatusPrefsBusy            Preferences update currently in progress
+       @constant kSCStatusNoConfigFile         Configuration file not found
+       @constant kSCStatusNoLink               No such link
+       @constant kSCStatusStale                Write attempted on stale version of object
+
+       @constant kSCStatusReachabilityUnknown
+               A determination could not be made regarding the reachability
+               of the specified nodename/address.
+*/
+enum {
+       /*
+        * Generic status codes
+        */
+       kSCStatusOK                             = 0,    /* Success */
+       kSCStatusFailed                         = 1001, /* Non-specific failure */
+       kSCStatusInvalidArgument                = 1002, /* Invalid argument */
+       kSCStatusAccessError                    = 1003, /* Permission denied
+                                                          - must be root to obtain lock
+                                                          - could not create access/create preferences
+                                                        */
+       kSCStatusNoKey                          = 1004, /* No such key */
+       kSCStatusKeyExists                      = 1005, /* Key already defined */
+       kSCStatusLocked                         = 1006, /* Lock already held */
+       kSCStatusNeedLock                       = 1007, /* Lock required for this operation */
+       /*
+        * SCDynamicStore status codes
+        */
+       kSCStatusNoStoreSession                 = 2001, /* Configuration daemon session not active */
+       kSCStatusNoStoreServer                  = 2002, /* Configuration daemon not (no longer) available */
+       kSCStatusNotifierActive                 = 2003, /* Notifier is currently active */
+       /*
+        * SCPreferences status codes
+        */
+       kSCStatusNoPrefsSession                 = 3001, /* Preference session not active */
+       kSCStatusPrefsBusy                      = 3002, /* Preferences update currently in progress */
+       kSCStatusNoConfigFile                   = 3003, /* Configuration file not found */
+       kSCStatusNoLink                         = 3004, /* No such link */
+       kSCStatusStale                          = 3005, /* Write attempted on stale version of object */
+       /*
+        * SCNetwork status codes
+        */
+       kSCStatusReachabilityUnknown            = 4001, /* Network reachability cannot be determined */
+};
 
- */
 
-/* cache access APIs */
-#include <SystemConfiguration/SCD.h>
-#include <SystemConfiguration/SCDKeys.h>
+/* store access APIs */
+#include <SystemConfiguration/SCDynamicStore.h>
+#include <SystemConfiguration/SCDynamicStoreKey.h>
+#include <SystemConfiguration/SCDynamicStoreCopySpecific.h>
 
 /* preference access APIs */
-#include <SystemConfiguration/SCP.h>
-#include <SystemConfiguration/SCPPath.h>
 #include <SystemConfiguration/SCPreferences.h>
+#include <SystemConfiguration/SCPreferencesPath.h>
 
-/* "console user" APIs */
-#include <SystemConfiguration/SCDConsoleUser.h>
-
-/* "computer/host name" APIs */
-#include <SystemConfiguration/SCDHostName.h>
+/* store and preference scheme definitions */
+#include <SystemConfiguration/SCSchemaDefinitions.h>
 
 /* "network reachability" APIs */
 #include <SystemConfiguration/SCNetwork.h>
 
+__BEGIN_DECLS
+
+/*!
+       @function SCError
+       @discussion Returns a last SystemConfiguration.framework API error code.
+       @result The last error encountered.
+ */
+int    SCError                         ();
+
+/*!
+       @function SCErrorString
+       @discussion Returns a pointer to the error message string associated
+               with the specified status.
+       @param status The SCDynamicStoreStatus to be returned.
+       @result The error message string.
+ */
+const char *   SCErrorString           (int    status);
+
+__END_DECLS
+
 #endif /* _SYSTEMCONFIGURATION_H */
index 7449dead71c60e97cf785790f5520e5654af8823..af98b56d54e6d4ba74bc57f4f032993c35cd83cb 100644 (file)
  * @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 <mach/std_types.defs>
 #include <mach/mach_types.defs>
 
@@ -73,12 +83,12 @@ routine configunlock        (       server          : mach_port_t;
        skip;   /* reserved for future use */
 
 /*
- * Cache access API's
+ * Dynamic store access API's
  */
 
 routine configlist     (       server          : mach_port_t;
                                xmlData         : xmlData;
-                               regexOptions    : int;
+                               isRegex         : int;
                         out    list            : xmlDataOut, dealloc;
                         out    status          : int);
 
@@ -115,9 +125,21 @@ routine configadd_s        (       server          : mach_port_t;
                         out    newInstance     : int;
                         out    status          : int);
 
-       skip;   /* reserved for future use */
-       skip;   /* reserved for future use */
-       skip;   /* reserved for future use */
+routine confignotify   (       server          : mach_port_t;
+                               key             : xmlData;
+                        out    status          : int);
+
+routine configget_m    (       server          : mach_port_t;
+                               keys            : xmlData;
+                               patterns        : xmlData;
+                        out    data            : xmlDataOut, dealloc;
+                        out    status          : int);
+
+routine configset_m    (       server          : mach_port_t;
+                               data            : xmlData;
+                               remove          : xmlData;
+                               notify          : xmlData;
+                        out    status          : int);
 
 /*
  * Notification API's
@@ -125,12 +147,12 @@ routine configadd_s       (       server          : mach_port_t;
 
 routine notifyadd      (       server          : mach_port_t;
                                key             : xmlData;
-                               regexOptions    : int;
+                               isRegex         : int;
                         out    status          : int);
 
 routine notifyremove   (       server          : mach_port_t;
                                key             : xmlData;
-                               regexOptions    : int;
+                               isRegex         : int;
                         out    status          : int);
 
 routine notifychanges  (       server          : mach_port_t;
index 78bc8e46f88bae688050f2701db0cd9a5ba97e18..c4eb32f735df336ed420ba346a060be6ba78659d 100644 (file)
 
 /*
  * Modification History
- * 3 Nov 2000  Dieter Siegmund (dieter@apple)
- *             - created
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * 27 Apr 2001                 Allan Nathanson (ajn@apple.com)
+ * - switch from "extern const CFStringRef ..." to "#define ..."
+ *
+ * 3 Nov 2000                  Dieter Siegmund (dieter@apple)
+ * - created
  */
 #include <stdio.h>
 #include <stdlib.h>
@@ -61,68 +68,90 @@ char copyright_string[] =
 " */\n";
 
 
-#define REGULAR                0
-#define COMMENT                1
-#define END            2
-
-#define STRING_MACRO_NAME      "STRING_DECL"
-
-#define KEY_PREFIX     "kSC"
-
-#define CACHE          "Cache"
-#define COMP           "Comp"
-#define PREF           "Pref"
-#define PROP           "Prop"
-#define PATH           "Path"
-#define NETENT         "EntNet"
-#define NETPROP                "PropNet"
-#define NETVAL         "ValNet"
-#define SETUPENT       "EntSetup"
-#define SETUPPROP      "PropSetup"
-#define SYSTEMENT      "EntSystem"
-#define SYSTEMPROP     "PropSystem"
-#define RESV           "Resv"
-#define USERSENT       "EntUsers"
-#define USERSPROP      "PropUsers"
-
-#define CFNUMBER       "CFNumber"
-#define CFSTRING       "CFString"
-#define CFNUMBER_BOOL  "CFNumber (0 or 1)"
-#define CFARRAY_CFSTRING "CFArray[CFString]"
+typedef enum {
+       COMMENT,
+       OBSOLETE,
+       REGULAR,
+       DEFINE ,
+       FUTURE,
+       END
+} controlType;
+
+#define KEY_PREFIX             "kSC"
+
+#define COMP                   "Comp"
+#define DYNAMICSTORE           "DynamicStore"
+#define PREF                   "Pref"
+#define PROP                   "Prop"
+#define PATH                   "Path"
+#define NETENT                 "EntNet"
+#define NETPROP                        "PropNet"
+#define NETVAL                 "ValNet"
+#define SETUPENT               "EntSetup"
+#define SETUPPROP              "PropSetup"
+#define SYSTEMENT              "EntSystem"
+#define SYSTEMPROP             "PropSystem"
+#define RESV                   "Resv"
+#define USERSENT               "EntUsers"
+#define USERSPROP              "PropUsers"
+#define VERSION                        "Version"
+
+#define CFARRAY_CFNUMBER       "CFArray[CFNumber]"
+#define CFARRAY_CFSTRING       "CFArray[CFString]"
+#define CFBOOLEAN              "CFBoolean"
+#define CFDICTIONARY           "CFDictionary"
+#define CFNUMBER               "CFNumber"
+#define CFNUMBER_BOOL          "CFNumber (0 or 1)"
+#define CFSTRING               "CFString"
 
 #define ACTIVE                 "Active"
 #define ADDRESSES              "Addresses"
 #define AIRPORT                        "AirPort"
 #define ALERT                  "Alert"
+#define ALTERNATEREMOTEADDRESS "AlternateRemoteAddress"
 #define ANYREGEX               "AnyRegex"
-#define AUTOMATIC              "Automatic"
 #define APPLETALK              "AppleTalk"
 #define AUTH                   "Auth"
+#define AUTOMATIC              "Automatic"
 #define BINDINGMETHODS         "BindingMethods"
 #define BOOTP                  "BOOTP"
 #define BROADCAST              "Broadcast"
 #define BROADCASTADDRESSES     "BroadcastAddresses"
 #define BROADCASTSERVERTAG     "BroadcastServerTag"
+#define CHAP                   "CHAP"
 #define COMM                   "Comm"
-#define COMPONENTSEPARATOR     "ComponentSeparator"
+#define COMPRESSIONACFIELD     "CompressionACField"
+#define COMPRESSIONPFIELD      "CompressionPField"
+#define COMPRESSIONVJ          "CompressionVJ"
 #define COMPUTERNAME           "ComputerName"
 #define CONFIGMETHOD           "ConfigMethod"
+#define CONNECTDELAY           "ConnectDelay"
+#define CONNECTIONSCRIPT       "ConnectionScript"
 #define CONSOLEUSER            "ConsoleUser"
 #define CURRENTSET             "CurrentSet"
+#define DATACOMPRESSION                "DataCompression"
 #define DEFAULTSERVERTAG       "DefaultServerTag"
 #define DEFAULTZONE            "DefaultZone"
 #define DESTADDRESSES          "DestAddresses"
+#define DEVICENAME             "DeviceName"
 #define DHCP                   "DHCP"
 #define DHCPCLIENTID           "DHCPClientID"
-#define DEVICENAME             "DeviceName"
 #define DIALMODE               "DialMode"
+#define DIALONDEMAND           "DialOnDemand"
+#define DISCONNECTONIDLE       "DisconnectOnIdle"
+#define DISCONNECTONIDLETIMER  "DisconnectOnIdleTimer"
+#define DISCONNECTONLOGOUT     "DisconnectOnLogout"
+#define DISPLAYTERMINALWINDOW  "DisplayTerminalWindow"
 #define DNS                    "DNS"
 #define DOMAIN                         "Domain"
 #define DOMAINNAME             "DomainName"
 #define DOMAINSEPARATOR                "DomainSeparator"
-#define DUPLEX                 "Duplex"
+#define ECHOENABLED            "EchoEnabled"
+#define ECHOFAILURE            "EchoFailure"
+#define ECHOINTERVAL           "EchoInterval"
 #define ENCODING               "Encoding"
 #define ENCRYPTION             "Encryption"
+#define ERRORCORRECTION                "ErrorCorrection"
 #define ETHERNET               "Ethernet"
 #define EXCEPTIONSLIST         "ExceptionsList"
 #define FILE                   "File"
@@ -139,10 +168,16 @@ char copyright_string[] =
 #define HTTPENABLE             "HTTPEnable"
 #define HTTPPORT               "HTTPPort"
 #define HTTPPROXY              "HTTPProxy"
+#define HTTPSENABLE            "HTTPSEnable"
+#define HTTPSPORT              "HTTPSPort"
+#define HTTPSPROXY             "HTTPSProxy"
+#define IDLEREMINDER           "IdleReminder"
+#define IDLEREMINDERTIMER      "IdleReminderTimer"
+#define IGNOREDIALTONE         "IgnoreDialTone"
 #define INACTIVE               "Inactive"
-#define INCLUDEPRIVATENETS     "IncludePrivateNets"
 #define INFORM                 "INFORM"
 #define INTERFACE              "Interface"
+#define INTERFACENAME          "InterfaceName"
 #define INTERFACES             "Interfaces"
 #define IPCP                   "IPCP"
 #define IPV4                   "IPv4"
@@ -150,29 +185,41 @@ char copyright_string[] =
 #define LASTUPDATED            "LastUpdated"
 #define LCP                    "LCP"
 #define LINK                   "Link"
+#define LOGFILE                        "Logfile"
 #define MACADDRESS             "MACAddress"
 #define MANUAL                 "Manual"
 #define MEDIA                  "Media"
 #define MODEM                  "Modem"
+#define MRU                    "MRU"
+#define MTU                    "MTU"
 #define NAME                   "Name"
 #define NETINFO                        "NetInfo"
 #define NETWORK                        "Network"
-#define NETWORKSERVICES                "NetworkServices"
 #define NETWORKID              "NetworkID"
+#define NETWORKSERVICES                "NetworkServices"
 #define NIS                    "NIS"
 #define NODE                   "Node"
 #define NODEID                 "NodeID"
+#define PAP                    "PAP"
 #define PASSWORD               "Password"
 #define PLUGIN                 "Plugin"
-#define PORTNAME               "PortName"
+#define POWERENABLED           "PowerEnabled"
 #define PPP                    "PPP"
 #define PPPOE                  "PPPoE"
-#define PPPSERIAL              "PPPSerial"
 #define PPPOVERRIDEPRIMARY     "PPPOverridePrimary"
+#define PPPSERIAL              "PPPSerial"
+#define PREFERREDNETWORK       "PreferredNetwork"
 #define PREFS                  "Prefs"
 #define PRIMARYINTERFACE       "PrimaryInterface"
+#define PRIMARYSERVICE         "PrimaryService"
 #define PROTOCOL               "Protocol"
 #define PROXIES                        "Proxies"
+#define PULSEDIAL              "PulseDial"
+#define RECEIVEACCM            "ReceiveACCM"
+#define REDIALCOUNT            "RedialCount"
+#define REDIALENABLED          "RedialEnabled"
+#define REDIALINTERVAL         "RedialInterval"
+#define REMOTEADDRESS          "RemoteAddress"
 #define ROOTSEPARATOR          "RootSeparator"
 #define ROUTER                 "Router"
 #define RTSPENABLE             "RTSPEnable"
@@ -182,26 +229,32 @@ char copyright_string[] =
 #define SEEDNETWORKRANGE       "SeedNetworkRange"
 #define SEEDROUTER             "SeedRouter"
 #define SEEDZONES              "SeedZones"
-#define SERVICE                        "Service"
 #define SERVERADDRESSES                "ServerAddresses"
 #define SERVERTAGS             "ServerTags"
-#define SERVICEORDER           "ServiceOrder"
+#define SERVICE                        "Service"
 #define SERVICEIDS             "ServiceIDs"
+#define SERVICEORDER           "ServiceOrder"
+#define SESSIONTIMER           "SessionTimer"
 #define SETS                   "Sets"
 #define SETUP                  "Setup"
-#define SPEED                  "Speed"
-#define STATE                  "State"
 #define SOCKSENABLE            "SOCKSEnable"
 #define SOCKSPORT              "SOCKSPort"
 #define SOCKSPROXY             "SOCKSProxy"
+#define SORTLIST               "SortList"
+#define SPEAKER                        "Speaker"
+#define SPEED                  "Speed"
+#define STATE                  "State"
 #define SUBNETMASKS            "SubnetMasks"
 #define SUBTYPE                        "SubType"
 #define SYSTEM                 "System"
+#define TERMINALSCRIPT         "TerminalScript"
+#define TRANSMITACCM           "TransmitACCM"
 #define TYPE                   "Type"
 #define UID                    "UID"
-#define USERS                  "Users"
 #define USERDEFINEDNAME                "UserDefinedName"
+#define USERS                  "Users"
 #define VERBOSELOGGING         "VerboseLogging"
+#define WAITFORDIALTONE                "WaitForDialTone"
 
 struct {
     int                                control;
@@ -216,16 +269,17 @@ struct {
     { COMMENT, "", NULL, NULL, NULL },
 
     { COMMENT, "/*\n * Generic Keys\n */", NULL },
+    { DEFINE , PROP, INTERFACENAME, NULL, CFSTRING },
     { REGULAR, PROP, MACADDRESS, NULL, CFSTRING },
     { REGULAR, PROP, USERDEFINEDNAME, NULL, CFSTRING },
+    { DEFINE , PROP, VERSION, NULL, CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
 
     { COMMENT, "/*\n * Preference Keys\n */", NULL },
-    { REGULAR, PREF, CURRENTSET, NULL, NULL },
-    { REGULAR, PREF, HARDWARE, NULL, NULL },
-    { REGULAR, PREF, NETWORKSERVICES, NULL, NULL },
-    { REGULAR, PREF, SETS, NULL, NULL },
-    { REGULAR, PREF, SYSTEM, NULL, NULL },
+    { REGULAR, PREF, CURRENTSET, NULL, CFSTRING },
+    { REGULAR, PREF, NETWORKSERVICES, NULL, CFDICTIONARY },
+    { REGULAR, PREF, SETS, NULL, CFDICTIONARY },
+    { REGULAR, PREF, SYSTEM, NULL, CFDICTIONARY },
     { COMMENT, "", NULL, NULL, NULL },
 
     { COMMENT, "/*\n * Component Keys\n */", NULL },
@@ -234,7 +288,7 @@ struct {
     { REGULAR, COMP, GLOBAL, NULL, NULL },
     { REGULAR, COMP, INTERFACE, NULL, NULL },
     { REGULAR, COMP, SYSTEM, NULL, NULL },
-    { REGULAR, COMP, USERS, "users", NULL },   /* FIX ME! */
+    { REGULAR, COMP, USERS, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
     { COMMENT, "/*\n * Regex key which matches any component\n */", NULL },
@@ -242,42 +296,43 @@ struct {
     { COMMENT, "", NULL, NULL, NULL },
 
     { COMMENT, "/*\n * Network Entity Keys\n */", NULL },
-    { REGULAR, NETENT, AIRPORT, NULL, NULL },
-    { REGULAR, NETENT, APPLETALK, NULL, NULL },
-    { REGULAR, NETENT, DNS, NULL, NULL },
-    { REGULAR, NETENT, ETHERNET, NULL, NULL },
-    { REGULAR, NETENT, INTERFACE, NULL, NULL },
-    { REGULAR, NETENT, IPV4, NULL, NULL },
-    { REGULAR, NETENT, IPV6, NULL, NULL },
-    { REGULAR, NETENT, LINK, NULL, NULL },
-    { REGULAR, NETENT, MODEM, NULL, NULL },
-    { REGULAR, NETENT, NETINFO, NULL, NULL },
-    { REGULAR, NETENT, NIS, NULL, NULL },
-    { REGULAR, NETENT, PPP, NULL, NULL },
-    { REGULAR, NETENT, PPPOE, NULL, NULL },
-    { REGULAR, NETENT, PROXIES, NULL, NULL },
-    { COMMENT, "", NULL, NULL, NULL },
-
-    { COMMENT, "/*\n * " NETWORK " Properties\n */", NULL },
+    { REGULAR, NETENT, AIRPORT, NULL, CFDICTIONARY },
+    { REGULAR, NETENT, APPLETALK, NULL, CFDICTIONARY },
+    { DEFINE , NETENT, DHCP, NULL, CFDICTIONARY },
+    { REGULAR, NETENT, DNS, NULL, CFDICTIONARY },
+    { REGULAR, NETENT, ETHERNET, NULL, CFDICTIONARY },
+    { REGULAR, NETENT, INTERFACE, NULL, CFDICTIONARY },
+    { REGULAR, NETENT, IPV4, NULL, CFDICTIONARY },
+    { REGULAR, NETENT, IPV6, NULL, CFDICTIONARY },
+    { REGULAR, NETENT, LINK, NULL, CFDICTIONARY },
+    { REGULAR, NETENT, MODEM, NULL, CFDICTIONARY },
+    { REGULAR, NETENT, NETINFO, NULL, CFDICTIONARY },
+    { FUTURE , NETENT, NIS, NULL, CFDICTIONARY },
+    { REGULAR, NETENT, PPP, NULL, CFDICTIONARY },
+    { REGULAR, NETENT, PPPOE, NULL, CFDICTIONARY },
+    { REGULAR, NETENT, PROXIES, NULL, CFDICTIONARY },
+    { COMMENT, "", NULL, NULL, NULL },
+
+    { COMMENT, "/*\n * " KEY_PREFIX COMP NETWORK " Properties\n */", NULL },
     { REGULAR, NETPROP, SERVICEORDER, NULL, CFARRAY_CFSTRING },
     { REGULAR, NETPROP, PPPOVERRIDEPRIMARY, NULL, CFNUMBER_BOOL },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " AIRPORT " (Hardware) Entity Keys\n */", NULL, NULL, NULL },
-    { REGULAR, NETPROP AIRPORT, "PowerEnabled", NULL, CFNUMBER_BOOL },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT AIRPORT " (Hardware) Entity Keys\n */", NULL, NULL, NULL },
+    { REGULAR, NETPROP AIRPORT, POWERENABLED, NULL, CFNUMBER_BOOL },
     { REGULAR, NETPROP AIRPORT, AUTH PASSWORD, NULL, CFSTRING },
     { REGULAR, NETPROP AIRPORT, AUTH PASSWORD ENCRYPTION, NULL, CFSTRING },
-    { REGULAR, NETPROP AIRPORT, "PreferredNetwork", NULL, CFSTRING },
+    { REGULAR, NETPROP AIRPORT, PREFERREDNETWORK, NULL, CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " APPLETALK " Entity Keys\n */", NULL, NULL, NULL },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT APPLETALK " Entity Keys\n */", NULL, NULL, NULL },
     { REGULAR, NETPROP APPLETALK, COMPUTERNAME, NULL, CFSTRING },
     { REGULAR, NETPROP APPLETALK, COMPUTERNAME ENCODING, NULL, CFNUMBER },
     { REGULAR, NETPROP APPLETALK, CONFIGMETHOD, NULL, CFSTRING },
     { REGULAR, NETPROP APPLETALK, DEFAULTZONE, NULL, CFSTRING },
     { REGULAR, NETPROP APPLETALK, NETWORKID, NULL, CFNUMBER },
     { REGULAR, NETPROP APPLETALK, NODEID, NULL, CFNUMBER },
-    { REGULAR, NETPROP APPLETALK, SEEDNETWORKRANGE, NULL, CFARRAY_CFSTRING },
+    { REGULAR, NETPROP APPLETALK, SEEDNETWORKRANGE, NULL, CFARRAY_CFNUMBER },
     { REGULAR, NETPROP APPLETALK, SEEDZONES, NULL, CFARRAY_CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
     { COMMENT, "/* " KEY_PREFIX NETPROP APPLETALK CONFIGMETHOD " values */", NULL, NULL, NULL },
@@ -286,16 +341,17 @@ struct {
     { REGULAR, NETVAL APPLETALK CONFIGMETHOD, SEEDROUTER, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " DNS " Entity Keys\n */", NULL, NULL, NULL },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT DNS " Entity Keys\n */", NULL, NULL, NULL },
     { REGULAR, NETPROP DNS, DOMAINNAME, NULL, CFSTRING },
     { REGULAR, NETPROP DNS, SEARCHDOMAINS, NULL, CFARRAY_CFSTRING},
     { REGULAR, NETPROP DNS, SERVERADDRESSES, NULL, CFARRAY_CFSTRING },
+    { DEFINE , NETPROP DNS, SORTLIST, NULL, CFARRAY_CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " ETHERNET " (Hardware) Entity Keys\n */", NULL, NULL, NULL },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT ETHERNET " (Hardware) Entity Keys\n */", NULL, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " INTERFACE " Entity Keys\n */", NULL },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT INTERFACE " Entity Keys\n */", NULL },
     { REGULAR, NETPROP INTERFACE, DEVICENAME, NULL, CFSTRING },
     { REGULAR, NETPROP INTERFACE, HARDWARE, NULL, CFSTRING },
     { REGULAR, NETPROP INTERFACE, TYPE, NULL, CFSTRING },
@@ -310,7 +366,7 @@ struct {
     { REGULAR, NETVAL INTERFACE SUBTYPE, PPPSERIAL, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " IPV4 " Entity Keys\n */", NULL, NULL, NULL },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT IPV4 " Entity Keys\n */", NULL, NULL, NULL },
     { REGULAR, NETPROP IPV4, ADDRESSES, NULL, CFARRAY_CFSTRING },
     { REGULAR, NETPROP IPV4, CONFIGMETHOD, NULL, CFSTRING },
     { REGULAR, NETPROP IPV4, DHCPCLIENTID, NULL, CFSTRING },
@@ -327,28 +383,31 @@ struct {
     { REGULAR, NETVAL IPV4 CONFIGMETHOD, PPP, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " IPV6 " Entity Keys\n */", NULL, NULL, NULL },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT IPV6 " Entity Keys\n */", NULL, NULL, NULL },
     { REGULAR, NETPROP IPV6, ADDRESSES, NULL, CFARRAY_CFSTRING },
     { REGULAR, NETPROP IPV6, CONFIGMETHOD, NULL, CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " LINK " Entity Keys\n */", NULL, NULL, NULL },
-    { REGULAR, NETPROP LINK, ACTIVE, NULL, CFNUMBER_BOOL },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT LINK " Entity Keys\n */", NULL, NULL, NULL },
+    { REGULAR, NETPROP LINK, ACTIVE, NULL, CFBOOLEAN },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " MODEM " (Hardware) Entity Keys\n */", NULL, NULL, NULL },
-    { REGULAR, NETPROP MODEM, "ConnectionScript", NULL, CFSTRING },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT MODEM " (Hardware) Entity Keys\n */", NULL, NULL, NULL },
+    { REGULAR, NETPROP MODEM, CONNECTIONSCRIPT, NULL, CFSTRING },
+    { DEFINE , NETPROP MODEM, DATACOMPRESSION, NULL, CFNUMBER_BOOL },
     { REGULAR, NETPROP MODEM, DIALMODE, NULL, CFSTRING },
-    { REGULAR, NETPROP MODEM, "PulseDial", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP MODEM, "Speaker", NULL, CFNUMBER_BOOL },
+    { DEFINE , NETPROP MODEM, ERRORCORRECTION, NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP MODEM, PULSEDIAL, NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP MODEM, SPEAKER, NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP MODEM, SPEED, NULL, CFNUMBER },
     { COMMENT, "", NULL, NULL, NULL },
     { COMMENT, "/* " KEY_PREFIX NETPROP MODEM DIALMODE " values */", NULL, NULL, NULL },
-    { REGULAR, NETVAL MODEM DIALMODE, "IgnoreDialTone", NULL, NULL },
+    { REGULAR, NETVAL MODEM DIALMODE, IGNOREDIALTONE, NULL, NULL },
     { REGULAR, NETVAL MODEM DIALMODE, MANUAL, NULL, NULL },
-    { REGULAR, NETVAL MODEM DIALMODE, "WaitForDialTone", NULL, NULL },
+    { REGULAR, NETVAL MODEM DIALMODE, WAITFORDIALTONE, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " NETINFO " Entity Keys\n */", NULL, NULL, NULL },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT NETINFO " Entity Keys\n */", NULL, NULL, NULL },
     { REGULAR, NETPROP NETINFO, BINDINGMETHODS, NULL, CFSTRING },
     { REGULAR, NETPROP NETINFO, SERVERADDRESSES, NULL, CFARRAY_CFSTRING },
     { REGULAR, NETPROP NETINFO, SERVERTAGS, NULL, CFARRAY_CFSTRING },
@@ -363,18 +422,19 @@ struct {
     { REGULAR, NETVAL NETINFO, DEFAULTSERVERTAG, "network", NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " NIS " Entity Keys\n */", NULL, NULL, NULL },
-    { REGULAR, NETPROP NIS, DOMAINNAME, NULL, CFSTRING },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT NIS " Entity Keys\n */", NULL, NULL, NULL },
+    { COMMENT, "/* RESERVED FOR FUTURE USE */", NULL, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " PPP " Entity Keys\n */", NULL, NULL, NULL },
-    { REGULAR, NETPROP PPP, "DialOnDemand", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, "DisconnectOnIdle", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, "DisconnectOnIdleTimer", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, "DisconnectOnLogout", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, "IdleReminderTimer", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, "IdleReminder", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, "Logfile", NULL, CFSTRING },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT PPP " Entity Keys\n */", NULL, NULL, NULL },
+    { REGULAR, NETPROP PPP, DIALONDEMAND, NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP PPP, DISCONNECTONIDLE, NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP PPP, DISCONNECTONIDLETIMER, NULL, CFNUMBER },
+    { REGULAR, NETPROP PPP, DISCONNECTONLOGOUT, NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP PPP, IDLEREMINDERTIMER, NULL, CFNUMBER },
+    { REGULAR, NETPROP PPP, IDLEREMINDER, NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP PPP, LOGFILE, NULL, CFSTRING },
+    { DEFINE , NETPROP PPP, SESSIONTIMER, NULL, CFNUMBER },
     { REGULAR, NETPROP PPP, VERBOSELOGGING, NULL, CFNUMBER_BOOL },
     { COMMENT, "", NULL, NULL, NULL },
 
@@ -385,43 +445,43 @@ struct {
     { REGULAR, NETPROP PPP, AUTH PROTOCOL, NULL, CFARRAY_CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
     { COMMENT, "/* " KEY_PREFIX NETPROP PPP AUTH PROTOCOL " values */", NULL, NULL, NULL },
-    { REGULAR, NETVAL PPP AUTH PROTOCOL, "CHAP", NULL, CFSTRING },
-    { REGULAR, NETVAL PPP AUTH PROTOCOL, "PAP", NULL, CFSTRING },
+    { REGULAR, NETVAL PPP AUTH PROTOCOL, CHAP, NULL, CFSTRING },
+    { REGULAR, NETVAL PPP AUTH PROTOCOL, PAP, NULL, CFSTRING },
 
     { COMMENT, "\n/* " COMM ": */", NULL, NULL, NULL },
-    { REGULAR, NETPROP PPP, COMM "AlternateRemoteAddress", NULL, CFSTRING },
-    { REGULAR, NETPROP PPP, COMM "ConnectDelay", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, COMM "DisplayTerminalWindow", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, COMM "RedialCount", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, COMM "RedialEnabled", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, COMM "RedialInterval", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, COMM "RemoteAddress", NULL, CFSTRING },
-    { REGULAR, NETPROP PPP, COMM "TerminalScript", NULL, CFSTRING },
+    { REGULAR, NETPROP PPP, COMM ALTERNATEREMOTEADDRESS, NULL, CFSTRING },
+    { REGULAR, NETPROP PPP, COMM CONNECTDELAY, NULL, CFNUMBER },
+    { REGULAR, NETPROP PPP, COMM DISPLAYTERMINALWINDOW, NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP PPP, COMM REDIALCOUNT, NULL, CFNUMBER },
+    { REGULAR, NETPROP PPP, COMM REDIALENABLED, NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP PPP, COMM REDIALINTERVAL, NULL, CFNUMBER },
+    { REGULAR, NETPROP PPP, COMM REMOTEADDRESS, NULL, CFSTRING },
+    { REGULAR, NETPROP PPP, COMM TERMINALSCRIPT, NULL, CFSTRING },
 
     { COMMENT, "\n/* " IPCP ": */", NULL, NULL, NULL },
-    { REGULAR, NETPROP PPP, IPCP "CompressionVJ", NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP PPP, IPCP COMPRESSIONVJ, NULL, CFNUMBER_BOOL },
 
     { COMMENT, "\n/* " LCP ": */", NULL, NULL, NULL },
-    { REGULAR, NETPROP PPP, LCP "EchoEnabled", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, LCP "EchoFailure", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, LCP "EchoInterval", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, LCP "CompressionACField", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, LCP "CompressionPField", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, LCP "MRU", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, LCP "MTU", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, LCP "ReceiveACCM", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, LCP "TransmitACCM", NULL, CFNUMBER },
-    { COMMENT, "", NULL, NULL, NULL },
-
-    { COMMENT, "/*\n * " PPPOE " Entity Keys\n */", NULL, NULL, NULL },
+    { REGULAR, NETPROP PPP, LCP ECHOENABLED, NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP PPP, LCP ECHOFAILURE, NULL, CFNUMBER },
+    { REGULAR, NETPROP PPP, LCP ECHOINTERVAL, NULL, CFNUMBER },
+    { REGULAR, NETPROP PPP, LCP COMPRESSIONACFIELD, NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP PPP, LCP COMPRESSIONPFIELD, NULL, CFNUMBER_BOOL },
+    { REGULAR, NETPROP PPP, LCP MRU, NULL, CFNUMBER },
+    { REGULAR, NETPROP PPP, LCP MTU, NULL, CFNUMBER },
+    { REGULAR, NETPROP PPP, LCP RECEIVEACCM, NULL, CFNUMBER },
+    { REGULAR, NETPROP PPP, LCP TRANSMITACCM, NULL, CFNUMBER },
+    { COMMENT, "", NULL, NULL, NULL },
+
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT PPPOE " Entity Keys\n */", NULL, NULL, NULL },
     { COMMENT, "/* RESERVED FOR FUTURE USE */", NULL, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " PPPSERIAL " Entity Keys\n */", NULL, NULL, NULL },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT PPPSERIAL " Entity Keys\n */", NULL, NULL, NULL },
     { COMMENT, "/* RESERVED FOR FUTURE USE */", NULL, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " PROXIES " Entity Keys\n */", NULL, NULL, NULL },
+    { COMMENT, "/*\n * " KEY_PREFIX NETENT PROXIES " Entity Keys\n */", NULL, NULL, NULL },
     { REGULAR, NETPROP PROXIES, EXCEPTIONSLIST, NULL, CFARRAY_CFSTRING },
     { REGULAR, NETPROP PROXIES, FTPENABLE, NULL, CFNUMBER_BOOL },
     { REGULAR, NETPROP PROXIES, FTPPASSIVE, NULL, CFNUMBER_BOOL },
@@ -433,6 +493,9 @@ struct {
     { REGULAR, NETPROP PROXIES, HTTPENABLE, NULL, CFNUMBER_BOOL },
     { REGULAR, NETPROP PROXIES, HTTPPORT, NULL, CFNUMBER },
     { REGULAR, NETPROP PROXIES, HTTPPROXY, NULL, CFSTRING },
+    { DEFINE , NETPROP PROXIES, HTTPSENABLE, NULL, CFNUMBER_BOOL },
+    { DEFINE , NETPROP PROXIES, HTTPSPORT, NULL, CFNUMBER },
+    { DEFINE , NETPROP PROXIES, HTTPSPROXY, NULL, CFSTRING },
     { REGULAR, NETPROP PROXIES, RTSPENABLE, NULL, CFNUMBER_BOOL },
     { REGULAR, NETPROP PROXIES, RTSPPORT, NULL, CFNUMBER },
     { REGULAR, NETPROP PROXIES, RTSPPROXY, NULL, CFSTRING },
@@ -441,99 +504,53 @@ struct {
     { REGULAR, NETPROP PROXIES, SOCKSPROXY, NULL, CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * Users Entity Keys\n */", NULL, NULL, NULL },
+    { COMMENT, "/*\n " KEY_PREFIX COMP USERS " Entity Keys\n */", NULL, NULL, NULL },
     { REGULAR, USERSENT, CONSOLEUSER, NULL, NULL },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n " CONSOLEUSER " Entity Keys\n */", NULL, NULL, NULL },
-    { REGULAR, USERSPROP CONSOLEUSER, NAME, "username", CFSTRING },    /* FIX ME! */
-    { REGULAR, USERSPROP CONSOLEUSER, UID, "uid", CFSTRING },          /* FIX ME! */
-    { REGULAR, USERSPROP CONSOLEUSER, GID, "gid", CFSTRING },          /* FIX ME! */
+    { COMMENT, "/*\n " KEY_PREFIX USERSPROP CONSOLEUSER " Properties\n */", NULL, NULL, NULL },
+    { REGULAR, USERSPROP CONSOLEUSER, NAME, NULL, CFSTRING },
+    { REGULAR, USERSPROP CONSOLEUSER, UID, NULL, CFSTRING },
+    { REGULAR, USERSPROP CONSOLEUSER, GID, NULL, CFSTRING },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * " SYSTEM " Entity Keys\n */", NULL, NULL, NULL },
+    { COMMENT, "/*\n * " KEY_PREFIX COMP SYSTEM " Properties\n */", NULL, NULL, NULL },
     { REGULAR, SYSTEMPROP, COMPUTERNAME, NULL, CFSTRING },
     { REGULAR, SYSTEMPROP, COMPUTERNAME ENCODING, NULL, CFNUMBER },
     { COMMENT, "", NULL, NULL, NULL },
 
-    { COMMENT, "/*\n * Configuration Cache Definitions\n */", NULL },
+    { COMMENT, "/*\n * Configuration Store Definitions\n */", NULL },
     { COMMENT, "/* domain prefixes */", NULL },
-    { REGULAR, CACHE DOMAIN, FILE, "File:", NULL },
-    { REGULAR, CACHE DOMAIN, PLUGIN, "Plugin:", NULL },
-    { REGULAR, CACHE DOMAIN, SETUP, "Setup:", NULL },
-    { REGULAR, CACHE DOMAIN, STATE, "State:", NULL },
-    { REGULAR, CACHE DOMAIN, PREFS, "Prefs:", NULL },
-    { COMMENT, "", NULL, NULL, NULL },
-
-    { COMMENT, "/* Setup: properties */", NULL },
-    { REGULAR, CACHE SETUPPROP, CURRENTSET, NULL, NULL },
-    { REGULAR, CACHE SETUPPROP, LASTUPDATED, NULL, NULL },
-    { COMMENT, "", NULL, NULL, NULL },
-
-    { COMMENT, "/* properties */", NULL },
-    { REGULAR, CACHE NETPROP, INTERFACES, NULL, CFARRAY_CFSTRING },
-    { REGULAR, CACHE NETPROP, PRIMARYINTERFACE, NULL, CFSTRING },
-    { REGULAR, CACHE NETPROP, SERVICEIDS, NULL, CFARRAY_CFSTRING },
-    { COMMENT, "", NULL, NULL, NULL },
-
-// XXX OBSOLETE XXX
-    { COMMENT, "/* OBSOLETE " NETPROP AIRPORT ": */", NULL, NULL, NULL },
-    { REGULAR, NETPROP AIRPORT, INCLUDEPRIVATENETS, NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP AIRPORT, "PreferredAirportNetwork", NULL, CFSTRING },
-
-    { COMMENT, "/* OBSOLETE " NETPROP ETHERNET ": */", NULL, NULL, NULL },
-    { REGULAR, NETPROP ETHERNET, SPEED, NULL, CFNUMBER },
-    { REGULAR, NETPROP ETHERNET, DUPLEX, NULL, CFSTRING },
-    { REGULAR, NETPROP ETHERNET, "WakeOnSignal", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP ETHERNET, "WakeOnTraffic", NULL, CFNUMBER_BOOL },
-    { COMMENT, "/* " KEY_PREFIX NETPROP ETHERNET DUPLEX " values */", NULL, NULL, NULL },
-    { REGULAR, NETVAL ETHERNET DUPLEX, AUTOMATIC, NULL, NULL },
-    { REGULAR, NETVAL ETHERNET DUPLEX, "FULL", NULL, NULL },
-    { REGULAR, NETVAL ETHERNET DUPLEX, "HALF", NULL, NULL },
-
-    { COMMENT, "/* OBSOLETE " NETPROP INTERFACE ": */", NULL, NULL, NULL },
-    { REGULAR, NETPROP INTERFACE, INTERFACE NAME, NULL, CFSTRING },
-    { REGULAR, NETPROP INTERFACE, MACADDRESS, NULL, CFSTRING },
-    { REGULAR, NETPROP INTERFACE, PORTNAME, NULL, CFSTRING },
-
-    { COMMENT, "/* OBSOLETE " NETPROP MODEM ": */", NULL, NULL, NULL },
-    { REGULAR, NETPROP MODEM, "IgnoreDialTone", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP MODEM, "InitString", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP MODEM, "Port", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP MODEM, PORTNAME, NULL, CFSTRING },
-    { REGULAR, NETPROP MODEM, "RedialCount", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP MODEM, "RedialEnabled", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP MODEM, "RedialTimeout", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP MODEM, "Script", NULL, CFSTRING },
-    { REGULAR, NETPROP MODEM, "SpeakerEnable", NULL, CFNUMBER },
-    { REGULAR, NETPROP MODEM, SPEED, NULL, CFNUMBER },
-    { REGULAR, NETPROP MODEM, "ToneDial", NULL, CFNUMBER },
-    { REGULAR, NETPROP MODEM, "WaitForTone", NULL, CFNUMBER },
-
-    { COMMENT, "/* OBSOLETE " NETPROP PPP ": */", NULL, NULL, NULL },
-    { REGULAR, NETPROP PPP, ALERT, NULL, CFARRAY_CFSTRING },
-    { REGULAR, NETVAL PPP ALERT, "Password", NULL, CFSTRING },
-    { REGULAR, NETVAL PPP ALERT, "Reminder", NULL, CFSTRING },
-    { REGULAR, NETVAL PPP ALERT, "Status", NULL, CFSTRING },
-    { REGULAR, NETPROP PPP, "CompressionEnable", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, "DeviceEntity", NULL, CFSTRING },
-    { REGULAR, NETPROP PPP, "HeaderCompression", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, "IdleDisconnect", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, "IdlePrompt", NULL, CFNUMBER_BOOL },
-    { REGULAR, NETPROP PPP, "IdleTimeout", NULL, CFSTRING },
-    { REGULAR, NETPROP PPP, "PromptTimeout", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, "ReminderTimer", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, "SessionTimer", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, COMM "IdleTimer", NULL, CFNUMBER },
-    { REGULAR, NETPROP PPP, IPCP "LocalAddress", NULL, CFSTRING },
-    { REGULAR, NETPROP PPP, IPCP "RemoteAddress", NULL, CFSTRING },
-    { REGULAR, NETPROP PPP, IPCP "UseServerDNS", NULL, CFNUMBER_BOOL },
-
-    { COMMENT, "/* OBSOLETE " NETPROP PPPOE ": */", NULL, NULL, NULL },
-    { REGULAR, NETPROP PPPOE, PORTNAME, NULL, CFSTRING },
-
-    { COMMENT, "", NULL, NULL, NULL },
-// XXX OBSOLETE XXX
+    { DEFINE , DYNAMICSTORE DOMAIN, FILE, "File:", NULL },
+    { DEFINE , DYNAMICSTORE DOMAIN, PLUGIN, "Plugin:", NULL },
+    { DEFINE , DYNAMICSTORE DOMAIN, SETUP, "Setup:", NULL },
+    { DEFINE , DYNAMICSTORE DOMAIN, STATE, "State:", NULL },
+    { DEFINE , DYNAMICSTORE DOMAIN, PREFS, "Prefs:", NULL },
+    { COMMENT, "", NULL, NULL, NULL },
+
+    { COMMENT, "/* " KEY_PREFIX DYNAMICSTORE DOMAIN SETUP " Properties */", NULL },
+    { DEFINE , DYNAMICSTORE SETUPPROP, CURRENTSET, NULL, CFSTRING },
+    { DEFINE , DYNAMICSTORE SETUPPROP, LASTUPDATED, NULL, NULL },
+    { COMMENT, "", NULL, NULL, NULL },
+
+    { COMMENT, "/* Properties */", NULL },
+    { DEFINE , DYNAMICSTORE NETPROP, INTERFACES, NULL, CFARRAY_CFSTRING },
+    { DEFINE , DYNAMICSTORE NETPROP, PRIMARYINTERFACE, NULL, CFSTRING },
+    { DEFINE , DYNAMICSTORE NETPROP, PRIMARYSERVICE, NULL, CFSTRING },
+    { DEFINE , DYNAMICSTORE NETPROP, SERVICEIDS, NULL, CFARRAY_CFSTRING },
+    { COMMENT, "", NULL, NULL, NULL },
+
+    /* obsolete keys */
+    { OBSOLETE, "Cache" DOMAIN, FILE, "File:", NULL },
+    { OBSOLETE, "Cache" DOMAIN, PLUGIN, "Plugin:", NULL },
+    { OBSOLETE, "Cache" DOMAIN, SETUP, "Setup:", NULL },
+    { OBSOLETE, "Cache" DOMAIN, STATE, "State:", NULL },
+    { OBSOLETE, "Cache" DOMAIN, PREFS, "Prefs:", NULL },
+    { OBSOLETE, "Cache" SETUPPROP, CURRENTSET, NULL, CFSTRING },
+    { OBSOLETE, "Cache" SETUPPROP, LASTUPDATED, NULL, NULL },
+    { OBSOLETE, "Cache" NETPROP, INTERFACES, NULL, CFARRAY_CFSTRING },
+    { OBSOLETE, "Cache" NETPROP, PRIMARYINTERFACE, NULL, CFSTRING },
+    { OBSOLETE, "Cache" NETPROP, SERVICEIDS, NULL, CFARRAY_CFSTRING },
 
     { END, NULL, NULL, NULL, NULL },
 };
@@ -562,40 +579,118 @@ dump_names(int type)
                }
                break;
            }
+           case DEFINE: {
+               char kbuf[256];
+               char vbuf[256];
+
+               switch (type) {
+               case gen_header_e:
+                   snprintf(kbuf, sizeof(kbuf), KEY_PREFIX "%s%s",
+                            names[i].prefix, names[i].key);
+
+                   if (names[i].value)
+                       snprintf(vbuf, sizeof(vbuf), "SCSTR(\"%s\")",
+                                names[i].value);
+                   else
+                       snprintf(vbuf, sizeof(vbuf), "SCSTR(\"%s\")",
+                                names[i].key);
+
+                   if (names[i].type)
+                       printf("#define %-40s %-40s /* %s */\n",
+                              kbuf, vbuf, names[i].type);
+                   else
+                       printf("#define %-40s %-40s\n",
+                              kbuf, vbuf);
+                   break;
+               default:
+                   break;
+               }
+               break;
+           }
            case REGULAR: {
-               char buf[256];
+               char kbuf[256];
+               char vbuf[256];
 
                switch (type) {
                case gen_header_e:
-                   snprintf(buf, sizeof(buf), KEY_PREFIX "%s%s;",
+                   snprintf(kbuf, sizeof(kbuf), KEY_PREFIX "%s%s",
                             names[i].prefix, names[i].key);
 
+                   if (names[i].value)
+                       snprintf(vbuf, sizeof(vbuf), "SCSTR(\"%s\")",
+                                names[i].value);
+                   else
+                       snprintf(vbuf, sizeof(vbuf), "SCSTR(\"%s\")",
+                                names[i].key);
+
                    if (names[i].type)
-                       printf(STRING_MACRO_NAME " %-40s /* %s */\n",
-                              buf, names[i].type);
+                       printf("#define %-40s %-40s /* %s */\n",
+                              kbuf, vbuf, names[i].type);
                    else
-                       printf(STRING_MACRO_NAME " %s\n", buf);
+                       printf("#define %-40s %-40s\n",
+                              kbuf, vbuf);
                    break;
                case gen_extern_e:
-                   snprintf(buf, sizeof(buf), KEY_PREFIX "%s%s",
+                   snprintf(kbuf, sizeof(kbuf), KEY_PREFIX "%s%s",
                             names[i].prefix, names[i].key);
 
                    printf("volatile CFStringRef " KEY_PREFIX "%s%s = NULL;\n",
                           names[i].prefix, names[i].key);
                    break;
                case gen_init_e:
-                   snprintf(buf, sizeof(buf), KEY_PREFIX "%s%s",
+                   snprintf(kbuf, sizeof(kbuf), KEY_PREFIX "%s%s",
                             names[i].prefix, names[i].key);
                    if (names[i].value)
                        printf("   *((void **)&%s) = (void *)CFSTR(\"%s\");\n",
-                              buf, names[i].value);
+                              kbuf, names[i].value);
                    else
                        printf("   *((void **)&%s) = (void *)CFSTR(\"%s\");\n",
-                              buf, names[i].key);
+                              kbuf, names[i].key);
                    break;
                default:
                    break;
                }
+               break;
+           }
+           case OBSOLETE: {
+               char kbuf[256];
+
+               switch (type) {
+               case gen_extern_e:
+                   snprintf(kbuf, sizeof(kbuf), KEY_PREFIX "%s%s",
+                            names[i].prefix, names[i].key);
+
+                   printf("volatile CFStringRef " KEY_PREFIX "%s%s = NULL;\n",
+                          names[i].prefix, names[i].key);
+                   break;
+               case gen_init_e:
+                   snprintf(kbuf, sizeof(kbuf), KEY_PREFIX "%s%s",
+                            names[i].prefix, names[i].key);
+                   if (names[i].value)
+                       printf("   *((void **)&%s) = (void *)CFSTR(\"%s\");\n",
+                              kbuf, names[i].value);
+                   else
+                       printf("   *((void **)&%s) = (void *)CFSTR(\"%s\");\n",
+                              kbuf, names[i].key);
+                   break;
+               default:
+                   break;
+               }
+               break;
+           }
+           case FUTURE: {
+               char kbuf[256];
+
+               if (type == gen_header_e) {
+                   snprintf(kbuf, sizeof(kbuf), KEY_PREFIX "%s%s",
+                            names[i].prefix, names[i].key);
+
+                   printf("/* #define %-37s %-40s /* %s */\n",
+                          kbuf,
+                          "SCSTR(\"???\") */",
+                          "RESERVED FOR FUTURE USE");
+               }
+               break;
            }
            default: {
                break;
@@ -617,24 +712,47 @@ main(int argc, char * argv[])
     if (strcmp(type, "header") == 0) {
        printf("%s\n", copyright_string);
        printf("/*\n * This file is automatically generated\n * DO NOT EDIT!\n */\n\n");
-       printf("#ifndef _SCPREFERENCES_H\n#define _SCPREFERENCES_H\n\n");
-       //printf("#ifndef " STRING_MACRO_NAME "\n");
-       printf("#ifndef __OBJC__\n");
-       printf("#define " STRING_MACRO_NAME "\t\textern const CFStringRef\n");
-       printf("#else\n");
-       printf("#define " STRING_MACRO_NAME "\t\textern NSString *\n");
+
+       printf("/*\n");
+       printf(" * Note: For Cocoa/Obj-C/Foundation programs accessing these preference\n");
+       printf(" *       keys you may want to consider the following:\n");
+       printf(" *\n");
+       printf(" *       #define SCSTR(s) (NSString *)CFSTR(s)\n");
+       printf(" *       #import <SystemConfiguration/SystemConfiguration.h>\n");
+       printf(" */\n\n");
+
+       printf("#ifndef _SCSCHEMADEFINITIONS_H\n#define _SCSCHEMADEFINITIONS_H\n\n");
+
+       printf("#ifndef  SCSTR\n");
+       printf("#include <CoreFoundation/CFString.h>\n");
+       printf("#define  SCSTR(s) CFSTR(s)\n");
        printf("#endif\n");
-       //printf("#endif " STRING_MACRO_NAME "\n");
+
        printf("\n");
        dump_names(gen_header_e);
-       printf("#endif /* _SCPREFERENCES_H */\n");
+       printf("#endif /* _SCSCHEMADEFINITIONS_H */\n");
     }
     else if (strcmp(type, "cfile") == 0) {
-       printf("/*\n * This file is automatically generated\n * DO NOT EDIT!\n */\n\n");
-       printf("\n#include <CoreFoundation/CFString.h>\n\n");
+       printf("/*\n");
+       printf(" * This file is automatically generated\n");
+       printf(" * DO NOT EDIT!\n");
+       printf(" */\n");
+       printf("\n");
+       printf("#include <CoreFoundation/CFString.h>\n");
+       printf("\n");
        dump_names(gen_extern_e);
-       printf("\n\nvoid\n__private_extern__\n__Initialize(void)\n{\n");
+       printf("\n");
+       printf("__private_extern__\nvoid\n__Initialize(void)\n");
+       printf("{\n");
+       printf("   static Boolean initialized = FALSE;\n");
+       printf("\n");
+       printf("   if (initialized)\n");
+       printf("      return;\n");
+       printf("\n");
        dump_names(gen_init_e);
+       printf("\n");
+       printf("   initialized = TRUE;\n");
+       printf("   return;\n");
        printf("}\n");
     }
     exit(0);
index 2af576063fbdd2c7918cc490f5db6d29a6e31f73..f0c109ff6a7b0baf81fb13ee2d3232359c5f3b8b 100644 (file)
  */
 
 #include <stdio.h>
-//#include <stdlib.h>
-//#include <string.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/errno.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <CoreFoundation/CoreFoundation.h>
-#include <SystemConfiguration/SystemConfiguration.h>
 
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
 
 #include "ppp_msg.h"
 #include "ppp.h"
 
-
 __private_extern__
 int
 PPPInit(int *ref)
@@ -93,20 +91,20 @@ PPPExec(int         ref,
        //  send the command
        n = write(ref, &msg, sizeof(msg));
        if (n == -1) {
-               SCDLog(LOG_ERR, CFSTR("PPPExec write() failed: %s"), strerror(errno));
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec write() failed: %s"), strerror(errno));
                return errno;
        } else if (n != sizeof(msg)) {
-               SCDLog(LOG_ERR, CFSTR("PPPExec write() failed: wrote=%d"), n);
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec write() failed: wrote=%d"), n);
                return -1;
        }
 
        if ((request != NULL) && (requestLen > 0)) {
                n = write(ref, request, requestLen);
                if (n == -1) {
-                       SCDLog(LOG_ERR, CFSTR("PPPExec write() failed: %s"), strerror(errno));
+                       SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec write() failed: %s"), strerror(errno));
                        return errno;
                } else if (n != requestLen) {
-                       SCDLog(LOG_ERR, CFSTR("PPPExec write() failed: wrote=%d"), n);
+                       SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec write() failed: wrote=%d"), n);
                        return -1;
                }
        }
@@ -114,10 +112,10 @@ PPPExec(int               ref,
        // always expect a reply
        n = read(ref, &msg, sizeof(msg));
        if (n == -1) {
-               SCDLog(LOG_ERR, CFSTR("PPPExec read() failed: error=%s"), strerror(errno));
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec read() failed: error=%s"), strerror(errno));
                return errno;
        } else if (n != sizeof(msg)) {
-               SCDLog(LOG_ERR, CFSTR("PPPExec read() failed: insufficent data, read=%d"), n);
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec read() failed: insufficent data, read=%d"), n);
                return -1;
        }
 
@@ -127,11 +125,11 @@ PPPExec(int               ref,
                        // read reply
                        n = read(ref, buf, msg.m_len);
                        if (n == -1) {
-                               SCDLog(LOG_ERR, CFSTR("PPPExec read() failed: error=%s"), strerror(errno));
+                               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec read() failed: error=%s"), strerror(errno));
                                CFAllocatorDeallocate(NULL, buf);
                                return errno;
                        } else if (n != msg.m_len) {
-                               SCDLog(LOG_ERR, CFSTR("PPPExec read() failed: insufficent data, read=%d"), n);
+                               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec read() failed: insufficent data, read=%d"), n);
                                CFAllocatorDeallocate(NULL, buf);
                                return -1;
                        }
@@ -150,6 +148,92 @@ PPPExec(int                ref,
 }
 
 
+#ifdef NOT_NEEDED
+int
+PPPConnect(int ref, u_long link)
+{
+       int     status;
+
+       status = PPPExec(ref,
+                        link,
+                        PPP_CONNECT,
+                        NULL,
+                        0,
+                        NULL,
+                        NULL);
+       if (status != 0) {
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_CONNECT) failed: status = %d"), status);
+               return status;
+       }
+
+       return status;
+}
+
+
+int
+PPPDisconnect(int ref, u_long link)
+{
+       int     status;
+
+       status = PPPExec(ref,
+                        link,
+                        PPP_DISCONNECT,
+                        NULL,
+                        0,
+                        NULL,
+                        NULL);
+       if (status != 0) {
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_DISCONNECT) failed: status = %d"), status);
+               return status;
+       }
+
+       return status;
+}
+
+
+int
+PPPListen(int ref, u_long link)
+{
+       int     status;
+
+       status = PPPExec(ref,
+                        link,
+                        PPP_LISTEN,
+                        NULL,
+                        0,
+                        NULL,
+                        NULL);
+       if (status != 0) {
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_LISTEN) failed: status = %d"), status);
+               return status;
+       }
+
+       return status;
+}
+
+
+int
+PPPApply(int ref, u_long link)
+{
+       int     status;
+
+       status = PPPExec(ref,
+                        link,
+                        PPP_APPLY,
+                        NULL,
+                        0,
+                        NULL,
+                        NULL);
+       if (status != 0) {
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_APPLY) failed: status = %d"), status);
+               return status;
+       }
+
+       return status;
+}
+#endif /* NOT_NEEDED */
+
+
 __private_extern__
 int
 PPPGetNumberOfLinks(int ref, u_long *nLinks)
@@ -166,7 +250,7 @@ PPPGetNumberOfLinks(int ref, u_long *nLinks)
                            &replyBuf,
                            &replyBufLen);
        if (status != 0) {
-               SCDLog(LOG_ERR, CFSTR("PPPExec() failed: status = %d"), status);
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_GETNBLINKS) failed: status = %d"), status);
                return status;
        }
 
@@ -194,7 +278,7 @@ PPPGetLinkByIndex(int ref, int index, u_int32_t *link)
                            &replyBuf,
                            &replyBufLen);
        if (status != 0) {
-               SCDLog(LOG_ERR, CFSTR("PPPExec() failed: status = %d"), status);
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_GETLINKBYINDEX) failed: status = %d"), status);
                return status;
        }
 
@@ -225,7 +309,7 @@ PPPGetLinkByServiceID(int ref, CFStringRef serviceID, u_int32_t *link)
 
        status = PPPGetNumberOfLinks(ref, &nLinks);
        if (status != 0) {
-               SCDLog(LOG_ERR, CFSTR("PPPGetNumberOfLinks() failed: %d"), status);
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPGetNumberOfLinks() failed: %d"), status);
                goto done;
        }
 
@@ -238,7 +322,7 @@ PPPGetLinkByServiceID(int ref, CFStringRef serviceID, u_int32_t *link)
 
                status = PPPGetLinkByIndex(ref, i, &iLink);
                if (status != 0) {
-                       SCDLog(LOG_ERR, CFSTR("PPPGetLinkByIndex() failed: %d"), status);
+                       SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPGetLinkByIndex() failed: %d"), status);
                        goto done;
                }
 
@@ -248,7 +332,7 @@ PPPGetLinkByServiceID(int ref, CFStringRef serviceID, u_int32_t *link)
                                      &data,
                                      &dataLen);
                if (status != 0) {
-                       SCDLog(LOG_ERR, CFSTR("PPPGetOption() failed: %d"), status);
+                       SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPGetOption(PPP_OPT_SERVICEID) failed: %d"), status);
                        goto done;
                }
 
@@ -292,7 +376,7 @@ PPPGetOption(int ref, u_long link, u_long option, void **data, u_long *dataLen)
                            &replyBuf,
                            &replyBufLen);
        if (status != 0) {
-               SCDLog(LOG_ERR, CFSTR("PPPExec() failed: status = %d"), status);
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_GETOPTION) failed: status = %d"), status);
                *data = NULL;
                *dataLen = 0;
                return status;
@@ -309,6 +393,40 @@ PPPGetOption(int ref, u_long link, u_long option, void **data, u_long *dataLen)
 }
 
 
+#ifdef NOT_NEEDED
+__private_extern__
+int
+PPPSetOption(int ref, u_long link, u_long option, void *data, u_long dataLen)
+{
+       void                    *buf;
+       u_long                  bufLen;
+       int                     status;
+
+       bufLen = sizeof(struct ppp_opt_hdr) + dataLen;
+       buf    = CFAllocatorAllocate(NULL, bufLen, 0);
+
+       bzero((struct ppp_opt_hdr *)buf, sizeof(struct ppp_opt_hdr));
+       ((struct ppp_opt_hdr *)buf)->o_type = option;
+       bcopy(data, ((struct ppp_opt *)buf)->o_data, dataLen);
+
+       status = PPPExec(ref,
+                        link,
+                        PPP_SETOPTION,
+                        buf,
+                        bufLen,
+                        NULL,
+                        NULL);
+       if (status != 0) {
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_SETOPTION) failed: status = %d"), status);
+       }
+
+       CFAllocatorDeallocate(NULL, buf);
+
+       return status;
+}
+#endif /* NOT_NEEDED */
+
+
 __private_extern__
 int
 PPPStatus(int ref, u_long link, struct ppp_status **stat)
@@ -325,7 +443,7 @@ PPPStatus(int ref, u_long link, struct ppp_status **stat)
                            &replyBuf,
                            &replyBufLen);
        if (status != 0) {
-               SCDLog(LOG_ERR, CFSTR("PPPExec() failed: status = %d"), status);
+               SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_STATUS) failed: status = %d"), status);
                return status;
        }
 
index 8375d1b62f51180bcff86e8eda80b770a50cb6eb..33eee1835372216d513f89753bb4b5b2eb373452 100644 (file)
 #ifndef _PPP_H
 #define _PPP_H
 
-
 #include <sys/cdefs.h>
 #include <CoreFoundation/CoreFoundation.h>
 #include "ppp_msg.h"
 
-
 __BEGIN_DECLS
 
 int            PPPInit                 (int                    *ref);
@@ -43,6 +41,20 @@ int          PPPExec                 (int                    ref,
                                         void                   **reply,
                                         u_long                 *replyLen);
 
+#ifdef NOT_NEEDED
+int            PPPConnect              (int                    ref,
+                                        u_long                 link);
+
+int            PPPDisconnect           (int                    ref,
+                                        u_long                 link);
+
+int            PPPListen               (int                    ref,
+                                        u_long                 link);
+
+int            PPPApply                (int                    ref,
+                                        u_long                 link);
+#endif /* NOT_NEEDED */
+
 int            PPPGetNumberOfLinks     (int                    ref,
                                         u_long                 *nLinks);
 
@@ -60,6 +72,14 @@ int          PPPGetOption            (int                    ref,
                                         void                   **data,
                                         u_long                 *dataLen);
 
+#ifdef NOT_NEEDED
+int            PPPSetOption            (int                    ref,
+                                        u_long                 link,
+                                        u_long                 option,
+                                        void                   *data,
+                                        u_long                 dataLen);
+#endif /* NOT_NEEDED */
+
 int            PPPStatus               (int                    ref,
                                         u_long                 link,
                                         struct ppp_status      **stat);
index 4a3c6da31d0bf43c3534b231ef8e9b307fec5377..106817d37508a8de7a079ac677cc73202ed23e28 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <sys/types.h>
 
-
 /* local socket path */
 #define PPP_PATH       "/var/run/pppconfd\0"
 
@@ -118,7 +117,7 @@ enum {
 
     PPP_OPT_IPCP_USESERVERDNS,         // 4 bytes
     PPP_OPT_COMM_CONNECTSPEED,         // 4 bytes, actual connection speed
-    PPP_OPT_SERVICEID                  // string, name of the associated service in the cache
+    PPP_OPT_SERVICEID                  // string, name of the associated service in the store
 
 };
 
diff --git a/SystemConfiguration.fproj/v1Compatibility.c b/SystemConfiguration.fproj/v1Compatibility.c
new file mode 100644 (file)
index 0000000..9a233ab
--- /dev/null
@@ -0,0 +1,816 @@
+/*
+ * Copyright (c) 2001 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Modification History
+ *
+ * March 28, 2001              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
+
+#include "v1Compatibility.h"
+
+extern void __Initialize();
+
+typedef struct {
+
+       /* configuration data associated with key */
+       CFPropertyListRef       data;
+
+       /* instance value of last fetched data */
+       int                     instance;
+
+} SCDHandlePrivate, *SCDHandlePrivateRef;
+
+
+SCDHandleRef
+SCDHandleInit()
+{
+       SCDHandlePrivateRef privateHandle = CFAllocatorAllocate(NULL, sizeof(SCDHandlePrivate), 0);
+
+       /* set data */
+       privateHandle->data = NULL;
+
+       /* set instance */
+       privateHandle->instance = 0;
+
+       return (SCDHandleRef)privateHandle;
+}
+
+
+void
+SCDHandleRelease(SCDHandleRef handle)
+{
+       SCDHandlePrivateRef privateHandle = (SCDHandlePrivateRef)handle;
+
+       if (privateHandle->data)
+               CFRelease(privateHandle->data);
+
+       CFAllocatorDeallocate(NULL, privateHandle);
+       return;
+}
+
+
+int
+SCDHandleGetInstance(SCDHandleRef handle)
+{
+       SCDHandlePrivateRef privateHandle = (SCDHandlePrivateRef)handle;
+
+       return privateHandle->instance;
+}
+
+
+void
+_SCDHandleSetInstance(SCDHandleRef handle, int instance)
+{
+       SCDHandlePrivateRef privateHandle = (SCDHandlePrivateRef)handle;
+
+       privateHandle->instance = instance;
+       return;
+}
+
+
+CFPropertyListRef
+SCDHandleGetData(SCDHandleRef handle)
+{
+       SCDHandlePrivateRef privateHandle = (SCDHandlePrivateRef)handle;
+
+       if (privateHandle->data == NULL) {
+               return CFSTR("SCDHandleRef not initialized.");
+       }
+
+       return privateHandle->data;
+}
+
+
+void
+SCDHandleSetData(SCDHandleRef handle, CFPropertyListRef data)
+{
+       SCDHandlePrivateRef privateHandle = (SCDHandlePrivateRef)handle;
+
+       /* remove reference to data previously associated with handle */
+       if (privateHandle->data)
+               CFRelease(privateHandle->data);
+
+       /* associate new data with handle, keep a reference as needed */
+       privateHandle->data = data;
+       if (privateHandle->data)
+               CFRetain(privateHandle->data);
+
+       return;
+}
+
+static int
+convert_SCDStatus_To_SCStatus(SCDStatus status)
+{
+       switch (status) {
+               case SCD_OK                     : return kSCStatusOK;
+               case SCD_NOSESSION              : return kSCStatusNoStoreSession;
+               case SCD_NOSERVER               : return kSCStatusNoStoreServer;
+               case SCD_LOCKED                 : return kSCStatusLocked;
+               case SCD_NEEDLOCK               : return kSCStatusNeedLock;
+               case SCD_EACCESS                : return kSCStatusAccessError;
+               case SCD_NOKEY                  : return kSCStatusNoKey;
+               case SCD_EXISTS                 : return kSCStatusKeyExists;
+               case SCD_STALE                  : return kSCStatusStale;
+               case SCD_INVALIDARGUMENT        : return kSCStatusInvalidArgument;
+               case SCD_NOTIFIERACTIVE         : return kSCStatusNotifierActive;
+               case SCD_FAILED                 : return kSCStatusFailed;
+               default                         : return kSCStatusFailed;
+       }
+}
+
+SCDStatus
+SCDOpen(SCDSessionRef *session, CFStringRef name)
+{
+       SCDynamicStoreRef       newStore;
+
+       __Initialize();         /* initialize framework */
+
+       newStore = SCDynamicStoreCreate(NULL, name, NULL, NULL);
+       if (!newStore) {
+               return SCD_NOSERVER;
+       }
+
+       *session = (SCDSessionRef)newStore;
+       return SCD_OK;
+}
+
+SCDStatus
+SCDClose(SCDSessionRef *session)
+{
+       CFRelease(*session);
+       *session = NULL;
+       return SCD_OK;
+}
+
+SCDStatus
+SCDLock(SCDSessionRef session)
+{
+       return SCDynamicStoreLock((SCDynamicStoreRef)session) ? SCD_OK : SCD_FAILED;
+}
+
+SCDStatus
+SCDUnlock(SCDSessionRef session)
+{
+       return SCDynamicStoreUnlock((SCDynamicStoreRef)session) ? SCD_OK : SCD_FAILED;
+}
+
+SCDStatus
+SCDList(SCDSessionRef session, CFStringRef key, int regexOptions, CFArrayRef *subKeys)
+{
+       CFMutableStringRef      pattern;
+
+       pattern = CFStringCreateMutableCopy(NULL, 0, key);
+       if ((regexOptions & kSCDRegexKey) != kSCDRegexKey) {
+               CFStringAppend(pattern, CFSTR(".*"));
+       }
+       *subKeys = SCDynamicStoreCopyKeyList((SCDynamicStoreRef)session, pattern);
+       CFRelease(pattern);
+
+       return (*subKeys) ? SCD_OK : SCD_FAILED;
+}
+
+SCDStatus
+SCDAdd(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
+{
+       CFTypeRef       value = SCDHandleGetData(handle);
+       return SCDynamicStoreAddValue((SCDynamicStoreRef)session, key, value) ? SCD_OK : SCD_EXISTS;
+}
+
+SCDStatus
+SCDAddSession(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
+{
+       CFTypeRef       value = SCDHandleGetData(handle);
+       return SCDynamicStoreAddTemporaryValue((SCDynamicStoreRef)session, key, value) ? SCD_OK : SCD_EXISTS;
+}
+
+SCDStatus
+SCDGet(SCDSessionRef session, CFStringRef key, SCDHandleRef *handle)
+{
+       CFTypeRef       value;
+
+       value = SCDynamicStoreCopyValue((SCDynamicStoreRef)session, key);
+       if (value) {
+               *handle = SCDHandleInit();
+               SCDHandleSetData(*handle, value);
+               CFRelease(value);
+               return SCD_OK;
+       }
+       return SCD_NOKEY;
+}
+
+SCDStatus
+SCDSet(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
+{
+       CFTypeRef       value = SCDHandleGetData(handle);
+       return SCDynamicStoreSetValue((SCDynamicStoreRef)session, key, value) ? SCD_OK : SCD_EXISTS;
+}
+
+SCDStatus
+SCDRemove(SCDSessionRef session, CFStringRef key)
+{
+       return SCDynamicStoreRemoveValue((SCDynamicStoreRef)session, key) ? SCD_OK : SCD_NOKEY;
+}
+
+SCDStatus
+SCDTouch(SCDSessionRef session, CFStringRef key)
+{
+       return SCDynamicStoreTouchValue((SCDynamicStoreRef)session, key) ? SCD_OK : SCD_FAILED;
+}
+
+SCDStatus
+SCDNotifierList(SCDSessionRef session, int regexOptions, CFArrayRef *notifierKeys)
+{
+       *notifierKeys = SCDynamicStoreCopyWatchedKeyList((SCDynamicStoreRef)session,
+                                                        ((regexOptions & kSCDRegexKey) == kSCDRegexKey));
+       return (*notifierKeys) ? SCD_OK : SCD_FAILED;
+}
+
+SCDStatus
+SCDNotifierAdd(SCDSessionRef session, CFStringRef key, int regexOptions)
+{
+       return SCDynamicStoreAddWatchedKey((SCDynamicStoreRef)session,
+                                          key,
+                                          ((regexOptions & kSCDRegexKey) == kSCDRegexKey)) ? SCD_OK : SCD_EXISTS;
+}
+
+SCDStatus
+SCDNotifierRemove(SCDSessionRef session, CFStringRef key, int regexOptions)
+{
+       return SCDynamicStoreRemoveWatchedKey((SCDynamicStoreRef)session,
+                                             key,
+                                             ((regexOptions & kSCDRegexKey) == kSCDRegexKey)) ? SCD_OK : SCD_NOKEY;
+}
+
+SCDStatus
+SCDNotifierGetChanges(SCDSessionRef session, CFArrayRef *changedKeys)
+{
+       *changedKeys = SCDynamicStoreCopyNotifiedKeys((SCDynamicStoreRef)session);
+       return (*changedKeys) ? SCD_OK : SCD_FAILED;
+}
+
+SCDStatus
+SCDNotifierWait(SCDSessionRef session)
+{
+       return SCDynamicStoreNotifyWait((SCDynamicStoreRef)session) ? SCD_OK : SCD_FAILED;
+}
+
+SCDStatus
+SCDNotifierInformViaCallback(SCDSessionRef session, SCDCallbackRoutine_t func, void *arg)
+{
+       return SCDynamicStoreNotifyCallback((SCDynamicStoreRef)session,
+                                           CFRunLoopGetCurrent(),
+                                           (SCDynamicStoreCallBack_v1)func,
+                                           arg) ? SCD_OK : SCD_NOTIFIERACTIVE;
+}
+
+SCDStatus
+SCDNotifierInformViaMachPort(SCDSessionRef session, mach_msg_id_t msgid, mach_port_t *port)
+{
+       return SCDynamicStoreNotifyMachPort((SCDynamicStoreRef)session, msgid, port) ? SCD_OK : SCD_NOTIFIERACTIVE;
+}
+
+SCDStatus
+SCDNotifierInformViaFD(SCDSessionRef session, int32_t identifier, int *fd)
+{
+       return SCDynamicStoreNotifyFileDescriptor((SCDynamicStoreRef)session, identifier, fd) ? SCD_OK : SCD_NOTIFIERACTIVE;
+}
+
+SCDStatus
+SCDNotifierInformViaSignal(SCDSessionRef session, pid_t pid, int sig)
+{
+       return SCDynamicStoreNotifySignal((SCDynamicStoreRef)session, pid, sig) ? SCD_OK : SCD_NOTIFIERACTIVE;
+}
+
+SCDStatus
+SCDNotifierCancel(SCDSessionRef session)
+{
+       return SCDynamicStoreNotifyCancel((SCDynamicStoreRef)session) ? SCD_OK : SCD_NOTIFIERACTIVE;
+}
+
+SCDStatus
+SCDSnapshot(SCDSessionRef session)
+{
+       return SCDynamicStoreSnapshot((SCDynamicStoreRef)session) ? SCD_OK : SCD_NOTIFIERACTIVE;
+}
+
+int
+SCDOptionGet(SCDSessionRef session, int option)
+{
+       int             value     = 0;
+
+       if (session) {
+               static  Boolean warned = FALSE;
+               if (!warned) {
+                       SCLog(TRUE, LOG_NOTICE, CFSTR("per-session options are no longer supported, using global options."));
+                       warned = TRUE;
+               }
+       }
+
+       switch (option) {
+               case kSCDOptionDebug :
+                       value = _sc_debug ? 1 : 0;
+                       break;
+
+               case kSCDOptionVerbose :
+                       value = _sc_verbose ? 1 : 0;
+                       break;
+
+               case kSCDOptionUseSyslog :
+                       value = _sc_log ? 1 : 0;
+                       break;
+
+               case kSCDOptionUseCFRunLoop :
+                       value = 1;      /* always TRUE */
+                       break;
+       }
+
+       return value;
+}
+
+void
+SCDOptionSet(SCDSessionRef session, int option, int value)
+{
+       if (session) {
+               static Boolean  warned = FALSE;
+               if (!warned) {
+                       SCLog(TRUE, LOG_NOTICE, CFSTR("per-session options are no longer supported, using global options."));
+                       warned = TRUE;
+               }
+       }
+
+       switch (option) {
+               case kSCDOptionDebug :
+                       _sc_debug = (value != 0);
+                       _sc_log   = (value == 0);
+                       break;
+
+               case kSCDOptionVerbose :
+                       _sc_verbose = (value != 0);
+                       break;
+
+               case kSCDOptionUseSyslog :
+               {
+                       _sc_log = (value != 0);
+                       break;
+               }
+
+               case kSCDOptionUseCFRunLoop :
+               {
+                       static Boolean warned = FALSE;
+                       if ((value == FALSE) && !warned) {
+                               SCLog(TRUE, LOG_NOTICE, CFSTR("The kSCDOptionUseCFRunLoop option can no longer be set FALSE.  The"));
+                               SCLog(TRUE, LOG_NOTICE, CFSTR("SCDNotifierInformViaCallback requires the use of a CFRunLoop."));
+                               warned = TRUE;
+                       }
+                       break;
+               }
+       }
+
+       return;
+}
+
+void
+SCDSessionLog(SCDSessionRef session, int level, CFStringRef formatString, ...)
+{
+       va_list         argList;
+       FILE            *f = (LOG_PRI(level) > LOG_NOTICE) ? stderr : stdout;
+       CFStringRef     resultString;
+
+       if ((LOG_PRI(level) == LOG_DEBUG) && !SCDOptionGet(session, kSCDOptionVerbose)) {
+               /* it's a debug message and we haven't requested verbose logging */
+               return;
+       }
+
+       va_start(argList, formatString);
+       resultString = CFStringCreateWithFormatAndArguments(NULL, NULL, formatString, argList);
+       va_end(argList);
+
+       if (SCDOptionGet(session, kSCDOptionUseSyslog)) {
+               __SCLog(level, resultString);
+       } else {
+               CFStringRef     newString;
+
+               /* add a new-line */
+               newString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@\n"), resultString);
+               __SCPrint(f, newString);
+               CFRelease(newString);
+       }
+       CFRelease(resultString);
+}
+
+void
+SCDLog(int level, CFStringRef formatString, ...)
+{
+       va_list         argList;
+       FILE            *f = (LOG_PRI(level) > LOG_NOTICE) ? stderr : stdout;
+       CFStringRef     resultString;
+
+       if ((LOG_PRI(level) == LOG_DEBUG) && !SCDOptionGet(NULL, kSCDOptionVerbose)) {
+               /* it's a debug message and we haven't requested verbose logging */
+               return;
+       }
+
+       va_start(argList, formatString);
+       resultString = CFStringCreateWithFormatAndArguments(NULL, NULL, formatString, argList);
+       va_end(argList);
+
+       if (SCDOptionGet(NULL, kSCDOptionUseSyslog)) {
+               __SCLog(level, resultString);
+       } else {
+               CFStringRef     newString;
+
+               /* add a new-line */
+               newString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@\n"), resultString);
+               __SCPrint(f, newString);
+               CFRelease(newString);
+       }
+       CFRelease(resultString);
+}
+
+const char *
+SCDError(SCDStatus status)
+{
+       return SCErrorString(convert_SCDStatus_To_SCStatus(status));
+}
+
+CFStringRef
+SCDKeyCreate(CFStringRef fmt, ...)
+{
+       va_list args;
+       va_start(args, fmt);
+       return (CFStringCreateWithFormatAndArguments(NULL,
+                                                    NULL,
+                                                    fmt,
+                                                    args));
+}
+
+CFStringRef
+SCDKeyCreateNetworkGlobalEntity(CFStringRef domain, CFStringRef entity)
+{
+       return SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, domain, entity);
+}
+
+CFStringRef
+SCDKeyCreateNetworkInterface(CFStringRef domain)
+{
+       return SCDynamicStoreKeyCreateNetworkInterface(NULL, domain);
+}
+
+CFStringRef
+SCDKeyCreateNetworkInterfaceEntity(CFStringRef domain, CFStringRef ifname, CFStringRef entity)
+{
+       return SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL, domain, ifname, entity);
+}
+
+CFStringRef
+SCDKeyCreateNetworkServiceEntity(CFStringRef domain, CFStringRef serviceID, CFStringRef entity)
+{
+       return SCDynamicStoreKeyCreateNetworkServiceEntity(NULL, domain, serviceID, entity);
+}
+
+static int
+convert_SCPStatus_To_SCStatus(SCPStatus status)
+{
+       switch (status) {
+               case SCP_OK                     : return kSCStatusOK;
+               case SCP_NOSESSION              : return kSCStatusNoPrefsSession;
+               case SCP_BUSY                   : return kSCStatusPrefsBusy;
+               case SCP_NEEDLOCK               : return kSCStatusNeedLock;
+               case SCP_EACCESS                : return kSCStatusAccessError;
+               case SCP_ENOENT                 : return kSCStatusNoConfigFile;
+               case SCP_BADCF                  : return kSCStatusFailed;
+               case SCP_NOKEY                  : return kSCStatusNoKey;
+               case SCP_NOLINK                 : return kSCStatusNoLink;
+               case SCP_EXISTS                 : return kSCStatusKeyExists;
+               case SCP_STALE                  : return kSCStatusStale;
+               case SCP_INVALIDARGUMENT        : return kSCStatusInvalidArgument;
+               case SCP_FAILED                 : return kSCStatusFailed;
+               default                         : return kSCStatusFailed;
+       }
+}
+
+SCPStatus
+SCPOpen(SCPSessionRef *session, CFStringRef name, CFStringRef prefsID, int options)
+{
+       CFArrayRef      keys;
+       CFIndex         nKeys;
+
+       __Initialize();         /* initialize framework */
+
+       *session = (SCPSessionRef)SCPreferencesCreate(NULL, name, prefsID);
+       if (*session == NULL) {
+               return SCP_EACCESS;
+       }
+
+       keys  = SCPreferencesCopyKeyList(*session);
+       nKeys = CFArrayGetCount(keys);
+       CFRelease(keys);
+
+       if ((nKeys == 0) &&
+           ((options & kSCPOpenCreatePrefs) != kSCPOpenCreatePrefs)) {
+               /* if no keys and not requesting the file be created */
+               return SCP_ENOENT;
+       }
+
+       return SCP_OK;
+}
+
+SCPStatus
+SCPUserOpen(SCPSessionRef *session, CFStringRef name, CFStringRef prefsID, CFStringRef user, int options)
+{
+       CFArrayRef      keys;
+       CFIndex         nKeys;
+
+       __Initialize();         /* initialize framework */
+
+       *session = (SCPSessionRef)SCUserPreferencesCreate(NULL, name, prefsID, user);
+       if (*session == NULL) {
+               return SCP_EACCESS;
+       }
+
+       keys  = SCPreferencesCopyKeyList(*session);
+       nKeys = CFArrayGetCount(keys);
+       CFRelease(keys);
+
+       if ((nKeys == 0) &&
+           ((options & kSCPOpenCreatePrefs) != kSCPOpenCreatePrefs)) {
+               /* if no keys and not requesting the file be created */
+               return SCP_ENOENT;
+       }
+
+       return SCP_OK;
+}
+
+SCPStatus
+SCPClose(SCPSessionRef *session)
+{
+       CFRelease(*session);
+       *session = NULL;
+       return SCD_OK;
+}
+
+SCPStatus
+SCPLock(SCPSessionRef session, boolean_t wait)
+{
+       /* XXXXX: old API error codes included kSCStatusPrefsBusy, kSCStatusAccessError, and kSCStatusStale */
+       return SCPreferencesLock((SCPreferencesRef)session, wait) ? SCP_OK : SCP_FAILED;
+}
+
+SCPStatus
+SCPCommit(SCPSessionRef session)
+{
+       /* XXXXX: old API error codes included kSCStatusAccessError, kSCStatusStale */
+       return SCPreferencesCommitChanges((SCPreferencesRef)session) ? SCP_OK : SCP_FAILED;
+}
+
+SCPStatus
+SCPApply(SCPSessionRef session)
+{
+       return SCPreferencesApplyChanges((SCPreferencesRef)session) ? SCP_OK : SCP_EACCESS;
+}
+
+SCPStatus
+SCPUnlock(SCPSessionRef session)
+{
+       return SCPreferencesUnlock((SCPreferencesRef)session) ? SCP_OK : SCP_FAILED;
+}
+
+SCPStatus
+SCPGetSignature(SCPSessionRef session, CFDataRef *signature)
+{
+       *signature = SCPreferencesGetSignature((SCPreferencesRef)session);
+       return (*signature) ? SCP_OK : SCP_FAILED;
+}
+
+SCPStatus
+SCPList(SCPSessionRef session, CFArrayRef *keys)
+{
+       *keys = SCPreferencesCopyKeyList((SCPreferencesRef)session);
+       return (*keys) ? SCP_OK : SCP_FAILED;
+}
+
+SCPStatus
+SCPGet(SCPSessionRef session, CFStringRef key, CFPropertyListRef *data)
+{
+       *data = SCPreferencesGetValue((SCPreferencesRef)session, key);
+       return (*data) ? SCP_OK : SCP_NOKEY;
+}
+
+SCPStatus
+SCPAdd(SCPSessionRef session, CFStringRef key, CFPropertyListRef data)
+{
+       return SCPreferencesAddValue((SCPreferencesRef)session, key, data) ? SCP_OK : SCP_EXISTS;
+}
+
+SCPStatus
+SCPSet(SCPSessionRef session, CFStringRef key, CFPropertyListRef data)
+{
+       return SCPreferencesSetValue((SCPreferencesRef)session, key, data) ? SCP_OK : SCP_FAILED;
+}
+
+SCPStatus
+SCPRemove(SCPSessionRef session, CFStringRef key)
+{
+       return SCPreferencesRemoveValue((SCPreferencesRef)session, key) ? SCP_OK : SCP_NOKEY;
+}
+
+CFStringRef
+SCPNotificationKeyCreate(CFStringRef prefsID, int keyType)
+{
+       return SCDynamicStoreKeyCreatePreferences(NULL, prefsID, keyType);
+}
+
+CFStringRef
+SCPUserNotificationKeyCreate(CFStringRef prefsID, CFStringRef user, int keyType)
+{
+       return SCDynamicStoreKeyCreateUserPreferences(NULL, prefsID, user, keyType);
+}
+
+SCPStatus
+SCPPathCreateUniqueChild(SCPSessionRef session, CFStringRef prefix, CFStringRef *newPath)
+{
+       *newPath = SCPreferencesPathCreateUniqueChild((SCPreferencesRef)session, prefix);
+       return (*newPath) ? SCP_OK : SCP_NOKEY;
+}
+
+SCPStatus
+SCPPathGetValue(SCPSessionRef session, CFStringRef path, CFDictionaryRef *value)
+{
+       *value = SCPreferencesPathGetValue((SCPreferencesRef)session, path);
+       return (*value) ? SCP_OK : SCP_NOKEY;
+}
+
+SCPStatus
+SCPPathGetLink(SCPSessionRef session, CFStringRef path, CFStringRef *link)
+{
+       *link = SCPreferencesPathGetLink((SCPreferencesRef)session, path);
+       return (*link) ? SCP_OK : SCP_NOKEY;
+}
+
+SCPStatus
+SCPPathSetValue(SCPSessionRef session, CFStringRef path, CFDictionaryRef value)
+{
+       return SCPreferencesPathSetValue((SCPreferencesRef)session, path, value) ? SCP_OK : SCP_FAILED;
+}
+
+SCPStatus
+SCPPathSetLink(SCPSessionRef session, CFStringRef path, CFStringRef link)
+{
+       return SCPreferencesPathSetLink((SCPreferencesRef)session, path, link) ? SCP_OK : SCP_FAILED;
+}
+
+SCPStatus
+SCPPathRemove(SCPSessionRef session, CFStringRef path)
+{
+       return SCPreferencesPathRemoveValue((SCPreferencesRef)session, path) ? SCP_OK : SCP_NOKEY;
+}
+
+const char *
+SCPError(SCPStatus status)
+{
+       return SCErrorString(convert_SCPStatus_To_SCStatus(status));
+}
+
+CFStringRef
+SCDKeyCreateConsoleUser()
+{
+       return SCDynamicStoreKeyCreateConsoleUser(NULL);
+}
+
+SCDStatus
+SCDConsoleUserGet(char *user, int userlen, uid_t *uid, gid_t *gid)
+{
+       CFStringRef     consoleUser;
+
+       consoleUser = SCDynamicStoreCopyConsoleUser(NULL, uid, gid);
+       if (!consoleUser) {
+               return SCD_NOKEY;
+       }
+
+       if (user && (userlen > 0)) {
+               CFIndex         len;
+               CFRange         range;
+
+               bzero(user, userlen);
+               range = CFRangeMake(0, CFStringGetLength(consoleUser));
+               (void) CFStringGetBytes(consoleUser,
+                                       range,
+                                       kCFStringEncodingMacRoman,
+                                       0,
+                                       FALSE,
+                                       user,
+                                       userlen,
+                                       &len);
+       }
+       CFRelease(consoleUser);
+       return SCD_OK;
+}
+
+SCDStatus
+SCDConsoleUserSet(const char *user, uid_t uid, gid_t gid)
+{
+       return SCDynamicStoreSetConsoleUser(NULL, user, uid, gid) ? SCD_OK : SCD_FAILED;
+}
+
+CFStringRef
+SCDKeyCreateHostName()
+{
+       return SCDynamicStoreKeyCreateComputerName(NULL);
+}
+
+SCDStatus
+SCDHostNameGet(CFStringRef *name, CFStringEncoding *nameEncoding)
+{
+       *name = SCDynamicStoreCopyComputerName(NULL, nameEncoding);
+       return (*name) ? SCD_OK : SCD_FAILED;
+}
+
+static SCNStatus
+convertReachability(int newFlags, int *oldFlags)
+{
+       SCNStatus       scn_status = SCN_REACHABLE_NO;
+
+       if (newFlags & kSCNetworkFlagsTransientConnection) {
+               if (oldFlags) {
+                       *oldFlags |= kSCNFlagsTransientConnection;
+               }
+       }
+
+       if (newFlags & kSCNetworkFlagsReachable) {
+               scn_status = SCN_REACHABLE_YES;
+
+               if (newFlags & kSCNetworkFlagsConnectionRequired) {
+                       scn_status = SCN_REACHABLE_CONNECTION_REQUIRED;
+               }
+
+               if (newFlags & kSCNetworkFlagsConnectionAutomatic) {
+                       if (oldFlags) {
+                               *oldFlags |= kSCNFlagsConnectionAutomatic;
+                       }
+               }
+
+               if (newFlags & kSCNetworkFlagsInterventionRequired) {
+                       if (oldFlags) {
+                               *oldFlags |= kSCNFlagsInterventionRequired;
+                       }
+               }
+       }
+
+       return scn_status;
+}
+
+SCNStatus
+SCNIsReachableByAddress(const struct sockaddr *address, const int addrlen, int *flags, const char **errorMessage)
+{
+       SCNetworkConnectionFlags        newFlags;
+
+       if (!SCNetworkCheckReachabilityByAddress(address, addrlen, &newFlags)) {
+               if (errorMessage) {
+                       *errorMessage = SCErrorString(kSCStatusReachabilityUnknown);
+               }
+               return SCN_REACHABLE_UNKNOWN;
+       }
+
+       return convertReachability(newFlags, flags);
+
+}
+
+SCNStatus
+SCNIsReachableByName(const char *nodename, int *flags, const char **errorMessage)
+{
+       SCNetworkConnectionFlags        newFlags;
+
+       if (!SCNetworkCheckReachabilityByName(nodename, &newFlags)) {
+               if (errorMessage) {
+                       *errorMessage = SCErrorString(kSCStatusReachabilityUnknown);
+               }
+               return SCN_REACHABLE_UNKNOWN;
+       }
+
+       return convertReachability(newFlags, flags);
+}
diff --git a/SystemConfiguration.fproj/v1Compatibility.h b/SystemConfiguration.fproj/v1Compatibility.h
new file mode 100644 (file)
index 0000000..a99e435
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2001 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _V1COMPATIBILITY_H
+#define        _V1COMPATIBILITY_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/syslog.h>
+#include <mach/message.h>
+#include <CoreFoundation/CoreFoundation.h>
+
+
+#define        kSCCacheDomainFile              kSCDynamicStoreDomainFile
+#define        kSCCacheDomainPlugin            kSCDynamicStoreDomainPlugin
+#define        kSCCacheDomainSetup             kSCDynamicStoreDomainSetup
+#define        kSCCacheDomainState             kSCDynamicStoreDomainState
+#define        kSCCacheDomainPrefs             kSCDynamicStoreDomainPrefs
+#define        kSCCachePropSetupCurrentSet     kSCDynamicStorePropSetupCurrentSet
+#define        kSCCachePropSetupLastUpdated    kSCDynamicStorePropSetupLastUpdated
+#define        kSCCachePropNetInterfaces       kSCDynamicStorePropNetInterfaces
+#define        kSCCachePropNetPrimaryInterface kSCDynamicStorePropNetPrimaryInterface
+#define        kSCCachePropNetPrimaryService   kSCDynamicStorePropNetPrimaryService
+#define        kSCCachePropNetServiceIDs       kSCDynamicStorePropNetServiceIDs
+
+
+typedef enum {
+       SCD_OK                  = 0,    /* Success */
+       SCD_NOSESSION           = 1,    /* Configuration daemon session not active */
+       SCD_NOSERVER            = 2,    /* Configuration daemon not (no longer) available */
+       SCD_LOCKED              = 3,    /* Lock already held */
+       SCD_NEEDLOCK            = 4,    /* Lock required for this operation */
+       SCD_EACCESS             = 5,    /* Permission denied (must be root to obtain lock) */
+       SCD_NOKEY               = 6,    /* No such key */
+       SCD_EXISTS              = 7,    /* Data associated with key already defined */
+       SCD_STALE               = 8,    /* Write attempted on stale version of object */
+       SCD_INVALIDARGUMENT     = 9,    /* Invalid argument */
+       SCD_NOTIFIERACTIVE      = 10,   /* Notifier is currently active */
+       SCD_FAILED              = 9999  /* Generic error */
+} SCDStatus;
+
+typedef const struct __SCDSession *    SCDSessionRef;
+
+typedef const struct __SCDHandle *     SCDHandleRef;
+
+typedef enum {
+       kSCDRegexKey            = 0100000,      /* pattern string is a regular expression */
+} SCDKeyOption;
+
+typedef enum {
+       kSCDOptionDebug         = 0,    /* Enable debugging */
+       kSCDOptionVerbose       = 1,    /* Enable verbose logging */
+       kSCDOptionUseSyslog     = 2,    /* Use syslog(3) for log messages */
+       kSCDOptionUseCFRunLoop  = 3,    /* Calling application is CFRunLoop() based */
+} SCDOption;
+
+typedef boolean_t (*SCDCallbackRoutine_t)      (SCDSessionRef  session,
+                                                void           *context);
+
+typedef void (*SCDBundleStartRoutine_t) (const char *bundlePath,
+                                        const char *bundleName);
+
+typedef void (*SCDBundlePrimeRoutine_t) ();
+
+typedef enum {
+       SCP_OK                  = 0,    /* Success */
+       SCP_NOSESSION           = 1024, /* Preference session not active */
+       SCP_BUSY                = 1025, /* Preferences update currently in progress */
+       SCP_NEEDLOCK            = 1026, /* Lock required for this operation */
+       SCP_EACCESS             = 1027, /* Permission denied */
+       SCP_ENOENT              = 1028, /* Configuration file not found */
+       SCP_BADCF               = 1029, /* Configuration file corrupt */
+       SCP_NOKEY               = 1030, /* No such key */
+       SCP_NOLINK              = 1031, /* No such link */
+       SCP_EXISTS              = 1032, /* No such key */
+       SCP_STALE               = 1033, /* Write attempted on stale version of object */
+       SCP_INVALIDARGUMENT     = 1034, /* Invalid argument */
+       SCP_FAILED              = 9999  /* Generic error */
+} SCPStatus;
+
+typedef enum {
+       kSCPOpenCreatePrefs     = 1,    /* create preferences file if not found */
+} SCPOption;
+
+typedef enum {
+       kSCPKeyLock     = 1,
+       kSCPKeyCommit   = 2,
+       kSCPKeyApply    = 3,
+} SCPKeyType;
+
+typedef void *         SCPSessionRef;
+
+typedef enum {
+       SCN_REACHABLE_UNKNOWN                   = -1,
+       SCN_REACHABLE_NO                        =  0,
+       SCN_REACHABLE_CONNECTION_REQUIRED       =  1,
+       SCN_REACHABLE_YES                       =  2,
+} SCNStatus;
+
+typedef enum {
+       kSCNFlagsTransientConnection    =  1<<0,
+       kSCNFlagsConnectionAutomatic    =  1<<1,
+       kSCNFlagsInterventionRequired   =  1<<2,
+} SCNConnectionFlags;
+
+__BEGIN_DECLS
+
+/*
+ * handle APIs
+ */
+
+SCDHandleRef   SCDHandleInit                   ();
+
+void           SCDHandleRelease                (SCDHandleRef           handle);
+
+int            SCDHandleGetInstance            (SCDHandleRef           handle);
+
+void           _SCDHandleSetInstance           (SCDHandleRef           handle,
+                                                int                    instance);
+
+CFPropertyListRef SCDHandleGetData             (SCDHandleRef           handle);
+
+void           SCDHandleSetData                (SCDHandleRef           handle,
+                                                CFPropertyListRef      data);
+
+/*
+ * store access APIs
+ */
+
+SCDStatus      SCDOpen                         (SCDSessionRef          *session,
+                                                CFStringRef            name);
+
+SCDStatus      SCDClose                        (SCDSessionRef          *session);
+
+SCDStatus      SCDLock                         (SCDSessionRef          session);
+
+SCDStatus      SCDUnlock                       (SCDSessionRef          session);
+
+SCDStatus      SCDList                         (SCDSessionRef          session,
+                                                CFStringRef            key,
+                                                int                    regexOptions,
+                                                CFArrayRef             *subKeys);
+
+SCDStatus      SCDAdd                          (SCDSessionRef          session,
+                                                CFStringRef            key,
+                                                SCDHandleRef           handle);
+
+SCDStatus      SCDAddSession                   (SCDSessionRef          session,
+                                                CFStringRef            key,
+                                                SCDHandleRef           handle);
+
+SCDStatus      SCDGet                          (SCDSessionRef          session,
+                                                CFStringRef            key,
+                                                SCDHandleRef           *handle);
+
+SCDStatus      SCDSet                          (SCDSessionRef          session,
+                                                CFStringRef            key,
+                                                SCDHandleRef           handle);
+
+SCDStatus      SCDRemove                       (SCDSessionRef          session,
+                                                CFStringRef            key);
+
+SCDStatus      SCDTouch                        (SCDSessionRef          session,
+                                               CFStringRef             key);
+
+SCDStatus      SCDNotifierList                 (SCDSessionRef          session,
+                                                int                    regexOptions,
+                                                CFArrayRef             *changedKeys);
+
+SCDStatus      SCDNotifierAdd                  (SCDSessionRef          session,
+                                                CFStringRef            key,
+                                                int                    regexOptions);
+
+SCDStatus      SCDNotifierRemove               (SCDSessionRef          session,
+                                                CFStringRef            key,
+                                                int                    regexOptions);
+
+SCDStatus      SCDNotifierGetChanges           (SCDSessionRef          session,
+                                                CFArrayRef             *notifierKeys);
+
+SCDStatus      SCDNotifierWait                 (SCDSessionRef          session);
+
+SCDStatus      SCDNotifierInformViaCallback    (SCDSessionRef          session,
+                                                SCDCallbackRoutine_t   func,
+                                                void                   *arg);
+
+SCDStatus      SCDNotifierInformViaMachPort    (SCDSessionRef          session,
+                                                mach_msg_id_t          msgid,
+                                                mach_port_t            *port);
+
+SCDStatus      SCDNotifierInformViaFD          (SCDSessionRef          session,
+                                                int32_t                identifier,
+                                                int                    *fd);
+
+SCDStatus      SCDNotifierInformViaSignal      (SCDSessionRef          session,
+                                                pid_t                  pid,
+                                                int                    sig);
+
+SCDStatus      SCDNotifierCancel               (SCDSessionRef          session);
+
+SCDStatus      SCDSnapshot                     (SCDSessionRef          session);
+
+int            SCDOptionGet                    (SCDSessionRef          session,
+                                                int                    option);
+
+void           SCDOptionSet                    (SCDSessionRef          session,
+                                                int                    option,
+                                                int                    value);
+
+void           SCDSessionLog                   (SCDSessionRef          session,
+                                                int                    level,
+                                                CFStringRef            formatString,
+                                                ...);
+
+void           SCDLog                          (int                    level,
+                                                CFStringRef            formatString,
+                                                ...);
+
+const char *   SCDError                        (SCDStatus              status);
+
+/*
+ * store/preference keys
+ */
+
+CFStringRef    SCDKeyCreate                            (CFStringRef    fmt,
+                                                        ...);
+
+CFStringRef    SCDKeyCreateNetworkGlobalEntity         (CFStringRef    domain,
+                                                        CFStringRef    entity);
+
+CFStringRef    SCDKeyCreateNetworkInterface            (CFStringRef    domain);
+
+CFStringRef    SCDKeyCreateNetworkInterfaceEntity      (CFStringRef    domain,
+                                                        CFStringRef    ifname,
+                                                        CFStringRef    entity);
+
+CFStringRef    SCDKeyCreateNetworkServiceEntity        (CFStringRef    domain,
+                                                        CFStringRef    serviceID,
+                                                        CFStringRef    entity);
+
+/*
+ * preference APIs
+ */
+
+SCPStatus      SCPOpen                         (SCPSessionRef          *session,
+                                                CFStringRef            name,
+                                                CFStringRef            prefsID,
+                                                int                    options);
+
+SCPStatus      SCPUserOpen                     (SCPSessionRef          *session,
+                                                CFStringRef            name,
+                                                CFStringRef            prefsID,
+                                                CFStringRef            user,
+                                                int                    options);
+
+SCPStatus      SCPClose                        (SCPSessionRef          *session);
+
+SCPStatus      SCPLock                         (SCPSessionRef          session,
+                                                boolean_t              wait);
+
+SCPStatus      SCPCommit                       (SCPSessionRef          session);
+
+SCPStatus      SCPApply                        (SCPSessionRef          session);
+
+SCPStatus      SCPUnlock                       (SCPSessionRef          session);
+
+SCPStatus      SCPGetSignature                 (SCPSessionRef          session,
+                                                CFDataRef              *signature);
+
+SCPStatus      SCPList                         (SCPSessionRef          session,
+                                                CFArrayRef             *keys);
+
+SCPStatus      SCPGet                          (SCPSessionRef          session,
+                                                CFStringRef            key,
+                                                CFPropertyListRef      *data);
+
+SCPStatus      SCPAdd                          (SCPSessionRef          session,
+                                                CFStringRef            key,
+                                                CFPropertyListRef      data);
+
+SCPStatus      SCPSet                          (SCPSessionRef          session,
+                                                CFStringRef            key,
+                                                CFPropertyListRef      data);
+
+SCPStatus      SCPRemove                       (SCPSessionRef          session,
+                                                CFStringRef            key);
+
+SCPStatus      SCPPathCreateUniqueChild        (SCPSessionRef          session,
+                                                CFStringRef            prefix,
+                                                CFStringRef            *newPath);
+
+SCPStatus      SCPPathGetValue                 (SCPSessionRef          session,
+                                                CFStringRef            path,
+                                                CFDictionaryRef        *value);
+
+SCPStatus      SCPPathGetLink                  (SCPSessionRef          session,
+                                                CFStringRef            path,
+                                                CFStringRef            *link);
+
+SCPStatus      SCPPathSetValue                 (SCPSessionRef          session,
+                                                CFStringRef            path,
+                                                CFDictionaryRef        value);
+
+SCPStatus      SCPPathSetLink                  (SCPSessionRef          session,
+                                                CFStringRef            path,
+                                                CFStringRef            link);
+
+SCPStatus      SCPPathRemove                   (SCPSessionRef          session,
+                                                CFStringRef            path);
+
+CFStringRef    SCPNotificationKeyCreate        (CFStringRef            prefsID,
+                                                int                    keyType);
+
+CFStringRef    SCPUserNotificationKeyCreate    (CFStringRef            prefsID,
+                                                CFStringRef            user,
+                                                int                    keyType);
+
+const char *   SCPError                        (SCPStatus              status);
+
+/*
+ * console user APIs
+ */
+
+CFStringRef    SCDKeyCreateConsoleUser         ();
+
+SCDStatus      SCDConsoleUserGet               (char                   *user,
+                                                int                    userlen,
+                                                uid_t                  *uid,
+                                                gid_t                  *gid);
+
+SCDStatus      SCDConsoleUserSet               (const char             *user,
+                                                uid_t                  uid,
+                                                gid_t                  gid);
+
+/*
+ * host name APIs
+ */
+
+CFStringRef    SCDKeyCreateHostName            ();
+
+SCDStatus      SCDHostNameGet                  (CFStringRef            *name,
+                                                CFStringEncoding       *nameEncoding);
+
+/*
+ * network reachability APIs
+ */
+SCNStatus      SCNIsReachableByAddress         (const struct sockaddr  *address,
+                                                const int              addrlen,
+                                                int                    *flags,
+                                                const char             **errorMessage);
+
+SCNStatus      SCNIsReachableByName            (const char             *nodename,
+                                                int                    *flags,
+                                                const char             **errorMessage);
+
+__END_DECLS
+
+#endif /* _V1COMPATIBILITY_H */
index d9c7c6fa2bf362fd8a4cc8fe4708ab2449f632ed..1579d6fe0bfcedd85caa378d1553ad1c43d4c732 100644 (file)
@@ -13,19 +13,20 @@ PROJECTVERSION = 2.8
 PROJECT_TYPE = Tool
 
 HFILES = configd.h _SCD.h configd_server.h notify_server.h\
-        plugin_support.h session.h notify.h
+         plugin_support.h session.h notify.h
 
 MFILES = configd.m
 
 CFILES = _SCD.c configd_server.c notify_server.c plugin_support.c\
-        session.c notify.c _configopen.c _configclose.c _configlock.c\
-        _configunlock.c _configlist.c _configadd.c _configadd_s.c\
-        _configget.c _configset.c _configremove.c _configtouch.c\
-        _notifyadd.c _notifyremove.c _notifychanges.c _notifyviaport.c\
-        _notifyviafd.c _notifyviasignal.c _notifycancel.c _snapshot.c
+         session.c notify.c _configopen.c _configclose.c _configlock.c\
+         _configunlock.c _configlist.c _configadd.c _configadd_s.c\
+         _configget.c _configset.c _configremove.c _configtouch.c\
+         _confignotify.c _notifyadd.c _notifyremove.c _notifychanges.c\
+         _notifyviaport.c _notifyviafd.c _notifyviasignal.c\
+         _notifycancel.c _snapshot.c
 
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\
-           h.template config.defs
+            h.template config.defs
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
@@ -39,7 +40,8 @@ DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
 
-FRAMEWORKS = -framework SystemConfiguration
+NEXTSTEP_PB_CFLAGS = -DUSE_SYSTEMCONFIGURATION_PUBLIC_APIS
+FRAMEWORKS = -framework CoreFoundation -framework SystemConfiguration
 
 
 NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
index 9174d1f032897ce1b567ba2f7a0f2db42c14d03e..225a4c547cad170100c83cd78452bc4f57514c06 100644 (file)
@@ -1,75 +1,77 @@
 {
-    DYNAMIC_CODE_GEN = YES;
+    DYNAMIC_CODE_GEN = YES; 
     FILESTABLE = {
-       FRAMEWORKS = (SystemConfiguration.framework);
-       FRAMEWORKSEARCH = ();
-       HEADERSEARCH = ();
-       H_FILES = (
-           configd.h,
-           _SCD.h,
-           configd_server.h,
-           notify_server.h,
-           plugin_support.h,
-           session.h,
-           notify.h
-       );
-       OTHER_LIBS = (objc);
-       OTHER_LINKED = (
-           configd.m,
-           _SCD.c,
-           configd_server.c,
-           notify_server.c,
-           plugin_support.c,
-           session.c,
-           notify.c,
-           _configopen.c,
-           _configclose.c,
-           _configlock.c,
-           _configunlock.c,
-           _configlist.c,
-           _configadd.c,
-           _configadd_s.c,
-           _configget.c,
-           _configset.c,
-           _configremove.c,
-           _configtouch.c,
-           _notifyadd.c,
-           _notifyremove.c,
-           _notifychanges.c,
-           _notifyviaport.c,
-           _notifyviafd.c,
-           _notifyviasignal.c,
-           _notifycancel.c,
-           _snapshot.c
-       );
-       OTHER_SOURCES = (
-           Makefile.preamble,
-           Makefile,
-           Makefile.postamble,
-           m.template,
-           h.template,
-           config.defs
-       );
-       PRECOMPILED_HEADERS = ();
-       PROJECT_HEADERS = ();
-       PUBLIC_HEADERS = ();
-       SUBPROJECTS = ();
-    };
-    LANGUAGE = English;
-    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles";
-    NEXTSTEP_BUILDTOOL = /usr/bin/gnumake;
-    NEXTSTEP_INSTALLDIR = /usr/sbin;
-    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac;
-    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc;
-    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make;
-    PDO_UNIX_INSTALLDIR = /bin;
-    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac";
-    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc";
-    PROJECTNAME = configd;
-    PROJECTTYPE = Tool;
-    PROJECTVERSION = 2.8;
-    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make;
-    WINDOWS_INSTALLDIR = /Library/Executables;
-    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe";
-    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc";
+        FRAMEWORKS = (CoreFoundation.framework, SystemConfiguration.framework); 
+        FRAMEWORKSEARCH = (); 
+        HEADERSEARCH = (); 
+        H_FILES = (
+            configd.h, 
+            _SCD.h, 
+            configd_server.h, 
+            notify_server.h, 
+            plugin_support.h, 
+            session.h, 
+            notify.h
+        ); 
+        OTHER_LIBS = (objc); 
+        OTHER_LINKED = (
+            configd.m, 
+            _SCD.c, 
+            configd_server.c, 
+            notify_server.c, 
+            plugin_support.c, 
+            session.c, 
+            notify.c, 
+            _configopen.c, 
+            _configclose.c, 
+            _configlock.c, 
+            _configunlock.c, 
+            _configlist.c, 
+            _configadd.c, 
+            _configadd_s.c, 
+            _configget.c, 
+            _configset.c, 
+            _configremove.c, 
+            _configtouch.c, 
+            _confignotify.c, 
+            _notifyadd.c, 
+            _notifyremove.c, 
+            _notifychanges.c, 
+            _notifyviaport.c, 
+            _notifyviafd.c, 
+            _notifyviasignal.c, 
+            _notifycancel.c, 
+            _snapshot.c
+        ); 
+        OTHER_SOURCES = (
+            Makefile.preamble, 
+            Makefile, 
+            Makefile.postamble, 
+            m.template, 
+            h.template, 
+            config.defs
+        ); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /usr/bin/gnumake; 
+    NEXTSTEP_COMPILEROPTIONS = "-DUSE_SYSTEMCONFIGURATION_PUBLIC_APIS"; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_INSTALLDIR = /bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = configd; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_INSTALLDIR = /Library/Executables; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
 }
index c89dd8c031b62df4d88abba928d9563c58038123..5d024af02f210fe7ca0b8527e15ca50bbcaef688 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * June 2, 2000                        Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 
 #include "configd.h"
 
 
-CFMutableDictionaryRef sessionData          = NULL;
+CFMutableDictionaryRef sessionData             = NULL;
+
+CFMutableDictionaryRef storeData               = NULL;
+CFMutableDictionaryRef storeData_s             = NULL;
 
-CFMutableDictionaryRef cacheData            = NULL;
-CFMutableDictionaryRef cacheData_s          = NULL;
+CFMutableSetRef                changedKeys             = NULL;
+CFMutableSetRef                changedKeys_s           = NULL;
 
-CFMutableSetRef                changedKeys          = NULL;
-CFMutableSetRef                changedKeys_s        = NULL;
+CFMutableSetRef                deferredRemovals        = NULL;
+CFMutableSetRef                deferredRemovals_s      = NULL;
 
-CFMutableSetRef                deferredRemovals     = NULL;
-CFMutableSetRef                deferredRemovals_s   = NULL;
+CFMutableSetRef                removedSessionKeys      = NULL;
+CFMutableSetRef                removedSessionKeys_s    = NULL;
 
-CFMutableSetRef                removedSessionKeys   = NULL;
-CFMutableSetRef                removedSessionKeys_s = NULL;
+CFMutableSetRef                needsNotification       = NULL;
 
-CFMutableSetRef                needsNotification    = NULL;
+int                    storeLocked             = 0;            /* > 0 if dynamic store locked */
 
 
 void
-_swapLockedCacheData()
+_swapLockedStoreData()
 {
        void    *temp;
 
-       temp                 = cacheData;
-       cacheData            = cacheData_s;
-       cacheData_s          = temp;
+       temp                 = storeData;
+       storeData            = storeData_s;
+       storeData_s          = temp;
 
        temp                 = changedKeys;
        changedKeys          = changedKeys_s;
@@ -80,9 +92,9 @@ _addWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
        CFNumberRef             refNum;
 
        /*
-        * Get the dictionary associated with this key out of the cache
+        * Get the dictionary associated with this key out of the store
         */
-       dict = CFDictionaryGetValue(cacheData, watchedKey);
+       dict = CFDictionaryGetValue(storeData, watchedKey);
        if (dict) {
                newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
        } else {
@@ -137,12 +149,12 @@ _addWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
        CFRelease(newWatcherRefs);
 
        /*
-        * Update the cache for this key
+        * Update the store for this key
         */
-       CFDictionarySetValue(cacheData, watchedKey, newDict);
+       CFDictionarySetValue(storeData, watchedKey, newDict);
        CFRelease(newDict);
 
-       SCDLog(LOG_DEBUG, CFSTR("  _addWatcher: %@, %@"), sessionNum, watchedKey);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  _addWatcher: %@, %@"), sessionNum, watchedKey);
 
        return;
 }
@@ -152,8 +164,8 @@ _addWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
  * _addRegexWatcherByKey()
  *
  * This is a CFDictionaryApplierFunction which will iterate over each key
- * defined in the "cacheData" dictionary. The arguments are the dictionary
- * key, it's associated cache dictionary, and a context structure which
+ * defined in the "storeData" dictionary. The arguments are the dictionary
+ * key, it's associated store dictionary, and a context structure which
  * includes the following:
  *
  *   1. the session which has just added a regex notification request
@@ -165,12 +177,12 @@ _addWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
 void
 _addRegexWatcherByKey(const void *key, void *val, void *context)
 {
-       CFStringRef     cacheStr  = key;
+       CFStringRef     storeStr  = key;
        CFDictionaryRef info      = val;
-       mach_port_t     sessionID = ((addContextRef)context)->session->server;
+       mach_port_t     sessionID = ((addContextRef)context)->store->server;
        regex_t         *preg     = ((addContextRef)context)->preg;
-       int             cacheKeyLen;
-       char            *cacheKey;
+       int             storeKeyLen;
+       char            *storeKey;
        CFNumberRef     sessionNum;
        int             reError;
        char            reErrBuf[256];
@@ -181,22 +193,22 @@ _addRegexWatcherByKey(const void *key, void *val, void *context)
                return;
        }
 
-       /* convert cache key to C string */
-       cacheKeyLen = CFStringGetLength(cacheStr) + 1;
-       cacheKey    = CFAllocatorAllocate(NULL, cacheKeyLen, 0);
-       if (!CFStringGetCString(cacheStr, cacheKey, cacheKeyLen, kCFStringEncodingMacRoman)) {
-               SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString: could not convert cache key to C string"));
-               CFAllocatorDeallocate(NULL, cacheKey);
+       /* convert store key to C string */
+       storeKeyLen = CFStringGetLength(storeStr) + 1;
+       storeKey    = CFAllocatorAllocate(NULL, storeKeyLen, 0);
+       if (!CFStringGetCString(storeStr, storeKey, storeKeyLen, kCFStringEncodingMacRoman)) {
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString: could not convert store key to C string"));
+               CFAllocatorDeallocate(NULL, storeKey);
                return;
        }
 
-       /* compare cache key to new notification keys regular expression pattern */
-       reError = regexec(preg, cacheKey, 0, NULL, 0);
+       /* compare store key to new notification keys regular expression pattern */
+       reError = regexec(preg, storeKey, 0, NULL, 0);
        switch (reError) {
                case 0 :
                        /* we've got a match */
                        sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionID);
-                       _addWatcher(sessionNum, cacheStr);
+                       _addWatcher(sessionNum, storeStr);
                        CFRelease(sessionNum);
                        break;
                case REG_NOMATCH :
@@ -204,10 +216,10 @@ _addRegexWatcherByKey(const void *key, void *val, void *context)
                        break;
                default :
                        reErrStrLen = regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
-                       SCDLog(LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
                        break;
        }
-       CFAllocatorDeallocate(NULL, cacheKey);
+       CFAllocatorDeallocate(NULL, storeKey);
 }
 
 
@@ -216,10 +228,10 @@ _addRegexWatcherByKey(const void *key, void *val, void *context)
  *
  * This is a CFDictionaryApplierFunction which will iterate over each session
  * defined in the "sessionData" dictionary. The arguments are the session
- * key, it's associated session dictionary, , and the cache key being added.
+ * key, it's associated session dictionary, , and the store key being added.
  *
  * If an active session includes any regular expression keys which match the
- * key being added to the "cacheData" dictionary then we mark this key as being
+ * key being added to the "storeData" dictionary then we mark this key as being
  * watched by the session.
  */
 void
@@ -250,7 +262,7 @@ _addRegexWatchersBySession(const void *key, void *val, void *context)
        newKeyLen = CFStringGetLength(addedKey) + 1;
        newKeyStr = CFAllocatorAllocate(NULL, newKeyLen, 0);
        if (!CFStringGetCString(addedKey, newKeyStr, newKeyLen, kCFStringEncodingMacRoman)) {
-               SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString: could not convert new key to C string"));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString: could not convert new key to C string"));
                CFAllocatorDeallocate(NULL, newKeyStr);
                return;
        }
@@ -280,7 +292,7 @@ _addRegexWatchersBySession(const void *key, void *val, void *context)
                                break;
                        default :
                                reErrStrLen = regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
-                               SCDLog(LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
+                               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
                                break;
                }
 
@@ -305,12 +317,12 @@ _removeWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
        CFNumberRef             refNum;
 
        /*
-        * Get the dictionary associated with this key out of the cache
+        * Get the dictionary associated with this key out of the store
         */
-       dict = CFDictionaryGetValue(cacheData, watchedKey);
+       dict = CFDictionaryGetValue(storeData, watchedKey);
        if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDWatchers) == FALSE)) {
                /* key doesn't exist (isn't this really fatal?) */
-               SCDLog(LOG_DEBUG, CFSTR("_removeWatcher: key not present in dictionary."));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  _removeWatcher: %@, %@, key not watched"), sessionNum, watchedKey);
                return;
        }
        newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
@@ -330,7 +342,7 @@ _removeWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
                                        CFRangeMake(0, CFArrayGetCount(newWatchers)),
                                        sessionNum);
        if (i == -1) {
-               SCDLog(LOG_DEBUG, CFSTR("_removeWatcher: no reference for session %@"), sessionNum);
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  _removeWatcher: %@, %@, session not watching"), sessionNum, watchedKey);
                CFRelease(newDict);
                CFRelease(newWatchers);
                CFRelease(newWatcherRefs);
@@ -364,14 +376,14 @@ _removeWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
 
        if (CFDictionaryGetCount(newDict) > 0) {
                /* if this key is still active */
-               CFDictionarySetValue(cacheData, watchedKey, newDict);
+               CFDictionarySetValue(storeData, watchedKey, newDict);
        } else {
                /* no information left, remove the empty dictionary */
-               CFDictionaryRemoveValue(cacheData, watchedKey);
+               CFDictionaryRemoveValue(storeData, watchedKey);
        }
        CFRelease(newDict);
 
-       SCDLog(LOG_DEBUG, CFSTR("  _removeWatcher: %@, %@"), sessionNum, watchedKey);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  _removeWatcher: %@, %@"), sessionNum, watchedKey);
 
        return;
 }
@@ -381,8 +393,8 @@ _removeWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
  * _removeRegexWatcherByKey()
  *
  * This is a CFDictionaryApplierFunction which will iterate over each key
- * defined in the "cacheData" dictionary. The arguments are the dictionary
- * key, it's associated cache dictionary, and a context structure which
+ * defined in the "storeData" dictionary. The arguments are the dictionary
+ * key, it's associated store dictionary, and a context structure which
  * includes the following:
  *
  *   1. the session which has just removed a regex notification request
@@ -394,14 +406,14 @@ _removeWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
 void
 _removeRegexWatcherByKey(const void *key, void *val, void *context)
 {
-       CFStringRef     cacheStr  = key;
+       CFStringRef     storeStr  = key;
        CFDictionaryRef info      = val;
-       mach_port_t     sessionID = ((removeContextRef)context)->session->server;
+       mach_port_t     sessionID = ((removeContextRef)context)->store->server;
        regex_t         *preg     = ((removeContextRef)context)->preg;
        CFNumberRef     sessionNum;
        CFArrayRef      watchers;
-       int             cacheKeyLen;
-       char            *cacheKey;
+       int             storeKeyLen;
+       char            *storeKey;
        int             reError;
        char            reErrBuf[256];
        int             reErrStrLen;
@@ -423,31 +435,31 @@ _removeRegexWatcherByKey(const void *key, void *val, void *context)
        }
 
        /* convert key to C string */
-       cacheKeyLen = CFStringGetLength(cacheStr) + 1;
-       cacheKey    = CFAllocatorAllocate(NULL, cacheKeyLen, 0);
-       if (!CFStringGetCString(cacheStr, cacheKey, cacheKeyLen, kCFStringEncodingMacRoman)) {
-               SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString: could not convert key to C string"));
-               CFAllocatorDeallocate(NULL, cacheKey);
+       storeKeyLen = CFStringGetLength(storeStr) + 1;
+       storeKey    = CFAllocatorAllocate(NULL, storeKeyLen, 0);
+       if (!CFStringGetCString(storeStr, storeKey, storeKeyLen, kCFStringEncodingMacRoman)) {
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString: could not convert key to C string"));
+               CFAllocatorDeallocate(NULL, storeKey);
                CFRelease(sessionNum);
                return;
        }
 
        /* check if this key matches the regular expression */
-       reError = regexec(preg, cacheKey, 0, NULL, 0);
+       reError = regexec(preg, storeKey, 0, NULL, 0);
        switch (reError) {
                case 0 :
                        /* we've got a match */
-                       _removeWatcher(sessionNum, cacheStr);
+                       _removeWatcher(sessionNum, storeStr);
                        break;
                case REG_NOMATCH :
                        /* no match */
                        break;
                default :
                        reErrStrLen = regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
-                       SCDLog(LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
                        break;
        }
-       CFAllocatorDeallocate(NULL, cacheKey);
+       CFAllocatorDeallocate(NULL, storeKey);
        CFRelease(sessionNum);
 }
 
@@ -457,10 +469,10 @@ _removeRegexWatcherByKey(const void *key, void *val, void *context)
  *
  * This is a CFDictionaryApplierFunction which will iterate over each session
  * defined in the "sessionData" dictionary. The arguments are the session
- * key, it's associated session dictionary, and the cache key being removed.
+ * key, it's associated session dictionary, and the store key being removed.
  *
  * If an active session includes any regular expression keys which match the
- * key being removed from the "cacheData" dictionary then we clear this keys
+ * key being removed from the "storeData" dictionary then we clear this keys
  * reference of being watched.
  */
 void
@@ -491,7 +503,7 @@ _removeRegexWatchersBySession(const void *key, void *val, void *context)
        oldKeyLen = CFStringGetLength(removedKey) + 1;
        oldKeyStr = CFAllocatorAllocate(NULL, oldKeyLen, 0);
        if (!CFStringGetCString(removedKey, oldKeyStr, oldKeyLen, kCFStringEncodingMacRoman)) {
-               SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString: could not convert old key to C string"));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString: could not convert old key to C string"));
                CFAllocatorDeallocate(NULL, oldKeyStr);
                return;
        }
@@ -521,7 +533,7 @@ _removeRegexWatchersBySession(const void *key, void *val, void *context)
                                break;
                        default :
                                reErrStrLen = regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
-                               SCDLog(LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
+                               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
                                break;
                }
 
index 32cf319556ba569a2d85f9c9a06d5ccd87aa896e..a2525a55c7a58873d46b06a5216b169f17021eb5 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * June 2, 2000                Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 
 #ifndef _S_SCD_H
 #define _S_SCD_H
@@ -28,7 +38,7 @@
 
 
 /*
- * keys in the "cacheData" dictionary
+ * keys in the "storeData" dictionary
  */
 
 /*
 #define        kSCDSessionKeys CFSTR("sessionKeys")
 
 
-extern CFMutableDictionaryRef  cacheData;
+extern int                     storeLocked;
+extern CFMutableDictionaryRef  storeData;
 extern CFMutableDictionaryRef  sessionData;
 extern CFMutableSetRef         changedKeys;
 extern CFMutableSetRef         deferredRemovals;
 extern CFMutableSetRef         removedSessionKeys;
 extern CFMutableSetRef         needsNotification;
 
-extern CFMutableDictionaryRef  cacheData_s;
+extern CFMutableDictionaryRef  storeData_s;
 extern CFMutableSetRef         changedKeys_s;
 extern CFMutableSetRef         deferredRemovals_s;
 extern CFMutableSetRef         removedSessionKeys_s;
@@ -93,109 +104,136 @@ extern CFMutableSetRef           removedSessionKeys_s;
  * _addRegexWatcherBySession(), and _removeRegexWatcherByKey() functions.
  */
 typedef struct {
-       SCDSessionPrivateRef    session;
-       regex_t                 *preg;
+       SCDynamicStorePrivateRef        store;
+       regex_t                         *preg;
 } addContext, *addContextRef;
 
 
 typedef struct {
-       SCDSessionPrivateRef    session;
-       regex_t                 *preg;
+       SCDynamicStorePrivateRef        store;
+       regex_t                         *preg;
 } removeContext, *removeContextRef;
 
 
 __BEGIN_DECLS
 
-SCDStatus      _SCDOpen                        __P((SCDSessionRef      *session,
-                                                    CFStringRef        name));
-
-SCDStatus      _SCDClose                       __P((SCDSessionRef      *session));
-
-SCDStatus      _SCDLock                        __P((SCDSessionRef      session));
-
-SCDStatus      _SCDUnlock                      __P((SCDSessionRef      session));
-
-SCDStatus      _SCDList                        __P((SCDSessionRef      session,
-                                                    CFStringRef        key,
-                                                    int                regexOptions,
-                                                    CFArrayRef         *subKeys));
-
-SCDStatus      _SCDAdd                         __P((SCDSessionRef      session,
-                                                    CFStringRef        key,
-                                                    SCDHandleRef       handle));
-
-SCDStatus      _SCDAddSession                  __P((SCDSessionRef      session,
-                                                    CFStringRef        key,
-                                                    SCDHandleRef       handle));
-
-SCDStatus      _SCDGet                         __P((SCDSessionRef      session,
-                                                    CFStringRef        key,
-                                                    SCDHandleRef       *handle));
-
-SCDStatus      _SCDSet                         __P((SCDSessionRef      session,
-                                                    CFStringRef        key,
-                                                    SCDHandleRef       handle));
-
-SCDStatus      _SCDRemove                      __P((SCDSessionRef      session,
-                                                    CFStringRef        key));
-
-SCDStatus      _SCDTouch                       __P((SCDSessionRef      session,
-                                                    CFStringRef        key));
-
-SCDStatus      _SCDSnapshot                    __P((SCDSessionRef      session));
-
-SCDStatus      _SCDNotifierList                __P((SCDSessionRef      session,
-                                                    int                regexOptions,
-                                                    CFArrayRef         *notifierKeys));
-
-SCDStatus      _SCDNotifierAdd                 __P((SCDSessionRef      session,
-                                                    CFStringRef        key,
-                                                    int                regexOptions));
-
-SCDStatus      _SCDNotifierRemove              __P((SCDSessionRef      session,
-                                                    CFStringRef        key,
-                                                    int                regexOptions));
-
-SCDStatus      _SCDNotifierGetChanges          __P((SCDSessionRef      session,
-                                                    CFArrayRef         *notifierKeys));
-
-SCDStatus      _SCDNotifierInformViaMachPort   __P((SCDSessionRef      session,
-                                                    mach_msg_id_t      msgid,
-                                                    mach_port_t        *port));
-
-SCDStatus      _SCDNotifierInformViaFD         __P((SCDSessionRef      session,
-                                                    int32_t            identifier,
-                                                    int                *fd));
-
-SCDStatus      _SCDNotifierInformViaSignal     __P((SCDSessionRef      session,
-                                                    pid_t              pid,
-                                                    int                sig));
-
-SCDStatus      _SCDNotifierCancel              __P((SCDSessionRef      session));
-
-void           _swapLockedCacheData            __P(());
-
-void           _addWatcher                     __P((CFNumberRef        sessionNum,
-                                                    CFStringRef        watchedKey));
-
-void           _addRegexWatcherByKey           __P((const void         *key,
-                                                    void               *val,
-                                                    void               *context));
-
-void           _addRegexWatchersBySession      __P((const void         *key,
-                                                    void               *val,
-                                                    void               *context));
-
-void           _removeWatcher                  __P((CFNumberRef        sessionNum,
-                                                    CFStringRef        watchedKey));
-
-void           _removeRegexWatcherByKey        __P((const void         *key,
-                                                    void               *val,
-                                                    void               *context));
-
-void           _removeRegexWatchersBySession   __P((const void         *key,
-                                                    void               *val,
-                                                    void               *context));
+int
+__SCDynamicStoreOpen                   (SCDynamicStoreRef      *store,
+                                        CFStringRef            name);
+int
+__SCDynamicStoreClose                  (SCDynamicStoreRef      *store);
+
+int
+__SCDynamicStoreLock                   (SCDynamicStoreRef      store,
+                                        Boolean                recursive);
+
+int
+__SCDynamicStoreUnlock                 (SCDynamicStoreRef      store,
+                                        Boolean                recursive);
+
+int
+__SCDynamicStoreCopyKeyList            (SCDynamicStoreRef      store,
+                                        CFStringRef            prefix,
+                                        Boolean                isRegex,
+                                        CFArrayRef             *subKeys);
+
+int
+__SCDynamicStoreAddValue               (SCDynamicStoreRef      store,
+                                        CFStringRef            key,
+                                        CFPropertyListRef      value);
+
+int
+__SCDynamicStoreAddTemporaryValue      (SCDynamicStoreRef      store,
+                                        CFStringRef            key,
+                                        CFPropertyListRef      value);
+
+int
+__SCDynamicStoreCopyValue              (SCDynamicStoreRef      store,
+                                        CFStringRef            key,
+                                        CFPropertyListRef      *value);
+
+int
+__SCDynamicStoreSetValue               (SCDynamicStoreRef      store,
+                                        CFStringRef            key,
+                                        CFPropertyListRef      value);
+
+int
+__SCDynamicStoreRemoveValue            (SCDynamicStoreRef      store,
+                                        CFStringRef            key);
+
+int
+__SCDynamicStoreTouchValue             (SCDynamicStoreRef      store,
+                                        CFStringRef            key);
+
+int
+__SCDynamicStoreNotifyValue            (SCDynamicStoreRef      store,
+                                        CFStringRef            key);
+
+int
+__SCDynamicStoreSnapshot               (SCDynamicStoreRef      store);
+
+int
+__SCDynamicStoreAddWatchedKey          (SCDynamicStoreRef      store,
+                                        CFStringRef            key,
+                                        Boolean                isRegex);
+
+int
+__SCDynamicStoreRemoveWatchedKey       (SCDynamicStoreRef      store,
+                                        CFStringRef            key,
+                                        Boolean                isRegex);
+
+int
+__SCDynamicStoreCopyNotifiedKeys       (SCDynamicStoreRef      store,
+                                        CFArrayRef             *notifierKeys);
+
+int
+__SCDynamicStoreNotifyMachPort         (SCDynamicStoreRef      store,
+                                        mach_msg_id_t          msgid,
+                                        mach_port_t            *port);
+
+int
+__SCDynamicStoreNotifyFileDescriptor   (SCDynamicStoreRef      store,
+                                        int32_t                identifier,
+                                        int                    *fd);
+
+int
+__SCDynamicStoreNotifySignal           (SCDynamicStoreRef      store,
+                                        pid_t                  pid,
+                                        int                    sig);
+
+int
+__SCDynamicStoreNotifyCancel           (SCDynamicStoreRef      store);
+
+void
+_swapLockedStoreData                   ();
+
+void
+_addWatcher                            (CFNumberRef            sessionNum,
+                                        CFStringRef            watchedKey);
+
+void
+_addRegexWatcherByKey                  (const void             *key,
+                                        void                   *val,
+                                        void                   *context);
+
+void
+_addRegexWatchersBySession             (const void             *key,
+                                        void                   *val,
+                                        void                   *context);
+
+void
+_removeWatcher                         (CFNumberRef            sessionNum,
+                                        CFStringRef            watchedKey);
+
+void
+_removeRegexWatcherByKey               (const void             *key,
+                                        void                   *val,
+                                        void                   *context);
+
+void
+_removeRegexWatchersBySession          (const void             *key,
+                                        void                   *val,
+                                        void                   *context);
 
 __END_DECLS
 
index 76a9dfbb1a1163bf5c6d6cd57823d2c3f3098460..d06abd15468db3f6371f5113f4696c546c39a5b2 100644 (file)
  * @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
-_SCDAdd(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
+int
+__SCDynamicStoreAddValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       SCDStatus               scd_status = SCD_OK;
-       boolean_t               wasLocked;
-       SCDHandleRef            tempHandle;
+       SCDynamicStorePrivateRef        storePrivate    = (SCDynamicStorePrivateRef)store;
+       int                             sc_status       = kSCStatusOK;
+       CFPropertyListRef               tempValue;
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDAdd:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key          = %@"), key);
-       SCDLog(LOG_DEBUG, CFSTR("  data         = %@"), SCDHandleGetData(handle));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreAddValue:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  key          = %@"), key);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  value        = %@"), value);
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
        /*
-        * 1. Determine if the cache lock is currently held
-        *    and acquire the lock if necessary.
+        * 1. Ensure that we hold the lock.
         */
-       wasLocked = SCDOptionGet(NULL, kSCDOptionIsLocked);
-       if (!wasLocked) {
-               scd_status = _SCDLock(session);
-               if (scd_status != SCD_OK) {
-                       SCDLog(LOG_DEBUG, CFSTR("  _SCDLock(): %s"), SCDError(scd_status));
-                       return scd_status;
-               }
+       sc_status = __SCDynamicStoreLock(store, TRUE);
+       if (sc_status != kSCStatusOK) {
+               return sc_status;
        }
 
        /*
         * 2. Ensure that this is a new key.
         */
-       scd_status = _SCDGet(session, key, &tempHandle);
-       switch (scd_status) {
-               case SCD_NOKEY :
-                       /* cache key does not exist, proceed */
+       sc_status = __SCDynamicStoreCopyValue(store, key, &tempValue);
+       switch (sc_status) {
+               case kSCStatusNoKey :
+                       /* store key does not exist, proceed */
                        break;
 
-               case SCD_OK :
-                       /* cache key exists, sorry */
-                       SCDHandleRelease(tempHandle);
-                       scd_status = SCD_EXISTS;
+               case kSCStatusOK :
+                       /* store key exists, sorry */
+                       CFRelease(tempValue);
+                       sc_status = kSCStatusKeyExists;
                        goto done;
 
                default :
-                       SCDLog(LOG_DEBUG, CFSTR("  _SCDGet(): %s"), SCDError(scd_status));
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  _SCDGet(): %s"), SCErrorString(sc_status));
                        goto done;
        }
 
        /*
         * 3. Save the new key.
         */
-       scd_status = _SCDSet(session, key, handle);
+       sc_status = __SCDynamicStoreSetValue(store, key, value);
 
        /*
-        * 4. Release the lock if we acquired it as part of this request.
+        * 4. Release our lock.
         */
     done:
-       if (!wasLocked)
-               _SCDUnlock(session);
+       __SCDynamicStoreUnlock(store, TRUE);
 
-       return scd_status;
+       return sc_status;
 }
 
 
@@ -95,7 +98,7 @@ _configadd(mach_port_t                        server,
           xmlData_t                    dataRef,        /* raw XML bytes */
           mach_msg_type_number_t       dataLen,
           int                          *newInstance,
-          int                          *scd_status
+          int                          *sc_status
 )
 {
        kern_return_t           status;
@@ -104,17 +107,18 @@ _configadd(mach_port_t                    server,
        CFStringRef             key;            /* key  (un-serialized) */
        CFDataRef               xmlData;        /* data (XML serialized) */
        CFPropertyListRef       data;           /* data (un-serialized) */
-       SCDHandleRef            handle;
        CFStringRef             xmlError;
 
-       SCDLog(LOG_DEBUG, CFSTR("Add key to configuration database."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Add key to configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
+
+       *sc_status = kSCStatusOK;
 
        /* 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));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        key = CFPropertyListCreateFromXMLData(NULL,
@@ -122,17 +126,23 @@ _configadd(mach_port_t                    server,
                                              kCFPropertyListImmutable,
                                              &xmlError);
        CFRelease(xmlKey);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
-               *scd_status = SCD_FAILED;
-               return KERN_SUCCESS;
+       if (!key) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+       } else if (!isA_CFString(key)) {
+               *sc_status = kSCStatusInvalidArgument;
        }
 
        /* un-serialize the data */
        xmlData = CFDataCreate(NULL, dataRef, dataLen);
        status = vm_deallocate(mach_task_self(), (vm_address_t)dataRef, dataLen);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        data = CFPropertyListCreateFromXMLData(NULL,
@@ -140,20 +150,27 @@ _configadd(mach_port_t                    server,
                                               kCFPropertyListImmutable,
                                               &xmlError);
        CFRelease(xmlData);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() data: %s"), xmlError);
-               CFRelease(key);
-               *scd_status = SCD_FAILED;
-               return KERN_SUCCESS;
+       if (!data) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() data: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+       } else if (!isA_CFPropertyList(data)) {
+               *sc_status = kSCStatusInvalidArgument;
        }
 
-       handle = SCDHandleInit();
-       SCDHandleSetData(handle, data);
-       *scd_status = _SCDAdd(mySession->session, key, handle);
-       if (*scd_status == SCD_OK) {
-               *newInstance = SCDHandleGetInstance(handle);
+       if (*sc_status != kSCStatusOK) {
+               if (key)        CFRelease(key);
+               if (data)       CFRelease(data);
+               return KERN_SUCCESS;
        }
-       SCDHandleRelease(handle);
+
+       *sc_status = __SCDynamicStoreAddValue(mySession->store, key, data);
+       *newInstance = 0;
+
        CFRelease(key);
        CFRelease(data);
 
index 8e54070f4895885c9c828d8267b3d9f3824447a9..c09c478f73793fdcebec9b37f7173fcd179a9d6d 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * October 17, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include "configd.h"
 #include "session.h"
 
-SCDStatus
-_SCDAddSession(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
+int
+__SCDynamicStoreAddTemporaryValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       SCDStatus               scd_status = SCD_OK;
-       CFStringRef             sessionKey;
-       CFDictionaryRef         dict;
-       CFMutableDictionaryRef  newDict;
-       CFArrayRef              keys;
-       CFMutableArrayRef       newKeys;
-
-       SCDLog(LOG_DEBUG, CFSTR("_SCDAddSession:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key          = %@"), key);
-       SCDLog(LOG_DEBUG, CFSTR("  data         = %@"), SCDHandleGetData(handle));
-
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       int                             sc_status = kSCStatusOK;
+       CFStringRef                     sessionKey;
+       CFDictionaryRef                 dict;
+       CFMutableDictionaryRef          newDict;
+       CFArrayRef                      keys;
+       CFMutableArrayRef               newKeys;
+
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreAddTemporaryValue:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  key          = %@"), key);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  value        = %@"), value);
+
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
        /*
         * 1. Add the key
         */
-       scd_status = _SCDAdd(session, key, handle);
-       if (scd_status != SCD_OK) {
-               SCDLog(LOG_DEBUG, CFSTR("  _SCDAdd(): %s"), SCDError(scd_status));
-               return scd_status;
+       sc_status = __SCDynamicStoreAddValue(store, key, value);
+       if (sc_status != kSCStatusOK) {
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  __SCDynamicStoreAddValue(): %s"), SCErrorString(sc_status));
+               return sc_status;
        }
 
        /*
         * 2. Create the session key
         */
-       sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), sessionPrivate->server);
+       sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
 
        /*
         * 3. Add this key to my list of per-session keys
@@ -89,14 +99,14 @@ _SCDAddSession(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
        /*
         * 4. Mark the key as a "session" key and track the creator.
         */
-       dict    = CFDictionaryGetValue(cacheData, key);
+       dict    = CFDictionaryGetValue(storeData, key);
        newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
        CFDictionarySetValue(newDict, kSCDSession, sessionKey);
-       CFDictionarySetValue(cacheData, key, newDict);
+       CFDictionarySetValue(storeData, key, newDict);
        CFRelease(newDict);
 
        CFRelease(sessionKey);
-       return scd_status;
+       return sc_status;
 }
 
 
@@ -107,7 +117,7 @@ _configadd_s(mach_port_t            server,
             xmlData_t                  dataRef,        /* raw XML bytes */
             mach_msg_type_number_t     dataLen,
             int                        *newInstance,
-            int                        *scd_status
+            int                        *sc_status
 )
 {
        kern_return_t           status;
@@ -116,17 +126,18 @@ _configadd_s(mach_port_t          server,
        CFStringRef             key;            /* key  (un-serialized) */
        CFDataRef               xmlData;        /* data (XML serialized) */
        CFPropertyListRef       data;           /* data (un-serialized) */
-       SCDHandleRef            handle;
        CFStringRef             xmlError;
 
-       SCDLog(LOG_DEBUG, CFSTR("Add (session) key to configuration database."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Add (session) key to configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
+
+       *sc_status = kSCStatusOK;
 
        /* 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));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        key = CFPropertyListCreateFromXMLData(NULL,
@@ -134,17 +145,23 @@ _configadd_s(mach_port_t          server,
                                              kCFPropertyListImmutable,
                                              &xmlError);
        CFRelease(xmlKey);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
-               *scd_status = SCD_FAILED;
-               return KERN_SUCCESS;
+       if (!key) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+       } else if (!isA_CFString(key)) {
+               *sc_status = kSCStatusInvalidArgument;
        }
 
        /* un-serialize the data */
        xmlData = CFDataCreate(NULL, dataRef, dataLen);
        status = vm_deallocate(mach_task_self(), (vm_address_t)dataRef, dataLen);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        data = CFPropertyListCreateFromXMLData(NULL,
@@ -152,20 +169,28 @@ _configadd_s(mach_port_t          server,
                                               kCFPropertyListImmutable,
                                               &xmlError);
        CFRelease(xmlData);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() data: %s"), xmlError);
-               CFRelease(key);
-               *scd_status = SCD_FAILED;
+       if (!data) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() data: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+       } else if (!isA_CFPropertyList(data)) {
+               *sc_status = kSCStatusInvalidArgument;
+       }
+
+       if (*sc_status != kSCStatusOK) {
+               if (key)        CFRelease(key);
+               if (data)       CFRelease(data);
                return KERN_SUCCESS;
        }
 
-       handle = SCDHandleInit();
-       SCDHandleSetData(handle, data);
-       *scd_status = _SCDAddSession(mySession->session, key, handle);
-       if (*scd_status == SCD_OK) {
-               *newInstance = SCDHandleGetInstance(handle);
+       *sc_status = __SCDynamicStoreAddTemporaryValue(mySession->store, key, data);
+       if (*sc_status == kSCStatusOK) {
+               *newInstance = 1;
        }
-       SCDHandleRelease(handle);
        CFRelease(key);
        CFRelease(data);
 
index afba5bb1b843505eed75a5e4f4249f866731216e..d623f85e857a11f1500c2f1d06915f484459a545 100644 (file)
  * @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 <unistd.h>
 
 #include "configd.h"
 #include "session.h"
 
-static boolean_t
+static Boolean
 isMySessionKey(CFStringRef sessionKey, CFStringRef key)
 {
        CFDictionaryRef dict;
-       CFStringRef     cacheSessionKey;
+       CFStringRef     storeSessionKey;
 
-       dict = CFDictionaryGetValue(cacheData, key);
+       dict = CFDictionaryGetValue(storeData, key);
        if (!dict) {
                /* if key no longer exists */
                return FALSE;
        }
 
-       cacheSessionKey = CFDictionaryGetValue(dict, kSCDSession);
-       if (!cacheSessionKey) {
+       storeSessionKey = CFDictionaryGetValue(dict, kSCDSession);
+       if (!storeSessionKey) {
                /* if this is not a session key */
                return FALSE;
        }
 
-       if (!CFEqual(sessionKey, cacheSessionKey)) {
+       if (!CFEqual(sessionKey, storeSessionKey)) {
                /* if this is not "my" session key */
                return FALSE;
        }
@@ -52,113 +62,113 @@ isMySessionKey(CFStringRef sessionKey, CFStringRef key)
 }
 
 
-SCDStatus
-_SCDClose(SCDSessionRef *session)
+int
+__SCDynamicStoreClose(SCDynamicStoreRef *store)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)*session;
-       CFIndex                 keyCnt;
-       CFStringRef             sessionKey;
-       CFDictionaryRef         dict;
-       CFArrayRef              keys;
-       serverSessionRef        mySession;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)*store;
+       CFIndex                         keyCnt;
+       CFStringRef                     sessionKey;
+       CFDictionaryRef                 dict;
+       CFArrayRef                      keys;
+       serverSessionRef                mySession;
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDClose:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreClose:"));
 
-       if ((*session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;
+       if ((*store == NULL) || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
        /* Remove notification keys */
-       if ((keyCnt = CFSetGetCount(sessionPrivate->keys)) > 0) {
+       if ((keyCnt = CFSetGetCount(storePrivate->keys)) > 0) {
                void            **watchedKeys;
                CFArrayRef      keysToRemove;
                CFIndex         i;
 
                watchedKeys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
-               CFSetGetValues(sessionPrivate->keys, watchedKeys);
+               CFSetGetValues(storePrivate->keys, watchedKeys);
                keysToRemove = CFArrayCreate(NULL, watchedKeys, keyCnt, &kCFTypeArrayCallBacks);
                CFAllocatorDeallocate(NULL, watchedKeys);
                for (i=0; i<keyCnt; i++) {
-                       (void) _SCDNotifierRemove(*session,
-                                                 CFArrayGetValueAtIndex(keysToRemove, i),
-                                                 0);
+                       (void) __SCDynamicStoreRemoveWatchedKey(*store,
+                                                               CFArrayGetValueAtIndex(keysToRemove, i),
+                                                               FALSE);
                }
                CFRelease(keysToRemove);
        }
 
        /* Remove regex notification keys */
-       if ((keyCnt = CFSetGetCount(sessionPrivate->reKeys)) > 0) {
+       if ((keyCnt = CFSetGetCount(storePrivate->reKeys)) > 0) {
                void            **watchedKeys;
                CFArrayRef      keysToRemove;
                CFIndex         i;
 
                watchedKeys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
-               CFSetGetValues(sessionPrivate->reKeys, watchedKeys);
+               CFSetGetValues(storePrivate->reKeys, watchedKeys);
                keysToRemove = CFArrayCreate(NULL, watchedKeys, keyCnt, &kCFTypeArrayCallBacks);
                CFAllocatorDeallocate(NULL, watchedKeys);
                for (i=0; i<keyCnt; i++) {
-                       (void) _SCDNotifierRemove(*session,
-                                                 CFArrayGetValueAtIndex(keysToRemove, i),
-                                                 kSCDRegexKey);
+                       (void) __SCDynamicStoreRemoveWatchedKey(*store,
+                                                               CFArrayGetValueAtIndex(keysToRemove, i),
+                                                               TRUE);
                }
                CFRelease(keysToRemove);
        }
 
        /* Remove/cancel any outstanding notification requests. */
-       (void) _SCDNotifierCancel(*session);
+       (void) __SCDynamicStoreNotifyCancel(*store);
 
        /* Remove any session keys */
-       sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), sessionPrivate->server);
+       sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
        dict = CFDictionaryGetValue(sessionData, sessionKey);
        keys = CFDictionaryGetValue(dict, kSCDSessionKeys);
        if (keys && ((keyCnt = CFArrayGetCount(keys)) > 0)) {
-               boolean_t       wasLocked;
-               CFIndex         i;
+               Boolean wasLocked;
+               CFIndex i;
 
                /*
                 * if necessary, claim a lock to ensure that we inform
                 * any processes that a session key was removed.
                 */
-               wasLocked = SCDOptionGet(NULL, kSCDOptionIsLocked);
+               wasLocked = (storeLocked > 0);
                if (!wasLocked) {
-                       (void) _SCDLock(*session);
+                       (void) __SCDynamicStoreLock(*store, FALSE);
                }
 
-               /* remove keys from "locked" cache" */
+               /* remove keys from "locked" store" */
                for (i=0; i<keyCnt; i++) {
-                       if (isMySessionKey(sessionKey, CFArrayGetValueAtIndex(keys, i)))
-                               (void) _SCDRemove(*session, CFArrayGetValueAtIndex(keys, i));
+                       if (isMySessionKey(sessionKey, CFArrayGetValueAtIndex(keys, i))) {
+                               (void) __SCDynamicStoreRemoveValue(*store, CFArrayGetValueAtIndex(keys, i));
+                       }
                }
 
                if (wasLocked) {
-                       /* remove keys from "unlocked" cache" */
-                       _swapLockedCacheData();
+                       /* remove keys from "unlocked" store" */
+                       _swapLockedStoreData();
                        for (i=0; i<keyCnt; i++) {
                                if (isMySessionKey(sessionKey, CFArrayGetValueAtIndex(keys, i)))
-                                       (void) _SCDRemove(*session, CFArrayGetValueAtIndex(keys, i));
+                                       (void) __SCDynamicStoreRemoveValue(*store, CFArrayGetValueAtIndex(keys, i));
                        }
-                       _swapLockedCacheData();
+                       _swapLockedStoreData();
                }
 
                /*
-                * Note: everyone who calls _SCDClose() ends up
-                *       removing this sessions dictionary. As
-                *       such, we don't need to worry about
-                *       the session keys.
+                * Note: everyone who calls __SCDynamicStoreClose() ends
+                *       up removing this sessions dictionary. As such,
+                *       we don't need to worry about the session keys.
                 */
        }
        CFRelease(sessionKey);
 
        /* release the lock */
-       if (SCDOptionGet(*session, kSCDOptionIsLocked)) {
-               (void) _SCDUnlock(*session);
+       if (storePrivate->locked) {
+               (void) __SCDynamicStoreUnlock(*store, FALSE);
        }
 
        /*
-        * Invalidate the server port (for this client) which will result
-        * in the removal of any associated run loop sources.
+        * Remove the run loop source on the server port (for this
+        * client).  Then, invalidate and release the port.
         */
-       mySession = getSession(sessionPrivate->server);
+       mySession = getSession(storePrivate->server);
        if (mySession->serverRunLoopSource) {
                CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
                                      mySession->serverRunLoopSource,
@@ -168,29 +178,28 @@ _SCDClose(SCDSessionRef *session)
        CFMachPortInvalidate(mySession->serverPort);
        CFRelease(mySession->serverPort);
 
-       CFRelease(sessionPrivate->keys);
-       CFRelease(sessionPrivate->reKeys);
-       CFAllocatorDeallocate(NULL, sessionPrivate);
-       *session = NULL;
+       storePrivate->server = MACH_PORT_NULL;
+       CFRelease(*store);
+       *store = NULL;
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
 kern_return_t
-_configclose(mach_port_t server, int *scd_status)
+_configclose(mach_port_t server, int *sc_status)
 {
        serverSessionRef        mySession = getSession(server);
 
-       SCDLog(LOG_DEBUG, CFSTR("Close session."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Close session."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
 
        /*
         * Close the session.
         */
-       *scd_status = _SCDClose(&mySession->session);
-       if (*scd_status != SCD_OK) {
-               SCDLog(LOG_DEBUG, CFSTR("  _SCDClose(): %s"), SCDError(*scd_status));
+       *sc_status = __SCDynamicStoreClose(&mySession->store);
+       if (*sc_status != kSCStatusOK) {
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  __SCDynamicStoreClose(): %s"), SCErrorString(*sc_status));
                return KERN_SUCCESS;
        }
 
index 7b1e64d59c8d0ffa3ca421d6a3838a7ab70f4253..48bab882daf3047305c19ea13efe1c541961a4cf 100644 (file)
  * @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,7 +67,7 @@ _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;
@@ -77,17 +75,17 @@ _configget(mach_port_t                      server,
        CFDataRef               xmlKey;         /* key  (XML serialized) */
        CFStringRef             key;            /* key  (un-serialized) */
        CFDataRef               xmlData;        /* data (XML serialized) */
-       SCDHandleRef            handle;
+       CFPropertyListRef       value;
        CFStringRef             xmlError;
 
-       SCDLog(LOG_DEBUG, CFSTR("Get key from configuration database."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Get key from configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
 
        /* 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));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        key = CFPropertyListCreateFromXMLData(NULL,
@@ -95,15 +93,23 @@ _configget(mach_port_t                      server,
                                              kCFPropertyListImmutable,
                                              &xmlError);
        CFRelease(xmlKey);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
-               *scd_status = SCD_FAILED;
+       if (!key) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+               return KERN_SUCCESS;
+       } else if (!isA_CFString(key)) {
+               *sc_status = kSCStatusInvalidArgument;
                return KERN_SUCCESS;
        }
 
-       *scd_status = _SCDGet(mySession->session, key, &handle);
+       *sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value);
        CFRelease(key);
-       if (*scd_status != SCD_OK) {
+       if (*sc_status != kSCStatusOK) {
                *dataRef = NULL;
                *dataLen = 0;
                return KERN_SUCCESS;
@@ -113,12 +119,13 @@ _configget(mach_port_t                    server,
         * 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));
+       xmlData = CFPropertyListCreateXMLData(NULL, value);
+       CFRelease(value);
        *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;
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
+               *sc_status = kSCStatusFailed;
                CFRelease(xmlData);
                *dataRef = NULL;
                *dataLen = 0;
@@ -131,9 +138,194 @@ _configget(mach_port_t                    server,
        /*
         * 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)
+{
+       kern_return_t           status;
+       serverSessionRef        mySession = getSession(server);
+       CFArrayRef              keys            = NULL; /* keys (un-serialized) */
+       CFArrayRef              patterns        = NULL; /* patterns (un-serialized) */
+       CFDataRef               xmlData;                /* data (XML serialized) */
+       addSpecific             myContext;
+
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Get key from configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
+
+       *sc_status = kSCStatusOK;
+
+       if (keysRef && (keysLen > 0)) {
+               CFDataRef       xmlKeys;                /* keys (XML serialized) */
+               CFStringRef     xmlError;
+
+               /* un-serialize the keys */
+               xmlKeys = CFDataCreate(NULL, keysRef, keysLen);
+               status = vm_deallocate(mach_task_self(), (vm_address_t)keysRef, keysLen);
+               if (status != KERN_SUCCESS) {
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+                       /* non-fatal???, proceed */
+               }
+               keys = CFPropertyListCreateFromXMLData(NULL,
+                                                      xmlKeys,
+                                                      kCFPropertyListImmutable,
+                                                      &xmlError);
+               CFRelease(xmlKeys);
+               if (!keys) {
+                       if (xmlError) {
+                               SCLog(_configd_verbose, LOG_DEBUG,
+                                      CFSTR("CFPropertyListCreateFromXMLData() keys: %@"),
+                                      xmlError);
+                               CFRelease(xmlError);
+                       }
+                       *sc_status = kSCStatusFailed;
+               } else if (!isA_CFArray(keys)) {
+                       *sc_status = kSCStatusInvalidArgument;
+               }
+       }
+
+       if (patternsRef && (patternsLen > 0)) {
+               CFDataRef       xmlPatterns;            /* patterns (XML serialized) */
+               CFStringRef     xmlError;
+
+               /* un-serialize the patterns */
+               xmlPatterns = CFDataCreate(NULL, patternsRef, patternsLen);
+               status = vm_deallocate(mach_task_self(), (vm_address_t)patternsRef, patternsLen);
+               if (status != KERN_SUCCESS) {
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+                       /* non-fatal???, proceed */
+               }
+               patterns = CFPropertyListCreateFromXMLData(NULL,
+                                                          xmlPatterns,
+                                                          kCFPropertyListImmutable,
+                                                          &xmlError);
+               CFRelease(xmlPatterns);
+               if (!patterns) {
+                       if (xmlError) {
+                               SCLog(_configd_verbose, LOG_DEBUG,
+                                      CFSTR("CFPropertyListCreateFromXMLData() patterns: %@"),
+                                      xmlError);
+                               CFRelease(xmlError);
+                       }
+                       *sc_status = kSCStatusFailed;
+               } else if (!isA_CFArray(patterns)) {
+                       *sc_status = kSCStatusInvalidArgument;
+               }
+       }
+
+       if (*sc_status != kSCStatusOK) {
+               if (keys)       CFRelease(keys);
+               if (patterns)   CFRelease(patterns);
+               *dataRef = NULL;
+               *dataLen = 0;
+               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, copy it into an
+        * allocated buffer which will be released when it is returned as part
+        * of a Mach message.
+        */
+       xmlData = CFPropertyListCreateXMLData(NULL, myContext.dict);
+       CFRelease(myContext.dict);
+       *dataLen = CFDataGetLength(xmlData);
+       status = vm_allocate(mach_task_self(), (void *)dataRef, *dataLen, TRUE);
+       if (status != KERN_SUCCESS) {
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
+               *sc_status = kSCStatusFailed;
+               CFRelease(xmlData);
+               *dataRef = NULL;
+               *dataLen = 0;
+               return KERN_SUCCESS;
+       }
+
+       bcopy((char *)CFDataGetBytePtr(xmlData), *dataRef, *dataLen);
+       CFRelease(xmlData);
 
        return KERN_SUCCESS;
 }
index 85286c3add660950d12d31572aed9243a59625ba..6613f8af7dd8e9df4835cde3c448dbe8a2d0b99f 100644 (file)
  * @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
-_SCDList(SCDSessionRef session, CFStringRef key, int regexOptions, CFArrayRef *subKeys)
+int
+__SCDynamicStoreCopyKeyList(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex, CFArrayRef *subKeys)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       CFIndex                 cacheCnt;
-       void                    **cacheKeys;
-       void                    **cacheValues;
-       CFMutableArrayRef       keyArray;
-       int                     i;
-       CFStringRef             cacheStr;
-       CFDictionaryRef         cacheValue;
-       int                     regexStrLen;
-       char                    *regexStr = NULL;
-       regex_t                 preg;
-       int                     reError;
-       char                    reErrBuf[256];
-       int                     reErrStrLen;
-
-       SCDLog(LOG_DEBUG, CFSTR("_SCDList:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key          = %@"), key);
-       SCDLog(LOG_DEBUG, CFSTR("  regexOptions = %0o"), regexOptions);
-
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       CFIndex                         storeCnt;
+       void                            **storeKeys;
+       void                            **storeValues;
+       CFMutableArrayRef               keyArray;
+       int                             i;
+       CFStringRef                     storeStr;
+       CFDictionaryRef                 storeValue;
+       int                             regexBufLen;
+       char                            *regexBuf = NULL;
+       regex_t                         preg;
+       int                             reError;
+       char                            reErrBuf[256];
+       int                             reErrStrLen;
+
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyKeyList:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  key     = %@"), key);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  isRegex = %s"), isRegex ? "TRUE" : "FALSE");
+
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
-       cacheCnt = CFDictionaryGetCount(cacheData);
-       keyArray = CFArrayCreateMutable(NULL, cacheCnt, &kCFTypeArrayCallBacks);
+       storeCnt = CFDictionaryGetCount(storeData);
+       keyArray = CFArrayCreateMutable(NULL, storeCnt, &kCFTypeArrayCallBacks);
+
+       if (isRegex) {
+               UniChar                 ch_s    = 0;
+               UniChar                 ch_e    = 0;
+               Boolean                 ok;
+               CFIndex                 regexLen;
+               CFMutableStringRef      regexStr;
+
+               regexStr = CFStringCreateMutableCopy(NULL, 0, key);
+               regexLen = CFStringGetLength(regexStr);
+               if (regexLen > 0) {
+                       ch_s = CFStringGetCharacterAtIndex(regexStr, 0);
+                       ch_e = CFStringGetCharacterAtIndex(regexStr, regexLen - 1);
+               }
+               if ((regexLen == 0) || ((ch_s != (UniChar)'^') && (ch_e != (UniChar)'$'))) {
+                       /* if regex pattern is not already bounded */
+                       CFStringInsert(regexStr, 0, CFSTR("^"));
+                       CFStringAppend(regexStr,    CFSTR("$"));
+               }
 
-       if (regexOptions & kSCDRegexKey) {
                /*
                 * compile the provided regular expression using the
-                * provided regexOptions (passing only those flags
-                * which would make sense).
+                * provided isRegex.
                 */
-               regexStrLen = CFStringGetLength(key) + 1;
-               regexStr    = CFAllocatorAllocate(NULL, regexStrLen, 0);
-               if (!CFStringGetCString(key,
-                                       regexStr,
-                                       regexStrLen,
-                                       kCFStringEncodingMacRoman)) {
-                       SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString() key: could not convert to regex string"));
-                       CFAllocatorDeallocate(NULL, regexStr);
-                       return SCD_FAILED;
+               regexBufLen = CFStringGetLength(regexStr)+1;
+               regexBuf    = CFAllocatorAllocate(NULL, regexBufLen, 0);
+               ok = CFStringGetCString(regexStr, regexBuf, regexBufLen, kCFStringEncodingMacRoman);
+               CFRelease(regexStr);
+               if (!ok) {
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString() key: could not convert to regex string"));
+                       CFAllocatorDeallocate(NULL, regexBuf);
+                       return kSCStatusFailed;
                }
 
-               reError = regcomp(&preg, regexStr, REG_EXTENDED);
+               reError = regcomp(&preg, regexBuf, REG_EXTENDED);
                if (reError != 0) {
                        reErrStrLen = regerror(reError, &preg, reErrBuf, sizeof(reErrBuf));
-                       cacheStr = CFStringCreateWithCString(NULL, reErrBuf, kCFStringEncodingMacRoman);
-                       CFArrayAppendValue(keyArray, cacheStr);
-                       CFRelease(cacheStr);
+                       storeStr = CFStringCreateWithCString(NULL, reErrBuf, kCFStringEncodingMacRoman);
+                       CFArrayAppendValue(keyArray, storeStr);
+                       CFRelease(storeStr);
                        *subKeys = CFArrayCreateCopy(NULL, keyArray);
                        CFRelease(keyArray);
-                       CFAllocatorDeallocate(NULL, regexStr);
-                       return SCD_FAILED;
+                       CFAllocatorDeallocate(NULL, regexBuf);
+                       return kSCStatusFailed;
                }
        }
 
-       cacheKeys   = CFAllocatorAllocate(NULL, cacheCnt * sizeof(CFStringRef), 0);
-       cacheValues = CFAllocatorAllocate(NULL, cacheCnt * sizeof(CFStringRef), 0);
-       CFDictionaryGetKeysAndValues(cacheData, cacheKeys, cacheValues);
-       for (i=0; i<cacheCnt; i++) {
-               cacheStr   = (CFStringRef)cacheKeys[i];
-               cacheValue = (CFDictionaryRef)cacheValues[i];
-               if (regexOptions & kSCDRegexKey) {
+       storeKeys   = CFAllocatorAllocate(NULL, storeCnt * sizeof(CFStringRef), 0);
+       storeValues = CFAllocatorAllocate(NULL, storeCnt * sizeof(CFStringRef), 0);
+       CFDictionaryGetKeysAndValues(storeData, storeKeys, storeValues);
+       for (i=0; i<storeCnt; i++) {
+               storeStr   = (CFStringRef)storeKeys[i];
+               storeValue = (CFDictionaryRef)storeValues[i];
+               if (isRegex) {
                        /*
                         * only return those keys which match the regular
                         * expression specified in the provided key.
                         */
 
-                       int     cacheKeyLen = CFStringGetLength(cacheStr) + 1;
-                       char    *cacheKey   = CFAllocatorAllocate(NULL, cacheKeyLen, 0);
+                       int     storeKeyLen = CFStringGetLength(storeStr) + 1;
+                       char    *storeKey   = CFAllocatorAllocate(NULL, storeKeyLen, 0);
 
-                       if (!CFStringGetCString(cacheStr,
-                                               cacheKey,
-                                               cacheKeyLen,
+                       if (!CFStringGetCString(storeStr,
+                                               storeKey,
+                                               storeKeyLen,
                                                kCFStringEncodingMacRoman)) {
-                               SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString: could not convert cache key to C string"));
-                               CFAllocatorDeallocate(NULL, cacheKey);
+                               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString: could not convert store key to C string"));
+                               CFAllocatorDeallocate(NULL, storeKey);
                                continue;
                        }
 
                        reError = regexec(&preg,
-                                         cacheKey,
+                                         storeKey,
                                          0,
                                          NULL,
                                          0);
                        switch (reError) {
                                case 0 :
                                        /* we've got a match */
-                                       if (CFDictionaryContainsKey(cacheValue, kSCDData))
-                                               CFArrayAppendValue(keyArray, cacheStr);
+                                       if (CFDictionaryContainsKey(storeValue, kSCDData))
+                                               CFArrayAppendValue(keyArray, storeStr);
                                        break;
                                case REG_NOMATCH :
                                        /* no match */
@@ -125,35 +151,32 @@ _SCDList(SCDSessionRef session, CFStringRef key, int regexOptions, CFArrayRef *s
                                                               &preg,
                                                               reErrBuf,
                                                               sizeof(reErrBuf));
-                                       SCDLog(LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
+                                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
                                        break;
                        }
-                       CFAllocatorDeallocate(NULL, cacheKey);
+                       CFAllocatorDeallocate(NULL, storeKey);
                } else {
                        /*
                         * only return those keys which are prefixed by the
                         * provided key string and have data.
                         */
-                       if (((CFStringGetLength(key) == 0) || CFStringHasPrefix(cacheStr, key)) &&
-                           CFDictionaryContainsKey(cacheValue, kSCDData)) {
-                               CFArrayAppendValue(keyArray, cacheStr);
+                       if (((CFStringGetLength(key) == 0) || CFStringHasPrefix(storeStr, key)) &&
+                           CFDictionaryContainsKey(storeValue, kSCDData)) {
+                               CFArrayAppendValue(keyArray, storeStr);
                        }
                }
        }
-       CFAllocatorDeallocate(NULL, cacheKeys);
-       CFAllocatorDeallocate(NULL, cacheValues);
+       CFAllocatorDeallocate(NULL, storeKeys);
+       CFAllocatorDeallocate(NULL, storeValues);
 
-       if (regexOptions & kSCDRegexKey) {
+       if (isRegex) {
                regfree(&preg);
+               CFAllocatorDeallocate(NULL, regexBuf);
        }
 
        *subKeys = keyArray;
 
-       if (regexOptions & kSCDRegexKey) {
-               CFAllocatorDeallocate(NULL, regexStr);
-       }
-
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
@@ -161,10 +184,10 @@ kern_return_t
 _configlist(mach_port_t                        server,
            xmlData_t                   keyRef,         /* raw XML bytes */
            mach_msg_type_number_t      keyLen,
-           int                         regexOptions,
+           int                         isRegex,
            xmlDataOut_t                *listRef,       /* raw XML bytes */
            mach_msg_type_number_t      *listLen,
-           int                         *scd_status
+           int                         *sc_status
 )
 {
        kern_return_t           status;
@@ -175,14 +198,17 @@ _configlist(mach_port_t                   server,
        CFDataRef               xmlList;        /* list (XML serialized) */
        CFStringRef             xmlError;
 
-       SCDLog(LOG_DEBUG, CFSTR("List keys in configuration database."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("List keys in configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
+
+       *listRef = NULL;
+       *listLen = 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));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        key = CFPropertyListCreateFromXMLData(NULL,
@@ -190,17 +216,24 @@ _configlist(mach_port_t                   server,
                                              kCFPropertyListImmutable,
                                              &xmlError);
        CFRelease(xmlKey);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
-               *scd_status = SCD_FAILED;
+       if (!key) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+               return KERN_SUCCESS;
+       } else if (!isA_CFString(key)) {
+               CFRelease(key);
+               *sc_status = kSCStatusInvalidArgument;
                return KERN_SUCCESS;
        }
 
-       *scd_status = _SCDList(mySession->session, key, regexOptions, &subKeys);
+       *sc_status = __SCDynamicStoreCopyKeyList(mySession->store, key, isRegex, &subKeys);
        CFRelease(key);
-       if (*scd_status != SCD_OK) {
-               *listRef = NULL;
-               *listLen = 0;
+       if (*sc_status != kSCStatusOK) {
                return KERN_SUCCESS;
        }
 
@@ -213,8 +246,8 @@ _configlist(mach_port_t                     server,
        *listLen = CFDataGetLength(xmlList);
        status = vm_allocate(mach_task_self(), (void *)listRef, *listLen, TRUE);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
-               *scd_status = SCD_FAILED;
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
+               *sc_status = kSCStatusFailed;
                CFRelease(xmlList);
                *listRef = NULL;
                *listLen = 0;
index ec6b9b1a4deb045f28f2eba1a80a32baadf23ce3..8544c78ea3b324873e2d4d312317b1d7538e697e 100644 (file)
  * @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 "configd_server.h"
 #include "session.h"
 
 
-SCDStatus
-_SCDLock(SCDSessionRef session)
+int
+__SCDynamicStoreLock(SCDynamicStoreRef store, Boolean recursive)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       serverSessionRef        mySession;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       serverSessionRef                mySession;
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDLock:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreLock:"));
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;   /* you must have an open session to play */
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession;         /* you must have an open session to play */
        }
 
-       if (SCDOptionGet(NULL, kSCDOptionIsLocked)) {
-               return SCD_LOCKED;      /* sorry, someone (you) already have the lock */
+       if (storeLocked > 0) {
+               if (storePrivate->locked && recursive) {
+                       /* if this session holds the lock and this is a recursive (internal) request */
+                       storeLocked++;
+                       return kSCStatusOK;
+               }
+               return kSCStatusLocked;                 /* sorry, someone (you) already have the lock */
        }
 
        /* check credentials */
-       mySession = getSession(sessionPrivate->server);
+       mySession = getSession(storePrivate->server);
        if (mySession->callerEUID != 0) {
-#ifdef DEBUG
-               if (!SCDOptionGet(NULL, kSCDOptionDebug)) {
-#endif /* DEBUG */
-                       return SCD_EACCESS;
-#ifdef DEBUG
-               } else {
-                       SCDLog(LOG_DEBUG, CFSTR("  non-root access granted while debugging"));
-               }
-#endif /* DEBUG */
+               return kSCStatusAccessError;
        }
 
-       SCDOptionSet(NULL,    kSCDOptionIsLocked, TRUE);        /* global lock flag */
-       SCDOptionSet(session, kSCDOptionIsLocked, TRUE);        /* per-session lock flag */
+       storeLocked          = 1;       /* global lock flag */
+       storePrivate->locked = TRUE;    /* per-session lock flag */
 
        /*
-        * defer all (actually, most) changes until the call to _SCDUnlock()
+        * defer all (actually, most) changes until the call to __SCDynamicStoreUnlock()
         */
-       if (cacheData_s) {
-               CFRelease(cacheData_s);
+       if (storeData_s) {
+               CFRelease(storeData_s);
                CFRelease(changedKeys_s);
                CFRelease(deferredRemovals_s);
                CFRelease(removedSessionKeys_s);
        }
-       cacheData_s          = CFDictionaryCreateMutableCopy(NULL, 0, cacheData);
+       storeData_s          = CFDictionaryCreateMutableCopy(NULL, 0, storeData);
        changedKeys_s        = CFSetCreateMutableCopy(NULL, 0, changedKeys);
        deferredRemovals_s   = CFSetCreateMutableCopy(NULL, 0, deferredRemovals);
        removedSessionKeys_s = CFSetCreateMutableCopy(NULL, 0, removedSessionKeys);
@@ -75,21 +82,21 @@ _SCDLock(SCDSessionRef session)
        /* Add a "locked" mode run loop source for this port */
        CFRunLoopAddSource(CFRunLoopGetCurrent(), mySession->serverRunLoopSource, CFSTR("locked"));
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
 kern_return_t
-_configlock(mach_port_t server, int *scd_status)
+_configlock(mach_port_t server, int *sc_status)
 {
        serverSessionRef        mySession = getSession(server);
 
-       SCDLog(LOG_DEBUG, CFSTR("Lock configuration database."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Lock configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
 
-       *scd_status = _SCDLock(mySession->session);
-       if (*scd_status != SCD_OK) {
-               SCDLog(LOG_DEBUG, CFSTR("  SCDLock(): %s"), SCDError(*scd_status));
+       *sc_status = __SCDynamicStoreLock(mySession->store, FALSE);
+       if (*sc_status != kSCStatusOK) {
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  SCDynamicStoreLock(): %s"), SCErrorString(*sc_status));
                return KERN_SUCCESS;
        }
 
diff --git a/configd.tproj/_confignotify.c b/configd.tproj/_confignotify.c
new file mode 100644 (file)
index 0000000..8c6e262
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2000 Apple Computer, 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 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.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Modification History
+ *
+ * May 19, 2001                        Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+#include "configd.h"
+#include "session.h"
+
+int
+__SCDynamicStoreNotifyValue(SCDynamicStoreRef store, CFStringRef key)
+{
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       int                             sc_status       = kSCStatusOK;
+       CFDictionaryRef                 dict;
+       Boolean                         newValue        = FALSE;
+       CFPropertyListRef               value;
+
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreNotifyValue:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  key = %@"), key);
+
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
+       }
+
+       /*
+        * 1. Ensure that we hold the lock.
+        */
+       sc_status = __SCDynamicStoreLock(store, TRUE);
+       if (sc_status != kSCStatusOK) {
+               return sc_status;
+       }
+
+       /*
+        * 2. Tickle the value in the dynamic store
+        */
+       dict = CFDictionaryGetValue(storeData, key);
+       if (!dict || !CFDictionaryGetValueIfPresent(dict, kSCDData, (void **)&value)) {
+               /* key doesn't exist (or data never defined) */
+               value = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
+               newValue = TRUE;
+       }
+
+       /* replace or store initial/temporary existing value */
+       __SCDynamicStoreSetValue(store, key, value);
+
+       if (newValue) {
+               /* remove the value we just created */
+               __SCDynamicStoreRemoveValue(store, key);
+               CFRelease(value);
+       }
+
+       /*
+        * 3. Release our lock.
+        */
+       __SCDynamicStoreUnlock(store, TRUE);
+
+       return sc_status;
+}
+
+
+kern_return_t
+_confignotify(mach_port_t              server,
+             xmlData_t                 keyRef,         /* raw XML bytes */
+             mach_msg_type_number_t    keyLen,
+             int                       *sc_status
+)
+{
+       kern_return_t           status;
+       serverSessionRef        mySession = getSession(server);
+       CFDataRef               xmlKey;         /* key  (XML serialized) */
+       CFStringRef             key;            /* key  (un-serialized) */
+       CFStringRef             xmlError;
+
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Notify key in configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
+
+       /* un-serialize the key */
+       xmlKey = CFDataCreate(NULL, keyRef, keyLen);
+       status = vm_deallocate(mach_task_self(), (vm_address_t)keyRef, keyLen);
+       if (status != KERN_SUCCESS) {
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+               /* non-fatal???, proceed */
+       }
+       key = CFPropertyListCreateFromXMLData(NULL,
+                                             xmlKey,
+                                             kCFPropertyListImmutable,
+                                             &xmlError);
+       CFRelease(xmlKey);
+       if (!key) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+               return KERN_SUCCESS;
+       } else if (!isA_CFString(key)) {
+               *sc_status = kSCStatusInvalidArgument;
+               return KERN_SUCCESS;
+       }
+
+       *sc_status = __SCDynamicStoreNotifyValue(mySession->store, key);
+       CFRelease(key);
+
+       return KERN_SUCCESS;
+}
index 62b1238568e684445bc0713ebdb921d583248d57..f462ee9cd90ba23b678e1edd45c76d20b549f88b 100644 (file)
  * @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 "configd_server.h"
 #include "session.h"
 
-SCDStatus
-_SCDOpen(SCDSessionRef *session, CFStringRef name)
+int
+__SCDynamicStoreOpen(SCDynamicStoreRef *store, CFStringRef name)
 {
-       SCDSessionPrivateRef    sessionPrivate;
-
-       SCDLog(LOG_DEBUG, CFSTR("_SCDOpen:"));
-       SCDLog(LOG_DEBUG, CFSTR("  name = %@"), name);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreOpen:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  name = %@"), name);
 
        /*
         * allocate and initialize a new session
         */
-       sessionPrivate = (SCDSessionPrivateRef)_SCDSessionCreatePrivate();
-       *session       = (SCDSessionRef)sessionPrivate;
+       *store = __SCDynamicStoreCreatePrivate(NULL, name, NULL, NULL);
 
        /*
-        * If necessary, initialize the cache and session data dictionaries
+        * If necessary, initialize the store and session data dictionaries
         */
-       if (cacheData == NULL) {
-               cacheData          = CFDictionaryCreateMutable(NULL,
+       if (storeData == NULL) {
+               storeData          = CFDictionaryCreateMutable(NULL,
                                                               0,
                                                               &kCFTypeDictionaryKeyCallBacks,
                                                               &kCFTypeDictionaryValueCallBacks);
@@ -61,7 +68,7 @@ _SCDOpen(SCDSessionRef *session, CFStringRef name)
                                                        &kCFTypeSetCallBacks);
        }
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
@@ -70,28 +77,28 @@ _configopen(mach_port_t                     server,
            xmlData_t                   nameRef,                /* raw XML bytes */
            mach_msg_type_number_t      nameLen,
            mach_port_t                 *newServer,
-           int                         *scd_status)
+           int                         *sc_status)
 {
        kern_return_t           status;
        serverSessionRef        mySession, newSession;
        CFDataRef               xmlName;        /* name (XML serialized) */
        CFStringRef             name;           /* name (un-serialized) */
        CFStringRef             xmlError;
-       mach_port_t             oldNotify;
+       mach_port_t             oldNotify;
        CFStringRef             sessionKey;
        CFDictionaryRef         info;
        CFMutableDictionaryRef  newInfo;
        CFMachPortRef           mp;
 
-       SCDLog(LOG_DEBUG, CFSTR("Open new session."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Open new session."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
 
        /* un-serialize the name */
        xmlName = CFDataCreate(NULL, nameRef, nameLen);
        status = vm_deallocate(mach_task_self(), (vm_address_t)nameRef, nameLen);
        if (status != KERN_SUCCESS) {
                CFRelease(xmlName);
-               SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        name = CFPropertyListCreateFromXMLData(NULL,
@@ -99,17 +106,26 @@ _configopen(mach_port_t                    server,
                                               kCFPropertyListImmutable,
                                               &xmlError);
        CFRelease(xmlName);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() name: %s"), xmlError);
-               *scd_status = SCD_FAILED;
+       if (!name) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() name: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+               return KERN_SUCCESS;
+       } else if (!isA_CFString(name)) {
+               CFRelease(name);
+               *sc_status = kSCStatusInvalidArgument;
                return KERN_SUCCESS;
        }
 
        mySession = getSession(server);
-       if (mySession->session) {
+       if (mySession->store) {
                CFRelease(name);
-               SCDLog(LOG_DEBUG, CFSTR("  Sorry, this session is already open."));
-               *scd_status = SCD_FAILED;       /* you can't re-open an "open" session */
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  Sorry, this session is already open."));
+               *sc_status = kSCStatusFailed;   /* you can't re-open an "open" session */
                return KERN_SUCCESS;
        }
 
@@ -136,12 +152,12 @@ _configopen(mach_port_t                   server,
        newSession->callerEUID = mySession->callerEUID;
        newSession->callerEGID = mySession->callerEGID;
 
-       *scd_status = _SCDOpen(&newSession->session, name);
+       *sc_status = __SCDynamicStoreOpen(&newSession->store, name);
 
        /*
         * Make the server port accessible to the framework routines.
         */
-       ((SCDSessionPrivateRef)newSession->session)->server = *newServer;
+       ((SCDynamicStorePrivateRef)newSession->store)->server = *newServer;
 
        /* Request a notification when/if the client dies */
        status = mach_port_request_notification(mach_task_self(),
@@ -152,19 +168,17 @@ _configopen(mach_port_t                   server,
                                                MACH_MSG_TYPE_MAKE_SEND_ONCE,
                                                &oldNotify);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
                CFRelease(name);
                cleanupSession(*newServer);
                *newServer = MACH_PORT_NULL;
-               *scd_status = SCD_FAILED;
+               *sc_status = kSCStatusFailed;
                return KERN_SUCCESS;
-       }
+       }
 
-#ifdef DEBUG
        if (oldNotify != MACH_PORT_NULL) {
-               SCDLog(LOG_DEBUG, CFSTR("_configopen(): why is oldNotify != MACH_PORT_NULL?"));
+               SCLog(_configd_verbose, LOG_ERR, CFSTR("_configopen(): why is oldNotify != MACH_PORT_NULL?"));
        }
-#endif /* DEBUG */
 
        /*
         * Save the name of the calling application / plug-in with the session data.
index 77c5fa979c33c75a96ba4d9b4585a20f284185f7..a496571f77bc8249bc4816cd40e59139cf01674f 100644 (file)
  * @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
-_SCDRemove(SCDSessionRef session, CFStringRef key)
+int
+__SCDynamicStoreRemoveValue(SCDynamicStoreRef store, CFStringRef key)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       SCDStatus               scd_status = SCD_OK;
-       boolean_t               wasLocked;
-       CFDictionaryRef         dict;
-       CFMutableDictionaryRef  newDict;
-       CFStringRef             sessionKey;
-
-       SCDLog(LOG_DEBUG, CFSTR("_SCDRemove:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key      = %@"), key);
-
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       int                             sc_status = kSCStatusOK;
+       CFDictionaryRef                 dict;
+       CFMutableDictionaryRef          newDict;
+       CFStringRef                     sessionKey;
+
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreRemoveValue:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  key      = %@"), key);
+
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
        /*
-        * 1. Determine if the cache lock is currently held  and acquire
-        *    the lock if necessary.
+        * 1. Ensure that we hold the lock.
         */
-       wasLocked = SCDOptionGet(NULL, kSCDOptionIsLocked);
-       if (!wasLocked) {
-               scd_status = _SCDLock(session);
-               if (scd_status != SCD_OK) {
-                       SCDLog(LOG_DEBUG, CFSTR("  _SCDLock(): %s"), SCDError(scd_status));
-                       return scd_status;
-               }
+       sc_status = __SCDynamicStoreLock(store, TRUE);
+       if (sc_status != kSCStatusOK) {
+               return sc_status;
        }
 
        /*
         * 2. Ensure that this key exists.
         */
-       dict = CFDictionaryGetValue(cacheData, key);
+       dict = CFDictionaryGetValue(storeData, key);
        if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
                /* key doesn't exist (or data never defined) */
-               scd_status = SCD_NOKEY;
+               sc_status = kSCStatusNoKey;
                goto done;
        }
        newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
@@ -96,27 +100,26 @@ _SCDRemove(SCDSessionRef session, CFStringRef key)
 
        /*
         * 6. Remove data, remove instance, and update/remove
-        *    the dictionary cache entry.
+        *    the dictionary store entry.
         */
        CFDictionaryRemoveValue(newDict, kSCDData);
        CFDictionaryRemoveValue(newDict, kSCDInstance);
        if (CFDictionaryGetCount(newDict) > 0) {
                /* this key is still being "watched" */
-               CFDictionarySetValue(cacheData, key, newDict);
+               CFDictionarySetValue(storeData, key, newDict);
        } else {
                /* no information left, remove the empty dictionary */
-               CFDictionaryRemoveValue(cacheData, key);
+               CFDictionaryRemoveValue(storeData, key);
        }
        CFRelease(newDict);
 
        /*
-        * 7. Release the lock if we acquired it as part of this request.
+        * 7. Release our lock.
         */
     done:
-       if (!wasLocked)
-               _SCDUnlock(session);
+       __SCDynamicStoreUnlock(store, TRUE);
 
-       return scd_status;
+       return sc_status;
 }
 
 
@@ -124,7 +127,7 @@ kern_return_t
 _configremove(mach_port_t              server,
              xmlData_t                 keyRef,         /* raw XML bytes */
              mach_msg_type_number_t    keyLen,
-             int                       *scd_status
+             int                       *sc_status
 )
 {
        kern_return_t           status;
@@ -133,14 +136,14 @@ _configremove(mach_port_t         server,
        CFStringRef             key;            /* key  (un-serialized) */
        CFStringRef             xmlError;
 
-       SCDLog(LOG_DEBUG, CFSTR("Remove key from configuration database."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Remove key from configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
 
        /* 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));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        key = CFPropertyListCreateFromXMLData(NULL,
@@ -148,13 +151,21 @@ _configremove(mach_port_t         server,
                                              kCFPropertyListImmutable,
                                              &xmlError);
        CFRelease(xmlKey);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
-               *scd_status = SCD_FAILED;
+       if (!key) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+               return KERN_SUCCESS;
+       } else if (!isA_CFString(key)) {
+               *sc_status = kSCStatusInvalidArgument;
                return KERN_SUCCESS;
        }
 
-       *scd_status = _SCDRemove(mySession->session, key);
+       *sc_status = __SCDynamicStoreRemoveValue(mySession->store, key);
        CFRelease(key);
 
        return KERN_SUCCESS;
index efa671c291f41662a34ceb17fc4dfb23b622423e..0b432608ae0088d78baee416da22cbdd9e4152af 100644 (file)
  * @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
-_SCDSet(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
+int
+__SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       SCDStatus               scd_status = SCD_OK;
-       boolean_t               wasLocked;
-       CFDictionaryRef         dict;
-       CFMutableDictionaryRef  newDict;
-       CFNumberRef             num;
-       int                     dictInstance;
-       CFStringRef             sessionKey;
-       CFStringRef             cacheSessionKey;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       int                             sc_status       = kSCStatusOK;
+       CFDictionaryRef                 dict;
+       CFMutableDictionaryRef          newDict;
+       Boolean                         newEntry        = FALSE;
+       CFStringRef                     sessionKey;
+       CFStringRef                     storeSessionKey;
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDSet:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key          = %@"), key);
-       SCDLog(LOG_DEBUG, CFSTR("  data         = %@"), SCDHandleGetData(handle));
-       SCDLog(LOG_DEBUG, CFSTR("  instance     = %d"), SCDHandleGetInstance(handle));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreSetValue:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  key          = %@"), key);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  value        = %@"), value);
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
        /*
-        * 1. Determine if the cache lock is currently held
-        *    and acquire the lock if necessary.
+        * 1. Ensure that we hold the lock.
         */
-       wasLocked = SCDOptionGet(NULL, kSCDOptionIsLocked);
-       if (!wasLocked) {
-               scd_status = _SCDLock(session);
-               if (scd_status != SCD_OK) {
-                       SCDLog(LOG_DEBUG, CFSTR("  _SCDLock(): %s"), SCDError(scd_status));
-                       return scd_status;
-               }
+       sc_status = __SCDynamicStoreLock(store, TRUE);
+       if (sc_status != kSCStatusOK) {
+               return sc_status;
        }
 
        /*
         * 2. Grab the current (or establish a new) dictionary for this key.
         */
 
-       dict = CFDictionaryGetValue(cacheData, key);
+       dict = CFDictionaryGetValue(storeData, key);
        if (dict) {
                newDict = CFDictionaryCreateMutableCopy(NULL,
                                                        0,
@@ -75,67 +77,40 @@ _SCDSet(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
        }
 
        /*
-        * 3. Make sure that we're not updating the cache with potentially
-        *    stale information.
+        * 3. Update the dictionary entry to be saved to the store.
         */
-
-       if ((num = CFDictionaryGetValue(newDict, kSCDInstance)) == NULL) {
-               /* if first instance */
-               dictInstance = 0;
-               _SCDHandleSetInstance(handle, dictInstance);
-       } else {
-               (void) CFNumberGetValue(num, kCFNumberIntType, &dictInstance);
-       }
-       if (SCDHandleGetInstance(handle) != dictInstance) {
-               /* data may be based on old information */
-               CFRelease(newDict);
-               scd_status = SCD_STALE;
-               goto done;
-       }
+       newEntry = !CFDictionaryContainsKey(newDict, kSCDData);
+       CFDictionarySetValue(newDict, kSCDData, value);
 
        /*
-        * 4. Update the dictionary entry (data & instance) to be saved to
-        *    the cache.
-        */
-
-       CFDictionarySetValue(newDict, kSCDData, SCDHandleGetData(handle));
-
-       dictInstance++;
-       num = CFNumberCreate(NULL, kCFNumberIntType, &dictInstance);
-       CFDictionarySetValue(newDict, kSCDInstance, num);
-       CFRelease(num);
-       _SCDHandleSetInstance(handle, dictInstance);
-       SCDLog(LOG_DEBUG, CFSTR("  new instance = %d"), SCDHandleGetInstance(handle));
-
-       /*
-        * 5. Since we are updating this key we need to check and, if
+        * 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"), sessionPrivate->server);
-       if (CFDictionaryGetValueIfPresent(newDict, kSCDSession, (void *)&cacheSessionKey) &&
-           !CFEqual(sessionKey, cacheSessionKey)) {
+       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("%@:%@"), cacheSessionKey, key);
+               removedKey = CFStringCreateWithFormat(NULL, 0, CFSTR("%@:%@"), storeSessionKey, key);
                CFSetAddValue(removedSessionKeys, removedKey);
                CFRelease(removedKey);
        }
        CFRelease(sessionKey);
 
        /*
-        * 6. Update the dictionary entry in the cache.
+        * 5. Update the dictionary entry in the store.
         */
 
-       CFDictionarySetValue(cacheData, key, newDict);
+       CFDictionarySetValue(storeData, key, newDict);
        CFRelease(newDict);
 
        /*
-        * 7. For "new" entries to the cache, check the deferred cleanup
+        * 6. For "new" entries to the store, check the deferred cleanup
         *    list. If the key is flagged for removal, remove it from the
         *    list since any defined regex's for this key are still defined
         *    and valid. If the key is not flagged then iterate over the
@@ -144,7 +119,7 @@ _SCDSet(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
         *    being watched.
         */
 
-       if (dictInstance == 1) {
+       if (newEntry) {
                if (CFSetContainsValue(deferredRemovals, key)) {
                        CFSetRemoveValue(deferredRemovals, key);
                } else {
@@ -155,22 +130,19 @@ _SCDSet(SCDSessionRef session, CFStringRef key, SCDHandleRef handle)
        }
 
        /*
-        * 8. Mark this key as "changed". Any "watchers" will be notified
+        * 7. Mark this key as "changed". Any "watchers" will be notified
         *    as soon as the lock is released.
         */
        CFSetAddValue(changedKeys, key);
 
        /*
-        * 9. Release the lock if we acquired it as part of this request.
+        * 8. Release our lock.
         */
-    done:
-       if (!wasLocked)
-               _SCDUnlock(session);
+       __SCDynamicStoreUnlock(store, TRUE);
 
-       return scd_status;
+       return sc_status;
 }
 
-
 kern_return_t
 _configset(mach_port_t                 server,
           xmlData_t                    keyRef,         /* raw XML bytes */
@@ -179,7 +151,7 @@ _configset(mach_port_t                      server,
           mach_msg_type_number_t       dataLen,
           int                          oldInstance,
           int                          *newInstance,
-          int                          *scd_status
+          int                          *sc_status
 )
 {
        kern_return_t           status;
@@ -188,17 +160,18 @@ _configset(mach_port_t                    server,
        CFStringRef             key;            /* key  (un-serialized) */
        CFDataRef               xmlData;        /* data (XML serialized) */
        CFPropertyListRef       data;           /* data (un-serialized) */
-       SCDHandleRef            handle;
        CFStringRef             xmlError;
 
-       SCDLog(LOG_DEBUG, CFSTR("Set key to configuration database."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Set key to configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
+
+       *sc_status = kSCStatusOK;
 
        /* 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));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        key = CFPropertyListCreateFromXMLData(NULL,
@@ -206,17 +179,23 @@ _configset(mach_port_t                    server,
                                              kCFPropertyListImmutable,
                                              &xmlError);
        CFRelease(xmlKey);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
-               *scd_status = SCD_FAILED;
-               return KERN_SUCCESS;
+       if (!key) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+       } else if (!isA_CFString(key)) {
+               *sc_status = kSCStatusInvalidArgument;
        }
 
        /* un-serialize the data */
        xmlData = CFDataCreate(NULL, dataRef, dataLen);
        status = vm_deallocate(mach_task_self(), (vm_address_t)dataRef, dataLen);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        data = CFPropertyListCreateFromXMLData(NULL,
@@ -224,23 +203,239 @@ _configset(mach_port_t                   server,
                                               kCFPropertyListImmutable,
                                               &xmlError);
        CFRelease(xmlData);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() data: %s"), xmlError);
-               CFRelease(key);
-               *scd_status = SCD_FAILED;
-               return KERN_SUCCESS;
+       if (!data) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() data: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+       } else if (!isA_CFPropertyList(data)) {
+               *sc_status = kSCStatusInvalidArgument;
        }
 
-       handle = SCDHandleInit();
-       SCDHandleSetData(handle, data);
-       _SCDHandleSetInstance(handle, oldInstance);
-       *scd_status = _SCDSet(mySession->session, key, handle);
-       if (*scd_status == SCD_OK) {
-               *newInstance = SCDHandleGetInstance(handle);
+       if (*sc_status != kSCStatusOK) {
+               if (key)        CFRelease(key);
+               if (data)       CFRelease(data);
+               return KERN_SUCCESS;
        }
-       SCDHandleRelease(handle);
+
+       *sc_status = __SCDynamicStoreSetValue(mySession->store, key, data);
+       *newInstance = 0;
+
        CFRelease(key);
        CFRelease(data);
 
        return KERN_SUCCESS;
 }
+
+static void
+setSpecificKey(const void *key, const void *value, void *context)
+{
+       CFStringRef             k       = (CFStringRef)key;
+       CFPropertyListRef       v       = (CFPropertyListRef)value;
+       SCDynamicStoreRef       store   = (SCDynamicStoreRef)context;
+
+       if (!isA_CFString(k)) {
+               return;
+       }
+
+       if (!isA_CFPropertyList(v)) {
+               return;
+       }
+
+       (void) __SCDynamicStoreSetValue(store, k, v);
+
+       return;
+}
+
+static void
+removeSpecificKey(const void *value, void *context)
+{
+       CFStringRef             k       = (CFStringRef)value;
+       SCDynamicStoreRef       store   = (SCDynamicStoreRef)context;
+
+       if (!isA_CFString(k)) {
+               return;
+       }
+
+       (void) __SCDynamicStoreRemoveValue(store, k);
+
+       return;
+}
+
+static void
+notifySpecificKey(const void *value, void *context)
+{
+       CFStringRef             k       = (CFStringRef)value;
+       SCDynamicStoreRef       store   = (SCDynamicStoreRef)context;
+
+       if (!isA_CFString(k)) {
+               return;
+       }
+
+       (void) __SCDynamicStoreNotifyValue(store, k);
+
+       return;
+}
+
+kern_return_t
+_configset_m(mach_port_t               server,
+            xmlData_t                  dictRef,
+            mach_msg_type_number_t     dictLen,
+            xmlData_t                  removeRef,
+            mach_msg_type_number_t     removeLen,
+            xmlData_t                  notifyRef,
+            mach_msg_type_number_t     notifyLen,
+            int                        *sc_status)
+{
+       kern_return_t           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) */
+
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Set key to configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
+
+       *sc_status = kSCStatusOK;
+
+       if (dictRef && (dictLen > 0)) {
+               CFDataRef       xmlDict;        /* key/value dictionary (XML serialized) */
+               CFStringRef     xmlError;
+
+               /* un-serialize the key/value pairs to set */
+               xmlDict = CFDataCreate(NULL, dictRef, dictLen);
+               status = vm_deallocate(mach_task_self(), (vm_address_t)dictRef, dictLen);
+               if (status != KERN_SUCCESS) {
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+                       /* non-fatal???, proceed */
+               }
+               dict = CFPropertyListCreateFromXMLData(NULL,
+                                                      xmlDict,
+                                                      kCFPropertyListImmutable,
+                                                      &xmlError);
+               CFRelease(xmlDict);
+               if (!dict) {
+                       if (xmlError) {
+                               SCLog(_configd_verbose, LOG_DEBUG,
+                                      CFSTR("CFPropertyListCreateFromXMLData() dict: %@"),
+                                      xmlError);
+                               CFRelease(xmlError);
+                       }
+                       *sc_status = kSCStatusFailed;
+               } else if (!isA_CFDictionary(dict)) {
+                       *sc_status = kSCStatusInvalidArgument;
+               }
+       }
+
+       if (removeRef && (removeLen > 0)) {
+               CFDataRef       xmlRemove;      /* keys to remove (XML serialized) */
+               CFStringRef     xmlError;
+
+               /* un-serialize the keys to remove */
+               xmlRemove = CFDataCreate(NULL, removeRef, removeLen);
+               status = vm_deallocate(mach_task_self(), (vm_address_t)removeRef, removeLen);
+               if (status != KERN_SUCCESS) {
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+                       /* non-fatal???, proceed */
+               }
+               remove = CFPropertyListCreateFromXMLData(NULL,
+                                                        xmlRemove,
+                                                        kCFPropertyListImmutable,
+                                                        &xmlError);
+               CFRelease(xmlRemove);
+               if (!remove) {
+                       if (xmlError) {
+                               SCLog(_configd_verbose, LOG_DEBUG,
+                                      CFSTR("CFPropertyListCreateFromXMLData() remove: %@"),
+                                      xmlError);
+                               CFRelease(xmlError);
+                       }
+                       *sc_status = kSCStatusFailed;
+               } else if (!isA_CFArray(remove)) {
+                       *sc_status = kSCStatusInvalidArgument;
+               }
+       }
+
+       if (notifyRef && (notifyLen > 0)) {
+               CFDataRef       xmlNotify;      /* keys to notify (XML serialized) */
+               CFStringRef     xmlError;
+
+               /* un-serialize the keys to notify */
+               xmlNotify = CFDataCreate(NULL, notifyRef, notifyLen);
+               status = vm_deallocate(mach_task_self(), (vm_address_t)notifyRef, notifyLen);
+               if (status != KERN_SUCCESS) {
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+                       /* non-fatal???, proceed */
+               }
+               notify = CFPropertyListCreateFromXMLData(NULL,
+                                                      xmlNotify,
+                                                      kCFPropertyListImmutable,
+                                                      &xmlError);
+               CFRelease(xmlNotify);
+               if (!notify) {
+                       if (xmlError) {
+                               SCLog(_configd_verbose, LOG_DEBUG,
+                                      CFSTR("CFPropertyListCreateFromXMLData() notify: %@"),
+                                      xmlError);
+                               CFRelease(xmlError);
+                       }
+                       *sc_status = kSCStatusFailed;
+               } else if (!isA_CFArray(notify)) {
+                       *sc_status = kSCStatusInvalidArgument;
+               }
+       }
+
+       if (*sc_status != kSCStatusOK) {
+               goto done;
+       }
+
+       /*
+        * Ensure that we hold the lock
+        */
+       *sc_status = __SCDynamicStoreLock(mySession->store, TRUE);
+       if (*sc_status != kSCStatusOK) {
+               goto done;
+       }
+
+       /*
+        * Set the new/updated keys
+        */
+       if (dict) {
+               CFDictionaryApplyFunction(dict,
+                                         setSpecificKey,
+                                         (void *)mySession->store);
+       }
+
+       /*
+        * Remove the specified keys
+        */
+       if (remove) {
+               CFArrayApplyFunction(remove,
+                                    CFRangeMake(0, CFArrayGetCount(remove)),
+                                    removeSpecificKey,
+                                    (void *)mySession->store);
+       }
+
+       /*
+        * Notify the specified keys
+        */
+       if (notify) {
+               CFArrayApplyFunction(notify,
+                                    CFRangeMake(0, CFArrayGetCount(notify)),
+                                    notifySpecificKey,
+                                    (void *)mySession->store);
+       }
+
+       __SCDynamicStoreUnlock(mySession->store, TRUE); /* Release our lock */
+
+    done :
+
+       if (dict)       CFRelease(dict);
+       if (remove)     CFRelease(remove);
+       if (notify)     CFRelease(notify);
+
+       return KERN_SUCCESS;
+}
index 318e6db7e0b2b387ce86deb33e07bedefe669c1d..f241ad839f74f34dd651b2b2f6ef297bd0bf03a0 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * June 20, 2000               Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include "configd.h"
 #include "session.h"
 
-SCDStatus
-_SCDTouch(SCDSessionRef session, CFStringRef key)
+int
+__SCDynamicStoreTouchValue(SCDynamicStoreRef store, CFStringRef key)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       SCDStatus               scd_status;
-       boolean_t               wasLocked;
-       SCDHandleRef            handle;
-       CFPropertyListRef       value;
+       SCDynamicStorePrivateRef        storePrivate    = (SCDynamicStorePrivateRef)store;
+       int                             sc_status;
+       Boolean                         newValue        = FALSE;
+       CFPropertyListRef               value;
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDTouch:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key = %@"), key);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreTouchValue:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  key = %@"), key);
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
        /*
-        * 1. Determine if the cache lock is currently held by this session
-        *    and acquire the lock if necessary.
+        * 1. Ensure that we hold the lock.
         */
-       wasLocked = SCDOptionGet(NULL, kSCDOptionIsLocked);
-       if (!wasLocked) {
-               scd_status = _SCDLock(session);
-               if (scd_status != SCD_OK) {
-                       SCDLog(LOG_DEBUG, CFSTR("  _SCDLock(): %s"), SCDError(scd_status));
-                       return scd_status;
-               }
+       sc_status = __SCDynamicStoreLock(store, TRUE);
+       if (sc_status != kSCStatusOK) {
+               return sc_status;
        }
 
        /*
-        * 2. Grab the current (or establish a new) cache entry for this key.
+        * 2. Grab the current (or establish a new) store entry for this key.
         */
-       scd_status = _SCDGet(session, key, &handle);
-       switch (scd_status) {
-               case SCD_NOKEY :
-                       /* cache entry does not exist, create */
-                       handle = SCDHandleInit();
-                       value  = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
-                       SCDLog(LOG_DEBUG, CFSTR("  new time stamp = %@"), value);
-                       SCDHandleSetData(handle, value);
-                       CFRelease(value);
+       sc_status = __SCDynamicStoreCopyValue(store, key, &value);
+       switch (sc_status) {
+               case kSCStatusNoKey :
+                       /* store entry does not exist, create */
+                       value    = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
+                       newValue = TRUE;
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  new time stamp = %@"), value);
                        break;
 
-               case SCD_OK :
-                       /* cache entry exists, update */
-                       value = SCDHandleGetData(handle);
+               case kSCStatusOK :
+                       /* store entry exists */
                        if (CFGetTypeID(value) == CFDateGetTypeID()) {
-                               /* if value is a CFDate */
-                               value = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
-                               SCDLog(LOG_DEBUG, CFSTR("  new time stamp = %@"), value);
-                               SCDHandleSetData(handle, value);
+                               /* the value is a CFDate, update the time stamp */
                                CFRelease(value);
+                               value = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
+                               newValue = TRUE;
+                               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  new time stamp = %@"), value);
                        } /* else, we'll just save the data (again) to bump the instance */
                        break;
 
                default :
-                       SCDLog(LOG_DEBUG, CFSTR("  _SCDGet(): %s"), SCDError(scd_status));
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  __SCDynamicStoreCopyValue(): %s"), SCErrorString(sc_status));
                        goto done;
        }
 
-       scd_status = _SCDSet(session, key, handle);
-       SCDHandleRelease(handle);
+       sc_status = __SCDynamicStoreSetValue(store, key, value);
+
+       if (newValue) {
+               CFRelease(value);
+       }
 
     done :
 
        /*
-        * 8. Release the lock if we acquired it as part of this request.
+        * 8. Release our lock.
         */
-       if (!wasLocked)
-               _SCDUnlock(session);
+       __SCDynamicStoreUnlock(store, TRUE);
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
 kern_return_t
-_configtouch(mach_port_t                       server,
+_configtouch(mach_port_t               server,
             xmlData_t                  keyRef,         /* raw XML bytes */
             mach_msg_type_number_t     keyLen,
-            int                                *scd_status
+            int                        *sc_status
 )
 {
        kern_return_t           status;
@@ -111,14 +114,14 @@ _configtouch(mach_port_t                  server,
        CFStringRef             key;            /* key  (un-serialized) */
        CFStringRef             xmlError;
 
-       SCDLog(LOG_DEBUG, CFSTR("Touch key in configuration database."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Touch key in configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
 
        /* 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));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        key = CFPropertyListCreateFromXMLData(NULL,
@@ -126,13 +129,21 @@ _configtouch(mach_port_t                  server,
                                              kCFPropertyListImmutable,
                                              &xmlError);
        CFRelease(xmlKey);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
-               *scd_status = SCD_FAILED;
+       if (!key) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+               return KERN_SUCCESS;
+       } else if (!isA_CFString(key)) {
+               *sc_status = kSCStatusInvalidArgument;
                return KERN_SUCCESS;
        }
 
-       *scd_status = _SCDTouch(mySession->session, key);
+       *sc_status = __SCDynamicStoreTouchValue(mySession->store, key);
        CFRelease(key);
 
        return KERN_SUCCESS;
index 421eee6f39d2f6bf1d235a06f332fecc31456ad1..8cf247a6d7a52ab465c6af362b0c9dcaab61d55f 100644 (file)
  * @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 "configd_server.h"
@@ -47,7 +57,7 @@ _notifyWatchers()
                CFArrayRef              changes;
                CFMutableArrayRef       newChanges;
 
-               dict = CFDictionaryGetValue(cacheData, (CFStringRef)keys[keyCnt]);
+               dict = CFDictionaryGetValue(storeData, (CFStringRef)keys[keyCnt]);
                if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDWatchers) == FALSE)) {
                        /* key doesn't exist or nobody cares if it changed */
                        continue;
@@ -110,7 +120,7 @@ _notifyWatchers()
 
        /*
         * The list of changed keys have been updated for any sessions
-        * monitoring changes to the "cache". The next step, handled by
+        * monitoring changes to the "store". The next step, handled by
         * the "configd" server, is to push out any needed notifications.
         */
        CFSetRemoveAllValues(changedKeys);
@@ -137,7 +147,7 @@ _processDeferredRemovals()
        CFAllocatorDeallocate(NULL, keys);
 
        /*
-        * All regex keys associated with removed cache dictionary keys have
+        * All regex keys associated with removed store dictionary keys have
         * been removed. Start the list fresh again.
         */
        CFSetRemoveAllValues(deferredRemovals);
@@ -215,35 +225,41 @@ _cleanupRemovedSessionKeys(const void *value, void *context)
 }
 
 
-SCDStatus
-_SCDUnlock(SCDSessionRef session)
+int
+__SCDynamicStoreUnlock(SCDynamicStoreRef store, Boolean recursive)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       serverSessionRef        mySession;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       serverSessionRef                mySession;
+
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreUnlock:"));
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDUnlock:"));
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession;         /* you must have an open session to play */
+       }
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;
+       if ((storeLocked == 0) || !storePrivate->locked) {
+               return kSCStatusNeedLock;               /* sorry, you don't have the lock */
        }
 
-       if (!SCDOptionGet(NULL, kSCDOptionIsLocked) || !SCDOptionGet(session, kSCDOptionIsLocked)) {
-               return SCD_NEEDLOCK;    /* sorry, you don't have the lock */
+       if ((storeLocked > 1) && recursive) {
+               /* if the lock is being held for a recursive (internal) request */
+               storeLocked--;
+               return kSCStatusOK;
        }
 
        /*
-        * all of the changes can be committed to the (real) cache.
+        * all of the changes can be committed to the (real) store.
         */
-       CFDictionaryRemoveAllValues(cacheData_s);
+       CFDictionaryRemoveAllValues(storeData_s);
        CFSetRemoveAllValues       (changedKeys_s);
        CFSetRemoveAllValues       (deferredRemovals_s);
        CFSetRemoveAllValues       (removedSessionKeys_s);
 
 #ifdef DEBUG
-       SCDLog(LOG_DEBUG, CFSTR("keys I changed           = %@"), changedKeys);
-       SCDLog(LOG_DEBUG, CFSTR("keys flagged for removal = %@"), deferredRemovals);
-       SCDLog(LOG_DEBUG, CFSTR("keys I'm watching        = %@"), sessionPrivate->keys);
-       SCDLog(LOG_DEBUG, CFSTR("regex keys I'm watching  = %@"), sessionPrivate->reKeys);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("keys I changed           = %@"), changedKeys);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("keys flagged for removal = %@"), deferredRemovals);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("keys I'm watching        = %@"), storePrivate->keys);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regex keys I'm watching  = %@"), storePrivate->reKeys);
 #endif /* DEBUG */
 
        /*
@@ -264,31 +280,31 @@ _SCDUnlock(SCDSessionRef session)
        CFSetRemoveAllValues(removedSessionKeys);
 
 #ifdef DEBUG
-       SCDLog(LOG_DEBUG, CFSTR("sessions to notify = %@"), needsNotification);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("sessions to notify = %@"), needsNotification);
 #endif /* DEBUG */
 
        /* Remove the "locked" run loop source for this port */
-       mySession = getSession(sessionPrivate->server);
+       mySession = getSession(storePrivate->server);
        CFRunLoopRemoveSource(CFRunLoopGetCurrent(), mySession->serverRunLoopSource, CFSTR("locked"));
 
-       SCDOptionSet(NULL,    kSCDOptionIsLocked, FALSE);       /* global lock flag */
-       SCDOptionSet(session, kSCDOptionIsLocked, FALSE);       /* per-session lock flag */
+       storeLocked          = 0;       /* global lock flag */
+       storePrivate->locked = FALSE;   /* per-session lock flag */
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
 kern_return_t
-_configunlock(mach_port_t server, int *scd_status)
+_configunlock(mach_port_t server, int *sc_status)
 {
        serverSessionRef        mySession = getSession(server);
 
-       SCDLog(LOG_DEBUG, CFSTR("Unlock configuration database."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Unlock configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
 
-       *scd_status = _SCDUnlock(mySession->session);
-       if (*scd_status != SCD_OK) {
-               SCDLog(LOG_DEBUG, CFSTR("  _SCDUnlock(): %s"), SCDError(*scd_status));
+       *sc_status = __SCDynamicStoreUnlock(mySession->store, FALSE);
+       if (*sc_status != kSCStatusOK) {
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  __SCDynamicStoreUnlock(): %s"), SCErrorString(*sc_status));
                return KERN_SUCCESS;
        }
 
index 5ca354af6fb9fdb6afaf1b15039ed30964fd33cd..56210cd50ddf8018048e1a1d62314b2adedefbbf 100644 (file)
  * @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
-_SCDNotifierAdd(SCDSessionRef session, CFStringRef key, int regexOptions)
+
+static __inline__ void
+my_CFDictionaryApplyFunction(CFDictionaryRef                   theDict,
+                            CFDictionaryApplierFunction        applier,
+                            void                               *context)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
+       CFAllocatorRef  myAllocator;
+       CFDictionaryRef myDict;
+
+       myAllocator = CFGetAllocator(theDict);
+       myDict      = CFDictionaryCreateCopy(myAllocator, theDict);
+       CFDictionaryApplyFunction(myDict, applier, context);
+       CFRelease(myDict);
+       return;
+}
+
+
+int
+__SCDynamicStoreAddWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex)
+{
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDNotifierAdd:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key          = %@"), key);
-       SCDLog(LOG_DEBUG, CFSTR("  regexOptions = %0o"), regexOptions);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreAddWatchedKey:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  key     = %@"), key);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  isRegex = %s"), isRegex ? "TRUE" : "FALSE");
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
        /*
         * add new key after checking if key has already been defined
         */
-       if (regexOptions & kSCDRegexKey) {
-               if (CFSetContainsValue(sessionPrivate->reKeys, key))
-                       return SCD_EXISTS;              /* sorry, key already exists in notifier list */
-               CFSetAddValue(sessionPrivate->reKeys, key);     /* add key to this sessions notifier list */
+       if (isRegex) {
+               if (CFSetContainsValue(storePrivate->reKeys, key))
+                       return kSCStatusKeyExists;              /* sorry, key already exists in notifier list */
+               CFSetAddValue(storePrivate->reKeys, key);       /* add key to this sessions notifier list */
        } else {
-               if (CFSetContainsValue(sessionPrivate->keys, key))
-                       return SCD_EXISTS;              /* sorry, key already exists in notifier list */
-               CFSetAddValue(sessionPrivate->keys, key);       /* add key to this sessions notifier list */
+               if (CFSetContainsValue(storePrivate->keys, key))
+                       return kSCStatusKeyExists;              /* sorry, key already exists in notifier list */
+               CFSetAddValue(storePrivate->keys, key); /* add key to this sessions notifier list */
        }
 
-       if (regexOptions & kSCDRegexKey) {
+       if (isRegex) {
                CFStringRef             sessionKey;
                int                     regexStrLen;
                char                    *regexStr;
@@ -67,7 +94,7 @@ _SCDNotifierAdd(SCDSessionRef session, CFStringRef key, int regexOptions)
 
                /*
                 * We are adding a regex key. As such, we need to flag
-                * any keys currently in the cache.
+                * any keys currently in the store.
                 */
 
                /* 1. Extract a C String version of the key pattern string. */
@@ -78,9 +105,9 @@ _SCDNotifierAdd(SCDSessionRef session, CFStringRef key, int regexOptions)
                                        regexStr,
                                        regexStrLen,
                                        kCFStringEncodingMacRoman)) {
-                       SCDLog(LOG_DEBUG, CFSTR("CFStringGetCString: could not convert regex key to C string"));
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString: could not convert regex key to C string"));
                        CFAllocatorDeallocate(NULL, regexStr);
-                       return SCD_FAILED;
+                       return kSCStatusFailed;
                }
 
                /* 2. Compile the regular expression from the pattern string. */
@@ -96,27 +123,27 @@ _SCDNotifierAdd(SCDSessionRef session, CFStringRef key, int regexOptions)
                                               (regex_t *)CFDataGetBytePtr(regexData),
                                               reErrBuf,
                                               sizeof(reErrBuf));
-                       SCDLog(LOG_DEBUG, CFSTR("regcomp() key: %s"), reErrBuf);
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regcomp() key: %s"), reErrBuf);
                        CFRelease(regexData);
-                       return SCD_FAILED;
+                       return kSCStatusFailed;
                }
 
                /*
                 * 3. Iterate over the current keys and add this session as a "watcher"
-                *    for any key already defined in the cache.
+                *    for any key already defined in the store.
                 */
 
-               context.session = sessionPrivate;
-               context.preg    = (regex_t *)CFDataGetBytePtr(regexData);
-               CFDictionaryApplyFunction(cacheData,
-                                         (CFDictionaryApplierFunction)_addRegexWatcherByKey,
-                                         &context);
+               context.store = storePrivate;
+               context.preg  = (regex_t *)CFDataGetBytePtr(regexData);
+               my_CFDictionaryApplyFunction(storeData,
+                                            (CFDictionaryApplierFunction)_addRegexWatcherByKey,
+                                            &context);
 
                /*
                 * 4. We also need to save this key and the associated regex data
                 *    for any subsequent additions.
                 */
-               sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), sessionPrivate->server);
+               sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
 
                info = CFDictionaryGetValue(sessionData, sessionKey);
                if (info) {
@@ -159,14 +186,14 @@ _SCDNotifierAdd(SCDSessionRef session, CFStringRef key, int regexOptions)
 
                /*
                 * We are watching a specific key. As such, update the
-                * cache to mark our interest in any changes.
+                * store to mark our interest in any changes.
                 */
-               sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionPrivate->server);
+               sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
                _addWatcher(sessionNum, key);
                CFRelease(sessionNum);
        }
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
@@ -174,8 +201,8 @@ kern_return_t
 _notifyadd(mach_port_t                         server,
           xmlData_t                    keyRef,         /* raw XML bytes */
           mach_msg_type_number_t       keyLen,
-          int                          regexOptions,
-          int                          *scd_status
+          int                          isRegex,
+          int                          *sc_status
 )
 {
        kern_return_t           status;
@@ -184,14 +211,14 @@ _notifyadd(mach_port_t                    server,
        CFStringRef             key;            /* key  (un-serialized) */
        CFStringRef             xmlError;
 
-       SCDLog(LOG_DEBUG, CFSTR("Add notification key for this session."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Add notification key for this session."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
 
        /* 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));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        key = CFPropertyListCreateFromXMLData(NULL,
@@ -199,13 +226,21 @@ _notifyadd(mach_port_t                    server,
                                              kCFPropertyListImmutable,
                                              &xmlError);
        CFRelease(xmlKey);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
-               *scd_status = SCD_FAILED;
+       if (!key) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+               return KERN_SUCCESS;
+       } else if (!isA_CFString(key)) {
+               *sc_status = kSCStatusInvalidArgument;
                return KERN_SUCCESS;
        }
 
-       *scd_status = _SCDNotifierAdd(mySession->session, key, regexOptions);
+       *sc_status = __SCDynamicStoreAddWatchedKey(mySession->store, key, isRegex);
        CFRelease(key);
 
        return KERN_SUCCESS;
index 5a77701d59dc97af3047fa14230513e5ab84bbb6..bcf06d70b67383e62b824a4d351184c938922096 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 31, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <unistd.h>
 
 #include "configd.h"
 #include "session.h"
 
 
-SCDStatus
-_SCDNotifierCancel(SCDSessionRef session)
+int
+__SCDynamicStoreNotifyCancel(SCDynamicStoreRef store)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDNotifierCancel:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreNotifyCancel:"));
 
-       if (session == NULL) {
-               return SCD_NOSESSION;   /* you must have an open session to play */
+       if (!store) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
        /*
         * cleanup any mach port based notifications.
         */
-       if (sessionPrivate->notifyPort != MACH_PORT_NULL) {
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->notifyPort);
-               sessionPrivate->notifyPort = MACH_PORT_NULL;
+       if (storePrivate->notifyPort != MACH_PORT_NULL) {
+               (void) mach_port_destroy(mach_task_self(), storePrivate->notifyPort);
+               storePrivate->notifyPort = MACH_PORT_NULL;
        }
 
        /*
         * cleanup any file based notifications.
         */
-       if (sessionPrivate->notifyFile >= 0) {
-               SCDLog(LOG_DEBUG, CFSTR("  closing (notification) fd %d"), sessionPrivate->notifyFile);
-               (void) close(sessionPrivate->notifyFile);
-               sessionPrivate->notifyFile = -1;
+       if (storePrivate->notifyFile >= 0) {
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  closing (notification) fd %d"), storePrivate->notifyFile);
+               (void) close(storePrivate->notifyFile);
+               storePrivate->notifyFile = -1;
        }
 
        /*
         * cleanup any signal notifications.
         */
-       if (sessionPrivate->notifySignal > 0) {
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->notifySignalTask);
-               sessionPrivate->notifySignal     = 0;
-               sessionPrivate->notifySignalTask = TASK_NULL;
+       if (storePrivate->notifySignal > 0) {
+               (void) mach_port_destroy(mach_task_self(), storePrivate->notifySignalTask);
+               storePrivate->notifySignal     = 0;
+               storePrivate->notifySignalTask = TASK_NULL;
        }
 
        /* remove this session from the to-be-notified list */
        if (needsNotification) {
                CFNumberRef     num;
 
-               num = CFNumberCreate(NULL, kCFNumberIntType, &sessionPrivate->server);
+               num = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
                CFSetRemoveValue(needsNotification, num);
                CFRelease(num);
 
@@ -78,24 +88,24 @@ _SCDNotifierCancel(SCDSessionRef session)
        }
 
        /* set notifier inactive */
-       sessionPrivate->notifyStatus = NotifierNotRegistered;
+       storePrivate->notifyStatus = NotifierNotRegistered;
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
 kern_return_t
 _notifycancel(mach_port_t      server,
-             int               *scd_status)
+             int               *sc_status)
 {
        serverSessionRef        mySession = getSession(server);
 
-       SCDLog(LOG_DEBUG, CFSTR("Cancel requested notifications."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Cancel requested notifications."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
 
-       *scd_status = _SCDNotifierCancel(mySession->session);
-       if (*scd_status != SCD_OK) {
-               SCDLog(LOG_DEBUG, CFSTR("  SCDNotifierCancel(): %s"), SCDError(*scd_status));
+       *sc_status = __SCDynamicStoreNotifyCancel(mySession->store);
+       if (*sc_status != kSCStatusOK) {
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  __SCDynamicStoreNotifyCancel(): %s"), SCErrorString(*sc_status));
        }
 
        return KERN_SUCCESS;
index 19ad363e739d5aadfac5c82daf69fb5745561dbf..0cb0ed8232a3d132338e3f9065f64059e49ed1a7 100644 (file)
  * @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
-_SCDNotifierGetChanges(SCDSessionRef session, CFArrayRef *notifierKeys)
+int
+__SCDynamicStoreCopyNotifiedKeys(SCDynamicStoreRef store, CFArrayRef *notifierKeys)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       CFStringRef             sessionKey;
-       CFDictionaryRef         info;
-       CFMutableDictionaryRef  newInfo;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       CFStringRef                     sessionKey;
+       CFDictionaryRef                 info;
+       CFMutableDictionaryRef          newInfo;
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDNotifierGetChanges:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyNotifiedKeys:"));
 
-       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 */
        }
 
-       sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), sessionPrivate->server);
+       sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
        info = CFDictionaryGetValue(sessionData, sessionKey);
        if ((info == NULL) ||
            (CFDictionaryContainsKey(info, kSCDChangedKeys) == FALSE)) {
                CFRelease(sessionKey);
                *notifierKeys = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);;
-               return SCD_OK;
+               return kSCStatusOK;
        }
        newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
 
@@ -59,7 +69,7 @@ _SCDNotifierGetChanges(SCDSessionRef session, CFArrayRef *notifierKeys)
        CFRelease(newInfo);
        CFRelease(sessionKey);
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
@@ -67,7 +77,7 @@ kern_return_t
 _notifychanges(mach_port_t                     server,
               xmlDataOut_t                     *listRef,       /* raw XML bytes */
               mach_msg_type_number_t           *listLen,
-              int                              *scd_status
+              int                              *sc_status
 )
 {
        kern_return_t           status;
@@ -75,11 +85,11 @@ _notifychanges(mach_port_t                  server,
        CFArrayRef              notifierKeys;   /* array of CFStringRef's */
        CFDataRef               xmlList;        /* list (XML serialized) */
 
-       SCDLog(LOG_DEBUG, CFSTR("List notification keys which have changed."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("List notification keys which have changed."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
 
-       *scd_status = _SCDNotifierGetChanges(mySession->session, &notifierKeys);
-       if (*scd_status != SCD_OK) {
+       *sc_status = __SCDynamicStoreCopyNotifiedKeys(mySession->store, &notifierKeys);
+       if (*sc_status != kSCStatusOK) {
                *listRef = NULL;
                *listLen = 0;
                return KERN_SUCCESS;
@@ -94,11 +104,11 @@ _notifychanges(mach_port_t                 server,
        *listLen = CFDataGetLength(xmlList);
        status = vm_allocate(mach_task_self(), (void *)listRef, *listLen, TRUE);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_allocate(): %s"), mach_error_string(status));
                CFRelease(xmlList);
                *listRef = NULL;
                *listLen = 0;
-               *scd_status = SCD_FAILED;
+               *sc_status = kSCStatusFailed;
                return KERN_SUCCESS;
        }
 
index e16f2a24744787529502cd8daffc7892b6d5c2d0..fb746074df8928d5af3f5993850cd91f5a281707 100644 (file)
  * @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
-_SCDNotifierRemove(SCDSessionRef session, CFStringRef key, int regexOptions)
+
+static __inline__ void
+my_CFDictionaryApplyFunction(CFDictionaryRef                   theDict,
+                            CFDictionaryApplierFunction        applier,
+                            void                               *context)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
+       CFAllocatorRef  myAllocator;
+       CFDictionaryRef myDict;
+
+       myAllocator = CFGetAllocator(theDict);
+       myDict      = CFDictionaryCreateCopy(myAllocator, theDict);
+       CFDictionaryApplyFunction(myDict, applier, context);
+       CFRelease(myDict);
+       return;
+}
+
+
+int
+__SCDynamicStoreRemoveWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex)
+{
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDNotifierRemove:"));
-       SCDLog(LOG_DEBUG, CFSTR("  key          = %@"), key);
-       SCDLog(LOG_DEBUG, CFSTR("  regexOptions = %0o"), regexOptions);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreRemoveWatchedKey:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  key     = %@"), key);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  isRegex = %s"), isRegex ? "TRUE" : "FALSE");
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;           /* you can't do anything with a closed session */
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
        /*
         * remove key from this sessions notifier list after checking that
         * it was previously defined.
         */
-       if (regexOptions & kSCDRegexKey) {
-               if (!CFSetContainsValue(sessionPrivate->reKeys, key))
-                       return SCD_NOKEY;               /* sorry, key does not exist in notifier list */
-               CFSetRemoveValue(sessionPrivate->reKeys, key);  /* remove key from this sessions notifier list */
+       if (isRegex) {
+               if (!CFSetContainsValue(storePrivate->reKeys, key))
+                       return kSCStatusNoKey;          /* sorry, key does not exist in notifier list */
+               CFSetRemoveValue(storePrivate->reKeys, key);    /* remove key from this sessions notifier list */
        } else {
-               if (!CFSetContainsValue(sessionPrivate->keys, key))
-                       return SCD_NOKEY;               /* sorry, key does not exist in notifier list */
-               CFSetRemoveValue(sessionPrivate->keys, key);    /* remove key from this sessions notifier list */
+               if (!CFSetContainsValue(storePrivate->keys, key))
+                       return kSCStatusNoKey;          /* sorry, key does not exist in notifier list */
+               CFSetRemoveValue(storePrivate->keys, key);      /* remove key from this sessions notifier list */
        }
 
-       if (regexOptions & kSCDRegexKey) {
+       if (isRegex) {
                CFStringRef             sessionKey;
                CFDictionaryRef         info;
                CFMutableDictionaryRef  newInfo;
@@ -62,7 +89,7 @@ _SCDNotifierRemove(SCDSessionRef session, CFStringRef key, int regexOptions)
                CFDataRef               regexData;
                removeContext           context;
 
-               sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), sessionPrivate->server);
+               sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
 
                info    = CFDictionaryGetValue(sessionData, sessionKey);
                newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
@@ -78,11 +105,11 @@ _SCDNotifierRemove(SCDSessionRef session, CFStringRef key, int regexOptions)
                                                key);
                regexData = CFArrayGetValueAtIndex(newRData, i);
 
-               context.session = sessionPrivate;
-               context.preg    = (regex_t *)CFDataGetBytePtr(regexData);
-               CFDictionaryApplyFunction(cacheData,
-                                         (CFDictionaryApplierFunction)_removeRegexWatcherByKey,
-                                         &context);
+               context.store = storePrivate;
+               context.preg  = (regex_t *)CFDataGetBytePtr(regexData);
+               my_CFDictionaryApplyFunction(storeData,
+                                            (CFDictionaryApplierFunction)_removeRegexWatcherByKey,
+                                            &context);
 
                /* remove the regex key */
                CFArrayRemoveValueAtIndex(newRKeys, i);
@@ -113,15 +140,15 @@ _SCDNotifierRemove(SCDSessionRef session, CFStringRef key, int regexOptions)
 
                /*
                 * We are watching a specific key. As such, update the
-                * cache to mark our interest in any changes.
+                * store to mark our interest in any changes.
                 */
 
-               sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionPrivate->server);
+               sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
                _removeWatcher(sessionNum, key);
                CFRelease(sessionNum);
        }
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
@@ -129,8 +156,8 @@ kern_return_t
 _notifyremove(mach_port_t              server,
              xmlData_t                 keyRef,         /* raw XML bytes */
              mach_msg_type_number_t    keyLen,
-             int                       regexOptions,
-             int                       *scd_status
+             int                       isRegex,
+             int                       *sc_status
 )
 {
        kern_return_t           status;
@@ -139,14 +166,14 @@ _notifyremove(mach_port_t         server,
        CFStringRef             key;            /* key  (un-serialized) */
        CFStringRef             xmlError;
 
-       SCDLog(LOG_DEBUG, CFSTR("Remove notification key for this session."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Remove notification key for this session."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
 
        /* 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));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
        key = CFPropertyListCreateFromXMLData(NULL,
@@ -154,13 +181,21 @@ _notifyremove(mach_port_t         server,
                                              kCFPropertyListImmutable,
                                              &xmlError);
        CFRelease(xmlKey);
-       if (xmlError) {
-               SCDLog(LOG_DEBUG, CFSTR("CFPropertyListCreateFromXMLData() key: %s"), xmlError);
-               *scd_status = SCD_FAILED;
+       if (!key) {
+               if (xmlError) {
+                       SCLog(_configd_verbose, LOG_DEBUG,
+                              CFSTR("CFPropertyListCreateFromXMLData() key: %@"),
+                              xmlError);
+                       CFRelease(xmlError);
+               }
+               *sc_status = kSCStatusFailed;
+               return KERN_SUCCESS;
+       } else if (!isA_CFString(key)) {
+               *sc_status = kSCStatusInvalidArgument;
                return KERN_SUCCESS;
        }
 
-       *scd_status = _SCDNotifierRemove(mySession->session, key, regexOptions);
+       *sc_status = __SCDynamicStoreRemoveWatchedKey(mySession->store, key, isRegex);
        CFRelease(key);
 
        return KERN_SUCCESS;
index 7eedbfc6c08aa9afe33b6d7b61bb6b4deaca3859..dd7f3ab6985962fa9f716f8f36955636034bbe37 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * April 5, 2000               Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <unistd.h>
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include "session.h"
 
 
-SCDStatus
-_SCDNotifierInformViaFD(SCDSessionRef  session,
-                      int32_t          identifier,
-                      int              *fd)
+int
+__SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store,
+                                    int32_t            identifier,
+                                    int                *fd)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       int                     sock;
-       CFStringRef             sessionKey;
-       CFDictionaryRef         info;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       int                             sock;
+       CFStringRef                     sessionKey;
+       CFDictionaryRef                 info;
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDNotifierInformViaFD:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreNotifyFileDescriptor:"));
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;   /* you must have an open session to play */
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
-       if (sessionPrivate->notifyStatus != NotifierNotRegistered) {
+       if (storePrivate->notifyStatus != NotifierNotRegistered) {
                /* sorry, you can only have one notification registered at once */
-               return SCD_NOTIFIERACTIVE;
+               return kSCStatusNotifierActive;
        }
 
        if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
-               SCDLog(LOG_NOTICE, CFSTR("socket: %s"), strerror(errno));
-               return SCD_FAILED;
+               SCLog(_configd_verbose, LOG_NOTICE, CFSTR("socket: %s"), strerror(errno));
+               return kSCStatusFailed;
        }
 
        *fd = sock;
 
        /* push out a notification if any changes are pending */
-       sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), sessionPrivate->server);
+       sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
        info = CFDictionaryGetValue(sessionData, sessionKey);
        CFRelease(sessionKey);
        if (info && CFDictionaryContainsKey(info, kSCDChangedKeys)) {
@@ -70,12 +80,12 @@ _SCDNotifierInformViaFD(SCDSessionRef       session,
                                                               0,
                                                               &kCFTypeSetCallBacks);
 
-               sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionPrivate->server);
+               sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
                CFSetAddValue(needsNotification, sessionNum);
                CFRelease(sessionNum);
        }
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
@@ -84,33 +94,33 @@ _notifyviafd(mach_port_t            server,
             xmlData_t                  pathRef,
             mach_msg_type_number_t     pathLen,
             int                        identifier,
-            int                        *scd_status
+            int                        *sc_status
 )
 {
        kern_return_t           status;
        serverSessionRef        mySession = getSession(server);
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)mySession->session;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)mySession->store;
        struct sockaddr_un      un;
        int                     sock;
-       int                     bufSiz  = sizeof(sessionPrivate->notifyFileIdentifier);
+       int                     bufSiz  = sizeof(storePrivate->notifyFileIdentifier);
        int                     nbioYes = 1;
 
-       SCDLog(LOG_DEBUG, CFSTR("Send message via UNIX domain socket when a notification key changes."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
-       SCDLog(LOG_DEBUG, CFSTR("  path   = %s"), pathRef);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Send message via UNIX domain socket when a notification key changes."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  path   = %s"), pathRef);
 
        /*
         * if socket currently open, close it!
         */
        /* validate the UNIX domain socket path */
        if (pathLen > (sizeof(un.sun_path) - 1)) {
-               SCDLog(LOG_NOTICE, CFSTR("domain socket path length too long!"));
+               SCLog(_configd_verbose, LOG_NOTICE, CFSTR("domain socket path length too long!"));
                status = vm_deallocate(mach_task_self(), (vm_address_t)pathRef, pathLen);
                if (status != KERN_SUCCESS) {
-                       SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                        /* non-fatal???, proceed */
                }
-               *scd_status = SCD_FAILED;
+               *sc_status = kSCStatusFailed;
                return KERN_SUCCESS;
        }
 
@@ -120,49 +130,49 @@ _notifyviafd(mach_port_t          server,
        un.sun_path[pathLen] = '\0';
        status = vm_deallocate(mach_task_self(), (vm_address_t)pathRef, pathLen);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
                /* non-fatal???, proceed */
        }
 
        /* do common sanity checks, get socket */
-       *scd_status = _SCDNotifierInformViaFD(mySession->session, identifier, &sock);
+       *sc_status = __SCDynamicStoreNotifyFileDescriptor(mySession->store, identifier, &sock);
 
-       /* check status of _SCDNotifierInformViaFD() */
-       if (*scd_status != SCD_OK) {
+       /* check status of __SCDynamicStoreNotifyFileDescriptor() */
+       if (*sc_status != kSCStatusOK) {
                return KERN_SUCCESS;
        }
 
        /* establish the connection, get ready for a read() */
        if (connect(sock, (struct sockaddr *)&un, sizeof(un)) == -1) {
-               SCDLog(LOG_DEBUG, CFSTR("connect: %s"), strerror(errno));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("connect: %s"), strerror(errno));
                (void) close(sock);
-               sessionPrivate->notifyStatus = NotifierNotRegistered;
-               sessionPrivate->notifyFile   = -1;
-               *scd_status = SCD_FAILED;
+               storePrivate->notifyStatus = NotifierNotRegistered;
+               storePrivate->notifyFile   = -1;
+               *sc_status = kSCStatusFailed;
                return KERN_SUCCESS;
        }
 
-       SCDLog(LOG_NOTICE, CFSTR("  fd     = %d"), sock);
+       SCLog(_configd_verbose, LOG_NOTICE, CFSTR("  fd     = %d"), sock);
        (void) unlink(un.sun_path);
 
        if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufSiz, sizeof(bufSiz)) < 0) {
-               SCDLog(LOG_DEBUG, CFSTR("setsockopt: %s"), strerror(errno));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("setsockopt: %s"), strerror(errno));
                (void) close(sock);
-               *scd_status = SCD_FAILED;
+               *sc_status = kSCStatusFailed;
                return KERN_SUCCESS;
        }
 
        if (ioctl(sock, FIONBIO, &nbioYes) == -1) {
-               SCDLog(LOG_DEBUG, CFSTR("ioctl(,FIONBIO,): %s"), strerror(errno));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("ioctl(,FIONBIO,): %s"), strerror(errno));
                (void) close(sock);
-               *scd_status = SCD_FAILED;
+               *sc_status = kSCStatusFailed;
                return KERN_SUCCESS;
        }
 
        /* set notifier active */
-       sessionPrivate->notifyStatus         = Using_NotifierInformViaFD;
-       sessionPrivate->notifyFile           = sock;
-       sessionPrivate->notifyFileIdentifier = identifier;
+       storePrivate->notifyStatus         = Using_NotifierInformViaFD;
+       storePrivate->notifyFile           = sock;
+       storePrivate->notifyFileIdentifier = identifier;
 
        return KERN_SUCCESS;
 }
index ac270ec6edbc9da5801a829f96f6a9ee5ed01426..0c20ffe398d0eacd9fb2ac25210667294e382ea1 100644 (file)
  * @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
-_SCDNotifierInformViaMachPort(SCDSessionRef session, mach_msg_id_t identifier, mach_port_t *port)
+int
+__SCDynamicStoreNotifyMachPort(SCDynamicStoreRef       store,
+                              mach_msg_id_t            identifier,
+                              mach_port_t              *port)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       CFStringRef             sessionKey;
-       CFDictionaryRef         info;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       CFStringRef                     sessionKey;
+       CFDictionaryRef                 info;
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDNotifierInformViaMachPort:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreNotifyMachPort:"));
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;   /* you must have an open session to play */
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession;         /* you must have an open session to play */
        }
 
-       if (sessionPrivate->notifyStatus != NotifierNotRegistered) {
+       if (storePrivate->notifyStatus != NotifierNotRegistered) {
                /* sorry, you can only have one notification registered at once */
-               return SCD_NOTIFIERACTIVE;
+               return kSCStatusNotifierActive;
        }
 
        if (*port == MACH_PORT_NULL) {
                /* sorry, you must specify a valid mach port */
-               return SCD_INVALIDARGUMENT;
+               return kSCStatusInvalidArgument;
        }
 
        /* push out a notification if any changes are pending */
-       sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), sessionPrivate->server);
+       sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
        info = CFDictionaryGetValue(sessionData, sessionKey);
        CFRelease(sessionKey);
        if (info && CFDictionaryContainsKey(info, kSCDChangedKeys)) {
@@ -58,12 +70,12 @@ _SCDNotifierInformViaMachPort(SCDSessionRef session, mach_msg_id_t identifier, m
                                                               0,
                                                               &kCFTypeSetCallBacks);
 
-               sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionPrivate->server);
+               sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
                CFSetAddValue(needsNotification, sessionNum);
                CFRelease(sessionNum);
        }
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
@@ -71,29 +83,29 @@ kern_return_t
 _notifyviaport(mach_port_t     server,
               mach_port_t      port,
               mach_msg_id_t    identifier,
-              int              *scd_status
+              int              *sc_status
 )
 {
-       serverSessionRef        mySession = getSession(server);
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)mySession->session;
+       serverSessionRef                mySession = getSession(server);
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)mySession->store;
 
-       SCDLog(LOG_DEBUG, CFSTR("Send mach message when a notification key changes."));
-       SCDLog(LOG_DEBUG, CFSTR("  server     = %d"), server);
-       SCDLog(LOG_DEBUG, CFSTR("  port       = %d"), port);
-       SCDLog(LOG_DEBUG, CFSTR("  message id = %d"), identifier);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Send mach message when a notification key changes."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server     = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  port       = %d"), port);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  message id = %d"), identifier);
 
-       if (sessionPrivate->notifyPort != MACH_PORT_NULL) {
-               SCDLog(LOG_DEBUG, CFSTR("  destroying old callback mach port %d"), sessionPrivate->notifyPort);
-               (void) mach_port_destroy(mach_task_self(), sessionPrivate->notifyPort);
+       if (storePrivate->notifyPort != MACH_PORT_NULL) {
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  destroying old callback mach port %d"), storePrivate->notifyPort);
+               (void) mach_port_destroy(mach_task_self(), storePrivate->notifyPort);
        }
 
-       *scd_status = _SCDNotifierInformViaMachPort(mySession->session, identifier, &port);
+       *sc_status = __SCDynamicStoreNotifyMachPort(mySession->store, identifier, &port);
 
-       if (*scd_status == SCD_OK) {
+       if (*sc_status == kSCStatusOK) {
                /* save notification port, requested identifier, and set notifier active */
-               sessionPrivate->notifyStatus         = Using_NotifierInformViaMachPort;
-               sessionPrivate->notifyPort           = port;
-               sessionPrivate->notifyPortIdentifier = identifier;
+               storePrivate->notifyStatus         = Using_NotifierInformViaMachPort;
+               storePrivate->notifyPort           = port;
+               storePrivate->notifyPortIdentifier = identifier;
        }
 
        return KERN_SUCCESS;
index fc10d1b5bf4a68057fff16abd8e0da689ed70b3c..bbe43ee44fd93ed21aada7fd440e02cd3efb9961 100644 (file)
  * @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 "configd_server.h"
 #include "session.h"
 
-SCDStatus
-_SCDNotifierInformViaSignal(SCDSessionRef session, pid_t pid, int sig)
+int
+__SCDynamicStoreNotifySignal(SCDynamicStoreRef store, pid_t pid, int sig)
 {
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)session;
-       CFStringRef             sessionKey;
-       CFDictionaryRef         info;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       CFStringRef                     sessionKey;
+       CFDictionaryRef                 info;
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDNotifierInformViaSignal:"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreNotifySignal:"));
 
-       if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
-               return SCD_NOSESSION;   /* you must have an open session to play */
+       if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+               return kSCStatusNoStoreSession; /* you must have an open session to play */
        }
 
-       if (sessionPrivate->notifyStatus != NotifierNotRegistered) {
+       if (storePrivate->notifyStatus != NotifierNotRegistered) {
                /* sorry, you can only have one notification registered at once */
-               return SCD_NOTIFIERACTIVE;
+               return kSCStatusNotifierActive;
+       }
+
+       if (pid == getpid()) {
+               /* sorry, you can't request that configd be signalled */
+               return kSCStatusFailed;
        }
 
        if ((sig <= 0) || (sig > NSIG)) {
                /* sorry, you must specify a valid signal */
-               return SCD_INVALIDARGUMENT;
+               return kSCStatusInvalidArgument;
        }
 
        /* push out a notification if any changes are pending */
-       sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), sessionPrivate->server);
+       sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
        info = CFDictionaryGetValue(sessionData, sessionKey);
        CFRelease(sessionKey);
        if (info && CFDictionaryContainsKey(info, kSCDChangedKeys)) {
@@ -59,12 +74,12 @@ _SCDNotifierInformViaSignal(SCDSessionRef session, pid_t pid, int sig)
                                                               0,
                                                               &kCFTypeSetCallBacks);
 
-               sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionPrivate->server);
+               sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
                CFSetAddValue(needsNotification, sessionNum);
                CFRelease(sessionNum);
        }
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
@@ -72,24 +87,30 @@ kern_return_t
 _notifyviasignal(mach_port_t   server,
                 task_t         task,
                 int            sig,
-                int            *scd_status)
+                int            *sc_status)
 {
-       serverSessionRef        mySession  = getSession(server);
-       SCDSessionPrivateRef    sessionPrivate = (SCDSessionPrivateRef)mySession->session;
-#if    defined(DEBUG) || defined(NOTYET)
-       kern_return_t           status;
-#endif
+       serverSessionRef                mySession  = getSession(server);
+       pid_t                           pid;
+       kern_return_t                   status;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)mySession->store;
 #ifdef NOTYET
-       mach_port_t             oldNotify;
+       mach_port_t                     oldNotify;
 #endif /* NOTYET */
 
-       SCDLog(LOG_DEBUG, CFSTR("Send signal when a notification key changes."));
-       SCDLog(LOG_DEBUG, CFSTR("  server = %d"), server);
-       SCDLog(LOG_DEBUG, CFSTR("  task   = %d"), task);
-       SCDLog(LOG_DEBUG, CFSTR("  signal = %d"), sig);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Send signal when a notification key changes."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  server = %d"), server);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  task   = %d"), task);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  signal = %d"), sig);
 
-       *scd_status = _SCDNotifierInformViaSignal(mySession->session, 0, sig);  /* pid is N/A for server */
-       if (*scd_status != SCD_OK) {
+       status = pid_for_task(task, &pid);
+       if (status != KERN_SUCCESS) {
+               /* could not determine pid for task */
+               *sc_status = kSCStatusFailed;
+               return KERN_SUCCESS;
+       }
+
+       *sc_status = __SCDynamicStoreNotifySignal(mySession->store, pid, sig);
+       if (*sc_status != kSCStatusOK) {
                if (task != TASK_NULL) {
                        (void) mach_port_destroy(mach_task_self(), task);
                }
@@ -115,7 +136,7 @@ _notifyviasignal(mach_port_t        server,
                                *rp++ = 'D';
                        *rp = '\0';
 
-                       SCDLog(LOG_DEBUG, CFSTR("Task %d, port rights = %s"), task, rights);
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Task %d, port rights = %s"), task, rights);
                }
        }
 #endif /* DEBUG */
@@ -130,29 +151,27 @@ _notifyviasignal(mach_port_t      server,
                                                MACH_MSG_TYPE_MAKE_SEND_ONCE,
                                                &oldNotify);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
-               *scd_status = SCD_FAILED;
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("mach_port_request_notification(): %s"), mach_error_string(status));
+               *sc_status = kSCStatusFailed;
                return KERN_SUCCESS;
        }
 
-#ifdef DEBUG
        if (oldNotify != MACH_PORT_NULL) {
-               SCDLog(LOG_DEBUG, CFSTR("_notifyviasignal(): why is oldNotify != MACH_PORT_NULL?"));
+               SCLog(_configd_verbose, LOG_ERR, CFSTR("_notifyviasignal(): why is oldNotify != MACH_PORT_NULL?"));
        }
-#endif /* DEBUG */
 
-       SCDLog(LOG_DEBUG, CFSTR("Adding task notification port %d to the server's port set"), task);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Adding task notification port %d to the server's port set"), task);
        status = mach_port_move_member(mach_task_self(), task, server_ports);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("mach_port_move_member(): %s"), mach_error_string(status));
-               *scd_status = SCD_FAILED;
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("mach_port_move_member(): %s"), mach_error_string(status));
+               *sc_status = kSCStatusFailed;
                return KERN_SUCCESS;
        }
 #endif /* NOTYET */
 
-       sessionPrivate->notifyStatus     = Using_NotifierInformViaSignal;
-       sessionPrivate->notifySignal     = sig;
-       sessionPrivate->notifySignalTask = task;
+       storePrivate->notifyStatus     = Using_NotifierInformViaSignal;
+       storePrivate->notifySignal     = sig;
+       storePrivate->notifySignalTask = task;
 
        return KERN_SUCCESS;
 }
index b21d96a0bc445e73464e28595a2514482fba2615..68e8509cffb32c24f56d1d4c8b1e7c6a250cd5e1 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * April 14, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <fcntl.h>
 #include <paths.h>
 #include <unistd.h>
 #include "session.h"
 
 
-#define        SNAPSHOT_PATH_CACHE     _PATH_VARTMP "configd-cache.xml"
+#define        SNAPSHOT_PATH_STORE     _PATH_VARTMP "configd-store.xml"
 #define        SNAPSHOT_PATH_SESSION   _PATH_VARTMP "configd-session.xml"
 
 
-SCDStatus
-_SCDSnapshot(SCDSessionRef session)
+int
+__SCDynamicStoreSnapshot(SCDynamicStoreRef store)
 {
-       int                     fd;
-       CFDataRef               xmlData;
+       int                             fd;
+       serverSessionRef                mySession;
+       SCDynamicStorePrivateRef        storePrivate = (SCDynamicStorePrivateRef)store;
+       CFDataRef                       xmlData;
+
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreSnapshot:"));
 
-       SCDLog(LOG_DEBUG, CFSTR("_SCDSnapshot:"));
+       /* check credentials */
+
+       mySession = getSession(storePrivate->server);
+       if (mySession->callerEUID != 0) {
+               return kSCStatusAccessError;
+       }
 
-       /* Save a snapshot of the "cache" data */
+       /* Save a snapshot of the "store" data */
 
-       (void) unlink(SNAPSHOT_PATH_CACHE);
-       fd = open(SNAPSHOT_PATH_CACHE, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+       (void) unlink(SNAPSHOT_PATH_STORE);
+       fd = open(SNAPSHOT_PATH_STORE, O_WRONLY|O_CREAT|O_TRUNC, 0644);
        if (fd < 0) {
-               return SCD_FAILED;
+               return kSCStatusFailed;
        }
 
-       xmlData = CFPropertyListCreateXMLData(NULL, cacheData);
+       xmlData = CFPropertyListCreateXMLData(NULL, storeData);
        (void) write(fd, CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData));
        (void) close(fd);
        CFRelease(xmlData);
@@ -59,7 +78,7 @@ _SCDSnapshot(SCDSessionRef session)
        (void) unlink(SNAPSHOT_PATH_SESSION);
        fd = open(SNAPSHOT_PATH_SESSION, O_WRONLY|O_CREAT|O_TRUNC, 0644);
        if (fd < 0) {
-               return SCD_FAILED;
+               return kSCStatusFailed;
        }
 
        /* Save a snapshot of the "session" data */
@@ -69,20 +88,20 @@ _SCDSnapshot(SCDSessionRef session)
        (void) close(fd);
        CFRelease(xmlData);
 
-       return SCD_OK;
+       return kSCStatusOK;
 }
 
 
 kern_return_t
-_snapshot(mach_port_t server, int *scd_status)
+_snapshot(mach_port_t server, int *sc_status)
 {
        serverSessionRef        mySession = getSession(server);
 
-       SCDLog(LOG_DEBUG, CFSTR("Snapshot configuration database."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Snapshot configuration database."));
 
-       *scd_status = _SCDSnapshot(mySession->session);
-       if (*scd_status != SCD_OK) {
-               SCDLog(LOG_DEBUG, CFSTR("  SCDUnlock(): %s"), SCDError(*scd_status));
+       *sc_status = __SCDynamicStoreSnapshot(mySession->store);
+       if (*sc_status != kSCStatusOK) {
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  __SCDynamicStoreSnapshot(): %s"), SCErrorString(*sc_status));
        }
 
        return KERN_SUCCESS;
index 05ffe705eba031c2719052157059f270adb1db86..f04426dac81e3398e5365d85a89875646879b8f9 100644 (file)
  * @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
+ */
+
 #ifndef _S_CONFIGD_H
 #define _S_CONFIGD_H
 
 #include <mach/mach.h>
 #include <mach/mach_error.h>
 
-#include <SystemConfiguration/SCD.h>
+/* configd doesn't need the preference keys */
+#define _SCSCHEMADEFINITIONS_H
+
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
+#include <SystemConfiguration/SCValidation.h>
 #include "config_types.h"
-#include "SCDPrivate.h"
 #include "_SCD.h"
 
+extern Boolean         _configd_fork;          /* TRUE if process should be run in the background */
+extern Boolean         _configd_verbose;       /* TRUE if verbose logging enabled */
+extern CFMutableSetRef _plugins_exclude;       /* bundle identifiers to exclude from loading */
+extern CFMutableSetRef _plugins_verbose;       /* bundle identifiers to enable verbose logging */
 
 __BEGIN_DECLS
 __END_DECLS
index dad2d5a02d309966686011b5fb66766fe2bd0439..55caa0bb798b62be87141b9c69d42b3bae5fa08d 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-/* 
- * Modification History 
- * 24 March 2000       Allan Nathanson (ajn@apple.com)
- *                     - created
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * 24 March 2000               Allan Nathanson (ajn@apple.com)
+ * - created
  */
 
 #include <stdio.h>
 #include "configd_server.h"
 #include "plugin_support.h"
 
+Boolean        _configd_fork           = TRUE;         /* TRUE if process should be run in the background */
+Boolean        _configd_verbose        = FALSE;        /* TRUE if verbose logging enabled */
+CFMutableSetRef        _plugins_exclude        = NULL;         /* bundle identifiers to exclude from loading */
+CFMutableSetRef        _plugins_verbose        = NULL;         /* bundle identifiers to enable verbose logging */
 
-const char *signames[] = {
+static const char *signames[] = {
        ""    , "HUP" , "INT"   , "QUIT", "ILL"  , "TRAP", "ABRT", "EMT" ,
        "FPE" , "KILL", "BUS"   , "SEGV", "SYS"  , "PIPE", "ALRM", "TERM",
        "URG" , "STOP", "TSTP"  , "CONT", "CHLD" , "TTIN", "TTOU", "IO"  ,
@@ -49,30 +57,32 @@ const char *signames[] = {
 };
 
 
-void
+static void
 usage(const char *prog)
 {
-       SCDLog(LOG_INFO, CFSTR("%s: [-d] [-v] [-b] [-t plugin-bundle-path]"), prog);
-       SCDLog(LOG_INFO, CFSTR("options:"));
-       SCDLog(LOG_INFO, CFSTR("\t-d\tenable debugging"));
-       SCDLog(LOG_INFO, CFSTR("\t-v\tenable verbose logging"));
-       SCDLog(LOG_INFO, CFSTR("\t-b\tdisable loading of ALL plug-ins"));
-       SCDLog(LOG_INFO, CFSTR("\t-t\tload/test the specified plug-in"));
-       SCDLog(LOG_INFO, CFSTR("\t\t  (Note: only the plug-in will be started)"), prog);
+       SCPrint(TRUE, stderr, CFSTR("%s: [-d] [-v] [-V bundleID] [-b] [-B bundleID] [-t plugin-path]\n"), prog);
+       SCPrint(TRUE, stderr, CFSTR("options:\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t-d\tdisable daemon/run in foreground\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t-v\tenable verbose logging\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t-V\tenable verbose logging for the specified plug-in\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t-b\tdisable loading of ALL plug-ins\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t-B\tdisable loading of the specified plug-in\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t-t\tload/test the specified plug-in\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t\t  (Note: only the plug-in will be started)\n"), prog);
        exit (EX_USAGE);
 }
 
 
-void
+static void
 catcher(int signum)
 {
        /*
         * log the signal
         *
-        * Note: we can't use SCDLog() since the signal may be received while the
+        * Note: we can't use SCLog() since the signal may be received while the
         *       logging thread lock is held.
         */
-       if (SCDOptionGet(NULL, kSCDOptionUseSyslog)) {
+       if (_configd_verbose) {
                syslog (LOG_INFO, "caught SIG%s"  , signames[signum]);
        } else {
                fprintf(stderr,   "caught SIG%s\n", signames[signum]);
@@ -127,44 +137,62 @@ fork_child()
        if (setsid() == -1)
                return -1;
 
-       (void)chdir("/");
+       (void) chdir("/");
 
        if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
-               (void)dup2(fd, STDIN_FILENO);
-               (void)dup2(fd, STDOUT_FILENO);
-               (void)dup2(fd, STDERR_FILENO);
+               (void) dup2(fd, STDIN_FILENO);
+               (void) dup2(fd, STDOUT_FILENO);
+               (void) dup2(fd, STDERR_FILENO);
                if (fd > 2)
-                       (void)close(fd);
+                       (void) close(fd);
        }
 
        return 0;
 }
 
 int
-main (int argc, const char *argv[])
+main(int argc, const char *argv[])
 {
-       extern int              optind;
+       Boolean                 loadBundles = TRUE;
+       struct sigaction        nact;
        int                     opt;
+       extern int              optind;
        const char              *prog = argv[0];
-       boolean_t               loadBundles = TRUE;
+       CFStringRef             str;
        const char              *testBundle = NULL;
-       struct sigaction        nact;
+
+       _plugins_exclude = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+       _plugins_verbose = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
 
        /* process any arguments */
 
-       while ((opt = getopt(argc, argv, "bdt:v")) != -1) {
+       while ((opt = getopt(argc, argv, "bB:dt:vV:")) != -1) {
                switch(opt) {
                        case 'b':
                                loadBundles = FALSE;
                                break;
+                       case 'B':
+                               str = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingMacRoman);
+                               CFSetSetValue(_plugins_exclude, str);
+                               CFRelease(str);
+                               break;
                        case 'd':
-                               SCDOptionSet(NULL, kSCDOptionDebug, TRUE);
+                               _configd_fork = FALSE;
                                break;
                        case 't':
                                testBundle = optarg;
                                break;
                        case 'v':
-                               SCDOptionSet(NULL, kSCDOptionVerbose, TRUE);
+                               _configd_verbose = TRUE;
+                               break;
+                       case 'V':
+                               if (strcmp(optarg, "com.apple.SystemConfiguration") == 0) {
+                                       _sc_verbose = TRUE;
+                               } else {
+                               str = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingMacRoman);
+                               CFSetSetValue(_plugins_verbose, str);
+                               CFRelease(str);
+                               }
                                break;
                        case '?':
                        default :
@@ -182,43 +210,47 @@ main (int argc, const char *argv[])
                exit (EX_UNAVAILABLE);
        }
 
-       /* get ready */
-
-       SCDOptionSet(NULL, kSCDOptionIsServer, TRUE);           /* Use the config API's "server" code */
-       SCDOptionSet(NULL, kSCDOptionUseCFRunLoop, TRUE);       /* Use the CFRunLoop */
-
        /* check credentials */
        if (getuid() != 0) {
-#ifdef DEBUG
-               if (!SCDOptionGet(NULL, kSCDOptionDebug)) {
-#endif /* DEBUG */
-                       fprintf(stderr, "%s: permission denied.\n", prog);
-                       exit (EX_NOPERM);
-#ifdef DEBUG
-               }
-#endif /* DEBUG */
+               fprintf(stderr, "%s: permission denied.\n", prog);
+               exit (EX_NOPERM);
        }
 
-       if ((testBundle == NULL) && !SCDOptionGet(NULL, kSCDOptionDebug)) {
+       if (_configd_fork) {
                if (fork_child() == -1) {
                        fprintf(stderr, "configd: fork() failed, %s\n", strerror(errno));
                        exit (1);
                }
                /* now the child process, parent waits in fork_child */
+       }
+
+       /* open syslog() facility */
+       if (_configd_fork) {
+               int     logopt  = LOG_NDELAY|LOG_PID;
 
-               /* log via syslog() facility */
-               openlog("configd", (LOG_NDELAY | LOG_PID), LOG_DAEMON);
-               SCDOptionSet(NULL, kSCDOptionUseSyslog, TRUE);
+               if (_configd_verbose)
+                       logopt |= LOG_CONS;
+               openlog("configd", logopt, LOG_DAEMON);
+       } else {
+               _sc_log = FALSE;        /* redirect SCLog() to stdout/stderr */
        }
 
-       /* add signal handler to catch a SIGPIPE */
+       /* add signal handler to catch a SIGHUP */
 
        nact.sa_handler = catcher;
        sigemptyset(&nact.sa_mask);
        nact.sa_flags = SA_RESTART;
 
+       if (sigaction(SIGHUP, &nact, NULL) == -1) {
+               SCLog(_configd_verbose, LOG_ERR,
+                      CFSTR("sigaction(SIGHUP, ...) failed: %s"),
+                      strerror(errno));
+       }
+
+       /* add signal handler to catch a SIGPIPE */
+
        if (sigaction(SIGPIPE, &nact, NULL) == -1) {
-               SCDLog(LOG_ERR,
+               SCLog(_configd_verbose, LOG_ERR,
                       CFSTR("sigaction(SIGPIPE, ...) failed: %s"),
                       strerror(errno));
        }
@@ -228,14 +260,14 @@ main (int argc, const char *argv[])
        objc_setMultithreaded(YES);
 
        if (testBundle == NULL) {
-               /* initialize primary (cache management) thread */
+               /* initialize primary (store management) thread */
                server_init();
 
                /* load/initialize/start bundles into the secondary thread */
                if (loadBundles) {
                        plugin_init();
                } else {
-                       if (!SCDOptionGet(NULL, kSCDOptionDebug)) {
+                       if (_configd_fork) {
                            /* synchronize with parent process */
                            kill(getppid(), SIGTERM);
                        }
@@ -245,7 +277,7 @@ main (int argc, const char *argv[])
        /* go */
 
        if (testBundle == NULL) {
-               /* start primary (cache management) thread */
+               /* start primary (store management) thread */
                server_loop();
        } else {
                /* load/initialize/start specified plug-in */
index 69a1911c33ccdaf97cd7369da664c415e2c050b8..d589c6931deab38b20d1382a29f967fafc1faa14 100644 (file)
  * @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 <servers/bootstrap.h>
 #include <sysexits.h>
 
@@ -34,14 +44,13 @@ extern struct rpc_subsystem _config_subsystem;
 extern boolean_t               config_server(mach_msg_header_t *, mach_msg_header_t *);
 
 /* server state information */
-CFMachPortRef          configd_port;           /* configd server port (for new session requests) */
+CFMachPortRef                  configd_port;           /* configd server port (for new session requests) */
 
 
 boolean_t
 config_demux(mach_msg_header_t *request, mach_msg_header_t *reply)
 {
-       boolean_t                       processed = FALSE;
-
+       Boolean                         processed = FALSE;
        mach_msg_format_0_trailer_t     *trailer;
 
        /* Feed the request into the ("MiG" generated) server */
@@ -61,14 +70,14 @@ config_demux(mach_msg_header_t *request, mach_msg_header_t *reply)
                            (trailer->msgh_trailer_size >= MACH_MSG_TRAILER_FORMAT_0_SIZE)) {
                                thisSession->callerEUID = trailer->msgh_sender.val[0];
                                thisSession->callerEGID = trailer->msgh_sender.val[1];
-                               SCDLog(LOG_DEBUG, CFSTR("caller has eUID = %d, eGID = %d"),
+                               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("caller has eUID = %d, eGID = %d"),
                                       thisSession->callerEUID,
                                       thisSession->callerEGID);
                        } else {
-                               static boolean_t warned = FALSE;
+                               static Boolean warned   = FALSE;
 
                                if (!warned) {
-                                       SCDLog(LOG_WARNING, CFSTR("caller's credentials not available."));
+                                       SCLog(_configd_verbose, LOG_WARNING, CFSTR("caller's credentials not available."));
                                        warned = TRUE;
                                }
                                thisSession->callerEUID = 0;
@@ -88,8 +97,15 @@ config_demux(mach_msg_header_t *request, mach_msg_header_t *reply)
        }
 
        if (!processed) {
-               SCDLog(LOG_WARNING, CFSTR("unknown message received"));
-               exit (EX_OSERR);
+               SCLog(TRUE, LOG_ERR, CFSTR("unknown message ID (%d) received"), request->msgh_id);
+
+               reply->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(request->msgh_bits), 0);
+               reply->msgh_remote_port = request->msgh_remote_port;
+               reply->msgh_size = sizeof(mig_reply_error_t);   /* Minimal size */
+               reply->msgh_local_port = MACH_PORT_NULL;
+               reply->msgh_id = request->msgh_id;
+               ((mig_reply_error_t *)reply)->NDR = NDR_record;
+               ((mig_reply_error_t *)reply)->RetCode = MIG_BAD_ID;
        }
 
        return processed;
@@ -176,6 +192,7 @@ configdCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
        }
 
        CFAllocatorDeallocate(NULL, bufReply);
+       return;
 }
 
 
@@ -225,7 +242,7 @@ server_init()
        /* Getting bootstrap server port */
        status = task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
        if (status != KERN_SUCCESS) {
-               SCDLog(LOG_DEBUG, CFSTR("task_get_bootstrap_port(): %s"), mach_error_string(status));
+               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("task_get_bootstrap_port(): %s"), mach_error_string(status));
                exit (EX_UNAVAILABLE);
        }
 
@@ -234,7 +251,7 @@ server_init()
        switch (status) {
                case BOOTSTRAP_SUCCESS :
                        if (active) {
-                               SCDLog(LOG_DEBUG, CFSTR("\"%s\" is currently active, exiting."), SCD_SERVER);
+                               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("\"%s\" is currently active, exiting."), SCD_SERVER);
                                exit (EX_UNAVAILABLE);
                        }
                        break;
@@ -264,20 +281,20 @@ server_init()
        /* Create a session for the primary / new connection port */
        (void) addSession(configd_port);
 
-       SCDLog(LOG_DEBUG, CFSTR("Registering service \"%s\""), SCD_SERVER);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Registering service \"%s\""), SCD_SERVER);
        status = bootstrap_register(bootstrap_port, SCD_SERVER, CFMachPortGetPort(configd_port));
        switch (status) {
                case BOOTSTRAP_SUCCESS :
                        /* service not currently registered, "a good thing" (tm) */
                        break;
                case BOOTSTRAP_NOT_PRIVILEGED :
-                       SCDLog(LOG_ERR, CFSTR("bootstrap_register(): bootstrap not privileged"));
+                       SCLog(_configd_verbose, LOG_ERR, CFSTR("bootstrap_register(): bootstrap not privileged"));
                        exit (EX_OSERR);
                case BOOTSTRAP_SERVICE_ACTIVE :
-                       SCDLog(LOG_ERR, CFSTR("bootstrap_register(): bootstrap service active"));
+                       SCLog(_configd_verbose, LOG_ERR, CFSTR("bootstrap_register(): bootstrap service active"));
                        exit (EX_OSERR);
                default :
-                       SCDLog(LOG_ERR, CFSTR("bootstrap_register(): %s"), mach_error_string(status));
+                       SCLog(_configd_verbose, LOG_ERR, CFSTR("bootstrap_register(): %s"), mach_error_string(status));
                        exit (EX_OSERR);
        }
 
@@ -292,18 +309,16 @@ server_loop()
        int             rlStatus;
 
        while (TRUE) {
-               boolean_t       isLocked = SCDOptionGet(NULL, kSCDOptionIsLocked);
-
                /*
                 * if linked with a DEBUG version of the framework, display some
                 * debugging information
                 */
-               _showMachPortStatus();
+               __showMachPortStatus();
 
                /*
                 * process one run loop event
                 */
-               rlMode = isLocked ? CFSTR("locked") : kCFRunLoopDefaultMode;
+               rlMode = (storeLocked > 0) ? CFSTR("locked") : kCFRunLoopDefaultMode;
                rlStatus = CFRunLoopRunInMode(rlMode, 1.0e10, TRUE);
 
                /*
index bc5708c64a504c8a9d9cc752a8a92b3a3a566df2..cb1c29c83a0d5dfe8fbc520567e9d6201c28829a 100644 (file)
  * @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
+ */
+
 #ifndef _S_CONFIGD_SERVER_H
 #define _S_CONFIGD_SERVER_H
 
@@ -33,116 +43,144 @@ extern    CFMachPortRef           configd_port;           /* configd server port (for new session req
 
 __BEGIN_DECLS
 
-void           configdCallback __P((CFMachPortRef              port,
-                                    void                       *msg,
-                                    CFIndex                    size,
-                                    void                       *info));
-
-boolean_t      server_active   __P(());
-void           server_init     __P(());
-
-void           server_loop     __P(());
-
-kern_return_t  _snapshot       __P((mach_port_t server, int *scd_status));
-
-kern_return_t  _configopen     __P((mach_port_t                server,
-                                    xmlData_t                  name,
-                                    mach_msg_type_number_t     nameCnt,
-                                    mach_port_t                *newServer,
-                                    int                        *scd_status));
-
-kern_return_t  _configclose    __P((mach_port_t server, int *scd_status));
-
-kern_return_t  _configlock     __P((mach_port_t server, int *scd_status));
-
-kern_return_t  _configunlock   __P((mach_port_t server, int *scd_status));
-
-kern_return_t  _configlist     __P((mach_port_t server,
-                                    xmlData_t                  key,
-                                    mach_msg_type_number_t     keyCnt,
-                                    int                        regexOptions,
-                                    xmlDataOut_t               *list,
-                                    mach_msg_type_number_t     *listCnt,
-                                    int                        *scd_status));
-
-kern_return_t  _configadd      __P((mach_port_t                server,
-                                    xmlData_t                  key,
-                                    mach_msg_type_number_t     keyCnt,
-                                    xmlData_t                  data,
-                                    mach_msg_type_number_t     dataCnt,
-                                    int                        *newInstance,
-                                    int                        *scd_status));
-
-kern_return_t  _configadd_s    __P((mach_port_t                server,
-                                    xmlData_t                  key,
-                                    mach_msg_type_number_t     keyCnt,
-                                    xmlData_t                  data,
-                                    mach_msg_type_number_t     dataCnt,
-                                    int                        *newInstance,
-                                    int                        *scd_status));
-
-kern_return_t  _configget      __P((mach_port_t                server,
-                                    xmlData_t                  key,
-                                    mach_msg_type_number_t     keyCnt,
-                                    xmlDataOut_t               *data,
-                                    mach_msg_type_number_t     *dataCnt,
-                                    int                        *newInstance,
-                                    int                        *scd_status));
-
-kern_return_t  _configset      __P((mach_port_t                server,
-                                    xmlData_t                  key,
-                                    mach_msg_type_number_t     keyCnt,
-                                    xmlData_t                  data,
-                                    mach_msg_type_number_t     dataCnt,
-                                    int                        *newInstance,
-                                    int                        *scd_status));
-
-kern_return_t  _configremove   __P((mach_port_t                server,
-                                    xmlData_t                  key,
-                                    mach_msg_type_number_t     keyCnt,
-                                    int                        *scd_status));
-
-kern_return_t  _configtouch    __P((mach_port_t                server,
-                                    xmlData_t                  key,
-                                    mach_msg_type_number_t     keyCnt,
-                                    int                        *scd_status));
-
-kern_return_t  _notifyadd      __P((mach_port_t                server,
-                                    xmlData_t                  key,
-                                    mach_msg_type_number_t     keyCnt,
-                                    int                        regexOptions,
-                                    int                        *status));
-
-kern_return_t  _notifyremove   __P((mach_port_t                server,
-                                    xmlData_t                  key,
-                                    mach_msg_type_number_t     keyCnt,
-                                    int                        regexOptions,
-                                    int                        *status));
-
-kern_return_t  _notifychanges  __P((mach_port_t                server,
-                                    xmlDataOut_t               *list,
-                                    mach_msg_type_number_t     *listCnt,
-                                    int                        *status));
-
-kern_return_t  _notifyviaport  __P((mach_port_t                server,
-                                    mach_port_t                port,
-                                    mach_msg_id_t              msgid,
-                                    int                        *status));
-
-kern_return_t  _notifyviafd    __P((mach_port_t                server,
-                                    xmlData_t                  path,
-                                    mach_msg_type_number_t     pathCnt,
-                                    int                        identifier,
-                                    int                        *status));
+void           configdCallback (CFMachPortRef          port,
+                                void                   *msg,
+                                CFIndex                size,
+                                void                   *info);
+
+boolean_t      server_active   ();
+
+void           server_init     ();
+
+void           server_loop     ();
+
+kern_return_t  _snapshot       (mach_port_t            server,
+                                int                    *sc_status);
+
+kern_return_t  _configopen     (mach_port_t            server,
+                                xmlData_t              nameRef,
+                                mach_msg_type_number_t nameLen,
+                                mach_port_t            *newServer,
+                                int                    *sc_status);
+
+kern_return_t  _configclose    (mach_port_t            server,
+                                int                    *sc_status);
+
+kern_return_t  _configlock     (mach_port_t            server,
+                                int                    *sc_status);
+
+kern_return_t  _configunlock   (mach_port_t            server,
+                                int                    *sc_status);
+
+kern_return_t  _configlist     (mach_port_t server,
+                                xmlData_t              keyRef,
+                                mach_msg_type_number_t keyLen,
+                                int                    isRegex,
+                                xmlDataOut_t           *listRef,
+                                mach_msg_type_number_t *listLen,
+                                int                    *sc_status);
+
+kern_return_t  _configadd      (mach_port_t            server,
+                                xmlData_t              keyRef,
+                                mach_msg_type_number_t keyLen,
+                                xmlData_t              dataRef,
+                                mach_msg_type_number_t dataLen,
+                                int                    *newInstance,
+                                int                    *sc_status);
+
+kern_return_t  _configadd_s    (mach_port_t            server,
+                                xmlData_t              keyRef,
+                                mach_msg_type_number_t keyLen,
+                                xmlData_t              dataRef,
+                                mach_msg_type_number_t dataLen,
+                                int                    *newInstance,
+                                int                    *sc_status);
+
+kern_return_t  _configget      (mach_port_t            server,
+                                xmlData_t              keyRef,
+                                mach_msg_type_number_t keyLen,
+                                xmlDataOut_t           *dataRef,
+                                mach_msg_type_number_t *dataLen,
+                                int                    *newInstance,
+                                int                    *sc_status);
+
+kern_return_t  _configset      (mach_port_t            server,
+                                xmlData_t              keyRef,
+                                mach_msg_type_number_t keyLen,
+                                xmlData_t              dataRef,
+                                mach_msg_type_number_t dataLen,
+                                int                    *newInstance,
+                                int                    *sc_status);
+
+kern_return_t  _configremove   (mach_port_t            server,
+                                xmlData_t              keyRef,
+                                mach_msg_type_number_t keyLen,
+                                int                    *sc_status);
+
+kern_return_t  _configtouch    (mach_port_t            server,
+                                xmlData_t              keyRef,
+                                mach_msg_type_number_t keyLen,
+                                int                    *sc_status);
+
+kern_return_t  _confignotify   (mach_port_t            server,
+                                xmlData_t              keyRef,
+                                mach_msg_type_number_t keyLen,
+                                int                    *sc_status);
+
+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);
+
+kern_return_t  _configset_m    (mach_port_t            server,
+                                xmlData_t              dataRef,
+                                mach_msg_type_number_t dataLen,
+                                xmlData_t              removeRef,
+                                mach_msg_type_number_t removeLen,
+                                xmlData_t              notifyRef,
+                                mach_msg_type_number_t notifyLen,
+                                int                    *sc_status);
+
+kern_return_t  _notifyadd      (mach_port_t            server,
+                                xmlData_t              keyRef,
+                                mach_msg_type_number_t keyLen,
+                                int                    isRegex,
+                                int                    *status);
+
+kern_return_t  _notifyremove   (mach_port_t            server,
+                                xmlData_t              keyRef,
+                                mach_msg_type_number_t keyLen,
+                                int                    isRegex,
+                                int                    *status);
+
+kern_return_t  _notifychanges  (mach_port_t            server,
+                                xmlDataOut_t           *listRef,
+                                mach_msg_type_number_t *listLen,
+                                int                    *status);
+
+kern_return_t  _notifyviaport  (mach_port_t            server,
+                                mach_port_t            port,
+                                mach_msg_id_t          msgid,
+                                int                    *status);
+
+kern_return_t  _notifyviafd    (mach_port_t            server,
+                                xmlData_t              pathRef,
+                                mach_msg_type_number_t pathLen,
+                                int                    identifier,
+                                int                    *status);
 
 kern_return_t  _notifyviasignal
-                               __P((mach_port_t                server,
-                                    task_t                     task,
-                                    int                        signal,
-                                    int                        *status));
+                               (mach_port_t            server,
+                                task_t                 task,
+                                int                    signal,
+                                int                    *status);
 
-kern_return_t  _notifycancel   __P((mach_port_t                server,
-                                    int                        *scd_status));
+kern_return_t  _notifycancel   (mach_port_t            server,
+                                int                    *sc_status);
 
 __END_DECLS
 
index b87dd9efb5bcc5922f3dc6e4818bad6aa753d6be..3248c92e944b0701875444b68ca55ebbd9c2672b 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 31, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 
 #include <unistd.h>
 
 void
 pushNotifications()
 {
-       void                    **sessionsToNotify;
-       CFIndex                 notifyCnt;
-       int                     server;
-       serverSessionRef        theSession;
-       SCDSessionPrivateRef    sessionPrivate;
+       void                            **sessionsToNotify;
+       CFIndex                         notifyCnt;
+       int                             server;
+       serverSessionRef                theSession;
+       SCDynamicStorePrivateRef        storePrivate;
 
        if (needsNotification == NULL)
                return;         /* if no sessions need to be kicked */
@@ -48,36 +58,27 @@ pushNotifications()
                                        kCFNumberIntType,
                                        &server);
                theSession = getSession(server);
-               sessionPrivate = (SCDSessionPrivateRef)theSession->session;
-
-               /*
-                * handle callbacks for "configd" plug-ins
-                */
-               if (sessionPrivate->callbackFunction != NULL) {
-                       SCDLog(LOG_DEBUG, CFSTR("executing notifiction callback function (server=%d)."),
-                              sessionPrivate->server);
-                       (void) (*sessionPrivate->callbackFunction)(theSession->session,
-                                                                  sessionPrivate->callbackArgument);
-               }
+               storePrivate = (SCDynamicStorePrivateRef)theSession->store;
 
                /*
                 * deliver notifications to client sessions
                 */
-               if (sessionPrivate->notifyPort != MACH_PORT_NULL) {
+               if ((storePrivate->notifyStatus == Using_NotifierInformViaMachPort) &&
+                   (storePrivate->notifyPort != MACH_PORT_NULL)) {
                        mach_msg_empty_send_t   msg;
                        mach_msg_option_t       options;
                        kern_return_t           status;
                        /*
                         * Post notification as mach message
                         */
-                       SCDLog(LOG_DEBUG, CFSTR("sending mach message notification."));
-                       SCDLog(LOG_DEBUG, CFSTR("  port  = %d"), sessionPrivate->notifyPort);
-                       SCDLog(LOG_DEBUG, CFSTR("  msgid = %d"), sessionPrivate->notifyPortIdentifier);
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("sending mach message notification."));
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  port  = %d"), storePrivate->notifyPort);
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  msgid = %d"), storePrivate->notifyPortIdentifier);
                        msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
                        msg.header.msgh_size = sizeof(msg);
-                       msg.header.msgh_remote_port = sessionPrivate->notifyPort;
+                       msg.header.msgh_remote_port = storePrivate->notifyPort;
                        msg.header.msgh_local_port = MACH_PORT_NULL;
-                       msg.header.msgh_id = sessionPrivate->notifyPortIdentifier;
+                       msg.header.msgh_id = storePrivate->notifyPortIdentifier;
                        options = MACH_SEND_TIMEOUT;
                        status = mach_msg(&msg.header,                  /* msg */
                                          MACH_SEND_MSG|options,        /* options */
@@ -88,64 +89,66 @@ pushNotifications()
                                          MACH_PORT_NULL);              /* notify */
                }
 
-               if (sessionPrivate->notifyFile >= 0) {
+               if ((storePrivate->notifyStatus == Using_NotifierInformViaFD) &&
+                   (storePrivate->notifyFile >= 0)) {
                        ssize_t         written;
 
-                       SCDLog(LOG_DEBUG, CFSTR("sending (UNIX domain) socket notification"));
-                       SCDLog(LOG_DEBUG, CFSTR("  fd    = %d"), sessionPrivate->notifyFile);
-                       SCDLog(LOG_DEBUG, CFSTR("  msgid = %d"), sessionPrivate->notifyFileIdentifier);
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("sending (UNIX domain) socket notification"));
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  fd    = %d"), storePrivate->notifyFile);
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  msgid = %d"), storePrivate->notifyFileIdentifier);
 
-                       written = write(sessionPrivate->notifyFile,
-                                       &sessionPrivate->notifyFileIdentifier,
-                                       sizeof(sessionPrivate->notifyFileIdentifier));
+                       written = write(storePrivate->notifyFile,
+                                       &storePrivate->notifyFileIdentifier,
+                                       sizeof(storePrivate->notifyFileIdentifier));
                        if (written == -1) {
                                if (errno == EWOULDBLOCK) {
-                                       SCDLog(LOG_DEBUG,
+                                       SCLog(_configd_verbose, LOG_DEBUG,
                                               CFSTR("sorry, only one outstanding notification per session."));
                                } else {
-                                       SCDLog(LOG_DEBUG,
+                                       SCLog(_configd_verbose, LOG_DEBUG,
                                               CFSTR("could not send notification, write() failed: %s"),
                                               strerror(errno));
-                                       sessionPrivate->notifyFile = -1;
+                                       storePrivate->notifyFile = -1;
                                }
-                       } else if (written != sizeof(sessionPrivate->notifyFileIdentifier)) {
-                               SCDLog(LOG_DEBUG,
+                       } else if (written != sizeof(storePrivate->notifyFileIdentifier)) {
+                               SCLog(_configd_verbose, LOG_DEBUG,
                                       CFSTR("could not send notification, incomplete write()"));
-                               sessionPrivate->notifyFile = -1;
+                               storePrivate->notifyFile = -1;
                        }
                }
 
-               if (sessionPrivate->notifySignal > 0) {
+               if ((storePrivate->notifyStatus == Using_NotifierInformViaSignal) &&
+                   (storePrivate->notifySignal > 0)) {
                        kern_return_t   status;
                        pid_t           pid;
                        /*
                         * Post notification as signal
                         */
-                       status = pid_for_task(sessionPrivate->notifySignalTask, &pid);
+                       status = pid_for_task(storePrivate->notifySignalTask, &pid);
                        if (status == KERN_SUCCESS) {
-                               SCDLog(LOG_DEBUG, CFSTR("sending signal notification"));
-                               SCDLog(LOG_DEBUG, CFSTR("  pid    = %d"), pid);
-                               SCDLog(LOG_DEBUG, CFSTR("  signal = %d"), sessionPrivate->notifySignal);
-                               if (kill(pid, sessionPrivate->notifySignal) != 0) {
-                                       SCDLog(LOG_DEBUG, CFSTR("could not send signal: %s"), strerror(errno));
+                               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("sending signal notification"));
+                               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  pid    = %d"), pid);
+                               SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  signal = %d"), storePrivate->notifySignal);
+                               if (kill(pid, storePrivate->notifySignal) != 0) {
+                                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("could not send signal: %s"), strerror(errno));
                                        status = KERN_FAILURE;
                                }
                        } else {
                                mach_port_type_t        pt;
 
-                               if ((mach_port_type(mach_task_self(), sessionPrivate->notifySignalTask, &pt) == KERN_SUCCESS) &&
+                               if ((mach_port_type(mach_task_self(), storePrivate->notifySignalTask, &pt) == KERN_SUCCESS) &&
                                    (pt & MACH_PORT_TYPE_DEAD_NAME)) {
-                                       SCDLog(LOG_DEBUG, CFSTR("could not send signal, process died"));
+                                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("could not send signal, process died"));
                                } else {
-                                       SCDLog(LOG_DEBUG, CFSTR("could not send signal: %s"), mach_error_string(status));
+                                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("could not send signal: %s"), mach_error_string(status));
                                }
                        }
 
                        if (status != KERN_SUCCESS) {
                                /* don't bother with any more attempts */
-                               (void) mach_port_destroy(mach_task_self(), sessionPrivate->notifySignalTask);
-                               sessionPrivate->notifySignal     = 0;
-                               sessionPrivate->notifySignalTask = TASK_NULL;
+                               (void) mach_port_destroy(mach_task_self(), storePrivate->notifySignalTask);
+                               storePrivate->notifySignal     = 0;
+                               storePrivate->notifySignalTask = TASK_NULL;
                        }
               }
        }
index cd1f018a135b6ca8837f6538b246541142c2638f..790e78125ce19ca171e9ddc9f02540aa02db61a9 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * March 31, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #ifndef _S_NOTIFY_H
 #define _S_NOTIFY_H
 
@@ -27,7 +34,7 @@
 
 __BEGIN_DECLS
 
-void           pushNotifications       __P(());
+void           pushNotifications       ();
 
 __END_DECLS
 
index c043d43af5f81ce7b16ec982193036b1f4d86e60..734b90db7117381b143ea30c5abcc1ce5d6c577f 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * March 24, 2000              Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include "configd.h"
 #include "session.h"
+#include "notify.h"
 
 boolean_t
 notify_server(mach_msg_header_t *request, mach_msg_header_t *reply)
@@ -35,7 +43,7 @@ notify_server(mach_msg_header_t *request, mach_msg_header_t *reply)
 
        switch (notify->not_header.msgh_id) {
                case MACH_NOTIFY_NO_SENDERS :
-                       SCDLog(LOG_DEBUG, CFSTR("No more senders for port %d, closing."),
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("No more senders for port %d, closing."),
                                 notify->not_header.msgh_local_port);
                        cleanupSession(notify->not_header.msgh_local_port);
 
@@ -44,7 +52,7 @@ notify_server(mach_msg_header_t *request, mach_msg_header_t *reply)
                        notify->not_header.msgh_remote_port = MACH_PORT_NULL;
                        return TRUE;
                case MACH_NOTIFY_DEAD_NAME :
-                       SCDLog(LOG_DEBUG, CFSTR("Dead name for port %d, closing."),
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Dead name for port %d, closing."),
                                 notify->not_header.msgh_local_port);
                        cleanupSession(notify->not_header.msgh_local_port);
 
@@ -56,7 +64,7 @@ notify_server(mach_msg_header_t *request, mach_msg_header_t *reply)
                        break;
        }
 
-       SCDLog(LOG_DEBUG, CFSTR("HELP!, Received notification: port=%d, msgh_id=%d"),
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("HELP!, Received notification: port=%d, msgh_id=%d"),
               notify->not_header.msgh_local_port,
               notify->not_header.msgh_id);
 
index 170d718240a16330f77e50f729c79b24d690ef65..150b58ef744b012ef0d253fc0d068c2d590c362f 100644 (file)
  * @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
+ */
+
 #ifndef _S_NOTIFY_SERVER_H
 #define _S_NOTIFY_SERVER_H
 
@@ -28,7 +38,7 @@
 
 __BEGIN_DECLS
 
-boolean_t      notify_server   __P((mach_msg_header_t *request, mach_msg_header_t *reply));
+boolean_t      notify_server   (mach_msg_header_t *request, mach_msg_header_t *reply);
 
 __END_DECLS
 
index fd6e3c8623c205a50db8af092eec1d06dd467f1c..b511a89d999f8bb45ea90ba2e006b898528ecb46 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 11, 2001               Allan Nathanson <ajn@apple.com>
+ * - start using CFBundle code
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * May 26, 2000                        Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <mach-o/dyld.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <NSSystemDirectories.h>
 
 #include "configd.h"
+#include <SystemConfiguration/SCDPlugin.h>
 
 
 /*
- * Information maintained for each to-be-kicked registration.
+ * path components, extensions, entry points, ...
  */
-typedef struct {
-       /*
-        * bundle paths
-        */
-       char                            bundle[MAXNAMLEN + 1];  /* bundle name */
-       char                            path  [MAXPATHLEN];     /* bundle path */
-
-       /*
-        * entry points for initialization code.
-        */
-       SCDBundleStartRoutine_t         start;  /* address of start() routine */
-       SCDBundlePrimeRoutine_t         prime;  /* address of prime() routine */
+#define        BUNDLE_DIRECTORY        "/SystemConfiguration"  /* [/System/Library]/... */
+#define        BUNDLE_DIR_EXTENSION    ".bundle"
 
-} plugin, *pluginRef;
 
-CFMutableArrayRef      plugins;
+static CFMutableArrayRef       allBundles      = NULL;
 
 
 /* exception handling functions */
@@ -166,262 +169,296 @@ catch_exception_raise_state_identity(mach_port_t                exception_port,
 }
 
 
-static boolean_t
-bundleLoad(pluginRef info)
+static CFStringRef
+shortBundleIdentifier(CFStringRef bundleID)
 {
-       int                             len;
-       NSObjectFileImage               image;
-       NSObjectFileImageReturnCode     status;
-       NSModule                        module;
-       NSSymbol                        symbol;
-       unsigned long                   options;
-       char                            *bundleExe;     /* full path of bundle executable */
-       struct stat                     sb;
+       CFIndex         len     = CFStringGetLength(bundleID);
+       CFRange         range;
+       CFStringRef     shortID = NULL;
+
+       if (CFStringFindWithOptions(bundleID,
+                                   CFSTR("."),
+                                   CFRangeMake(0, len),
+                                   kCFCompareBackwards,
+                                   &range)) {
+               range.location = range.location + range.length;
+               range.length   = len - range.location;
+               shortID = CFStringCreateWithSubstring(NULL, bundleID, range);
+       }
 
-       /*
-        * allocate enough space for the bundle directory path, a "/" separator,
-        * the bundle name, and the (optional) "_debug" extension.
-        */
+       return shortID;
+}
 
-       len =  strlen(info->path);              /* path */
-       len += sizeof(BUNDLE_NEW_SUBDIR) - 1;   /* "/" or "/Contents/MacOS/" */
-       len += strlen(info->bundle);            /* bundle name */
-       len += sizeof(BUNDLE_DEBUG_EXTENSION);  /* "_debug" (and NUL) */
-       bundleExe = CFAllocatorAllocate(NULL, len, 0);
-
-       /* check for the (old layout) bundle executable path */
-       strcpy(bundleExe, info->path);
-       strcat(bundleExe, BUNDLE_OLD_SUBDIR);
-       strcat(bundleExe, info->bundle);
-       if (stat(bundleExe, &sb) == 0) {
-               goto load;
-       }
 
-       /* check for the "_debug" version */
-       strcat(bundleExe, BUNDLE_DEBUG_EXTENSION);
-       if (stat(bundleExe, &sb) == 0) {
-               goto load;
+static void
+loadBundle(const void *value, void *context) {
+       CFBundleRef                             bundle          = (CFBundleRef)value;
+       CFStringRef                             bundleID        = CFBundleGetIdentifier(bundle);
+       Boolean                                 bundleExclude   = FALSE;
+       Boolean                                 bundleVerbose   = FALSE;
+       CFDictionaryRef                         dict;
+       void                                    *func;
+       SCDynamicStoreBundleLoadFunction        load;
+       Boolean                                 loaded;
+       CFIndex                                 *nLoaded        = (CFIndex *)context;
+
+       SCLog(TRUE, LOG_DEBUG, CFSTR("loading %@"), bundleID);
+
+       bundleExclude = CFSetContainsValue(_plugins_exclude, bundleID);
+       if (!bundleExclude) {
+               CFStringRef     shortID = shortBundleIdentifier(bundleID);
+
+               if (shortID) {
+                       bundleExclude = CFSetContainsValue(_plugins_exclude, shortID);
+                       CFRelease(shortID);
+               }
        }
 
-       /* check for the (new layout) bundle executable path */
-       strcpy(bundleExe, info->path);
-       strcat(bundleExe, BUNDLE_NEW_SUBDIR);
-       strcat(bundleExe, info->bundle);
-       if (stat(bundleExe, &sb) == 0) {
-               goto load;
+       if (bundleExclude) {
+               SCLog(TRUE,
+                     LOG_DEBUG,
+                     CFSTR("%@ load skipped"),
+                     bundleID);
+               return;
        }
 
-       /* check for the "_debug" version */
-       strcat(bundleExe, BUNDLE_DEBUG_EXTENSION);
-       if (stat(bundleExe, &sb) == 0) {
-               goto load;
+       loaded = CFBundleLoadExecutable(bundle);
+       if (!loaded) {
+               SCLog(TRUE,
+                     LOG_NOTICE,
+                     CFSTR("%@ load failed"),
+                     bundleID);
+               return;
        }
 
-       SCDLog(LOG_ERR,
-              CFSTR("bundleLoad() failed, no executable for %s in %s"),
-              info->bundle,
-              info->path);
-       CFAllocatorDeallocate(NULL, bundleExe);
-       return FALSE;
+       if (!CFBundleIsExecutableLoaded(bundle)) {
+               SCLog(TRUE,
+                     LOG_NOTICE,
+                     CFSTR("%@ executable not loaded"),
+                     bundleID);
+               return;
+       }
 
-    load :
+       /* bump the count of loaded bundles */
+       *nLoaded = *nLoaded + 1;
 
-       /* load the bundle */
-       SCDLog(LOG_DEBUG, CFSTR("loading %s"), bundleExe);
-       status = NSCreateObjectFileImageFromFile(bundleExe, &image);
-       if (status != NSObjectFileImageSuccess) {
-               char    *err;
+       /* identify any exception handling functions */
 
-               switch (status) {
-                       case NSObjectFileImageFailure :
-                               err = "NSObjectFileImageFailure";
-                               break;
-                       case NSObjectFileImageInappropriateFile :
-                               err = "NSObjectFileImageInappropriateFile";
-                               break;
-                       case NSObjectFileImageArch :
-                               err = "NSObjectFileImageArch";
-                               break;
-                       case NSObjectFileImageFormat :
-                               err = "NSObjectFileImageFormat";
-                               break;
-                       case NSObjectFileImageAccess :
-                               err = "NSObjectFileImageAccess";
-                               break;
-                       default :
-                               err = "Unknown";
-                               break;
-               }
-               SCDLog(LOG_ERR, CFSTR("NSCreateObjectFileImageFromFile() failed"));
-               SCDLog(LOG_ERR, CFSTR("  executable path = %s"), bundleExe);
-               SCDLog(LOG_ERR, CFSTR("  error status    = %s"), err);
-               CFAllocatorDeallocate(NULL, bundleExe);
-               return FALSE;
+       func = CFBundleGetFunctionPointerForName(bundle, CFSTR("catch_exception_raise"));
+       if (func) {
+               catch_exception_raise_func = func;
        }
 
-       options =  NSLINKMODULE_OPTION_BINDNOW;
-       options |= NSLINKMODULE_OPTION_PRIVATE;
-       options |= NSLINKMODULE_OPTION_RETURN_ON_ERROR;
-       module = NSLinkModule(image, bundleExe, options);
-
-       if (module == NULL) {
-               NSLinkEditErrors        c;
-               int                     errorNumber;
-               const char              *fileName;
-               const char              *errorString;
-
-               SCDLog(LOG_ERR, CFSTR("NSLinkModule() failed"));
-               SCDLog(LOG_ERR, CFSTR("  executable path = %s"), bundleExe);
-
-               /* collect and report the details */
-               NSLinkEditError(&c, &errorNumber, &fileName, &errorString);
-               SCDLog(LOG_ERR, CFSTR("  NSLinkEditErrors = %d"), (int)c);
-               SCDLog(LOG_ERR, CFSTR("  errorNumber      = %d"), errorNumber);
-               if((fileName != NULL) && (*fileName != '\0'))
-                       SCDLog(LOG_ERR, CFSTR("  fileName         = %s"), fileName);
-               if((errorString != NULL) && (*errorString != '\0'))
-                       SCDLog(LOG_ERR, CFSTR("  errorString      = %s"), errorString);
-
-               CFAllocatorDeallocate(NULL, bundleExe);
-               return FALSE;
+       func = CFBundleGetFunctionPointerForName(bundle, CFSTR("catch_exception_raise_state"));
+       if (func) {
+               catch_exception_raise_state_func = func;
        }
 
-       CFAllocatorDeallocate(NULL, bundleExe);
-
-       /* identify the initialization functions */
-
-       symbol = NSLookupSymbolInModule(module, BUNDLE_ENTRY_POINT);
-       if (symbol) {
-               info->start = NSAddressOfSymbol(symbol);
+       func = CFBundleGetFunctionPointerForName(bundle, CFSTR("catch_exception_raise_identity"));
+       if (func) {
+               catch_exception_raise_identity_func = func;
        }
 
-       symbol = NSLookupSymbolInModule(module, BUNDLE_ENTRY_POINT2);
-       if (symbol) {
-               info->prime = NSAddressOfSymbol(symbol);
-       }
+       /* if defined, call the bundles load() function */
 
-       if ((info->start == NULL) && (info->prime == NULL)) {
-               SCDLog(LOG_DEBUG, CFSTR("  no entry points"));
-               return FALSE;
+       load = CFBundleGetFunctionPointerForName(bundle, CFSTR("load"));
+       if (!load) {
+               return;
        }
 
-       /* identify any exception handling functions */
+       bundleVerbose = CFSetContainsValue(_plugins_verbose, bundleID);
+       if (!bundleVerbose) {
+               CFStringRef     shortID = shortBundleIdentifier(bundleID);
 
-       symbol = NSLookupSymbolInModule(module, "_catch_exception_raise");
-       if (symbol) {
-               catch_exception_raise_func = NSAddressOfSymbol(symbol);
+               if (shortID) {
+                       bundleVerbose = CFSetContainsValue(_plugins_verbose, shortID);
+                       CFRelease(shortID);
+               }
        }
 
-       symbol = NSLookupSymbolInModule(module, "_catch_exception_raise_state");
-       if (symbol) {
-               catch_exception_raise_state_func = NSAddressOfSymbol(symbol);
-       }
+       if (!bundleVerbose) {
+       dict = CFBundleGetInfoDictionary(bundle);
+       if (isA_CFDictionary(dict)) {
+               CFBooleanRef    bool;
 
-       symbol = NSLookupSymbolInModule(module, "_catch_exception_raise_identity");
-       if (symbol) {
-               catch_exception_raise_identity_func = NSAddressOfSymbol(symbol);
+                       bool = CFDictionaryGetValue(dict, kSCBundleVerbose);
+               if (isA_CFBoolean(bool) && CFBooleanGetValue(bool)) {
+                               bundleVerbose = TRUE;
+                       }
+               }
        }
 
-       return TRUE;
+       (*load)(bundle, bundleVerbose);
+       return;
 }
 
 
 static void
-bundleStart(const void *value, void *context)
-{
-       CFDataRef       data = (CFDataRef)value;
-       pluginRef       info;
-
-       info = (pluginRef)CFDataGetBytePtr(data);
-       if (info->start) {
-               (*info->start)(info->bundle, info->path);
+startBundle(const void *value, void *context) {
+       CFBundleRef                             bundle          = (CFBundleRef)value;
+       CFURLRef                                bundleURL;
+       char                                    bundleName[MAXNAMLEN + 1];
+       char                                    bundlePath[MAXPATHLEN];
+       char                                    *cp;
+       CFDictionaryRef                         dict;
+       int                                     len;
+       Boolean                                 ok;
+       SCDynamicStoreBundleStartFunction       start;
+
+       if (!CFBundleIsExecutableLoaded(bundle)) {
+               return;
        }
-}
 
+       start = CFBundleGetFunctionPointerForName(bundle, CFSTR("start"));
+       if (!start) {
+               return;
+       }
 
-static void
-bundlePrime(const void *value, void *context)
-{
-       CFDataRef       data = (CFDataRef)value;
-       pluginRef       info;
+       dict = isA_CFDictionary(CFBundleGetInfoDictionary(bundle));
+       if (!dict) {
+               return;
+       }
 
-       info = (pluginRef)CFDataGetBytePtr(data);
-       if (info->prime) {
-               (*info->prime)(info->bundle, info->path);
+       bundleURL = CFBundleCopyBundleURL(bundle);
+       if (!bundleURL) {
+               return;
        }
-}
 
+       ok = CFURLGetFileSystemRepresentation(bundleURL,
+                                             TRUE,
+                                             (UInt8 *)&bundlePath,
+                                             sizeof(bundlePath));
+       CFRelease(bundleURL);
+       if (!ok) {
+               return;
+       }
 
-static void
-loadOne(const char *bundleDir, const char *bundleName)
-{
-       CFMutableDataRef        info;
-       pluginRef               pluginInfo;
-       int                     len;
+       cp = strrchr(bundlePath, '/');
+       if (cp) {
+               cp++;
+       } else {
+               cp = bundlePath;
+       }
 
        /* check if this directory entry is a valid bundle name */
-       len = strlen(bundleName);
+       len = strlen(cp);
        if (len <= sizeof(BUNDLE_DIR_EXTENSION)) {
                /* if entry name isn't long enough */
                return;
        }
 
        len -= sizeof(BUNDLE_DIR_EXTENSION) - 1;
-       if (strcmp(&bundleName[len], BUNDLE_DIR_EXTENSION) != 0) {
+       if (strcmp(&cp[len], BUNDLE_DIR_EXTENSION) != 0) {
                /* if entry name doesn end with ".bundle" */
                return;
        }
 
-       info = CFDataCreateMutable(NULL, sizeof(plugin));
-       pluginInfo = (pluginRef)CFDataGetBytePtr(info);
-       pluginInfo->start = NULL;
-       pluginInfo->prime = NULL;
-
        /* get (just) the bundle's name */
-       pluginInfo->bundle[0] = '\0';
-       (void) strncat(pluginInfo->bundle, bundleName, len);
-
-       /* get the bundle directory path */
-       (void) sprintf(pluginInfo->path, "%s/%s", bundleDir, bundleName);
-
-       /* load the bundle */
-       if (bundleLoad(pluginInfo)) {
-               SCDLog(LOG_INFO, CFSTR("%s loaded"), bundleName);
-               CFArrayAppendValue(plugins, info);
-       } else {
-               SCDLog(LOG_ERR,  CFSTR("load of \"%s\" failed"), bundleName);
-       }
-       CFRelease(info);
+       bundleName[0] = '\0';
+       (void) strncat(bundleName, cp, len);
 
+       (*start)(bundleName, bundlePath);
        return;
 }
 
 
 static void
-loadAll(const char *bundleDir)
-{
-       DIR                     *dirp;
-       struct dirent           *dp;
+primeBundle(const void *value, void *context) {
+       CFBundleRef                             bundle          = (CFBundleRef)value;
+       SCDynamicStoreBundlePrimeFunction       prime;
 
-       dirp = opendir(bundleDir);
-       if (dirp == NULL) {
-               /* if no plugin directory */
+       if (!CFBundleIsExecutableLoaded(bundle)) {
                return;
        }
 
-       while ((dp = readdir(dirp)) != NULL) {
-               loadOne(bundleDir, dp->d_name);
+       prime = CFBundleGetFunctionPointerForName(bundle, CFSTR("prime"));
+       if (!prime) {
+               return;
        }
 
-       closedir(dirp);
+       (*prime)();
        return;
 }
 
 
-void
+static void
 timerCallback(CFRunLoopTimerRef timer, void *info)
 {
-       SCDLog(LOG_INFO, CFSTR("the CFRunLoop is waiting for something to happen...."));
+       SCLog(_configd_verbose,
+             LOG_INFO,
+             CFSTR("the CFRunLoop is waiting for something to happen...."));
+       return;
+}
+
+
+static void
+sortBundles(CFMutableArrayRef orig)
+{
+       CFMutableArrayRef   new;
+
+       new = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       while (CFArrayGetCount(orig) > 0) {
+               int     i;
+               Boolean inserted = FALSE;
+
+               for (i = 0; i < CFArrayGetCount(orig); i++) {
+                       CFBundleRef     bundle1   = CFArrayGetValueAtIndex(orig, i);
+                       CFStringRef     bundleID1 = CFBundleGetIdentifier(bundle1);
+                       int             count;
+                       CFDictionaryRef dict;
+                       int             j;
+                       CFArrayRef      requires  = NULL;
+
+                       dict = isA_CFDictionary(CFBundleGetInfoDictionary(bundle1));
+                       if (dict) {
+                               requires = CFDictionaryGetValue(dict, kSCBundleRequires);
+                               requires = isA_CFArray(requires);
+                       }
+                       if (bundleID1 == NULL || requires == NULL) {
+                               CFArrayInsertValueAtIndex(new, 0, bundle1);
+                               CFArrayRemoveValueAtIndex(orig, i);
+                               inserted = TRUE;
+                               break;
+                       }
+                       count = CFArrayGetCount(requires);
+                       for (j = 0; j < CFArrayGetCount(requires); j++) {
+                               int             k;
+                               CFStringRef     r       = CFArrayGetValueAtIndex(requires, j);
+
+                               for (k = 0; k < CFArrayGetCount(new); k++) {
+                                       CFBundleRef     bundle2   = CFArrayGetValueAtIndex(new, k);
+                                       CFStringRef     bundleID2 = CFBundleGetIdentifier(bundle2);
+
+                                       if (bundleID2 && CFEqual(bundleID2, r)) {
+                                               count--;
+                                       }
+                               }
+                       }
+                       if (count == 0) {
+                               /* all dependencies are met, append */
+                               CFArrayAppendValue(new, bundle1);
+                               CFArrayRemoveValueAtIndex(orig, i);
+                               inserted = TRUE;
+                               break;
+                       }
+               }
+
+               if (inserted == FALSE) {
+                       SCLog(TRUE, LOG_NOTICE, CFSTR("Bundles have circular dependency!!!"));
+                       break;
+               }
+       }
+       if (CFArrayGetCount(orig) > 0) {
+               /* we have a circular dependency, append remaining items on new array */
+               CFArrayAppendArray(new, orig, CFRangeMake(0, CFArrayGetCount(orig)));
+       }
+       else {
+               /* new one is a sorted version of original */
+       }
+
+       CFArrayRemoveAllValues(orig);
+       CFArrayAppendArray(orig, new, CFRangeMake(0, CFArrayGetCount(new)));
+       CFRelease(new);
        return;
 }
 
@@ -429,66 +466,113 @@ timerCallback(CFRunLoopTimerRef timer, void *info)
 void *
 plugin_exec(void *arg)
 {
-       NSSearchPathEnumerationState    state;
-       char                            path[MAXPATHLEN];
+       CFIndex                 nLoaded         = 0;
 
-       /* keep track of loaded plugins */
-       plugins = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       /* keep track of bundles */
+       allBundles = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
 
        if (arg == NULL) {
+               char                            path[MAXPATHLEN];
+               NSSearchPathEnumerationState    state;
+
                /*
-                * identify and load all plugins
+                * identify and load all bundles
                 */
                state = NSStartSearchPathEnumeration(NSLibraryDirectory,
                                                     NSLocalDomainMask|NSSystemDomainMask);
                while ((state = NSGetNextSearchPathEnumeration(state, path))) {
-                       /* load any available plugins */
+                       CFArrayRef      bundles;
+                       CFURLRef        url;
+
+                       /* load any available bundle */
                        strcat(path, BUNDLE_DIRECTORY);
-                       SCDLog(LOG_DEBUG, CFSTR("searching for plugins in \"%s\""), path);
-                       loadAll(path);
+                       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("searching for bundles in \".\""));
+                       url = CFURLCreateFromFileSystemRepresentation(NULL,
+                                                                     path,
+                                                                     strlen(path),
+                                                                     TRUE);
+                       bundles = CFBundleCreateBundlesFromDirectory(NULL, url, CFSTR(".bundle"));
+                       CFRelease(url);
+
+                       if (bundles) {
+                               CFArrayAppendArray(allBundles,
+                                                  bundles,
+                                                  CFRangeMake(0, CFArrayGetCount(bundles)));
+                               CFRelease(bundles);
+                       }
                }
 
-               if (SCDOptionGet(NULL, kSCDOptionDebug)) {
-                       SCDLog(LOG_DEBUG, CFSTR("searching for plugins in \".\""));
-                       loadAll(".");
-               }
+               sortBundles(allBundles);
        } else {
+               CFBundleRef     bundle;
+               CFURLRef        url;
+
                /*
-                * load the plugin specified on the command line
+                * load (only) the specified bundle
                 */
-               char    *bn, *bd;
-
-               if ((bn = strrchr((char *)arg, '/')) != NULL) {
-                       int     len;
-
-                       /* plug-in directory */
-                       len = bn - (char *)arg;
-                       if (len == 0)
-                               len++;          /* if plugin is in the root directory */
-
-                       bd = CFAllocatorAllocate(NULL, len + 1, 0);
-                       bd[0] = '\0';
-                       (void) strncat(bd, (char *)arg, len);
+               url = CFURLCreateFromFileSystemRepresentation(NULL,
+                                                             (char *)arg,
+                                                             strlen((char *)arg),
+                                                             TRUE);
+               bundle = CFBundleCreate(NULL, url);
+               if (bundle) {
+                       CFArrayAppendValue(allBundles, bundle);
+                       CFRelease(bundle);
+               }
+               CFRelease(url);
+       }
 
-                       /* plug-in name */
-                       bn++;           /* name starts just after trailing path separator */
-               } else {
-                       /* plug-in (in current) directory */
-                       bd = CFAllocatorAllocate(NULL, sizeof("."), 0);
-                       (void) strcpy(bd, ".");
+       /*
+        * load each bundle and, if defined, call its load() function.  This
+        * function (or the start() function) should initialize any variables,
+        * open any sessions with "configd", and register any needed notifications.
+        *
+        * Note: Establishing initial information in the store should be
+        *       deferred until the prime() initialization function so that
+        *       any bundles which want to receive a notification that the
+        *       data has changed will have an opportunity to install a
+        *       notification handler.
+        */
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("calling bundle load() functions"));
+       CFArrayApplyFunction(allBundles,
+                            CFRangeMake(0, CFArrayGetCount(allBundles)),
+                            loadBundle,
+                            &nLoaded);
 
-                       /* plug-in name */
-                       bn = (char *)arg;       /* no path separators */
-               }
+       /*
+        * If defined, call each bundles start() function.  This function is
+        * called after the bundle has been loaded and its load() function has
+        * been called.  It should initialize any variables, open any sessions
+        * with "configd", and register any needed notifications.
+        *
+        * Note: Establishing initial information in the store should be
+        *       deferred until the prime() initialization function so that
+        *       any bundles which want to receive a notification that the
+        *       data has changed will have an opportunity to install a
+        *       notification handler.
+        */
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("calling bundle start() functions"));
+       CFArrayApplyFunction(allBundles,
+                            CFRangeMake(0, CFArrayGetCount(allBundles)),
+                            startBundle,
+                            NULL);
 
-               loadOne(bd, bn);
+       /*
+        * If defined, call each bundles prime() function.  This function is
+        * called after the bundle has been loaded and its load() and start()
+        * functions have been called.  It should initialize any configuration
+        * information and/or state in the store.
+        */
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("calling bundle prime() functions"));
+       CFArrayApplyFunction(allBundles,
+                            CFRangeMake(0, CFArrayGetCount(allBundles)),
+                            primeBundle,
+                            NULL);
 
-               CFAllocatorDeallocate(NULL, bd);
+       if (arg == NULL && (nLoaded > 0)) {
+               CFRunLoopTimerRef       timer;
 
                /* allocate a periodic event (to help show we're not blocking) */
-               if (CFArrayGetCount(plugins)) {
-                       CFRunLoopTimerRef       timer;
-
                        timer = CFRunLoopTimerCreate(NULL,                              /* allocator */
                                                     CFAbsoluteTimeGetCurrent() + 1.0,  /* fireDate */
                                                     60.0,                              /* interval */
@@ -499,40 +583,10 @@ plugin_exec(void *arg)
                        CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
                        CFRelease(timer);
                }
-       }
-
-       /*
-        * execute each plugins start() function which should initialize any
-        * variables, open any sessions with "configd", and register any needed
-        * notifications. Establishing initial information in the cache should
-        * be deferred until the prime() initialization function so that any
-        * plug-ins which want to receive a notification that the data has
-        * changed will have an opportunity to install a notification handler.
-        */
-       SCDLog(LOG_DEBUG, CFSTR("calling plugin start() functions"));
-       CFArrayApplyFunction(plugins,
-                            CFRangeMake(0, CFArrayGetCount(plugins)),
-                            bundleStart,
-                            NULL);
-
-       /*
-        * execute each plugins prime() function which should initialize any
-        * configuration information and/or state in the cache.
-        */
-       SCDLog(LOG_DEBUG, CFSTR("calling plugin prime() functions"));
-       CFArrayApplyFunction(plugins,
-                            CFRangeMake(0, CFArrayGetCount(plugins)),
-                            bundlePrime,
-                            NULL);
-
-       /*
-        * all plugins have been loaded and started.
-        */
-       CFRelease(plugins);
 
-       if (!SCDOptionGet(NULL, kSCDOptionDebug) && (arg == NULL)) {
-           /* synchronize with parent process */
-           kill(getppid(), SIGTERM);
+       if (_configd_fork) {
+               /* synchronize with parent process */
+               kill(getppid(), SIGTERM);
        }
 
        /*
@@ -542,9 +596,9 @@ plugin_exec(void *arg)
         * needs to wait and/or block at any time it should do so only in its a
         * private thread.
         */
-       SCDLog(LOG_DEBUG, CFSTR("starting plugin CFRunLoop"));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("starting plugin CFRunLoop"));
        CFRunLoopRun();
-       SCDLog(LOG_INFO, CFSTR("what, no more work for the \"configd\" plugins?"));
+       SCLog(_configd_verbose, LOG_INFO, CFSTR("what, no more work for the \"configd\" bundles?"));
        return NULL;
 }
 
@@ -555,14 +609,14 @@ plugin_init()
        pthread_attr_t  tattr;
        pthread_t       tid;
 
-       SCDLog(LOG_DEBUG, CFSTR("Starting thread for plug-ins..."));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Starting thread for plug-ins..."));
        pthread_attr_init(&tattr);
        pthread_attr_setscope(&tattr, PTHREAD_SCOPE_SYSTEM);
        pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
 //      pthread_attr_setstacksize(&tattr, 96 * 1024); // each thread gets a 96K stack
        pthread_create(&tid, &tattr, plugin_exec, NULL);
        pthread_attr_destroy(&tattr);
-       SCDLog(LOG_DEBUG, CFSTR("  thread id=0x%08x"), tid);
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("  thread id=0x%08x"), tid);
 
        return;
 }
index 072e3c1c8efdf7dcb97825ad568f0d5d34999be2..5097a4c4ffa0d9e60883b3ac145821c0901de221 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * May 26, 2000                Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #ifndef _S_PLUGIN_SUPPORT_H
 #define _S_PLUGIN_SUPPORT_H
 
@@ -27,8 +34,8 @@
 
 __BEGIN_DECLS
 
-void   plugin_init     __P(());
-void   plugin_exec     __P((void       *arg));
+void   plugin_init     ();
+void   plugin_exec     (void   *arg);
 
 __END_DECLS
 
index 88577cdebdc1480f1c17563b84f28b8f9288291c..0ded56d8c8078a5b1ca775aa78ef2249847e12e5 100644 (file)
  * @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 "configd_server.h"
 #include "session.h"
@@ -35,7 +45,7 @@ getSession(mach_port_t server)
        int     i;
 
        if (server == MACH_PORT_NULL) {
-               SCDLog(LOG_NOTICE, CFSTR("Excuse me, why is getSession() being called with an invalid port?"));
+               SCLog(_configd_verbose, LOG_NOTICE, CFSTR("Excuse me, why is getSession() being called with an invalid port?"));
                return NULL;
        }
 
@@ -48,9 +58,9 @@ getSession(mach_port_t server)
                                continue;
                        } else if (thisSession->key == server) {
                                return thisSession;     /* we've seen this server before */
-                       } else if ((thisSession->session != NULL) &&
-                                  (((SCDSessionPrivateRef)thisSession->session)->notifySignalTask == server)) {
-                                       return thisSession;
+                       } else if (thisSession->store &&
+                                  (((SCDynamicStorePrivateRef)thisSession->store)->notifySignalTask == server)) {
+                               return thisSession;
                        }
                }
        }
@@ -86,12 +96,12 @@ addSession(CFMachPortRef server)
                }
        }
 
-       SCDLog(LOG_DEBUG, CFSTR("Allocating new session for port %d"), CFMachPortGetPort(server));
+       SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Allocating new session for port %d"), CFMachPortGetPort(server));
        sessions[n] = malloc(sizeof(serverSession));
        sessions[n]->key                 = CFMachPortGetPort(server);
        sessions[n]->serverPort          = server;
        sessions[n]->serverRunLoopSource = NULL;
-       sessions[n]->session             = NULL;
+       sessions[n]->store               = NULL;
        sessions[n]->callerEUID          = 1;           /* not "root" */
        sessions[n]->callerEGID          = 1;           /* not "wheel" */
 
@@ -152,21 +162,21 @@ cleanupSession(mach_port_t server)
                         * Ensure that any changes made while we held the "lock"
                         * are discarded.
                         */
-                       if (SCDOptionGet(NULL, kSCDOptionIsLocked) &&
-                           SCDOptionGet(thisSession->session, kSCDOptionIsLocked)) {
+                       if ((storeLocked > 0) &&
+                           ((SCDynamicStorePrivateRef)thisSession->store)->locked) {
                                /*
-                                * swap cache and associated data which, after
+                                * swap store and associated data which, after
                                 * being closed, will result in the restoration
                                 * of the original pre-"locked" data.
                                 */
-                               _swapLockedCacheData();
+                               _swapLockedStoreData();
                        }
 
                        /*
                         * Close any open connections including cancelling any outstanding
                         * notification requests and releasing any locks.
                         */
-                       (void) _SCDClose(&thisSession->session);
+                       (void) __SCDynamicStoreClose(&thisSession->store);
 
                        /*
                         * Lastly, remove the session entry.
@@ -195,8 +205,8 @@ listSessions()
 
                fprintf(stderr, " %d", thisSession->key);
 
-               if (thisSession->session != NULL) {
-                       task_t  task = ((SCDSessionPrivateRef)thisSession->session)->notifySignalTask;
+               if (thisSession->store) {
+                       task_t  task = ((SCDynamicStorePrivateRef)thisSession->store)->notifySignalTask;
 
                        if (task != TASK_NULL) {
                               fprintf(stderr, "/%d", task);
index 9d431de77fbc7922088a5d1126917cc5320c73cc..023fd70614b95ccc3e8e3d36429051aa7f17f62c 100644 (file)
  * @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
+ */
+
 #ifndef _S_SESSION_H
 #define _S_SESSION_H
 
@@ -33,10 +43,10 @@ typedef struct {
 
        /* mach port associated with this session */
        CFMachPortRef           serverPort;
-       CFRunLoopSourceRef      serverRunLoopSource;    /* XXX CFMachPortInvalidate() doesn't work */
+       CFRunLoopSourceRef      serverRunLoopSource;
 
        /* data associated with this "open" session */
-       SCDSessionRef           session;
+       SCDynamicStoreRef       store;
 
        /* credentials associated with this "open" session */
        int                     callerEUID;
@@ -46,15 +56,15 @@ typedef struct {
 
 __BEGIN_DECLS
 
-serverSessionRef       getSession      __P((mach_port_t server));
+serverSessionRef       getSession      (mach_port_t    server);
 
-serverSessionRef       addSession      __P((CFMachPortRef server));
+serverSessionRef       addSession      (CFMachPortRef  server);
 
-void                   removeSession   __P((mach_port_t server));
+void                   removeSession   (mach_port_t    server);
 
-void                   cleanupSession  __P((mach_port_t server));
+void                   cleanupSession  (mach_port_t    server);
 
-void                   listSessions    __P(());
+void                   listSessions    ();
 
 __END_DECLS
 
index 64e8cfcbd00d3db4d371d0b849fbbe3cdf71000e..87fc31cc1ba0b5409b98c43ce7c3586bade9e081 100644 (file)
@@ -29,7 +29,8 @@ DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
 
-FRAMEWORKS = -framework SystemConfiguration
+NEXTSTEP_PB_CFLAGS = -DUSE_SYSTEMCONFIGURATION_PUBLIC_APIS
+FRAMEWORKS = -framework CoreFoundation -framework SystemConfiguration
 
 
 NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
index 5e4c7da368960cc3ba2c48e43591a23538a82b2e..32e4349ec06ba65db0f4e425749f8735b59ea544 100644 (file)
@@ -1,7 +1,7 @@
 {
     DYNAMIC_CODE_GEN = YES; 
     FILESTABLE = {
-        FRAMEWORKS = (SystemConfiguration.framework); 
+        FRAMEWORKS = (CoreFoundation.framework, SystemConfiguration.framework); 
         H_FILES = (); 
         OTHER_LINKED = (scselect.c); 
         OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, m.template, h.template); 
@@ -13,6 +13,7 @@
     LANGUAGE = English; 
     MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
     NEXTSTEP_BUILDTOOL = /usr/bin/gnumake; 
+    NEXTSTEP_COMPILEROPTIONS = "-DUSE_SYSTEMCONFIGURATION_PUBLIC_APIS"; 
     NEXTSTEP_INSTALLDIR = /usr/sbin; 
     NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
     NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
index b889b4fac05aa56d6d22c967eda3769ac014be36..7abf11edec5b52326e74d6c7592931af5ad882fe 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <SystemConfiguration/SystemConfiguration.h>
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * January 1, 2001             Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <unistd.h>
 
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+
 
-boolean_t      apply   = TRUE;
+Boolean        apply   = TRUE;
 
 
 void
 usage(const char *command)
 {
-       SCDLog(LOG_ERR, CFSTR("usage: %s [-n] new-set-name"), command);
+       SCPrint(TRUE, stderr, CFSTR("usage: %s [-n] new-set-name\n"), command);
        return;
 }
 
@@ -46,8 +58,7 @@ main(int argc, char **argv)
        CFStringRef             newSet          = NULL; /* set key */
        CFStringRef             newSetUDN       = NULL; /* user defined name */
        CFStringRef             prefix;
-       SCPStatus               status;
-       SCPSessionRef           session;
+       SCPreferencesRef        session;
        CFDictionaryRef         sets;
        CFIndex                 nSets;
        void                    **setKeys;
@@ -56,15 +67,14 @@ main(int argc, char **argv)
 
        /* process any arguments */
 
-       SCDOptionSet(NULL, kSCDOptionUseSyslog, FALSE);
-
        while ((opt = getopt(argc, argv, "dvn")) != -1)
                switch(opt) {
                case 'd':
-                       SCDOptionSet(NULL, kSCDOptionDebug, TRUE);
+                       _sc_debug = TRUE;
+                       _sc_log   = FALSE;      /* enable framework logging */
                        break;
                case 'v':
-                       SCDOptionSet(NULL, kSCDOptionVerbose, TRUE);
+                       _sc_verbose = TRUE;
                        break;
                case 'n':
                        apply = FALSE;
@@ -82,11 +92,9 @@ main(int argc, char **argv)
                        ? CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman)
                        : CFSTR("");
 
-       status = SCPOpen(&session, CFSTR("Select Set Command"), NULL, 0);
-       if (status != SCP_OK) {
-               SCDLog(LOG_ERR,
-                      CFSTR("SCPOpen() failed: %s"),
-                      SCPError(status));
+       session = SCPreferencesCreate(NULL, CFSTR("Select Set Command"), NULL);
+       if (!session) {
+               SCPrint(TRUE, stderr, CFSTR("SCPreferencesCreate() failed\n"));
                exit (1);
        }
 
@@ -100,7 +108,7 @@ main(int argc, char **argv)
 
                range = CFStringFind(str, CFSTR("/"), 0);
                if (range.location != kCFNotFound) {
-                       SCDLog(LOG_ERR, CFSTR("Set \"%@\" not available."), newSet);
+                       SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available\n."), newSet);
                        exit (1);
                }
 
@@ -108,32 +116,26 @@ main(int argc, char **argv)
                newSet = str;
        }
 
-       status = SCPGet(session, kSCPrefSets, (CFPropertyListRef *)&sets);
-       if (status != SCP_OK) {
-               SCDLog(LOG_ERR, CFSTR("SCDGet(...,%s,...) failed: %s"), SCPError(status));
+       sets = SCPreferencesGetValue(session, kSCPrefSets);
+       if (!sets) {
+               SCPrint(TRUE, stderr, CFSTR("SCPreferencesGetValue(...,%s,...) failed\n"));
                exit (1);
        }
 
-       status = SCPGet(session, kSCPrefCurrentSet, (CFPropertyListRef *)&current);
-       switch (status) {
-               case SCP_OK :
-                       if (CFStringHasPrefix(current, prefix)) {
-                               CFMutableStringRef      tmp;
-
-                               tmp = CFStringCreateMutableCopy(NULL, 0, current);
-                               CFStringDelete(tmp, CFRangeMake(0, CFStringGetLength(prefix)));
-                               current = tmp;
-                       } else {
-                               currentMatched = -1;    /* not prefixed */
-                       }
-                       break;
-               case SCP_NOKEY :
-                       current = CFSTR("");
-                       currentMatched = -2;    /* not defined */
-                       break;
-               default :
-                       SCDLog(LOG_ERR, CFSTR("SCDGet(...,%s,...) failed: %s"), SCPError(status));
-                       exit (1);
+       current = SCPreferencesGetValue(session, kSCPrefCurrentSet);
+       if (current) {
+               if (CFStringHasPrefix(current, prefix)) {
+                       CFMutableStringRef      tmp;
+
+                       tmp = CFStringCreateMutableCopy(NULL, 0, current);
+                       CFStringDelete(tmp, CFRangeMake(0, CFStringGetLength(prefix)));
+                       current = tmp;
+               } else {
+                       currentMatched = -1;    /* not prefixed */
+               }
+       } else {
+               current = CFSTR("");
+               currentMatched = -2;    /* not defined */
        }
 
        nSets = CFDictionaryGetCount(sets);
@@ -174,23 +176,23 @@ main(int argc, char **argv)
        }
 
        if (argc == 2) {
-               SCDLog(LOG_ERR, CFSTR("Set \"%@\" not available."), newSet);
+               SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available.\n"), newSet);
        } else {
                usage(command);
        }
 
-       SCDLog(LOG_ERR, CFSTR(""));
-       SCDLog(LOG_ERR,
-              CFSTR("Defined sets include:%s"),
-              (currentMatched > 0) ? " (* == current set)" : "");
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr,
+               CFSTR("Defined sets include:%s\n"),
+               (currentMatched > 0) ? " (* == current set)" : "");
 
        for (i=0; i<nSets; i++) {
                CFStringRef     key  = (CFStringRef)    setKeys[i];
                CFDictionaryRef dict = (CFDictionaryRef)setVals[i];
                CFStringRef     udn  = CFDictionaryGetValue(dict, kSCPropUserDefinedName);
 
-               SCDLog(LOG_ERR,
-                       CFSTR(" %s %@\t(%@)"),
+               SCPrint(TRUE, stderr,
+                       CFSTR(" %s %@\t(%@)\n"),
                        ((currentMatched > 0) && CFEqual(key, current)) ? "*" : " ",
                        key,
                        udn ? udn : CFSTR(""));
@@ -198,16 +200,13 @@ main(int argc, char **argv)
 
        switch (currentMatched) {
                case -2 :
-                       SCDLog(LOG_ERR, CFSTR(""));
-                       SCDLog(LOG_ERR, CFSTR("CurrentSet not defined"));
+                       SCPrint(TRUE, stderr, CFSTR("\nCurrentSet not defined.\n"));
                        break;
                case -1 :
-                       SCDLog(LOG_ERR, CFSTR(""));
-                       SCDLog(LOG_ERR, CFSTR("CurrentSet \"%@\" may not be valid"), current);
+                       SCPrint(TRUE, stderr, CFSTR("\nCurrentSet \"%@\" may not be valid\n"), current);
                        break;
                case  0 :
-                       SCDLog(LOG_ERR, CFSTR(""));
-                       SCDLog(LOG_ERR, CFSTR("CurrentSet \"%@\" not valid"), current);
+                       SCPrint(TRUE, stderr, CFSTR("\nCurrentSet \"%@\" not valid\n"), current);
                        break;
                default :
                        break;
@@ -217,38 +216,30 @@ main(int argc, char **argv)
 
     found :
 
-       status = SCPSet(session, kSCPrefCurrentSet, current);
-       if (status != SCP_OK) {
-               SCDLog(LOG_ERR,
-                       CFSTR("SCDSet(...,%@,%@) failed: %s"),
+       if (!SCPreferencesSetValue(session, kSCPrefCurrentSet, current)) {
+               SCPrint(TRUE, stderr,
+                       CFSTR("SCPreferencesSetValue(...,%@,%@) failed\n"),
                        kSCPrefCurrentSet,
-                       current,
-                       SCPError(status));
+                       current);
                exit (1);
        }
 
-       status = SCPCommit(session);
-       if (status != SCP_OK) {
-               SCDLog(LOG_ERR, CFSTR("SCPCommit() failed: %s"), SCPError(status));
+       if (!SCPreferencesCommitChanges(session)) {
+               SCPrint(TRUE, stderr, CFSTR("SCPreferencesCommitChanges() failed\n"));
                exit (1);
        }
 
        if (apply) {
-               status = SCPApply(session);
-               if (status != SCP_OK) {
-                       SCDLog(LOG_ERR, CFSTR("SCPApply() failed: %s"), SCPError(status));
+               if (!SCPreferencesApplyChanges(session)) {
+                       SCPrint(TRUE, stderr, CFSTR("SCPreferencesApplyChanges() failed\n"));
                        exit (1);
                }
        }
 
-       status = SCPClose(&session);
-       if (status != SCP_OK) {
-               SCDLog(LOG_ERR, CFSTR("SCPClose() failed: %s"), SCPError(status));
-               exit (1);
-       }
+       CFRelease(session);
 
-       SCDLog(LOG_NOTICE,
-               CFSTR("%@ updated to %@ (%@)"),
+       SCPrint(TRUE, stdout,
+               CFSTR("%@ updated to %@ (%@)\n"),
                kSCPrefCurrentSet,
                newSet,
                newSetUDN ? newSetUDN : CFSTR(""));
index c23c5f1d74186b9a38d92ef7bc0f3cac6f7c86e4..4daf58e29215a56ecf0c174fd23880a954377487 100644 (file)
@@ -13,13 +13,13 @@ PROJECTVERSION = 2.8
 PROJECT_TYPE = Tool
 
 HFILES = scutil.h commands.h dictionary.h session.h cache.h notify.h\
-        tests.h
+         tests.h
 
 CFILES = scutil.c commands.c dictionary.c session.c cache.c notify.c\
-        tests.c
+         tests.c
 
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\
-           h.template
+            h.template
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
@@ -28,12 +28,13 @@ MAKEFILE = tool.make
 NEXTSTEP_INSTALLDIR = /usr/sbin
 WINDOWS_INSTALLDIR = /Library/Executables
 PDO_UNIX_INSTALLDIR = /bin
-LIBS =
+LIBS = 
 DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
 
-FRAMEWORKS = -framework SystemConfiguration
+NEXTSTEP_PB_CFLAGS = -DUSE_SYSTEMCONFIGURATION_PUBLIC_APIS
+FRAMEWORKS = -framework CoreFoundation -framework SystemConfiguration
 
 
 NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
index c1ceca4a733981d1819d35652945d8adf43d8fd2..e5060626d25d4f8590739c27e87376a2017981d2 100644 (file)
@@ -1,28 +1,32 @@
 {
-    DYNAMIC_CODE_GEN = YES;
+    DYNAMIC_CODE_GEN = YES; 
     FILESTABLE = {
-       FRAMEWORKS = (SystemConfiguration.framework);
-       FRAMEWORKSEARCH = ();
-       H_FILES = (scutil.h, commands.h, dictionary.h, session.h, cache.h, notify.h, tests.h);
-       OTHER_LINKED = (scutil.c, commands.c, dictionary.c, session.c, cache.c, notify.c, tests.c);
-       OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, m.template, h.template);
-       SUBPROJECTS = ();
-    };
-    LANGUAGE = English;
-    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles";
-    NEXTSTEP_BUILDTOOL = /usr/bin/gnumake;
-    NEXTSTEP_INSTALLDIR = /usr/sbin;
-    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac;
-    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc;
-    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make;
-    PDO_UNIX_INSTALLDIR = /bin;
-    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac";
-    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc";
-    PROJECTNAME = scutil;
-    PROJECTTYPE = Tool;
-    PROJECTVERSION = 2.8;
-    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make;
-    WINDOWS_INSTALLDIR = /Library/Executables;
-    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe";
-    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc";
+        FRAMEWORKS = (CoreFoundation.framework, SystemConfiguration.framework); 
+        FRAMEWORKSEARCH = (); 
+        H_FILES = (scutil.h, commands.h, dictionary.h, session.h, cache.h, notify.h, tests.h); 
+        OTHER_LINKED = (scutil.c, commands.c, dictionary.c, session.c, cache.c, notify.c, tests.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, m.template, h.template); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (); 
+        SUBPROJECTS = (); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /usr/bin/gnumake; 
+    NEXTSTEP_COMPILEROPTIONS = "-DUSE_SYSTEMCONFIGURATION_PUBLIC_APIS"; 
+    NEXTSTEP_INSTALLDIR = /usr/sbin; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_INSTALLDIR = /bin; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = scutil; 
+    PROJECTTYPE = Tool; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_INSTALLDIR = /Library/Executables; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
 }
index 759959bad742fb896445315caa6bc1778ef1b829..3739acb0cfbf650eb655083c59d31bb335ee4190 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <sys/types.h>
 
 #include "scutil.h"
 
+
+static CFComparisonResult
+sort_keys(const void *p1, const void *p2, void *context) {
+       CFStringRef key1 = (CFStringRef)p1;
+       CFStringRef key2 = (CFStringRef)p2;
+       return CFStringCompare(key1, key2, 0);
+}
+
+
 void
 do_list(int argc, char **argv)
 {
-       CFStringRef             key;
-       int                     regexOptions = 0;
-       SCDStatus               status;
+       int                     i;
+       CFStringRef             pattern;
        CFArrayRef              list;
        CFIndex                 listCnt;
-       int                     i;
+       CFMutableArrayRef       sortedList;
 
-       key = CFStringCreateWithCString(NULL,
-                                       (argc >= 1) ? argv[0] : "",
-                                       kCFStringEncodingMacRoman);
+       pattern = CFStringCreateWithCString(NULL,
+                                           (argc >= 1) ? argv[0] : ".*",
+                                           kCFStringEncodingMacRoman);
 
-       if (argc == 2)
-               regexOptions = kSCDRegexKey;
-
-       status = SCDList(session, key, regexOptions, &list);
-       CFRelease(key);
-       if (status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDList: %s"), SCDError(status));
+       list = SCDynamicStoreCopyKeyList(store, pattern);
+       CFRelease(pattern);
+       if (!list) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                return;
        }
 
        listCnt = CFArrayGetCount(list);
+       sortedList = CFArrayCreateMutableCopy(NULL, listCnt, list);
+       CFRelease(list);
+       CFArraySortValues(sortedList,
+                         CFRangeMake(0, listCnt),
+                         sort_keys,
+                         NULL);
+
        if (listCnt > 0) {
                for (i=0; i<listCnt; i++) {
-                       SCDLog(LOG_NOTICE, CFSTR("  subKey [%d] = %@"), i, CFArrayGetValueAtIndex(list, i));
+                       SCPrint(TRUE,
+                               stdout,
+                               CFSTR("  subKey [%d] = %@\n"),
+                               i,
+                               CFArrayGetValueAtIndex(sortedList, i));
                }
        } else {
-               SCDLog(LOG_NOTICE, CFSTR("  no subKey's"));
+               SCPrint(TRUE, stdout, CFSTR("  no subKey's.\n"));
        }
-       CFRelease(list);
+       CFRelease(sortedList);
 
        return;
 }
@@ -66,19 +92,16 @@ void
 do_add(int argc, char **argv)
 {
        CFStringRef     key;
-       SCDStatus       status;
 
        key    = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
 
        if (argc < 2) {
-               status = SCDAdd(session, key, data);
-               if (status != SCD_OK) {
-                       SCDLog(LOG_INFO, CFSTR("SCDAdd: %s"), SCDError(status));
+               if (!SCDynamicStoreAddValue(store, key, value)) {
+                       SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                }
        } else {
-               status = SCDAddSession(session, key, data);
-               if (status != SCD_OK) {
-                       SCDLog(LOG_INFO, CFSTR("SCDAddSession: %s"), SCDError(status));
+               if (!SCDynamicStoreAddTemporaryValue(store, key, value)) {
+                       SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                }
        }
 
@@ -90,25 +113,21 @@ do_add(int argc, char **argv)
 void
 do_get(int argc, char **argv)
 {
-       SCDStatus       status;
-       CFStringRef     key;
-       SCDHandleRef    newData = NULL;
+       CFStringRef             key;
+       CFPropertyListRef       newValue;
 
-       key    = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
-       status = SCDGet(session, key, &newData);
+       key      = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
+       newValue = SCDynamicStoreCopyValue(store, key);
        CFRelease(key);
-       if (status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDGet: %s"), SCDError(status));
-               if (newData != NULL) {
-                       SCDHandleRelease(newData);      /* toss the handle from SCDGet() */
-               }
+       if (!newValue) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                return;
        }
 
-       if (data != NULL) {
-               SCDHandleRelease(data);         /* we got a new handle from SCDGet() */
+       if (value != NULL) {
+               CFRelease(value);               /* we have new information, release the old */
        }
-       data = newData;
+       value = newValue;
 
        return;
 }
@@ -117,15 +136,33 @@ do_get(int argc, char **argv)
 void
 do_set(int argc, char **argv)
 {
-       SCDStatus       status;
        CFStringRef     key;
 
        key    = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
-       status = SCDSet(session, key, data);
+       if (!SCDynamicStoreSetValue(store, key, value)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
+       }
+       CFRelease(key);
+       return;
+}
+
+
+void
+do_show(int argc, char **argv)
+{
+       CFStringRef             key;
+       CFPropertyListRef       newValue;
+
+       key      = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
+       newValue = SCDynamicStoreCopyValue(store, key);
        CFRelease(key);
-       if (status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDSet: %s"), SCDError(status));
+       if (!newValue) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
+               return;
        }
+
+       SCPrint(TRUE, stdout, CFSTR("%@\n"), newValue);
+       CFRelease(newValue);
        return;
 }
 
@@ -133,15 +170,27 @@ do_set(int argc, char **argv)
 void
 do_remove(int argc, char **argv)
 {
-       SCDStatus       status;
        CFStringRef     key;
 
        key    = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
-       status = SCDRemove(session, key);
+       if (!SCDynamicStoreRemoveValue(store, key)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
+       }
        CFRelease(key);
-       if (status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDRemove: %s"), SCDError(status));
+       return;
+}
+
+
+void
+do_notify(int argc, char **argv)
+{
+       CFStringRef     key;
+
+       key    = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
+       if (!SCDynamicStoreNotifyValue(store, key)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
        }
+       CFRelease(key);
        return;
 }
 
@@ -149,14 +198,12 @@ do_remove(int argc, char **argv)
 void
 do_touch(int argc, char **argv)
 {
-       SCDStatus       status;
        CFStringRef     key;
 
        key    = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
-       status = SCDTouch(session, key);
-       CFRelease(key);
-       if (status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDTouch: %s"), SCDError(status));
+       if (!SCDynamicStoreTouchValue(store, key)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
        }
+       CFRelease(key);
        return;
 }
index 3b024262a4e4abffaba2c16a56448b74169e4058..3c2d0cfa7bc52edd27ab7c253b996b1c28195367 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #ifndef _CACHE_H
 #define _CACHE_H
 
 
 __BEGIN_DECLS
 
-void   do_list                 __P((int argc, char **argv));
-void   do_add                  __P((int argc, char **argv));
-void   do_get                  __P((int argc, char **argv));
-void   do_set                  __P((int argc, char **argv));
-void   do_remove               __P((int argc, char **argv));
-void   do_touch                __P((int argc, char **argv));
+void   do_list                 (int argc, char **argv);
+void   do_add                  (int argc, char **argv);
+void   do_get                  (int argc, char **argv);
+void   do_set                  (int argc, char **argv);
+void   do_show                 (int argc, char **argv);
+void   do_remove               (int argc, char **argv);
+void   do_notify               (int argc, char **argv);
+void   do_touch                (int argc, char **argv);
 
 __END_DECLS
 
index 501b23fa9261e6133780a6539d6dbdc3be4afabb..482341b7db1ec666fbb65603c2161b0a1de11623 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <stdio.h>
 #include <string.h>
 #include <sys/errno.h>
 #include "notify.h"
 #include "tests.h"
 
-#include "SCDPrivate.h"
+#include <SystemConfiguration/SCPrivate.h>
+
 
 const cmdInfo commands[] = {
-       /* cmd          minArgs maxArgs func                                    */
-       /*      usage                                                           */
+       /* cmd          minArgs maxArgs func                    group   ctype                   */
+       /*      usage                                                                           */
 
-       { "help",       0,      0,      do_help,                0,
-               " help                          : list available commands"                      },
+       { "help",       0,      0,      do_help,                0,      0,
+               " help                          : list available commands"                      },
 
-       { "f.read",     1,      1,      do_readFile,            0,
-               " f.read file                   : process commands from file"                   },
+       { "f.read",     1,      1,      do_readFile,            0,      0,
+               " f.read file                   : process commands from file"                   },
 
        /* local dictionary manipulation commands */
 
-       { "d.init",     0,      0,      do_dictInit,            1,
-               " d.init                        : initialize (empty) dictionary"                },
+       { "d.init",     0,      0,      do_dictInit,            1,      0,
+               " d.init                        : initialize (empty) dictionary"                },
 
-       { "d.show",     0,      0,      do_dictShow,            1,
-               " d.show                        : show dictionary contents"                     },
+       { "d.show",     0,      0,      do_dictShow,            1,      0,
+               " d.show                        : show dictionary contents"                     },
 
-       { "d.add",      2,      101,    do_dictSetKey,          1,
-               " d.add key [*#?] val [v2 ...]  : add information to dictionary\n"
+       { "d.add",      2,      101,    do_dictSetKey,          1,      0,
+               " d.add key [*#?] val [v2 ...]  : add information to dictionary\n"
                "       (*=array, #=number, ?=boolean)"                         },
 
-       { "d.remove",   1,      1,      do_dictRemoveKey,               1,
-               " d.remove key                  : remove key from dictionary"                   },
+       { "d.remove",   1,      1,      do_dictRemoveKey,       1,      0,
+               " d.remove key                  : remove key from dictionary"                   },
 
        /* data store manipulation commands */
 
-       { "open",       0,      0,      do_open,                2,
-               " open                          : open a session with \"configd\""              },
+       { "open",       0,      0,      do_open,                2,      0,
+               " open                          : open a session with \"configd\""              },
+
+       { "close",      0,      0,      do_close,               2,      0,
+               " close                         : close current \"configd\" session"            },
+
+       { "lock",       0,      0,      do_lock,                3,      1,
+               " lock                          : secures write access to data store"           },
 
-       { "close",      0,      0,      do_close,               2,
-               " close                         : close current \"configd\" session"            },
+       { "unlock",     0,      0,      do_unlock,              3,      1,
+               " unlock                        : secures write access to data store"           },
 
-       { "lock",       0,      0,      do_lock,                3,
-               " lock                          : secures write access to data store"           },
+       { "list",       0,      2,      do_list,                4,      0,
+               " list [pattern]                : list keys in data store"                      },
 
-       { "unlock",     0,      0,      do_unlock,              3,
-               " unlock                        : secures write access to data store"           },
+       { "add",        1,      2,      do_add,                 4,      0,
+               " add key [\"temporary\"]         : add key in data store w/current dict"               },
 
-       { "list",       0,      2,      do_list,                4,
-               " list [prefix] [regex]         : list keys in data store"                      },
+       { "get",        1,      1,      do_get,                 4,      0,
+               " get key                       : get dict from data store w/key"               },
 
-       { "add",        1,      2,      do_add,                 4,
-               " add key [session]             : add key in data store w/current dict"         },
+       { "set",        1,      1,      do_set,                 4,      0,
+               " set key                       : set key in data store w/current dict"         },
 
-       { "get",        1,      1,      do_get,                 4,
-               " get key                       : get dict from data store w/key"               },
+       { "show",       1,      1,      do_show,                4,      1,
+               " show key                      : show dict in data store w/key"                },
 
-       { "set",        1,      1,      do_set,                 4,
-               " set key                       : set key in data store w/current dict"         },
+       { "remove",     1,      1,      do_remove,              4,      0,
+               " remove key                    : remove key from data store"                   },
 
-       { "remove",     1,      1,      do_remove,              4,
-               " remove key                    : remove key from data store"                   },
+       { "notify",     1,      1,      do_notify,              4,      0,
+               " notify key                    : notify key in data store"                     },
 
-       { "touch",      1,      1,      do_touch,               4,
-               " touch key                     : touch key in data store"                      },
+       { "touch",      1,      1,      do_touch,               4,      1,
+               " touch key                     : touch key in data store"                      },
 
-       { "n.list",     0,      1,      do_notify_list,         5,
-               " n.list [regex]                : list notification keys"                       },
+       { "n.list",     0,      1,      do_notify_list,         5,      0,
+               " n.list [\"pattern\"]            : list notification keys"                     },
 
-       { "n.add",      1,      2,      do_notify_add,          5,
-               " n.add key [regex]             : add notification key"                         },
+       { "n.add",      1,      2,      do_notify_add,          5,      0,
+               " n.add key [\"pattern\"]         : add notification key"                               },
 
-       { "n.remove",   1,      2,      do_notify_remove,       5,
-               " n.remove key [regex]          : remove notification key"                      },
+       { "n.remove",   1,      2,      do_notify_remove,       5,      0,
+               " n.remove key [\"pattern\"]      : remove notification key"                    },
 
-       { "n.changes",  0,      0,      do_notify_changes,      5,
-               " n.changes                     : list changed keys"                            },
+       { "n.changes",  0,      0,      do_notify_changes,      5,      0,
+               " n.changes                     : list changed keys"                            },
 
-       { "n.wait",     0,      0,      do_notify_wait,         5,
-               " n.wait                        : wait for changes"                             },
+       { "n.watch",    0,      1,      do_notify_watch,        5,      0,
+               " n.watch [verbose]             : watch for changes"                            },
 
-       { "n.watch",    0,      1,      do_notify_callback,     5,
-               " n.watch [verbose]             : watch for changes"                            },
+       { "n.wait",     0,      0,      do_notify_wait,         5,      2,
+               " n.wait                        : wait for changes"                             },
 
-       { "n.signal",   1,      2,      do_notify_signal,       5,
-               " n.signal sig [pid]            : signal changes"                               },
+       { "n.callback", 0,      1,      do_notify_callback,     5,      2,
+               " n.callback [\"verbose\"]        : watch for changes"                          },
 
-       { "n.file",     0,      1,      do_notify_file,         5,
-               " n.file [identifier]           : watch for changes via file"                   },
+       { "n.signal",   1,      2,      do_notify_signal,       5,      2,
+               " n.signal sig [pid]            : signal changes"                               },
 
-       { "n.cancel",   0,      1,      do_notify_cancel,       5,
-               " n.cancel                      : cancel notification requests"                 },
+       { "n.file",     0,      1,      do_notify_file,         5,      2,
+               " n.file [identifier]           : watch for changes via file"                   },
 
-       { "snapshot",   0,      0,      do_snapshot,            9,
-               " snapshot                      : save snapshot of cache and session data"      },
+       { "n.cancel",   0,      1,      do_notify_cancel,       5,      0,
+               " n.cancel                      : cancel notification requests"                 },
 
-#ifdef DEBUG
-       { "t.ocleak",   0,      1,      test_openCloseLeak,     9,
-               " t.ocleak [#]                  : test for leaks (open/close)"                  },
-#endif /* DEBUG */
+       { "snapshot",   0,      0,      do_snapshot,            9,      2,
+               " snapshot                      : save snapshot of store and session data"      },
 };
 
 const int nCommands = (sizeof(commands)/sizeof(cmdInfo));
 
+Boolean enablePrivateAPI       = FALSE;
+
 
 void
 do_command(int argc, char **argv)
@@ -137,14 +154,18 @@ do_command(int argc, char **argv)
        char    *cmd = argv[0];
 
        for (i=0; i<nCommands; i++) {
+               if ((commands[i].ctype > 1) && !enablePrivateAPI)  {
+                       continue;       /* if "private" API and access has not been enabled */
+               }
+
                if (strcasecmp(cmd, commands[i].cmd) == 0) {
                        --argc;
                        argv++;
                        if (argc < commands[i].minArgs) {
-                               SCDLog(LOG_INFO, CFSTR("%s: too few arguments"), cmd);
+                               SCPrint(TRUE, stdout, CFSTR("%s: too few arguments\n"), cmd);
                                return;
                        } else if (argc > commands[i].maxArgs) {
-                               SCDLog(LOG_INFO, CFSTR("%s: too many arguments"), cmd);
+                               SCPrint(TRUE, stdout, CFSTR("%s: too many arguments\n"), cmd);
                                return;
                        }
                        commands[i].func(argc, argv);
@@ -152,7 +173,7 @@ do_command(int argc, char **argv)
                }
        }
 
-       SCDLog(LOG_INFO, CFSTR("%s: unknown, type \"help\" for command info"), cmd);
+       SCPrint(TRUE, stdout, CFSTR("%s: unknown, type \"help\" for command info\n"), cmd);
        return;
 }
 
@@ -163,16 +184,22 @@ do_help(int argc, char **argv)
        int     g = -1;         /* current group */
        int     i;
 
-       SCDLog(LOG_NOTICE, CFSTR(""));
-       SCDLog(LOG_NOTICE, CFSTR("Available commands:"));
+       SCPrint(TRUE, stdout, CFSTR("\nAvailable commands:\n"));
        for (i=0; i<nCommands; i++) {
+               if ((commands[i].ctype > 0) && !enablePrivateAPI)  {
+                       continue;       /* if "private" API and access has not been enabled */
+               }
+
+               /* check if this is a new command group */
                if (g != commands[i].group) {
-                       SCDLog(LOG_NOTICE, CFSTR(""));
+                       SCPrint(TRUE, stdout, CFSTR("\n"));
                        g = commands[i].group;
                }
-               SCDLog(LOG_NOTICE, CFSTR("%s"), commands[i].usage);
+
+               /* display the command */
+               SCPrint(TRUE, stdout, CFSTR("%s\n"), commands[i].usage);
        }
-       SCDLog(LOG_NOTICE, CFSTR(""));
+       SCPrint(TRUE, stdout, CFSTR("\n"));
 
        return;
 }
@@ -181,62 +208,52 @@ do_help(int argc, char **argv)
 void
 do_readFile(int argc, char **argv)
 {
-       FILE            *fp = fopen(argv[0], "r");
-       boolean_t       ok;
+       CFSocketContext         context;
+       FILE                    *fp = fopen(argv[0], "r");
+       CFSocketRef             in;
+       CFRunLoopSourceRef      rls;
 
        if (fp == NULL) {
-               SCDLog(LOG_INFO, CFSTR("f.read: could not open file (%s)."), strerror(errno));
+               SCPrint(TRUE, stdout, CFSTR("f.read: could not open file (%s).\n"), strerror(errno));
                return;
        }
 
        /* open file, increase nesting level */
-       SCDLog(LOG_DEBUG, CFSTR("f.read: reading file (%s)."), argv[0]);
+       SCPrint(TRUE, stdout, CFSTR("f.read: reading file (%s).\n"), argv[0]);
        nesting++;
 
-       if (SCDOptionGet(NULL, kSCDOptionUseCFRunLoop)) {
-               CFSocketRef             in;
-               CFSocketContext         context = { 0, fp, NULL, NULL, NULL };
-               CFRunLoopSourceRef      rls;
-
-               /* create a "socket" reference with the file descriptor associated with stdin */
-               in  = CFSocketCreateWithNative(NULL,
-                                              fileno(fp),
-                                              kCFSocketReadCallBack,
-                                              runLoopProcessInput,
-                                              &context);
-
-               /* Create and add a run loop source for the file descriptor */
-               rls = CFSocketCreateRunLoopSource(NULL, in, nesting);
-
-               /*
-                * Remove the current input file from the run loop sources. We
-                * will reactivate the current input file source when we are
-                * finished reading data from the new file.
-                */
-               CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
-                                     (CFRunLoopSourceRef) CFArrayGetValueAtIndex(sources, 0),
-                                     kCFRunLoopDefaultMode);
-
-               /* keep track of this new source */
-               CFArrayInsertValueAtIndex(sources, 0, rls);
-
-               /* add this source to the run loop */
-               CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
-
-               CFRelease(rls);
-               CFRelease(in);
-       } else {
-               do {
-                       /* debug information, diagnostics */
-                       _showMachPortStatus();
-
-                       /* process command */
-                       ok = process_line(fp);
-               } while (ok);
-
-               /* decrement the nesting level */
-               nesting--;
-       }
+       /* create a "socket" reference with the file descriptor associated with stdin */
+       context.version         = 0;
+       context.info            = fp;
+       context.retain          = NULL;
+       context.release         = NULL;
+       context.copyDescription = NULL;
+       in  = CFSocketCreateWithNative(NULL,
+                                      fileno(fp),
+                                      kCFSocketReadCallBack,
+                                      runLoopProcessInput,
+                                      &context);
+
+       /* Create and add a run loop source for the file descriptor */
+       rls = CFSocketCreateRunLoopSource(NULL, in, nesting);
+
+       /*
+        * Remove the current input file from the run loop sources. We
+        * will reactivate the current input file source when we are
+        * finished reading data from the new file.
+        */
+       CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
+                             (CFRunLoopSourceRef) CFArrayGetValueAtIndex(sources, 0),
+                             kCFRunLoopDefaultMode);
+
+       /* keep track of this new source */
+       CFArrayInsertValueAtIndex(sources, 0, rls);
+
+       /* add this source to the run loop */
+       CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+
+       CFRelease(rls);
+       CFRelease(in);
 
        return;
 }
index c36a766da63c0c4cae91d63e8e0dc1b58a0ec78a..00b7ecd93065a81923ecab188e5db77c624e38eb 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #ifndef _COMMANDS_H
 #define _COMMANDS_H
 
@@ -31,17 +41,19 @@ typedef struct {
        int     maxArgs;
        void    (*func)();
        int     group;
+       int     ctype;  /* 0==normal, 1==limited, 2==private */
        char    *usage;
 } cmdInfo;
 
 extern const cmdInfo   commands[];
 extern const int       nCommands;
+extern Boolean         enablePrivateAPI;
 
 __BEGIN_DECLS
 
-void   do_command              __P((int argc, char **argv));
-void   do_help                 __P((int argc, char **argv));
-void   do_readFile             __P((int argc, char **argv));
+void   do_command              (int argc, char **argv);
+void   do_help                 (int argc, char **argv);
+void   do_readFile             (int argc, char **argv);
 
 __END_DECLS
 
index 35371d4491fb36712085dd264aed53f7443f4ad2..55f5660581ec65f24aefe1643a861923751ec609 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include "scutil.h"
 
 
 void
 do_dictInit(int argc, char **argv)
 {
-       CFMutableDictionaryRef  dict;
-
-       if (data != NULL) {
-               SCDHandleRelease(data);
+       if (value != NULL) {
+               CFRelease(value);
        }
 
-       data = SCDHandleInit();
-       dict = CFDictionaryCreateMutable(NULL
+       value = CFDictionaryCreateMutable(NULL
                                         ,0
                                         ,&kCFTypeDictionaryKeyCallBacks
                                         ,&kCFTypeDictionaryValueCallBacks
                                         );
-       SCDHandleSetData(data, dict);
-       CFRelease(dict);
 
        return;
 }
@@ -52,18 +57,12 @@ do_dictInit(int argc, char **argv)
 void
 do_dictShow(int argc, char **argv)
 {
-       int                     instance;
-       CFPropertyListRef       store;
-
-       if (data == NULL) {
-               SCDLog(LOG_INFO, CFSTR("d.show: dictionary must be initialized."));
+       if (value == NULL) {
+               SCPrint(TRUE, stdout, CFSTR("d.show: dictionary must be initialized.\n"));
                return;
        }
 
-       instance = SCDHandleGetInstance(data);
-       store    = SCDHandleGetData(data);
-
-       SCDLog(LOG_NOTICE, CFSTR("dict (instance = %d) = \n\t%@"), instance, store);
+       SCPrint(TRUE, stdout, CFSTR("%@\n"), value);
 
        return;
 }
@@ -72,25 +71,26 @@ do_dictShow(int argc, char **argv)
 void
 do_dictSetKey(int argc, char **argv)
 {
-       CFPropertyListRef       store;
-       CFStringRef             key;
-       CFPropertyListRef       value     = NULL;
        CFMutableArrayRef       array     = NULL;
-       boolean_t               doArray   = FALSE;
-       boolean_t               doBoolean = FALSE;
-       boolean_t               doNumeric = FALSE;
+       Boolean                 doArray   = FALSE;
+       Boolean                 doBoolean = FALSE;
+       Boolean                 doNumeric = FALSE;
+       CFStringRef             key;
+       CFTypeRef               val;
 
-       if (data == NULL) {
-               SCDLog(LOG_INFO, CFSTR("d.add: dictionary must be initialized."));
+       if (value == NULL) {
+               SCPrint(TRUE, stdout, CFSTR("d.add: dictionary must be initialized.\n"));
                return;
        }
 
-       store = SCDHandleGetData(data);
-       if (CFGetTypeID(store) != CFDictionaryGetTypeID()) {
-               SCDLog(LOG_INFO, CFSTR("d.add: data (fetched from configuration server) is not a dictionary"));
+       if (CFGetTypeID(value) != CFDictionaryGetTypeID()) {
+               SCPrint(TRUE, stdout, CFSTR("d.add: data (fetched from configuration server) is not a dictionary.\n"));
                return;
        }
 
+       val = CFDictionaryCreateMutableCopy(NULL, 0, value);
+       CFRelease(value);
+       value = val;
 
        key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
        argv++; argc--;
@@ -117,7 +117,7 @@ do_dictSetKey(int argc, char **argv)
        if (argc > 1) {
                doArray = TRUE;
        } else if (!doArray && (argc == 0)) {
-               SCDLog(LOG_INFO, CFSTR("d.add: no values"));
+               SCPrint(TRUE, stdout, CFSTR("d.add: no values.\n"));
                return;
        }
 
@@ -132,15 +132,15 @@ do_dictSetKey(int argc, char **argv)
                                    (strcasecmp(argv[0], "yes" ) == 0) ||
                                    (strcasecmp(argv[0], "y"   ) == 0) ||
                                    (strcmp    (argv[0], "1"   ) == 0)) {
-                               value = CFRetain(kCFBooleanTrue);
+                               val = CFRetain(kCFBooleanTrue);
                        } else if ((strcasecmp(argv[0], "false") == 0) ||
                                   (strcasecmp(argv[0], "f"    ) == 0) ||
                                   (strcasecmp(argv[0], "no"   ) == 0) ||
                                   (strcasecmp(argv[0], "n"    ) == 0) ||
                                   (strcmp    (argv[0], "0"    ) == 0)) {
-                               value = CFRetain(kCFBooleanFalse);
+                               val = CFRetain(kCFBooleanFalse);
                        } else {
-                               SCDLog(LOG_INFO, CFSTR("d.add: invalid data"));
+                               SCPrint(TRUE, stdout, CFSTR("d.add: invalid data.\n"));
                                if (doArray) {
                                        CFRelease(array);
                                }
@@ -150,31 +150,31 @@ do_dictSetKey(int argc, char **argv)
                        int     intValue;
 
                        if (sscanf(argv[0], "%d", &intValue) == 1) {
-                               value = CFNumberCreate(NULL, kCFNumberIntType, &intValue);
+                               val = CFNumberCreate(NULL, kCFNumberIntType, &intValue);
                        } else {
-                               SCDLog(LOG_INFO, CFSTR("d.add: invalid data"));
+                               SCPrint(TRUE, stdout, CFSTR("d.add: invalid data.\n"));
                                if (doArray) {
                                        CFRelease(array);
                                }
                                return;
                        }
                } else {
-                       value = (CFPropertyListRef)CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
+                       val = (CFPropertyListRef)CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
                }
 
                if (doArray) {
-                       CFArrayAppendValue(array, value);
+                       CFArrayAppendValue(array, val);
                }
 
                argv++; argc--;
        }
 
        if (doArray) {
-               value = array;
+               val = array;
        }
 
-       CFDictionarySetValue((CFMutableDictionaryRef)store, key, value);
-       CFRelease(value);
+       CFDictionarySetValue((CFMutableDictionaryRef)value, key, val);
+       CFRelease(val);
        CFRelease(key);
 
        return;
@@ -184,22 +184,26 @@ do_dictSetKey(int argc, char **argv)
 void
 do_dictRemoveKey(int argc, char **argv)
 {
-       CFPropertyListRef       store;
        CFStringRef             key;
+       CFMutableDictionaryRef  val;
 
-       if (data == NULL) {
-               SCDLog(LOG_INFO, CFSTR("d.remove: dictionary must be initialized."));
+       if (value == NULL) {
+               SCPrint(TRUE, stdout, CFSTR("d.remove: dictionary must be initialized.\n"));
                return;
        }
 
-       store = SCDHandleGetData(data);
-       if (CFGetTypeID(store) == CFDictionaryGetTypeID()) {
-               key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
-               CFDictionaryRemoveValue((CFMutableDictionaryRef)store, key);
-               CFRelease(key);
-       } else {
-               SCDLog(LOG_INFO, CFSTR("d.add: data (fetched from configuration server) is not a dictionary"));
+       if (CFGetTypeID(value) != CFDictionaryGetTypeID()) {
+               SCPrint(TRUE, stdout, CFSTR("d.remove: data (fetched from configuration server) is not a dictionary.\n"));
+               return;
        }
 
+       val = CFDictionaryCreateMutableCopy(NULL, 0, value);
+       CFRelease(value);
+       value = val;
+
+       key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
+       CFDictionaryRemoveValue((CFMutableDictionaryRef)value, key);
+       CFRelease(key);
+
        return;
 }
index 8ea9cfe705f0041b5c9a5b5ed66d6cecae5b237b..0a521a0db8135f5af35bd0cdbcfa04eddd4cd109 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #ifndef _DICTIONARY_H
 #define _DICTIONARY_H
 
 
 __BEGIN_DECLS
 
-void   do_dictInit             __P((int argc, char **argv));
-void   do_dictShow             __P((int argc, char **argv));
-void   do_dictSetKey           __P((int argc, char **argv));
-void   do_dictRemoveKey                __P((int argc, char **argv));
+void   do_dictInit             (int argc, char **argv);
+void   do_dictShow             (int argc, char **argv);
+void   do_dictSetKey           (int argc, char **argv);
+void   do_dictRemoveKey        (int argc, char **argv);
 
 __END_DECLS
 
index b19df551d0dc464801b4189546e7e808c5a62f76..6629a6b23fd00e2994c766953182ccaec119026e 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 
 #include "scutil.h"
 
-static int             osig;
-static struct sigaction        *oact = NULL;
+#include <SystemConfiguration/SCPrivate.h>
+#include "v1Compatibility.h"
+
+
+static int                     osig;
+static struct sigaction                *oact   = NULL;
+
+
+static CFComparisonResult
+sort_keys(const void *p1, const void *p2, void *context) {
+       CFStringRef key1 = (CFStringRef)p1;
+       CFStringRef key2 = (CFStringRef)p2;
+       return CFStringCompare(key1, key2, 0);
+}
+
 
 void
-do_notify_list(int argc, char **argv)
+storeCallback(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info)
 {
-       int             regexOptions = 0;
-       SCDStatus       status;
-       CFArrayRef      list;
-       CFIndex         listCnt;
        int             i;
+       CFIndex         n;
+
+       SCPrint(TRUE, stdout, CFSTR("notification callback (store address = %p).\n"), store);
+
+       n = CFArrayGetCount(changedKeys);
+       if (n > 0) {
+               for (i=0; i<n; i++) {
+                       SCPrint(TRUE,
+                               stdout,
+                               CFSTR("  changedKey [%d] = %@\n"),
+                               i,
+                               CFArrayGetValueAtIndex(changedKeys, i));
+               }
+       } else {
+               SCPrint(TRUE, stdout, CFSTR("  no changedKey's.\n"));
+       }
+
+       return;
+}
+
+
+void
+do_notify_list(int argc, char **argv)
+{
+       int                     i;
+       CFArrayRef              list;
+       CFIndex                 listCnt;
+       Boolean                 isRegex = FALSE;
+       CFMutableArrayRef       sortedList;
 
        if (argc == 1)
-               regexOptions = kSCDRegexKey;
+               isRegex = TRUE;
 
-       status = SCDNotifierList(session, regexOptions, &list);
-       if (status != SCD_OK) {
-               printf("SCDNotifierList: %s\n", SCDError(status));
+       list = SCDynamicStoreCopyWatchedKeyList(store, isRegex);
+       if (!list) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                return;
        }
 
        listCnt = CFArrayGetCount(list);
+       sortedList = CFArrayCreateMutableCopy(NULL, listCnt, list);
+       CFRelease(list);
+       CFArraySortValues(sortedList,
+                         CFRangeMake(0, listCnt),
+                         sort_keys,
+                         NULL);
+
        if (listCnt > 0) {
                for (i=0; i<listCnt; i++) {
-                       SCDLog(LOG_NOTICE, CFSTR("  notifierKey [%d] = %@"), i, CFArrayGetValueAtIndex(list, i));
+                       SCPrint(TRUE,
+                               stdout,
+                               CFSTR("  notifierKey [%d] = %@\n"),
+                               i,
+                               CFArrayGetValueAtIndex(sortedList, i));
                }
        } else {
-               SCDLog(LOG_NOTICE, CFSTR("  no notifierKey's"));
+               SCPrint(TRUE, stdout, CFSTR("  no notifierKey's.\n"));
        }
-       CFRelease(list);
+       CFRelease(sortedList);
 
        return;
 }
@@ -66,19 +125,17 @@ void
 do_notify_add(int argc, char **argv)
 {
        CFStringRef     key;
-       int             regexOptions = 0;
-       SCDStatus       status;
+       Boolean         isRegex = FALSE;
 
        key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
 
        if (argc == 2)
-               regexOptions = kSCDRegexKey;
+               isRegex = TRUE;
 
-       status = SCDNotifierAdd(session, key, regexOptions);
-       CFRelease(key);
-       if (status != SCD_OK) {
-               printf("SCDNotifierAdd: %s\n", SCDError(status));
+       if (!SCDynamicStoreAddWatchedKey(store, key, isRegex)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
        }
+       CFRelease(key);
        return;
 }
 
@@ -86,20 +143,18 @@ do_notify_add(int argc, char **argv)
 void
 do_notify_remove(int argc, char **argv)
 {
-       SCDStatus       status;
        CFStringRef     key;
-       int             regexOptions = 0;
+       Boolean         isRegex = FALSE;
 
        key   = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
 
        if (argc == 2)
-               regexOptions = kSCDRegexKey;
+               isRegex = TRUE;
 
-       status = SCDNotifierRemove(session, key, regexOptions);
-       CFRelease(key);
-       if (status != SCD_OK) {
-               printf("SCDNotifierRemove: %s\n", SCDError(status));
+       if (!SCDynamicStoreRemoveWatchedKey(store, key, isRegex)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
        }
+       CFRelease(key);
        return;
 }
 
@@ -109,22 +164,25 @@ do_notify_changes(int argc, char **argv)
 {
        CFArrayRef      list;
        CFIndex         listCnt;
-       SCDStatus       status;
        int             i;
 
-       status = SCDNotifierGetChanges(session, &list);
-       if (status != SCD_OK) {
-               printf("SCDNotifierGetChanges: %s\n", SCDError(status));
+       list = SCDynamicStoreCopyNotifiedKeys(store);
+       if (!list) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                return;
        }
 
        listCnt = CFArrayGetCount(list);
        if (listCnt > 0) {
                for (i=0; i<listCnt; i++) {
-                       SCDLog(LOG_NOTICE, CFSTR("  changedKey [%d] = %@"), i, CFArrayGetValueAtIndex(list, i));
+                       SCPrint(TRUE,
+                               stdout,
+                               CFSTR("  changedKey [%d] = %@\n"),
+                               i,
+                               CFArrayGetValueAtIndex(list, i));
                }
        } else {
-               SCDLog(LOG_NOTICE, CFSTR("  no changedKey's"));
+               SCPrint(TRUE, stdout, CFSTR("  no changedKey's.\n"));
        }
        CFRelease(list);
 
@@ -133,35 +191,45 @@ do_notify_changes(int argc, char **argv)
 
 
 void
-do_notify_wait(int argc, char **argv)
+do_notify_watch(int argc, char **argv)
 {
-       SCDStatus       status;
+       notifyRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
+       if (!notifyRls) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
+               return;
+       }
 
-       status = SCDNotifierWait(session);
-       if (status != SCD_OK) {
-               printf("SCDNotifierWait: %s\n", SCDError(status));
+       CFRunLoopAddSource(CFRunLoopGetCurrent(), notifyRls, kCFRunLoopDefaultMode);
+       return;
+}
+
+
+void
+do_notify_wait(int argc, char **argv)
+{
+       if (!SCDynamicStoreNotifyWait(store)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                return;
        }
 
-       printf("OK, something changed!\n");
        return;
 }
 
 
 static boolean_t
-notificationWatcher(SCDSessionRef session, void *arg)
+notificationWatcher(SCDynamicStoreRef store, void *arg)
 {
-       printf("notification callback (session address = %p)\n", session);
-       printf("  arg = %s\n", (char *)arg);
+       SCPrint(TRUE, stdout, CFSTR("notification callback (store address = %p).\n"), store);
+       SCPrint(TRUE, stdout, CFSTR("  arg = %s.\n"), (char *)arg);
        return TRUE;
 }
 
 
 static boolean_t
-notificationWatcherVerbose(SCDSessionRef session, void *arg)
+notificationWatcherVerbose(SCDynamicStoreRef store, void *arg)
 {
-       printf("notification callback (session address = %p)\n", session);
-       printf("  arg = %s\n", (char *)arg);
+       SCPrint(TRUE, stdout, CFSTR("notification callback (store address = %p).\n"), store);
+       SCPrint(TRUE, stdout, CFSTR("  arg = %s.\n"), (char *)arg);
        do_notify_changes(0, NULL);     /* report the keys which changed */
        return TRUE;
 }
@@ -170,18 +238,14 @@ notificationWatcherVerbose(SCDSessionRef session, void *arg)
 void
 do_notify_callback(int argc, char **argv)
 {
-       SCDStatus               status;
-       SCDCallbackRoutine_t    func  = notificationWatcher;
+       SCDynamicStoreCallBack_v1       func  = notificationWatcher;
 
        if ((argc == 1) && (strcmp(argv[0], "verbose") == 0)) {
                func = notificationWatcherVerbose;
        }
 
-       status = SCDNotifierInformViaCallback(session,
-                                             func,
-                                             "Changed detected by callback handler!");
-       if (status != SCD_OK) {
-               printf("SCDNotifierInformViaCallback: %s\n", SCDError(status));
+       if (!SCDynamicStoreNotifyCallback(store, CFRunLoopGetCurrent(), func, "Changed detected by callback handler!")) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                return;
        }
 
@@ -193,7 +257,6 @@ void
 do_notify_file(int argc, char **argv)
 {
        int32_t         reqID = 0;
-       SCDStatus       status;
        int             fd;
        union {
                char    data[4];
@@ -204,14 +267,13 @@ do_notify_file(int argc, char **argv)
 
        if (argc == 1) {
                if ((sscanf(argv[0], "%d", &reqID) != 1)) {
-                       printf("invalid identifier\n");
+                       SCPrint(TRUE, stdout, CFSTR("invalid identifier.\n"));
                        return;
                }
        }
 
-       status = SCDNotifierInformViaFD(session, reqID, &fd);
-       if (status != SCD_OK) {
-               printf("SCDNotifierInformViaFD: %s\n", SCDError(status));
+       if (!SCDynamicStoreNotifyFileDescriptor(store, reqID, &fd)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                return;
        }
 
@@ -224,27 +286,27 @@ do_notify_file(int argc, char **argv)
                got = read(fd, bufPtr, needed);
                if (got == -1) {
                        /* if error detected */
-                       printf("read() failed: %s\n", strerror(errno));
+                       SCPrint(TRUE, stdout, CFSTR("read() failed: %s.\n"), strerror(errno));
                        break;
                }
 
                if (got == 0) {
                        /* if end of file detected */
-                       printf("read(): detected end of file\n");
+                       SCPrint(TRUE, stdout, CFSTR("read(): detected end of file.\n"));
                        break;
                }
 
-               printf("Received %d bytes\n", got);
+               SCPrint(TRUE, stdout, CFSTR("Received %d bytes.\n"), got);
                bufPtr += got;
                needed -= got;
        }
 
        if (needed != sizeof(buf.gotID)) {
-               printf("  Received notification, identifier = %d\n", buf.gotID);
+               SCPrint(TRUE, stdout, CFSTR("  Received notification, identifier = %d.\n"), buf.gotID);
        }
 
        /* this utility only allows processes one notification per "n.file" request */
-       (void)SCDNotifierCancel(session);
+       (void) SCDynamicStoreNotifyCancel(store);
 
        (void) close(fd);       /* close my side of the file descriptor */
 
@@ -266,7 +328,7 @@ signalCatcher(int signum)
 {
        static int      n = 0;
 
-       printf("Received SIG%s (#%d)\n", signames[signum], n++);
+       SCPrint(TRUE, stdout, CFSTR("Received SIG%s (#%d).\n"), signames[signum], n++);
        return;
 }
 
@@ -278,11 +340,10 @@ do_notify_signal(int argc, char **argv)
        pid_t                   pid;
        struct sigaction        nact;
        int                     ret;
-       SCDStatus               status;
 
        if (isdigit(*argv[0])) {
                if ((sscanf(argv[0], "%d", &sig) != 1) || (sig <= 0) || (sig >= NSIG)) {
-                       printf("signal must be in the range of 1 .. %d\n", NSIG-1);
+                       SCPrint(TRUE, stdout, CFSTR("signal must be in the range of 1 .. %d.\n"), NSIG-1);
                        return;
                }
        } else {
@@ -291,13 +352,22 @@ do_notify_signal(int argc, char **argv)
                                break;
                }
                if (sig >= NSIG) {
-                       printf("Signal must be one of the following:");
+                       CFMutableStringRef      str;
+
+                       SCPrint(TRUE, stdout, CFSTR("Signal must be one of the following:\n"));
+
+                       str = CFStringCreateMutable(NULL, 0);
                        for (sig=1; sig<NSIG; sig++) {
-                               if ((sig % 10) == 1)
-                                       printf("\n ");
-                               printf(" %-6s", signames[sig]);
+                               CFStringAppendFormat(str, NULL, CFSTR(" %-6s"), signames[sig]);
+                               if ((sig % 10) == 0) {
+                                       CFStringAppendFormat(str, NULL, CFSTR("\n"));
+                               }
+                       }
+                       if ((sig % 10) != 0) {
+                               CFStringAppendFormat(str, NULL, CFSTR("\n"));
                        }
-                       printf("\n");
+                       SCPrint(TRUE, stdout, CFSTR("%@"), str);
+                       CFRelease(str);
                        return;
                }
 
@@ -318,11 +388,10 @@ do_notify_signal(int argc, char **argv)
        nact.sa_flags = SA_RESTART;
        ret = sigaction(sig, &nact, oact);
        osig = sig;
-       printf("signal handler started\n");
+       SCPrint(TRUE, stdout, CFSTR("signal handler started.\n"));
 
-       status = SCDNotifierInformViaSignal(session, pid, sig);
-       if (status != SCD_OK) {
-               printf("SCDNotifierInformViaSignal: %s\n", SCDError(status));
+       if (!SCDynamicStoreNotifySignal(store, pid, sig)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                return;
        }
 
@@ -333,12 +402,16 @@ do_notify_signal(int argc, char **argv)
 void
 do_notify_cancel(int argc, char **argv)
 {
-       SCDStatus               status;
        int                     ret;
 
-       status = SCDNotifierCancel(session);
-       if (status != SCD_OK) {
-               printf("SCDNotifierCancel: %s\n", SCDError(status));
+       if (notifyRls) {
+               CFRunLoopRemoveSource(CFRunLoopGetCurrent(), notifyRls, kCFRunLoopDefaultMode);
+               CFRelease(notifyRls);
+               notifyRls = NULL;
+       }
+
+       if (!SCDynamicStoreNotifyCancel(store)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                return;
        }
 
index 6a353ff42e58c64c429e9de1734d8f47069bc625..3bd16011a906ee818a27efe95b92a05e3ac6e35c 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #ifndef _NOTIFY_H
 #define _NOTIFY_H
 
 
 __BEGIN_DECLS
 
-void   do_notify_list          __P((int argc, char **argv));
-void   do_notify_add           __P((int argc, char **argv));
-void   do_notify_remove        __P((int argc, char **argv));
-void   do_notify_changes       __P((int argc, char **argv));
-void   do_notify_wait          __P((int argc, char **argv));
-void   do_notify_callback      __P((int argc, char **argv));
-void   do_notify_signal        __P((int argc, char **argv));
-void   do_notify_file          __P((int argc, char **argv));
-void   do_notify_cancel        __P((int argc, char **argv));
+void   storeCallback           (SCDynamicStoreRef      store,
+                                CFArrayRef             changedKeys,
+                                void                   *info);
+
+void   do_notify_list          (int argc, char **argv);
+void   do_notify_add           (int argc, char **argv);
+void   do_notify_remove        (int argc, char **argv);
+void   do_notify_changes       (int argc, char **argv);
+void   do_notify_watch         (int argc, char **argv);
+void   do_notify_wait          (int argc, char **argv);
+void   do_notify_callback      (int argc, char **argv);
+void   do_notify_signal        (int argc, char **argv);
+void   do_notify_file          (int argc, char **argv);
+void   do_notify_cancel        (int argc, char **argv);
 
 __END_DECLS
 
index b46c128ca59016ff3359038e322a1139870c690b..fc844b40254c3474548641c4eb38bb43030c8227 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * July 9, 2001                        Allan Nathanson <ajn@apple.com>
+ * - added "-r" option for checking network reachability
+ * - added "-w" option to check/wait for the presence of a
+ *   dynamic store key.
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #endif /* DEBUG */
 
 #include "scutil.h"
-#include "SCDPrivate.h"
 #include "commands.h"
 #include "dictionary.h"
+#include "tests.h"
+
+#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
+
 
 #define LINE_LENGTH 256
 
-SCDSessionRef          session = NULL;
-SCDHandleRef           data    = NULL;
-int                    nesting = 0;
-CFMutableArrayRef      sources = NULL;
+
+int                    nesting         = 0;
+CFRunLoopSourceRef     notifyRls       = NULL;
+CFMutableArrayRef      sources         = NULL;
+SCDynamicStoreRef      store           = NULL;
+CFPropertyListRef      value           = NULL;
 
 
 static char *
@@ -119,7 +140,7 @@ getString(char **line)
 }
 
 
-boolean_t
+Boolean
 process_line(FILE *fp)
 {
        char    line[LINE_LENGTH], *s, *arg, **argv = NULL;
@@ -129,8 +150,8 @@ process_line(FILE *fp)
        if (getLine(line, sizeof(line), fp) == NULL)
                return FALSE;
 
-       if ((nesting > 0) && SCDOptionGet(NULL, kSCDOptionVerbose)) {
-               SCDLog(LOG_NOTICE, CFSTR("%d> %s"), nesting, line);
+       if (nesting > 0) {
+               SCPrint(TRUE, stdout, CFSTR("%d> %s"), nesting, line);
        }
 
        /* if requested, exit */
@@ -196,97 +217,126 @@ runLoopProcessInput(CFSocketRef s, CFSocketCallBackType type, CFDataRef address,
                nesting--;
        }
 
-       if (SCDOptionGet(NULL, kSCDOptionUseCFRunLoop)) {
-               /* debug information, diagnostics */
-               _showMachPortStatus();
+       /* debug information, diagnostics */
+       __showMachPortStatus();
 
-               /* if necessary, re-issue prompt */
-               if ((CFArrayGetCount(sources) == 1) && isatty(STDIN_FILENO)) {
-                       printf("> ");
-                       fflush(stdout);
-               }
+       /* if necessary, re-issue prompt */
+       if ((CFArrayGetCount(sources) == 1) && isatty(STDIN_FILENO)) {
+               printf("> ");
+               fflush(stdout);
        }
 
        return;
 }
 
 
+void
+usage(const char *command)
+{
+       SCPrint(TRUE, stderr, CFSTR("usage: %s\n"), command);
+       SCPrint(TRUE, stderr, CFSTR("   or: %s -r node-or-address\n"), command);
+       SCPrint(TRUE, stderr, CFSTR("\t-r\tcheck reachability of node/address\n"));
+       SCPrint(TRUE, stderr, CFSTR("   or: %s -w dynamic-store-key [ -t timeout ]\n"), command);
+       SCPrint(TRUE, stderr, CFSTR("\t-w\twait for presense of dynamic store key\n"));
+       SCPrint(TRUE, stderr, CFSTR("\t-t\ttime to wait for key\n"));
+       SCPrint(TRUE, stderr, CFSTR("\n"));
+       SCPrint(TRUE, stderr, CFSTR("Note: you may only specify one of \"-r\" or \"-w\".\n"));
+       exit (EX_USAGE);
+}
+
+
 int
 main(int argc, const char *argv[])
 {
-       extern int      optind;
-       int             opt;
-       boolean_t       ok;
+       CFSocketContext         context = { 0, stdin, NULL, NULL, NULL };
+       char                    *dest   = NULL;
+       CFSocketRef             in;
+       extern int              optind;
+       int                     opt;
+       const char              *prog   = argv[0];
+       CFRunLoopSourceRef      rls;
+       int                     timeout = 15;   /* default timeout (in seconds) */
+       char                    *wait   = NULL;
 
        /* process any arguments */
 
-       SCDOptionSet(NULL, kSCDOptionUseCFRunLoop, FALSE);
-
-       while ((opt = getopt(argc, argv, "dvr")) != -1)
+       while ((opt = getopt(argc, argv, "dvpr:t:w:")) != -1)
                switch(opt) {
                case 'd':
-                       SCDOptionSet(NULL, kSCDOptionDebug, TRUE);
+                       _sc_debug = TRUE;
+                       _sc_log   = FALSE;      /* enable framework logging */
                        break;
                case 'v':
-                       SCDOptionSet(NULL, kSCDOptionVerbose, TRUE);
+                       _sc_verbose = TRUE;
+                       _sc_log     = FALSE;    /* enable framework logging */
+                       break;
+               case 'p':
+                       enablePrivateAPI = TRUE;
                        break;
                case 'r':
-                       SCDOptionSet(NULL, kSCDOptionUseCFRunLoop, TRUE);
+                       dest = optarg;
+                       break;
+               case 't':
+                       timeout = atoi(optarg);
+                       break;
+               case 'w':
+                       wait = optarg;
                        break;
                case '?':
                default :
-                       do_help(0, NULL);
+                       usage(prog);
        }
        argc -= optind;
        argv += optind;
 
+       if (dest && wait) {
+               usage(prog);
+       }
+
+       /* are we checking the reachability of a host/address */
+       if (dest) {
+               do_checkReachability(dest);
+               /* NOT REACHED */
+       }
+
+       /* are we waiting on the presense of a dynamic store key */
+       if (wait) {
+               do_wait(wait, timeout);
+               /* NOT REACHED */
+       }
+
        /* start with an empty dictionary */
        do_dictInit(0, NULL);
 
-       if (SCDOptionGet(NULL, kSCDOptionUseCFRunLoop)) {
-               CFSocketRef             in;
-               CFSocketContext         context = { 0, stdin, NULL, NULL, NULL };
-               CFRunLoopSourceRef      rls;
+       /* create a "socket" reference with the file descriptor associated with stdin */
+       in  = CFSocketCreateWithNative(NULL,
+                                      STDIN_FILENO,
+                                      kCFSocketReadCallBack,
+                                      runLoopProcessInput,
+                                      &context);
 
-               /* create a "socket" reference with the file descriptor associated with stdin */
-               in  = CFSocketCreateWithNative(NULL,
-                                              STDIN_FILENO,
-                                              kCFSocketReadCallBack,
-                                              runLoopProcessInput,
-                                              &context);
+       /* Create a run loop source for the (stdin) file descriptor */
+       rls = CFSocketCreateRunLoopSource(NULL, in, nesting);
 
-               /* Create a run loop source for the (stdin) file descriptor */
-               rls = CFSocketCreateRunLoopSource(NULL, in, nesting);
+       /* keep track of input file sources */
+       sources = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       CFArrayAppendValue(sources, rls);
 
-               /* keep track of input file sources */
-               sources = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-               CFArrayAppendValue(sources, rls);
+       /* add this source to the run loop */
+       CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+       CFRelease(rls);
+       CFRelease(in);
 
-               /* add this source to the run loop */
-               CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+       /* show (initial) debug information, diagnostics */
+       __showMachPortStatus();
 
-               CFRelease(rls);
-               CFRelease(in);
+       /* issue (initial) prompt */
+       if (isatty(STDIN_FILENO)) {
+               printf("> ");
+               fflush(stdout);
        }
 
-       do {
-               /* debug information, diagnostics */
-               _showMachPortStatus();
-
-               /* issue prompt */
-               if (isatty(STDIN_FILENO)) {
-                       printf("> ");
-                       fflush(stdout);
-               }
-
-               if (SCDOptionGet(NULL, kSCDOptionUseCFRunLoop)) {
-                       CFRunLoopRun(); /* process input, process events */
-                       ok = FALSE;     /* if the RunLoop exited */
-               } else {
-                       /* process command */
-                       ok = process_line(stdin);
-               }
-       } while (ok);
+       CFRunLoopRun(); /* process input, process events */
 
        exit (EX_OK);   // insure the process exit status is 0
        return 0;       // ...and make main fit the ANSI spec.
index b1d13dd6bdad2701792d4f3825c4030c092e71f7..ebeae2e9579e79044f886620e4912d8ed949e8d8 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #ifndef _SC_H
 #define _SC_H
 
 #include <sys/cdefs.h>
 
-#include <SystemConfiguration/SCD.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+
 
-extern SCDSessionRef           session;
-extern SCDHandleRef            data;
 extern int                     nesting;
+extern CFRunLoopSourceRef      notifyRls;
 extern CFMutableArrayRef       sources;
+extern SCDynamicStoreRef       store;
+extern CFPropertyListRef       value;
+
 
 __BEGIN_DECLS
 
-boolean_t      process_line            __P((FILE       *fp));
+Boolean        process_line            (FILE   *fp);
 
-void           runLoopProcessInput     __P((CFSocketRef                s,
-                                            CFSocketCallBackType       type,
-                                            CFDataRef                  address,
-                                            const void                 *data,
-                                            void                       *info));
+void           runLoopProcessInput     (CFSocketRef            s,
+                                        CFSocketCallBackType   type,
+                                        CFDataRef              address,
+                                        const void             *data,
+                                        void                   *info);
 
 __END_DECLS
 
index 7a8287eefa0d0d4f51c73a883584f1c682f130b9..82a6f43b7bec7c7226f20338b7c8c4771f5c50a1 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include "scutil.h"
+#include "notify.h"
 
 void
 do_open(int argc, char **argv)
 {
-       SCDStatus       status;
+       if (store)      CFRelease(store);
 
-       if (session != NULL) {
-               status = SCDClose(&session);
-               switch (status) {
-                       case SCD_OK :
-                       case SCD_NOSESSION :
-                               /*
-                                * if the "close" was successful or if we had an open
-                                * session but can no talk to the server
-                                */
-                               break;
-                       default :
-                               SCDLog(LOG_INFO, CFSTR("SCDClose: %s"), SCDError(status));
-                               return;
-               }
-       }
-
-       status = SCDOpen(&session, CFSTR("sc"));
-       if (status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDOpen: %s"), SCDError(status));
+       store = SCDynamicStoreCreate(NULL, CFSTR("scutil"), storeCallback, NULL);
+       if (!store) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
                return;
        }
 
@@ -56,11 +51,15 @@ do_open(int argc, char **argv)
 void
 do_close(int argc, char **argv)
 {
-       SCDStatus       status;
+       if (notifyRls) {
+               CFRunLoopRemoveSource(CFRunLoopGetCurrent(), notifyRls, kCFRunLoopDefaultMode);
+               CFRelease(notifyRls);
+               notifyRls = NULL;
+       }
 
-       status = SCDClose(&session);
-       if (status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDClose: %s"), SCDError(status));
+       if (store) {
+               CFRelease(store);
+               store = NULL;
        }
        return;
 }
@@ -69,11 +68,8 @@ do_close(int argc, char **argv)
 void
 do_lock(int argc, char **argv)
 {
-       SCDStatus       status;
-
-       status = SCDLock(session);
-       if (status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDLock: %s"), SCDError(status));
+       if (!SCDynamicStoreLock(store)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
        }
        return;
 }
@@ -82,11 +78,8 @@ do_lock(int argc, char **argv)
 void
 do_unlock(int argc, char **argv)
 {
-       SCDStatus       status;
-
-       status = SCDUnlock(session);
-       if (status != SCD_OK) {
-               SCDLog(LOG_INFO, CFSTR("SCDUnlock: %s"), SCDError(status));
+       if (!SCDynamicStoreUnlock(store)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
        }
        return;
 }
index 8a3f8bbbfada86057688f38a09738c6f1392eef2..211ddb75f7341f17ff2666e2f4dd1be1c7e2902b 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #ifndef _SESSION_H
 #define _SESSION_H
 
 
 __BEGIN_DECLS
 
-void   do_open                 __P((int argc, char **argv));
-void   do_close                __P((int argc, char **argv));
-void   do_lock                 __P((int argc, char **argv));
-void   do_unlock               __P((int argc, char **argv));
+void   do_open                 (int argc, char **argv);
+void   do_close                (int argc, char **argv);
+void   do_lock                 (int argc, char **argv);
+void   do_unlock               (int argc, char **argv);
 
 __END_DECLS
 
index 703ef5ffd8a98acae4b33ef656dd072f13408bb8..e6d9ed06fd835e4221b9e9a9756d5f94f175c676 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * July 9, 2001                        Allan Nathanson <ajn@apple.com>
+ * - added "-r" option for checking network reachability
+ * - added "-w" option to check/wait for the presence of a
+ *   dynamic store key.
+ *
+ * June 1, 2001                        Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #include "scutil.h"
-#include "SCDPrivate.h"
+
+#include <SystemConfiguration/SCPrivate.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
 
 void
-do_snapshot(int argc, char **argv)
+do_checkReachability(char *node)
 {
-       SCDStatus       status;
+       SCNetworkConnectionFlags        flags   = 0;
+       Boolean                         ok      = FALSE;
+
+       if (isdigit(node[0])) {
+               struct sockaddr_in      sin;
+
+               bzero(&sin, sizeof(sin));
+               sin.sin_len         = sizeof(sin);
+               sin.sin_family      = AF_INET;
+               sin.sin_addr.s_addr = inet_addr(node);
+               if (inet_aton(node, &sin.sin_addr) == 0) {
+                       SCPrint(TRUE, stderr, CFSTR("Could not interpret address \"%s\"\n"), node);
+                       exit(1);
+               }
+               ok = SCNetworkCheckReachabilityByAddress((struct sockaddr *)&sin,
+                                                        sizeof(sin),
+                                                        &flags);
+
+       } else {
+               ok = SCNetworkCheckReachabilityByName(node,
+                                                     &flags);
+       }
+
+       if (!ok) {
+               SCPrint(TRUE, stderr, CFSTR("  Could not determine status: %s\n"), SCErrorString(SCError()));
+               exit(1);
+       }
+
+       SCPrint(_sc_debug, stdout, CFSTR("flags = 0x%x"), flags);
+       if (flags != 0) {
+               SCPrint(_sc_debug, stdout, CFSTR(" ("));
+               if (flags & kSCNetworkFlagsReachable) {
+                       SCPrint(TRUE, stdout, CFSTR("Reachable"));
+                       flags &= ~kSCNetworkFlagsReachable;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+               if (flags & kSCNetworkFlagsTransientConnection) {
+                       SCPrint(TRUE, stdout, CFSTR("Transient Connection"));
+                       flags &= ~kSCNetworkFlagsTransientConnection;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+               if (flags & kSCNetworkFlagsConnectionRequired) {
+                       SCPrint(TRUE, stdout, CFSTR("Connection Required"));
+                       flags &= ~kSCNetworkFlagsConnectionRequired;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+               if (flags & kSCNetworkFlagsConnectionAutomatic) {
+                       SCPrint(TRUE, stdout, CFSTR("Connection Automatic"));
+                       flags &= ~kSCNetworkFlagsConnectionAutomatic;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+               if (flags & kSCNetworkFlagsInterventionRequired) {
+                       SCPrint(TRUE, stdout, CFSTR("Intervention Required"));
+                       flags &= ~kSCNetworkFlagsInterventionRequired;
+                       SCPrint(flags != 0, stdout, CFSTR(","));
+               }
+               SCPrint(_sc_debug, stdout, CFSTR(")"));
+       } else {
+               SCPrint(_sc_debug, stdout, CFSTR(" ("));
+               SCPrint(TRUE, stdout, CFSTR("Not Reachable"));
+               SCPrint(_sc_debug, stdout, CFSTR(")"));
+       }
+       SCPrint(TRUE, stdout, CFSTR("\n"));
+       exit(0);
+}
 
-       status = SCDSnapshot(session);
-       if (status != SCD_OK) {
-               printf("SCDSnapshot: %s\n", SCDError(status));
+
+void
+do_snapshot(int argc, char **argv)
+{
+       if (!SCDynamicStoreSnapshot(store)) {
+               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
        }
        return;
 }
 
 
-#ifdef DEBUG
+static void
+waitKeyFound()
+{
+       exit(0);
+}
+
+
+static void
+waitTimeout(int sigraised)
+{
+       exit(1);
+}
+
 
 void
-test_openCloseLeak(int argc, char **argv)
+do_wait(char *waitKey, int timeout)
 {
-       SCDStatus       status;
-       int             i, loopCnt;
-       SCDSessionRef   *sessions;
+       struct itimerval        itv;
+       CFStringRef             key;
+       CFMutableArrayRef       keys;
 
-       if ((argc == 0) || (sscanf(argv[0], "%d", &loopCnt) != 1)) {
-               loopCnt = 100;
+       store = SCDynamicStoreCreate(NULL, CFSTR("scutil (wait)"), waitKeyFound, NULL);
+       if (!store) {
+               SCPrint(TRUE, stderr,
+                       CFSTR("SCDynamicStoreCreate() failed: %s\n"), SCErrorString(SCError()));
+               exit(1);
        }
 
-       sessions = malloc(loopCnt * sizeof(SCDSessionRef));
+       keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+       key  = CFStringCreateWithCString(NULL, waitKey, kCFStringEncodingMacRoman);
+       CFArrayAppendValue(keys, key);
 
-       /* open, close, open, close, open, close, ... */
-       for (i=0; i<loopCnt; i++) {
-               status = SCDOpen(&sessions[i], CFSTR("sc"));
-               if (status != SCD_OK) {
-                       printf("SCDOpen: %s\n", SCDError(status));
-                       break;
-               }
+       if (!SCDynamicStoreSetNotificationKeys(store, keys, NULL)) {
+               SCPrint(TRUE, stderr,
+                       CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s\n"), SCErrorString(SCError()));
+               exit(1);
+       }
 
-               status = SCDClose(&sessions[i]);
-               if (status != SCD_OK) {
-                       printf("SCDClose: %s\n", SCDError(status));
-                       break;
-               }
+       notifyRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
+       if (!notifyRls) {
+               SCPrint(TRUE, stderr,
+                       CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s\n"), SCErrorString(SCError()));
+               exit(1);
        }
 
-       /* open, open, open, close, close, close, ... */
-       for (i=0; i<loopCnt; i++) {
-               status = SCDOpen(&sessions[i], CFSTR("sc"));
-               if (status != SCD_OK) {
-                       printf("SCDOpen: %s\n", SCDError(status));
-                       break;
-               }
+       CFRunLoopAddSource(CFRunLoopGetCurrent(), notifyRls, kCFRunLoopDefaultMode);
+
+       value = SCDynamicStoreCopyValue(store, key);
+       if (value) {
+               /* if the key is already present */
+               exit(0);
        }
-       for (i=0; i<loopCnt; i++) {
-               status = SCDClose(&sessions[i]);
-               if (status != SCD_OK) {
-                       printf("SCDClose: %s\n", SCDError(status));
-                       break;
+       CFRelease(key);
+
+       if (waitTimeout > 0) {
+               signal(SIGALRM, waitTimeout);
+               bzero(&itv, sizeof(itv));
+               itv.it_value.tv_sec = timeout;
+               if (setitimer(ITIMER_REAL, &itv, NULL) < 0) {
+                       SCPrint(TRUE, stderr,
+                               CFSTR("setitimer() failed: %s\n"), strerror(errno));
+                       exit(1);
                }
        }
 
-       return;
+       CFRunLoopRun();
 }
-#endif /* DEBUG */
index 38d9b9b9f4a7e87d90a9311eba7adc6f27d2f60b..0d280807e4128fd10cb014bea48685e3833cf48b 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+/*
+ * Modification History
+ *
+ * July 9, 2001                        Allan Nathanson <ajn@apple.com>
+ * - added "-r" option for checking network reachability
+ * - added "-w" option to check/wait for the presence of a
+ *   dynamic store key.
+ *
+ * November 9, 2000            Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
 #ifndef _TESTS_H
 #define _TESTS_H
 
 
 __BEGIN_DECLS
 
-void   do_snapshot             __P((int argc, char **argv));
-
-#ifdef DEBUG
-void   test_setServer          __P((int argc, char **argv));
-void   test_openCloseLeak      __P((int argc, char **argv));
-#endif /* DEBUG */
+void   do_checkReachability    (char *node);
+void   do_snapshot             (int argc, char **argv);
+void   do_wait                 (char *waitKey, int timeout);
 
 __END_DECLS