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;
{
CFBundleName = "SystemConfiguration";
CFBundleIdentifier = "com.apple.SystemConfiguration";
- CFBundleShortVersionString = "1.0.1";
+ CFBundleShortVersionString = "1.1.0";
}
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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 */
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
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 =
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
$(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
# 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
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,
SCDSet.c,
SCDRemove.c,
SCDTouch.c,
+ SCDNotify.c,
+ SCDNotifierSetKeys.c,
SCDNotifierList.c,
SCDNotifierAdd.c,
SCDNotifierRemove.c,
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;
* @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);
}
#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 */
* @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 */
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);
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;
}
* @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 */
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);
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;
}
+++ /dev/null
-/*
- * 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;
-}
* @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;
}
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;
}
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;
}
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;
}
#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 */
* @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 */
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,
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;
}
+++ /dev/null
-/*
- * 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;
-}
* @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();
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;
}
#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 */
* @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,
}
CFStringRef
-SCDKeyCreateNetworkInterface(CFStringRef domain)
+SCDynamicStoreKeyCreateNetworkInterface(CFAllocatorRef allocator,
+ CFStringRef domain)
{
- return (CFStringCreateWithFormat(NULL,
+ return (CFStringCreateWithFormat(allocator,
NULL,
CFSTR("%@/%@/%@"),
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,
kSCCompInterface,
ifname));
} else {
- return (CFStringCreateWithFormat(NULL,
+ return (CFStringCreateWithFormat(allocator,
NULL,
CFSTR("%@/%@/%@/%@/%@"),
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,
kSCCompService,
serviceID));
} else {
- return (CFStringCreateWithFormat(NULL,
+ return (CFStringCreateWithFormat(allocator,
NULL,
CFSTR("%@/%@/%@/%@/%@"),
domain,
* @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 */
* @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,
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;
}
* @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;
}
* @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 */
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;
}
* @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;
}
* @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,
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;
}
* @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);
}
+
* @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 */
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;
}
* @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 */
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;
}
* @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;
}
* @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;
}
* @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 */
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;
}
--- /dev/null
+/*
+ * 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;
+}
* @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 */
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;
}
--- /dev/null
+/*
+ * 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;
+}
* @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);
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 */
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;
}
--- /dev/null
+/*
+ * 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 */
* @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);
*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 */
void
-_showMachPortReferences(mach_port_t port)
+__showMachPortReferences(mach_port_t port)
{
#ifdef DEBUG
kern_return_t status;
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,
+++ /dev/null
-/*
- * 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 */
* @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 */
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;
}
* @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 */
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);
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;
}
* @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;
}
* @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 */
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;
}
* @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;
}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
* @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>
#include "ppp.h"
-
static int
inet_atonCF(CFStringRef cfStr, struct in_addr *addr)
{
}
-/*
- * 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;
}
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 {
/* 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;
}
}
/*
* 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;
}
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 {
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;
}
}
/*
* 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;
}
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;
*/
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 :
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;
}
*/
#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;
}
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;
}
* @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 */
* @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;
__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;
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 */
}
/* create prefs ID */
- path = CFStringCreateWithFormat(NULL,
+ path = CFStringCreateWithFormat(allocator,
NULL,
CFSTR("%s/%@/%@"),
pwd->pw_dir,
} else {
if (prefsID == NULL) {
/* default preference ID */
- path = CFStringCreateWithFormat(NULL,
+ path = CFStringCreateWithFormat(allocator,
NULL,
CFSTR("%@/%@"),
PREFS_DEFAULT_DIR,
path = CFRetain(prefsID);
} else {
/* relative path */
- path = CFStringCreateWithFormat(NULL,
+ path = CFStringCreateWithFormat(allocator,
NULL,
CFSTR("%@/%@"),
PREFS_DEFAULT_DIR,
* 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;
}
}
-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);
}
#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 */
* @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;
}
* @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
*/
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;
}
+++ /dev/null
-/*
- * 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;
-}
* @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
*/
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;
}
}
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;
}
}
}
}
}
- 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;
}
* @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;
}
* @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;
}
* @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
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;
}
* @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;
}
* 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) {
/*
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;
}
}
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;
}
* @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)
}
-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;
}
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 :
}
-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,
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;
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++;
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 */
(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,
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;
}
pathComponent = CFArrayGetValueAtIndex(elements, i);
tmpElement = (void *)CFDictionaryGetValue(element, pathComponent);
if (tmpElement == NULL) {
- status = SCP_NOKEY;
goto done;
}
element = tmpElement;
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;
}
#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 */
+++ /dev/null
-/*
- * 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 */
* @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;
}
* @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;
}
* @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;
}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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> <dict>
+ <BR> <key>key1</key>
+ <BR> <string>val1</string>
+ <BR> <key>key2</key>
+ <BR> <string>val2</string>
+ <BR> <key>path1</key>
+ <BR> <dict>
+ <BR> <key>key3</key>
+ <BR> <string>val3</string>
+ <BR> <key>key4</key>
+ <BR> <string>val4</string>
+ <BR> </dict>
+ <BR> </dict>
+ </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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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 */
+
#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 */
* @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>
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);
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
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;
/*
* 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>
" */\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"
#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"
#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"
#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;
{ 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 },
{ 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 },
{ 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 },
{ 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 },
{ 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 },
{ 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 },
{ 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 },
{ 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 },
{ 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 },
{ 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 },
};
}
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;
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);
*/
#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)
// 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;
}
}
// 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;
}
// 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;
}
}
+#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)
&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;
}
&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;
}
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;
}
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;
}
&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;
}
&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;
}
+#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)
&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;
}
#ifndef _PPP_H
#define _PPP_H
-
#include <sys/cdefs.h>
#include <CoreFoundation/CoreFoundation.h>
#include "ppp_msg.h"
-
__BEGIN_DECLS
int PPPInit (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);
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);
#include <sys/types.h>
-
/* local socket path */
#define PPP_PATH "/var/run/pppconfd\0"
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
};
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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 */
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
PROF_LIBS = $(LIBS)
-FRAMEWORKS = -framework SystemConfiguration
+NEXTSTEP_PB_CFLAGS = -DUSE_SYSTEMCONFIGURATION_PUBLIC_APIS
+FRAMEWORKS = -framework CoreFoundation -framework SystemConfiguration
NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
{
- 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";
}
* @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;
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 {
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;
}
* _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
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];
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 :
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);
}
*
* 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
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;
}
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;
}
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);
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);
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;
}
* _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
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;
}
/* 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);
}
*
* 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
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;
}
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;
}
* @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
/*
- * 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;
* _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
* @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;
}
xmlData_t dataRef, /* raw XML bytes */
mach_msg_type_number_t dataLen,
int *newInstance,
- int *scd_status
+ int *sc_status
)
{
kern_return_t status;
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,
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,
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);
* @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
/*
* 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;
}
xmlData_t dataRef, /* raw XML bytes */
mach_msg_type_number_t dataLen,
int *newInstance,
- int *scd_status
+ int *sc_status
)
{
kern_return_t status;
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,
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,
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);
* @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;
}
}
-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,
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;
}
* @APPLE_LICENSE_HEADER_END@
*/
+/*
+ * Modification History
+ *
+ * June 1, 2001 Allan Nathanson <ajn@apple.com>
+ * - public API conversion
+ *
+ * March 24, 2000 Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
#include "configd.h"
#include "session.h"
-SCDStatus
-_SCDGet(SCDSessionRef session, CFStringRef key, SCDHandleRef *handle)
+int
+__SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef *value)
{
- SCDSessionPrivateRef sessionPrivate = (SCDSessionPrivateRef)session;
- CFDictionaryRef dict;
- CFNumberRef num;
- int dictInstance;
+ SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
+ CFDictionaryRef dict;
- SCDLog(LOG_DEBUG, CFSTR("_SCDGet:"));
- SCDLog(LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyValue:"));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
- if ((session == NULL) || (sessionPrivate->server == MACH_PORT_NULL)) {
- return SCD_NOSESSION;
+ if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+ return kSCStatusNoStoreSession; /* you must have an open session to play */
}
- dict = CFDictionaryGetValue(cacheData, key);
+ dict = CFDictionaryGetValue(storeData, key);
if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
/* key doesn't exist (or data never defined) */
- return SCD_NOKEY;
+ return kSCStatusNoKey;
}
- /* Create a new handle associated with the cached data */
- *handle = SCDHandleInit();
-
/* Return the data associated with the key */
- SCDHandleSetData(*handle, CFDictionaryGetValue(dict, kSCDData));
-
- /* Return the instance number associated with the key */
- num = CFDictionaryGetValue(dict, kSCDInstance);
- (void) CFNumberGetValue(num, kCFNumberIntType, &dictInstance);
- _SCDHandleSetInstance(*handle, dictInstance);
+ *value = CFRetain(CFDictionaryGetValue(dict, kSCDData));
- SCDLog(LOG_DEBUG, CFSTR(" data = %@"), SCDHandleGetData(*handle));
- SCDLog(LOG_DEBUG, CFSTR(" instance = %d"), SCDHandleGetInstance(*handle));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" value = %@"), *value);
- return SCD_OK;
+ return kSCStatusOK;
}
-
kern_return_t
_configget(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
xmlDataOut_t *dataRef, /* raw XML bytes */
mach_msg_type_number_t *dataLen,
int *newInstance,
- int *scd_status
+ int *sc_status
)
{
kern_return_t status;
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,
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;
* 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;
/*
* 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;
}
* @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 */
&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;
}
_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;
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,
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;
}
*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;
* @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);
/* 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;
}
--- /dev/null
+/*
+ * 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;
+}
* @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);
&kCFTypeSetCallBacks);
}
- return SCD_OK;
+ return kSCStatusOK;
}
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,
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;
}
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(),
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.
* @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);
/*
* 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;
}
_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;
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,
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;
* @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,
}
/*
- * 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
* being watched.
*/
- if (dictInstance == 1) {
+ if (newEntry) {
if (CFSetContainsValue(deferredRemovals, key)) {
CFSetRemoveValue(deferredRemovals, key);
} else {
}
/*
- * 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 */
mach_msg_type_number_t dataLen,
int oldInstance,
int *newInstance,
- int *scd_status
+ int *sc_status
)
{
kern_return_t status;
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,
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,
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;
+}
* @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;
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,
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;
* @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"
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;
/*
* 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);
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);
}
-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 */
/*
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;
}
* @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;
/*
* 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. */
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. */
(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) {
/*
* 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;
}
_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;
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,
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;
* @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);
}
/* 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;
* @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);
CFRelease(newInfo);
CFRelease(sessionKey);
- return SCD_OK;
+ return kSCStatusOK;
}
_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;
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, ¬ifierKeys);
- if (*scd_status != SCD_OK) {
+ *sc_status = __SCDynamicStoreCopyNotifiedKeys(mySession->store, ¬ifierKeys);
+ if (*sc_status != kSCStatusOK) {
*listRef = NULL;
*listLen = 0;
return KERN_SUCCESS;
*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;
}
* @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;
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);
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);
/*
* 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;
}
_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;
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,
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;
* @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)) {
0,
&kCFTypeSetCallBacks);
- sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionPrivate->server);
+ sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
CFSetAddValue(needsNotification, sessionNum);
CFRelease(sessionNum);
}
- return SCD_OK;
+ return kSCStatusOK;
}
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;
}
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;
}
* @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)) {
0,
&kCFTypeSetCallBacks);
- sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionPrivate->server);
+ sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
CFSetAddValue(needsNotification, sessionNum);
CFRelease(sessionNum);
}
- return SCD_OK;
+ return kSCStatusOK;
}
_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;
* @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)) {
0,
&kCFTypeSetCallBacks);
- sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionPrivate->server);
+ sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
CFSetAddValue(needsNotification, sessionNum);
CFRelease(sessionNum);
}
- return SCD_OK;
+ return kSCStatusOK;
}
_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);
}
*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 */
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;
}
* @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);
(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 */
(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;
* @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
* @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" ,
};
-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]);
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 :
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));
}
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);
}
/* go */
if (testBundle == NULL) {
- /* start primary (cache management) thread */
+ /* start primary (store management) thread */
server_loop();
} else {
/* load/initialize/start specified plug-in */
* @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>
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 */
(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;
}
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;
}
CFAllocatorDeallocate(NULL, bufReply);
+ return;
}
/* 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);
}
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;
/* 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);
}
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);
/*
* @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
__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
* @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 */
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 */
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;
}
}
}
* @APPLE_LICENSE_HEADER_END@
*/
+/*
+ * Modification History
+ *
+ * March 31, 2000 Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
#ifndef _S_NOTIFY_H
#define _S_NOTIFY_H
__BEGIN_DECLS
-void pushNotifications __P(());
+void pushNotifications ();
__END_DECLS
* @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)
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);
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);
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);
* @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
__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
* @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 */
}
-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;
}
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 */
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);
}
/*
* 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;
}
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;
}
* @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
__BEGIN_DECLS
-void plugin_init __P(());
-void plugin_exec __P((void *arg));
+void plugin_init ();
+void plugin_exec (void *arg);
__END_DECLS
* @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"
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;
}
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;
}
}
}
}
}
- 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" */
* 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.
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);
* @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
/* 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;
__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
PROF_LIBS = $(LIBS)
-FRAMEWORKS = -framework SystemConfiguration
+NEXTSTEP_PB_CFLAGS = -DUSE_SYSTEMCONFIGURATION_PUBLIC_APIS
+FRAMEWORKS = -framework CoreFoundation -framework SystemConfiguration
NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
{
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);
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;
* @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;
}
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;
/* 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;
? 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);
}
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);
}
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 *)¤t);
- 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);
}
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(""));
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;
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(""));
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
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
{
- 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";
}
* @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;
}
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()));
}
}
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;
}
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;
}
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;
}
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;
}
* @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
* @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)
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);
}
}
- 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;
}
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;
}
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;
}
* @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
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
* @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;
}
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;
}
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--;
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;
}
(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);
}
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;
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;
}
* @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
* @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;
}
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;
}
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;
}
{
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);
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;
}
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;
}
do_notify_file(int argc, char **argv)
{
int32_t reqID = 0;
- SCDStatus status;
int fd;
union {
char data[4];
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;
}
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 */
{
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;
}
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 {
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;
}
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;
}
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;
}
* @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
* @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 *
}
-boolean_t
+Boolean
process_line(FILE *fp)
{
char line[LINE_LENGTH], *s, *arg, **argv = NULL;
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 */
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.
* @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
* @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;
}
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;
}
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;
}
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;
}
* @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
* @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 */
* @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