# owned by the top-level Makefile API and no context has been set up for where
# derived files should go.
#
-SYSCONFIG_PREFS_DIR = /private/var/db/SystemConfiguration
+PREFS_DIR = /Library/Preferences/SystemConfiguration
install_extra:
- $(MKDIRS) $(DSTROOT)$(SYSCONFIG_PREFS_DIR)
- install -c -m 644 preferences.xml $(DSTROOT)$(SYSCONFIG_PREFS_DIR)/preferences.xml
+ $(MKDIRS) $(DSTROOT)$(PREFS_DIR)
+ $(CHMOD) 755 $(DSTROOT)$(PREFS_DIR)
+ install -c -m 644 preferences.xml $(DSTROOT)$(PREFS_DIR)/preferences.plist
{
- DYNAMIC_CODE_GEN = YES;
+ "DYNAMIC_CODE_GEN" = YES;
FILESTABLE = {
- H_FILES = ();
- OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, preferences.xml);
- PRECOMPILED_HEADERS = ();
- PROJECT_HEADERS = ();
- PUBLIC_HEADERS = ();
- SUBPROJECTS = (SystemConfiguration.fproj, configd.tproj, scselect.tproj, scutil.tproj);
+ "H_FILES" = ();
+ "OTHER_SOURCES" = ("Makefile.preamble", Makefile, "Makefile.postamble", "preferences.xml");
+ "PRECOMPILED_HEADERS" = ();
+ "PROJECT_HEADERS" = ();
+ "PUBLIC_HEADERS" = ();
+ SUBPROJECTS = (
+ "SystemConfiguration.fproj",
+ "configd.tproj",
+ "scselect.tproj",
+ "scutil.tproj"
+ );
};
LANGUAGE = English;
MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles";
- 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;
- PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac";
- PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc";
+ "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";
+ "PDO_UNIX_JAVA_COMPILER" = "$(JDKBINDIR)/javac";
+ "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc";
PROJECTNAME = configd;
PROJECTTYPE = Aggregate;
- PROJECTVERSION = 2.8;
- WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make;
- WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe";
- WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc";
+ PROJECTVERSION = "2.8";
+ "WINDOWS_BUILDTOOL" = "$NEXT_ROOT/Developer/Executables/make";
+ "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe";
+ "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc";
}
{
CFBundleName = "SystemConfiguration";
CFBundleIdentifier = "com.apple.SystemConfiguration";
- CFBundleShortVersionString = "1.3.0";
+ CFBundleShortVersionString = "1.4.0";
}
/*
- * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2001-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
my_CFArrayAppendUniqueValue(CFMutableArrayRef arr, CFTypeRef new)
{
int i;
+ int n = CFArrayGetCount(arr);
- for (i = 0; i < CFArrayGetCount(arr); i++) {
+ for (i = 0; i < n; i++) {
CFStringRef element = CFArrayGetValueAtIndex(arr, i);
if (CFEqual(element, new)) {
return;
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "DeviceOnHold.h"
-#define kIODeviceSupportsHoldKey "DeviceSupportsHold"
+#define kIODeviceSupportsHoldKey "V92Modem"
typedef struct {
static pthread_once_t initialized = PTHREAD_ONCE_INIT;
-
static void
__DeviceOnHoldInitialize(void)
{
}
-DeviceOnHoldRef
+static DeviceOnHoldPrivateRef
__DeviceOnHoldCreatePrivate(CFAllocatorRef allocator)
{
- DeviceOnHoldPrivateRef devicePrivate;
- UInt32 size;
+ DeviceOnHoldPrivateRef devicePrivate;
+ uint32_t size;
/* initialize runtime */
pthread_once(&initialized, __DeviceOnHoldInitialize);
devicePrivate->name = NULL;
devicePrivate->sock = -1;
- return (DeviceOnHoldRef)devicePrivate;
+ return devicePrivate;
+}
+
+
+CFTypeID
+DeviceOnHoldGetTypeID(void) {
+ pthread_once(&initialized, __DeviceOnHoldInitialize); /* initialize runtime */
+ return __kDeviceOnHoldTypeID;
}
CFDictionaryRef options)
{
CFMutableDictionaryRef deviceToMatch;
- u_int32_t deviceSupportsHoldValue;
+ uint32_t deviceSupportsHoldValue;
kern_return_t kr;
mach_port_t masterPort;
io_iterator_t matchingServices;
goto errorExit;
}
- for ( ; service = IOIteratorNext(matchingServices) ; IOObjectRelease(service)) {
+ for ( ; (service = IOIteratorNext(matchingServices)) ; IOObjectRelease(service)) {
io_string_t path;
kr = IORegistryEntryGetPath(service, kIOServicePlane, path);
CFStringRef deviceName, // "modem"
CFDictionaryRef options)
{
- DeviceOnHoldRef device = NULL;
DeviceOnHoldPrivateRef devicePrivate;
int status;
return NULL;
}
- device = __DeviceOnHoldCreatePrivate(allocator);
- if (!device) {
+ devicePrivate = __DeviceOnHoldCreatePrivate(allocator);
+ if (!devicePrivate) {
return NULL;
}
- devicePrivate = (DeviceOnHoldPrivateRef)device;
-
status = MOHInit(&devicePrivate->sock, deviceName);
if (status != 0) {
- CFRelease(device);
+ CFRelease(devicePrivate);
return NULL;
}
- devicePrivate->name = CFRetain(deviceName);
+ devicePrivate->name = CFStringCreateCopy(NULL, deviceName);
- return device;
+ return (DeviceOnHoldRef)devicePrivate;
}
* Copyright (c) 2002 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "dy_framework.h"
-static struct ifmedia_description ifm_subtype_shared_descriptions[] =
+static const struct ifmedia_description ifm_subtype_shared_descriptions[] =
IFM_SUBTYPE_SHARED_DESCRIPTIONS;
-static struct ifmedia_description ifm_subtype_ethernet_descriptions[] =
+static const struct ifmedia_description ifm_subtype_ethernet_descriptions[] =
IFM_SUBTYPE_ETHERNET_DESCRIPTIONS;
-static struct ifmedia_description ifm_shared_option_descriptions[] =
+static const struct ifmedia_description ifm_shared_option_descriptions[] =
IFM_SHARED_OPTION_DESCRIPTIONS;
-static struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] =
+static const struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] =
IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS;
-static char *
-cfstring_to_cstring(CFStringRef cfstr, char *buf, int bufLen)
-{
- CFIndex len = CFStringGetLength(cfstr);
-
- if (!buf) {
- bufLen = len + 1;
- buf = CFAllocatorAllocate(NULL, bufLen, 0);
- }
-
- if (len >= bufLen) {
- len = bufLen - 1;
- }
-
- (void)CFStringGetBytes(cfstr,
- CFRangeMake(0, len),
- kCFStringEncodingASCII,
- 0,
- FALSE,
- buf,
- bufLen,
- NULL);
- buf[len] = '\0';
-
- return buf;
-}
-
-
-
static CFDictionaryRef
__createMediaDictionary(int media_options, Boolean filter)
{
/* subtype */
val = NULL;
- for (i=0; !val && ifm_subtype_shared_descriptions[i].ifmt_string; i++) {
+ for (i = 0; !val && ifm_subtype_shared_descriptions[i].ifmt_string; i++) {
if (IFM_SUBTYPE(media_options) == ifm_subtype_shared_descriptions[i].ifmt_word) {
val = CFStringCreateWithCString(NULL,
ifm_subtype_shared_descriptions[i].ifmt_string,
}
}
- for (i=0; !val && ifm_subtype_ethernet_descriptions[i].ifmt_string; i++) {
+ for (i = 0; !val && ifm_subtype_ethernet_descriptions[i].ifmt_string; i++) {
if (IFM_SUBTYPE(media_options) == ifm_subtype_ethernet_descriptions[i].ifmt_word) {
val = CFStringCreateWithCString(NULL,
ifm_subtype_ethernet_descriptions[i].ifmt_string,
}
val = NULL;
- for (i=0; !val && ifm_shared_option_descriptions[i].ifmt_string; i++) {
+ for (i = 0; !val && ifm_shared_option_descriptions[i].ifmt_string; i++) {
if (IFM_OPTIONS(media_options) & ifm_shared_option_descriptions[i].ifmt_word) {
val = CFStringCreateWithCString(NULL,
ifm_shared_option_descriptions[i].ifmt_string,
}
}
- for (i=0; !val && ifm_subtype_ethernet_option_descriptions[i].ifmt_string; i++) {
+ for (i = 0; !val && ifm_subtype_ethernet_option_descriptions[i].ifmt_string; i++) {
if (IFM_OPTIONS(media_options) & ifm_subtype_ethernet_option_descriptions[i].ifmt_word) {
val = CFStringCreateWithCString(NULL,
ifm_subtype_ethernet_option_descriptions[i].ifmt_string,
CFIndex i;
Boolean match;
int ifm_new = IFM_ETHER;
+ CFIndex n;
CFArrayRef options;
char *str;
CFStringRef val;
return -1;
}
- str = cfstring_to_cstring(val, NULL, 0);
- if (!str) {
+ str = _SC_cfstring_to_cstring(val, NULL, 0, kCFStringEncodingASCII);
+ if (str == NULL) {
return -1;
}
match = FALSE;
- for (i=0; !match && ifm_subtype_shared_descriptions[i].ifmt_string; i++) {
+ for (i = 0; !match && ifm_subtype_shared_descriptions[i].ifmt_string; i++) {
if (strcasecmp(str, ifm_subtype_shared_descriptions[i].ifmt_string) == 0) {
ifm_new |= ifm_subtype_shared_descriptions[i].ifmt_word;
match = TRUE;
}
}
- for (i=0; !match && ifm_subtype_ethernet_descriptions[i].ifmt_string; i++) {
+ for (i = 0; !match && ifm_subtype_ethernet_descriptions[i].ifmt_string; i++) {
if (strcasecmp(str, ifm_subtype_ethernet_descriptions[i].ifmt_string) == 0) {
ifm_new |= ifm_subtype_ethernet_descriptions[i].ifmt_word;
match = TRUE;
return -1;
}
- for (i=0; i<CFArrayGetCount(options); i++) {
+ n = CFArrayGetCount(options);
+ for (i = 0; i < n; i++) {
CFIndex j;
val = CFArrayGetValueAtIndex(options, i);
return -1;
}
- str = cfstring_to_cstring(val, NULL, 0);
- if (!str) {
+ str = _SC_cfstring_to_cstring(val, NULL, 0, kCFStringEncodingASCII);
+ if (str == NULL) {
return -1;
}
match = FALSE;
- for (j=0; !match && ifm_shared_option_descriptions[j].ifmt_string; j++) {
+ for (j = 0; !match && ifm_shared_option_descriptions[j].ifmt_string; j++) {
if (strcasecmp(str, ifm_shared_option_descriptions[j].ifmt_string) == 0) {
ifm_new |= ifm_shared_option_descriptions[j].ifmt_word;
match = TRUE;
}
}
- for (j=0; !match && ifm_subtype_ethernet_option_descriptions[j].ifmt_string; j++) {
+ for (j = 0; !match && ifm_subtype_ethernet_option_descriptions[j].ifmt_string; j++) {
if (strcasecmp(str, ifm_subtype_ethernet_option_descriptions[j].ifmt_string) == 0) {
ifm_new |= ifm_subtype_ethernet_option_descriptions[j].ifmt_word;
match = TRUE;
Boolean ok = FALSE;
int sock = -1;
- bzero((char *)&ifm, sizeof(ifm));
+ bzero((void *)&ifm, sizeof(ifm));
- (void)cfstring_to_cstring(interface, ifm.ifm_name, sizeof(ifm.ifm_name));
+ if (_SC_cfstring_to_cstring(interface, ifm.ifm_name, sizeof(ifm.ifm_name), kCFStringEncodingASCII) == NULL) {
+ SCLog(TRUE, LOG_ERR, CFSTR("could not convert inteface name"));
+ goto done;
+ }
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
CFMutableArrayRef media_options;
media_options = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
- for (i=0; i<ifm.ifm_count; i++) {
+ for (i = 0; i < ifm.ifm_count; i++) {
CFDictionaryRef options;
options = __createMediaDictionary(media_list[i], filter);
NetworkInterfaceCopyMediaSubTypes(CFArrayRef available)
{
CFIndex i;
+ CFIndex n;
CFMutableArrayRef subTypes;
if (!isA_CFArray(available)) {
}
subTypes = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
- for (i=0; i<CFArrayGetCount(available); i++) {
+
+ n = CFArrayGetCount(available);
+ for (i = 0; i < n; i++) {
CFDictionaryRef options;
CFStringRef subType;
CFStringRef subType)
{
CFIndex i;
+ CFIndex n;
CFMutableArrayRef subTypeOptions;
if (!isA_CFArray(available)) {
}
subTypeOptions = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
- for (i=0; i<CFArrayGetCount(available); i++) {
+
+ n = CFArrayGetCount(available);
+ for (i = 0; i < n; i++) {
CFDictionaryRef options;
CFArrayRef mediaOptions;
CFStringRef mediaSubType;
Boolean ok = FALSE;
int sock = -1;
- bzero((char *)&ifr, sizeof(ifr));
- (void)cfstring_to_cstring(interface, ifr.ifr_name, sizeof(ifr.ifr_name));
+ bzero((void *)&ifr, sizeof(ifr));
+ if (_SC_cfstring_to_cstring(interface, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII) == NULL) {
+ SCLog(TRUE, LOG_ERR, CFSTR("could not convert inteface name"));
+ goto done;
+ }
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
/* get valid MTU range */
if (mtu_min || mtu_max) {
- char ifName[IFNAMSIZ+1];
int ifType = 0;
io_iterator_t io_iter = 0;
io_registry_entry_t io_interface = 0;
/* look for a matching interface in the IORegistry */
- (void)cfstring_to_cstring(interface, ifName, sizeof(ifName));
- matchingDict = IOBSDNameMatching(masterPort, 0, ifName);
+ matchingDict = IOBSDNameMatching(masterPort, 0, ifr.ifr_name);
if (matchingDict) {
/* Note: IOServiceGetMatchingServices consumes a reference on the 'matchingDict' */
kr = IOServiceGetMatchingServices(masterPort, matchingDict, &io_iter);
* Copyright (c) 2002 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
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\
+ SCDynamicStoreCopySpecific.h SCDynamicStoreCopySpecificPrivate.h\
+ SCDynamicStoreSetSpecificPrivate.h SCPreferencesInternal.h\
+ SCPreferences.h SCPreferencesPrivate.h SCPreferencesPath.h\
+ SCPreferencesSetSpecific.h SCNetwork.h SCNetworkConnection.h\
+ SCNetworkReachability.h SCValidation.h ppp.h\
DHCPClientPreferences.h SCDynamicStoreCopyDHCPInfo.h moh_msg.h\
moh.h DeviceOnHold.h LinkConfiguration.h dy_framework.h
CFILES = SCD.c SCDKeys.c SCDPrivate.c SCDPlugin.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\
+ SCDNotifierSetKeys.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 SCPLock.c\
SCPUnlock.c SCPList.c SCPGet.c SCPAdd.c SCPSet.c SCPRemove.c\
SCPCommit.c SCPApply.c SCPPath.c SCDConsoleUser.c\
- SCDHostName.c SCLocation.c SCNetwork.c SCProxies.c ppp.c\
- v1Compatibility.c DHCP.c moh.c DeviceOnHold.c\
- LinkConfiguration.c dy_framework.c
+ SCDHostName.c SCLocation.c SCNetwork.c SCNetworkConnection.c\
+ SCNetworkReachability.c SCProxies.c ppp.c DHCP.c moh.c\
+ DeviceOnHold.c LinkConfiguration.c dy_framework.c
OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\
h.template config.defs genSCPreferences.c CustomInfo.plist
PROF_LIBS = $(LIBS)
+HEADER_PATHS =\
+ -I$(NEXT_ROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
+NEXTSTEP_PB_CFLAGS = -fconstant-cfstrings -DBIND_8_COMPAT -DCHECK_IPV6_REACHABILITY
FRAMEWORKS = -framework CoreFoundation
PUBLIC_HEADERS = SystemConfiguration.h SCDynamicStore.h\
SCDynamicStoreKey.h SCDynamicStoreCopySpecific.h\
SCPreferences.h SCPreferencesPath.h\
SCPreferencesSetSpecific.h SCNetwork.h\
+ SCNetworkConnection.h SCNetworkReachability.h\
DHCPClientPreferences.h SCDynamicStoreCopyDHCPInfo.h
-PROJECT_HEADERS = SCPrivate.h config_types.h SCDynamicStoreInternal.h\
- SCDynamicStore.h SCDynamicStorePrivate.h\
- SCDynamicStoreKey.h SCDynamicStoreCopySpecific.h\
+PROJECT_HEADERS = SystemConfiguration.h SCPrivate.h config_types.h\
+ SCDynamicStoreInternal.h SCDynamicStore.h\
+ SCDynamicStorePrivate.h SCDynamicStoreKey.h\
+ SCDynamicStoreCopySpecific.h\
+ SCDynamicStoreCopySpecificPrivate.h\
SCDynamicStoreSetSpecificPrivate.h\
SCPreferencesInternal.h SCPreferences.h\
SCPreferencesPrivate.h SCPreferencesPath.h\
- SCPreferencesSetSpecific.h SCNetwork.h SCValidation.h\
- SystemConfiguration.h v1Compatibility.h
+ SCPreferencesSetSpecific.h SCNetwork.h\
+ SCNetworkConnection.h SCNetworkReachability.h\
+ SCValidation.h
# the include path (defaults to -I.)
# DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
# passed to ld/libtool (defaults to nothing)
+WARNING_CFLAGS=-Wall
# Library and Framework projects only:
$(OFILE_DIR)/genSCPreferences: genSCPreferences.o
$(CC) -o $@ $(ARCHITECTURE_FLAGS) $<
+SCSchemaDefinitions_10_1.h: $(OFILE_DIR)/genSCPreferences
+ $(CD) $(SFILE_DIR) && $(OFILE_DIR)/genSCPreferences header-x > $@
+
SCSchemaDefinitions.h: $(OFILE_DIR)/genSCPreferences
- $(CD) $(SFILE_DIR) && $(OFILE_DIR)/genSCPreferences header > $@
+ $(CD) $(SFILE_DIR) && $(OFILE_DIR)/genSCPreferences header > $@
SCSchemaDefinitions.c: $(OFILE_DIR)/genSCPreferences
- $(CD) $(SFILE_DIR) && $(OFILE_DIR)/genSCPreferences cfile > $@
+ $(CD) $(SFILE_DIR) && $(OFILE_DIR)/genSCPreferences cfile > $@
genSCFiles:
cc -o /tmp/genSCFiles genSCPreferences.c -framework CoreFoundation
- /tmp/genSCFiles header > /tmp/SCSchemaDefinitions.h
- /tmp/genSCFiles cfile > /tmp/SCSchemaDefinitions.c
+ /tmp/genSCFiles header > /tmp/SCSchemaDefinitions.h
+ /tmp/genSCFiles header-x > /tmp/SCSchemaDefinitions_10_1.h
+ /tmp/genSCFiles cfile > /tmp/SCSchemaDefinitions.c
dhcp: DHCP.c
cc -Wall -DTEST_DHCPCLIENT_PREFERENCES -g -o dhcp DHCP.c -framework CoreFoundation -framework SystemConfiguration
OTHER_PRIVATE_HEADERS += SCPrivate.h
OTHER_PRIVATE_HEADERS += SCDynamicStorePrivate.h
+OTHER_PRIVATE_HEADERS += SCDynamicStoreCopySpecificPrivate.h
OTHER_PRIVATE_HEADERS += SCDynamicStoreSetSpecificPrivate.h
OTHER_PRIVATE_HEADERS += SCPreferencesPrivate.h
OTHER_PRIVATE_HEADERS += SCValidation.h
OTHER_PRIVATE_HEADERS += DeviceOnHold.h
OTHER_PRIVATE_HEADERS += LinkConfiguration.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
#
# Additional options to create generated headers, source
BEFORE_INSTALLHDRS = before_installhdrs
OTHER_SOURCEFILES += genSCPreferences.c
-OTHER_GENERATED_SRCFILES += SCSchemaDefinitions.h SCSchemaDefinitions.c
+OTHER_GENERATED_SRCFILES += SCSchemaDefinitions_10_1.h
+OTHER_GENERATED_SRCFILES += SCSchemaDefinitions.h
+OTHER_GENERATED_SRCFILES += SCSchemaDefinitions.c
+OTHER_PUBLIC_HEADERS += SCSchemaDefinitions_10_1.h
OTHER_PUBLIC_HEADERS += SCSchemaDefinitions.h
OTHER_OFILES += SCSchemaDefinitions.o
{
- CURRENTLY_ACTIVE_VERSION = YES;
- DEPLOY_WITH_VERSION_NAME = A;
- DYNAMIC_CODE_GEN = YES;
+ "CURRENTLY_ACTIVE_VERSION" = YES;
+ "DEPLOY_WITH_VERSION_NAME" = A;
+ "DYNAMIC_CODE_GEN" = YES;
FILESTABLE = {
- FRAMEWORKS = (CoreFoundation.framework);
+ FRAMEWORKS = ("CoreFoundation.framework");
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,
- SCP.h,
- SCPPath.h,
- SCDConsoleUser.h,
- SCDHostName.h,
- DHCPClientPreferences.h,
- SCDynamicStoreCopyDHCPInfo.h,
- moh_msg.h,
- moh.h,
- DeviceOnHold.h,
- LinkConfiguration.h,
- dy_framework.h
+ HEADERSEARCH = (
+ "$(NEXT_ROOT)/System/Library/Frameworks/System.framework/PrivateHeaders"
);
- OTHER_LINKED = (
- SCD.c,
- SCDKeys.c,
- SCDPrivate.c,
- SCDPlugin.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,
- SCPLock.c,
- SCPUnlock.c,
- SCPList.c,
- SCPGet.c,
- SCPAdd.c,
- SCPSet.c,
- SCPRemove.c,
- SCPCommit.c,
- SCPApply.c,
- SCPPath.c,
- SCDConsoleUser.c,
- SCDHostName.c,
- SCLocation.c,
- SCNetwork.c,
- SCProxies.c,
- ppp.c,
- v1Compatibility.c,
- DHCP.c,
- moh.c,
- DeviceOnHold.c,
- LinkConfiguration.c,
- dy_framework.c
+ "H_FILES" = (
+ "SystemConfiguration.h",
+ "SCPrivate.h",
+ "SCDPlugin.h",
+ "config_types.h",
+ "SCDynamicStoreInternal.h",
+ "SCDynamicStore.h",
+ "SCDynamicStorePrivate.h",
+ "SCDynamicStoreKey.h",
+ "SCDynamicStoreCopySpecific.h",
+ "SCDynamicStoreCopySpecificPrivate.h",
+ "SCDynamicStoreSetSpecificPrivate.h",
+ "SCPreferencesInternal.h",
+ "SCPreferences.h",
+ "SCPreferencesPrivate.h",
+ "SCPreferencesPath.h",
+ "SCPreferencesSetSpecific.h",
+ "SCNetwork.h",
+ "SCNetworkConnection.h",
+ "SCNetworkReachability.h",
+ "SCValidation.h",
+ "ppp.h",
+ "DHCPClientPreferences.h",
+ "SCDynamicStoreCopyDHCPInfo.h",
+ "moh_msg.h",
+ "moh.h",
+ "DeviceOnHold.h",
+ "LinkConfiguration.h",
+ "dy_framework.h"
);
- OTHER_SOURCES = (
- Makefile.preamble,
+ "OTHER_LIBS" = ();
+ "OTHER_LINKED" = (
+ "SCD.c",
+ "SCDKeys.c",
+ "SCDPrivate.c",
+ "SCDPlugin.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",
+ "SCDNotifierAdd.c",
+ "SCDNotifierRemove.c",
+ "SCDNotifierGetChanges.c",
+ "SCDNotifierWait.c",
+ "SCDNotifierInformViaCallback.c",
+ "SCDNotifierInformViaMachPort.c",
+ "SCDNotifierInformViaFD.c",
+ "SCDNotifierInformViaSignal.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",
+ "SCLocation.c",
+ "SCNetwork.c",
+ "SCNetworkConnection.c",
+ "SCNetworkReachability.c",
+ "SCProxies.c",
+ "ppp.c",
+ "DHCP.c",
+ "moh.c",
+ "DeviceOnHold.c",
+ "LinkConfiguration.c",
+ "dy_framework.c"
+ );
+ "OTHER_SOURCES" = (
+ "Makefile.preamble",
Makefile,
- Makefile.postamble,
- m.template,
- h.template,
- config.defs,
- genSCPreferences.c,
- CustomInfo.plist
+ "Makefile.postamble",
+ "m.template",
+ "h.template",
+ "config.defs",
+ "genSCPreferences.c",
+ "CustomInfo.plist"
);
- PRECOMPILED_HEADERS = ();
- PROJECT_HEADERS = (
- 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,
- SystemConfiguration.h,
- v1Compatibility.h
+ "PRECOMPILED_HEADERS" = ();
+ "PROJECT_HEADERS" = (
+ "SystemConfiguration.h",
+ "SCPrivate.h",
+ "config_types.h",
+ "SCDynamicStoreInternal.h",
+ "SCDynamicStore.h",
+ "SCDynamicStorePrivate.h",
+ "SCDynamicStoreKey.h",
+ "SCDynamicStoreCopySpecific.h",
+ "SCDynamicStoreCopySpecificPrivate.h",
+ "SCDynamicStoreSetSpecificPrivate.h",
+ "SCPreferencesInternal.h",
+ "SCPreferences.h",
+ "SCPreferencesPrivate.h",
+ "SCPreferencesPath.h",
+ "SCPreferencesSetSpecific.h",
+ "SCNetwork.h",
+ "SCNetworkConnection.h",
+ "SCNetworkReachability.h",
+ "SCValidation.h"
);
- PUBLIC_HEADERS = (
- SystemConfiguration.h,
- SCDynamicStore.h,
- SCDynamicStoreKey.h,
- SCDynamicStoreCopySpecific.h,
- SCPreferences.h,
- SCPreferencesPath.h,
- SCPreferencesSetSpecific.h,
- SCNetwork.h,
- DHCPClientPreferences.h,
- SCDynamicStoreCopyDHCPInfo.h
+ "PUBLIC_HEADERS" = (
+ "SystemConfiguration.h",
+ "SCDynamicStore.h",
+ "SCDynamicStoreKey.h",
+ "SCDynamicStoreCopySpecific.h",
+ "SCPreferences.h",
+ "SCPreferencesPath.h",
+ "SCPreferencesSetSpecific.h",
+ "SCNetwork.h",
+ "SCNetworkConnection.h",
+ "SCNetworkReachability.h",
+ "DHCPClientPreferences.h",
+ "SCDynamicStoreCopyDHCPInfo.h"
);
SUBPROJECTS = ();
};
LANGUAGE = English;
MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles";
- NEXTSTEP_BUILDTOOL = /usr/bin/gnumake;
- 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;
- PDO_UNIX_INSTALLDIR = /Library/Frameworks;
- PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac";
- PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc";
+ "NEXTSTEP_BUILDTOOL" = "/usr/bin/gnumake";
+ "NEXTSTEP_COMPILEROPTIONS" = "-fconstant-cfstrings -DBIND_8_COMPAT -DCHECK_IPV6_REACHABILITY";
+ "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";
+ "PDO_UNIX_INSTALLDIR" = "/Library/Frameworks";
+ "PDO_UNIX_JAVA_COMPILER" = "$(JDKBINDIR)/javac";
+ "PDO_UNIX_OBJCPLUS_COMPILER" = "$(NEXTDEV_BIN)/gcc";
PROJECTNAME = SystemConfiguration;
PROJECTTYPE = Framework;
- PROJECTVERSION = 2.8;
- WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make;
- WINDOWS_INSTALLDIR = /Library/Frameworks;
- WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe";
- WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc";
+ PROJECTVERSION = "2.8";
+ "WINDOWS_BUILDTOOL" = "$NEXT_ROOT/Developer/Executables/make";
+ "WINDOWS_INSTALLDIR" = "/Library/Frameworks";
+ "WINDOWS_JAVA_COMPILER" = "$(JDKBINDIR)/javac.exe";
+ "WINDOWS_OBJCPLUS_COMPILER" = "$(DEVDIR)/gcc";
}
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
// from <CoreFoundation/CFVeryPrivate.h>
extern CFStringRef _CFStringCreateWithFormatAndArgumentsAux(CFAllocatorRef alloc, CFStringRef (*copyDescFunc)(void *, CFDictionaryRef), CFDictionaryRef formatOptions, CFStringRef format, va_list arguments);
+#define N_QUICK 32
+
static CFStringRef
_SCCopyDescription(void *info, CFDictionaryRef formatOptions)
{
}
if (type == CFDataGetTypeID()) {
- const u_int8_t *data;
+ const uint8_t *data;
CFIndex dataLen;
CFIndex i;
CFMutableStringRef str;
}
if (type == CFArrayGetTypeID()) {
- const void **elements;
+ const void * elements_q[32];
+ const void ** elements = elements_q;
CFIndex i;
CFIndex nElements;
CFMutableStringRef str;
nElements = CFArrayGetCount(info);
if (nElements > 0) {
- elements = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ if (nElements > (CFIndex)(sizeof(elements_q)/sizeof(CFTypeRef)))
+ elements = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
CFArrayGetValues(info, CFRangeMake(0, nElements), elements);
- for (i=0; i<nElements; i++) {
+ for (i = 0; i < nElements; i++) {
CFMutableStringRef nPrefix1;
CFMutableStringRef nPrefix2;
CFStringRef nStr;
vStr);
CFRelease(vStr);
}
- CFAllocatorDeallocate(NULL, elements);
+ if (elements != elements_q) CFAllocatorDeallocate(NULL, elements);
}
CFStringAppendFormat(str, formatOptions, CFSTR("\n%@}"), prefix2);
}
if (type == CFDictionaryGetTypeID()) {
- const void **keys;
+ const void * keys_q[N_QUICK];
+ const void ** keys = keys_q;
CFIndex i;
CFIndex nElements;
CFMutableStringRef nPrefix1;
CFMutableStringRef nPrefix2;
CFMutableStringRef str;
- const void **values;
+ const void * values_q[N_QUICK];
+ const void ** values = values_q;
str = CFStringCreateMutable(NULL, 0);
CFStringAppendFormat(str, formatOptions, CFSTR("%@<dictionary> {"), prefix1);
nElements = CFDictionaryGetCount(info);
if (nElements > 0) {
- keys = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
- values = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ if (nElements > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
+ keys = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ values = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ }
CFDictionaryGetKeysAndValues(info, keys, values);
- for (i=0; i<nElements; i++) {
+ for (i = 0; i < nElements; i++) {
CFStringRef kStr;
CFStringRef vStr;
vStr);
CFRelease(vStr);
}
- CFAllocatorDeallocate(NULL, keys);
- CFAllocatorDeallocate(NULL, values);
+ if (keys != keys_q) {
+ CFAllocatorDeallocate(NULL, keys);
+ CFAllocatorDeallocate(NULL, values);
+ }
}
CFStringAppendFormat(str, formatOptions, CFSTR("\n%@}"), prefix2);
return str;
}
+ CFRelease(nFormatOptions);
+
{
CFStringRef cfStr;
CFStringRef str;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
-__private_extern__ void
-__SCLog(int level, CFStringRef str)
+static void
+__SCLog(int level, CFStringRef formatString, va_list formatArguments)
{
CFArrayRef lines;
+ CFStringRef str;
+
+#ifdef USE_SCCOPYDESCRIPTION
+ str = _CFStringCreateWithFormatAndArgumentsAux(NULL,
+ _SCCopyDescription,
+ NULL,
+ formatString,
+ formatArguments);
+#else /* USE_SCCOPYDESCRIPTION */
+ str = CFStringCreateWithFormatAndArguments (NULL,
+ NULL,
+ formatString,
+ formatArguments);
+#endif /* !USE_SCCOPYDESCRIPTION */
lines = CFStringCreateArrayBySeparatingStrings(NULL, str, CFSTR("\n"));
+ CFRelease(str);
+
if (lines) {
- int i;
+ int i;
+ int n = CFArrayGetCount(lines);
pthread_mutex_lock(&lock);
- for (i=0; i<CFArrayGetCount(lines); i++) {
+ for (i = 0; i < n; i++) {
CFDataRef line;
line = CFStringCreateExternalRepresentation(NULL,
}
-__private_extern__ void
-__SCPrint(FILE *stream, CFStringRef str)
+static void
+__SCPrint(FILE *stream, CFStringRef formatString, va_list formatArguments, Boolean trace, Boolean addNL)
{
CFDataRef line;
+ CFStringRef str;
+
+#ifdef USE_SCCOPYDESCRIPTION
+ str = _CFStringCreateWithFormatAndArgumentsAux(NULL,
+ _SCCopyDescription,
+ NULL,
+ formatString,
+ formatArguments);
+#else /* USE_SCCOPYDESCRIPTION */
+ str = CFStringCreateWithFormatAndArguments (NULL,
+ NULL,
+ formatString,
+ formatArguments);
+#endif /* !USE_SCCOPYDESCRIPTION */
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);
+ CFRelease(str);
+ if (!line) {
+ return;
+ }
+
+ pthread_mutex_lock(&lock);
+ if (trace) {
+ time_t now = time(NULL);
+ struct tm tm;
+
+ (void)localtime_r(&now, &tm);
+ fprintf(stream, "%2d:%02d:%02d %.*s%s",
+ tm.tm_hour, tm.tm_min, tm.tm_sec,
+ (int)CFDataGetLength(line), CFDataGetBytePtr(line),
+ addNL ? "\n" : "");
+ } else {
+ fprintf(stream, "%.*s%s",
+ (int)CFDataGetLength(line), CFDataGetBytePtr(line),
+ addNL ? "\n" : "");
}
+ fflush (stream);
+ pthread_mutex_unlock(&lock);
+ CFRelease(line);
return;
}
void
SCLog(Boolean condition, int level, CFStringRef formatString, ...)
{
- va_list argList;
- CFStringRef resultString;
+ va_list formatArguments;
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);
-
+ va_start(formatArguments, formatString);
if (_sc_log) {
- __SCLog(level, resultString);
+ __SCLog(level, formatString, formatArguments);
} 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);
+ __SCPrint((LOG_PRI(level) > LOG_NOTICE) ? stderr : stdout,
+ formatString,
+ formatArguments,
+ FALSE, // trace
+ TRUE); // add newline
}
- CFRelease(resultString);
+ va_end(formatArguments);
+
return;
}
void
SCPrint(Boolean condition, FILE *stream, CFStringRef formatString, ...)
{
- va_list argList;
- CFStringRef resultString;
+ va_list formatArguments;
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);
+ va_start(formatArguments, formatString);
+ __SCPrint(stream, formatString, formatArguments, FALSE, FALSE);
+ va_end(formatArguments);
+
+ return;
+}
+
+
+void
+SCTrace(Boolean condition, FILE *stream, CFStringRef formatString, ...)
+{
+ va_list formatArguments;
+
+ if (!condition) {
+ return;
+ }
+
+ va_start(formatArguments, formatString);
+ __SCPrint(stream, formatString, formatArguments, TRUE, FALSE);
+ va_end(formatArguments);
- __SCPrint(stream, resultString);
- CFRelease(resultString);
return;
}
{
int i;
- for (i = 0; i < nSC_ERRMSGS; i++) {
+ for (i = 0; i < (int)nSC_ERRMSGS; i++) {
if (sc_errmsgs[i].status == status) {
return sc_errmsgs[i].message;
}
+++ /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 _SCD_H
-#define _SCD_H
-
-#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 */
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
- CFDataRef xmlKey; /* serialized key */
+ CFDataRef utfKey; /* serialized key */
xmlData_t myKeyRef;
CFIndex myKeyLen;
CFDataRef xmlData; /* serialized data */
int newInstance;
int sc_status;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreAddValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" value = %@"), value);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreAddValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" value = %@"), value);
+ }
if (!store) {
/* sorry, you must provide a session */
}
/* serialize the key */
- if (!_SCSerialize(key, &xmlKey, (void **)&myKeyRef, &myKeyLen)) {
+ if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) {
_SCErrorSet(kSCStatusFailed);
return FALSE;
}
/* serialize the data */
if (!_SCSerialize(value, &xmlData, (void **)&myDataRef, &myDataLen)) {
- CFRelease(xmlKey);
+ CFRelease(utfKey);
_SCErrorSet(kSCStatusFailed);
return FALSE;
}
(int *)&sc_status);
/* clean up */
- CFRelease(xmlKey);
+ CFRelease(utfKey);
CFRelease(xmlData);
if (status != KERN_SUCCESS) {
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
- CFDataRef xmlKey; /* serialized key */
+ CFDataRef utfKey; /* serialized key */
xmlData_t myKeyRef;
CFIndex myKeyLen;
CFDataRef xmlData; /* serialized data */
int newInstance;
int sc_status;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreAddTemporaryValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" value = %@"), value);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreAddTemporaryValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" value = %@"), value);
+ }
if (!store) {
/* sorry, you must provide a session */
}
/* serialize the key */
- if (!_SCSerialize(key, &xmlKey, (void **)&myKeyRef, &myKeyLen)) {
+ if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) {
_SCErrorSet(kSCStatusFailed);
return FALSE;
}
/* serialize the data */
if (!_SCSerialize(value, &xmlData, (void **)&myDataRef, &myDataLen)) {
- CFRelease(xmlKey);
+ CFRelease(utfKey);
_SCErrorSet(kSCStatusFailed);
return FALSE;
}
(int *)&sc_status);
/* clean up */
- CFRelease(xmlKey);
+ CFRelease(utfKey);
CFRelease(xmlData);
if (status != KERN_SUCCESS) {
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Modification History
*
+ * May 1, 2003 Allan Nathanson <ajn@apple.com>
+ * - add console [session] information SPIs
+ *
* June 1, 2001 Allan Nathanson <ajn@apple.com>
* - public API conversion
*
#include <SystemConfiguration/SCValidation.h>
#include <SystemConfiguration/SCPrivate.h>
+
+#ifndef kSCPropUsersConsoleUserName
+#define kSCPropUsersConsoleUserName CFSTR("Name")
+#endif
+
+#ifndef kSCPropUsersConsoleUserUID
+#define kSCPropUsersConsoleUserUID CFSTR("UID")
+#endif
+
+#ifndef kSCPropUsersConsoleUserGID
+#define kSCPropUsersConsoleUserGID CFSTR("GID")
+#endif
+
+#ifndef kSCPropUsersConsoleSessionInfo
+#define kSCPropUsersConsoleSessionInfo CFSTR("SessionInfo")
+#endif
+
+
+const CFStringRef kSCConsoleSessionID = CFSTR("kCGSSessionIDKey"); /* value is CFNumber */
+const CFStringRef kSCConsoleSessionUserName = CFSTR("kCGSSessionUserNameKey"); /* value is CFString */
+const CFStringRef kSCConsoleSessionUID = CFSTR("kCGSSessionUserIDKey"); /* value is CFNumber */
+const CFStringRef kSCConsoleSessionConsoleSet = CFSTR("kCGSSessionConsoleSetKey"); /* value is CFNumber */
+const CFStringRef kSCConsoleSessionOnConsole = CFSTR("kCGSSessionOnConsoleKey"); /* value is CFBoolean */
+
+
CFStringRef
SCDynamicStoreKeyCreateConsoleUser(CFAllocatorRef allocator)
{
if (tempSession) CFRelease(store);
if (dict) CFRelease(dict);
return consoleUser;
+}
+
+
+CFArrayRef
+SCDynamicStoreCopyConsoleInformation(SCDynamicStoreRef store)
+{
+ CFDictionaryRef dict = NULL;
+ CFArrayRef info = NULL;
+ CFStringRef key;
+ Boolean tempSession = FALSE;
+
+ if (!store) {
+ store = SCDynamicStoreCreate(NULL,
+ CFSTR("SCDynamicStoreCopyConsoleUser"),
+ NULL,
+ NULL);
+ if (!store) {
+ SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+ return NULL;
+ }
+ tempSession = TRUE;
+ }
+
+ key = SCDynamicStoreKeyCreateConsoleUser(NULL);
+ dict = SCDynamicStoreCopyValue(store, key);
+ CFRelease(key);
+ if (!isA_CFDictionary(dict)) {
+ _SCErrorSet(kSCStatusNoKey);
+ goto done;
+ }
+ info = CFDictionaryGetValue(dict, kSCPropUsersConsoleSessionInfo);
+ info = isA_CFArray(info);
+ if (!info) {
+ _SCErrorSet(kSCStatusNoKey);
+ goto done;
+ }
+
+ CFRetain(info);
+
+ done :
+
+ if (tempSession) CFRelease(store);
+ if (dict) CFRelease(dict);
+ return info;
+}
+
+
+Boolean
+SCDynamicStoreSetConsoleInformation(SCDynamicStoreRef store,
+ const char *user,
+ uid_t uid,
+ gid_t gid,
+ CFArrayRef sessions)
+{
+ CFStringRef consoleUser;
+ CFMutableDictionaryRef dict = NULL;
+ CFStringRef key = SCDynamicStoreKeyCreateConsoleUser(NULL);
+ CFNumberRef num;
+ Boolean ok = TRUE;
+ Boolean tempSession = FALSE;
+
+ if (!store) {
+ store = SCDynamicStoreCreate(NULL,
+ CFSTR("SCDynamicStoreSetConsoleUser"),
+ NULL,
+ NULL);
+ if (!store) {
+ SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+ return FALSE;
+ }
+ tempSession = TRUE;
+ }
+
+ if (user == NULL) {
+ ok = SCDynamicStoreRemoveValue(store, key);
+ goto done;
+ }
+
+ dict = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ consoleUser = CFStringCreateWithCString(NULL, user, kCFStringEncodingMacRoman);
+ CFDictionarySetValue(dict, kSCPropUsersConsoleUserName, consoleUser);
+ CFRelease(consoleUser);
+
+ num = CFNumberCreate(NULL, kCFNumberSInt32Type, (SInt32 *)&uid);
+ CFDictionarySetValue(dict, kSCPropUsersConsoleUserUID, num);
+ CFRelease(num);
+
+ num = CFNumberCreate(NULL, kCFNumberSInt32Type, (SInt32 *)&gid);
+ CFDictionarySetValue(dict, kSCPropUsersConsoleUserGID, num);
+ CFRelease(num);
+
+ CFDictionarySetValue(dict, kSCPropUsersConsoleSessionInfo, sessions);
+
+ ok = SCDynamicStoreSetValue(store, key, dict);
+
+ done :
+
+ if (dict) CFRelease(dict);
+ if (key) CFRelease(key);
+ if (tempSession) CFRelease(store);
+ return ok;
}
+++ /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 _SCDCONSOLEUSER_H
-#define _SCDCONSOLEUSER_H
-
-#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 */
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
xmlDataOut_t xmlDictRef; /* dict (serialized) */
CFIndex xmlDictLen;
CFDictionaryRef dict = NULL; /* dict (un-serialized) */
+ CFDictionaryRef expDict = NULL; /* dict (un-serialized / expanded) */
int sc_status;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreCopyMultiple:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" keys = %@"), keys);
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" patterns = %@"), patterns);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreCopyMultiple:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" keys = %@"), keys);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" patterns = %@"), patterns);
+ }
if (!store) {
/* sorry, you must provide a session */
}
/* un-serialize the dictionary */
- if (!_SCUnserialize((CFPropertyListRef *)&dict, xmlDictRef, xmlDictLen)) {
+ if (!_SCUnserialize((CFPropertyListRef *)&dict, NULL, xmlDictRef, xmlDictLen)) {
_SCErrorSet(kSCStatusFailed);
return NULL;
}
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" value = %@"), dict);
+ expDict = _SCUnserializeMultiple(dict);
+ CFRelease(dict);
+
+ SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" value = %@"), expDict);
- return dict;
+ return expDict;
}
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
- CFDataRef xmlKey; /* key (XML serialized) */
+ CFDataRef utfKey; /* key (XML serialized) */
xmlData_t myKeyRef; /* key (serialized) */
CFIndex myKeyLen;
xmlDataOut_t xmlDataRef; /* data (serialized) */
int newInstance;
int sc_status;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreCopyValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreCopyValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ }
if (!store) {
/* sorry, you must provide a session */
}
/* serialize the key */
- if (!_SCSerialize(key, &xmlKey, (void **)&myKeyRef, &myKeyLen)) {
+ if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) {
_SCErrorSet(kSCStatusFailed);
return NULL;
}
(int *)&sc_status);
/* clean up */
- CFRelease(xmlKey);
+ CFRelease(utfKey);
if (status != KERN_SUCCESS) {
if (status != MACH_SEND_INVALID_DEST)
}
/* un-serialize the data */
- if (!_SCUnserialize(&data, xmlDataRef, xmlDataLen)) {
+ if (!_SCUnserialize(&data, NULL, xmlDataRef, xmlDataLen)) {
_SCErrorSet(kSCStatusFailed);
return NULL;
}
* Copyright (c) 2000-2002 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
char next = *(scan + 1);
if (prev == '.' || prev == '\0') {
- if (isalpha(ch) == 0) {
+ if (isalnum(ch) == 0) {
+ /* a label must begin with a letter or digit */
return FALSE;
}
} else if (next == '\0' || next == '.') {
if (isalnum(ch) == 0) {
+ /* a label must end with a letter or digit */
return FALSE;
}
} else if (isalnum(ch) == 0) {
case '.':
case '-':
if (prev == '.' || prev == '-') {
+ /* a label cannot begin or end with a hyphen */
return FALSE;
}
break;
default:
+ /* an invalid character */
return FALSE;
break;
}
_SC_CFStringIsValidDNSName(CFStringRef name)
{
Boolean clean = FALSE;
- CFIndex len;
char *str = NULL;
if (!isA_CFString(name)) {
- goto failed;
- }
-
- len = CFStringGetLength(name) + 1;
- if (len == 0) {
- goto failed;
+ return FALSE;
}
- str = CFAllocatorAllocate(NULL, len, 0);
+ str = _SC_cfstring_to_cstring(name, NULL, 0, kCFStringEncodingASCII);
if (str == NULL) {
- goto failed;
- }
-
- if (!CFStringGetCString(name, str, len, kCFStringEncodingASCII)) {
- goto failed;
+ return FALSE;
}
clean = _SC_stringIsValidDNSName(str);
- failed:
-
if (str) CFAllocatorDeallocate(NULL, str);
return clean;
}
Boolean
SCPreferencesSetLocalHostName(SCPreferencesRef session,
- CFStringRef name)
+ CFStringRef name)
{
CFDictionaryRef dict;
CFMutableDictionaryRef newDict = NULL;
CFStringRef path = NULL;
if (name) {
+ CFIndex len;
+
if (!isA_CFString(name)) {
_SCErrorSet(kSCStatusInvalidArgument);
return FALSE;
}
- if (CFStringGetLength(name) == 0) {
+ len = CFStringGetLength(name);
+ if (len > 0) {
+ if (!_SC_CFStringIsValidDNSName(name)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return FALSE;
+ }
+
+ if (CFStringFindWithOptions(name, CFSTR("."), CFRangeMake(0, len), 0, NULL)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return FALSE;
+ }
+ } else {
name = NULL;
}
}
- if (name && !_SC_CFStringIsValidDNSName(name)) {
- _SCErrorSet(kSCStatusInvalidArgument);
- return FALSE;
- }
-
path = CFStringCreateWithFormat(NULL,
NULL,
CFSTR("/%@/%@/%@"),
+++ /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 _SCDHOSTNAME_H
-#define _SCDHOSTNAME_H
-
-#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 */
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
+++ /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 _SCDKEYS_H
-#define _SCDKEYS_H
-
-#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 */
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
- CFDataRef xmlPattern; /* serialized pattern */
+ CFDataRef utfPattern; /* serialized pattern */
xmlData_t myPatternRef;
CFIndex myPatternLen;
xmlDataOut_t xmlDataRef; /* serialized data */
int sc_status;
CFArrayRef allKeys;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreCopyKeyList:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" pattern = %@"), pattern);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreCopyKeyList:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" pattern = %@"), pattern);
+ }
if (!store) {
/* sorry, you must provide a session */
}
/* serialize the pattern */
- if (!_SCSerialize(pattern, &xmlPattern, (void **)&myPatternRef, &myPatternLen)) {
+ if (!_SCSerializeString(pattern, &utfPattern, (void **)&myPatternRef, &myPatternLen)) {
_SCErrorSet(kSCStatusFailed);
return NULL;
}
(int *)&sc_status);
/* clean up */
- CFRelease(xmlPattern);
+ CFRelease(utfPattern);
if (status != KERN_SUCCESS) {
if (status != MACH_SEND_INVALID_DEST)
}
/* un-serialize the list of keys */
- if (!_SCUnserialize((CFPropertyListRef *)&allKeys, xmlDataRef, xmlDataLen)) {
+ if (!_SCUnserialize((CFPropertyListRef *)&allKeys, NULL, xmlDataRef, xmlDataLen)) {
_SCErrorSet(kSCStatusFailed);
return 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
- CFDataRef xmlKey; /* serialized key */
+ CFDataRef utfKey; /* serialized key */
xmlData_t myKeyRef;
CFIndex myKeyLen;
int sc_status;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreAddWatchedKey:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" isRegex = %s"), isRegex ? "TRUE" : "FALSE");
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreAddWatchedKey:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" isRegex = %s"), isRegex ? "TRUE" : "FALSE");
+ }
if (!store) {
/* sorry, you must provide a session */
return FALSE;
}
- /*
- * add new key after checking if key has already been defined
- */
- if (isRegex) {
- if (CFSetContainsValue(storePrivate->reKeys, key)) {
- /* sorry, key already exists in notifier list */
- _SCErrorSet(kSCStatusKeyExists);
- return FALSE;
- }
- CFSetAddValue(storePrivate->reKeys, key); /* add key to this sessions notifier list */
- } else {
- if (CFSetContainsValue(storePrivate->keys, key)) {
- /* sorry, key already exists in notifier list */
- _SCErrorSet(kSCStatusKeyExists);
- return FALSE;
- }
- CFSetAddValue(storePrivate->keys, key); /* add key to this sessions notifier list */
- }
-
/* serialize the key */
- if (!_SCSerialize(key, &xmlKey, (void **)&myKeyRef, &myKeyLen)) {
+ if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) {
_SCErrorSet(kSCStatusFailed);
return FALSE;
}
(int *)&sc_status);
/* clean up */
- CFRelease(xmlKey);
+ CFRelease(utfKey);
if (status != KERN_SUCCESS) {
if (status != MACH_SEND_INVALID_DEST)
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
storePrivate->callbackRunLoopSource,
kCFRunLoopDefaultMode);
CFRelease(storePrivate->callbackRunLoopSource);
+ storePrivate->callbackRunLoop = NULL;
+ storePrivate->callbackRunLoopSource = NULL;
/* invalidate port */
CFMachPortInvalidate(storePrivate->callbackPort);
CFRelease(storePrivate->callbackPort);
+ storePrivate->callbackPort = NULL;
storePrivate->callbackArgument = NULL;
storePrivate->callbackFunction = NULL;
- storePrivate->callbackRunLoop = NULL;
- storePrivate->callbackRunLoopSource = NULL;
- storePrivate->callbackPort = NULL;
break;
default :
break;
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
}
/* un-serialize the list of keys which have changed */
- if (!_SCUnserialize((CFPropertyListRef *)&allKeys, xmlDataRef, xmlDataLen)) {
+ if (!_SCUnserialize((CFPropertyListRef *)&allKeys, NULL, xmlDataRef, xmlDataLen)) {
_SCErrorSet(kSCStatusFailed);
return NULL;
}
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "SCDynamicStoreInternal.h"
#include "config.h" /* MiG generated file */
-#include "v1Compatibility.h"
-
static void
informCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
{
#endif /* DEBUG */
/* remove the run loop source */
- CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
+ CFRunLoopRemoveSource(storePrivate->callbackRunLoop,
storePrivate->callbackRunLoopSource,
kCFRunLoopDefaultMode);
CFRelease(storePrivate->callbackRunLoopSource);
+ storePrivate->callbackRunLoop = NULL;
+ storePrivate->callbackRunLoopSource = NULL;
/* invalidate port */
CFMachPortInvalidate(storePrivate->callbackPort);
CFRelease(storePrivate->callbackPort);
+ storePrivate->callbackPort = NULL;
/* disable notifier */
storePrivate->notifyStatus = NotifierNotRegistered;
storePrivate->callbackArgument = NULL;
storePrivate->callbackFunction = NULL;
- storePrivate->callbackPort = NULL;
- storePrivate->callbackRunLoop = NULL;
- storePrivate->callbackRunLoopSource = NULL;
return;
}
// A simple deallocate won't get rid of all the references we've accumulated
SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" invalidate = %d"), port);
- mach_port_destroy(mach_task_self(), port);
+ (void)mach_port_mod_refs(mach_task_self(), port, MACH_PORT_RIGHT_RECEIVE, -1);
}
storePrivate->callbackRunLoopSource = CFMachPortCreateRunLoopSource(NULL, storePrivate->callbackPort, 0);
}
- CFRunLoopAddSource(rl, storePrivate->callbackRunLoopSource, mode);
+ if (storePrivate->callbackRunLoopSource) {
+ CFRunLoopAddSource(rl, storePrivate->callbackRunLoopSource, mode);
+ }
+
return;
}
SCLog(_sc_verbose, LOG_DEBUG, CFSTR("cancel notifications for mode %@"), mode);
- CFRunLoopRemoveSource(rl, storePrivate->callbackRunLoopSource, mode);
+ if (storePrivate->callbackRunLoopSource) {
+ CFRunLoopRemoveSource(rl, storePrivate->callbackRunLoopSource, mode);
+ }
if (--storePrivate->rlsRefs == 0) {
int sc_status;
SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" cancel callback runloop source"));
- /* remove the run loop source */
- CFRelease(storePrivate->callbackRunLoopSource);
- storePrivate->callbackRunLoopSource = NULL;
+ if (storePrivate->callbackRunLoopSource) {
+ /* remove the run loop source */
+ CFRelease(storePrivate->callbackRunLoopSource);
+ storePrivate->callbackRunLoopSource = NULL;
+ }
- /* invalidate port */
- CFMachPortInvalidate(storePrivate->callbackPort);
- CFRelease(storePrivate->callbackPort);
- storePrivate->callbackPort = NULL;
+ if (storePrivate->callbackPort) {
+ /* invalidate port */
+ CFMachPortInvalidate(storePrivate->callbackPort);
+ CFRelease(storePrivate->callbackPort);
+ storePrivate->callbackPort = NULL;
+ }
- status = notifycancel(storePrivate->server, (int *)&sc_status);
- if (status != KERN_SUCCESS) {
- if (status != MACH_SEND_INVALID_DEST)
+ if (storePrivate->server) {
+ 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;
+ (void) mach_port_destroy(mach_task_self(), storePrivate->server);
+ storePrivate->server = MACH_PORT_NULL;
+ return;
+ }
}
}
return;
}
+
static void
rlsPerform(void *info)
{
return cf;
}
+
static void
rlsRelease(CFTypeRef cf)
{
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
+++ /dev/null
-/*
- * Copyright (c) 2000-2002 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>
- * - public API conversion
- *
- * March 24, 2000 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"
-
-CFArrayRef
-SCDynamicStoreCopyWatchedKeyList(SCDynamicStoreRef store, Boolean isRegex)
-{
- SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
- CFIndex keyCnt;
- CFSetRef keys;
- const void **keyRefs;
- CFArrayRef watchedKeys = NULL;
-
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreCopyWatchedKeyList:"));
-
- keys = isRegex ? storePrivate->reKeys : storePrivate->keys;
- keyCnt = CFSetGetCount(keys);
- if (keyCnt > 0) {
- keyRefs = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
- CFSetGetValues(keys, keyRefs);
- watchedKeys = CFArrayCreate(NULL, keyRefs, keyCnt, &kCFTypeArrayCallBacks);
- CFAllocatorDeallocate(NULL, keyRefs);
- } else {
- watchedKeys = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
- }
-
- return watchedKeys;
-}
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
- CFDataRef xmlKey; /* serialized key */
+ CFDataRef utfKey; /* serialized key */
xmlData_t myKeyRef;
CFIndex myKeyLen;
int sc_status;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreRemoveWatchedKey:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" isRegex = %s"), isRegex ? "TRUE" : "FALSE");
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreRemoveWatchedKey:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" isRegex = %s"), isRegex ? "TRUE" : "FALSE");
+ }
if (!store) {
/* sorry, you must provide a session */
return FALSE;
}
- /*
- * remove key from this sessions notifier list after checking that
- * it was previously defined.
- */
- 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(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 */
- if (!_SCSerialize(key, &xmlKey, (void **)&myKeyRef, &myKeyLen)) {
+ if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) {
_SCErrorSet(kSCStatusFailed);
return FALSE;
}
(int *)&sc_status);
/* clean up */
- CFRelease(xmlKey);
+ CFRelease(utfKey);
if (status != KERN_SUCCESS) {
if (status != MACH_SEND_INVALID_DEST)
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#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);
+ 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;
+ int sc_status;
+
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreSetNotificationKeys:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" keys = %@"), keys);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" patterns = %@"), patterns);
+ }
if (!store) {
/* sorry, you must provide a session */
}
if (storePrivate->server == MACH_PORT_NULL) {
- /* sorry, you must have an open session to play */
_SCErrorSet(kSCStatusNoStoreServer);
- return FALSE;
+ return FALSE; /* you must have an open session to play */
}
- 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 */
+ /* serialize the keys */
if (keys) {
- CFArrayApplyFunction(keys,
- CFRangeMake(0, CFArrayGetCount(keys)),
- addNewKey,
- &myContext);
+ if (!_SCSerialize(keys, &xmlKeys, (void **)&myKeysRef, &myKeysLen)) {
+ _SCErrorSet(kSCStatusFailed);
+ return FALSE;
+ }
}
- /* remove any previously registered patterns */
- myContext.newKeys = patterns;
- myContext.isRegex = TRUE;
- my_CFSetApplyFunction(storePrivate->reKeys, removeOldKey, &myContext);
-
- /* register any new patterns */
+ /* serialize the patterns */
if (patterns) {
- CFArrayApplyFunction(patterns,
- CFRangeMake(0, CFArrayGetCount(patterns)),
- addNewKey,
- &myContext);
+ if (!_SCSerialize(patterns, &xmlPatterns, (void **)&myPatternsRef, &myPatternsLen)) {
+ CFRelease(xmlKeys);
+ _SCErrorSet(kSCStatusFailed);
+ return FALSE;
+ }
+ }
+
+ /* send the keys and patterns, fetch the associated result from the server */
+ status = notifyset(storePrivate->server,
+ myKeysRef,
+ myKeysLen,
+ myPatternsRef,
+ myPatternsLen,
+ (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("notifyset(): %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 myContext.ok;
+ return TRUE;
}
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
- CFDataRef xmlKey; /* serialized key */
+ CFDataRef utfKey; /* serialized key */
xmlData_t myKeyRef;
CFIndex myKeyLen;
int sc_status;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreNotifyValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreNotifyValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ }
if (!store) {
/* sorry, you must provide a session */
return FALSE;
}
- /* serialize the key */
- if (!_SCSerialize(key, &xmlKey, (void **)&myKeyRef, &myKeyLen)) {
- _SCErrorSet(kSCStatusFailed);
- return FALSE;
- }
+ /* serialize the key */
+ if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) {
+ _SCErrorSet(kSCStatusFailed);
+ return FALSE;
+ }
/* send the key to the server */
status = confignotify(storePrivate->server,
(int *)&sc_status);
/* clean up */
- CFRelease(xmlKey);
+ CFRelease(utfKey);
if (status != KERN_SUCCESS) {
if (status != MACH_SEND_INVALID_DEST)
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
static void
__SCDynamicStoreDeallocate(CFTypeRef cf)
{
- CFIndex keyCnt;
int oldThreadState;
int sc_status;
kern_return_t status;
(void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldThreadState);
- /* Remove notification keys */
- keyCnt = CFSetGetCount(storePrivate->keys);
- if (keyCnt > 0) {
- const 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 */
- keyCnt = CFSetGetCount(storePrivate->reKeys);
- if (keyCnt > 0) {
- const 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);
/* release any keys being watched */
CFRelease(storePrivate->keys);
- CFRelease(storePrivate->reKeys);
+ CFRelease(storePrivate->patterns);
return;
}
static pthread_once_t initialized = PTHREAD_ONCE_INIT;
-
static void
__SCDynamicStoreInitialize(void) {
__kSCDynamicStoreTypeID = _CFRuntimeRegisterClass(&__SCDynamicStoreClass);
}
-SCDynamicStoreRef
+SCDynamicStorePrivateRef
__SCDynamicStoreCreatePrivate(CFAllocatorRef allocator,
const CFStringRef name,
SCDynamicStoreCallBack callout,
SCDynamicStoreContext *context)
{
- SCDynamicStorePrivateRef store;
- UInt32 size;
+ uint32_t size;
+ SCDynamicStorePrivateRef storePrivate;
/* initialize runtime */
pthread_once(&initialized, __SCDynamicStoreInitialize);
/* allocate session */
size = sizeof(SCDynamicStorePrivate) - sizeof(CFRuntimeBase);
- store = (SCDynamicStorePrivateRef)_CFRuntimeCreateInstance(allocator,
- __kSCDynamicStoreTypeID,
- size,
- NULL);
- if (!store) {
+ storePrivate = (SCDynamicStorePrivateRef)_CFRuntimeCreateInstance(allocator,
+ __kSCDynamicStoreTypeID,
+ size,
+ NULL);
+ if (!storePrivate) {
return NULL;
}
/* server side of the "configd" session */
- store->server = MACH_PORT_NULL;
+ storePrivate->server = MACH_PORT_NULL;
/* flags */
- store->locked = FALSE;
-
- /* SCDKeys being watched */
- store->keys = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
- store->reKeys = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+ storePrivate->locked = FALSE;
/* Notification status */
- store->notifyStatus = NotifierNotRegistered;
+ storePrivate->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;
+ storePrivate->rlsRefs = 0;
+ storePrivate->rls = NULL;
+ storePrivate->rlsFunction = callout;
+ storePrivate->rlsContext.info = NULL;
+ storePrivate->rlsContext.retain = NULL;
+ storePrivate->rlsContext.release = NULL;
+ storePrivate->rlsContext.copyDescription = NULL;
if (context) {
- bcopy(context, &store->rlsContext, sizeof(SCDynamicStoreContext));
+ bcopy(context, &storePrivate->rlsContext, sizeof(SCDynamicStoreContext));
if (context->retain) {
- store->rlsContext.info = (void *)context->retain(context->info);
+ storePrivate->rlsContext.info = (void *)context->retain(context->info);
}
}
/* "client" information associated with SCDynamicStoreNotifyCallback() */
- store->callbackFunction = NULL;
- store->callbackArgument = NULL;
- store->callbackPort = NULL;
- store->callbackRunLoop = NULL;
- store->callbackRunLoopSource = NULL;
+ storePrivate->callbackFunction = NULL;
+ storePrivate->callbackArgument = NULL;
+ storePrivate->callbackPort = NULL;
+ storePrivate->callbackRunLoop = NULL;
+ storePrivate->callbackRunLoopSource = NULL;
+
+ /* "server" information associated with SCDynamicStoreSetNotificationKeys() */
+ storePrivate->keys = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+ storePrivate->patterns = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
/* "server" information associated with SCDynamicStoreNotifyMachPort(); */
- store->notifyPort = MACH_PORT_NULL;
- store->notifyPortIdentifier = 0;
+ storePrivate->notifyPort = MACH_PORT_NULL;
+ storePrivate->notifyPortIdentifier = 0;
/* "server" information associated with SCDynamicStoreNotifyFileDescriptor(); */
- store->notifyFile = -1;
- store->notifyFileIdentifier = 0;
+ storePrivate->notifyFile = -1;
+ storePrivate->notifyFileIdentifier = 0;
/* "server" information associated with SCDynamicStoreNotifySignal(); */
- store->notifySignal = 0;
- store->notifySignalTask = TASK_NULL;
+ storePrivate->notifySignal = 0;
+ storePrivate->notifySignalTask = TASK_NULL;
- return (SCDynamicStoreRef)store;
+ return storePrivate;
}
SCDynamicStoreCallBack callout,
SCDynamicStoreContext *context)
{
- SCDynamicStoreRef store;
SCDynamicStorePrivateRef storePrivate;
kern_return_t status;
mach_port_t bootstrap_port;
+ CFBundleRef bundle;
+ CFStringRef bundleID = NULL;
mach_port_t server;
char *server_name;
- CFDataRef xmlName; /* serialized name */
+ CFDataRef utfName; /* 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);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreCreate:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" name = %@"), name);
+ }
/*
* allocate and initialize a new session
*/
- store = __SCDynamicStoreCreatePrivate(allocator, name, callout, context);
- storePrivate = (SCDynamicStorePrivateRef)store;
+ storePrivate = __SCDynamicStoreCreatePrivate(allocator, name, callout, context);
status = task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
if (status != KERN_SUCCESS) {
SCLog(_sc_verbose, LOG_DEBUG, CFSTR("task_get_bootstrap_port(): %s"), mach_error_string(status));
- CFRelease(store);
+ CFRelease(storePrivate);
_SCErrorSet(status);
return NULL;
}
break;
case BOOTSTRAP_UNKNOWN_SERVICE :
/* service not currently registered, try again later */
- CFRelease(store);
+ CFRelease(storePrivate);
_SCErrorSet(status);
return NULL;
break;
default :
#ifdef DEBUG
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("bootstrap_status: %s"), mach_error_string(status));
+ SCLog(_sc_verbose, LOG_DEBUG, CFSTR("bootstrap_look_up() failed: status=%d"), status);
#endif /* DEBUG */
- CFRelease(store);
+ CFRelease(storePrivate);
_SCErrorSet(status);
return NULL;
}
/* serialize the name */
- if (!_SCSerialize(name, &xmlName, (void **)&myNameRef, &myNameLen)) {
+ bundle = CFBundleGetMainBundle();
+ if (bundle) {
+ bundleID = CFBundleGetIdentifier(bundle);
+ if (bundleID) {
+ CFRetain(bundleID);
+ } else {
+ CFURLRef url;
+
+ url = CFBundleCopyExecutableURL(bundle);
+ if (url) {
+ bundleID = CFURLCopyPath(url);
+ CFRelease(url);
+ }
+ }
+ }
+
+ if (bundleID) {
+ CFStringRef fullName;
+
+ if (CFEqual(bundleID, CFSTR("/"))) {
+ CFRelease(bundleID);
+ bundleID = CFStringCreateWithFormat(NULL, NULL, CFSTR("(%d)"), getpid());
+ }
+
+ fullName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@:%@"), bundleID, name);
+ name = fullName;
+ CFRelease(bundleID);
+ } else {
+ CFRetain(name);
+ }
+
+ if (!_SCSerializeString(name, &utfName, (void **)&myNameRef, &myNameLen)) {
+ CFRelease(name);
_SCErrorSet(kSCStatusFailed);
return NULL;
}
+ CFRelease(name);
/* open a new session with the server */
status = configopen(server, myNameRef, myNameLen, &storePrivate->server, (int *)&sc_status);
/* clean up */
- CFRelease(xmlName);
+ CFRelease(utfName);
if (status != KERN_SUCCESS) {
if (status != MACH_SEND_INVALID_DEST)
SCLog(_sc_verbose, LOG_DEBUG, CFSTR("configopen(): %s"), mach_error_string(status));
- CFRelease(store);
+ CFRelease(storePrivate);
_SCErrorSet(status);
return NULL;
}
if (sc_status != kSCStatusOK) {
- CFRelease(store);
+ CFRelease(storePrivate);
_SCErrorSet(sc_status);
- return FALSE;
+ return NULL;
}
SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" server port = %d"), storePrivate->server);
- return store;
+ return (SCDynamicStoreRef)storePrivate;
}
CFTypeID
SCDynamicStoreGetTypeID(void) {
+ pthread_once(&initialized, __SCDynamicStoreInitialize); /* initialize runtime */
return __kSCDynamicStoreTypeID;
}
/*
- * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2001-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
*/
#include <fcntl.h>
+#include <paths.h>
#include <pthread.h>
#include <unistd.h>
+#include <sysexits.h>
#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
#include <sys/wait.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
msg.header.msgh_id = 0;
options = MACH_SEND_TIMEOUT;
status = mach_msg(&msg.header, /* msg */
- MACH_SEND_MSG|options, /* options */
- msg.header.msgh_size, /* send_size */
- 0, /* rcv_size */
- MACH_PORT_NULL, /* rcv_name */
- 0, /* timeout */
- MACH_PORT_NULL); /* notify */
+ MACH_SEND_MSG|options, /* options */
+ msg.header.msgh_size, /* send_size */
+ 0, /* rcv_size */
+ MACH_PORT_NULL, /* rcv_name */
+ 0, /* timeout */
+ MACH_PORT_NULL); /* notify */
return;
}
pid_t
-_SCDPluginExecCommand(SCDPluginExecCallBack callout,
- void *context,
- uid_t uid,
- gid_t gid,
- const char *path,
- char * const argv[])
+_SCDPluginExecCommand2(SCDPluginExecCallBack callout,
+ void *context,
+ uid_t uid,
+ gid_t gid,
+ const char *path,
+ char * const argv[],
+ SCDPluginExecSetup setup,
+ void *setupContext
+ )
{
pid_t pid;
pthread_mutex_lock(&lock);
pid = fork();
+
switch (pid) {
case -1 : { /* if error */
int status;
status = errno;
- printf("fork() failed: %s", strerror(status));
+ printf("fork() failed: %s\n", strerror(status));
errno = status;
break;
}
(void) setgid(gid);
}
- /* close any open FDs */
- for (i = getdtablesize()-1; i>=0; i--) close(i);
- open("/dev/null", O_RDWR, 0);
- dup(0);
- dup(0);
+ if (setup) {
+ (setup)(pid, setupContext);
+ } else {
+ /* close any open FDs */
+ for (i = getdtablesize()-1; i>=0; i--) close(i);
+ open(_PATH_DEVNULL, O_RDWR, 0);
+ dup(0);
+ dup(0);
+ }
+
+ /* ensure that our PATH environment variable is somewhat reasonable */
+ if (setenv("PATH", "/bin:/sbin:/usr/bin:/usr/sbin", 0) == -1) {
+ printf("setenv() failed: %s\n", strerror(errno));
+ exit(EX_OSERR);
+ }
/* execute requested command */
(void) execv(path, argv);
}
default : { /* if parent */
+ if (setup) {
+ (setup)(pid, setupContext);
+ }
if (callout) {
childInfoRef child;
return pid;
}
+
+
+pid_t
+_SCDPluginExecCommand(SCDPluginExecCallBack callout,
+ void *context,
+ uid_t uid,
+ gid_t gid,
+ const char *path,
+ char * const argv[])
+{
+ return _SCDPluginExecCommand2(callout, context, uid, gid, path, argv, NULL, NULL);
+}
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*!
- @typedef SCDPluginExecCallBack
+ @typedef SCDPluginExecCallBack
@discussion Type of the callback function used when a child process
started by a plug-in has exited.
@param pid The process id of the child which has exited.
@param rusage A summary of the resources used by the child process
and all its children.
@param context The callback argument specified on the call
- to _SCDPluginExecCommand().
+ to _SCDPluginExecCommand().
*/
typedef void (*SCDPluginExecCallBack) (pid_t pid,
- int status,
- struct rusage *rusage,
- void *context);
+ int status,
+ struct rusage *rusage,
+ void *context);
+
+
+/*!
+ @typedef SCDPluginExecSetup
+ @discussion Type of the setup function used when a child process
+ is being started.
+ @param pid The process id of the child, zero for the child process.
+ @param setupContext The setup argument specified on the call
+ to _SCDPluginExecCommand2().
+ */
+typedef void (*SCDPluginExecSetup) (pid_t pid,
+ void *setupContext);
__BEGIN_DECLS
/*!
@function _SCDPluginExecCommand
- @discussion Starts a child process.
- @param callout The function to be called when the child
+ @discussion Starts a child process.
+ @param callout The function to be called when the child
+ process exits. A NULL value can be specified if no
+ callouts are desired.
+ @param context A argument which will be passed
+ to the callout function.
+ @param uid The desired user id of the child process.
+ @param gid The desired group id of the child process.
+ @param path The command to be executed.
+ @param argv The arguments to be passed to the child process.
+ @result The process ID of the child.
+ */
+pid_t
+_SCDPluginExecCommand (
+ SCDPluginExecCallBack callout,
+ void *context,
+ uid_t uid,
+ gid_t gid,
+ const char *path,
+ char * const argv[]
+ );
+
+/*!
+ @function _SCDPluginExecCommand2
+ @discussion Starts a child process.
+ @param callout The function to be called when the child
process exits. A NULL value can be specified if no
- callouts are desired.
- @param context A argument which will be passed
- to the callout function.
- @param uid The desired user id of the child process.
+ callouts are desired.
+ @param context An argument which will be passed
+ to the callout function.
+ @param uid The desired user id of the child process.
@param gid The desired group id of the child process.
@param path The command to be executed.
@param argv The arguments to be passed to the child process.
- @result The process ID of the child.
+ @param setup A pointer to a function which, if specified, will
+ be called after the call to fork(2) but before the call
+ to exec(3).
+ The function will be called in both the parent and child
+ processes.
+ The process ID returned by fork(2) will be passed as
+ an argument to this function (i.e. non-zero in the parent,
+ zero in the child).
+
+ Note: the setup function is responsibile for establishing
+ (and closing) all file descriptors that are (not) needed
+ by the child process.
+ @param setupContext An argument which will be passed
+ to the setup function.
+ @result The process ID of the child.
*/
pid_t
-_SCDPluginExecCommand (
- SCDPluginExecCallBack callout,
- void *context,
- uid_t uid,
- gid_t gid,
- const char *path,
- char * const argv[]
- );
+_SCDPluginExecCommand2 (
+ SCDPluginExecCallBack callout,
+ void *context,
+ uid_t uid,
+ gid_t gid,
+ const char *path,
+ char * const argv[],
+ SCDPluginExecSetup setup,
+ void *setupContext
+ );
__END_DECLS
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
*/
#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCValidation.h>
#include <SystemConfiguration/SCPrivate.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <pthread.h>
-Boolean
-_SCSerialize(CFPropertyListRef obj,
- CFDataRef *xml,
- void **dataRef,
- CFIndex *dataLen)
+#define N_QUICK 32
+
+
+char *
+_SC_cfstring_to_cstring(CFStringRef cfstr, char *buf, int bufLen, CFStringEncoding encoding)
{
- CFDataRef myXml;
+ CFIndex last;
+ CFIndex len = CFStringGetLength(cfstr);
+
+ /* how much buffer space will we really need? */
+ (void)CFStringGetBytes(cfstr,
+ CFRangeMake(0, len),
+ encoding,
+ 0,
+ FALSE,
+ NULL,
+ 0,
+ &len);
+
+ if (!buf) {
+ bufLen = len + 1;
+ buf = CFAllocatorAllocate(NULL, bufLen, 0);
+ if (!buf) {
+ return NULL;
+ }
+ }
- if (!obj) {
- /* if no object to serialize */
- return FALSE;
+ if (len >= bufLen) {
+ len = bufLen - 1;
}
+ (void)CFStringGetBytes(cfstr,
+ CFRangeMake(0, len),
+ encoding,
+ 0,
+ FALSE,
+ buf,
+ bufLen,
+ &last);
+ buf[last] = '\0';
+
+ return buf;
+}
+
+
+Boolean
+_SCSerialize(CFPropertyListRef obj, CFDataRef *xml, void **dataRef, CFIndex *dataLen)
+{
+ CFDataRef myXml;
+
if (!xml && !(dataRef && dataLen)) {
/* if not keeping track of allocated space */
return FALSE;
Boolean
-_SCUnserialize(CFPropertyListRef *obj,
- void *dataRef,
- CFIndex dataLen)
+_SCUnserialize(CFPropertyListRef *obj, CFDataRef xml, void *dataRef, CFIndex dataLen)
{
- kern_return_t status;
- CFDataRef xml;
- CFStringRef xmlError;
+ CFStringRef xmlError;
- if (!obj) {
- return FALSE;
- }
+ if (!xml) {
+ kern_return_t status;
- xml = CFDataCreate(NULL, (void *)dataRef, dataLen);
- status = vm_deallocate(mach_task_self(), (vm_address_t)dataRef, dataLen);
- if (status != KERN_SUCCESS) {
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
- /* non-fatal???, proceed */
+ xml = CFDataCreateWithBytesNoCopy(NULL, (void *)dataRef, dataLen, kCFAllocatorNull);
+ *obj = CFPropertyListCreateFromXMLData(NULL,
+ xml,
+ kCFPropertyListImmutable,
+ &xmlError);
+ CFRelease(xml);
+
+ status = vm_deallocate(mach_task_self(), (vm_address_t)dataRef, dataLen);
+ if (status != KERN_SUCCESS) {
+ SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+ /* non-fatal???, proceed */
+ }
+ } else {
+ *obj = CFPropertyListCreateFromXMLData(NULL,
+ xml,
+ kCFPropertyListImmutable,
+ &xmlError);
}
- *obj = CFPropertyListCreateFromXMLData(NULL,
- xml,
- kCFPropertyListImmutable,
- &xmlError);
- CFRelease(xml);
- if (!obj) {
+ if (*obj == NULL) {
if (xmlError) {
SCLog(TRUE,
LOG_ERR,
}
+Boolean
+_SCSerializeString(CFStringRef str, CFDataRef *data, void **dataRef, CFIndex *dataLen)
+{
+ CFDataRef myData;
+
+ if (!isA_CFString(str)) {
+ /* if not a CFString */
+ return FALSE;
+ }
+
+ if (!data && !(dataRef && dataLen)) {
+ /* if not keeping track of allocated space */
+ return FALSE;
+ }
+
+ myData = CFStringCreateExternalRepresentation(NULL, str, kCFStringEncodingUTF8, 0);
+ if (!myData) {
+ SCLog(TRUE, LOG_ERR, CFSTR("CFStringCreateExternalRepresentation() failed"));
+ if (data) *data = NULL;
+ if (dataRef) *dataRef = NULL;
+ if (dataLen) *dataLen = 0;
+ return FALSE;
+ }
+
+ if (data) {
+ *data = myData;
+ if (dataRef) {
+ *dataRef = (void *)CFDataGetBytePtr(myData);
+ }
+ if (dataLen) {
+ *dataLen = CFDataGetLength(myData);
+ }
+ } else {
+ kern_return_t status;
+
+ *dataLen = CFDataGetLength(myData);
+ status = vm_allocate(mach_task_self(), (void *)dataRef, *dataLen, TRUE);
+ if (status != KERN_SUCCESS) {
+ SCLog(TRUE,
+ LOG_ERR,
+ CFSTR("vm_allocate(): %s"),
+ mach_error_string(status));
+ CFRelease(myData);
+ *dataRef = NULL;
+ *dataLen = 0;
+ return FALSE;
+ }
+
+ bcopy((char *)CFDataGetBytePtr(myData), *dataRef, *dataLen);
+ CFRelease(myData);
+ }
+
+ return TRUE;
+}
+
+
+Boolean
+_SCUnserializeString(CFStringRef *str, CFDataRef utf8, void *dataRef, CFIndex dataLen)
+{
+ if (!utf8) {
+ kern_return_t status;
+
+ utf8 = CFDataCreateWithBytesNoCopy(NULL, dataRef, dataLen, kCFAllocatorNull);
+ *str = CFStringCreateFromExternalRepresentation(NULL, utf8, kCFStringEncodingUTF8);
+ CFRelease(utf8);
+
+ status = vm_deallocate(mach_task_self(), (vm_address_t)dataRef, dataLen);
+ if (status != KERN_SUCCESS) {
+ SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+ /* non-fatal???, proceed */
+ }
+ } else {
+ *str = CFStringCreateFromExternalRepresentation(NULL, utf8, kCFStringEncodingUTF8);
+ }
+
+ if (*str == NULL) {
+ SCLog(TRUE, LOG_ERR, CFSTR("CFStringCreateFromExternalRepresentation() failed"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+Boolean
+_SCSerializeData(CFDataRef data, void **dataRef, CFIndex *dataLen)
+{
+ kern_return_t status;
+
+ if (!isA_CFData(data)) {
+ /* if not a CFData */
+ return FALSE;
+ }
+
+ *dataLen = CFDataGetLength(data);
+ status = vm_allocate(mach_task_self(), (void *)dataRef, *dataLen, TRUE);
+ if (status != KERN_SUCCESS) {
+ SCLog(TRUE,
+ LOG_ERR,
+ CFSTR("vm_allocate(): %s"),
+ mach_error_string(status));
+ *dataRef = NULL;
+ *dataLen = 0;
+ return FALSE;
+ }
+
+ bcopy((char *)CFDataGetBytePtr(data), *dataRef, *dataLen);
+
+ return TRUE;
+}
+
+
+Boolean
+_SCUnserializeData(CFDataRef *data, void *dataRef, CFIndex dataLen)
+{
+ kern_return_t status;
+
+ *data = CFDataCreate(NULL, dataRef, dataLen);
+ status = vm_deallocate(mach_task_self(), (vm_address_t)dataRef, dataLen);
+ if (status != KERN_SUCCESS) {
+ SCLog(_sc_verbose, LOG_DEBUG, CFSTR("vm_deallocate(): %s"), mach_error_string(status));
+ _SCErrorSet(kSCStatusFailed);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+CFDictionaryRef
+_SCSerializeMultiple(CFDictionaryRef dict)
+{
+ const void * keys_q[N_QUICK];
+ const void ** keys = keys_q;
+ CFIndex nElements;
+ CFDictionaryRef newDict = NULL;
+ const void * pLists_q[N_QUICK];
+ const void ** pLists = pLists_q;
+ const void * values_q[N_QUICK];
+ const void ** values = values_q;
+
+ nElements = CFDictionaryGetCount(dict);
+ if (nElements > 0) {
+ CFIndex i;
+
+ if (nElements > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
+ keys = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ values = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ pLists = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ }
+ bzero(pLists, nElements * sizeof(CFTypeRef));
+
+ CFDictionaryGetKeysAndValues(dict, keys, values);
+ for (i = 0; i < nElements; i++) {
+ if (!_SCSerialize((CFPropertyListRef)values[i], (CFDataRef *)&pLists[i], NULL, NULL)) {
+ goto done;
+ }
+ }
+ }
+
+ newDict = CFDictionaryCreate(NULL,
+ keys,
+ pLists,
+ nElements,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ done :
+
+ if (nElements > 0) {
+ CFIndex i;
+
+ for (i = 0; i < nElements; i++) {
+ if (pLists[i]) CFRelease(pLists[i]);
+ }
+
+ if (keys != keys_q) {
+ CFAllocatorDeallocate(NULL, keys);
+ CFAllocatorDeallocate(NULL, values);
+ CFAllocatorDeallocate(NULL, pLists);
+ }
+ }
+
+ return newDict;
+}
+
+
+CFDictionaryRef
+_SCUnserializeMultiple(CFDictionaryRef dict)
+{
+ const void * keys_q[N_QUICK];
+ const void ** keys = keys_q;
+ CFIndex nElements;
+ CFDictionaryRef newDict = NULL;
+ const void * pLists_q[N_QUICK];
+ const void ** pLists = pLists_q;
+ const void * values_q[N_QUICK];
+ const void ** values = values_q;
+
+ nElements = CFDictionaryGetCount(dict);
+ if (nElements > 0) {
+ CFIndex i;
+
+ if (nElements > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
+ keys = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ values = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ pLists = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ }
+ bzero(pLists, nElements * sizeof(CFTypeRef));
+
+ CFDictionaryGetKeysAndValues(dict, keys, values);
+ for (i = 0; i < nElements; i++) {
+ if (!_SCUnserialize((CFPropertyListRef *)&pLists[i], values[i], NULL, NULL)) {
+ goto done;
+ }
+ }
+ }
+
+ newDict = CFDictionaryCreate(NULL,
+ keys,
+ pLists,
+ nElements,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ done :
+
+ if (nElements > 0) {
+ CFIndex i;
+
+ for (i = 0; i < nElements; i++) {
+ if (pLists[i]) CFRelease(pLists[i]);
+ }
+
+ if (keys != keys_q) {
+ CFAllocatorDeallocate(NULL, keys);
+ CFAllocatorDeallocate(NULL, values);
+ CFAllocatorDeallocate(NULL, pLists);
+ }
+ }
+
+ return newDict;
+}
+
+
void
__showMachPortStatus()
{
status = mach_port_names(mach_task_self(), &ports, &pn, &types, &tn);
if (status == MACH_MSG_SUCCESS) {
str = CFStringCreateMutable(NULL, 0);
- for (pi=0; pi < pn; pi++) {
+ for (pi = 0; pi < pn; pi++) {
char rights[16], *rp = &rights[0];
if (types[pi] != MACH_PORT_TYPE_NONE) {
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
- CFDataRef xmlKey; /* serialized key */
+ CFDataRef utfKey; /* serialized key */
xmlData_t myKeyRef;
CFIndex myKeyLen;
int sc_status;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreRemoveValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreRemoveValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ }
if (!store) {
/* sorry, you must provide a session */
}
/* serialize the key */
- if (!_SCSerialize(key, &xmlKey, (void **)&myKeyRef, &myKeyLen)) {
+ if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) {
_SCErrorSet(kSCStatusFailed);
return FALSE;
}
(int *)&sc_status);
/* clean up */
- CFRelease(xmlKey);
+ CFRelease(utfKey);
if (status != KERN_SUCCESS) {
if (status != MACH_SEND_INVALID_DEST)
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "SCDynamicStoreInternal.h"
#include "config.h" /* MiG generated file */
+
Boolean
SCDynamicStoreSetMultiple(SCDynamicStoreRef store,
CFDictionaryRef keysToSet,
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 (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreSetMultiple:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" keysToSet = %@"), keysToSet);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" keysToRemove = %@"), keysToRemove);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" keysToNotify = %@"), keysToNotify);
+ }
if (!store) {
/* sorry, you must provide a session */
/* serialize the key/value pairs to set*/
if (keysToSet) {
- if (!_SCSerialize(keysToSet, &xmlSet, (void **)&mySetRef, &mySetLen)) {
+ CFDictionaryRef newInfo;
+ Boolean ok;
+
+ newInfo = _SCSerializeMultiple(keysToSet);
+ if (!newInfo) {
+ _SCErrorSet(kSCStatusFailed);
+ return NULL;
+ }
+
+ ok = _SCSerialize(newInfo, &xmlSet, (void **)&mySetRef, &mySetLen);
+ CFRelease(newInfo);
+
+ if (!ok) {
_SCErrorSet(kSCStatusFailed);
return NULL;
}
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
- CFDataRef xmlKey; /* serialized key */
+ CFDataRef utfKey; /* serialized key */
xmlData_t myKeyRef;
CFIndex myKeyLen;
CFDataRef xmlData; /* serialized data */
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 (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreSetValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" value = %@"), value);
+ }
if (!store) {
/* sorry, you must provide a session */
}
/* serialize the key */
- if (!_SCSerialize(key, &xmlKey, (void **)&myKeyRef, &myKeyLen)) {
+ if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) {
_SCErrorSet(kSCStatusFailed);
- return NULL;
+ return FALSE;
}
/* serialize the data */
if (!_SCSerialize(value, &xmlData, (void **)&myDataRef, &myDataLen)) {
- CFRelease(xmlKey);
+ CFRelease(utfKey);
_SCErrorSet(kSCStatusFailed);
- return NULL;
+ return FALSE;
}
/* send the key & data to the server, get new instance id */
(int *)&sc_status);
/* clean up */
- CFRelease(xmlKey);
+ CFRelease(utfKey);
CFRelease(xmlData);
if (status != KERN_SUCCESS) {
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
kern_return_t status;
- CFDataRef xmlKey; /* serialized key */
+ CFDataRef utfKey; /* serialized key */
xmlData_t myKeyRef;
CFIndex myKeyLen;
int sc_status;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCDynamicStoreTouchValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCDynamicStoreTouchValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ }
if (!store) {
/* sorry, you must provide a session */
}
/* serialize the key */
- if (!_SCSerialize(key, &xmlKey, (void **)&myKeyRef, &myKeyLen)) {
+ if (!_SCSerializeString(key, &utfKey, (void **)&myKeyRef, &myKeyLen)) {
_SCErrorSet(kSCStatusFailed);
return FALSE;
}
(int *)&sc_status);
/* clean up */
- CFRelease(xmlKey);
+ CFRelease(utfKey);
if (status != KERN_SUCCESS) {
if (status != MACH_SEND_INVALID_DEST)
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
* Copyright (c) 2001-2002 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
*/
CFStringRef
SCDynamicStoreCopyConsoleUser (
- SCDynamicStoreRef session,
+ SCDynamicStoreRef store,
uid_t *uid,
gid_t *gid
);
If NULL, a temporary session will be used.
@result A string representing the current "location" identifier;
NULL if no "location" identifier has been defined or if an error
- was encountered.
+ was encountered.
You must release the returned value.
*/
CFStringRef
-SCDynamicStoreCopyLocation (
+SCDynamicStoreCopyLocation (
SCDynamicStoreRef store
);
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCDYNAMICSTORECOPYSPECIFICPRIVATE_H
+#define _SCDYNAMICSTORECOPYSPECIFICPRIVATE_H
+
+#include <sys/cdefs.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SCDynamicStore.h>
+
+
+/*!
+ @header SCDynamicStoreCopySpecificPrivate.h
+ The following APIs allow an application to retrieve console
+ information.
+ */
+
+
+__BEGIN_DECLS
+
+/*
+ * Predefined keys for the console session dictionaries
+ */
+extern const CFStringRef kSCConsoleSessionID; /* value is CFNumber */
+extern const CFStringRef kSCConsoleSessionUserName; /* value is CFString */
+extern const CFStringRef kSCConsoleSessionUID; /* value is CFNumber */
+extern const CFStringRef kSCConsoleSessionConsoleSet; /* value is CFNumber */
+extern const CFStringRef kSCConsoleSessionOnConsole; /* value is CFBoolean */
+
+/*!
+ @function SCDynamicStoreCopyConsoleInformation
+ @discussion Returns information about all console sessions on the system.
+ @param store An SCDynamicStoreRef that should be used for communication
+ with the server.
+ If NULL, a temporary session will be used.
+ @result An array of dictionaries containing information about each
+ console session on the system; NULL if no sessions are defined
+ or if an error was encountered.
+
+ The contents of the returned array match that of the CoreGraphics
+ CGSCopySessionList() SPI.
+
+ You must release the returned value.
+ */
+CFArrayRef
+SCDynamicStoreCopyConsoleInformation (
+ SCDynamicStoreRef store
+ );
+
+
+__END_DECLS
+
+#endif /* _SCDYNAMICSTORECOPYSPECIFICPRIVATE_H */
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
Using_NotifierInformViaMachPort,
Using_NotifierInformViaFD,
Using_NotifierInformViaSignal,
- Using_NotifierInformViaRunLoop,
+ Using_NotifierInformViaRunLoop
} __SCDynamicStoreNotificationStatus;
/* SCDynamicStoreKeys being watched */
CFMutableSetRef keys;
- CFMutableSetRef reKeys;
+ CFMutableSetRef patterns;
/* current status of notification requests */
__SCDynamicStoreNotificationStatus notifyStatus;
__BEGIN_DECLS
-SCDynamicStoreRef
+SCDynamicStorePrivateRef
__SCDynamicStoreCreatePrivate (CFAllocatorRef allocator,
const CFStringRef name,
SCDynamicStoreCallBack callout,
SCDynamicStoreContext *context);
-void
-__SCLog (int level,
- CFStringRef str);
-
-void
-__SCPrint (FILE *stream,
- CFStringRef str);
-
void
__showMachPortStatus ();
* Copyright (c) 2000-2002 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
CFStringRef key,
Boolean isRegex);
-CFArrayRef
-SCDynamicStoreCopyWatchedKeyList (SCDynamicStoreRef store,
- Boolean isRegex);
-
/*!
@function SCDynamicStoreNotifyCallback
@discussion Requests that the specified function be called whenever a
/*
- * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2001-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
__BEGIN_DECLS
+/*!
+ @function SCDynamicStoreSetConsoleInformation
+ @discussion Returns information about all console users on the system.
+ @param store 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/primary "Console" session. If NULL, any current
+ "Console" session information will be reset.
+ @param uid The user ID of the current/primary "Console" user.
+ @param gid The group ID of the current/primary "Console" user.
+ @param sessions An array of dictionaries containing information about
+ each console session on the system; NULL if no sessions are
+ defined.
+
+ The contents of this array should match that of the CoreGraphics
+ CGSCopySessionList() SPI.
+
+ @result A boolean indicating the success (or failure) of the call.
+ */
+Boolean
+SCDynamicStoreSetConsoleInformation (
+ SCDynamicStoreRef store,
+ const char *user,
+ uid_t uid,
+ gid_t gid,
+ CFArrayRef sessions
+ );
+
/*!
@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
+ @param store 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
*/
Boolean
SCDynamicStoreSetConsoleUser (
- SCDynamicStoreRef session,
+ SCDynamicStoreRef store,
const char *user,
uid_t uid,
gid_t gid
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Modification History
*
+ * January 19, 2003 Allan Nathanson <ajn@apple.com>
+ * - add advanced reachability APIs
+ *
* June 10, 2001 Allan Nathanson <ajn@apple.com>
* - updated to use service-based "State:" information
*
* - initial revision
*/
-#include <SystemConfiguration/SystemConfiguration.h>
-#include <SystemConfiguration/SCPrivate.h>
-#include <SystemConfiguration/SCValidation.h>
-
+#include <sys/types.h>
#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <netdb.h>
-#include <resolv.h>
#include <unistd.h>
-#include <sys/ioctl.h>
#include <sys/socket.h>
-#include <net/if.h>
-
-#include "ppp.h"
-
-static int
-inet_atonCF(CFStringRef cfStr, struct in_addr *addr)
-{
- char cStr[sizeof("255.255.255.255")];
-
- if (!CFStringGetCString(cfStr, cStr, sizeof(cStr), kCFStringEncodingMacRoman)) {
- return 0;
- }
-
- return inet_aton(cStr, addr);
-}
-
-
-/*
- * Function: parse_component
- * Purpose:
- * Given a string 'key' and a string prefix 'prefix',
- * return the next component in the slash '/' separated
- * key.
- *
- * Examples:
- * 1. key = "a/b/c" prefix = "a/"
- * returns "b"
- * 2. key = "a/b/c" prefix = "a/b/"
- * returns "c"
- */
-static CFStringRef
-parse_component(CFStringRef key, CFStringRef prefix)
-{
- CFMutableStringRef comp;
- CFRange range;
-
- if (CFStringHasPrefix(key, prefix) == FALSE) {
- return NULL;
- }
- comp = CFStringCreateMutableCopy(NULL, 0, key);
- CFStringDelete(comp, CFRangeMake(0, CFStringGetLength(prefix)));
- range = CFStringFind(comp, CFSTR("/"), 0);
- if (range.location == kCFNotFound) {
- return comp;
- }
- range.length = CFStringGetLength(comp) - range.location;
- CFStringDelete(comp, range);
- return comp;
-}
-
-
-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)
-{
- initContextRef info = (initContextRef)context;
- CFStringRef interface;
- CFStringRef interfaceKey;
- CFStringRef service;
- CFStringRef serviceKey;
-
- if (!isA_CFString(key) || !isA_CFDictionary(value)) {
- return;
- }
-
- 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);
- }
- CFRelease(serviceKey);
-
- if (!CFArrayContainsValue(info->order, CFRangeMake(0, CFArrayGetCount(info->order)), service)) {
- CFArrayAppendValue(info->order, service);
- }
-
- 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);
- }
- CFRelease(serviceKey);
-
- if (!CFArrayContainsValue(info->order, CFRangeMake(0, CFArrayGetCount(info->order)), service)) {
- CFArrayAppendValue(info->order, service);
- }
-
- CFRelease(service);
- return;
- }
-
- 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;
-}
-
-
-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;
- }
-
- 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;
- }
-
- 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;
- }
-
- done :
-
- CFRelease(service);
- return;
-}
-
-
-static void
-removeKnownAddresses(const void *key, const void *value, void *context)
-{
- CFMutableDictionaryRef ifDict;
- CFStringRef ifName;
- CFMutableDictionaryRef interfaces = (CFMutableDictionaryRef)context;
- CFMutableDictionaryRef serviceDict = (CFMutableDictionaryRef)value;
- Boolean updated = FALSE;
-
- 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;
- }
-
- ifDict = (CFMutableDictionaryRef)CFDictionaryGetValue(interfaces, ifName);
- if (!ifDict) {
- /* if the indicated interface is not active */
- return;
- }
-
- sAddrs = isA_CFArray(CFDictionaryGetValue(serviceDict,
- kSCPropNetIPv4Addresses));
- sDests = isA_CFArray(CFDictionaryGetValue(serviceDict,
- kSCPropNetIPv4DestAddresses));
- sMasks = isA_CFArray(CFDictionaryGetValue(serviceDict,
- kSCPropNetIPv4SubnetMasks));
-
- if (!sAddrs || ((n = CFArrayGetCount(sAddrs)) == 0)) {
- /* if no addresses */
- return;
- }
-
- if (((sMasks == NULL) && (sDests == NULL)) ||
- ((sMasks != NULL) && (sDests != NULL))) {
- /*
- * sorry, we expect to have "SubnetMasks" or
- * "DestAddresses" (not both).
- */
- return;
- }
-
- if (sMasks && (n != CFArrayGetCount(sMasks))) {
- /* if we don't like the "SubnetMasks" */
- return;
- }
-
- if (sDests && (n != CFArrayGetCount(sDests))) {
- /* if we don't like the "DestAddresses" */
- return;
- }
-
- iAddrs = isA_CFArray(CFDictionaryGetValue(ifDict,
- kSCPropNetIPv4Addresses));
- iDests = isA_CFArray(CFDictionaryGetValue(ifDict,
- kSCPropNetIPv4DestAddresses));
- iMasks = isA_CFArray(CFDictionaryGetValue(ifDict,
- kSCPropNetIPv4SubnetMasks));
-
- if (((iMasks == NULL) && (iDests == NULL)) ||
- ((iMasks != NULL) && (iDests != NULL))) {
- /*
- * sorry, we expect to have "SubnetMasks" or
- * "DestAddresses" (not both).
- */
- return;
- }
-
- if (!iAddrs || ((i = CFArrayGetCount(iAddrs)) == 0)) {
- /* if no addresses */
- return;
- }
-
- 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;
- }
-
- if (((sMasks == NULL) && (iMasks != NULL)) ||
- ((sDests == NULL) && (iDests != NULL))) {
- /* if our addressing schemes are in conflict */
- return;
- }
-
- 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;
- }
- }
- }
-
- 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;
-}
-
-
-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;
- }
-
- /* 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
-getAddresses(CFDictionaryRef iDict,
- CFIndex *nAddrs,
- CFArrayRef *addrs,
- CFArrayRef *masks,
- CFArrayRef *dests)
-{
- *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 == NULL) && (*dests == NULL)) ||
- ((*masks != NULL) && (*dests != NULL))) {
- /*
- * sorry, we expect to have "SubnetMasks" or
- * "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 Boolean
-checkAddress(SCDynamicStoreRef store,
- const struct sockaddr *address,
- const int addrlen,
- CFDictionaryRef config,
- CFDictionaryRef active,
- CFArrayRef serviceOrder,
- struct in_addr *defaultRoute,
- SCNetworkConnectionFlags *flags)
-{
- CFIndex aCnt;
- CFStringRef aType = NULL;
- CFDictionaryRef cDict = NULL;
- CFIndex i;
- CFStringRef key = NULL;
- int pppRef = -1;
- int sc_status = kSCStatusReachabilityUnknown;
- char *statusMessage = NULL;
-
- if (!address || !flags) {
- sc_status = kSCStatusInvalidArgument;
- goto done;
- }
-
- *flags = 0;
-
- if (address->sa_family == AF_INET) {
- struct sockaddr_in *sin = (struct sockaddr_in *)address;
-
- 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
- */
- aCnt = CFArrayGetCount(serviceOrder);
- for (i=0; i<aCnt; i++) {
- CFDictionaryRef aDict;
- CFArrayRef addrs;
- CFArrayRef dests;
- CFIndex j;
- CFArrayRef masks;
- CFIndex nAddrs = 0;
-
- key = CFArrayGetValueAtIndex(serviceOrder, i);
- aDict = CFDictionaryGetValue(active, key);
-
- if (!aDict ||
- !getAddresses(aDict, &nAddrs, &addrs, &masks, &dests)) {
- /* if no addresses to check */
- continue;
- }
-
- 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;
-
- if (inet_atonCF(CFArrayGetValueAtIndex(masks, j),
- &ifMask) == 0) {
- /* if SubnetMask 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 */
- statusMessage = "isReachable (my subnet)";
- *flags |= kSCNetworkFlagsReachable;
- goto checkInterface;
- }
- } else {
- struct in_addr destAddr;
-
- /* check remote address */
- if (inet_atonCF(CFArrayGetValueAtIndex(dests, j),
- &destAddr) == 0) {
- /* if DestAddresses string is invalid */
- break;
- }
- /* check local address */
- if (ntohl(sin->sin_addr.s_addr) == ntohl(ifAddr.s_addr)) {
- /* the address is our side of the link */
- 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 */
- statusMessage = "isReachable (my remote address)";
- *flags |= kSCNetworkFlagsReachable;
- goto checkInterface;
- }
- }
- }
- }
-
- /*
- * Check if the address is accessible via the "default" route.
- */
- for (i=0; i<aCnt; i++) {
- CFDictionaryRef aDict;
- CFArrayRef addrs;
- CFArrayRef dests;
- CFIndex j;
- CFArrayRef masks;
- CFIndex nAddrs = 0;
-
- key = CFArrayGetValueAtIndex(serviceOrder, i);
- aDict = CFDictionaryGetValue(active, key);
-
- if (!sin->sin_addr.s_addr ||
- !defaultRoute ||
- !aDict ||
- !getAddresses(aDict, &nAddrs, &addrs, &masks, &dests)) {
- /* if no addresses to check */
- continue;
- }
-
- for (j=0; defaultRoute && j<nAddrs; j++) {
- if (masks) {
- struct in_addr ifAddr;
- struct in_addr ifMask;
-
- if (inet_atonCF(CFArrayGetValueAtIndex(addrs, j),
- &ifAddr) == 0) {
- /* if Addresses string is invalid */
- break;
- }
-
- if (inet_atonCF(CFArrayGetValueAtIndex(masks, j),
- &ifMask) == 0) {
- /* if SubnetMasks string is invalid */
- break;
- }
-
- if ((ntohl(ifAddr.s_addr) & ntohl(ifMask.s_addr)) ==
- (ntohl(defaultRoute->s_addr) & ntohl(ifMask.s_addr))) {
- /* the requested address is on this subnet */
- statusMessage = "isReachable via default route (my subnet)";
- *flags |= kSCNetworkFlagsReachable;
- goto checkInterface;
- }
- } else {
- struct in_addr destAddr;
-
- /* check remote address */
- if (inet_atonCF(CFArrayGetValueAtIndex(dests, j),
- &destAddr) == 0) {
- /* if DestAddresses string is invalid */
- break;
- }
-
- if (ntohl(destAddr.s_addr) == ntohl(defaultRoute->s_addr)) {
- /* the address is the other side of the link */
- statusMessage = "isReachable via default route (my remote address)";
- *flags |= kSCNetworkFlagsReachable;
- goto checkInterface;
- }
- }
- }
- }
-
- /*
- * Check the not active (but configured) IPv4 services
- */
- for (i=0; i<aCnt; i++) {
- key = CFArrayGetValueAtIndex(serviceOrder, i);
-
- if (CFDictionaryContainsKey(active, key)) {
- /* if this service is active */
- continue;
- }
-
- cDict = CFDictionaryGetValue(config, key);
- if (!cDict) {
- /* if no configuration for this service */
- continue;
- }
-
- /*
- * 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.
- */
- aType = CFDictionaryGetValue(cDict, kSCPropNetInterfaceType);
- if (!aType || !CFEqual(aType, kSCValNetInterfaceTypePPP)) {
- /* if we can't get a connection on this service */
- sc_status = kSCStatusOK;
- goto done;
- }
-
- statusMessage = "is configured w/dynamic addressing";
- *flags |= kSCNetworkFlagsTransientConnection;
- *flags |= kSCNetworkFlagsReachable;
- *flags |= kSCNetworkFlagsConnectionRequired;
-
- if (_sc_debug) {
- SCLog(TRUE, LOG_INFO, CFSTR(" status = %s"), statusMessage);
- SCLog(TRUE, LOG_INFO, CFSTR(" service id = %@"), key);
- }
-
- sc_status = kSCStatusOK;
- goto done;
- }
-
- SCLog(_sc_debug, LOG_INFO, CFSTR(" cannot be reached"));
- sc_status = kSCStatusOK;
- goto done;
-
- } else {
- /*
- * if no code for this address family (yet)
- */
- SCLog(_sc_verbose, LOG_ERR,
- CFSTR("checkAddress(): unexpected address family %d"),
- address->sa_family);
- sc_status = kSCStatusInvalidArgument;
- goto done;
- }
-
- 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.
- */
- {
- CFNumberRef num;
- CFDictionaryRef cDict;
-
- /* attempt to get the interface type from the config info */
- cDict = CFDictionaryGetValue(config, key);
- if (cDict) {
- aType = CFDictionaryGetValue(cDict, kSCPropNetInterfaceType);
- }
-
- 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(cDict, kSCPropNetPPPDialOnDemand);
- if (num) {
- int dialOnDemand;
-
- CFNumberGetValue(num, kCFNumberIntType, &dialOnDemand);
- if (dialOnDemand != 0) {
- *flags |= kSCNetworkFlagsConnectionAutomatic;
- }
-
- }
- }
-
- *flags |= kSCNetworkFlagsTransientConnection;
-
- {
- u_int32_t pppLink;
- struct ppp_status *pppLinkStatus;
- int pppStatus;
-
- /*
- * The service ID is available, ask the PPP controller
- * for the extended status.
- */
- pppStatus = PPPInit(&pppRef);
- if (pppStatus != 0) {
- SCLog(_sc_debug, LOG_DEBUG, CFSTR(" PPPInit() failed: status=%d"), pppStatus);
- sc_status = kSCStatusReachabilityUnknown;
- goto done;
- }
-
- pppStatus = PPPGetLinkByServiceID(pppRef, key, &pppLink);
- if (pppStatus != 0) {
- SCLog(_sc_debug, LOG_DEBUG, CFSTR(" PPPGetLinkByServiceID() failed: status=%d"), pppStatus);
- sc_status = kSCStatusReachabilityUnknown;
- goto done;
- }
-
- pppStatus = PPPStatus(pppRef, pppLink, &pppLinkStatus);
- if (pppStatus != 0) {
- SCLog(_sc_debug, LOG_DEBUG, CFSTR(" PPPStatus() failed: status=%d"), pppStatus);
- sc_status = kSCStatusReachabilityUnknown;
- goto done;
- }
-#ifdef DEBUG
- SCLog(_sc_debug, LOG_DEBUG, CFSTR(" PPP link status = %d"), pppLinkStatus->status);
-#endif /* DEBUG */
- switch (pppLinkStatus->status) {
- case PPP_RUNNING :
- /* if we're really UP and RUNNING */
- break;
- case PPP_ONHOLD :
- /* if we're effectively UP and RUNNING */
- break;
- case PPP_IDLE :
- /* if we're not connected at all */
- 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 */
- SCLog(_sc_debug, LOG_INFO, CFSTR(" PPP link, connection in progress"));
- *flags |= kSCNetworkFlagsReachable;
- *flags |= kSCNetworkFlagsConnectionRequired;
- sc_status = kSCStatusOK;
- break;
- }
- CFAllocatorDeallocate(NULL, pppLinkStatus);
- }
-
- goto done;
-
- done :
-
- if (pppRef != -1) (void) PPPDispose(pppRef);
-
- if (sc_status != kSCStatusOK) {
- _SCErrorSet(sc_status);
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-static void
-_CheckReachabilityInit(SCDynamicStoreRef store,
- CFDictionaryRef *config,
- CFDictionaryRef *active,
- CFArrayRef *serviceOrder,
- struct in_addr **defaultRoute)
-{
- 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);
-
- /*
- * collect information on the configured services and their
- * associated interface type.
- */
- keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
- patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
-
- /*
- * Setup:/Network/Global/IPv4 (for the ServiceOrder)
- */
- orderKey = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
- kSCDynamicStoreDomainSetup,
- kSCEntNetIPv4);
- CFArrayAppendValue(keys, orderKey);
-
- /*
- * 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 the ServiceOrder key from the global settings.
- */
- 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;
- } else {
- *defaultRoute = route;
- }
- }
- }
-
- /*
- * collect the configured services, the active services, and
- * the active interfaces.
- */
- 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);
-
- /*
- * add additional information for the configured services
- */
- CFDictionaryApplyFunction(dict, collectExtraInfo, &context);
-
- /*
- * 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
- 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
-_CheckReachabilityFree(CFDictionaryRef config,
- CFDictionaryRef active,
- CFArrayRef serviceOrder,
- struct in_addr *defaultRoute)
-{
- if (config) CFRelease(config);
- if (active) CFRelease(active);
- if (serviceOrder) CFRelease(serviceOrder);
- if (defaultRoute) CFAllocatorDeallocate(NULL, defaultRoute);
- return;
-}
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#ifndef kSCEntNetRefreshConfiguration
+#define kSCEntNetRefreshConfiguration CFSTR("RefreshConfiguration")
+#endif kSCEntNetRefreshConfiguration
Boolean
SCNetworkCheckReachabilityByAddress(const struct sockaddr *address,
const int addrlen,
SCNetworkConnectionFlags *flags)
{
- CFDictionaryRef active = NULL;
- CFDictionaryRef config = NULL;
- struct in_addr *defaultRoute = NULL;
+ SCNetworkReachabilityRef networkAddress;
Boolean ok;
- CFArrayRef serviceOrder = NULL;
- SCDynamicStoreRef store = NULL;
-
- *flags = 0;
+ struct sockaddr_storage ss;
- /*
- * 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;
- }
- }
-
- store = SCDynamicStoreCreate(NULL,
- CFSTR("SCNetworkCheckReachabilityByAddress"),
- NULL,
- NULL);
- if (!store) {
- SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+ if (!address ||
+ (addrlen == 0) ||
+ (addrlen > (int)sizeof(struct sockaddr_storage))) {
+ _SCErrorSet(kSCStatusInvalidArgument);
return FALSE;
}
- _CheckReachabilityInit(store, &config, &active, &serviceOrder, &defaultRoute);
- ok = checkAddress(store,
- address,
- addrlen,
- config,
- active,
- serviceOrder,
- defaultRoute,
- flags);
- _CheckReachabilityFree(config, active, serviceOrder, defaultRoute);
+ bzero(&ss, sizeof(ss));
+ bcopy(address, &ss, addrlen);
+ ss.ss_len = addrlen;
- CFRelease(store);
+ networkAddress = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&ss);
+ ok = SCNetworkReachabilityGetFlags(networkAddress, flags);
+ CFRelease(networkAddress);
return ok;
}
-/*
- * rankReachability()
- * Not reachable == 0
- * Connection Required == 1
- * Reachable == 2
- */
-static int
-rankReachability(int flags)
-{
- 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;
-#ifdef CHECK_IPV6_REACHABILITY
- struct addrinfo *res = NULL;
- struct addrinfo *resP;
-#endif /* CHECK_IPV6_REACHABILITY */
- CFArrayRef serviceOrder = NULL;
- SCDynamicStoreRef store = NULL;
+ SCNetworkReachabilityRef networkAddress;
+ Boolean ok;
- store = SCDynamicStoreCreate(NULL,
- CFSTR("SCNetworkCheckReachabilityByName"),
- NULL,
- NULL);
- if (!store) {
- SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+ if (!nodename) {
+ _SCErrorSet(kSCStatusInvalidArgument);
return FALSE;
}
- _CheckReachabilityInit(store, &config, &active, &serviceOrder, &defaultRoute);
-
- /*
- * 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++) {
- 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 */
- *flags = ns_flags;
- }
- }
-
- 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.
- */
- *flags = 0;
-
- /*
- * resolve the nodename into an address
- */
-
-#ifdef CHECK_IPV6_REACHABILITY
- i = getaddrinfo(nodename, NULL, NULL, &res);
- if (i != 0) {
- SCLog(_sc_verbose, LOG_ERR,
- CFSTR("getaddrinfo() failed: %s"),
- gai_strerror(i));
- goto done;
- }
-
- for (resP=res; resP!=NULL; resP=resP->ai_next) {
- 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;
- }
- }
+ networkAddress = SCNetworkReachabilityCreateWithName(NULL, nodename);
+ ok = SCNetworkReachabilityGetFlags(networkAddress, flags);
+ CFRelease(networkAddress);
+ return ok;
+}
- 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 */
- *flags = ns_flags;
- if (rankReachability(*flags) == 2) {
- /* we're in luck */
- break;
- }
- }
- }
+Boolean
+SCNetworkInterfaceRefreshConfiguration(CFStringRef ifName)
+{
+ CFStringRef key;
+ Boolean ret = FALSE;
+ SCDynamicStoreRef store = NULL;
- if (res) {
+ store = SCDynamicStoreCreate(NULL,
+ CFSTR("SCNetworkInterfaceRefreshConfiguration"),
+ NULL, NULL);
+ if (store == NULL) {
goto done;
}
+ key = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
+ kSCDynamicStoreDomainState,
+ ifName,
+ kSCEntNetRefreshConfiguration);
+ ret = SCDynamicStoreNotifyValue(store, key);
+ CFRelease(key);
- /*
- * The getaddrinfo() function call didn't return any addresses. While
- * this may be the correct answer we have found that some DNS servers
- * may, depending on what has been cached, not return all available
- * records when issued a T_ANY query. To accomodate these servers
- * we double check by using the gethostbyname() function which uses
- * a simple T_A query.
- */
-
-#ifdef DEBUG
- SCLog(_sc_debug,
- LOG_INFO,
- CFSTR("getaddrinfo() returned no addresses, try gethostbyname()"));
-#endif /* DEBUG */
-#endif /* CHECK_IPV6_REACHABILITY */
-
- h = gethostbyname(nodename);
- if (h && h->h_length) {
- struct in_addr **s = (struct in_addr **)h->h_addr_list;
-
- 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;
-
- 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 */
- *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:
+ if (store != NULL) {
+ CFRelease(store);
}
-
- done :
-
- _CheckReachabilityFree(config, active, serviceOrder, defaultRoute);
- if (store) CFRelease(store);
-#ifdef CHECK_IPV6_REACHABILITY
- if (res) freeaddrinfo(res);
-#endif /* CHECK_IPV6_REACHABILITY */
-
- return ok;
+ return (ret);
}
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*!
@header SCNetwork
+
+ SCNetworkCheckReachabilityXXX()
+
The SCNetworkCheckReachabilityXXX() APIs allow an application to
- determine the status of the system's current network configuration.
+ determine the status of the system's current network configuration
+ and the accessibility of a target host/address.
The term "reachable" reflects whether a data packet, sent by
- an application into the network stack, will be able to reach
- the destination host.
+ an application into the network stack, can be sent to the
+ the target host/address. Please note that their is no
+ guarantee that the data packet will actually be received by
+ the host.
- 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 system's current
- configuration.
+ SCNetworkInterfaceRefreshConfiguration()
+
+ This API sends a notification to interested network configuration
+ agents to retry their configuraton immediately. For example, calling
+ this API will cause the DHCP client to contact the DHCP server
+ immediately rather than waiting until its timeout has expired.
+ The utility of this API is to allow the caller to give a hint to
+ the system that the network infrastructure/configuration has changed.
*/
/*!
form of user intervention will be required to establish
this connection (e.g. providing a password, authentication
token, etc.).
- */
-typedef enum {
- kSCNetworkFlagsTransientConnection = 1<<0,
- kSCNetworkFlagsReachable = 1<<1,
- kSCNetworkFlagsConnectionRequired = 1<<2,
- kSCNetworkFlagsConnectionAutomatic = 1<<3,
- kSCNetworkFlagsInterventionRequired = 1<<4,
-} SCNetworkConnectionFlags;
+ @constant kSCNetworkFlagsIsLocalAddress
+ This flag indicates that the specified nodename/address
+ is one associated with a network interface on the current
+ system.
+
+ @constant kSCNetworkFlagsIsDirect
+ This flag indicates that network traffic to the specified
+ nodename/address will not go through a gateway but is routed
+ directly to one of the interfaces in the system.
+ */
+enum {
+ kSCNetworkFlagsTransientConnection = 1<<0,
+ kSCNetworkFlagsReachable = 1<<1,
+ kSCNetworkFlagsConnectionRequired = 1<<2,
+ kSCNetworkFlagsConnectionAutomatic = 1<<3,
+ kSCNetworkFlagsInterventionRequired = 1<<4,
+ kSCNetworkFlagsIsLocalAddress = 1<<16,
+ kSCNetworkFlagsIsDirect = 1<<17
+};
+typedef uint32_t SCNetworkConnectionFlags;
__BEGIN_DECLS
@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 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
Boolean
SCNetworkCheckReachabilityByAddress (
const struct sockaddr *address,
- const int addrlen,
+ int addrlen,
SCNetworkConnectionFlags *flags
);
@function SCNetworkCheckReachabilityByName
@discussion Determines if the given network host/node name is
reachable using the current network configuration.
-
- 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 that will be filled with a
const char *nodename,
SCNetworkConnectionFlags *flags
);
-
+/*!
+ @function SCNetworkInterfaceRefreshConfiguration
+ @discussion Sends a notification to interested configuration agents
+ to have them immediately retry their configuration over a
+ particular network interface.
+ Note: This API must be invoked by root (uid == 0).
+
+ @param ifName The BSD name of the network interface e.g. CFSTR("en0").
+ @result TRUE if the notification was sent; FALSE otherwise.
+ */
+Boolean
+SCNetworkInterfaceRefreshConfiguration (
+ CFStringRef ifName
+ );
__END_DECLS
#endif /* _SCNETWORK_H */
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Modification History
+ *
+ * December 20, 2002 Christophe Allie <callie@apple.com>
+ * - initial revision
+ */
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFRuntime.h>
+
+#include <Security/Security.h>
+#include "dy_framework.h"
+
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCPrivate.h>
+#include <SystemConfiguration/SCValidation.h>
+
+#include <pthread.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+#include "ppp.h"
+
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+typedef struct {
+
+ /* base CFType information */
+ CFRuntimeBase cfBase;
+
+ /* service ID */
+ CFStringRef serviceID; /* serviceID */
+
+ int eventRef; /* ref to PPP controller for event messages */
+ CFSocketRef eventRefCF; /* ref to PPP controller for event messages */
+ int controlRef; /* ref to PPP controller for control messages */
+ //u_int32_t status; /* current status of the connection */
+ //char ifname[IFNAMSIZ]; /* ppp interface used for this connection */
+
+ /* run loop source, callout, context, rl scheduling info */
+ CFRunLoopSourceRef rls;
+ SCNetworkConnectionCallBack rlsFunction;
+ SCNetworkConnectionContext rlsContext;
+ CFMutableArrayRef rlList;
+
+} SCNetworkConnectionPrivate, *SCNetworkConnectionPrivateRef;
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+static __inline__ CFTypeRef
+isA_SCNetworkConnection(CFTypeRef obj)
+{
+ return (isA_CFType(obj, SCNetworkConnectionGetTypeID()));
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+static CFStringRef
+__SCNetworkConnectionCopyDescription(CFTypeRef cf)
+{
+ CFAllocatorRef allocator = CFGetAllocator(cf);
+ CFMutableStringRef result;
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)cf;
+
+ result = CFStringCreateMutable(allocator, 0);
+ CFStringAppendFormat(result, NULL, CFSTR("<SCNetworkConnection, %p [%p]> {\n"), cf, allocator);
+ CFStringAppendFormat(result, NULL, CFSTR(" serviceID = %@ \n"), connectionPrivate->serviceID);
+ CFStringAppendFormat(result, NULL, CFSTR("}"));
+
+ return result;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+static void
+__SCNetworkConnectionDeallocate(CFTypeRef cf)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)cf;
+
+ SCLog(_sc_verbose, LOG_DEBUG, CFSTR("__SCNetworkConnectionDeallocate:"));
+
+ /* release resources */
+ if (connectionPrivate->eventRef != -1) {
+ while (CFArrayGetCount(connectionPrivate->rlList)) {
+ CFRunLoopRef runLoop;
+ CFStringRef runLoopMode;
+
+ runLoop = (CFRunLoopRef)CFArrayGetValueAtIndex(connectionPrivate->rlList, 1);
+ runLoopMode = CFArrayGetValueAtIndex(connectionPrivate->rlList, 2);
+ CFRunLoopRemoveSource(runLoop, connectionPrivate->rls, runLoopMode);
+
+ CFArrayRemoveValueAtIndex(connectionPrivate->rlList, 2);
+ CFArrayRemoveValueAtIndex(connectionPrivate->rlList, 1);
+ CFArrayRemoveValueAtIndex(connectionPrivate->rlList, 0);
+ }
+ CFRelease(connectionPrivate->rls);
+ CFRelease(connectionPrivate->rlList);
+ //PPPDispose(connectionPrivate->eventRef);
+ CFSocketInvalidate(connectionPrivate->eventRefCF);
+ CFRelease(connectionPrivate->eventRefCF);
+ }
+ if (connectionPrivate->controlRef != -1)
+ PPPDispose(connectionPrivate->controlRef);
+ if (connectionPrivate->rlsContext.release)
+ connectionPrivate->rlsContext.release(connectionPrivate->rlsContext.info);
+ if (connectionPrivate->serviceID)
+ CFRelease(connectionPrivate->serviceID);
+
+ return;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+static pthread_once_t initialized = PTHREAD_ONCE_INIT;
+
+static CFTypeID __kSCNetworkConnectionTypeID = _kCFRuntimeNotATypeID;
+
+static const CFRuntimeClass __SCNetworkConnectionClass = {
+ 0, // version
+ "SCNetworkConnection", // className
+ NULL, // init
+ NULL, // copy
+ __SCNetworkConnectionDeallocate, // dealloc
+ NULL, // equal
+ NULL, // hash
+ NULL, // copyFormattingDesc
+ __SCNetworkConnectionCopyDescription // copyDebugDesc
+};
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+static void
+__SCNetworkConnectionInitialize(void)
+{
+ __kSCNetworkConnectionTypeID = _CFRuntimeRegisterClass(&__SCNetworkConnectionClass);
+ return;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+static SCNetworkConnectionPrivateRef
+__SCNetworkConnectionCreatePrivate(CFAllocatorRef allocator, CFStringRef serviceID)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate = 0;
+ uint32_t size;
+ struct ppp_status *stats = 0;
+ int error = kSCStatusFailed;
+
+ /* initialize runtime */
+ pthread_once(&initialized, __SCNetworkConnectionInitialize);
+
+ SCLog(_sc_verbose, LOG_DEBUG, CFSTR("__SCNetworkConnectionCreatePrivate:"));
+
+ /* allocate NetworkConnection */
+ size = sizeof(SCNetworkConnectionPrivate) - sizeof(CFRuntimeBase);
+ connectionPrivate = (SCNetworkConnectionPrivateRef)_CFRuntimeCreateInstance(allocator, __kSCNetworkConnectionTypeID,size, NULL);
+ if (connectionPrivate == 0)
+ goto fail;
+
+ /* zero the data structure */
+ bzero(((u_char*)connectionPrivate)+sizeof(CFRuntimeBase), size);
+
+ /* save the serviceID */
+ connectionPrivate->serviceID = CFStringCreateCopy(NULL, serviceID);
+
+ connectionPrivate->controlRef = -1;
+ connectionPrivate->eventRef = -1;
+
+ if (PPPInit(&connectionPrivate->controlRef))
+ goto fail;
+
+ if (PPPStatus(connectionPrivate->controlRef, serviceID, 0, &stats)) {
+ error = kSCStatusInvalidArgument; // XXX can't get status, invalid service id
+ goto fail;
+ }
+
+ CFAllocatorDeallocate(NULL, stats);
+ stats = 0;
+
+ /* success, return the connection reference */
+ return connectionPrivate;
+
+ fail:
+
+ /* failure, clean up and leave */
+ if (connectionPrivate)
+ CFRelease(connectionPrivate);
+ if (stats)
+ CFAllocatorDeallocate(NULL, stats);
+ _SCErrorSet(error);
+ return NULL;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+CFTypeID
+SCNetworkConnectionGetTypeID (void) {
+ pthread_once(&initialized, __SCNetworkConnectionInitialize); /* initialize runtime */
+ return __kSCNetworkConnectionTypeID;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+static SCNetworkConnectionStatus
+__SCNetworkConnectionConvertStatus (int state)
+{
+ SCNetworkConnectionStatus status = kSCNetworkConnectionDisconnected;
+
+ switch (state) {
+ case PPP_INITIALIZE:
+ case PPP_CONNECTLINK:
+ case PPP_ESTABLISH:
+ case PPP_AUTHENTICATE:
+ case PPP_CALLBACK:
+ case PPP_NETWORK:
+ case PPP_WAITONBUSY:
+ status = kSCNetworkConnectionConnecting;
+ break;
+ case PPP_TERMINATE:
+ case PPP_DISCONNECTLINK:
+ case PPP_HOLDOFF:
+ status = kSCNetworkConnectionDisconnecting;
+ break;
+ case PPP_RUNNING:
+ case PPP_ONHOLD:
+ status = kSCNetworkConnectionConnected;
+ break;
+ case PPP_IDLE:
+ case PPP_STATERESERVED:
+ default:
+ status = kSCNetworkConnectionDisconnected;
+ }
+ return status;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+SCNetworkConnectionRef
+SCNetworkConnectionCreateWithServiceID (CFAllocatorRef allocator,
+ CFStringRef serviceID,
+ SCNetworkConnectionCallBack callout,
+ SCNetworkConnectionContext *context)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate;
+
+ if (!isA_CFString(serviceID)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ connectionPrivate = __SCNetworkConnectionCreatePrivate(allocator, serviceID);
+
+ if (connectionPrivate) {
+ connectionPrivate->rlsFunction = callout;
+ if (context) {
+ bcopy(context, &connectionPrivate->rlsContext, sizeof(SCNetworkConnectionContext));
+ if (context->retain) {
+ connectionPrivate->rlsContext.info = (void *)context->retain(context->info);
+ }
+ }
+ }
+
+ return (SCNetworkConnectionRef)connectionPrivate;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+CFStringRef
+SCNetworkConnectionCopyServiceID (SCNetworkConnectionRef connection)
+{
+ if (!isA_SCNetworkConnection(connection)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ return CFRetain(((SCNetworkConnectionPrivateRef)connection)->serviceID);
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+CFDictionaryRef
+SCNetworkConnectionCopyStatistics (SCNetworkConnectionRef connection)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)connection;
+ int error = kSCStatusFailed;
+ struct ppp_status *stats = 0;
+ CFMutableDictionaryRef dict = 0;
+ CFMutableDictionaryRef statsdict = 0;
+
+#define ADDNUMBER(d, k, n) \
+{ \
+ CFNumberRef num; \
+ num = CFNumberCreate(NULL, kCFNumberSInt32Type, n); \
+ if (num) { \
+ CFDictionaryAddValue(d, k, num); \
+ CFRelease(num); \
+ } \
+}
+
+ if (!isA_SCNetworkConnection(connection)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ /* get status and check connected state */
+ if (PPPStatus(connectionPrivate->controlRef, connectionPrivate->serviceID, 0, &stats))
+ goto fail;
+
+ if (__SCNetworkConnectionConvertStatus(stats->status) != kSCNetworkConnectionConnected)
+ goto fail;
+
+ /* create dictionaries */
+ if ((statsdict = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)) == 0)
+ goto fail;
+
+ if ((dict = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)) == 0)
+ goto fail;
+
+ /* add statistics */
+ ADDNUMBER(dict, kSCNetworkConnectionBytesIn, &stats->s.run.inBytes);
+ ADDNUMBER(dict, kSCNetworkConnectionBytesOut, &stats->s.run.outBytes);
+ ADDNUMBER(dict, kSCNetworkConnectionPacketsIn, &stats->s.run.inPackets);
+ ADDNUMBER(dict, kSCNetworkConnectionPacketsOut, &stats->s.run.outPackets);
+ ADDNUMBER(dict, kSCNetworkConnectionErrorsIn, &stats->s.run.inErrors);
+ ADDNUMBER(dict, kSCNetworkConnectionErrorsOut, &stats->s.run.outErrors);
+
+ /* add the PPP dictionary to the statistics dictionary */
+ CFDictionaryAddValue(statsdict, kSCEntNetPPP, dict);
+ CFRelease(dict);
+
+ /* done */
+ CFAllocatorDeallocate(NULL, stats);
+ return statsdict;
+
+ fail:
+
+ if (stats)
+ CFAllocatorDeallocate(NULL, stats);
+ if (dict)
+ CFRelease(dict);
+ if (statsdict)
+ CFRelease(statsdict);
+ _SCErrorSet(error);
+ return NULL;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+SCNetworkConnectionStatus
+SCNetworkConnectionGetStatus (SCNetworkConnectionRef connection)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)connection;
+ struct ppp_status *stats = 0;
+ SCNetworkConnectionStatus status;
+
+ if (!isA_SCNetworkConnection(connection)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ if (PPPStatus(connectionPrivate->controlRef, connectionPrivate->serviceID, 0, &stats))
+ return kSCNetworkConnectionDisconnected; // XXX
+
+ status = __SCNetworkConnectionConvertStatus(stats->status);
+
+ CFAllocatorDeallocate(NULL, stats);
+ return status;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+CFDictionaryRef
+SCNetworkConnectionCopyExtendedStatus (SCNetworkConnectionRef connection)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)connection;
+ CFPropertyListRef status = 0;
+ void *data = 0;
+ u_int32_t datalen;
+
+ if (!isA_SCNetworkConnection(connection)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ if (PPPExtendedStatus(connectionPrivate->controlRef, connectionPrivate->serviceID, 0, &data, &datalen))
+ goto fail;
+
+ if (!data
+ || !(status = PPPUnserialize(data, datalen))
+ || !isA_CFDictionary(status))
+ goto fail;
+
+ CFAllocatorDeallocate(NULL, data);
+ return status;
+
+ fail:
+
+ _SCErrorSet(kSCStatusFailed);
+ if (status)
+ CFRelease(status);
+ if (data)
+ CFAllocatorDeallocate(NULL, data);
+ return NULL;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+Boolean
+SCNetworkConnectionStart (SCNetworkConnectionRef connection,
+ CFDictionaryRef userOptions,
+ Boolean linger)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)connection;
+ CFDataRef dataref = 0;
+ void *data = 0;
+ u_int32_t datalen = 0;
+
+ if (!isA_SCNetworkConnection(connection)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ if (userOptions && !(dataref = PPPSerialize(userOptions, &data, &datalen)))
+ goto fail;
+
+ if (PPPConnect(connectionPrivate->controlRef, connectionPrivate->serviceID, 0, data, datalen, linger))
+ goto fail;
+
+ if (dataref)
+ CFRelease(dataref);
+
+ /* connection is now started */
+ return TRUE;
+
+ fail:
+
+ if (dataref)
+ CFRelease(dataref);
+ _SCErrorSet(kSCStatusFailed); // XXX
+ return FALSE;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+Boolean
+SCNetworkConnectionStop (SCNetworkConnectionRef connection,
+ Boolean forceDisconnect)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)connection;
+
+ if (!isA_SCNetworkConnection(connection)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return FALSE;
+ }
+
+ if (PPPDisconnect(connectionPrivate->controlRef, connectionPrivate->serviceID, 0, forceDisconnect)) {
+ _SCErrorSet(kSCStatusFailed);
+ return FALSE;
+ }
+
+ /* connection is now disconnecting */
+ return TRUE;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+Boolean
+SCNetworkConnectionSuspend (SCNetworkConnectionRef connection)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)connection;
+
+ if (!isA_SCNetworkConnection(connection)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ if (PPPSuspend(connectionPrivate->controlRef, connectionPrivate->serviceID, 0)) {
+ _SCErrorSet(kSCStatusFailed);
+ return FALSE;
+ }
+
+ /* connection is now suspended */
+ return TRUE;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+Boolean
+SCNetworkConnectionResume (SCNetworkConnectionRef connection)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)connection;
+
+ if (!isA_SCNetworkConnection(connection)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ if (PPPResume(connectionPrivate->controlRef, connectionPrivate->serviceID, 0)) {
+ _SCErrorSet(kSCStatusFailed);
+ return FALSE;
+ }
+
+ /* connection is now resume */
+ return TRUE;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+CFDictionaryRef
+SCNetworkConnectionCopyUserOptions (SCNetworkConnectionRef connection)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)connection;
+ void *data = 0;
+ u_int32_t datalen;
+ CFPropertyListRef userOptions = 0;
+
+ if (!isA_SCNetworkConnection(connection)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ if (PPPGetConnectData(connectionPrivate->controlRef, connectionPrivate->serviceID, 0, &data, &datalen))
+ goto fail;
+
+ // no data were used, return an empty dictionary
+ if (data == 0) {
+ CFDictionaryRef dict;
+
+ dict = CFDictionaryCreateMutable(NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ if (dict == 0)
+ _SCErrorSet(kSCStatusFailed); // XXX
+ return dict;
+ }
+
+ userOptions = PPPUnserialize(data, datalen);
+ if (!isA_CFDictionary(userOptions))
+ goto fail;
+
+ CFAllocatorDeallocate(NULL, data);
+ return userOptions;
+
+ fail:
+
+ _SCErrorSet(kSCStatusFailed);
+ if (userOptions)
+ CFRelease(userOptions);
+ if (data)
+ CFAllocatorDeallocate(NULL, data);
+ return NULL;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+static Boolean
+__isScheduled(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode, CFMutableArrayRef rlList)
+{
+ CFIndex i;
+ CFIndex n = CFArrayGetCount(rlList);
+
+ for (i = 0; i < n; i += 3) {
+ if (obj && !CFEqual(obj, CFArrayGetValueAtIndex(rlList, i))) {
+ continue;
+ }
+ if (runLoop && !CFEqual(runLoop, CFArrayGetValueAtIndex(rlList, i+1))) {
+ continue;
+ }
+ if (runLoopMode && !CFEqual(runLoopMode, CFArrayGetValueAtIndex(rlList, i+2))) {
+ continue;
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+static void
+__schedule(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode, CFMutableArrayRef rlList)
+{
+ CFArrayAppendValue(rlList, obj);
+ CFArrayAppendValue(rlList, runLoop);
+ CFArrayAppendValue(rlList, runLoopMode);
+
+ return;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+static Boolean
+__unschedule(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode, CFMutableArrayRef rlList, Boolean all)
+{
+ CFIndex i = 0;
+ Boolean found = FALSE;
+ CFIndex n = CFArrayGetCount(rlList);
+
+ while (i < n) {
+ if (obj && !CFEqual(obj, CFArrayGetValueAtIndex(rlList, i))) {
+ i += 3;
+ continue;
+ }
+ if (runLoop && !CFEqual(runLoop, CFArrayGetValueAtIndex(rlList, i+1))) {
+ i += 3;
+ continue;
+ }
+ if (runLoopMode && !CFEqual(runLoopMode, CFArrayGetValueAtIndex(rlList, i+2))) {
+ i += 3;
+ continue;
+ }
+
+ found = TRUE;
+
+ CFArrayRemoveValueAtIndex(rlList, i + 2);
+ CFArrayRemoveValueAtIndex(rlList, i + 1);
+ CFArrayRemoveValueAtIndex(rlList, i);
+
+ if (!all) {
+ return found;
+ }
+
+ n -= 3;
+ }
+
+ return found;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+static void
+__SCNetworkConnectionCallBack(CFSocketRef inref,
+ CFSocketCallBackType type,
+ CFDataRef address,
+ const void *data,
+ void *info)
+{
+ void *context_info;
+ void (*context_release)(const void *);
+ SCNetworkConnectionRef connection = (SCNetworkConnectionRef)info;
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)connection;
+ SCNetworkConnectionCallBack rlsFunction;
+ SCNetworkConnectionStatus status;
+ int pppstatus;
+ int err;
+
+ err = PPPReadEvent(connectionPrivate->eventRef, &pppstatus);
+ if (err)
+ return;
+
+ rlsFunction = connectionPrivate->rlsFunction;
+ if (connectionPrivate->rlsContext.retain && connectionPrivate->rlsContext.info) {
+ context_info = (void *)connectionPrivate->rlsContext.retain(connectionPrivate->rlsContext.info);
+ context_release = connectionPrivate->rlsContext.release;
+ }
+ else {
+ context_info = connectionPrivate->rlsContext.info;
+ context_release = NULL;
+ }
+
+ status = __SCNetworkConnectionConvertStatus(pppstatus);
+
+ (*rlsFunction)(connection, status, context_info);
+ if (context_release && context_info) {
+ context_release(context_info);
+ }
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+Boolean
+SCNetworkConnectionScheduleWithRunLoop(SCNetworkConnectionRef connection,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)connection;
+ //CFSocketRef ref;
+
+ if (!isA_SCNetworkConnection(connection) || runLoop == NULL || runLoopMode == NULL) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return FALSE;
+ }
+
+ if (connectionPrivate->rlsFunction == 0) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return FALSE;
+ }
+
+ if (connectionPrivate->rlList
+ && __isScheduled(NULL, runLoop, runLoopMode, connectionPrivate->rlList)) {
+ /* already scheduled */
+ _SCErrorSet(kSCStatusFailed);
+ return FALSE;
+ }
+
+ if (connectionPrivate->eventRef == -1) {
+ CFSocketContext context = { 0, (void*)connection, CFRetain, CFRelease, CFCopyDescription };
+
+ if (PPPInit(&connectionPrivate->eventRef)) {
+ _SCErrorSet(kSCStatusFailed);
+ return FALSE;
+ }
+
+ PPPEnableEvents(connectionPrivate->eventRef, connectionPrivate->serviceID, 0, 1);
+
+ connectionPrivate->eventRefCF = CFSocketCreateWithNative(NULL, connectionPrivate->eventRef,
+ kCFSocketReadCallBack, __SCNetworkConnectionCallBack, &context);
+ connectionPrivate->rls = CFSocketCreateRunLoopSource(NULL, connectionPrivate->eventRefCF, 0);
+ connectionPrivate->rlList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+ //CFRelease(ref);
+ }
+
+ CFRunLoopAddSource(runLoop, connectionPrivate->rls, runLoopMode);
+ __schedule(connectionPrivate, runLoop, runLoopMode, connectionPrivate->rlList);
+
+ return TRUE;
+}
+
+/* -------------------------------------------------------------------------------------------
+------------------------------------------------------------------------------------------- */
+
+Boolean
+SCNetworkConnectionUnscheduleFromRunLoop(SCNetworkConnectionRef connection,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode)
+{
+ SCNetworkConnectionPrivateRef connectionPrivate = (SCNetworkConnectionPrivateRef)connection;
+
+ if (!isA_SCNetworkConnection(connection) || runLoop == NULL || runLoopMode == NULL) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return FALSE;
+ }
+
+ if (connectionPrivate->rlList == NULL
+ || !__unschedule(connectionPrivate, runLoop, runLoopMode, connectionPrivate->rlList, FALSE)) {
+ /* if not currently scheduled */
+ _SCErrorSet(kSCStatusFailed);
+ return FALSE;
+ }
+
+ CFRunLoopRemoveSource(runLoop, connectionPrivate->rls, runLoopMode);
+
+ if (CFArrayGetCount(connectionPrivate->rlList) == 0) {
+ CFRelease(connectionPrivate->rls);
+ connectionPrivate->rls = NULL;
+ CFRelease(connectionPrivate->rlList);
+ connectionPrivate->rlList = NULL;
+ //PPPDispose(connectionPrivate->eventRef);
+ CFSocketInvalidate(connectionPrivate->eventRefCF);
+ CFRelease(connectionPrivate->eventRefCF);
+ connectionPrivate->eventRefCF = 0;
+ connectionPrivate->eventRef = -1;
+ }
+
+ return TRUE;
+}
+
+
+//************************* USER LEVEL DIAL API **********************************
+
+
+#define k_NetworkConnect_Pref_File CFSTR("com.apple.networkConnect")
+#define k_InterentConnect_Pref_File CFSTR("com.apple.internetconnect")
+
+#define k_Dial_Default_Key CFSTR("ConnectByDefault") // needs to go into SC
+#define k_Last_Service_Id_Key CFSTR("ServiceID")
+#define k_Unique_Id_Key CFSTR("UniqueIdentifier")
+
+
+/* Private Prototypes */
+static Boolean SCNetworkConnectionPrivateCopyDefaultServiceIDForDial (SCDynamicStoreRef session, CFStringRef *serviceID);
+static Boolean SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore (SCDynamicStoreRef session, CFStringRef *serviceID);
+static Boolean SCNetworkConnectionPrivateCopyDefaultUserOptionsFromArray(CFArrayRef userOptionsArray, CFDictionaryRef *userOptions);
+static Boolean SCNetworkConnectionPrivateIsPPPService (SCDynamicStoreRef session, CFStringRef serviceID);
+static void addPasswordFromKeychain(CFDictionaryRef *userOptions);
+static CFArrayRef copyKeychainEnumerator(CFStringRef uniqueIdentifier);
+
+Boolean
+SCNetworkConnectionCopyUserPreferences (CFDictionaryRef selectionOptions,
+ CFStringRef *serviceID,
+ CFDictionaryRef *userOptions)
+{
+ SCDynamicStoreRef session = SCDynamicStoreCreate(NULL, CFSTR("SCNetworkConnection"), NULL, NULL);
+ Boolean success = FALSE;
+
+ // NOTE: we are currently ignoring selectionOptions
+
+ if (session != NULL) {
+ // (1) Figure out which service ID we care about, allocate it into passed "serviceID"
+ success = SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(session, serviceID);
+
+ if (success && (*serviceID != NULL)) {
+ // (2) Get the list of user data for this service ID
+ CFPropertyListRef userServices = CFPreferencesCopyValue(*serviceID,
+ k_NetworkConnect_Pref_File,
+ kCFPreferencesCurrentUser,
+ kCFPreferencesCurrentHost);
+
+ // (3) We are expecting an array if the user has defined records for this service ID or NULL if the user hasn't
+ if (userServices != NULL) {
+ if (isA_CFArray(userServices)) {
+ // (4) Get the default set of user options for this service
+ success = SCNetworkConnectionPrivateCopyDefaultUserOptionsFromArray(
+ (CFArrayRef)userServices,
+ userOptions);
+ if(success && userOptions != NULL)
+ {
+ addPasswordFromKeychain(userOptions);
+ }
+ } else {
+ fprintf(stderr, "Error, userServices are not of type CFArray!\n");
+ }
+
+ CFRelease(userServices); // this is OK because SCNetworkConnectionPrivateISExpectedCFType() checks for NULL
+ }
+ }
+
+ CFRelease(session);
+ } else {
+ fprintf(stderr, "Error, SCNetworkConnectionCopyUserPreferences, SCDynamicStoreCreate() returned NULL!\n");
+ }
+
+ return success;
+}
+
+//*******************************************************************************************
+// SCNetworkConnectionPrivateCopyDefaultServiceIDForDial
+// ----------------------------------------------------
+// Try to find the service id to connect
+// (1) Start by looking at the last service used in Internet Connect
+// (2) If Internet Connect has not been used, find the PPP service with the highest ordering
+//********************************************************************************************
+static Boolean
+SCNetworkConnectionPrivateCopyDefaultServiceIDForDial(SCDynamicStoreRef session, CFStringRef *serviceID)
+{
+ Boolean foundService = FALSE;
+ CFPropertyListRef lastServiceSelectedInIC = NULL;
+
+ // NULL out the pointer
+ *serviceID = NULL;
+
+ // read out the last service from the Internet Connect preference file
+ lastServiceSelectedInIC = CFPreferencesCopyValue(k_Last_Service_Id_Key,
+ k_InterentConnect_Pref_File,
+ kCFPreferencesCurrentUser,
+ kCFPreferencesAnyHost);
+
+ // we found the service the user last had open in IC
+ if (lastServiceSelectedInIC != NULL) {
+ // make sure its a PPP service
+ if (SCNetworkConnectionPrivateIsPPPService(session, lastServiceSelectedInIC)) {
+ // make sure the service that we found is valid
+ CFDictionaryRef dict;
+ CFStringRef key;
+
+ key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+ kSCDynamicStoreDomainSetup,
+ lastServiceSelectedInIC,
+ kSCEntNetInterface);
+ dict = SCDynamicStoreCopyValue(session, key);
+ CFRelease(key);
+ if (dict) {
+ *serviceID = CFRetain(lastServiceSelectedInIC);
+ foundService = TRUE;
+ CFRelease(dict);
+ }
+ }
+ CFRelease(lastServiceSelectedInIC);
+ }
+
+ if (!foundService) {
+ foundService = SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore(session, serviceID);
+ }
+
+ return foundService;
+}
+
+//********************************************************************************
+// SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore
+// -------------------------------------------------------
+// Find the highest ordered PPP service in the dynamic store
+//********************************************************************************
+static Boolean
+SCNetworkConnectionPrivateGetPPPServiceFromDynamicStore(SCDynamicStoreRef session, CFStringRef *serviceID)
+{
+ Boolean success = FALSE;
+ CFStringRef key = NULL;
+ CFDictionaryRef dict = NULL;
+ CFArrayRef serviceIDs = NULL;
+
+ *serviceID = NULL;
+
+ do {
+ CFIndex count;
+ CFIndex i;
+
+ key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL, kSCDynamicStoreDomainSetup, kSCEntNetIPv4);
+ if (key == NULL) {
+ fprintf(stderr, "Error, Setup Key == NULL!\n");
+ break;
+ }
+
+ dict = SCDynamicStoreCopyValue(session, key);
+ if (dict == NULL) {
+ fprintf(stderr, "Error, Dictionary for setup key == NULL!\n");
+ break;
+ }
+
+ serviceIDs = CFDictionaryGetValue(dict, kSCPropNetServiceOrder); // array of service id's
+ if (isA_CFArray(serviceIDs) == NULL) {
+ if (serviceIDs == NULL)
+ fprintf(stderr, "Error, Array of service IDs == NULL!\n");
+ else
+ fprintf(stderr, "Error, serviceIds are not of type CFArray!\n");
+ break;
+ }
+
+ count = CFArrayGetCount(serviceIDs);
+ for (i = 0; i < count; i++) {
+ CFStringRef service = CFArrayGetValueAtIndex(serviceIDs, i);
+
+ if (SCNetworkConnectionPrivateIsPPPService(session, service)) {
+ *serviceID = CFRetain(service);
+ success = TRUE;
+ break;
+ }
+ }
+ } while (FALSE);
+
+ if (key != NULL)
+ CFRelease(key);
+
+ if (dict != NULL)
+ CFRelease(dict);
+
+ return success;
+}
+
+//********************************************************************************
+// SCNetworkConnectionPrivateCopyDefaultUserOptionsFromArray
+// ---------------------------------------------------------
+// Copy over user preferences for a particular service if they exist
+//********************************************************************************
+static Boolean
+SCNetworkConnectionPrivateCopyDefaultUserOptionsFromArray(CFArrayRef userOptionsArray, CFDictionaryRef *userOptions)
+{
+ CFIndex count = CFArrayGetCount(userOptionsArray);
+ int i;
+
+ *userOptions = NULL;
+
+ for (i = 0; i < count; i++) {
+ // (1) Find the dictionary
+ CFPropertyListRef propertyList = CFArrayGetValueAtIndex(userOptionsArray, i);
+
+ if (isA_CFDictionary(propertyList) != NULL) {
+ // See if there's a value for dial on demand
+ CFPropertyListRef value = CFDictionaryGetValue((CFDictionaryRef)propertyList,
+ k_Dial_Default_Key);
+ if (isA_CFBoolean(value) != NULL) {
+ if (CFBooleanGetValue(value)) {
+ // we found the default user options
+ *userOptions = CFDictionaryCreateCopy(NULL,
+ (CFDictionaryRef)propertyList);
+ break;
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+//********************************************************************************
+// SCNetworkConnectionPrivateIsPPPService
+// --------------------------------------
+// Check and see if the service is a PPP service
+//********************************************************************************
+static Boolean
+SCNetworkConnectionPrivateIsPPPService(SCDynamicStoreRef session, CFStringRef serviceID)
+{
+ CFStringRef entityKey;
+ Boolean isPPPService = FALSE;
+ Boolean isModemOrPPPoE = FALSE;
+
+ entityKey = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+ kSCDynamicStoreDomainSetup,
+ serviceID,
+ kSCEntNetInterface);
+ if (entityKey != NULL) {
+ CFDictionaryRef serviceDict;
+
+ serviceDict = SCDynamicStoreCopyValue(session, entityKey);
+ if (serviceDict != NULL) {
+ if (isA_CFDictionary(serviceDict)) {
+ CFStringRef type;
+ CFStringRef subtype;
+
+ type = CFDictionaryGetValue(serviceDict, kSCPropNetInterfaceType);
+ if (isA_CFString(type)) {
+ isPPPService = CFEqual(type, kSCValNetInterfaceTypePPP);
+ }
+
+ subtype = CFDictionaryGetValue(serviceDict, kSCPropNetInterfaceSubType);
+ if (isA_CFString(subtype)) {
+ isModemOrPPPoE = (CFEqual(subtype, kSCValNetInterfaceSubTypePPPSerial) ||
+ CFEqual(subtype, kSCValNetInterfaceSubTypePPPoE));
+ }
+ }
+ CFRelease(serviceDict);
+ }
+ CFRelease(entityKey);
+ }
+
+ return (isPPPService && isModemOrPPPoE);
+}
+
+//********************************************************************************
+// addPasswordFromKeychain
+// --------------------------------------
+// Get the password out of the keychain and add it to the PPP dictionary
+//********************************************************************************
+static void
+addPasswordFromKeychain(CFDictionaryRef *userOptions)
+{
+ CFArrayRef enumerator;
+ CFIndex n;
+ CFDictionaryRef oldDict;
+ CFPropertyListRef uniqueID = NULL;
+
+ oldDict = *userOptions;
+ if(oldDict == NULL) {
+ return; // if no userOptions
+ }
+
+ uniqueID = CFDictionaryGetValue(oldDict, k_Unique_Id_Key);
+ if(!isA_CFString(uniqueID)) {
+ return; // if no unique ID
+ }
+
+ enumerator = copyKeychainEnumerator(uniqueID);
+ if(enumerator == NULL) {
+ return; // if no keychain enumerator
+ }
+
+
+ n = CFArrayGetCount(enumerator);
+ if (n > 0) {
+ void *data = NULL;
+ UInt32 dataLen = 0;
+ SecKeychainItemRef itemRef;
+ OSStatus result;
+
+ itemRef = (SecKeychainItemRef)CFArrayGetValueAtIndex(enumerator, 0);
+ result = SecKeychainItemCopyContent(itemRef, // itemRef
+ NULL, // itemClass
+ NULL, // attrList
+ &dataLen, // length
+ (void *)&data); // outData
+ if(result == noErr && data != NULL && dataLen > 0) {
+ CFStringRef pass;
+
+ pass = CFStringCreateWithBytes(NULL, data, dataLen, kCFStringEncodingUTF8, TRUE);
+ if (pass) {
+ CFMutableDictionaryRef newDict;
+ CFMutableDictionaryRef newPPP;
+ CFDictionaryRef pppDict;
+
+ newDict = CFDictionaryCreateMutableCopy(NULL, 0, oldDict);
+ pppDict = CFDictionaryGetValue(newDict, kSCEntNetPPP);
+ if (isA_CFDictionary(pppDict)) {
+ newPPP = CFDictionaryCreateMutableCopy(NULL, 0, pppDict);
+ } else {
+ newPPP = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ }
+
+ // set the PPP password
+ CFDictionarySetValue(newPPP, kSCPropNetPPPAuthPassword, pass);
+ CFRelease(pass);
+
+ // update the PPP entity
+ CFDictionarySetValue(newDict, kSCEntNetPPP, newPPP);
+ CFRelease(newPPP);
+
+ // update the userOptions dictionary
+ CFRelease(oldDict);
+ *userOptions = CFDictionaryCreateCopy(NULL, newDict);
+ CFRelease(newDict);
+ }
+ }
+ }
+
+ CFRelease(enumerator);
+ return;
+}
+
+//********************************************************************************
+// copyKeychainEnumerator
+// --------------------------------------
+// Gather Keychain Enumerator
+//********************************************************************************
+static CFArrayRef
+copyKeychainEnumerator(CFStringRef uniqueIdentifier)
+{
+ char *buf = NULL;
+ CFMutableArrayRef itemArray = NULL;
+ OSStatus result;
+ SecKeychainSearchRef search = NULL;
+
+ buf = _SC_cfstring_to_cstring(uniqueIdentifier, NULL, 0, kCFStringEncodingUTF8);
+ if (buf != NULL) {
+ // search for unique identifier in "svce" attribute
+ SecKeychainAttribute attributes[] = {{ kSecServiceItemAttr,
+ CFStringGetLength(uniqueIdentifier),
+ (void *)buf
+ }};
+
+ SecKeychainAttributeList attrList = { sizeof(attributes) / sizeof(*attributes),
+ attributes };
+
+ result = SecKeychainSearchCreateFromAttributes(NULL, kSecGenericPasswordItemClass, &attrList, &search);
+ if (result == noErr) {
+ itemArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+ while (result == noErr) {
+ SecKeychainItemRef itemFound = NULL;
+
+ result = SecKeychainSearchCopyNext(search, &itemFound);
+ if (result != noErr) {
+ break;
+ }
+
+ if (itemFound) {
+ CFArrayAppendValue(itemArray, itemFound);
+ CFRelease(itemFound);
+ }
+ }
+ }
+ }
+
+ if (search) CFRelease(search);
+ if (buf) CFAllocatorDeallocate(NULL, buf);
+
+ return itemArray;
+}
--- /dev/null
+/*
+ * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCNETWORKCONNECTION_H
+#define _SCNETWORKCONNECTION_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <AvailabilityMacros.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SystemConfiguration.h>
+
+
+/*!
+ @header SCNetworkConnection
+ The SCNetworkConnectionXXX() APIs allow an application to
+ control connection oriented services defined in the system.
+
+ This is a set of control APIs only. Using these APIs, an
+ application will be able to control existing services.
+ To create, change, or remove services, SCPreferences APIs
+ must be used.
+
+ Note: Currently only PPP services can be controlled.
+ */
+
+
+/*!
+ @typedef SCNetworkConnectionRef
+ @discussion This is the handle to manage a connection oriented service.
+ */
+typedef const struct __SCNetworkConnection * SCNetworkConnectionRef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @typedef SCNetworkConnectionContext
+ */
+typedef struct {
+ CFIndex version;
+ void * info;
+ const void *(*retain)(const void *info);
+ void (*release)(const void *info);
+ CFStringRef (*copyDescription)(const void *info);
+} SCNetworkConnectionContext AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+
+/*!
+ @enum SCNetworkConnectionStatus
+ @discussion Status of the network connection.
+ This status is intended to be generic and high level.
+ An extended status, specific to the type of network
+ connection is also available for applications that
+ need additonal information.
+
+ @constant kSCNetworkConnectionInvalid
+ The network connection refers to an invalid service.
+
+ @constant kSCNetworkConnectionDisconnected
+ The network connection is disconnected.
+
+ @constant kSCNetworkConnectionConnecting
+ The network connection is connecting.
+
+ @constant kSCNetworkConnectionConnected
+ The network connection is connected.
+
+ @constant kSCNetworkConnectionDisconnecting
+ The network connection is disconnecting.
+ */
+enum {
+ kSCNetworkConnectionInvalid = -1,
+ kSCNetworkConnectionDisconnected = 0,
+ kSCNetworkConnectionConnecting = 1,
+ kSCNetworkConnectionConnected = 2,
+ kSCNetworkConnectionDisconnecting = 3
+};
+typedef int32_t SCNetworkConnectionStatus AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @enum SCNetworkConnectionPPPStatus
+ @discussion PPP specific status of the network connection.
+ This status is PPP specific and returned as part of the extended information
+ for a PPP service.
+ Note: additional status might be returned in the future, and the application should
+ be prepared to receive an unknown value.
+
+ @constant kSCNetworkConnectionPPPDisconnected
+ PPP is disconnected.
+
+ @constant kSCNetworkConnectionPPPInitializing
+ PPP is initializing.
+
+ @constant kSCNetworkConnectionPPPConnectingLink
+ PPP is connecting the lower connection layer (for example, the modem is dialing out).
+
+ @constant kSCNetworkConnectionPPPDialOnTraffic
+ PPP is waiting for networking traffic to automatically establish the connection.
+
+ @constant kSCNetworkConnectionPPPNegotiatingLink
+ PPP lower layer is connected and PPP is negotiating the link layer (LCP protocol).
+
+ @constant kSCNetworkConnectionPPPAuthenticating
+ PPP is authenticating to the server (PAP, CHAP, MS-CHAP or EAP protocols).
+
+ @constant kSCNetworkConnectionPPPWaitingForCallBack
+ PPP is waiting for server to call back.
+
+ @constant kSCNetworkConnectionPPPNegotiatingNetwork
+ PPP is now authenticated and negotiating the networking layer (IPCP or IPv6CP protocols)
+
+ @constant kSCNetworkConnectionPPPConnected
+ PPP is now fully connected for at least one of the networking layer.
+ Additional networking protocol might still be negotiating.
+
+ @constant kSCNetworkConnectionPPPTerminating
+ PPP networking and link protocols are terminating.
+
+ @constant kSCNetworkConnectionPPPDisconnectingLink
+ PPP is disconnecting the lower level (for example, the modem is hanging up).
+
+ @constant kSCNetworkConnectionPPPHoldingLinkOff
+ PPP is disconnected and maintaining the link temporarily off.
+
+ @constant kSCNetworkConnectionPPPSuspended
+ PPP is suspended as a result of the suspend command (for example, when a V92 Modem is On Hold).
+
+ @constant kSCNetworkConnectionPPPWaitingForRedial
+ PPP has found a busy server and is waiting for redial.
+ */
+enum {
+ kSCNetworkConnectionPPPDisconnected = 0,
+ kSCNetworkConnectionPPPInitializing = 1,
+ kSCNetworkConnectionPPPConnectingLink = 2,
+ kSCNetworkConnectionPPPDialOnTraffic = 3,
+ kSCNetworkConnectionPPPNegotiatingLink = 4,
+ kSCNetworkConnectionPPPAuthenticating = 5,
+ kSCNetworkConnectionPPPWaitingForCallBack = 6,
+ kSCNetworkConnectionPPPNegotiatingNetwork = 7,
+ kSCNetworkConnectionPPPConnected = 8,
+ kSCNetworkConnectionPPPTerminating = 9,
+ kSCNetworkConnectionPPPDisconnectingLink = 10,
+ kSCNetworkConnectionPPPHoldingLinkOff = 11,
+ kSCNetworkConnectionPPPSuspended = 12,
+ kSCNetworkConnectionPPPWaitingForRedial = 13
+};
+typedef int32_t SCNetworkConnectionPPPStatus AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @typedef SCNetworkConnectionCallBack
+ @discussion Type of the callback function used when a
+ status event is delivered.
+ @param status The connection status.
+ @param connection The connection reference.
+ @param info ....
+ */
+typedef void (*SCNetworkConnectionCallBack) (
+ SCNetworkConnectionRef connection,
+ SCNetworkConnectionStatus status,
+ void *info
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+
+/*
+ Keys for the statistics dictionary
+*/
+
+#define kSCNetworkConnectionBytesIn CFSTR("BytesIn") /* CFNumber */
+#define kSCNetworkConnectionBytesOut CFSTR("BytesOut") /* CFNumber */
+#define kSCNetworkConnectionPacketsIn CFSTR("PacketsIn") /* CFNumber */
+#define kSCNetworkConnectionPacketsOut CFSTR("PacketsOut") /* CFNumber */
+#define kSCNetworkConnectionErrorsIn CFSTR("ErrorsIn") /* CFNumber */
+#define kSCNetworkConnectionErrorsOut CFSTR("ErrorsOut") /* CFNumber */
+
+
+__BEGIN_DECLS
+
+/*!
+ @function SCDynamicStoreGetTypeID
+ Returns the type identifier of all SCNetworkConnection instances.
+ */
+CF_EXPORT
+CFTypeID SCNetworkConnectionGetTypeID (void) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @function SCNetworkConnectionCopyUserPreferences
+ @discussion Provides the default serviceID and a userOptions dictionary for the connection.
+ Applications can use the serviceID and userOptions returned to open a connection on the fly.
+ @param selectionOptions Currently unimplemented. Pass NULL for this version.
+ @param serviceID Reference to the default serviceID for starting connections,
+ this value will be returned by the function.
+ @param userOptions Reference to default userOptions for starting connections,
+ this will be returned by the function.
+ @result TRUE if there is a valid service to dial.
+ FALSE if function was unable to retrieve a service to dial.
+ */
+Boolean SCNetworkConnectionCopyUserPreferences (
+ CFDictionaryRef selectionOptions,
+ CFStringRef *serviceID,
+ CFDictionaryRef *userOptions
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @function SCNetworkConnectionCreateWithServiceID
+ @discussion Creates a new connection reference to use for getting the status,
+ for connecting or for disconnecting the associated service.
+ @param allocator The CFAllocator which should be used to allocate
+ memory for the connection structure.
+ 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 serviceID A string that defines the service identifier
+ of the connection. Service identifiers uniquely identify
+ services in the system configuration database.
+ @param callout The function to be called when the status
+ of the connection changes.
+ If this parameter is NULL, the application will not receive
+ change of status notifications and will need to poll for updates.
+ @param context The SCNetworkConnectionContext associated with the callout.
+ @result A reference to the new SCNetworkConnection.
+ */
+SCNetworkConnectionRef
+SCNetworkConnectionCreateWithServiceID (
+ CFAllocatorRef allocator,
+ CFStringRef serviceID,
+ SCNetworkConnectionCallBack callout,
+ SCNetworkConnectionContext *context
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @function SCNetworkConnectionCopyService
+ @discussion Returns the service ID associated with the SCNetworkConnection.
+ @param connection The SCNetworkConnection to obtained status from.
+ Returns the service ID associated with the SCNetworkConnection.
+ */
+CFStringRef
+SCNetworkConnectionCopyServiceID (
+ SCNetworkConnectionRef connection
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @function SCNetworkConnectionGetStatus
+ @discussion Returns the status of the SCNetworkConnection.
+ A status is one of the following values :
+ kSCNetworkConnectionInvalid
+ kSCNetworkConnectionDisconnected
+ kSCNetworkConnectionConnecting
+ kSCNetworkConnectionDisconnecting
+ kSCNetworkConnectionConnected
+
+ @param connection The SCNetworkConnection to obtain status from.
+ @result The status value.
+*/
+SCNetworkConnectionStatus
+SCNetworkConnectionGetStatus (
+ SCNetworkConnectionRef connection
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @function SCNetworkConnectionCopyExtendedStatus
+ @discussion Returns the extended status of the connection.
+ An extended status dictionary contains specific dictionaries
+ describing the status for each subcomponent of the service.
+
+ For example, a status dictionary will contain the following dictionaries:
+
+ IPv4:
+ IPaddress: IP address used.
+
+ PPP:
+ Status: PPP specific status of type SCNetworkConnectionPPPStatus.
+ LastCause: Available when status is Disconnected.
+ Contains the last error of disconnection.
+ ConnectTime: time when the connection happened
+ MaxTime: maximum time for this connection
+
+ Modem:
+ ConnectionSpeed: Speed of the modem connection in bits/s
+
+ Other dictionaries could be present for PPPoE, PPTP and L2TP.
+
+ The status dictionary can be extended as needed in the future
+ to contain additional information.
+
+ @param connection The SCNetworkConnection to obtain status from.
+ @result The status dictionary.
+ If NULL is returned, the error can be retrieved with SCError().
+ */
+CFDictionaryRef
+SCNetworkConnectionCopyExtendedStatus (
+ SCNetworkConnectionRef connection
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @function SCNetworkConnectionCopyStatistics
+ @discussion Returns the statistics of the SCNetworkConnection.
+ A statistic dictionary contains specific dictionaries
+ with statistics for each subcomponents of the service.
+
+ For example, a statistic dictionary will contain the following dictionaries:
+
+ PPP: {Bytes,Packets,Errors}{In,Out}:
+ Statistics at the Network level.
+ Contains the number of bytes, packets, and errors on the PPP interface.
+ For example, BytesIn contains the number of bytes going up
+ into the network stack, for any networking protocol,
+ without the PPP headers and trailers.
+
+ The statistic dictionary can be extended as needed in the future
+ to contain additional information.
+
+ @param connection The SCNetworkConnection to obtained statistics from.
+ @result The statistics dictionary.
+ If NULL is returned, the error can be retrieved with SCError().
+ */
+CFDictionaryRef
+SCNetworkConnectionCopyStatistics (
+ SCNetworkConnectionRef connection
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @function SCNetworkConnectionStart
+ @discussion Start the connection for the SCNetworkConnection.
+ The connection process is asynchronous and the function will
+ return immediately. The connection status can be obtain by polling or
+ by callback.
+ The connection is done with the default settings from the administrator.
+ Some of the settings can be overridden for the duration of
+ the connection. They are given in an option dictionary.
+ The options dictionary is in the format of a Network Service
+ as described in SystemConfiguration.
+
+ Note: Starting and stopping of connections is implicitely arbitrated.
+ Calling Start on a connection already started will indicate
+ that the application has interest in the connection and it shouldn't
+ be stopped by anyone else.
+
+ @param connection The SCNetworkConnection to start.
+ @param userOptions The options dictionary to start the connection with.
+ If userOptions is NULL, the default settings will be used.
+ If userOptions are specified, they must be in the SystemConfiguration format.
+ The options will override the default settings defined for the service.
+
+ For security reasons, not all the options can be overridden, the appropriate merging
+ of all the settings will be done before the connection is established,
+ and inappropriate options will be ignored.
+
+ @param linger This parameter indicates whether or not the connection can stay around
+ when the application no longer has interest in it.
+ Typical application should pass FALSE, and the Stop function will
+ automatically be called when the reference is released or if the application quits.
+ If the application passes TRUE, the application can release the reference
+ or exit and the Stop function will not be called.
+
+ @result TRUE if the connection was correctly started. The actual connection is not established yet,
+ and the connection status needs to be periodically checked.
+ FALSE if the connection request didn't start. Error must be taken
+ from SCError().
+ */
+Boolean
+SCNetworkConnectionStart (
+ SCNetworkConnectionRef connection,
+ CFDictionaryRef userOptions,
+ Boolean linger
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @function SCNetworkConnectionStop
+ @discussion Stop the connection for the SCNetworkConnection.
+ The disconnection process is asynchronous and the function will
+ return immediately. The connection status can be obtain by polling or
+ by callback.
+ This function performs an arbitrated stop of the connection.
+ If several applications have marked their interest in the connection,
+ by calling SCNetworkConnectionStart, the call will succeed but the the actual
+ connection will be maintained until the last interested application calls stop.
+
+ In certain cases, you might want to stop the connection anyway, and
+ SCNetworkConnectionStop with forceDisconnect argument can be used.
+
+ @param connection The SCNetworkConnection to stop.
+ @result TRUE if the disconnection request succeeded.
+ FALSE if the disconnection request failed. Error must be taken from SCError().
+ */
+Boolean
+SCNetworkConnectionStop (
+ SCNetworkConnectionRef connection,
+ Boolean forceDisconnect
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @function SCNetworkConnectionCopyCurrentOptions
+ @discussion Copy the user options used to start the connection.
+ This is a mechanism for a client to retrieve the user options
+ previously passed to the SCNetworkConnectionStart function.
+ @param connection The SCNetworkConnection to obtain options from.
+ @result The service dictionary containing the connection options.
+ The dictionary can be empty if no user options were used.
+ If NULL is returned, the error can be retrieved with SCError().
+ */
+CFDictionaryRef
+SCNetworkConnectionCopyUserOptions (
+ SCNetworkConnectionRef connection
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @function SCNetworkConnectionScheduleWithRunLoop
+ @discussion Schedule a connection with the Run Loop.
+ @param connection The SCNetworkConnection to schedule.
+ @param runLoop The runloop to schedule with.
+ @param runLoopMode The runloop mode.
+ @result TRUE if success.
+ FALSE if failed. The error can be retrieved with SCError().
+ */
+Boolean
+SCNetworkConnectionScheduleWithRunLoop (
+ SCNetworkConnectionRef connection,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @function SCNetworkConnectionUnscheduleFromRunLoop
+ @discussion Unschedule a connection from the Run Loop.
+ @param connection The SCNetworkConnection to unschedule.
+ @param runLoop The runloop to unschedule from.
+ @param runLoopMode The runloop mode.
+ @result TRUE if success.
+ FALSE if failed. The error can be retrieved with SCError().
+ */
+Boolean
+SCNetworkConnectionUnscheduleFromRunLoop (
+ SCNetworkConnectionRef connection,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+__END_DECLS
+
+#endif /* _SCNETWORKCONNECTION_H */
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Modification History
+ *
+ * January 19, 2003 Allan Nathanson <ajn@apple.com>
+ * - add advanced reachability APIs
+ */
+
+#include <SystemConfiguration/SystemConfiguration.h>
+#include <SystemConfiguration/SCValidation.h>
+#include <SystemConfiguration/SCPrivate.h>
+
+#include <CoreFoundation/CFRuntime.h>
+#include <pthread.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <netdb_async.h>
+#include <resolv.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#define KERNEL_PRIVATE
+#include <net/route.h>
+#undef KERNEL_PRIVATE
+
+#ifndef s6_addr16
+#define s6_addr16 __u6_addr.__u6_addr16
+#endif
+
+#include "ppp.h"
+
+
+#define kSCNetworkFlagsFirstResolvePending (1<<31)
+
+
+#define N_QUICK 32
+
+
+typedef enum {
+ reachabilityTypeAddress,
+ reachabilityTypeAddressPair,
+ reachabilityTypeName
+} addressType;
+
+
+static CFStringRef __SCNetworkReachabilityCopyDescription (CFTypeRef cf);
+static void __SCNetworkReachabilityDeallocate (CFTypeRef cf);
+
+
+typedef struct {
+
+ /* base CFType information */
+ CFRuntimeBase cfBase;
+
+ /* lock */
+ pthread_mutex_t lock;
+
+ /* address type */
+ addressType type;
+
+ /* target host name */
+ const char *name;
+ CFArrayRef resolvedAddress; /* CFArray[CFData] */
+ int resolvedAddressError;
+
+ /* local & remote addresses */
+ struct sockaddr *localAddress;
+ struct sockaddr *remoteAddress;
+
+ /* current reachability flags */
+ SCNetworkConnectionFlags flags;
+ uint16_t if_index;
+
+ /* run loop source, callout, context, rl scheduling info */
+ CFRunLoopSourceRef rls;
+ SCNetworkReachabilityCallBack rlsFunction;
+ SCNetworkReachabilityContext rlsContext;
+ CFMutableArrayRef rlList;
+
+ /* async DNS query info */
+ CFMachPortRef dnsPort;
+ CFRunLoopSourceRef dnsRLS;
+
+} SCNetworkReachabilityPrivate, *SCNetworkReachabilityPrivateRef;
+
+
+static CFTypeID __kSCNetworkReachabilityTypeID = _kCFRuntimeNotATypeID;
+
+
+static const CFRuntimeClass __SCNetworkReachabilityClass = {
+ 0, // version
+ "SCNetworkReachability", // className
+ NULL, // init
+ NULL, // copy
+ __SCNetworkReachabilityDeallocate, // dealloc
+ NULL, // equal
+ NULL, // hash
+ NULL, // copyFormattingDesc
+ __SCNetworkReachabilityCopyDescription // copyDebugDesc
+};
+
+
+static pthread_once_t initialized = PTHREAD_ONCE_INIT;
+static Boolean needDNS = TRUE;
+
+
+/* host "something has changed" notifications */
+static pthread_mutex_t hn_lock = PTHREAD_MUTEX_INITIALIZER;
+static SCDynamicStoreRef hn_store = NULL;
+static CFRunLoopSourceRef hn_storeRLS = NULL;
+static CFMutableArrayRef hn_rlList = NULL;
+static CFMutableSetRef hn_targets = NULL;
+
+
+static __inline__ CFTypeRef
+isA_SCNetworkReachability(CFTypeRef obj)
+{
+ return (isA_CFType(obj, SCNetworkReachabilityGetTypeID()));
+}
+
+
+static void
+sockaddr_to_string(const struct sockaddr *address, char *buf, size_t bufLen)
+{
+ bzero(buf, bufLen);
+ switch (address->sa_family) {
+ case AF_INET :
+ (void)inet_ntop(((struct sockaddr_in *)address)->sin_family,
+ &((struct sockaddr_in *)address)->sin_addr,
+ buf,
+ bufLen);
+ break;
+ case AF_INET6 : {
+ (void)inet_ntop(((struct sockaddr_in6 *)address)->sin6_family,
+ &((struct sockaddr_in6 *)address)->sin6_addr,
+ buf,
+ bufLen);
+ if (((struct sockaddr_in6 *)address)->sin6_scope_id != 0) {
+ int n;
+
+ n = strlen(buf);
+ if ((n+IF_NAMESIZE+1) <= (int)bufLen) {
+ buf[n++] = '%';
+ if_indextoname(((struct sockaddr_in6 *)address)->sin6_scope_id, &buf[n]);
+ }
+ }
+ break;
+ }
+ case AF_LINK :
+ if (((struct sockaddr_dl *)address)->sdl_len < bufLen) {
+ bufLen = ((struct sockaddr_dl *)address)->sdl_len;
+ } else {
+ bufLen = bufLen - 1;
+ }
+
+ bcopy(((struct sockaddr_dl *)address)->sdl_data, buf, bufLen);
+ break;
+ default :
+ snprintf(buf, bufLen, "unexpected address family %d", address->sa_family);
+ break;
+ }
+
+ return;
+}
+
+
+#ifndef CHECK_IPV6_REACHABILITY
+static char *
+__netdb_error(int error)
+{
+ char *msg;
+
+ switch(error) {
+ case NETDB_INTERNAL :
+ msg = strerror(errno);
+ break;
+ case HOST_NOT_FOUND :
+ msg = "Host not found.";
+ 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;
+ }
+
+ return msg;
+}
+#endif /* CHECK_IPV6_REACHABILITY */
+
+
+static void
+__signalRunLoop(CFTypeRef obj, CFRunLoopSourceRef rls, CFArrayRef rlList)
+{
+ CFRunLoopRef rl = NULL;
+ CFRunLoopRef rl1 = NULL;
+ CFIndex i;
+ CFIndex n = CFArrayGetCount(rlList);
+
+ if (n == 0) {
+ return;
+ }
+
+ /* get first runLoop for this object */
+ for (i = 0; i < n; i += 3) {
+ if (!CFEqual(obj, CFArrayGetValueAtIndex(rlList, i))) {
+ continue;
+ }
+
+ rl1 = (CFRunLoopRef)CFArrayGetValueAtIndex(rlList, i+1);
+ break;
+ }
+
+ if (!rl1) {
+ /* if not scheduled */
+ return;
+ }
+
+ /* check if we have another runLoop for this object */
+ rl = rl1;
+ for (i = i+3; i < n; i += 3) {
+ CFRunLoopRef rl2;
+
+ if (!CFEqual(obj, CFArrayGetValueAtIndex(rlList, i))) {
+ continue;
+ }
+
+ rl2 = (CFRunLoopRef)CFArrayGetValueAtIndex(rlList, i+1);
+ if (!CFEqual(rl1, rl2)) {
+ /* we've got more than one runLoop */
+ rl = NULL;
+ break;
+ }
+ }
+
+ if (rl) {
+ /* if we only have one runLoop */
+ CFRunLoopWakeUp(rl);
+ return;
+ }
+
+ /* more than one different runLoop, so we must pick one */
+ for (i = 0; i < n; i+=3) {
+ CFStringRef rlMode;
+
+ if (!CFEqual(obj, CFArrayGetValueAtIndex(rlList, i))) {
+ continue;
+ }
+
+ rl = (CFRunLoopRef)CFArrayGetValueAtIndex(rlList, i+1);
+ rlMode = CFRunLoopCopyCurrentMode(rl);
+ if (rlMode && CFRunLoopIsWaiting(rl) && CFRunLoopContainsSource(rl, rls, rlMode)) {
+ /* we've found a runLoop that's "ready" */
+ CFRelease(rlMode);
+ CFRunLoopWakeUp(rl);
+ return;
+ }
+ if (rlMode) CFRelease(rlMode);
+ }
+
+ /* didn't choose one above, so choose first */
+ CFRunLoopWakeUp(rl1);
+ return;
+}
+
+
+static int
+updatePPPStatus(SCDynamicStoreRef *storeP,
+ const struct sockaddr *sa,
+ const char *if_name,
+ SCNetworkConnectionFlags *flags)
+{
+ CFDictionaryRef dict = NULL;
+ CFStringRef entity;
+ CFIndex i;
+ const void * keys_q[N_QUICK];
+ const void ** keys = keys_q;
+ CFIndex n;
+ CFStringRef ppp_if;
+ int sc_status = kSCStatusReachabilityUnknown;
+ SCDynamicStoreRef store = (storeP) ? *storeP : NULL;
+ const void * values_q[N_QUICK];
+ const void ** values = values_q;
+
+ switch (sa->sa_family) {
+ case AF_INET :
+ entity = kSCEntNetIPv4;
+ break;
+ case AF_INET6 :
+ entity = kSCEntNetIPv6;
+ break;
+ default :
+ goto done;
+ }
+
+ if (!store) {
+ store = SCDynamicStoreCreate(NULL, CFSTR("SCNetworkReachability"), NULL, NULL);
+ if (!store) {
+ SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+ goto done;
+ }
+ }
+
+ /*
+ * grab a snapshot of the PPP configuration from the dynamic store
+ */
+ {
+ CFStringRef pattern;
+ CFMutableArrayRef patterns;
+
+ patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+ kSCDynamicStoreDomainState,
+ kSCCompAnyRegex,
+ entity);
+ CFArrayAppendValue(patterns, pattern);
+ CFRelease(pattern);
+ pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+ kSCDynamicStoreDomainSetup,
+ kSCCompAnyRegex,
+ kSCEntNetPPP);
+ CFArrayAppendValue(patterns, pattern);
+ CFRelease(pattern);
+ pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+ kSCDynamicStoreDomainState,
+ kSCCompAnyRegex,
+ kSCEntNetPPP);
+ CFArrayAppendValue(patterns, pattern);
+ CFRelease(pattern);
+ dict = SCDynamicStoreCopyMultiple(store, NULL, patterns);
+ CFRelease(patterns);
+ }
+ if (!dict) {
+ /* if we could not access the dynamic store */
+ goto done;
+ }
+
+ sc_status = kSCStatusOK;
+
+ /*
+ * look for the service which matches the provided interface
+ */
+ n = CFDictionaryGetCount(dict);
+ if (n <= 0) {
+ goto done;
+ }
+
+ ppp_if = CFStringCreateWithCStringNoCopy(NULL,
+ if_name,
+ kCFStringEncodingASCII,
+ kCFAllocatorNull);
+
+ if (n > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
+ keys = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0);
+ values = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0);
+ }
+ CFDictionaryGetKeysAndValues(dict, keys, values);
+
+ for (i=0; i < n; i++) {
+ CFArrayRef components;
+ CFStringRef key;
+ CFNumberRef num;
+ CFDictionaryRef p_setup;
+ CFDictionaryRef p_state;
+ int32_t ppp_status;
+ CFStringRef service = NULL;
+ CFStringRef s_key = (CFStringRef) keys[i];
+ CFDictionaryRef s_dict = (CFDictionaryRef)values[i];
+ CFStringRef s_if;
+
+ if (!isA_CFString(s_key) || !isA_CFDictionary(s_dict)) {
+ continue;
+ }
+
+ if (!CFStringHasSuffix(s_key, entity)) {
+ continue; // if not an IPv4 or IPv6 entity
+ }
+
+ s_if = CFDictionaryGetValue(s_dict, kSCPropInterfaceName);
+ if (!isA_CFString(s_if)) {
+ continue; // if no interface
+ }
+
+ if (!CFEqual(ppp_if, s_if)) {
+ continue; // if not this interface
+ }
+
+ /*
+ * extract service ID, get PPP "state" entity (for status), and get
+ * the "setup" entity (for dial-on-traffic flag)
+ */
+ components = CFStringCreateArrayBySeparatingStrings(NULL, s_key, CFSTR("/"));
+ if (CFArrayGetCount(components) != 5) {
+ continue;
+ }
+ service = CFArrayGetValueAtIndex(components, 3);
+ key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+ kSCDynamicStoreDomainState,
+ service,
+ kSCEntNetPPP);
+ p_state = CFDictionaryGetValue(dict, key);
+ CFRelease(key);
+ key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+ kSCDynamicStoreDomainSetup,
+ service,
+ kSCEntNetPPP);
+ p_setup = CFDictionaryGetValue(dict, key);
+ CFRelease(key);
+ CFRelease(components);
+
+ // get PPP status
+ if (!isA_CFDictionary(p_state)) {
+ continue;
+ }
+ num = CFDictionaryGetValue(p_state, kSCPropNetPPPStatus);
+ if (!isA_CFNumber(num)) {
+ continue;
+ }
+
+ if (!CFNumberGetValue(num, kCFNumberSInt32Type, &ppp_status)) {
+ continue;
+ }
+ switch (ppp_status) {
+ case PPP_RUNNING :
+ /* if we're really UP and RUNNING */
+ break;
+ case PPP_ONHOLD :
+ /* if we're effectively UP and RUNNING */
+ break;
+ case PPP_IDLE :
+ case PPP_STATERESERVED :
+ /* if we're not connected at all */
+ SCLog(_sc_debug, LOG_INFO, CFSTR(" PPP link idle, dial-on-traffic to connect"));
+ *flags |= kSCNetworkFlagsConnectionRequired;
+ break;
+ default :
+ /* if we're in the process of [dis]connecting */
+ SCLog(_sc_debug, LOG_INFO, CFSTR(" PPP link, connection in progress"));
+ *flags |= kSCNetworkFlagsConnectionRequired;
+ break;
+ }
+
+ // check PPP dial-on-traffic status
+ if (isA_CFDictionary(p_setup)) {
+ num = CFDictionaryGetValue(p_setup, kSCPropNetPPPDialOnDemand);
+ if (isA_CFNumber(num)) {
+ int32_t ppp_demand;
+
+ if (CFNumberGetValue(num, kCFNumberSInt32Type, &ppp_demand)) {
+ if (ppp_demand) {
+ *flags |= kSCNetworkFlagsConnectionAutomatic;
+ if (ppp_status == PPP_IDLE) {
+ *flags |= kSCNetworkFlagsInterventionRequired;
+ }
+ }
+ }
+ }
+ }
+
+ break;
+ }
+
+ CFRelease(ppp_if);
+ if (keys != keys_q) {
+ CFAllocatorDeallocate(NULL, keys);
+ CFAllocatorDeallocate(NULL, values);
+ }
+
+ done :
+
+ if (dict) CFRelease(dict);
+ if (storeP) *storeP = store;
+ return sc_status;
+}
+
+
+static int
+updatePPPAvailable(SCDynamicStoreRef *storeP,
+ const struct sockaddr *sa,
+ SCNetworkConnectionFlags *flags)
+{
+ CFDictionaryRef dict = NULL;
+ CFStringRef entity;
+ CFIndex i;
+ const void * keys_q[N_QUICK];
+ const void ** keys = keys_q;
+ CFIndex n;
+ int sc_status = kSCStatusReachabilityUnknown;
+ SCDynamicStoreRef store = (storeP) ? *storeP : NULL;
+ const void * values_q[N_QUICK];
+ const void ** values = values_q;
+
+ switch (sa->sa_family) {
+ case AF_INET :
+ entity = kSCEntNetIPv4;
+ break;
+ case AF_INET6 :
+ entity = kSCEntNetIPv6;
+ break;
+ default :
+ goto done;
+ }
+
+ if (!store) {
+ store = SCDynamicStoreCreate(NULL, CFSTR("SCNetworkReachability"), NULL, NULL);
+ if (!store) {
+ SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+ goto done;
+ }
+ }
+
+ /*
+ * grab a snapshot of the PPP configuration from the dynamic store
+ */
+ {
+ CFStringRef pattern;
+ CFMutableArrayRef patterns;
+
+ patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+ kSCDynamicStoreDomainSetup,
+ kSCCompAnyRegex,
+ entity);
+ CFArrayAppendValue(patterns, pattern);
+ CFRelease(pattern);
+ pattern = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+ kSCDynamicStoreDomainSetup,
+ kSCCompAnyRegex,
+ kSCEntNetPPP);
+ CFArrayAppendValue(patterns, pattern);
+ CFRelease(pattern);
+ dict = SCDynamicStoreCopyMultiple(store, NULL, patterns);
+ CFRelease(patterns);
+ }
+ if (!dict) {
+ /* if we could not access the dynamic store */
+ goto done;
+ }
+
+ sc_status = kSCStatusOK;
+
+ /*
+ * look for an available service which will provide connectivity
+ * for the requested address family.
+ */
+ n = CFDictionaryGetCount(dict);
+ if (n <= 0) {
+ goto done;
+ }
+
+ if (n > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
+ keys = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0);
+ values = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0);
+ }
+ CFDictionaryGetKeysAndValues(dict, keys, values);
+
+ for (i = 0; i < n; i++) {
+ CFArrayRef components;
+ Boolean found = FALSE;
+ CFStringRef p_key;
+ CFDictionaryRef p_dict;
+ CFStringRef service;
+ CFStringRef s_key = (CFStringRef) keys[i];
+ CFDictionaryRef s_dict = (CFDictionaryRef)values[i];
+
+ if (!isA_CFString(s_key) || !isA_CFDictionary(s_dict)) {
+ continue;
+ }
+
+ if (!CFStringHasSuffix(s_key, entity)) {
+ continue; // if not an IPv4 or IPv6 entity
+ }
+
+ // extract service ID
+ components = CFStringCreateArrayBySeparatingStrings(NULL, s_key, CFSTR("/"));
+ if (CFArrayGetCount(components) != 5) {
+ continue;
+ }
+ service = CFArrayGetValueAtIndex(components, 3);
+
+ // check for PPP entity
+ p_key = SCDynamicStoreKeyCreateNetworkServiceEntity(NULL,
+ kSCDynamicStoreDomainSetup,
+ service,
+ kSCEntNetPPP);
+ p_dict = CFDictionaryGetValue(dict, p_key);
+ CFRelease(p_key);
+
+ if (isA_CFDictionary(p_dict)) {
+ CFNumberRef num;
+
+ /*
+ * we have a PPP service for this address family
+ */
+ found = TRUE;
+
+ *flags |= kSCNetworkFlagsReachable;
+ *flags |= kSCNetworkFlagsTransientConnection;
+ *flags |= kSCNetworkFlagsConnectionRequired;
+
+ /*
+ * get PPP dial-on-traffic status
+ */
+ num = CFDictionaryGetValue(p_dict, kSCPropNetPPPDialOnDemand);
+ if (isA_CFNumber(num)) {
+ int32_t ppp_demand;
+
+ if (CFNumberGetValue(num, kCFNumberSInt32Type, &ppp_demand)) {
+ if (ppp_demand) {
+ *flags |= kSCNetworkFlagsConnectionAutomatic;
+ }
+ }
+ }
+
+ if (_sc_debug) {
+ SCLog(TRUE, LOG_INFO, CFSTR(" status = isReachable (after connect)"));
+ SCLog(TRUE, LOG_INFO, CFSTR(" service = %@"), service);
+ }
+
+ }
+
+ CFRelease(components);
+
+ if (found) {
+ break;
+ }
+ }
+
+ if (keys != keys_q) {
+ CFAllocatorDeallocate(NULL, keys);
+ CFAllocatorDeallocate(NULL, values);
+ }
+
+ done :
+
+ if (dict) CFRelease(dict);
+ if (storeP) *storeP = store;
+ return sc_status;
+}
+
+
+#define ROUNDUP(a, size) \
+ (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
+
+#define NEXT_SA(ap) (ap) = (struct sockaddr *) \
+ ((caddr_t)(ap) + ((ap)->sa_len ? ROUNDUP((ap)->sa_len,\
+ sizeof(u_long)) :\
+ sizeof(u_long)))
+
+static void
+get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
+{
+ int i;
+
+ for (i = 0; i < RTAX_MAX; i++) {
+ if (addrs & (1 << i)) {
+ rti_info[i] = sa;
+ NEXT_SA(sa);
+ } else
+ rti_info[i] = NULL;
+ }
+}
+
+
+#define BUFLEN (sizeof(struct rt_msghdr) + 512) /* 8 * sizeof(struct sockaddr_in6) = 192 */
+
+static Boolean
+checkAddress(SCDynamicStoreRef *storeP,
+ const struct sockaddr *address,
+ SCNetworkConnectionFlags *flags,
+ uint16_t *if_index)
+{
+ char buf[BUFLEN];
+ struct ifreq ifr;
+ char if_name[IFNAMSIZ+1];
+ int isock;
+ int n;
+ pid_t pid = getpid();
+ int rsock;
+ struct sockaddr *rti_info[RTAX_MAX];
+ struct rt_msghdr *rtm;
+ struct sockaddr *sa;
+ int sc_status = kSCStatusReachabilityUnknown;
+ struct sockaddr_dl *sdl;
+ int seq = (int)pthread_self();
+ SCDynamicStoreRef store = (storeP) ? *storeP : NULL;
+ char *statusMessage = NULL;
+#ifndef RTM_GET_SILENT
+#warning Note: Using RTM_GET (and not RTM_GET_SILENT)
+ static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+ int sosize = 48 * 1024;
+#endif
+
+ if (!address || !flags) {
+ sc_status = kSCStatusInvalidArgument;
+ goto done;
+ }
+
+ switch (address->sa_family) {
+ case AF_INET :
+ case AF_INET6 :
+ if (_sc_debug) {
+ sockaddr_to_string(address, buf, sizeof(buf));
+ SCLog(TRUE, LOG_INFO, CFSTR("checkAddress(%s)"), buf);
+ }
+ break;
+ default :
+ /*
+ * if no code for this address family (yet)
+ */
+ SCLog(_sc_verbose, LOG_ERR,
+ CFSTR("checkAddress(): unexpected address family %d"),
+ address->sa_family);
+ sc_status = kSCStatusInvalidArgument;
+ goto done;
+ }
+
+ *flags = 0;
+ if (if_index) {
+ *if_index = 0;
+ }
+
+ if ((address->sa_family == AF_INET) && (((struct sockaddr_in *)address)->sin_addr.s_addr == 0)) {
+ /* special case: check for available paths off the system */
+ goto checkAvailable;
+ }
+
+ bzero(&buf, sizeof(buf));
+
+ rtm = (struct rt_msghdr *)&buf;
+ rtm->rtm_msglen = sizeof(struct rt_msghdr);
+ rtm->rtm_version = RTM_VERSION;
+#ifdef RTM_GET_SILENT
+ rtm->rtm_type = RTM_GET_SILENT;
+#else
+ rtm->rtm_type = RTM_GET;
+#endif
+ rtm->rtm_flags = RTF_STATIC|RTF_UP|RTF_HOST|RTF_GATEWAY;
+ rtm->rtm_addrs = RTA_DST|RTA_IFP; /* Both destination and device */
+ rtm->rtm_pid = pid;
+ rtm->rtm_seq = seq;
+
+ switch (address->sa_family) {
+ case AF_INET6: {
+ struct sockaddr_in6 *sin6;
+
+ sin6 = (struct sockaddr_in6 *)address;
+ if ((IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
+ IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr)) &&
+ (sin6->sin6_scope_id != 0)) {
+ sin6->sin6_addr.s6_addr16[1] = htons(sin6->sin6_scope_id);
+ sin6->sin6_scope_id = 0;
+ }
+ break;
+ }
+ }
+
+ sa = (struct sockaddr *) (rtm + 1);
+ bcopy(address, sa, address->sa_len);
+ n = ROUNDUP(sa->sa_len, sizeof(u_long));
+ rtm->rtm_msglen += n;
+
+ sdl = (struct sockaddr_dl *) ((void *)sa + n);
+ sdl->sdl_family = AF_LINK;
+ sdl->sdl_len = sizeof (struct sockaddr_dl);
+ n = ROUNDUP(sdl->sdl_len, sizeof(u_long));
+ rtm->rtm_msglen += n;
+
+#ifndef RTM_GET_SILENT
+ pthread_mutex_lock(&lock);
+#endif
+ rsock = socket(PF_ROUTE, SOCK_RAW, 0);
+ if (rsock == -1) {
+#ifndef RTM_GET_SILENT
+ pthread_mutex_unlock(&lock);
+#endif
+ SCLog(TRUE, LOG_ERR, CFSTR("socket(PF_ROUTE) failed: %s"), strerror(errno));
+ sc_status = kSCStatusFailed;
+ goto done;
+ }
+
+#ifndef RTM_GET_SILENT
+ if (setsockopt(rsock, SOL_SOCKET, SO_RCVBUF, &sosize, sizeof(sosize)) == -1) {
+ (void)close(rsock);
+ pthread_mutex_unlock(&lock);
+ SCLog(TRUE, LOG_ERR, CFSTR("setsockopt(SO_RCVBUF) failed: %s"), strerror(errno));
+ sc_status = kSCStatusFailed;
+ goto done;
+ }
+#endif
+
+ if (write(rsock, &buf, rtm->rtm_msglen) == -1) {
+ int err = errno;
+
+ (void)close(rsock);
+#ifndef RTM_GET_SILENT
+ pthread_mutex_unlock(&lock);
+#endif
+ if (err != ESRCH) {
+ SCLog(TRUE, LOG_ERR, CFSTR("write() failed: %s"), strerror(err));
+ goto done;
+ }
+ goto checkAvailable;
+ }
+
+ /*
+ * Type, seq, pid identify our response.
+ * Routing sockets are broadcasters on input.
+ */
+ do {
+ int n;
+
+ n = read(rsock, (void *)&buf, sizeof(buf));
+ if (n == -1) {
+ int err = errno;
+
+ if (err != EINTR) {
+ (void)close(rsock);
+ SCLog(TRUE, LOG_ERR, CFSTR("read() failed: %s"), strerror(err));
+#ifndef RTM_GET_SILENT
+ pthread_mutex_unlock(&lock);
+#endif
+ goto done;
+ }
+ }
+ } while (rtm->rtm_type != RTM_GET ||
+ rtm->rtm_seq != seq ||
+ rtm->rtm_pid != pid);
+
+ (void)close(rsock);
+#ifndef RTM_GET_SILENT
+ pthread_mutex_unlock(&lock);
+#endif
+
+ get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
+
+#ifdef DEBUG
+{
+ int i;
+ char buf[200];
+
+ SCLog(_sc_debug, LOG_DEBUG, CFSTR("rtm_flags = 0x%8.8x"), rtm->rtm_flags);
+
+ for (i = 0; i < RTAX_MAX; i++) {
+ if (rti_info[i] != NULL) {
+ sockaddr_to_string(rti_info[i], buf, sizeof(buf));
+ SCLog(_sc_debug, LOG_DEBUG, CFSTR("%d: %s"), i, buf);
+ }
+ }
+}
+#endif /* DEBUG */
+
+ if ((rti_info[RTAX_IFP] == NULL) ||
+ (rti_info[RTAX_IFP]->sa_family != AF_LINK)) {
+ /* no interface info */
+ goto done; // ???
+ }
+
+ sdl = (struct sockaddr_dl *) rti_info[RTAX_IFP];
+ if ((sdl->sdl_nlen == 0) || (sdl->sdl_nlen > IFNAMSIZ)) {
+ /* no interface name */
+ goto done; // ???
+ }
+
+ /* get the interface flags */
+
+ bzero(&ifr, sizeof(ifr));
+ bcopy(sdl->sdl_data, ifr.ifr_name, sdl->sdl_len);
+
+ isock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (isock < 0) {
+ SCLog(TRUE, LOG_NOTICE, CFSTR("socket() failed: %s"), strerror(errno));
+ goto done;
+ }
+
+ if (ioctl(isock, SIOCGIFFLAGS, (char *)&ifr) < 0) {
+ SCLog(TRUE, LOG_NOTICE, CFSTR("ioctl() failed: %s"), strerror(errno));
+ (void)close(isock);
+ goto done;
+ }
+ (void)close(isock);
+
+ if (!(ifr.ifr_flags & IFF_UP)) {
+ goto checkAvailable;
+ }
+
+ statusMessage = "isReachable";
+ *flags |= kSCNetworkFlagsReachable;
+
+ if (rtm->rtm_flags & RTF_LOCAL) {
+ statusMessage = "isReachable (is a local address)";
+ *flags |= kSCNetworkFlagsIsLocalAddress;
+ } else if (ifr.ifr_flags & IFF_LOOPBACK) {
+ statusMessage = "isReachable (is loopback network)";
+ *flags |= kSCNetworkFlagsIsLocalAddress;
+ } else if (rti_info[RTAX_IFA]) {
+ void *addr1 = (void *)address;
+ void *addr2 = (void *)rti_info[RTAX_IFA];
+ size_t len = address->sa_len;
+
+ if ((address->sa_family != rti_info[RTAX_IFA]->sa_family) &&
+ (address->sa_len != rti_info[RTAX_IFA]->sa_len)) {
+ SCLog(TRUE, LOG_NOTICE,
+ CFSTR("address family/length mismatch: %d/%d != %d/%d"),
+ address->sa_family,
+ address->sa_len,
+ rti_info[RTAX_IFA]->sa_family,
+ rti_info[RTAX_IFA]->sa_len);
+ goto done;
+ }
+
+ switch (address->sa_family) {
+ case AF_INET :
+ addr1 = &((struct sockaddr_in *)address)->sin_addr;
+ addr2 = &((struct sockaddr_in *)rti_info[RTAX_IFA])->sin_addr;
+ len = sizeof(struct in_addr);
+ break;
+ case AF_INET6 :
+ addr1 = &((struct sockaddr_in6 *)address)->sin6_addr;
+ addr2 = &((struct sockaddr_in6 *)rti_info[RTAX_IFA])->sin6_addr;
+ len = sizeof(struct in6_addr);
+ break;
+ default :
+ break;
+ }
+
+ if (memcmp(addr1, addr2, len) == 0) {
+ statusMessage = "isReachable (is interface address)";
+ *flags |= kSCNetworkFlagsIsLocalAddress;
+ }
+ }
+
+ if (rti_info[RTAX_GATEWAY] && (rti_info[RTAX_GATEWAY]->sa_family == AF_LINK)) {
+ *flags |= kSCNetworkFlagsIsDirect;
+ }
+
+ bzero(&if_name, sizeof(if_name));
+ bcopy(sdl->sdl_data,
+ if_name,
+ (sdl->sdl_len <= IFNAMSIZ) ? sdl->sdl_len : IFNAMSIZ);
+
+ if (if_index) {
+ *if_index = sdl->sdl_index;
+ }
+
+ if (_sc_debug) {
+ SCLog(TRUE, LOG_INFO, CFSTR(" status = %s"), statusMessage);
+ SCLog(TRUE, LOG_INFO, CFSTR(" device = %s (%hu)"), if_name, sdl->sdl_index);
+ SCLog(TRUE, LOG_INFO, CFSTR(" ifr_flags = 0x%04hx"), ifr.ifr_flags);
+ SCLog(TRUE, LOG_INFO, CFSTR(" rtm_flags = 0x%08x"), rtm->rtm_flags);
+ }
+
+ sc_status = kSCStatusOK;
+
+ if (ifr.ifr_flags & IFF_POINTOPOINT) {
+ /*
+ * We have an interface which "claims" to be a valid path
+ * off of the system.
+ */
+ *flags |= kSCNetworkFlagsTransientConnection;
+
+ /*
+ * Check if this is a dial-on-demand PPP link that isn't
+ * connected yet.
+ */
+ sc_status = updatePPPStatus(&store, address, if_name, flags);
+ }
+
+ goto done;
+
+ checkAvailable :
+
+ sc_status = updatePPPAvailable(&store, address, flags);
+
+ done :
+
+ if (*flags == 0) {
+ SCLog(_sc_debug, LOG_INFO, CFSTR(" cannot be reached"));
+ }
+
+ if (storeP) *storeP = store;
+ if (sc_status != kSCStatusOK) {
+ _SCErrorSet(sc_status);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static Boolean
+checkAddressZero(SCDynamicStoreRef *storeP,
+ SCNetworkConnectionFlags *flags,
+ uint16_t *if_index)
+{
+ Boolean ok;
+ struct sockaddr_in sin;
+
+ bzero(&sin, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = 0;
+
+ ok = checkAddress(storeP, (struct sockaddr *)&sin, flags, if_index);
+
+ return ok;
+}
+
+
+static Boolean
+isAddressZero(struct sockaddr *sa, SCNetworkConnectionFlags *flags)
+{
+ /*
+ * Check if 0.0.0.0
+ */
+ if (sa->sa_family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+
+ if (sin->sin_addr.s_addr == 0) {
+ SCLog(_sc_debug, LOG_INFO, CFSTR("isAddressZero(0.0.0.0)"));
+ SCLog(_sc_debug, LOG_INFO, CFSTR(" status = isReachable (this host)"));
+ *flags |= kSCNetworkFlagsReachable;
+ *flags |= kSCNetworkFlagsIsLocalAddress;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+static CFStringRef
+__SCNetworkReachabilityCopyDescription(CFTypeRef cf)
+{
+ CFAllocatorRef allocator = CFGetAllocator(cf);
+ CFMutableStringRef result;
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)cf;
+
+ result = CFStringCreateMutable(allocator, 0);
+ CFStringAppendFormat(result, NULL, CFSTR("<SCNetworkReachability %p [%p]> { "), cf, allocator);
+ switch (targetPrivate->type) {
+ case reachabilityTypeAddress :
+ case reachabilityTypeAddressPair : {
+ char buf[64];
+
+ if (targetPrivate->localAddress) {
+ sockaddr_to_string(targetPrivate->localAddress, buf, sizeof(buf));
+ CFStringAppendFormat(result, NULL, CFSTR("local address=%s"),
+ buf);
+ }
+
+ if (targetPrivate->remoteAddress) {
+ sockaddr_to_string(targetPrivate->remoteAddress, buf, sizeof(buf));
+ CFStringAppendFormat(result, NULL, CFSTR("%s%saddress=%s"),
+ targetPrivate->localAddress ? ", " : "",
+ (targetPrivate->type == reachabilityTypeAddressPair) ? "remote " : "",
+ buf);
+ }
+ break;
+ }
+ case reachabilityTypeName : {
+ CFStringAppendFormat(result, NULL, CFSTR("name=%s"), targetPrivate->name);
+ if (targetPrivate->resolvedAddress || (targetPrivate->resolvedAddressError != NETDB_SUCCESS)) {
+ if (targetPrivate->resolvedAddress) {
+ if (isA_CFArray(targetPrivate->resolvedAddress)) {
+ CFIndex i;
+ CFIndex n = CFArrayGetCount(targetPrivate->resolvedAddress);
+
+ CFStringAppendFormat(result, NULL, CFSTR(" ("));
+ for (i = 0; i < n; i++) {
+ CFDataRef address;
+ char buf[64];
+ struct sockaddr *sa;
+
+ address = CFArrayGetValueAtIndex(targetPrivate->resolvedAddress, i);
+ sa = (struct sockaddr *)CFDataGetBytePtr(address);
+ sockaddr_to_string(sa, buf, sizeof(buf));
+ CFStringAppendFormat(result, NULL, CFSTR("%s%s"),
+ i > 0 ? ", " : "",
+ buf);
+ }
+ CFStringAppendFormat(result, NULL, CFSTR(")"));
+ } else {
+ CFStringAppendFormat(result, NULL, CFSTR(" (no addresses)"));
+ }
+ } else {
+#ifdef CHECK_IPV6_REACHABILITY
+ CFStringAppendFormat(result, NULL, CFSTR(" (%s)"),
+ gai_strerror(targetPrivate->resolvedAddressError));
+#else /* CHECK_IPV6_REACHABILITY */
+ CFStringAppendFormat(result, NULL, CFSTR(" (%s)"),
+ __netdb_error(targetPrivate->resolvedAddressError));
+#endif /* CHECK_IPV6_REACHABILITY */
+ }
+ } else if (targetPrivate->dnsPort) {
+ CFStringAppendFormat(result, NULL, CFSTR(" (DNS query active)"));
+ }
+ break;
+ }
+ }
+ if (targetPrivate->rls) {
+ CFStringAppendFormat(result,
+ NULL,
+ CFSTR(", flags=%8.8x, if_index=%hu"),
+ targetPrivate->flags,
+ targetPrivate->if_index);
+ }
+ CFStringAppendFormat(result, NULL, CFSTR(" }"));
+
+ return result;
+}
+
+
+static void
+__SCNetworkReachabilityDeallocate(CFTypeRef cf)
+{
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)cf;
+
+ SCLog(_sc_verbose, LOG_DEBUG, CFSTR("__SCNetworkReachabilityDeallocate:"));
+
+ /* release resources */
+
+ pthread_mutex_destroy(&targetPrivate->lock);
+
+ if (targetPrivate->name)
+ CFAllocatorDeallocate(NULL, (void *)targetPrivate->name);
+
+ if (targetPrivate->resolvedAddress)
+ CFRelease(targetPrivate->resolvedAddress);
+
+ if (targetPrivate->localAddress)
+ CFAllocatorDeallocate(NULL, (void *)targetPrivate->localAddress);
+
+ if (targetPrivate->remoteAddress)
+ CFAllocatorDeallocate(NULL, (void *)targetPrivate->remoteAddress);
+
+ if (targetPrivate->rlsContext.release) {
+ targetPrivate->rlsContext.release(targetPrivate->rlsContext.info);
+ }
+
+ return;
+}
+
+
+static void
+__SCNetworkReachabilityInitialize(void)
+{
+ __kSCNetworkReachabilityTypeID = _CFRuntimeRegisterClass(&__SCNetworkReachabilityClass);
+ return;
+}
+
+
+static SCNetworkReachabilityPrivateRef
+__SCNetworkReachabilityCreatePrivate(CFAllocatorRef allocator)
+{
+ SCNetworkReachabilityPrivateRef targetPrivate;
+ uint32_t size;
+
+ /* initialize runtime */
+ pthread_once(&initialized, __SCNetworkReachabilityInitialize);
+
+ SCLog(_sc_verbose, LOG_DEBUG, CFSTR("__SCNetworkReachabilityCreatePrivate:"));
+
+ /* allocate target */
+ size = sizeof(SCNetworkReachabilityPrivate) - sizeof(CFRuntimeBase);
+ targetPrivate = (SCNetworkReachabilityPrivateRef)_CFRuntimeCreateInstance(allocator,
+ __kSCNetworkReachabilityTypeID,
+ size,
+ NULL);
+ if (!targetPrivate) {
+ return NULL;
+ }
+
+ pthread_mutex_init(&targetPrivate->lock, NULL);
+
+ targetPrivate->name = NULL;
+
+ targetPrivate->resolvedAddress = NULL;
+ targetPrivate->resolvedAddressError = NETDB_SUCCESS;
+
+ targetPrivate->localAddress = NULL;
+ targetPrivate->remoteAddress = NULL;
+
+ targetPrivate->flags = 0;
+ targetPrivate->if_index = 0;
+
+ targetPrivate->rls = NULL;
+ targetPrivate->rlsFunction = NULL;
+ targetPrivate->rlsContext.info = NULL;
+ targetPrivate->rlsContext.retain = NULL;
+ targetPrivate->rlsContext.release = NULL;
+ targetPrivate->rlsContext.copyDescription = NULL;
+ targetPrivate->rlList = NULL;
+
+ targetPrivate->dnsPort = NULL;
+ targetPrivate->dnsRLS = NULL;
+
+ return targetPrivate;
+}
+
+
+SCNetworkReachabilityRef
+SCNetworkReachabilityCreateWithAddress(CFAllocatorRef allocator,
+ const struct sockaddr *address)
+{
+ SCNetworkReachabilityPrivateRef targetPrivate;
+
+ if (!address ||
+ (address->sa_len == 0) ||
+ (address->sa_len > sizeof(struct sockaddr_storage))) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ targetPrivate = __SCNetworkReachabilityCreatePrivate(allocator);
+ if (!targetPrivate) {
+ return NULL;
+ }
+
+ targetPrivate->type = reachabilityTypeAddress;
+ targetPrivate->remoteAddress = CFAllocatorAllocate(NULL, address->sa_len, 0);
+ bcopy(address, targetPrivate->remoteAddress, address->sa_len);
+
+ return (SCNetworkReachabilityRef)targetPrivate;
+}
+
+
+SCNetworkReachabilityRef
+SCNetworkReachabilityCreateWithAddressPair(CFAllocatorRef allocator,
+ const struct sockaddr *localAddress,
+ const struct sockaddr *remoteAddress)
+{
+ SCNetworkReachabilityPrivateRef targetPrivate;
+
+ if ((localAddress == NULL) && (remoteAddress == NULL)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ if (localAddress) {
+ if ((localAddress->sa_len == 0) ||
+ (localAddress->sa_len > sizeof(struct sockaddr_storage))) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+ }
+
+ if (remoteAddress) {
+ if ((remoteAddress->sa_len == 0) ||
+ (remoteAddress->sa_len > sizeof(struct sockaddr_storage))) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+ }
+
+ targetPrivate = __SCNetworkReachabilityCreatePrivate(allocator);
+ if (!targetPrivate) {
+ return NULL;
+ }
+
+ targetPrivate->type = reachabilityTypeAddressPair;
+
+ if (localAddress) {
+ targetPrivate->localAddress = CFAllocatorAllocate(NULL, localAddress->sa_len, 0);
+ bcopy(localAddress, targetPrivate->localAddress, localAddress->sa_len);
+ }
+
+ if (remoteAddress) {
+ targetPrivate->remoteAddress = CFAllocatorAllocate(NULL, remoteAddress->sa_len, 0);
+ bcopy(remoteAddress, targetPrivate->remoteAddress, remoteAddress->sa_len);
+ }
+
+ return (SCNetworkReachabilityRef)targetPrivate;
+}
+
+
+SCNetworkReachabilityRef
+SCNetworkReachabilityCreateWithName(CFAllocatorRef allocator,
+ const char *nodename)
+{
+ SCNetworkReachabilityPrivateRef targetPrivate;
+
+ if (!nodename) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ targetPrivate = __SCNetworkReachabilityCreatePrivate(allocator);
+ if (!targetPrivate) {
+ return NULL;
+ }
+
+ targetPrivate->type = reachabilityTypeName;
+
+ targetPrivate->flags |= kSCNetworkFlagsFirstResolvePending;
+
+ targetPrivate->name = CFAllocatorAllocate(NULL, strlen(nodename) + 1, 0);
+ strcpy((char *)targetPrivate->name, nodename);
+
+ return (SCNetworkReachabilityRef)targetPrivate;
+}
+
+
+CFTypeID
+SCNetworkReachabilityGetTypeID(void)
+{
+ pthread_once(&initialized, __SCNetworkReachabilityInitialize); /* initialize runtime */
+ return __kSCNetworkReachabilityTypeID;
+}
+
+
+CFArrayRef
+SCNetworkReachabilityCopyResolvedAddress(SCNetworkReachabilityRef target,
+ int *error_num)
+{
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+
+ if (!isA_SCNetworkReachability(target)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ if (targetPrivate->type != reachabilityTypeName) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return NULL;
+ }
+
+ if (error_num) {
+ *error_num = targetPrivate->resolvedAddressError;
+ }
+
+ if (targetPrivate->resolvedAddress || (targetPrivate->resolvedAddressError != NETDB_SUCCESS)) {
+ if (targetPrivate->resolvedAddress) {
+ return CFRetain(targetPrivate->resolvedAddress);
+ } else {
+ /* if status is known but no resolved addresses to return */
+ _SCErrorSet(kSCStatusOK);
+ return NULL;
+ }
+ }
+
+ _SCErrorSet(kSCStatusReachabilityUnknown);
+ return NULL;
+}
+
+
+static void
+__SCNetworkReachabilitySetResolvedAddress(SCNetworkReachabilityRef target,
+ CFArrayRef addresses,
+ int error_num)
+{
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+
+ if (targetPrivate->resolvedAddress) {
+ CFRelease(targetPrivate->resolvedAddress);
+ }
+ targetPrivate->resolvedAddress = addresses ? CFRetain(addresses) : NULL;
+ targetPrivate->resolvedAddressError = error_num;
+ return;
+}
+
+
+#ifdef CHECK_IPV6_REACHABILITY
+static void
+__SCNetworkReachabilityCallbackSetResolvedAddress(int32_t status, struct addrinfo *res, void *context)
+{
+ Boolean ok;
+ struct addrinfo *resP;
+ SCNetworkReachabilityRef target = (SCNetworkReachabilityRef)context;
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+
+ ok = (status == 0) && (res != NULL);
+
+ SCLog(_sc_debug, LOG_DEBUG,
+ CFSTR("process async DNS complete%s"),
+ ok ? "" : ", host not found");
+
+ if (ok) {
+ CFMutableArrayRef addresses;
+
+ addresses = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+ for (resP = res; resP; resP = resP->ai_next) {
+ CFDataRef newAddress;
+
+ newAddress = CFDataCreate(NULL, (void *)resP->ai_addr, resP->ai_addr->sa_len);
+ CFArrayAppendValue(addresses, newAddress);
+ CFRelease(newAddress);
+ }
+
+ /* save the resolved address[es] */
+ __SCNetworkReachabilitySetResolvedAddress(target, addresses, NETDB_SUCCESS);
+ CFRelease(addresses);
+ } else {
+ SCLog(_sc_debug, LOG_INFO, CFSTR("getaddrinfo() failed: %s"), gai_strerror(status));
+
+ /* save the error associated with the attempt to resolve the name */
+ __SCNetworkReachabilitySetResolvedAddress(target, (CFArrayRef)kCFNull, status);
+ }
+
+ if (res) freeaddrinfo(res);
+
+ if (targetPrivate->rls) {
+ SCLog(_sc_debug, LOG_INFO, CFSTR("DNS request completed"));
+ CFRunLoopSourceSignal(targetPrivate->rls);
+ __signalRunLoop(target, targetPrivate->rls, targetPrivate->rlList);
+ }
+
+ return;
+}
+#else /* CHECK_IPV6_REACHABILITY */
+static void
+__SCNetworkReachabilityCallbackSetResolvedAddress(struct hostent *h, int error, void *context)
+{
+ SCNetworkReachabilityRef target = (SCNetworkReachabilityRef)context;
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+
+ SCLog(_sc_debug, LOG_DEBUG,
+ CFSTR("process async DNS complete%s"),
+ (h == NULL) ? ", host not found" : "");
+
+ if (h && h->h_length) {
+ CFMutableArrayRef addresses;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ struct sockaddr_storage ss;
+ } addr;
+ char **ha = h->h_addr_list;
+
+ addresses = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+ bzero(&addr, sizeof(addr));
+
+ while (*ha) {
+ CFDataRef newAddress;
+
+ switch (h->h_length) {
+ case sizeof(struct in_addr) :
+ addr.sin.sin_family = AF_INET;
+ addr.sin.sin_len = sizeof(struct sockaddr_in);
+ bcopy(*ha, &addr.sin.sin_addr, h->h_length);
+ break;
+ case sizeof(struct in6_addr) :
+ addr.sin6.sin6_family = AF_INET6;
+ addr.sin6.sin6_len = sizeof(struct sockaddr_in6);
+ bcopy(*ha, &addr.sin6.sin6_addr, h->h_length);
+ break;
+ }
+
+ newAddress = CFDataCreate(NULL, (void *)&addr, addr.sa.sa_len);
+ CFArrayAppendValue(addresses, newAddress);
+ CFRelease(newAddress);
+
+ ha++;
+ }
+
+ /* save the resolved address[es] */
+ __SCNetworkReachabilitySetResolvedAddress(target, addresses, NETDB_SUCCESS);
+ CFRelease(addresses);
+ } else {
+ SCLog(_sc_debug, LOG_INFO, CFSTR("getipnodebyname() failed: %s"), __netdb_error(error));
+
+ /* save the error associated with the attempt to resolve the name */
+ __SCNetworkReachabilitySetResolvedAddress(target, (CFArrayRef)kCFNull, error);
+ }
+
+ if (h) freehostent(h);
+
+ if (targetPrivate->rls) {
+ SCLog(_sc_debug, LOG_INFO, CFSTR("DNS request completed"));
+ CFRunLoopSourceSignal(targetPrivate->rls);
+ __signalRunLoop(target, targetPrivate->rls, targetPrivate->rlList);
+ }
+
+ return;
+}
+#endif /* CHECK_IPV6_REACHABILITY */
+
+
+/*
+ * rankReachability()
+ * Not reachable == 0
+ * Connection Required == 1
+ * Reachable == 2
+ */
+static int
+rankReachability(SCNetworkConnectionFlags flags)
+{
+ int rank = 0;
+
+ if (flags & kSCNetworkFlagsReachable) rank = 2;
+ if (flags & kSCNetworkFlagsConnectionRequired) rank = 1;
+ return rank;
+}
+
+
+#ifdef CHECK_IPV6_REACHABILITY
+static void
+getaddrinfo_async_handleCFReply(CFMachPortRef port, void *msg, CFIndex size, void *info)
+{
+ SCNetworkReachabilityRef target = (SCNetworkReachabilityRef)info;
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+
+ pthread_mutex_lock(&targetPrivate->lock);
+
+ getaddrinfo_async_handle_reply(msg);
+
+ if (port == targetPrivate->dnsPort) {
+ CFRelease(targetPrivate->dnsRLS);
+ targetPrivate->dnsRLS = NULL;
+ CFRelease(targetPrivate->dnsPort);
+ targetPrivate->dnsPort = NULL;
+ }
+
+ pthread_mutex_unlock(&targetPrivate->lock);
+
+ return;
+}
+#else /* CHECK_IPV6_REACHABILITY */
+static void
+getipnodebyname_async_handleCFReply(CFMachPortRef port, void *msg, CFIndex size, void *info)
+{
+ SCNetworkReachabilityRef target = (SCNetworkReachabilityRef)info;
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+
+ pthread_mutex_lock(&targetPrivate->lock);
+
+ getipnodebyname_async_handleReply(msg);
+
+ if (port == targetPrivate->dnsPort) {
+ CFRelease(targetPrivate->dnsRLS);
+ targetPrivate->dnsRLS = NULL;
+ CFRelease(targetPrivate->dnsPort);
+ targetPrivate->dnsPort = NULL;
+ }
+
+ pthread_mutex_unlock(&targetPrivate->lock);
+
+ return;
+}
+#endif /* CHECK_IPV6_REACHABILITY */
+
+
+static Boolean
+checkResolverReachability(SCDynamicStoreRef *storeP,
+ SCNetworkConnectionFlags *flags,
+ Boolean *haveDNS)
+{
+ int i;
+ Boolean ok = TRUE;
+
+ /*
+ * 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;
+ *haveDNS = FALSE;
+
+ if (needDNS) {
+ if (hn_store) {
+ /* if we are actively watching at least one host */
+ needDNS = FALSE;
+ }
+ res_init();
+ }
+
+ for (i = 0; i < _res.nscount; i++) {
+ 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(storeP, (struct sockaddr *)&_res.nsaddr_list[i], &ns_flags, NULL);
+ if (!ok) {
+ /* not today */
+ break;
+ }
+ if (rankReachability(ns_flags) < rankReachability(*flags)) {
+ /* return the worst case result */
+ *flags = ns_flags;
+ }
+ }
+
+ if (!*haveDNS) {
+ /* if no DNS server addresses */
+ *flags = 0;
+ }
+
+ return ok;
+}
+
+
+static Boolean
+startAsyncDNSQuery(SCNetworkReachabilityRef target) {
+ CFMachPortContext context = { 0, (void *)target, CFRetain, CFRelease, CFCopyDescription };
+ int error;
+#ifdef CHECK_IPV6_REACHABILITY
+ struct addrinfo hints;
+#endif /* CHECK_IPV6_REACHABILITY */
+ CFIndex i;
+ CFIndex n;
+ mach_port_t port;
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+
+#ifdef CHECK_IPV6_REACHABILITY
+ bzero(&hints, sizeof(hints));
+ hints.ai_flags = AI_ADDRCONFIG;
+
+ error = getaddrinfo_async_start(&port,
+ targetPrivate->name,
+ NULL,
+ &hints,
+ __SCNetworkReachabilityCallbackSetResolvedAddress,
+ (void *)target);
+ if (error != 0) {
+ /* save the error associated with the attempt to resolve the name */
+ __SCNetworkReachabilitySetResolvedAddress(target, (CFArrayRef)kCFNull, error);
+ return FALSE;
+ }
+
+ targetPrivate->dnsPort = CFMachPortCreateWithPort(NULL,
+ port,
+ getaddrinfo_async_handleCFReply,
+ &context,
+ NULL);
+#else /* CHECK_IPV6_REACHABILITY */
+ port = getipnodebyname_async_start(targetPrivate->name,
+ AF_INET,
+ 0,
+ &error,
+ __SCNetworkReachabilityCallbackSetResolvedAddress,
+ (void *)target);
+ if (port == MACH_PORT_NULL) {
+ /* save the error associated with the attempt to resolve the name */
+ __SCNetworkReachabilitySetResolvedAddress(target, (CFArrayRef)kCFNull, error);
+ return FALSE;
+ }
+
+ targetPrivate->dnsPort = CFMachPortCreateWithPort(NULL,
+ port,
+ getipnodebyname_async_handleCFReply,
+ &context,
+ NULL);
+#endif /* CHECK_IPV6_REACHABILITY */
+
+ targetPrivate->dnsRLS = CFMachPortCreateRunLoopSource(NULL, targetPrivate->dnsPort, 0);
+
+ n = CFArrayGetCount(targetPrivate->rlList);
+ for (i = 0; i < n; i += 3) {
+ CFRunLoopRef rl = (CFRunLoopRef)CFArrayGetValueAtIndex(targetPrivate->rlList, i+1);
+ CFStringRef rlMode = (CFStringRef) CFArrayGetValueAtIndex(targetPrivate->rlList, i+2);
+
+ CFRunLoopAddSource(rl, targetPrivate->dnsRLS, rlMode);
+ }
+
+ return TRUE;
+}
+
+
+static Boolean
+__SCNetworkReachabilityGetFlags(SCDynamicStoreRef *storeP,
+ SCNetworkReachabilityRef target,
+ SCNetworkConnectionFlags *flags,
+ uint16_t *if_index,
+ Boolean async)
+{
+ CFMutableArrayRef addresses = NULL;
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+ SCNetworkConnectionFlags my_flags = 0;
+ uint16_t my_index = 0;
+ Boolean ok = TRUE;
+
+ *flags = 0;
+ if (if_index) {
+ *if_index = 0;
+ }
+
+ if (!isA_SCNetworkReachability(target)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return FALSE;
+ }
+
+ switch (targetPrivate->type) {
+ case reachabilityTypeAddress :
+ case reachabilityTypeAddressPair : {
+ /*
+ * Check "local" address
+ */
+ if (targetPrivate->localAddress) {
+ /*
+ * Check if 0.0.0.0
+ */
+ if (isAddressZero(targetPrivate->localAddress, &my_flags)) {
+ goto checkRemote;
+ }
+
+ /*
+ * Check "local" address
+ */
+ ok = checkAddress(storeP, targetPrivate->localAddress, &my_flags, &my_index);
+ if (!ok) {
+ goto error; /* not today */
+ }
+
+ if (!(my_flags & kSCNetworkFlagsIsLocalAddress)) {
+ goto error; /* not reachable, non-"local" address */
+ }
+ }
+
+ checkRemote :
+
+ /*
+ * Check "remote" address
+ */
+ if (targetPrivate->remoteAddress) {
+ /*
+ * in cases where we have "local" and "remote" addresses
+ * we need to re-initialize the to-be-returned flags.
+ */
+ my_flags = 0;
+ my_index = 0;
+
+ /*
+ * Check if 0.0.0.0
+ */
+ if (isAddressZero(targetPrivate->remoteAddress, &my_flags)) {
+ break;
+ }
+
+ /*
+ * Check "remote" address
+ */
+ ok = checkAddress(storeP, targetPrivate->remoteAddress, &my_flags, &my_index);
+ if (!ok) {
+ goto error; /* not today */
+ }
+ }
+
+ break;
+
+ }
+
+ case reachabilityTypeName : {
+ int error;
+#ifndef CHECK_IPV6_REACHABILITY
+ struct hostent *h;
+#endif /* CHECK_IPV6_REACHABILITY */
+ Boolean haveDNS = FALSE;
+#ifdef CHECK_IPV6_REACHABILITY
+ struct addrinfo hints;
+#endif /* CHECK_IPV6_REACHABILITY */
+ SCNetworkConnectionFlags ns_flags;
+#ifdef CHECK_IPV6_REACHABILITY
+ struct addrinfo *res;
+#endif /* CHECK_IPV6_REACHABILITY */
+
+ addresses = (CFMutableArrayRef)SCNetworkReachabilityCopyResolvedAddress(target, &error);
+ if (addresses || (error != NETDB_SUCCESS)) {
+ /* if resolved or an error had been detected */
+ goto checkResolvedAddress;
+ }
+
+ /* check the reachability of the DNS servers */
+ ok = checkResolverReachability(storeP, &ns_flags, &haveDNS);\
+ if (!ok) {
+ /* if we could not get DNS server info */
+ goto error;
+ }
+
+ if (rankReachability(ns_flags) < 2) {
+ /*
+ * if DNS servers are not (or are no longer) reachable, set
+ * flags based on the availability of configured (but not
+ * active) services.
+ */
+ if (!checkAddressZero(storeP, &my_flags, &my_index)) {
+ goto error;
+ }
+
+ if (async && targetPrivate->rls) {
+ /*
+ * return HOST_NOT_FOUND, set flags appropriately,
+ * and schedule notification.
+ */
+#ifdef CHECK_IPV6_REACHABILITY
+ __SCNetworkReachabilityCallbackSetResolvedAddress(EAI_NODATA,
+ NULL,
+ (void *)target);
+#else /* CHECK_IPV6_REACHABILITY */
+ __SCNetworkReachabilityCallbackSetResolvedAddress(NULL,
+ HOST_NOT_FOUND,
+ (void *)target);
+#endif /* CHECK_IPV6_REACHABILITY */
+
+ my_flags |= (targetPrivate->flags & kSCNetworkFlagsFirstResolvePending);
+
+ SCLog(_sc_debug, LOG_INFO, CFSTR("no DNS servers are reachable"));
+ CFRunLoopSourceSignal(targetPrivate->rls);
+ __signalRunLoop(target, targetPrivate->rls, targetPrivate->rlList);
+ }
+ break;
+ }
+
+ if (async) {
+ /* for async requests we return the last known status */
+ my_flags = targetPrivate->flags;
+ my_index = targetPrivate->if_index;
+
+ if (targetPrivate->dnsPort) {
+ /* if request already in progress */
+ break;
+ }
+
+ SCLog(_sc_debug, LOG_INFO, CFSTR("start DNS query for \"%s\""), targetPrivate->name);
+
+ /*
+ * initiate an async DNS query
+ */
+ if (!startAsyncDNSQuery(target)) {
+ /* if we could not initiate the request, process error */
+ goto checkResolvedAddress;
+ }
+
+ /* if request initiated */
+ break;
+ }
+
+ SCLog(_sc_debug, LOG_INFO, CFSTR("check DNS for \"%s\""), targetPrivate->name);
+
+ /*
+ * OK, all of the DNS name servers are available. Let's
+ * resolve the nodename into an address.
+ */
+#ifdef CHECK_IPV6_REACHABILITY
+ bzero(&hints, sizeof(hints));
+ hints.ai_flags = AI_ADDRCONFIG;
+
+ error = getaddrinfo(targetPrivate->name, NULL, &hints, &res);
+ __SCNetworkReachabilityCallbackSetResolvedAddress(error, res, (void *)target);
+#else /* CHECK_IPV6_REACHABILITY */
+ h = getipnodebyname(targetPrivate->name, AF_INET, 0, &error);
+ __SCNetworkReachabilityCallbackSetResolvedAddress(h, error, (void *)target);
+#endif /* CHECK_IPV6_REACHABILITY */
+
+ addresses = (CFMutableArrayRef)SCNetworkReachabilityCopyResolvedAddress(target, &error);
+
+ checkResolvedAddress :
+
+ /*
+ * We first assume that the requested host is NOT available.
+ * Then, check each address for accessibility and return the
+ * best status available.
+ */
+ my_flags = 0;
+ my_index = 0;
+
+ if (isA_CFArray(addresses)) {
+ CFIndex i;
+ CFIndex n = CFArrayGetCount(addresses);
+
+ for (i = 0; i < n; i++) {
+ SCNetworkConnectionFlags ns_flags = 0;
+ uint16_t ns_if_index = 0;
+ struct sockaddr *sa;
+
+ sa = (struct sockaddr *)CFDataGetBytePtr(CFArrayGetValueAtIndex(addresses, i));
+ ok = checkAddress(storeP, sa, &ns_flags, &ns_if_index);
+ if (!ok) {
+ goto error; /* not today */
+ }
+
+ if (rankReachability(ns_flags) > rankReachability(my_flags)) {
+ /* return the best case result */
+ my_flags = ns_flags;
+ my_index = ns_if_index;
+ if (rankReachability(my_flags) == 2) {
+ /* we're in luck */
+ break;
+ }
+ }
+ }
+ } else {
+ if ((error == HOST_NOT_FOUND) && !haveDNS) {
+ /*
+ * No DNS servers are defined. Set flags based on
+ * the availability of configured (but not active)
+ * services.
+ */
+ ok = checkAddressZero(storeP, &my_flags, &my_index);
+ if (!ok) {
+ goto error; /* not today */
+ }
+
+ if ((my_flags & kSCNetworkFlagsReachable) &&
+ (my_flags & kSCNetworkFlagsConnectionRequired)) {
+ /*
+ * Since we might pick up a set of DNS servers when this connection
+ * is established, don't reply with a "HOST NOT FOUND" error just yet.
+ */
+ break;
+ }
+
+ /* Host not found, not reachable! */
+ my_flags = 0;
+ my_index = 0;
+ }
+ }
+
+ break;
+ }
+ }
+
+ *flags = my_flags;
+ if (if_index) {
+ *if_index = my_index;
+ }
+
+ error :
+
+ if (addresses) CFRelease(addresses);
+ return ok;
+}
+
+
+Boolean
+SCNetworkReachabilityGetFlags(SCNetworkReachabilityRef target,
+ SCNetworkConnectionFlags *flags)
+{
+ Boolean ok;
+ SCDynamicStoreRef store = NULL;
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+
+ if (!isA_SCNetworkReachability(target)) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return FALSE;
+ }
+
+ if (targetPrivate->rlList) {
+ /* if being watched, return current (OK, last known) status */
+ *flags = targetPrivate->flags & ~kSCNetworkFlagsFirstResolvePending;
+ return TRUE;
+ }
+
+ ok = __SCNetworkReachabilityGetFlags(&store, target, flags, NULL, FALSE);
+ *flags &= ~kSCNetworkFlagsFirstResolvePending;
+ if (store) CFRelease(store);
+ return ok;
+}
+
+
+static void
+__SCNetworkReachabilityReachabilitySetNotifications(SCDynamicStoreRef store)
+{
+ CFStringRef key;
+ CFMutableArrayRef keys;
+ CFStringRef pattern;
+ CFMutableArrayRef patterns;
+
+ keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ patterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+ /*
+ * Setup:/Network/Global/IPv4 (for the ServiceOrder)
+ */
+ key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+ kSCDynamicStoreDomainSetup,
+ kSCEntNetIPv4);
+ CFArrayAppendValue(keys, key);
+ CFRelease(key);
+
+ /*
+ * State:/Network/Global/DNS
+ */
+ key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+ kSCDynamicStoreDomainState,
+ kSCEntNetDNS);
+ CFArrayAppendValue(keys, key);
+ CFRelease(key);
+
+ /*
+ * State:/Network/Global/IPv4
+ */
+ key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+ kSCDynamicStoreDomainState,
+ kSCEntNetIPv4);
+ CFArrayAppendValue(keys, key);
+ CFRelease(key);
+
+ /* 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);
+
+ /* State: per-interface IPv6 info */
+ pattern = SCDynamicStoreKeyCreateNetworkInterfaceEntity(NULL,
+ kSCDynamicStoreDomainState,
+ kSCCompAnyRegex,
+ kSCEntNetIPv6);
+ CFArrayAppendValue(patterns, pattern);
+ CFRelease(pattern);
+
+ (void)SCDynamicStoreSetNotificationKeys(store, keys, patterns);
+ CFRelease(keys);
+ CFRelease(patterns);
+
+ return;
+}
+
+
+static void
+__SCNetworkReachabilityReachabilityHandleChanges(SCDynamicStoreRef store,
+ CFArrayRef changedKeys,
+ void *info)
+{
+ Boolean dnsChanged = FALSE;
+ CFIndex i;
+ CFStringRef key;
+ CFIndex nTargets;
+ const void * targets_q[N_QUICK];
+ const void ** targets = targets_q;
+
+ pthread_mutex_lock(&hn_lock);
+
+ nTargets = CFSetGetCount(hn_targets);
+ if (nTargets == 0) {
+ /* if no addresses being monitored */
+ goto done;
+ }
+
+ if (CFArrayGetCount(changedKeys) == 0) {
+ /* if no changes */
+ goto done;
+ }
+
+ SCLog(_sc_debug, LOG_INFO, CFSTR("process configuration change"));
+
+ key = SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL,
+ kSCDynamicStoreDomainState,
+ kSCEntNetDNS);
+ if (CFArrayContainsValue(changedKeys,
+ CFRangeMake(0, CFArrayGetCount(changedKeys)),
+ key)) {
+ dnsChanged = TRUE; /* the DNS server(s) have changed */
+ needDNS = TRUE; /* ... and we need to res_init() on the next query */
+ }
+ CFRelease(key);
+
+ if (!dnsChanged) {
+ /*
+ * if the DNS configuration didn't change we still need to
+ * check that the DNS servers are accessible.
+ */
+ Boolean haveDNS = FALSE;
+ SCNetworkConnectionFlags ns_flags;
+ Boolean ok;
+
+ /* check the reachability of the DNS servers */
+ ok = checkResolverReachability(&store, &ns_flags, &haveDNS);\
+ if (!ok || (rankReachability(ns_flags) < 2)) {
+ /* if DNS servers are not reachable */
+ dnsChanged = TRUE;
+ }
+ }
+
+ SCLog(_sc_debug && dnsChanged, LOG_INFO, CFSTR(" DNS changed"));
+
+ if (nTargets > (CFIndex)(sizeof(targets_q) / sizeof(CFTypeRef)))
+ targets = CFAllocatorAllocate(NULL, nTargets * sizeof(CFTypeRef), 0);
+ CFSetGetValues(hn_targets, targets);
+ for (i = 0; i < nTargets; i++) {
+ SCNetworkReachabilityRef target = targets[i];
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+
+ pthread_mutex_lock(&targetPrivate->lock);
+
+ if (dnsChanged) {
+ if (targetPrivate->dnsPort) {
+ /* cancel the outstanding DNS query */
+#ifdef CHECK_IPV6_REACHABILITY
+ lu_async_call_cancel(CFMachPortGetPort(targetPrivate->dnsPort));
+#else /* CHECK_IPV6_REACHABILITY */
+ getipnodebyname_async_cancel(CFMachPortGetPort(targetPrivate->dnsPort));
+#endif /* CHECK_IPV6_REACHABILITY */
+ CFRelease(targetPrivate->dnsRLS);
+ targetPrivate->dnsRLS = NULL;
+ CFRelease(targetPrivate->dnsPort);
+ targetPrivate->dnsPort = NULL;
+ }
+
+ /* schedule request to resolve the name again */
+ __SCNetworkReachabilitySetResolvedAddress(target, NULL, NETDB_SUCCESS);
+ }
+
+ CFRunLoopSourceSignal(targetPrivate->rls);
+ __signalRunLoop(target, targetPrivate->rls, targetPrivate->rlList);
+
+ pthread_mutex_unlock(&targetPrivate->lock);
+ }
+ if (targets != targets_q) CFAllocatorDeallocate(NULL, targets);
+
+ done :
+
+ pthread_mutex_unlock(&hn_lock);
+ return;
+}
+
+
+static Boolean
+__isScheduled(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode, CFMutableArrayRef rlList)
+{
+ CFIndex i;
+ CFIndex n = CFArrayGetCount(rlList);
+
+ for (i = 0; i < n; i += 3) {
+ if (obj && !CFEqual(obj, CFArrayGetValueAtIndex(rlList, i))) {
+ continue;
+ }
+ if (runLoop && !CFEqual(runLoop, CFArrayGetValueAtIndex(rlList, i+1))) {
+ continue;
+ }
+ if (runLoopMode && !CFEqual(runLoopMode, CFArrayGetValueAtIndex(rlList, i+2))) {
+ continue;
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static void
+__schedule(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode, CFMutableArrayRef rlList)
+{
+ CFArrayAppendValue(rlList, obj);
+ CFArrayAppendValue(rlList, runLoop);
+ CFArrayAppendValue(rlList, runLoopMode);
+
+ return;
+}
+
+
+static Boolean
+__unschedule(CFTypeRef obj, CFRunLoopRef runLoop, CFStringRef runLoopMode, CFMutableArrayRef rlList, Boolean all)
+{
+ CFIndex i = 0;
+ Boolean found = FALSE;
+ CFIndex n = CFArrayGetCount(rlList);
+
+ while (i < n) {
+ if (obj && !CFEqual(obj, CFArrayGetValueAtIndex(rlList, i))) {
+ i += 3;
+ continue;
+ }
+ if (runLoop && !CFEqual(runLoop, CFArrayGetValueAtIndex(rlList, i+1))) {
+ i += 3;
+ continue;
+ }
+ if (runLoopMode && !CFEqual(runLoopMode, CFArrayGetValueAtIndex(rlList, i+2))) {
+ i += 3;
+ continue;
+ }
+
+ found = TRUE;
+
+ CFArrayRemoveValueAtIndex(rlList, i + 2);
+ CFArrayRemoveValueAtIndex(rlList, i + 1);
+ CFArrayRemoveValueAtIndex(rlList, i);
+
+ if (!all) {
+ return found;
+ }
+
+ n -= 3;
+ }
+
+ return found;
+}
+
+
+static void
+rlsPerform(void *info)
+{
+ void *context_info;
+ void (*context_release)(const void *);
+ SCNetworkConnectionFlags flags;
+ uint16_t if_index;
+ Boolean ok;
+ SCNetworkReachabilityCallBack rlsFunction;
+ SCDynamicStoreRef store = NULL;
+ SCNetworkReachabilityRef target = (SCNetworkReachabilityRef)info;
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+
+ SCLog(_sc_debug, LOG_DEBUG, CFSTR("process reachability change"));
+
+ pthread_mutex_lock(&targetPrivate->lock);
+
+ /* update reachability, notify if status changed */
+ ok = __SCNetworkReachabilityGetFlags(&store, target, &flags, &if_index, TRUE);
+ if (store) CFRelease(store);
+ if (!ok) {
+ /* if reachability status not available */
+ flags = 0;
+ if_index = 0;
+ }
+
+ if ((targetPrivate->flags == flags) && (targetPrivate->if_index == if_index)) {
+ /* if reachability flags and interface have not changed */
+ pthread_mutex_unlock(&targetPrivate->lock);
+ SCLog(_sc_debug, LOG_DEBUG, CFSTR("flags/interface match"));
+ return;
+ }
+
+ /* update flags / interface */
+ targetPrivate->flags = flags;
+ targetPrivate->if_index = if_index;
+
+ /* callout */
+ rlsFunction = targetPrivate->rlsFunction;
+ if (NULL != targetPrivate->rlsContext.retain) {
+ context_info = (void *)targetPrivate->rlsContext.retain(targetPrivate->rlsContext.info);
+ context_release = targetPrivate->rlsContext.release;
+ } else {
+ context_info = targetPrivate->rlsContext.info;
+ context_release = NULL;
+ }
+
+ pthread_mutex_unlock(&targetPrivate->lock);
+
+ if (rlsFunction) {
+ SCLog(_sc_debug, LOG_DEBUG, CFSTR("flags/interface have changed"));
+ (*rlsFunction)(target, flags, context_info);
+ }
+
+ if (context_release) {
+ context_release(context_info);
+ }
+
+ return;
+}
+
+
+Boolean
+SCNetworkReachabilitySetCallback(SCNetworkReachabilityRef target,
+ SCNetworkReachabilityCallBack callout,
+ SCNetworkReachabilityContext *context)
+{
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+
+ pthread_mutex_lock(&targetPrivate->lock);
+
+ if (targetPrivate->rlsContext.release) {
+ /* let go of the current context */
+ targetPrivate->rlsContext.release(targetPrivate->rlsContext.info);
+ }
+
+ targetPrivate->rlsFunction = callout;
+ targetPrivate->rlsContext.info = NULL;
+ targetPrivate->rlsContext.retain = NULL;
+ targetPrivate->rlsContext.release = NULL;
+ targetPrivate->rlsContext.copyDescription = NULL;
+ if (context) {
+ bcopy(context, &targetPrivate->rlsContext, sizeof(SCNetworkReachabilityContext));
+ if (context->retain) {
+ targetPrivate->rlsContext.info = (void *)context->retain(context->info);
+ }
+ }
+
+ pthread_mutex_unlock(&targetPrivate->lock);
+
+ return TRUE;
+}
+
+
+Boolean
+SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef target,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode)
+{
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+ Boolean init = FALSE;
+ Boolean ok = FALSE;
+
+ if (!isA_SCNetworkReachability(target) || runLoop == NULL || runLoopMode == NULL) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ return FALSE;
+ }
+
+ /* schedule the SCNetworkReachability run loop source */
+
+ pthread_mutex_lock(&hn_lock);
+ pthread_mutex_lock(&targetPrivate->lock);
+
+ if (!hn_store) {
+ /*
+ * if we are not monitoring any hosts
+ */
+ hn_store = SCDynamicStoreCreate(NULL,
+ CFSTR("SCNetworkReachability"),
+ __SCNetworkReachabilityReachabilityHandleChanges,
+ NULL);
+ if (!hn_store) {
+ SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
+ goto done;
+ }
+
+ __SCNetworkReachabilityReachabilitySetNotifications(hn_store);
+
+ hn_storeRLS = SCDynamicStoreCreateRunLoopSource(NULL, hn_store, 0);
+ hn_rlList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ hn_targets = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
+ }
+
+ if (!targetPrivate->rls) {
+ CFRunLoopSourceContext context = { 0 // version
+ , (void *)target // info
+ , CFRetain // retain
+ , CFRelease // release
+ , CFCopyDescription // copyDescription
+ , CFEqual // equal
+ , CFHash // hash
+ , NULL // schedule
+ , NULL // cancel
+ , rlsPerform // perform
+ };
+
+ targetPrivate->rls = CFRunLoopSourceCreate(NULL, 0, &context);
+ targetPrivate->rlList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ init = TRUE;
+ }
+
+ if (!__isScheduled(NULL, runLoop, runLoopMode, targetPrivate->rlList)) {
+ /*
+ * if we do not already have host notifications scheduled with
+ * this runLoop / runLoopMode
+ */
+ CFRunLoopAddSource(runLoop, targetPrivate->rls, runLoopMode);
+
+ if (targetPrivate->dnsRLS) {
+ /* if we have an active async DNS query too */
+ CFRunLoopAddSource(runLoop, targetPrivate->dnsRLS, runLoopMode);
+ }
+ }
+
+ __schedule(target, runLoop, runLoopMode, targetPrivate->rlList);
+
+ /* schedule the SCNetworkReachability run loop source */
+
+ if (!__isScheduled(NULL, runLoop, runLoopMode, hn_rlList)) {
+ /*
+ * if we do not already have SC notifications scheduled with
+ * this runLoop / runLoopMode
+ */
+ CFRunLoopAddSource(runLoop, hn_storeRLS, runLoopMode);
+ }
+
+ __schedule(target, runLoop, runLoopMode, hn_rlList);
+ CFSetAddValue(hn_targets, target);
+
+ if (init) {
+ SCNetworkConnectionFlags flags;
+ uint16_t if_index;
+ SCDynamicStoreRef store = NULL;
+
+ /*
+ * if we have yet to schedule SC notifications for this address
+ * - initialize current reachability status
+ */
+ if (__SCNetworkReachabilityGetFlags(&store, target, &flags, &if_index, TRUE)) {
+ /*
+ * if reachability status available
+ * - set flags
+ * - schedule notification to report status via callback
+ */
+ targetPrivate->flags = flags;
+ targetPrivate->if_index = if_index;
+ CFRunLoopSourceSignal(targetPrivate->rls);
+ __signalRunLoop(target, targetPrivate->rls, targetPrivate->rlList);
+ } else {
+ /* if reachability status not available, async lookup started */
+ targetPrivate->flags = 0;
+ targetPrivate->if_index = 0;
+ }
+ if (store) CFRelease(store);
+ }
+
+ ok = TRUE;
+
+ done :
+
+ pthread_mutex_unlock(&targetPrivate->lock);
+ pthread_mutex_unlock(&hn_lock);
+ return ok;
+}
+
+
+Boolean
+SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef target,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode)
+{
+ SCNetworkReachabilityPrivateRef targetPrivate = (SCNetworkReachabilityPrivateRef)target;
+ CFIndex n;
+ Boolean ok = FALSE;
+
+ if (!isA_SCNetworkReachability(target) || runLoop == NULL || runLoopMode == NULL) {
+ _SCErrorSet(kSCStatusInvalidArgument);
+ goto done;
+ }
+
+ pthread_mutex_lock(&hn_lock);
+ pthread_mutex_lock(&targetPrivate->lock);
+
+ if (!targetPrivate->rls) {
+ /* if not currently scheduled */
+ goto done;
+ }
+
+ if (!__unschedule(NULL, runLoop, runLoopMode, targetPrivate->rlList, FALSE)) {
+ /* if not currently scheduled */
+ goto done;
+ }
+
+ n = CFArrayGetCount(targetPrivate->rlList);
+ if (n == 0 || !__isScheduled(NULL, runLoop, runLoopMode, targetPrivate->rlList)) {
+ /*
+ * if this host is no longer scheduled for this runLoop / runLoopMode
+ */
+ CFRunLoopRemoveSource(runLoop, targetPrivate->rls, runLoopMode);
+
+ if (targetPrivate->dnsRLS) {
+ /* if we have an active async DNS query too */
+ CFRunLoopRemoveSource(runLoop, targetPrivate->dnsRLS, runLoopMode);
+ }
+
+ if (n == 0) {
+ /*
+ * if this host is no longer scheduled
+ */
+ CFRelease(targetPrivate->rls); /* cleanup SCNetworkReachability resources */
+ targetPrivate->rls = NULL;
+ CFRelease(targetPrivate->rlList);
+ targetPrivate->rlList = NULL;
+ CFSetRemoveValue(hn_targets, target); /* cleanup notification resources */
+
+ if (targetPrivate->dnsPort) {
+ /* if we have an active async DNS query too */
+#ifdef CHECK_IPV6_REACHABILITY
+ lu_async_call_cancel(CFMachPortGetPort(targetPrivate->dnsPort));
+#else /* CHECK_IPV6_REACHABILITY */
+ getipnodebyname_async_cancel(CFMachPortGetPort(targetPrivate->dnsPort));
+#endif /* CHECK_IPV6_REACHABILITY */
+ CFRelease(targetPrivate->dnsRLS);
+ targetPrivate->dnsRLS = NULL;
+ CFRelease(targetPrivate->dnsPort);
+ targetPrivate->dnsPort = NULL;
+ }
+ }
+ }
+
+ (void)__unschedule(target, runLoop, runLoopMode, hn_rlList, FALSE);
+
+ n = CFArrayGetCount(hn_rlList);
+ if (n == 0 || !__isScheduled(NULL, runLoop, runLoopMode, hn_rlList)) {
+ /*
+ * if we no longer have any addresses scheduled for
+ * this runLoop / runLoopMode
+ */
+ CFRunLoopRemoveSource(runLoop, hn_storeRLS, runLoopMode);
+
+ if (n == 0) {
+ /*
+ * if we are no longer monitoring any addresses
+ */
+ CFRelease(hn_targets);
+ CFRelease(hn_rlList);
+ CFRelease(hn_storeRLS);
+ CFRelease(hn_store);
+ hn_store = NULL;
+
+ /*
+ * until we start monitoring again, ensure that
+ * all subsequent reachability-by-name checks
+ * call res_init()
+ */
+ needDNS = TRUE;
+ }
+ }
+
+ ok = TRUE;
+
+ done :
+
+ pthread_mutex_unlock(&targetPrivate->lock);
+ pthread_mutex_unlock(&hn_lock);
+ return ok;
+}
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SCNETWORKREACHABILITY_H
+#define _SCNETWORKREACHABILITY_H
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <AvailabilityMacros.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <SystemConfiguration/SCNetwork.h>
+
+/*!
+ @header SCNetworkReachability
+ The SCNetworkReachabilityXXX() APIs allow an application to determine the status
+ of a system's current network configuration and the reachability
+ of a target host. In addition, the reachability can be monitored
+ with a notification being provided when/if the status has changed.
+
+ The term "reachable" reflects whether a data packet, sent by
+ an application into the network stack, can be sent to the
+ the target host/address. Please note that there is no
+ guarantee that the data packet will actually be received by
+ the host.
+ */
+
+/*!
+ @typedef SCNetworkReachabilityRef
+ @discussion This is the handle to a network address/name.
+ */
+typedef const struct __SCNetworkReachability * SCNetworkReachabilityRef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @typedef SCNetworkReachabilityContext
+ */
+typedef struct {
+ CFIndex version;
+ void * info;
+ const void *(*retain)(const void *info);
+ void (*release)(const void *info);
+ CFStringRef (*copyDescription)(const void *info);
+} SCNetworkReachabilityContext AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+/*!
+ @typedef SCNetworkReachabilityCallBack
+ @discussion Type of the callback function used when the
+ reachability of a network address/name changes.
+ @param target The SCNetworkReachability reference being monitored for changes.
+ @param flags The new SCNetworkConnectionFlags representing the
+ reachability status of the network address/name.
+ @param info ....
+ */
+typedef void (*SCNetworkReachabilityCallBack) (
+ SCNetworkReachabilityRef target,
+ SCNetworkConnectionFlags flags,
+ void *info
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+__BEGIN_DECLS
+
+/*!
+ @function SCNetworkReachabilityCreateWithAddress
+ @discussion Creates a reference to the specified network
+ address. This reference can later be used to monitor
+ the reachability of the target host.
+ @param address The address of the desired host.
+ @result A reference to the new immutable SCNetworkReachabilityRef.
+
+ You must release the returned value.
+ */
+SCNetworkReachabilityRef
+SCNetworkReachabilityCreateWithAddress (
+ CFAllocatorRef allocator,
+ const struct sockaddr *address
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+/*!
+ @function SCNetworkReachabilityCreateWithAddressPair
+ @discussion Creates a reference to the specified network
+ address. This reference can later be used to monitor
+ the reachability of the target host.
+ @param localAddress The local address associated with a network
+ connection. If NULL, only the remote address is of interest.
+ @param remoteAddress The remote address associated with a network
+ connection. If NULL, only the local address is of interest.
+ @result A reference to the new immutable SCNetworkReachabilityRef.
+
+ You must release the returned value.
+ */
+SCNetworkReachabilityRef
+SCNetworkReachabilityCreateWithAddressPair (
+ CFAllocatorRef allocator,
+ const struct sockaddr *localAddress,
+ const struct sockaddr *remoteAddress
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+/*!
+ @function SCNetworkReachabilityCreateWithName
+ @discussion Creates a reference to the specified network host/node
+ name. This reference can later be used to monitor the
+ reachability of the target host.
+ @param nodename The node name of the desired host. This name would
+ be the same as that passed to gethostbyname() or getaddrinfo().
+ @result A reference to the new immutable SCNetworkReachabilityRef.
+
+ You must release the returned value.
+ */
+SCNetworkReachabilityRef
+SCNetworkReachabilityCreateWithName (
+ CFAllocatorRef allocator,
+ const char *nodename
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+/*!
+ @function SCNetworkReachabilityGetTypeID
+ Returns the type identifier of all SCNetworkReachability instances.
+ */
+CFTypeID
+SCNetworkReachabilityGetTypeID (void) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+
+/*!
+ @function SCNetworkReachabilityGetFlags
+ @discussion Determines if the given target is reachable using the
+ current network configuration.
+ @param target The network reference associated with the address/name
+ to be checked for reachability.
+ @param flags A pointer to memory that will be filled with the
+ SCNetworkConnectionFlags detailing the reachability
+ of the specified target.
+ @result TRUE if the network connection flags are valid; FALSE if the
+ status could not be determined.
+ */
+Boolean
+SCNetworkReachabilityGetFlags (
+ SCNetworkReachabilityRef target,
+ SCNetworkConnectionFlags *flags
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+/*!
+ @function SCNetworkReachabilitySetCallback
+ @discussion Assigns a client to a target, which receives callbacks
+ when the reachability of the target changes.
+ @param target The network reference associated with the address/name
+ to be checked for reachability.
+ @param callout The function to be called when the reachability of
+ target changes. If NULL, the current client for the target
+ is removed.
+ @param context The SCNetworkReachabilityContext associated with
+ the callout.
+ @result TRUE if the notification client was successfully set.
+ */
+Boolean
+SCNetworkReachabilitySetCallback (
+ SCNetworkReachabilityRef target,
+ SCNetworkReachabilityCallBack callout,
+ SCNetworkReachabilityContext *context
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+/*!
+ @function SCNetworkReachabilityScheduleWithRunLoop
+ @discussion Schedule the given target from the given run loop and mode.
+ @param target The address/name which is set up for asynchronous mode. Must be non-NULL.
+ @param runLoop A reference to a runloop on which the target should be scheduled. Must be non-NULL.
+ @param runLoopMode The mode on which to schedule the target. Must be non-NULL.
+ */
+Boolean
+SCNetworkReachabilityScheduleWithRunLoop (
+ SCNetworkReachabilityRef target,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+/*!
+ @function SCNetworkReachabilityUnscheduleFromRunLoop
+ @discussion Unschedule the given target from the given run loop and mode.
+ @param target The address/name which is set up for asynchronous mode. Must be non-NULL.
+ @param runLoop A reference to a runloop on which the target should be scheduled. Must be non-NULL.
+ @param runLoopMode The mode on which to schedule the target. Must be non-NULL.
+ */
+Boolean
+SCNetworkReachabilityUnscheduleFromRunLoop (
+ SCNetworkReachabilityRef target,
+ CFRunLoopRef runLoop,
+ CFStringRef runLoopMode
+ ) AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER;
+
+__END_DECLS
+
+#endif /* _SCNETWORKREACHABILITY_H */
/*
- * Copyright(c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright(c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
__SCPreferencesPath(CFAllocatorRef allocator,
CFStringRef prefsID,
Boolean perUser,
- CFStringRef user)
+ CFStringRef user,
+ Boolean useNewPrefs)
{
CFStringRef path = NULL;
- int pathLen;
char *pathStr;
if (perUser) {
return NULL;
} else if (CFStringHasPrefix(prefsID, CFSTR("/"))) {
/* if absolute path */
- path = CFRetain(prefsID);
+ path = CFStringCreateCopy(allocator, prefsID);
} else {
/*
* relative (to the user's preferences) path
/* if could not get console user */
return NULL;
}
- (void) CFStringGetBytes(u,
- CFRangeMake(0, CFStringGetLength(u)),
- kCFStringEncodingMacRoman,
- 0,
- FALSE,
- login,
- MAXLOGNAME,
- NULL);
+
+ (void)_SC_cfstring_to_cstring(u, login, sizeof(login), kCFStringEncodingASCII);
CFRelease(u);
} else {
/* use specified user */
- (void) CFStringGetBytes(user,
- CFRangeMake(0, CFStringGetLength(user)),
- kCFStringEncodingMacRoman,
- 0,
- FALSE,
- login,
- MAXLOGNAME,
- NULL);
+ (void)_SC_cfstring_to_cstring(user, login, sizeof(login), kCFStringEncodingASCII);
}
/* get password entry for user */
path = CFStringCreateWithFormat(allocator,
NULL,
CFSTR("%@/%@"),
- PREFS_DEFAULT_DIR,
- PREFS_DEFAULT_CONFIG);
+ useNewPrefs ? PREFS_DEFAULT_DIR : PREFS_DEFAULT_DIR_OLD,
+ useNewPrefs ? PREFS_DEFAULT_CONFIG : PREFS_DEFAULT_CONFIG_OLD);
} else if (CFStringHasPrefix(prefsID, CFSTR("/"))) {
/* if absolute path */
- path = CFRetain(prefsID);
+ path = CFStringCreateCopy(allocator, prefsID);
} else {
/* relative path */
path = CFStringCreateWithFormat(allocator,
NULL,
CFSTR("%@/%@"),
- PREFS_DEFAULT_DIR,
+ useNewPrefs ? PREFS_DEFAULT_DIR : PREFS_DEFAULT_DIR_OLD,
prefsID);
+ if (useNewPrefs && CFStringHasSuffix(path, CFSTR(".xml"))) {
+ CFMutableStringRef newPath;
+
+ newPath = CFStringCreateMutableCopy(allocator, 0, path);
+ CFStringReplace(newPath,
+ CFRangeMake(CFStringGetLength(newPath)-4, 4),
+ CFSTR(".plist"));
+ CFRelease(path);
+ path = newPath;
+ }
}
}
/*
* convert CFStringRef path to C-string path
*/
- pathLen = CFStringGetLength(path) + 1;
- pathStr = CFAllocatorAllocate(allocator, pathLen, 0);
- if (!CFStringGetCString(path,
- pathStr,
- pathLen,
- kCFStringEncodingMacRoman)) {
+ pathStr = _SC_cfstring_to_cstring(path, NULL, 0, kCFStringEncodingASCII);
+ if (pathStr == NULL) {
SCLog(_sc_verbose, LOG_DEBUG, CFSTR("could not convert path to C string"));
- CFAllocatorDeallocate(allocator, pathStr);
- pathStr = NULL;
}
CFRelease(path);
char *pathStr;
char *typeStr;
- pathStr = __SCPreferencesPath(allocator, prefsID, perUser, user);
+ pathStr = __SCPreferencesPath(allocator, prefsID, perUser, user, TRUE);
if (pathStr == NULL) {
return NULL;
}
typeStr,
pathStr);
- CFAllocatorDeallocate(allocator, pathStr);
+ CFAllocatorDeallocate(NULL, pathStr);
return key;
}
CFStringRef
SCDynamicStoreKeyCreatePreferences(CFAllocatorRef allocator,
CFStringRef prefsID,
- int keyType)
+ SCPreferencesKeyType keyType)
{
return _SCPNotificationKey(allocator, prefsID, FALSE, NULL, keyType);
}
CFStringRef
-SCDynamicStoreKeyCreateUserPreferences(CFAllocatorRef allocator,
- CFStringRef prefsID,
- CFStringRef user,
- int keyType)
+SCDynamicStoreKeyCreateUserPreferences(CFAllocatorRef allocator,
+ CFStringRef prefsID,
+ CFStringRef user,
+ SCPreferencesKeyType keyType)
{
return _SCPNotificationKey(allocator, prefsID, TRUE, user, keyType);
}
+++ /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 _SCP_H
-#define _SCP_H
-
-#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 */
/*
- * Copyright(c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright(c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
{
SCPreferencesPrivateRef sessionPrivate = (SCPreferencesPrivateRef)session;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesAddValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" value = %@"), value);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCPreferencesAddValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" value = %@"), value);
+ }
sessionPrivate->accessed = TRUE;
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright(c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright(c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include <unistd.h>
#include <sys/errno.h>
+static ssize_t
+writen(int d, const void *buf, size_t nbytes)
+{
+ size_t left = nbytes;
+ const void *p = buf;
+
+ while (left > 0) {
+ ssize_t n;
+
+ n = write(d, p, left);
+ if (n >= 0) {
+ left -= n;
+ p += n;
+ } else {
+ if (errno != EINTR) {
+ return -1;
+ }
+ }
+ }
+ return nbytes;
+}
+
+
Boolean
SCPreferencesCommitChanges(SCPreferencesRef session)
{
* if necessary, apply changes
*/
if (sessionPrivate->changed) {
- struct stat statBuf;
- int pathLen;
- char *newPath;
int fd;
CFDataRef newPrefs;
+ char * path;
+ int pathLen;
+ struct stat statBuf;
+ char * thePath;
if (stat(sessionPrivate->path, &statBuf) == -1) {
if (errno == ENOENT) {
}
/* create the (new) preferences file */
- pathLen = strlen(sessionPrivate->path) + sizeof("-new");
- newPath = CFAllocatorAllocate(NULL, pathLen, 0);
- snprintf(newPath, pathLen, "%s-new", sessionPrivate->path);
+ path = sessionPrivate->newPath ? sessionPrivate->newPath : sessionPrivate->path;
+ pathLen = strlen(path) + sizeof("-new");
+ thePath = CFAllocatorAllocate(NULL, pathLen, 0);
+ snprintf(thePath, pathLen, "%s-new", path);
/* open the (new) preferences file */
reopen :
- fd = open(newPath, O_WRONLY|O_CREAT, statBuf.st_mode);
+ fd = open(thePath, O_WRONLY|O_CREAT, statBuf.st_mode);
if (fd == -1) {
if ((errno == ENOENT) &&
((sessionPrivate->prefsID == NULL) || !CFStringHasPrefix(sessionPrivate->prefsID, CFSTR("/")))) {
char *ch;
- ch = strrchr(newPath, '/');
+ ch = strrchr(thePath, '/');
if (ch != NULL) {
int status;
*ch = '\0';
- status = mkdir(newPath, 0755);
+ status = mkdir(thePath, 0755);
*ch = '/';
if (status == 0) {
goto reopen;
}
}
SCLog(_sc_verbose, LOG_ERR, CFSTR("SCPCommit open() failed: %s"), strerror(errno));
- CFAllocatorDeallocate(NULL, newPath);
+ CFAllocatorDeallocate(NULL, thePath);
goto error;
}
/* preserve permissions */
(void) fchown(fd, statBuf.st_uid, statBuf.st_gid);
+ (void) fchmod(fd, statBuf.st_mode);
/* write the new preferences */
newPrefs = CFPropertyListCreateXMLData(NULL, sessionPrivate->prefs);
if (!newPrefs) {
_SCErrorSet(kSCStatusFailed);
SCLog(_sc_verbose, LOG_ERR, CFSTR(" CFPropertyListCreateXMLData() failed"));
- CFAllocatorDeallocate(NULL, newPath);
+ CFAllocatorDeallocate(NULL, thePath);
+ (void) close(fd);
+ goto error;
+ }
+ if (writen(fd, (void *)CFDataGetBytePtr(newPrefs), CFDataGetLength(newPrefs)) == -1) {
+ _SCErrorSet(errno);
+ SCLog(_sc_verbose, LOG_ERR, CFSTR("write() failed: %s"), strerror(errno));
+ (void) unlink(thePath);
+ CFAllocatorDeallocate(NULL, thePath);
(void) close(fd);
+ CFRelease(newPrefs);
goto error;
}
- (void) write(fd, CFDataGetBytePtr(newPrefs), CFDataGetLength(newPrefs));
(void) close(fd);
CFRelease(newPrefs);
/* rename new->old */
- if (rename(newPath, sessionPrivate->path) == -1) {
+ if (rename(thePath, path) == -1) {
_SCErrorSet(errno);
SCLog(_sc_verbose, LOG_ERR, CFSTR("rename() failed: %s"), strerror(errno));
- CFAllocatorDeallocate(NULL, newPath);
+ CFAllocatorDeallocate(NULL, thePath);
goto error;
}
- CFAllocatorDeallocate(NULL, newPath);
+ CFAllocatorDeallocate(NULL, thePath);
+
+ if (sessionPrivate->newPath) {
+ /* prefs file saved in "new" directory */
+ (void) unlink(sessionPrivate->path);
+ (void) symlink(sessionPrivate->newPath, sessionPrivate->path);
+ CFAllocatorDeallocate(NULL, sessionPrivate->path);
+ sessionPrivate->path = path;
+ sessionPrivate->newPath = NULL;
+ }
/* update signature */
- if (stat(sessionPrivate->path, &statBuf) == -1) {
+ if (stat(path, &statBuf) == -1) {
_SCErrorSet(errno);
SCLog(_sc_verbose, LOG_ERR, CFSTR("stat() failed: %s"), strerror(errno));
goto error;
/*
- * Copyright(c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright(c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
SCPreferencesPrivateRef sessionPrivate = (SCPreferencesPrivateRef)session;
CFPropertyListRef value;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesGetValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCPreferencesGetValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ }
sessionPrivate->accessed = TRUE;
value = CFDictionaryGetValue(sessionPrivate->prefs, key);
/*
- * Copyright(c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright(c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
CFArrayRef keys;
SCPreferencesPrivateRef sessionPrivate = (SCPreferencesPrivateRef)session;
CFIndex prefsCnt;
- const void **prefsKeys;
+ const void ** prefsKeys;
SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesCopyKeyList:"));
* Copyright(c) 2000-2002 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
Boolean
SCPreferencesLock(SCPreferencesRef session, Boolean wait)
{
+ CFAllocatorRef allocator = CFGetAllocator(session);
CFArrayRef changes;
CFDataRef currentSignature = NULL;
Boolean haveLock = FALSE;
if (sessionPrivate->session == NULL) {
/* open a session */
- sessionPrivate->session = SCDynamicStoreCreate(NULL,
+ sessionPrivate->session = SCDynamicStoreCreate(allocator,
CFSTR("SCPreferencesLock"),
NULL,
NULL);
if (sessionPrivate->sessionKeyLock == NULL) {
/* create the session "lock" key */
- sessionPrivate->sessionKeyLock = _SCPNotificationKey(NULL,
+ sessionPrivate->sessionKeyLock = _SCPNotificationKey(allocator,
sessionPrivate->prefsID,
sessionPrivate->perUser,
sessionPrivate->user,
goto error;
}
- value = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
+ value = CFDateCreate(allocator, CFAbsoluteTimeGetCurrent());
while (TRUE) {
CFArrayRef changedKeys;
SCPreferencesRef newPrefs;
SCPreferencesPrivateRef newPrivate;
- newPrefs = __SCPreferencesCreate(NULL,
+ newPrefs = __SCPreferencesCreate(allocator,
sessionPrivate->name,
sessionPrivate->prefsID,
sessionPrivate->perUser,
/*
- * Copyright(c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright(c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
*/
#include <SystemConfiguration/SystemConfiguration.h>
-#include <SystemConfiguration/SCPrivate.h>
#include <SystemConfiguration/SCValidation.h>
+#include <SystemConfiguration/SCPrivate.h>
#include "SCPreferencesInternal.h"
#include <fcntl.h>
if (sessionPrivate->prefsID) CFRelease(sessionPrivate->prefsID);
if (sessionPrivate->user) CFRelease(sessionPrivate->user);
if (sessionPrivate->path) CFAllocatorDeallocate(NULL, sessionPrivate->path);
+ if (sessionPrivate->newPath) CFAllocatorDeallocate(NULL, sessionPrivate->newPath);
if (sessionPrivate->signature) CFRelease(sessionPrivate->signature);
if (sessionPrivate->session) CFRelease(sessionPrivate->session);
if (sessionPrivate->sessionKeyLock) CFRelease(sessionPrivate->sessionKeyLock);
}
-static CFTypeID __kSCPreferencesTypeID = _kCFRuntimeNotATypeID;
+static CFTypeID __kSCPreferencesTypeID = _kCFRuntimeNotATypeID;
static const CFRuntimeClass __SCPreferencesClass = {
static pthread_once_t initialized = PTHREAD_ONCE_INIT;
-
static void
__SCPreferencesInitialize(void) {
__kSCPreferencesTypeID = _CFRuntimeRegisterClass(&__SCPreferencesClass);
}
-SCPreferencesRef
+static SCPreferencesPrivateRef
__SCPreferencesCreatePrivate(CFAllocatorRef allocator)
{
- SCPreferencesPrivateRef prefs;
- UInt32 size;
+ SCPreferencesPrivateRef prefsPrivate;
+ uint32_t size;
/* initialize runtime */
pthread_once(&initialized, __SCPreferencesInitialize);
/* allocate session */
size = sizeof(SCPreferencesPrivate) - sizeof(CFRuntimeBase);
- prefs = (SCPreferencesPrivateRef)_CFRuntimeCreateInstance(allocator,
+ prefsPrivate = (SCPreferencesPrivateRef)_CFRuntimeCreateInstance(allocator,
__kSCPreferencesTypeID,
size,
NULL);
- if (!prefs) {
+ if (!prefsPrivate) {
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;
+ prefsPrivate->name = NULL;
+ prefsPrivate->prefsID = NULL;
+ prefsPrivate->perUser = FALSE;
+ prefsPrivate->user = NULL;
+ prefsPrivate->path = NULL;
+ prefsPrivate->newPath = NULL; // new prefs path
+ prefsPrivate->signature = NULL;
+ prefsPrivate->session = NULL;
+ prefsPrivate->sessionKeyLock = NULL;
+ prefsPrivate->sessionKeyCommit = NULL;
+ prefsPrivate->sessionKeyApply = NULL;
+ prefsPrivate->prefs = NULL;
+ prefsPrivate->accessed = FALSE;
+ prefsPrivate->changed = FALSE;
+ prefsPrivate->locked = FALSE;
+ prefsPrivate->isRoot = (geteuid() == 0);
+
+ return prefsPrivate;
}
CFStringRef user)
{
int fd = -1;
- SCPreferencesRef prefs;
SCPreferencesPrivateRef prefsPrivate;
int sc_status = kSCStatusOK;
struct stat statBuf;
/*
* allocate and initialize a new session
*/
- prefs = __SCPreferencesCreatePrivate(allocator);
- if (!prefs) {
+ prefsPrivate = __SCPreferencesCreatePrivate(allocator);
+ if (!prefsPrivate) {
return NULL;
}
- prefsPrivate = (SCPreferencesPrivateRef)prefs;
+
+ retry :
/*
* convert prefsID to path
*/
- prefsPrivate->path = __SCPreferencesPath(NULL, prefsID, perUser, user);
+ prefsPrivate->path = __SCPreferencesPath(allocator,
+ prefsID,
+ perUser,
+ user,
+ (prefsPrivate->newPath == NULL));
if (prefsPrivate->path == NULL) {
sc_status = kSCStatusFailed;
goto error;
if (fd == -1) {
switch (errno) {
case ENOENT :
- /* no prefs file, start fresh */
+ /* no prefs file */
+ if (!perUser &&
+ ((prefsID == NULL) || !CFStringHasPrefix(prefsID, CFSTR("/")))) {
+ /* if default preference ID or relative path */
+ if (prefsPrivate->newPath == NULL) {
+ /*
+ * we've looked in the "new" prefs directory
+ * without success. Save the "new" path and
+ * look in the "old" prefs directory.
+ */
+ prefsPrivate->newPath = prefsPrivate->path;
+ goto retry;
+ } else {
+ /*
+ * we've looked in both the "new" and "old"
+ * prefs directories without success. USe
+ * the "new" path.
+ */
+ CFAllocatorDeallocate(NULL, prefsPrivate->path);
+ prefsPrivate->path = prefsPrivate->newPath;
+ prefsPrivate->newPath = NULL;
+ }
+ }
+
+ /* start fresh */
bzero(&statBuf, sizeof(statBuf));
goto create_1;
case EACCES :
/*
* extract property list
*/
- xmlData = CFDataCreateMutable(NULL, statBuf.st_size);
+ xmlData = CFDataCreateMutable(allocator, statBuf.st_size);
CFDataSetLength(xmlData, statBuf.st_size);
if (read(fd, (void *)CFDataGetBytePtr(xmlData), statBuf.st_size) != statBuf.st_size) {
/* corrupt prefs file, start fresh */
/*
* load preferences
*/
- dict = CFPropertyListCreateFromXMLData(NULL,
+ dict = CFPropertyListCreateFromXMLData(allocator,
xmlData,
kCFPropertyListImmutable,
&xmlError);
goto create_2;
}
- prefsPrivate->prefs = CFDictionaryCreateMutableCopy(NULL, 0, dict);
+ prefsPrivate->prefs = CFDictionaryCreateMutableCopy(allocator, 0, dict);
CFRelease(dict);
}
* new file, create empty preferences
*/
SCLog(_sc_verbose, LOG_DEBUG, CFSTR("_SCPOpen(): creating new dictionary."));
- prefsPrivate->prefs = CFDictionaryCreateMutable(NULL,
+ prefsPrivate->prefs = CFDictionaryCreateMutable(allocator,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
/*
* all OK
*/
- prefsPrivate->name = CFRetain(name);
- if (prefsID) {
- prefsPrivate->prefsID = CFRetain(prefsID);
- }
+ prefsPrivate->name = CFStringCreateCopy(allocator, name);
+ if (prefsID) prefsPrivate->prefsID = CFStringCreateCopy(allocator, prefsID);
prefsPrivate->perUser = perUser;
- if (user) {
- prefsPrivate->user = CFRetain(user);
- }
- return prefs;
+ if (user) prefsPrivate->user = CFStringCreateCopy(allocator, user);
+ return (SCPreferencesRef)prefsPrivate;
error :
- if (fd != -1) {
- (void) close(fd);
- }
- CFRelease(prefs);
+ if (fd != -1) (void) close(fd);
+ CFRelease(prefsPrivate);
_SCErrorSet(sc_status);
return NULL;
}
CFStringRef name,
CFStringRef prefsID)
{
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesCreate:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" name = %@"), name);
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" prefsID = %@"), prefsID);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCPreferencesCreate:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" name = %@"), name);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" prefsID = %@"), prefsID);
+ }
return __SCPreferencesCreate(allocator, name, prefsID, FALSE, NULL);
}
CFStringRef prefsID,
CFStringRef user)
{
- 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);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCUserPreferencesCreate:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" name = %@"), name);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" prefsID = %@"), prefsID);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" user = %@"), user);
+ }
return __SCPreferencesCreate(allocator, name, prefsID, TRUE, user);
}
CFTypeID
SCPreferencesGetTypeID(void) {
+ pthread_once(&initialized, __SCPreferencesInitialize); /* initialize runtime */
return __kSCPreferencesTypeID;
}
/*
- * Copyright(c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright(c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/* remove empty path components */
nElements = CFArrayGetCount(elements);
- for (i=nElements; i>0; i--) {
+ for (i = nElements; i > 0; i--) {
CFStringRef pathElement;
pathElement = CFArrayGetValueAtIndex(elements, i-1);
restart :
nElements = CFArrayGetCount(elements);
- for (i=0; i<nElements; i++) {
+ for (i = 0; i < nElements; i++) {
element = CFArrayGetValueAtIndex(elements, i);
if (i == 0) {
sessionPrivate->accessed = TRUE;
nElements = CFArrayGetCount(elements);
nodes = CFArrayCreateMutable(NULL, nElements-1, &kCFTypeArrayCallBacks);
- for (i=0; i<nElements-1; i++) {
+ for (i = 0; i < nElements - 1; i++) {
element = CFArrayGetValueAtIndex(elements, i);
if (i == 0) {
sessionPrivate->accessed = TRUE;
if (entity) {
newEntity = CFRetain(entity);
}
- for (i=nElements-1; i>=0; i--) {
+ for (i = nElements - 1; i >= 0; i--) {
element = CFArrayGetValueAtIndex(elements, i);
if (i == 0) {
if (newEntity) {
CFUUIDRef uuid;
CFDictionaryRef entity;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesPathCreateUniqueChild:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" prefix = %@"), prefix);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCPreferencesPathCreateUniqueChild:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" prefix = %@"), prefix);
+ }
if (getPath(session, prefix, &entity)) {
// if prefix path exists
CFDictionaryRef entity;
CFStringRef entityLink;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesPathGetValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" path = %@"), path);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCPreferencesPathGetValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" path = %@"), path);
+ }
if (!getPath(session, path, &entity)) {
return NULL;
CFDictionaryRef entity;
CFStringRef entityLink;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesPathGetLink:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" path = %@"), path);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCPreferencesPathGetLink:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" path = %@"), path);
+ }
if (!getPath(session, path, &entity)) {
return NULL;
{
Boolean ok;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesPathSetValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" path = %@"), path);
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" value = %@"), value);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCPreferencesPathSetValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" path = %@"), path);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" value = %@"), value);
+ }
if (!value) {
_SCErrorSet(kSCStatusInvalidArgument);
CFDictionaryRef entity;
Boolean ok;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesPathSetLink:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" path = %@"), path);
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" link = %@"), link);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCPreferencesPathSetLink:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" path = %@"), path);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" link = %@"), link);
+ }
if (!link) {
_SCErrorSet(kSCStatusInvalidArgument);
Boolean ok = FALSE;
CFDictionaryRef value;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesPathRemoveValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" path = %@"), path);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCPreferencesPathRemoveValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" path = %@"), path);
+ }
if (!getPath(session, path, &value)) {
// if no such path
+++ /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 _SCPPATH_H
-#define _SCPPATH_H
-
-#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 */
/*
- * Copyright(c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright(c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
{
SCPreferencesPrivateRef sessionPrivate = (SCPreferencesPrivateRef)session;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesRemoveValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCPreferencesRemoveValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ }
sessionPrivate->accessed = TRUE;
/*
- * Copyright(c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright(c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
{
SCPreferencesPrivateRef sessionPrivate = (SCPreferencesPrivateRef)session;
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR("SCPreferencesSetValue:"));
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
- SCLog(_sc_verbose, LOG_DEBUG, CFSTR(" value = %@"), value);
+ if (_sc_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("SCPreferencesSetValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" value = %@"), value);
+ }
CFDictionarySetValue(sessionPrivate->prefs, key, value);
sessionPrivate->accessed = TRUE;
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
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.
*/
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 (
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.
+
+ Note: This routine commits changes to persistent storage.
+ Call SCPreferencesApplyChanges() to apply the changes
+ to the running system.
@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 (
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include <SystemConfiguration/SCDynamicStore.h>
-#define PREFS_DEFAULT_DIR CFSTR("/var/db/SystemConfiguration")
-#define PREFS_DEFAULT_CONFIG CFSTR("preferences.xml")
+#define PREFS_DEFAULT_DIR CFSTR("/Library/Preferences/SystemConfiguration")
+#define PREFS_DEFAULT_CONFIG CFSTR("preferences.plist")
-#define PREFS_DEFAULT_USER_DIR CFSTR("Library/Preferences")
+#define PREFS_DEFAULT_DIR_OLD CFSTR("/var/db/SystemConfiguration")
+#define PREFS_DEFAULT_CONFIG_OLD CFSTR("preferences.xml")
+
+#define PREFS_DEFAULT_USER_DIR CFSTR("Library/Preferences")
/* Define the per-preference-handle structure */
/* configuration file path */
char *path;
+ char *newPath;
/* configuration file signature */
CFDataRef signature;
__SCPreferencesPath (CFAllocatorRef allocator,
CFStringRef prefsID,
Boolean perUser,
- CFStringRef user);
+ CFStringRef user,
+ Boolean useNewPrefs);
CFStringRef
_SCPNotificationKey (CFAllocatorRef allocator,
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
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.
*/
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
@constant kSCPreferencesKeyApply Key used when new preferences are
to be applied to the active system configuration.
*/
-typedef enum {
+enum {
kSCPreferencesKeyLock = 1,
kSCPreferencesKeyCommit = 2,
- kSCPreferencesKeyApply = 3,
-} SCPreferencesKeyType;
-
+ kSCPreferencesKeyApply = 3
+};
+typedef int32_t SCPreferencesKeyType;
__BEGIN_DECLS
@result A notification string for the specified preference identifier.
*/
CFStringRef
-SCDynamicStoreKeyCreatePreferences (CFAllocatorRef allocator,
- CFStringRef prefsID,
- int keyType);
+SCDynamicStoreKeyCreatePreferences (
+ CFAllocatorRef allocator,
+ CFStringRef prefsID,
+ SCPreferencesKeyType keyType
+ );
SCPreferencesRef
-SCUserPreferencesCreate (CFAllocatorRef allocator,
- CFStringRef name,
- CFStringRef prefsID,
- CFStringRef user);
+SCUserPreferencesCreate (
+ CFAllocatorRef allocator,
+ CFStringRef name,
+ CFStringRef prefsID,
+ CFStringRef user
+ );
CFStringRef
-SCDynamicStoreKeyCreateUserPreferences (CFAllocatorRef allocator,
- CFStringRef prefsID,
- CFStringRef user,
- int keyType);
+SCDynamicStoreKeyCreateUserPreferences (
+ CFAllocatorRef allocator,
+ CFStringRef prefsID,
+ CFStringRef user,
+ SCPreferencesKeyType keyType
+ );
__END_DECLS
* Copyright (c) 2000-2002 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SCDynamicStorePrivate.h>
+#include <SystemConfiguration/SCDynamicStoreCopySpecificPrivate.h>
#include <SystemConfiguration/SCDynamicStoreSetSpecificPrivate.h>
#include <SystemConfiguration/SCPreferencesPrivate.h>
@function _SCUnserialize
@discussion Unserialize a stream of bytes passed from/to configd
into a CFPropertyList object.
- @param obj A pointer to memory that will be filled with the CFPropertyList
- associated with the stream of bytes.
+ @param obj A pointer to memory that will be filled with the CFPropertyList
+ associated with the stream of bytes.
+ @param xml CFDataRef with the serialized data
@param data A pointer to the serialized data
@param dataLen A pointer to the length of the serialized data
+
+ Specify either "xml" or "data/dataLen".
*/
Boolean _SCUnserialize (CFPropertyListRef *obj,
+ CFDataRef xml,
+ void *dataRef,
+ CFIndex dataLen);
+
+/*
+ @function _SCSerializeString
+ @discussion Serialize a CFString object for passing
+ to/from configd.
+ @param str CFString key to serialize
+ @param data A pointer to a CFDataRef, NULL if storage should be
+ vm_allocated.
+ @param data A pointer to the newly allocated/serialized data
+ @param dataLen A pointer to the length in bytes of the newly
+ allocated/serialized data
+ */
+Boolean _SCSerializeString (CFStringRef str,
+ CFDataRef *data,
+ void **dataRef,
+ CFIndex *dataLen);
+
+/*
+ @function _SCUnserializeString
+ @discussion Unserialize a stream of bytes passed from/to configd
+ into a CFString object.
+ @param str A pointer to memory that will be filled with the CFPropertyList
+ associated with the stream of bytes.
+ @param utf8 CFDataRef with the serialized data
+ @param data A pointer to the serialized data
+ @param dataLen A pointer to the length of the serialized data
+
+ Specify either "utf8" or "data/dataLen".
+ */
+Boolean _SCUnserializeString (CFStringRef *str,
+ CFDataRef utf8,
void *dataRef,
CFIndex dataLen);
+/*
+ @function _SCSerializeData
+ @discussion Serialize a CFData object for passing
+ to/from configd.
+ @param data CFData key to serialize
+ @param data A pointer to the newly allocated/serialized data
+ @param dataLen A pointer to the length in bytes of the newly
+ allocated/serialized data
+ */
+Boolean _SCSerializeData (CFDataRef data,
+ void **dataRef,
+ CFIndex *dataLen);
+
+/*
+ @function _SCUnserializeData
+ @discussion Unserialize a stream of bytes passed from/to configd
+ into a CFData object.
+ @param data A pointer to memory that will be filled with the CFPropertyList
+ associated with the stream of bytes.
+ @param data A pointer to the serialized data
+ @param dataLen A pointer to the length of the serialized data
+ */
+Boolean _SCUnserializeData (CFDataRef *data,
+ void *dataRef,
+ CFIndex dataLen);
+
+/*
+ @function _SCSerializeMultiple
+ @discussion Convert a CFDictionary containing a set of CFPropertlyList
+ values into a CFDictionary containing a set of serialized CFData
+ values.
+ @param dict The CFDictionary with CFPropertyList values.
+ @result The serialized CFDictionary with CFData values
+ */
+CFDictionaryRef _SCSerializeMultiple (CFDictionaryRef dict);
+
+/*
+ @function _SCUnserializeMultiple
+ @discussion Convert a CFDictionary containing a set of CFData
+ values into a CFDictionary containing a set of serialized
+ CFPropertlyList values.
+ @param dict The CFDictionary with CFData values.
+ @result The serialized CFDictionary with CFPropertyList values
+ */
+CFDictionaryRef _SCUnserializeMultiple (CFDictionaryRef dict);
+
+/*
+ @function _SC_cfstring_to_cstring
+ @discussion Extracts a C-string from a CFString.
+ @param cfstr The CFString to extract the data from.
+ @param buf A user provided buffer of the specefied length. If NULL,
+ a new buffer will be allocated to contain the C-string. It
+ is the responsiblity of the caller to free an allocated
+ buffer.
+ @param bufLen The size of the user provided buffer.
+ @param encoding The string encoding
+ @result If the extraction (conversion) is successful then a pointer
+ to the user provided (or allocated) buffer is returned, NULL
+ if the string could not be extracted.
+ */
+char * _SC_cfstring_to_cstring (CFStringRef cfstr,
+ char *buf,
+ int bufLen,
+ CFStringEncoding encoding);
+
/*
@function SCLog
@discussion Conditionally issue a log 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
+ @result The message will be written to the specified stream
stream.
*/
void SCPrint (Boolean condition,
CFStringRef formatString,
...);
+/*
+ @function SCTrace
+ @discussion Conditionally issue a debug message with a time stamp.
+ @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 message will be written to the specified stream
+ stream.
+ */
+void SCTrace (Boolean condition,
+ FILE *stream,
+ CFStringRef formatString,
+ ...);
+
__END_DECLS
#endif /* _SCPRIVATE_H */
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
if (!store) {
store = SCDynamicStoreCreate(NULL,
- CFSTR("SCDynamicStoreCopyConsoleUser"),
+ CFSTR("SCDynamicStoreCopyProxies"),
NULL,
NULL);
if (!store) {
* Copyright (c) 2001-2002 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
* SCNetwork status codes
*/
- kSCStatusReachabilityUnknown = 4001, /* Network reachability cannot be determined */
+ kSCStatusReachabilityUnknown = 4001 /* Network reachability cannot be determined */
};
/* store and preference scheme definitions */
#include <SystemConfiguration/SCSchemaDefinitions.h>
-/* "network reachability" APIs */
+/* network reachability / connection APIs */
#include <SystemConfiguration/SCNetwork.h>
+#include <SystemConfiguration/SCNetworkReachability.h>
+#include <SystemConfiguration/SCNetworkConnection.h>
__BEGIN_DECLS
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
import "config_types.h";
/*
- * serialized XML data (client->server)
+ * serialized XML or UTF8 data (client->server)
*/
type xmlData = ^ array [] of MACH_MSG_TYPE_BYTE
ctype : xmlData_t;
/*
- * serialized XML data (server->client)
+ * serialized XML or UTF8 data (server->client)
*/
type xmlDataOut = ^ array [] of MACH_MSG_TYPE_BYTE
ctype : xmlDataOut_t;
routine notifycancel ( server : mach_port_t;
out status : int);
- skip; /* reserved for future use */
+routine notifyset ( server : mach_port_t;
+ keys : xmlData;
+ patterns : xmlData;
+ out status : int);
+
skip; /* reserved for future use */
skip; /* reserved for future use */
skip; /* reserved for future use */
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Mach server port name
*/
-#define SCD_SERVER "System Configuration Server"
+#define SCD_SERVER "com.apple.SystemConfiguration.configd"
/*
* Input arguments: serialized key's, list delimiters, ...
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <mach-o/dyld.h>
-#include <CoreFoundation/CoreFoundation.h>
#include "dy_framework.h"
}
return dyfunc ? dyfunc(name) : NULL;
}
+
+static void *
+__loadSecurity(void) {
+ static const void *image = NULL;
+ if (NULL == image) {
+ const char *framework = "/System/Library/Frameworks/Security.framework/Security";
+ struct stat statbuf;
+ const char *suffix = getenv("DYLD_IMAGE_SUFFIX");
+ char path[MAXPATHLEN];
+
+ strcpy(path, framework);
+ if (suffix) strcat(path, suffix);
+ if (0 <= stat(path, &statbuf)) {
+ image = NSAddImage(path, NSADDIMAGE_OPTION_NONE);
+ } else {
+ image = NSAddImage(framework, NSADDIMAGE_OPTION_NONE);
+ }
+ }
+ return (void *)image;
+}
+
+
+__private_extern__ OSStatus
+_SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass *itemClass, SecKeychainAttributeList *attrList, UInt32 *length, void **outData)
+{
+ static OSStatus (*dyfunc)(SecKeychainItemRef, SecItemClass *, SecKeychainAttributeList *, UInt32 *, void **) = NULL;
+ if (!dyfunc) {
+ void *image = __loadSecurity();
+ if (image) dyfunc = NSAddressOfSymbol(NSLookupSymbolInImage(image, "_SecKeychainItemCopyContent", NSLOOKUPSYMBOLINIMAGE_OPTION_BIND));
+ }
+ return dyfunc ? dyfunc(itemRef, itemClass, attrList, length, outData) : -1;
+}
+
+__private_extern__ OSStatus
+_SecKeychainSearchCopyNext(SecKeychainSearchRef searchRef, SecKeychainItemRef *itemRef)
+{
+ static OSStatus (*dyfunc)(SecKeychainSearchRef, SecKeychainItemRef *) = NULL;
+ if (!dyfunc) {
+ void *image = __loadSecurity();
+ if (image) dyfunc = NSAddressOfSymbol(NSLookupSymbolInImage(image, "_SecKeychainSearchCopyNext", NSLOOKUPSYMBOLINIMAGE_OPTION_BIND));
+ }
+ return dyfunc ? dyfunc(searchRef, itemRef) : -1;
+}
+
+__private_extern__ OSStatus
+_SecKeychainSearchCreateFromAttributes(CFTypeRef keychainOrArray, SecItemClass itemClass, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef)
+{
+ static OSStatus (*dyfunc)(CFTypeRef, SecItemClass, const SecKeychainAttributeList *, SecKeychainSearchRef *) = NULL;
+ if (!dyfunc) {
+ void *image = __loadSecurity();
+ if (image) dyfunc = NSAddressOfSymbol(NSLookupSymbolInImage(image, "_SecKeychainSearchCreateFromAttributes", NSLOOKUPSYMBOLINIMAGE_OPTION_BIND));
+ }
+ return dyfunc ? dyfunc(keychainOrArray, itemClass, attrList, searchRef) : -1;
+}
* Copyright (c) 2002 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include <mach/mach.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
+#include <Security/Security.h>
__BEGIN_DECLS
);
#define IOServiceMatching _IOServiceMatching
+OSStatus
+_SecKeychainItemCopyContent (
+ SecKeychainItemRef itemRef,
+ SecItemClass *itemClass,
+ SecKeychainAttributeList *attrList,
+ UInt32 *length,
+ void **outData
+ );
+#define SecKeychainItemCopyContent _SecKeychainItemCopyContent
+
+OSStatus
+_SecKeychainSearchCopyNext (
+ SecKeychainSearchRef searchRef,
+ SecKeychainItemRef *itemRef
+ );
+#define SecKeychainSearchCopyNext _SecKeychainSearchCopyNext
+
+OSStatus
+_SecKeychainSearchCreateFromAttributes (
+ CFTypeRef keychainOrArray,
+ SecItemClass itemClass,
+ const SecKeychainAttributeList *attrList,
+ SecKeychainSearchRef *searchRef
+ );
+#define SecKeychainSearchCreateFromAttributes _SecKeychainSearchCreateFromAttributes
+
__END_DECLS
#endif /* _DY_FRAMEWORK_H */
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Modification History
*
- * June 1, 2001 Allan Nathanson <ajn@apple.com>
+ * 16 July 2003 Allan Nathanson (ajn@apple.com)
+ * - changes to facilitate cross-compilation to earlier releases
+ *
+ * 5 May 2003 Allan Nathanson (ajn@apple.com)
+ * - switch back to "extern const CFStringRef ..."
+ *
+ * 1 June 2001 Allan Nathanson <ajn@apple.com>
* - public API conversion
*
* 27 Apr 2001 Allan Nathanson (ajn@apple.com)
char copyright_string[] =
"/*\n"
-" * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.\n"
+" * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.\n"
" *\n"
-" * @APPLE_LICENSE_HEADER_START@\n"
-" * \n"
-" * The contents of this file constitute Original Code as defined in and\n"
-" * are subject to the Apple Public Source License Version 1.1 (the\n"
-" * \"License\"). You may not use this file except in compliance with the\n"
-" * License. Please obtain a copy of the License at\n"
-" * http://www.apple.com/publicsource and read it before using this file.\n"
-" * \n"
-" * This Original Code and all software distributed under the License are\n"
-" * distributed on an \"AS IS\" basis, WITHOUT WARRANTY OF ANY KIND, EITHER\n"
-" * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,\n"
-" * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,\n"
-" * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the\n"
-" * License for the specific language governing rights and limitations\n"
-" * under the License.\n"
-" * \n"
-" * @APPLE_LICENSE_HEADER_END@\n"
+" * @APPLE_LICENSE_HEADER_START@
+" *
+" * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+" *
+" * This file contains Original Code and/or Modifications of Original Code
+" * as defined in and that are subject to the Apple Public Source License
+" * Version 2.0 (the 'License'). You may not use this file except in
+" * compliance with the License. Please obtain a copy of the License at
+" * http://www.opensource.apple.com/apsl/ and read it before using this
+" * file.
+" *
+" * The Original Code and all software distributed under the License are
+" * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+" * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+" * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+" * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+" * Please see the License for the specific language governing rights and
+" * limitations under the License.
+" *
+" * @APPLE_LICENSE_HEADER_END@
" */\n";
END
} controlType;
+#define SC_SCHEMA_DECLARATION "SC_SCHEMA_DECLARATION"
+
#define KEY_PREFIX "kSC"
#define COMP "Comp"
#define CFNUMBER_BOOL "CFNumber (0 or 1)"
#define CFSTRING "CFString"
+#define ACSPENABLED "ACSPEnabled" // Apple Client Server Protocol
#define ACTIVE "Active"
#define ADDRESSES "Addresses"
+#define AFTER "After"
#define AIRPORT "AirPort"
#define ALERT "Alert"
#define ALLOWNETCREATION "AllowNetCreation"
#define APPLETALK "AppleTalk"
#define AUTH "Auth"
#define AUTOMATIC "Automatic"
+#define BEFORE "Before"
#define BINDINGMETHODS "BindingMethods"
#define BOOTP "BOOTP"
#define BROADCAST "Broadcast"
#define DISCONNECTONIDLETIMER "DisconnectOnIdleTimer"
#define DISCONNECTONLOGOUT "DisconnectOnLogout"
#define DISCONNECTONSLEEP "DisconnectOnSleep"
+#define DISCONNECTTIME "DisconnectTime"
#define DISPLAYTERMINALWINDOW "DisplayTerminalWindow"
#define DNS "DNS"
#define DOMAIN "Domain"
#define DOMAINNAME "DomainName"
#define DOMAINSEPARATOR "DomainSeparator"
+#define EAP "EAP"
#define ECHOENABLED "EchoEnabled"
#define ECHOFAILURE "EchoFailure"
#define ECHOINTERVAL "EchoInterval"
#define ETHERNET "Ethernet"
#define EXCEPTIONSLIST "ExceptionsList"
#define FILE "File"
+#define FIREWIRE "FireWire"
+#define FLAGS "Flags"
#define FTPENABLE "FTPEnable"
#define FTPPASSIVE "FTPPassive"
#define FTPPORT "FTPPort"
#define INTERFACE "Interface"
#define INTERFACENAME "InterfaceName"
#define INTERFACES "Interfaces"
+#define IP "IP"
#define IPCP "IPCP"
#define IPV4 "IPv4"
#define IPV6 "IPv6"
+#define IPSEC "IPSec"
#define JOINMODE "JoinMode"
+#define KEYCHAIN "Keychain"
+#define L2TP "L2TP"
#define LASTCAUSE "LastCause"
#define LASTUPDATED "LastUpdated"
#define LCP "LCP"
#define OPTIONS "Options"
#define MODEM "Modem"
#define MRU "MRU"
+#define MSCHAP1 "MSCHAP1"
+#define MSCHAP2 "MSCHAP2"
#define MTU "MTU"
#define NAME "Name"
#define NETINFO "NetInfo"
#define PPTP "PPTP"
#define PREFERRED "Preferred"
#define PREFERREDNETWORK "PreferredNetwork"
+#define PREFIXLENGTH "PrefixLength"
#define PREFS "Prefs"
#define PRIMARYINTERFACE "PrimaryInterface"
#define PRIMARYSERVICE "PrimaryService"
+#define PROMPT "Prompt"
#define PROTOCOL "Protocol"
#define PROXIES "Proxies"
#define PULSEDIAL "PulseDial"
#define REDIALCOUNT "RedialCount"
#define REDIALENABLED "RedialEnabled"
#define REDIALINTERVAL "RedialInterval"
+#define RELAY "Relay"
#define REMINDER "Reminder"
#define REMINDERTIME "ReminderTime"
#define REMOTEADDRESS "RemoteAddress"
+#define RETRYCONNECTTIME "RetryConnectTime"
#define ROOTSEPARATOR "RootSeparator"
#define ROUTER "Router"
+#define ROUTERADVERTISEMENT "RouterAdvertisement"
#define RTSPENABLE "RTSPEnable"
#define RTSPPORT "RTSPPort"
#define RTSPPROXY "RTSPProxy"
#define SESSIONTIMER "SessionTimer"
#define SETS "Sets"
#define SETUP "Setup"
+#define SHAREDSECRET "SharedSecret"
#define SOCKSENABLE "SOCKSEnable"
#define SOCKSPORT "SOCKSPort"
#define SOCKSPROXY "SOCKSProxy"
#define SPEED "Speed"
#define STATE "State"
#define STATUS "Status"
+#define STF "6to4"
#define STRONGEST "Strongest"
#define SUBNETMASKS "SubnetMasks"
#define SUBTYPE "SubType"
#define SYSTEM "System"
#define TERMINALSCRIPT "TerminalScript"
#define TRANSMITACCM "TransmitACCM"
+#define TRANSPORT "Transport"
#define TYPE "Type"
#define UID "UID"
#define USERDEFINEDNAME "UserDefinedName"
struct {
int control;
- unsigned char * prefix;
- unsigned char * key;
- unsigned char * value;
- unsigned char * type;
+ const char * prefix;
+ const char * key;
+ const char * value;
+ const char * type;
} names[] = {
{ COMMENT, "/*\n * Reserved Keys\n */", NULL, NULL },
{ REGULAR, RESV, LINK, "__LINK__", CFSTRING },
{ DEFINE , NETENT, DHCP, NULL, CFDICTIONARY },
{ REGULAR, NETENT, DNS, NULL, CFDICTIONARY },
{ REGULAR, NETENT, ETHERNET, NULL, CFDICTIONARY },
+ { DEFINE , NETENT, FIREWIRE, NULL, CFDICTIONARY },
{ REGULAR, NETENT, INTERFACE, NULL, CFDICTIONARY },
{ REGULAR, NETENT, IPV4, NULL, CFDICTIONARY },
{ REGULAR, NETENT, IPV6, NULL, CFDICTIONARY },
+ { DEFINE , NETENT, L2TP, 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 },
+ { DEFINE , NETENT, PPPSERIAL, NULL, CFDICTIONARY },
+ { DEFINE , NETENT, PPTP, NULL, CFDICTIONARY },
{ REGULAR, NETENT, PROXIES, NULL, CFDICTIONARY },
+ { DEFINE , NETENT, STF, NULL, CFDICTIONARY },
{ COMMENT, "", NULL, NULL, NULL },
{ COMMENT, "/*\n * " KEY_PREFIX COMP NETWORK " Properties\n */", NULL },
{ DEFINE , NETPROP AIRPORT, SAVEPASSWORDS, NULL, CFNUMBER_BOOL },
{ COMMENT, "", NULL, NULL, NULL },
{ COMMENT, "/* " KEY_PREFIX NETPROP AIRPORT JOINMODE " values */", NULL, NULL, NULL },
+ { DEFINE , NETVAL AIRPORT JOINMODE, AUTOMATIC, NULL, NULL },
{ DEFINE , NETVAL AIRPORT JOINMODE, PREFERRED, NULL, NULL },
{ DEFINE , NETVAL AIRPORT JOINMODE, RECENT, NULL, NULL },
{ DEFINE , NETVAL AIRPORT JOINMODE, STRONGEST, NULL, NULL },
{ COMMENT, "", NULL, NULL, NULL },
+ { COMMENT, "/* " KEY_PREFIX NETPROP AIRPORT PASSWORD ENCRYPTION " values */", NULL, NULL, NULL },
+ { DEFINE , NETVAL AIRPORT AUTH PASSWORD ENCRYPTION, KEYCHAIN, NULL, NULL },
+ { COMMENT, "", NULL, NULL, NULL },
{ COMMENT, "/*\n * " KEY_PREFIX NETENT APPLETALK " Entity Keys\n */", NULL, NULL, NULL },
{ REGULAR, NETPROP APPLETALK, COMPUTERNAME, NULL, CFSTRING },
{ DEFINE , NETPROP ETHERNET, MTU, NULL, CFNUMBER },
{ COMMENT, "", NULL, NULL, NULL },
+ { COMMENT, "/*\n * " KEY_PREFIX NETENT FIREWIRE " (Hardware) Entity Keys\n */", NULL, NULL, NULL },
+ { COMMENT, "/* RESERVED FOR FUTURE USE */", NULL, NULL, NULL },
+ { COMMENT, "", NULL, NULL, NULL },
+
{ COMMENT, "/*\n * " KEY_PREFIX NETENT INTERFACE " Entity Keys\n */", NULL },
{ REGULAR, NETPROP INTERFACE, DEVICENAME, NULL, CFSTRING },
{ REGULAR, NETPROP INTERFACE, HARDWARE, NULL, CFSTRING },
{ COMMENT, "", NULL, NULL, NULL },
{ COMMENT, "/* " KEY_PREFIX NETPROP INTERFACE TYPE " values */", NULL, NULL, NULL },
{ REGULAR, NETVAL INTERFACE TYPE, ETHERNET, NULL, NULL },
+ { DEFINE , NETVAL INTERFACE TYPE, FIREWIRE, NULL, NULL },
{ REGULAR, NETVAL INTERFACE TYPE, PPP, NULL, NULL },
+ { DEFINE , NETVAL INTERFACE TYPE, STF, NULL, NULL },
{ COMMENT, "", NULL, NULL, NULL },
{ COMMENT, "/* " KEY_PREFIX NETPROP SERVICE SUBTYPE " values (for " PPP ") */", NULL, NULL, NULL },
{ REGULAR, NETVAL INTERFACE SUBTYPE, PPPOE, NULL, NULL },
{ REGULAR, NETVAL INTERFACE SUBTYPE, PPPSERIAL, NULL, NULL },
{ DEFINE , NETVAL INTERFACE SUBTYPE, PPTP, NULL, NULL },
+ { DEFINE , NETVAL INTERFACE SUBTYPE, L2TP, NULL, NULL },
{ COMMENT, "", NULL, NULL, NULL },
{ COMMENT, "/*\n * " KEY_PREFIX NETENT IPV4 " 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 },
+ { DEFINE , NETPROP IPV6, DESTADDRESSES, NULL, CFARRAY_CFSTRING },
+ { DEFINE , NETPROP IPV6, FLAGS, NULL, CFNUMBER },
+ { DEFINE , NETPROP IPV6, PREFIXLENGTH, NULL, CFARRAY_CFNUMBER },
+ { DEFINE , NETPROP IPV6, ROUTER, NULL, CFSTRING },
+ { COMMENT, "", NULL, NULL, NULL },
+ { COMMENT, "/* " KEY_PREFIX NETPROP IPV6 CONFIGMETHOD " values */", NULL, NULL, NULL },
+ { DEFINE , NETVAL IPV6 CONFIGMETHOD, AUTOMATIC, NULL, NULL },
+ { DEFINE , NETVAL IPV6 CONFIGMETHOD, MANUAL, NULL, NULL },
+ { DEFINE , NETVAL IPV6 CONFIGMETHOD, ROUTERADVERTISEMENT, NULL, NULL },
+ { DEFINE , NETVAL IPV6 CONFIGMETHOD, STF, NULL, NULL },
+ { COMMENT, "", NULL, NULL, NULL },
+
+ { COMMENT, "/*\n * " KEY_PREFIX NETENT STF " Entity Keys\n */", NULL, NULL, NULL },
+ { DEFINE , NETPROP STF, RELAY, NULL, CFSTRING },
{ COMMENT, "", NULL, NULL, NULL },
{ COMMENT, "/*\n * " KEY_PREFIX NETENT LINK " Entity Keys\n */", NULL, NULL, NULL },
{ COMMENT, "", NULL, NULL, NULL },
{ COMMENT, "/*\n * " KEY_PREFIX NETENT PPP " Entity Keys\n */", NULL, NULL, NULL },
+ { DEFINE , NETPROP PPP, ACSPENABLED, NULL, CFNUMBER_BOOL },
{ DEFINE , NETPROP PPP, CONNECTTIME, NULL, CFNUMBER },
{ DEFINE , NETPROP PPP, DEVICE LASTCAUSE, NULL, CFNUMBER },
{ REGULAR, NETPROP PPP, DIALONDEMAND, NULL, CFNUMBER_BOOL },
{ REGULAR, NETPROP PPP, DISCONNECTONIDLETIMER, NULL, CFNUMBER },
{ REGULAR, NETPROP PPP, DISCONNECTONLOGOUT, NULL, CFNUMBER_BOOL },
{ DEFINE , NETPROP PPP, DISCONNECTONSLEEP, NULL, CFNUMBER_BOOL },
+ { DEFINE , NETPROP PPP, DISCONNECTTIME, NULL, CFNUMBER },
{ REGULAR, NETPROP PPP, IDLEREMINDERTIMER, NULL, CFNUMBER },
{ REGULAR, NETPROP PPP, IDLEREMINDER, NULL, CFNUMBER_BOOL },
{ DEFINE , NETPROP PPP, LASTCAUSE, NULL, CFNUMBER },
{ REGULAR, NETPROP PPP, LOGFILE, NULL, CFSTRING },
{ DEFINE , NETPROP PPP, PLUGINS, NULL, CFARRAY_CFSTRING },
+ { DEFINE , NETPROP PPP, RETRYCONNECTTIME, NULL, CFNUMBER },
{ DEFINE , NETPROP PPP, SESSIONTIMER, NULL, CFNUMBER },
- { DEFINE , NETPROP PPP, STATUS, NULL, CFSTRING },
+ { DEFINE , NETPROP PPP, STATUS, NULL, CFNUMBER },
{ DEFINE , NETPROP PPP, USE SESSIONTIMER, NULL, CFNUMBER_BOOL },
{ REGULAR, NETPROP PPP, VERBOSELOGGING, NULL, CFNUMBER_BOOL },
{ COMMENT, "", NULL, NULL, NULL },
{ COMMENT, "/* " AUTH ": */", NULL, NULL, NULL },
+ { DEFINE , NETPROP PPP, AUTH EAP PLUGINS, NULL, CFARRAY_CFSTRING },
{ REGULAR, NETPROP PPP, AUTH NAME, NULL, CFSTRING },
{ REGULAR, NETPROP PPP, AUTH PASSWORD, NULL, CFSTRING },
{ REGULAR, NETPROP PPP, AUTH PASSWORD ENCRYPTION, NULL, CFSTRING },
+ { DEFINE , NETPROP PPP, AUTH PROMPT, NULL, CFSTRING },
{ REGULAR, NETPROP PPP, AUTH PROTOCOL, NULL, CFARRAY_CFSTRING },
{ COMMENT, "", NULL, NULL, NULL },
+ { COMMENT, "/* " KEY_PREFIX NETPROP PPP AUTH PASSWORD ENCRYPTION " values */", NULL, NULL, NULL },
+ { DEFINE , NETVAL PPP AUTH PASSWORD ENCRYPTION, KEYCHAIN, NULL, NULL },
+ { COMMENT, "", NULL, NULL, NULL },
+ { COMMENT, "/* " KEY_PREFIX NETPROP PPP AUTH PROMPT " values */", NULL, NULL, NULL },
+ { DEFINE , NETVAL PPP AUTH PROMPT, BEFORE, NULL, CFSTRING },
+ { DEFINE , NETVAL PPP AUTH PROMPT, AFTER, NULL, CFSTRING },
+ { COMMENT, "", NULL, NULL, NULL },
{ COMMENT, "/* " KEY_PREFIX NETPROP PPP AUTH PROTOCOL " values */", NULL, NULL, NULL },
{ REGULAR, NETVAL PPP AUTH PROTOCOL, CHAP, NULL, CFSTRING },
+ { DEFINE , NETVAL PPP AUTH PROTOCOL, EAP, NULL, CFSTRING },
+ { DEFINE , NETVAL PPP AUTH PROTOCOL, MSCHAP1, NULL, CFSTRING },
+ { DEFINE , NETVAL PPP AUTH PROTOCOL, MSCHAP2, NULL, CFSTRING },
{ REGULAR, NETVAL PPP AUTH PROTOCOL, PAP, NULL, CFSTRING },
{ COMMENT, "\n/* " COMM ": */", NULL, NULL, NULL },
{ COMMENT, "/* RESERVED FOR FUTURE USE */", NULL, NULL, NULL },
{ COMMENT, "", NULL, NULL, NULL },
+ { COMMENT, "/*\n * " KEY_PREFIX NETENT PPTP " Entity Keys\n */", NULL, NULL, NULL },
+ { COMMENT, "/* RESERVED FOR FUTURE USE */", NULL, NULL, NULL },
+ { COMMENT, "", NULL, NULL, NULL },
+
+ { COMMENT, "/*\n * " KEY_PREFIX NETENT L2TP " Entity Keys\n */", NULL, NULL, NULL },
+ { DEFINE , NETPROP L2TP, IPSEC SHAREDSECRET, NULL, CFSTRING },
+ { DEFINE , NETPROP L2TP, IPSEC SHAREDSECRET ENCRYPTION, NULL, CFSTRING },
+ { DEFINE , NETPROP L2TP, TRANSPORT, NULL, CFSTRING },
+ { COMMENT, "", NULL, NULL, NULL },
+ { COMMENT, "/* " KEY_PREFIX NETPROP L2TP IPSEC SHAREDSECRET ENCRYPTION " values */", NULL, NULL, NULL },
+ { DEFINE , NETVAL L2TP IPSEC SHAREDSECRET ENCRYPTION, KEYCHAIN, NULL, NULL },
+ { COMMENT, "", NULL, NULL, NULL },
+ { COMMENT, "/* " KEY_PREFIX NETPROP L2TP TRANSPORT " values */", NULL, NULL, NULL },
+ { DEFINE , NETVAL L2TP TRANSPORT, IP, NULL, NULL },
+ { DEFINE , NETVAL L2TP TRANSPORT, IPSEC, NULL, NULL },
+ { COMMENT, "", 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, USERSENT, CONSOLEUSER, NULL, NULL },
{ COMMENT, "", NULL, NULL, NULL },
- { 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 * " KEY_PREFIX COMP SYSTEM " Properties\n */", NULL, NULL, NULL },
{ REGULAR, SYSTEMPROP, COMPUTERNAME, NULL, CFSTRING },
{ REGULAR, SYSTEMPROP, COMPUTERNAME ENCODING, NULL, CFNUMBER },
{ 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 },
+ { COMMENT, "/*\n * Obsolete schema definitions which will be removed \"soon\".\n */", NULL },
+ { OBSOLETE, USERSPROP CONSOLEUSER, NAME, NULL, CFSTRING },
+ { OBSOLETE, USERSPROP CONSOLEUSER, UID, NULL, CFNUMBER },
+ { OBSOLETE, USERSPROP CONSOLEUSER, GID, NULL, CFNUMBER },
+ { COMMENT, "", NULL, NULL, NULL },
{ END, NULL, NULL, NULL, NULL },
};
+static inline void
+setmax(int *max, char **maxstr, char *str)
+{
+ int l;
+
+ l = strlen(str);
+ if (l > *max) {
+ if (*maxstr) free(*maxstr);
+ *maxstr = strdup(str);
+ *max = l;
+ }
+ return;
+}
+
enum {
- gen_extern_e,
- gen_init_e,
gen_header_e,
+ gen_hfile_e,
+ gen_cfile_e,
};
void
dump_names(int type)
{
int i;
+ int maxkbuf = 0;
+ char *maxkstr = NULL;
+ int maxvbuf = 0;
+ char *maxvstr = NULL;
for (i = 0; TRUE; i++) {
switch (names[i].control) {
break;
}
case COMMENT: {
- if (type != gen_extern_e && type != gen_init_e) {
+ switch (type) {
+ case gen_header_e:
+ case gen_hfile_e:
if (names[i].prefix)
printf("%s\n", names[i].prefix);
+ break;
+ default:
+ break;
}
break;
}
printf("#define %-40s %-40s\n",
kbuf, vbuf);
break;
+ case gen_hfile_e:
+ snprintf(kbuf, sizeof(kbuf), "(" KEY_PREFIX "%s%s);",
+ names[i].prefix, names[i].key);
+ setmax(&maxkbuf, &maxkstr, kbuf);
+
+ snprintf(vbuf, sizeof(vbuf), "\"%s\"",
+ names[i].value ? names[i].value : names[i].key);
+ setmax(&maxvbuf, &maxvstr, vbuf);
+
+ printf("SC_SCHEMA_DECLARATION%-42s /* %-17s %-30s */\n",
+ kbuf,
+ names[i].type ? names[i].type : "",
+ vbuf);
+ break;
+ case gen_cfile_e:
+ snprintf(kbuf, sizeof(kbuf), KEY_PREFIX "%s%s",
+ names[i].prefix, names[i].key);
+
+ if (names[i].value)
+ printf("const CFStringRef %-45s = CFSTR(\"%s\");\n",
+ kbuf, names[i].value);
+ else
+ printf("const CFStringRef %-45s = CFSTR(\"%s\");\n",
+ kbuf, names[i].key);
+ break;
default:
break;
}
printf("#define %-40s %-40s\n",
kbuf, vbuf);
break;
- case gen_extern_e:
- snprintf(kbuf, sizeof(kbuf), KEY_PREFIX "%s%s",
+ case gen_hfile_e:
+ snprintf(kbuf, sizeof(kbuf), "(" KEY_PREFIX "%s%s);",
names[i].prefix, names[i].key);
+ setmax(&maxkbuf, &maxkstr, kbuf);
- printf("volatile CFStringRef " KEY_PREFIX "%s%s = NULL;\n",
- names[i].prefix, names[i].key);
+ snprintf(vbuf, sizeof(vbuf), "\"%s\"",
+ names[i].value ? names[i].value : names[i].key);
+ setmax(&maxvbuf, &maxvstr, vbuf);
+
+ printf("SC_SCHEMA_DECLARATION%-42s /* %-17s %-30s */\n",
+ kbuf,
+ names[i].type ? names[i].type : "",
+ vbuf);
break;
- case gen_init_e:
+ case gen_cfile_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",
+ printf("const CFStringRef %-45s = CFSTR(\"%s\");\n",
kbuf, names[i].value);
else
- printf(" *((void **)&%s) = (void *)CFSTR(\"%s\");\n",
+ printf("const CFStringRef %-45s = CFSTR(\"%s\");\n",
kbuf, names[i].key);
break;
default:
break;
}
case OBSOLETE: {
+ static int nObsolete = 0;
char kbuf[256];
+ char vbuf[256];
switch (type) {
- case gen_extern_e:
- snprintf(kbuf, sizeof(kbuf), KEY_PREFIX "%s%s",
- names[i].prefix, names[i].key);
+ case gen_hfile_e:
+ if (nObsolete++ == 0) {
+ printf("#ifndef SCSTR\n");
+ printf("#include <CoreFoundation/CFString.h>\n");
+ printf("#define SCSTR(s) CFSTR(s)\n");
+ printf("#endif\n");
+ }
- 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);
+ snprintf(vbuf, sizeof(vbuf), "SCSTR(\"%s\")",
+ names[i].value);
else
- printf(" *((void **)&%s) = (void *)CFSTR(\"%s\");\n",
- kbuf, names[i].key);
+ snprintf(vbuf, sizeof(vbuf), "SCSTR(\"%s\")",
+ names[i].key);
+
+ printf("#define %-40s %-40s /* %s */\n",
+ kbuf,
+ vbuf,
+ names[i].type ? names[i].type : "");
break;
default:
break;
case FUTURE: {
char kbuf[256];
- if (type == gen_header_e) {
+ switch (type) {
+ case gen_header_e:
snprintf(kbuf, sizeof(kbuf), KEY_PREFIX "%s%s",
names[i].prefix, names[i].key);
- printf("/* #define %-37s %-40s /* %s */\n",
+ printf("// #define %-37s %-40s /* %s */\n",
kbuf,
"SCSTR(\"???\") */",
"RESERVED FOR FUTURE USE");
+ break;
+ case gen_hfile_e:
+ snprintf(kbuf, sizeof(kbuf), "(" KEY_PREFIX "%s%s);",
+ names[i].prefix, names[i].key);
+ setmax(&maxkbuf, &maxkstr, kbuf);
+
+ printf("// SC_SCHEMA_DECLARATION%-39s /* %s */\n",
+ kbuf, "RESERVED FOR FUTURE USE");
+ break;
+ default:
+ break;
}
break;
}
}
}
done:
+ switch (type) {
+ case gen_hfile_e:
+ fprintf(stderr, "max key: length = %2d, string = %s\n", maxkbuf, maxkstr);
+ fprintf(stderr, "max val: length = %2d, string = %s\n", maxvbuf, maxvstr);
+ break;
+ }
return;
}
if (argc >= 2)
type = argv[1];
- if (strcmp(type, "header") == 0) {
+ if (strcmp(type, "header-x") == 0) {
printf("%s\n", copyright_string);
printf("/*\n * This file is automatically generated\n * DO NOT EDIT!\n */\n\n");
printf(" * #import <SystemConfiguration/SystemConfiguration.h>\n");
printf(" */\n\n");
- printf("#ifndef _SCSCHEMADEFINITIONS_H\n#define _SCSCHEMADEFINITIONS_H\n\n");
+ printf("#ifndef _SCSCHEMADEFINITIONS_10_1_H\n#define _SCSCHEMADEFINITIONS_10_1_H\n\n");
printf("#ifndef SCSTR\n");
printf("#include <CoreFoundation/CFString.h>\n");
printf("\n");
dump_names(gen_header_e);
+ printf("#endif /* _SCSCHEMADEFINITIONS_10_1_H */\n");
+ }
+ else 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("/*\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 " SC_SCHEMA_DECLARATION "(x)\t\textern NSString * x\n");
+ printf(" * #import <SystemConfiguration/SystemConfiguration.h>\n");
+ printf(" */\n\n");
+
+ printf("#ifndef _SCSCHEMADEFINITIONS_H\n#define _SCSCHEMADEFINITIONS_H\n\n");
+
+ printf("#ifndef SC_SCHEMA_DECLARATION\n");
+ printf("#ifndef SCSTR\n");
+ printf("#include <CoreFoundation/CFString.h>\n");
+ printf("#define " SC_SCHEMA_DECLARATION "(x)\textern const CFStringRef x\n");
+ printf("#else\n");
+ printf("#import <Foundation/NSString.h>\n");
+ printf("#define " SC_SCHEMA_DECLARATION "(x)\textern NSString * x\n");
+ printf("#endif\n");
+ printf("#endif\n");
+
+ printf("\n");
+ dump_names(gen_hfile_e);
+
+ printf("#include <AvailabilityMacros.h>\n");
+ printf("#if MAC_OS_X_VERSION_10_3 > MAC_OS_X_VERSION_MIN_REQUIRED\n");
+ printf(" #if MAC_OS_X_VERSION_10_1 <= MAC_OS_X_VERSION_MIN_REQUIRED\n");
+ printf(" #include <SystemConfiguration/SCSchemaDefinitions_10_1.h>\n");
+ printf(" #endif\n");
+ printf("#endif\n\n");
+
printf("#endif /* _SCSCHEMADEFINITIONS_H */\n");
}
else if (strcmp(type, "cfile") == 0) {
printf("\n");
printf("#include <CoreFoundation/CFString.h>\n");
printf("\n");
- dump_names(gen_extern_e);
- 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");
+ dump_names(gen_cfile_e);
}
exit(0);
return (0);
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include <sys/errno.h>
#include <sys/socket.h>
#include <sys/un.h>
-#include <CoreFoundation/CoreFoundation.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <SystemConfiguration/SCPrivate.h>
int
MOHExec(int ref,
u_long link,
- u_int32_t cmd,
+ uint32_t cmd,
void *request,
u_long requestLen,
void **reply,
if (n == -1) {
SCLog(_sc_verbose, LOG_ERR, CFSTR("MOHExec writen() failed: %s"), strerror(errno));
return errno;
- } else if (n != requestLen) {
+ } else if (n != (ssize_t)requestLen) {
SCLog(_sc_verbose, LOG_ERR, CFSTR("MOHExec writen() failed: wrote=%d"), n);
return -1;
}
SCLog(_sc_verbose, LOG_ERR, CFSTR("MOHExec readn() failed: error=%s"), strerror(errno));
CFAllocatorDeallocate(NULL, buf);
return errno;
- } else if (n != msg.m_len) {
+ } else if (n != (ssize_t)msg.m_len) {
SCLog(_sc_verbose, LOG_ERR, CFSTR("MOHExec readn() failed: insufficent data, read=%d"), n);
CFAllocatorDeallocate(NULL, buf);
return -1;
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
int
MOHExec (int ref,
u_long link,
- u_int32_t cmd,
+ uint32_t cmd,
void *request,
u_long requestLen,
void **reply,
/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/* MOH message paquets */
struct moh_msg_hdr {
- u_int32_t m_type; // type of the message
- u_int32_t m_result; // error code of notification message
- u_int32_t m_cookie; // user param
- u_int32_t m_link; // link for this message
- u_int32_t m_len; // len of the following data
+ uint32_t m_type; // type of the message
+ uint32_t m_result; // error code of notification message
+ uint32_t m_cookie; // user param
+ uint32_t m_link; // link for this message
+ uint32_t m_len; // len of the following data
};
struct moh_msg {
- u_int32_t m_type; // type of the message
- u_int32_t m_result; // error code of notification message
- u_int32_t m_cookie; // user param, or error num for event
- u_int32_t m_link; // link for this message
- u_int32_t m_len; // len of the following data
+ uint32_t m_type; // type of the message
+ uint32_t m_result; // error code of notification message
+ uint32_t m_cookie; // user param, or error num for event
+ uint32_t m_link; // link for this message
+ uint32_t m_len; // len of the following data
u_char m_data[1]; // msg data sent or received
};
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Modification History
*
- * Feb 28, 2002 Christophe Allie <callie@apple.com>
+ * Nov 7, 2002 Allan Nathanson <ajn@apple.com>
+ * - use ServiceID *or* LinkID
+ *
+ * Oct 25, 2002 Christophe Allie <callie@apple.com>
+ * - use ServiceID instead of LinkID
+ *
+ * Feb 28, 2002 Christophe Allie <callie@apple.com>
* - socket API fixes
*
- * Feb 10, 2001 Allan Nathanson <ajn@apple.com>
+ * Feb 10, 2001 Allan Nathanson <ajn@apple.com>
* - cleanup API
*
- * Feb 2000 Christophe Allie <callie@apple.com>
- * - initial revision (as ppplib.c)
+ * Feb 2000 Christophe Allie <callie@apple.com>
+ * - initial revision
*/
#include <stdio.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <SystemConfiguration/SCPrivate.h>
-#include "ppp_msg.h"
+#include <ppp/ppp_msg.h>
#include "ppp.h"
}
-__private_extern__
-int
+static int
PPPExec(int ref,
- u_long link,
- u_int32_t cmd,
+ CFStringRef serviceID,
+ uint32_t link,
+ uint32_t cmd,
+ u_int16_t flags,
void *request,
- u_long requestLen,
+ uint32_t requestLen,
void **reply,
- u_long *replyLen)
+ uint32_t *replyLen)
{
struct ppp_msg_hdr msg;
char *buf = NULL;
ssize_t n;
+ CFDataRef sID = NULL;
bzero(&msg, sizeof(msg));
- msg.m_type = cmd;
- msg.m_link = link;
- msg.m_len = ((request != NULL) && (requestLen > 0)) ? requestLen : 0;
- // send the command
- if (writen(ref, &msg, sizeof(msg)) < 0) {
- SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec write() failed: %s"), strerror(errno));
- return errno;
- }
+ // first send request, if necessary
+ if (cmd) {
+ msg.m_type = cmd;
+ msg.m_flags = flags;
+ if (serviceID) {
+ sID = CFStringCreateExternalRepresentation(NULL,
+ serviceID,
+ kCFStringEncodingUTF8,
+ 0);
+ // serviceID is present, use it
+ msg.m_flags |= USE_SERVICEID;
+ msg.m_link = CFDataGetLength(sID);
+ } else {
+ // no service ID, use the requested link
+ msg.m_link = link;
+ }
+ msg.m_len = ((request != NULL) && (requestLen > 0)) ? requestLen : 0;
- if ((request != NULL) && (requestLen > 0)) {
- if (writen(ref, request, requestLen) < 0) {
+ // send the command
+ if (writen(ref, &msg, sizeof(msg)) < 0) {
SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec write() failed: %s"), strerror(errno));
+ if (sID) CFRelease(sID);
return errno;
}
+
+ if (sID) {
+ if (writen(ref, (void *)CFDataGetBytePtr(sID), msg.m_link) < 0) {
+ SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec write() failed: %s"), strerror(errno));
+ CFRelease(sID);
+ return errno;
+ }
+ CFRelease(sID);
+ }
+
+ if ((request != NULL) && (requestLen > 0)) {
+ if (writen(ref, request, requestLen) < 0) {
+ SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec write() failed: %s"), strerror(errno));
+ return errno;
+ }
+ }
}
- // always expect a reply
+ // then read replies or incoming message
n = readn(ref, &msg, sizeof(msg));
if (n == -1) {
SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec readn() failed: error=%s"), strerror(errno));
return -1;
}
+ if ((msg.m_flags & USE_SERVICEID) && msg.m_link) {
+ buf = CFAllocatorAllocate(NULL, msg.m_link, 0);
+ if (buf) {
+ // read reply
+ n = readn(ref, buf, msg.m_link);
+ if (n == -1) {
+ SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec readn() failed: error=%s"), strerror(errno));
+ CFAllocatorDeallocate(NULL, buf);
+ return errno;
+ } else if (n != (ssize_t)msg.m_link) {
+ SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec readn() failed: error=%s"), strerror(errno));
+ CFAllocatorDeallocate(NULL, buf);
+ return -1;
+ }
+ // buf contains the service id we passed in the request
+ CFAllocatorDeallocate(NULL, buf);
+ buf = NULL;
+ }
+ }
+
if (msg.m_len) {
buf = CFAllocatorAllocate(NULL, msg.m_len, 0);
if (buf) {
SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec readn() failed: error=%s"), strerror(errno));
CFAllocatorDeallocate(NULL, buf);
return errno;
- } else if (n != msg.m_len) {
+ } else if (n != (ssize_t)msg.m_len) {
SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec readn() failed: insufficent data, read=%d"), n);
CFAllocatorDeallocate(NULL, buf);
return -1;
}
-#ifdef NOT_NEEDED
+__private_extern__
int
-PPPConnect(int ref, u_long link)
+PPPGetLinkByInterface(int ref, char *if_name, uint32_t *link)
{
- int status;
+ void *replyBuf = NULL;
+ uint32_t replyBufLen = 0;
+ int status;
status = PPPExec(ref,
- link,
- PPP_CONNECT,
NULL,
+ -1,
+ PPP_GETLINKBYIFNAME,
0,
- NULL,
- NULL);
+ (void *)if_name,
+ strlen(if_name),
+ &replyBuf,
+ &replyBufLen);
if (status != 0) {
- SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_CONNECT) failed: status = %d"), status);
return status;
}
+ if (replyBuf && (replyBufLen == sizeof(uint32_t))) {
+ *link = *(uint32_t *)replyBuf;
+ } else {
+ status = -2; /* if not found */
+ }
+ if (replyBuf) CFAllocatorDeallocate(NULL, replyBuf);
+
return status;
}
+__private_extern__
int
-PPPDisconnect(int ref, u_long link)
+PPPConnect(int ref, CFStringRef serviceID, uint32_t link, void *data, uint32_t dataLen, int linger)
{
int status;
status = PPPExec(ref,
+ serviceID,
link,
- PPP_DISCONNECT,
- NULL,
- 0,
+ PPP_CONNECT,
+ CONNECT_ARBITRATED_FLAG + (linger ? 0 : CONNECT_AUTOCLOSE_FLAG),
+ data,
+ dataLen,
NULL,
NULL);
- if (status != 0) {
- SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_DISCONNECT) failed: status = %d"), status);
- return status;
- }
-
return status;
}
-#endif /* NOT_NEEDED */
__private_extern__
int
-PPPGetNumberOfLinks(int ref, u_long *nLinks)
+PPPDisconnect(int ref, CFStringRef serviceID, uint32_t link, int force)
{
- void *replyBuf = NULL;
- u_long replyBufLen = 0;
int status;
status = PPPExec(ref,
- -1,
- PPP_GETNBLINKS,
- NULL,
- 0,
- &replyBuf,
- &replyBufLen);
- if (status != 0) {
- SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_GETNBLINKS) failed: status = %d"), status);
- return status;
- }
-
- *nLinks = (replyBufLen == sizeof(u_long)) ? *(u_long *)replyBuf : 0;
- if (replyBuf) CFAllocatorDeallocate(NULL, replyBuf);
-
+ serviceID,
+ link,
+ PPP_DISCONNECT,
+ force ? 0 : DISCONNECT_ARBITRATED_FLAG,
+ NULL,
+ 0,
+ NULL,
+ NULL);
return status;
}
__private_extern__
int
-PPPGetLinkByIndex(int ref, int index, u_int32_t *link)
+PPPSuspend(int ref, CFStringRef serviceID, uint32_t link)
{
- u_int32_t i = index;
- void *replyBuf = NULL;
- u_long replyBufLen = 0;
- int status;
+ int status;
status = PPPExec(ref,
- -1,
- PPP_GETLINKBYINDEX,
- (void *)&i,
- sizeof(i),
- &replyBuf,
- &replyBufLen);
- if (status != 0) {
- SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_GETLINKBYINDEX) failed: status = %d"), status);
- return status;
- }
-
- if (replyBuf && (replyBufLen == sizeof(u_int32_t))) {
- *link = *(u_int32_t *)replyBuf;
- } else {
- status = -2; /* if not found */
- }
- if (replyBuf) CFAllocatorDeallocate(NULL, replyBuf);
-
+ serviceID,
+ link,
+ PPP_SUSPEND,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ NULL);
return status;
}
__private_extern__
int
-PPPGetLinkByServiceID(int ref, CFStringRef serviceID, u_int32_t *link)
+PPPResume(int ref, CFStringRef serviceID, uint32_t link)
{
- int i;
- u_long nLinks;
- int status;
- CFDataRef sID;
-
- sID = CFStringCreateExternalRepresentation(NULL,
- serviceID,
- kCFStringEncodingMacRoman,
- 0);
-
- status = PPPGetNumberOfLinks(ref, &nLinks);
- if (status != 0) {
- SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPGetNumberOfLinks() failed: %d"), status);
- goto done;
- }
-
- status = -2; /* assume no link */
-
- for (i=0; i<nLinks; i++) {
- u_int32_t iLink;
- void *data = NULL;
- u_long dataLen = 0;
-
- status = PPPGetLinkByIndex(ref, i, &iLink);
- if (status != 0) {
- SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPGetLinkByIndex() failed: %d"), status);
- goto done;
- }
-
- status = PPPGetOption(ref,
- iLink,
- PPP_OPT_SERVICEID,
- &data,
- &dataLen);
- if (status != 0) {
- SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPGetOption(PPP_OPT_SERVICEID) failed: %d"), status);
- goto done;
- }
-
- if ((dataLen != CFDataGetLength(sID)) ||
- (strncmp(data, CFDataGetBytePtr(sID), dataLen) != 0)) {
- /* if link not found */
- status = -2;
- }
-
- CFAllocatorDeallocate(NULL, data);
- if (status == 0) {
- *link = iLink;
- goto done;
- }
- }
-
- done :
+ int status;
- CFRelease(sID);
+ status = PPPExec(ref,
+ serviceID,
+ link,
+ PPP_RESUME,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ NULL);
return status;
}
__private_extern__
int
-PPPGetOption(int ref, u_long link, u_long option, void **data, u_long *dataLen)
+PPPGetOption(int ref, CFStringRef serviceID, uint32_t link, uint32_t option, void **data, uint32_t *dataLen)
{
- struct ppp_opt_hdr opt;
+ struct ppp_opt_hdr opt;
void *replyBuf = NULL;
- u_long replyBufLen = 0;
+ uint32_t replyBufLen = 0;
int status;
+ *dataLen = 0;
+ *data = NULL;
+
bzero(&opt, sizeof(opt));
opt.o_type = option;
status = PPPExec(ref,
- link,
- PPP_GETOPTION,
- (void *)&opt,
- sizeof(opt),
- &replyBuf,
- &replyBufLen);
+ serviceID,
+ link,
+ PPP_GETOPTION,
+ 0,
+ (void *)&opt,
+ sizeof(opt),
+ &replyBuf,
+ &replyBufLen);
if (status != 0) {
- 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)
+PPPSetOption(int ref, CFStringRef serviceID, uint32_t link, uint32_t option, void *data, uint32_t dataLen)
{
- void *buf;
- u_long bufLen;
- int status;
+ void *buf;
+ uint32_t bufLen;
+ int status;
bufLen = sizeof(struct ppp_opt_hdr) + dataLen;
buf = CFAllocatorAllocate(NULL, bufLen, 0);
bcopy(data, ((struct ppp_opt *)buf)->o_data, dataLen);
status = PPPExec(ref,
+ serviceID,
link,
PPP_SETOPTION,
+ 0,
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)
+PPPGetConnectData(int ref, CFStringRef serviceID, uint32_t link, void **data, uint32_t *dataLen)
{
- void *replyBuf = NULL;
- u_long replyBufLen = 0;
int status;
+ *dataLen = 0;
+ *data = NULL;
+
status = PPPExec(ref,
- link,
- PPP_STATUS,
- NULL,
- 0,
- &replyBuf,
- &replyBufLen);
+ serviceID,
+ link,
+ PPP_GETCONNECTDATA,
+ 0,
+ NULL,
+ 0,
+ data,
+ dataLen);
+ return status;
+}
+
+
+__private_extern__
+int
+PPPStatus(int ref, CFStringRef serviceID, uint32_t link, struct ppp_status **stat)
+{
+ void *replyBuf = NULL;
+ uint32_t replyBufLen = 0;
+ int status;
+
+ *stat = NULL;
+
+ status = PPPExec(ref,
+ serviceID,
+ link,
+ PPP_STATUS,
+ 0,
+ NULL,
+ 0,
+ &replyBuf,
+ &replyBufLen);
if (status != 0) {
- SCLog(_sc_verbose, LOG_ERR, CFSTR("PPPExec(PPP_STATUS) failed: status = %d"), status);
return status;
}
*stat = (struct ppp_status *)replyBuf;
} else {
if (replyBuf) CFAllocatorDeallocate(NULL, replyBuf);
- *stat = NULL;
status = -1;
}
}
-#ifdef NOT_NEEDED
__private_extern__
int
-PPPEnableEvents(int ref, u_long link, u_char enable)
+PPPExtendedStatus(int ref, CFStringRef serviceID, uint32_t link, void **data, uint32_t *dataLen)
{
int status;
+ *dataLen = 0;
+ *data = NULL;
+
status = PPPExec(ref,
+ serviceID,
link,
- enable ? PPP_ENABLE_EVENT : PPP_DISABLE_EVENT,
+ PPP_EXTENDEDSTATUS,
+ 0,
NULL,
0,
+ data,
+ dataLen);
+ return status;
+}
+
+
+__private_extern__
+int
+PPPEnableEvents(int ref, CFStringRef serviceID, uint32_t link, u_char enable)
+{
+ int status;
+ uint32_t lval = 2; // status notifications
+
+ status = PPPExec(ref,
+ serviceID,
+ link,
+ enable ? PPP_ENABLE_EVENT : PPP_DISABLE_EVENT,
+ 0,
+ &lval,
+ sizeof(lval),
NULL,
NULL);
- if (status != 0) {
- SCLog(_sc_verbose,
- LOG_ERR,
- CFSTR("PPPExec(%s) failed: status = %d"),
- enable ? "PPP_ENABLE_EVENT" : "PPP_DISABLE_EVENT",
- status);
- return status;
+ return status;
+}
+
+
+__private_extern__
+int
+PPPReadEvent(int ref, uint32_t *event)
+{
+
+ *event = PPPExec(ref, NULL, 0, 0, 0, NULL, 0, NULL, NULL);
+ return 0;
+}
+
+
+__private_extern__
+CFDataRef
+PPPSerialize(CFPropertyListRef obj, void **data, uint32_t *dataLen)
+{
+ CFDataRef xml;
+
+ xml = CFPropertyListCreateXMLData(NULL, obj);
+ if (xml) {
+ *data = (void*)CFDataGetBytePtr(xml);
+ *dataLen = CFDataGetLength(xml);
}
+ return xml;
+}
- return status;
+
+__private_extern__
+CFPropertyListRef
+PPPUnserialize(void *data, uint32_t dataLen)
+{
+ CFDataRef xml;
+ CFStringRef xmlError;
+ CFPropertyListRef ref = NULL;
+
+ xml = CFDataCreateWithBytesNoCopy(NULL, data, dataLen, kCFAllocatorNull);
+ if (xml) {
+ ref = CFPropertyListCreateFromXMLData(NULL,
+ xml,
+ kCFPropertyListImmutable,
+ &xmlError);
+ if (!ref) {
+ if (xmlError) {
+ SCLog(TRUE,
+ LOG_ERR,
+ CFSTR("CFPropertyListCreateFromXMLData() failed: %@"),
+ xmlError);
+ CFRelease(xmlError);
+ }
+ }
+
+ CFRelease(xml);
+ }
+
+ return ref;
}
-#endif /* NOT_NEEDED */
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Modification History
*
+ * Nov 7, 2002 Allan Nathanson <ajn@apple.com>
+ * - use ServiceID *or* LinkID
+ *
* Feb 10, 2001 Allan Nathanson <ajn@apple.com>
* - cleanup API
*
#define _PPP_H
#include <sys/cdefs.h>
+#include <ppp/ppp_msg.h>
#include <CoreFoundation/CoreFoundation.h>
-#include "ppp_msg.h"
__BEGIN_DECLS
int PPPDispose (int ref);
-int PPPExec (int ref,
- u_long link,
- u_int32_t cmd,
- void *request,
- u_long requestLen,
- void **reply,
- u_long *replyLen);
+int PPPGetLinkByInterface (int ref,
+ char *if_name,
+ uint32_t *link);
-#ifdef NOT_NEEDED
int PPPConnect (int ref,
- u_long link);
+ CFStringRef serviceid,
+ uint32_t link,
+ void *data,
+ uint32_t dataLen,
+ int linger);
int PPPDisconnect (int ref,
- u_long link);
-#endif /* NOT_NEEDED */
-
-int PPPGetNumberOfLinks (int ref,
- u_long *nLinks);
+ CFStringRef serviceid,
+ uint32_t link,
+ int force);
-int PPPGetLinkByIndex (int ref,
- int index,
- u_int32_t *link);
+int PPPSuspend (int ref,
+ CFStringRef serviceID,
+ uint32_t link);
-int PPPGetLinkByServiceID (int ref,
+int PPPResume (int ref,
CFStringRef serviceID,
- u_int32_t *link);
+ uint32_t link);
int PPPGetOption (int ref,
- u_long link,
- u_long option,
+ CFStringRef serviceid,
+ uint32_t link,
+ uint32_t option,
void **data,
- u_long *dataLen);
+ uint32_t *dataLen);
-#ifdef NOT_NEEDED
int PPPSetOption (int ref,
- u_long link,
- u_long option,
+ CFStringRef serviceid,
+ uint32_t link,
+ uint32_t option,
void *data,
- u_long dataLen);
-#endif /* NOT_NEEDED */
+ uint32_t dataLen);
+
+int PPPGetConnectData (int ref,
+ CFStringRef serviceID,
+ uint32_t link,
+ void **data,
+ uint32_t *dataLen);
int PPPStatus (int ref,
- u_long link,
+ CFStringRef serviceid,
+ uint32_t link,
struct ppp_status **stat);
-#ifdef NOT_NEEDED
+int PPPExtendedStatus (int ref,
+ CFStringRef serviceid,
+ uint32_t link,
+ void **data,
+ uint32_t *dataLen);
+
int PPPEnableEvents (int ref,
- u_long link,
+ CFStringRef serviceid,
+ uint32_t link,
u_char enable);
-#endif /* NOT_NEEDED */
+
+int PPPReadEvent (int ref,
+ uint32_t *event);
+
+CFDataRef PPPSerialize (CFPropertyListRef obj,
+ void **data,
+ uint32_t *dataLen);
+
+CFPropertyListRef PPPUnserialize (void *data,
+ uint32_t dataLen);
__END_DECLS
+++ /dev/null
-/*
- * Copyright (c) 2000-2002 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 _PPP_MSG_H
-#define _PPP_MSG_H
-
-#include <sys/types.h>
-
-/* local socket path */
-#define PPP_PATH "/var/run/pppconfd\0"
-
-
-/* PPP message paquets */
-struct ppp_msg_hdr {
- u_int32_t m_type; // type of the message
- u_int32_t m_result; // error code of notification message
- u_int32_t m_cookie; // user param
- u_int32_t m_link; // link for this message
- u_int32_t m_len; // len of the following data
-};
-
-struct ppp_msg {
- u_int32_t m_type; // type of the message
- u_int32_t m_result; // error code of notification message
- u_int32_t m_cookie; // user param, or error num for event
- u_int32_t m_link; // link for this message
- u_int32_t m_len; // len of the following data
- u_char m_data[1]; // msg data sent or received
-};
-
-
-
-/* codes for ppp messages */
-enum {
- /* API client commands */
- PPP_VERSION = 1,
- PPP_STATUS,
- PPP_CONNECT,
- PPP_DISCONNECT = 5,
- PPP_GETOPTION,
- PPP_SETOPTION,
- PPP_ENABLE_EVENT,
- PPP_DISABLE_EVENT,
- PPP_EVENT,
- PPP_GETNBLINKS,
- PPP_GETLINKBYINDEX
-
-};
-
-// struct for an option
-struct ppp_opt_hdr {
- u_int32_t o_type;
-};
-
-struct ppp_opt {
- u_int32_t o_type;
- u_char o_data[1];
-};
-
-
-/* codes for options management */
-enum {
-
- PPP_OPT_DEV_NAME = 1, // string
- PPP_OPT_DEV_SPEED, // 4 bytes
- PPP_OPT_DEV_CONNECTSCRIPT, // string
-
- PPP_OPT_COMM_IDLETIMER, // 4 bytes
- PPP_OPT_COMM_REMOTEADDR, // string
-
- PPP_OPT_AUTH_PROTO, // 4 bytes
- PPP_OPT_AUTH_NAME, // string
- PPP_OPT_AUTH_PASSWD, // string
-
- PPP_OPT_LCP_HDRCOMP, // 4 bytes
- PPP_OPT_LCP_MRU, // 4 bytes
- PPP_OPT_LCP_MTU, // 4 bytes
- PPP_OPT_LCP_RCACCM, // 4 bytes
- PPP_OPT_LCP_TXACCM, // 4 bytes
-
- PPP_OPT_IPCP_HDRCOMP, // 4 bytes
- PPP_OPT_IPCP_LOCALADDR, // 4 bytes
- PPP_OPT_IPCP_REMOTEADDR, // 4 bytes
-
- PPP_OPT_LOGFILE, // string
- PPP_OPT_RESERVED, // 4 bytes
- PPP_OPT_REMINDERTIMER, // 4 bytes (not implemented)
- PPP_OPT_ALERTENABLE, // 4 bytes (not implemented)
-
- PPP_OPT_LCP_ECHO, // struct ppp_opt_echo
-
- PPP_OPT_COMM_CONNECTDELAY, // 4 bytes
- PPP_OPT_COMM_SESSIONTIMER, // 4 bytes
- PPP_OPT_COMM_TERMINALMODE, // 4 bytes
- PPP_OPT_COMM_TERMINALSCRIPT, // string. Additionnal connection script, once modem is connected
- PPP_OPT_DEV_CAPS, // struct ppp_caps...
-
- 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 store
-
-};
-
-// options values
-
-// PPP_LCP_OPT_HDRCOMP -- option ppp addr/ctrl compression
-enum {
- PPP_LCP_HDRCOMP_NONE = 0,
- PPP_LCP_HDRCOMP_ADDR = 1,
- PPP_LCP_HDRCOMP_PROTO = 2
-};
-
-enum {
- PPP_COMM_TERM_NONE = 0,
- PPP_COMM_TERM_SCRIPT,
- PPP_COMM_TERM_WINDOW
-};
-
-enum {
- PPP_IPCP_HDRCOMP_NONE = 0,
- PPP_IPCP_HDRCOMP_VJ
-};
-
-// PPP_LCP_OPT_RCACCM -- option receive control asynchronous character map
-enum {
- PPP_LCP_ACCM_NONE = 0,
- PPP_LCP_ACCM_XONXOFF = 0x000A0000,
- PPP_LCP_ACCM_ALL = 0xFFFFFFFF
-};
-
-// PPP_OPT_AUTH
-enum {
- PPP_AUTH_NONE = 0,
- PPP_AUTH_PAPCHAP,
- PPP_AUTH_PAP,
- PPP_AUTH_CHAP
-};
-
-// state machine
-enum {
- PPP_IDLE = 0,
- PPP_INITIALIZE,
- PPP_CONNECTLINK,
- PPP_STATERESERVED,
- PPP_ESTABLISH,
- PPP_AUTHENTICATE,
- PPP_CALLBACK,
- PPP_NETWORK,
- PPP_RUNNING,
- PPP_TERMINATE,
- PPP_DISCONNECTLINK,
- PPP_HOLDOFF,
- PPP_ONHOLD
-};
-
-// events
-enum {
- PPP_EVT_DISCONNECTED = 1,
- PPP_EVT_CONNSCRIPT_STARTED,
- PPP_EVT_CONNSCRIPT_FINISHED,
- PPP_EVT_TERMSCRIPT_STARTED,
- PPP_EVT_TERMSCRIPT_FINISHED,
- PPP_EVT_LOWERLAYER_UP,
- PPP_EVT_LOWERLAYER_DOWN,
- PPP_EVT_LCP_UP,
- PPP_EVT_LCP_DOWN,
- PPP_EVT_IPCP_UP,
- PPP_EVT_IPCP_DOWN,
- PPP_EVT_AUTH_STARTED,
- PPP_EVT_AUTH_FAILED,
- PPP_EVT_AUTH_SUCCEDED
-};
-
-struct ppp_opt_echo { // 0 for the following value will cancel echo option
- u_int16_t interval; // delay in seconds between echo requests
- u_int16_t failure; // # of failure before declaring the link down
-};
-
-struct ppp_status {
- // connection stats
- u_int32_t status;
- union {
- struct connected {
- u_int32_t timeElapsed;
- u_int32_t timeRemaining;
- // bytes stats
- u_int32_t inBytes;
- u_int32_t inPackets;
- u_int32_t inErrors;
- u_int32_t outBytes;
- u_int32_t outPackets;
- u_int32_t outErrors;
- } run;
- struct disconnected {
- u_int32_t lastDiscCause;
- } disc;
- } s;
-};
-
-enum {
- // from 0 to 255, we use bsd error codes from errno.h
-
- // ppp speficic error codes
- PPP_ERR_GEN_ERROR = 256,
- PPP_ERR_CONNSCRIPTFAILED,
- PPP_ERR_TERMSCRIPTFAILED,
- PPP_ERR_LCPFAILED,
- PPP_ERR_AUTHFAILED,
- PPP_ERR_IDLETIMEOUT,
- PPP_ERR_SESSIONTIMEOUT,
- PPP_ERR_LOOPBACK,
- PPP_ERR_PEERDEAD,
- PPP_ERR_DISCSCRIPTFAILED,
-
- // modem specific error codes
- PPP_ERR_MOD_NOCARRIER = 512,
- PPP_ERR_MOD_BUSY,
- PPP_ERR_MOD_NODIALTONE,
- PPP_ERR_MOD_ERROR
-};
-
-#endif /* _PPP_MSG_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@
- */
-
-/*
- * 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 pattern.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\
- _confignotify.c _notifyadd.c _notifyremove.c _notifychanges.c\
- _notifyviaport.c _notifyviafd.c _notifyviasignal.c\
- _notifycancel.c _snapshot.c
+ session.c pattern.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 configd.plist
MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
PROF_LIBS = $(LIBS)
+NEXTSTEP_PB_LDFLAGS = -prebind_all_twolevel_modules
FRAMEWORKS = -framework CoreFoundation -framework SystemConfiguration
# the include path (defaults to -I.)
# DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
# passed to ld/libtool (defaults to nothing)
+WARNING_CFLAGS=-Wall
# Library and Framework projects only:
# owned by the top-level Makefile API and no context has been set up for where
# derived files should go.
#
+MACH_INIT_DIR = /private/etc/mach_init.d
+install_extra:
+ $(MKDIRS) $(DSTROOT)$(MACH_INIT_DIR)
+ install -c -m 644 configd.plist $(DSTROOT)$(MACH_INIT_DIR)/configd.plist
# Change this definition to install projects somewhere other than the
# standard locations. NEXT_ROOT defaults to "C:/Apple" on Windows systems
# and "" on other systems.
-# DSTROOT = $(HOME)
+DSTROOT = $(HOME)
+AFTER_INSTALL = install_extra
# Additional flags (for MiG generated files)
ALL_MIGFLAGS = -F$(SYMROOT)
"notify_server.h",
"plugin_support.h",
"session.h",
+ "pattern.h",
"notify.h"
);
"OTHER_LIBS" = (objc);
"notify_server.c",
"plugin_support.c",
"session.c",
+ "pattern.c",
"notify.c",
"_configopen.c",
"_configclose.c",
"Makefile.postamble",
"m.template",
"h.template",
- "config.defs"
+ "config.defs",
+ "configd.plist"
);
"PRECOMPILED_HEADERS" = ();
"PROJECT_HEADERS" = ();
"NEXTSTEP_BUILDTOOL" = "/usr/bin/gnumake";
"NEXTSTEP_INSTALLDIR" = "/usr/sbin";
"NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac";
+ "NEXTSTEP_LINKEROPTIONS" = "-prebind_all_twolevel_modules";
"NEXTSTEP_OBJCPLUS_COMPILER" = "/usr/bin/cc";
"PDO_UNIX_BUILDTOOL" = "$NEXT_ROOT/Developer/bin/make";
"PDO_UNIX_INSTALLDIR" = "/bin";
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
-CFMutableDictionaryRef sessionData = NULL;
+__private_extern__ CFMutableDictionaryRef sessionData = NULL;
-CFMutableDictionaryRef storeData = NULL;
-CFMutableDictionaryRef storeData_s = NULL;
+__private_extern__ CFMutableDictionaryRef storeData = NULL;
+__private_extern__ CFMutableDictionaryRef storeData_s = NULL;
-CFMutableSetRef changedKeys = NULL;
-CFMutableSetRef changedKeys_s = NULL;
+__private_extern__ CFMutableDictionaryRef patternData = NULL;
+__private_extern__ CFMutableDictionaryRef patternData_s = NULL;
-CFMutableSetRef deferredRemovals = NULL;
-CFMutableSetRef deferredRemovals_s = NULL;
+__private_extern__ CFMutableSetRef changedKeys = NULL;
+__private_extern__ CFMutableSetRef changedKeys_s = NULL;
-CFMutableSetRef removedSessionKeys = NULL;
-CFMutableSetRef removedSessionKeys_s = NULL;
+__private_extern__ CFMutableSetRef deferredRemovals = NULL;
+__private_extern__ CFMutableSetRef deferredRemovals_s = NULL;
-CFMutableSetRef needsNotification = NULL;
+__private_extern__ CFMutableSetRef removedSessionKeys = NULL;
+__private_extern__ CFMutableSetRef removedSessionKeys_s = NULL;
-int storeLocked = 0; /* > 0 if dynamic store locked */
+__private_extern__ CFMutableSetRef needsNotification = NULL;
+__private_extern__ int storeLocked = 0; /* > 0 if dynamic store locked */
+
+__private_extern__
void
_swapLockedStoreData()
{
storeData = storeData_s;
storeData_s = temp;
+ temp = patternData;
+ patternData = patternData_s;
+ patternData_s = temp;
+
temp = changedKeys;
changedKeys = changedKeys_s;
changedKeys_s = temp;
}
+__private_extern__
void
_addWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
{
}
-/*
- * _addRegexWatcherByKey()
- *
- * This is a CFDictionaryApplierFunction which will iterate over each key
- * 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
- * 2. the compiled regular expression associated with the above key.
- *
- * If a (real) dictionary key is found which matches the provided regular
- * expression then we mark that key as being watched by the session.
- */
-void
-_addRegexWatcherByKey(const void *key, void *val, void *context)
-{
- CFStringRef storeStr = key;
- CFDictionaryRef info = val;
- mach_port_t sessionID = ((addContextRef)context)->store->server;
- regex_t *preg = ((addContextRef)context)->preg;
- int storeKeyLen;
- char *storeKey;
- CFNumberRef sessionNum;
- int reError;
- char reErrBuf[256];
- int reErrStrLen;
-
- if (!CFDictionaryContainsKey(info, kSCDData)) {
- /* if no data (yet) */
- return;
- }
-
- /* 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 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, storeStr);
- CFRelease(sessionNum);
- break;
- case REG_NOMATCH :
- /* no match */
- break;
- default :
- reErrStrLen = regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
- break;
- }
- CFAllocatorDeallocate(NULL, storeKey);
-}
-
-
-/*
- * _addRegexWatchersBySession()
- *
- * 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 store key being added.
- *
- * If an active session includes any regular expression keys which match the
- * key being added to the "storeData" dictionary then we mark this key as being
- * watched by the session.
- */
-void
-_addRegexWatchersBySession(const void *key, void *val, void *context)
-{
- CFStringRef sessionKey = key;
- CFDictionaryRef info = val;
- CFStringRef addedKey = context;
- CFIndex newKeyLen;
- char *newKeyStr;
- CFArrayRef rKeys;
- CFArrayRef rData;
- CFIndex i;
-
- rKeys = CFDictionaryGetValue(info, kSCDRegexKeys);
- if (rKeys == NULL) {
- /* if no regex keys for this session */
- return;
- }
- rData = CFDictionaryGetValue(info, kSCDRegexData);
-
- /* convert new key to C string */
- newKeyLen = CFStringGetLength(addedKey) + 1;
- newKeyStr = CFAllocatorAllocate(NULL, newKeyLen, 0);
- if (!CFStringGetCString(addedKey, newKeyStr, newKeyLen, kCFStringEncodingMacRoman)) {
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString: could not convert new key to C string"));
- CFAllocatorDeallocate(NULL, newKeyStr);
- return;
- }
-
- /* iterate over the regex keys looking for an pattern which matches the new key */
- for (i=0; i<CFArrayGetCount(rKeys); i++) {
- CFDataRef regexData = CFArrayGetValueAtIndex(rData, i);
- regex_t *preg = (regex_t *)CFDataGetBytePtr(regexData);
- int reError;
- char reErrBuf[256];
- int reErrStrLen;
- SInt32 sessionInt;
- CFNumberRef sessionNum;
-
- /* check if this key matches the regular expression */
- reError = regexec(preg, newKeyStr, 0, NULL, 0);
- switch (reError) {
- case 0 :
- /* we've got a match, add a reference */
- sessionInt = CFStringGetIntValue(sessionKey);
- sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionInt);
- _addWatcher(sessionNum, addedKey);
- CFRelease(sessionNum);
- break;
- case REG_NOMATCH :
- /* no match */
- break;
- default :
- reErrStrLen = regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
- break;
- }
-
- }
- CFAllocatorDeallocate(NULL, newKeyStr);
-
- return;
-}
-
-
+__private_extern__
void
_removeWatcher(CFNumberRef sessionNum, CFStringRef watchedKey)
{
return;
}
-
-
-/*
- * _removeRegexWatcherByKey()
- *
- * This is a CFDictionaryApplierFunction which will iterate over each key
- * 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
- * 2. the compiled regular expression associated with the above key.
- *
- * If a key is found and it matches the provided regular expression then
- * it will its "being watched" status will be cleared.
- */
-void
-_removeRegexWatcherByKey(const void *key, void *val, void *context)
-{
- CFStringRef storeStr = key;
- CFDictionaryRef info = val;
- mach_port_t sessionID = ((removeContextRef)context)->store->server;
- regex_t *preg = ((removeContextRef)context)->preg;
- CFNumberRef sessionNum;
- CFArrayRef watchers;
- int storeKeyLen;
- char *storeKey;
- int reError;
- char reErrBuf[256];
- int reErrStrLen;
-
- if (CFDictionaryContainsKey(info, kSCDWatchers) == FALSE) {
- /* if no watchers */
- return;
- }
-
- sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionID);
-
- watchers = CFDictionaryGetValue(info, kSCDWatchers);
- if (CFArrayContainsValue(watchers,
- CFRangeMake(0, CFArrayGetCount(watchers)),
- sessionNum) == FALSE) {
- /* this session is not watching this key */
- CFRelease(sessionNum);
- return;
- }
-
- /* convert 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 key to C string"));
- CFAllocatorDeallocate(NULL, storeKey);
- CFRelease(sessionNum);
- return;
- }
-
- /* check if this key matches the regular expression */
- reError = regexec(preg, storeKey, 0, NULL, 0);
- switch (reError) {
- case 0 :
- /* we've got a match */
- _removeWatcher(sessionNum, storeStr);
- break;
- case REG_NOMATCH :
- /* no match */
- break;
- default :
- reErrStrLen = regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
- break;
- }
- CFAllocatorDeallocate(NULL, storeKey);
- CFRelease(sessionNum);
-}
-
-
-/*
- * _removeRegexWatchersBySession()
- *
- * 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 store key being removed.
- *
- * If an active session includes any regular expression keys which match the
- * key being removed from the "storeData" dictionary then we clear this keys
- * reference of being watched.
- */
-void
-_removeRegexWatchersBySession(const void *key, void *val, void *context)
-{
- CFStringRef sessionKey = key;
- CFDictionaryRef info = val;
- CFStringRef removedKey = context;
- CFIndex oldKeyLen;
- char *oldKeyStr;
- CFArrayRef rKeys;
- CFArrayRef rData;
- CFIndex i;
-
- rKeys = CFDictionaryGetValue(info, kSCDRegexKeys);
- if (rKeys == NULL) {
- /* if no regex keys for this session */
- return;
- }
- rData = CFDictionaryGetValue(info, kSCDRegexData);
-
- /* convert new key to C string */
- oldKeyLen = CFStringGetLength(removedKey) + 1;
- oldKeyStr = CFAllocatorAllocate(NULL, oldKeyLen, 0);
- if (!CFStringGetCString(removedKey, oldKeyStr, oldKeyLen, kCFStringEncodingMacRoman)) {
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString: could not convert old key to C string"));
- CFAllocatorDeallocate(NULL, oldKeyStr);
- return;
- }
-
- /* iterate over the regex keys looking for an pattern which matches the old key */
- for (i=0; i<CFArrayGetCount(rKeys); i++) {
- CFDataRef regexData = CFArrayGetValueAtIndex(rData, i);
- regex_t *preg = (regex_t *)CFDataGetBytePtr(regexData);
- int reError;
- char reErrBuf[256];
- int reErrStrLen;
- SInt32 sessionInt;
- CFNumberRef sessionNum;
-
- /* check if this key matches the regular expression */
- reError = regexec(preg, oldKeyStr, 0, NULL, 0);
- switch (reError) {
- case 0 :
- /* we've got a match, remove a reference */
- sessionInt = CFStringGetIntValue(sessionKey);
- sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &sessionInt);
- _removeWatcher(sessionNum, removedKey);
- CFRelease(sessionNum);
- break;
- case REG_NOMATCH :
- /* no match */
- break;
- default :
- reErrStrLen = regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
- break;
- }
-
- }
- CFAllocatorDeallocate(NULL, oldKeyStr);
-
- return;
-}
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
* data associated with a key
*/
#define kSCDData CFSTR("data")
-/*
- * instance value associated with a key
- */
-#define kSCDInstance CFSTR("instance")
/*
* client session ids watching a key and, since we can possibly have
* multiple regex keys which reference the key, a count of active
* keys which have changed since last call to SCDNotifierGetChanges()
*/
#define kSCDChangedKeys CFSTR("changedKeys")
-/*
- * for notification keys which consist of a regular expression we keep
- * both the pattern string and the compiled regular expression
- */
-#define kSCDRegexKeys CFSTR("regexKeys")
-#define kSCDRegexData CFSTR("regexData")
/*
* keys which are to be removed when the session is closed
*/
extern int storeLocked;
extern CFMutableDictionaryRef storeData;
extern CFMutableDictionaryRef sessionData;
+extern CFMutableDictionaryRef patternData;
extern CFMutableSetRef changedKeys;
extern CFMutableSetRef deferredRemovals;
extern CFMutableSetRef removedSessionKeys;
extern CFMutableSetRef needsNotification;
extern CFMutableDictionaryRef storeData_s;
+extern CFMutableDictionaryRef patternData_s;
extern CFMutableSetRef changedKeys_s;
extern CFMutableSetRef deferredRemovals_s;
extern CFMutableSetRef removedSessionKeys_s;
-/*
- * "context" argument for CFDictionaryArrayApplier _addRegexWatcherByKey(),
- * _addRegexWatcherBySession(), and _removeRegexWatcherByKey() functions.
- */
-typedef struct {
- SCDynamicStorePrivateRef store;
- regex_t *preg;
-} addContext, *addContextRef;
-
-
-typedef struct {
- SCDynamicStorePrivateRef store;
- regex_t *preg;
-} removeContext, *removeContextRef;
-
__BEGIN_DECLS
__SCDynamicStoreOpen (SCDynamicStoreRef *store,
CFStringRef name);
int
-__SCDynamicStoreClose (SCDynamicStoreRef *store);
+__SCDynamicStoreClose (SCDynamicStoreRef *store,
+ Boolean internal);
int
__SCDynamicStoreLock (SCDynamicStoreRef store,
int
__SCDynamicStoreAddValue (SCDynamicStoreRef store,
CFStringRef key,
- CFPropertyListRef value);
+ CFDataRef value);
int
__SCDynamicStoreAddTemporaryValue (SCDynamicStoreRef store,
CFStringRef key,
- CFPropertyListRef value);
+ CFDataRef value);
int
__SCDynamicStoreCopyValue (SCDynamicStoreRef store,
CFStringRef key,
- CFPropertyListRef *value);
+ CFDataRef *value,
+ Boolean internal);
+
+int
+__SCDynamicStoreCopyMultiple (SCDynamicStoreRef store,
+ CFArrayRef keys,
+ CFArrayRef patterns,
+ CFDictionaryRef *values);
int
__SCDynamicStoreSetValue (SCDynamicStoreRef store,
CFStringRef key,
- CFPropertyListRef value);
+ CFDataRef value,
+ Boolean internal);
+
+int
+__SCDynamicStoreSetMultiple (SCDynamicStoreRef store,
+ CFDictionaryRef keysToSet,
+ CFArrayRef keysToRemove,
+ CFArrayRef keysToNotify);
int
__SCDynamicStoreRemoveValue (SCDynamicStoreRef store,
- CFStringRef key);
+ CFStringRef key,
+ Boolean internal);
int
__SCDynamicStoreTouchValue (SCDynamicStoreRef store,
int
__SCDynamicStoreNotifyValue (SCDynamicStoreRef store,
- CFStringRef key);
+ CFStringRef key,
+ Boolean internal);
int
__SCDynamicStoreSnapshot (SCDynamicStoreRef store);
int
__SCDynamicStoreAddWatchedKey (SCDynamicStoreRef store,
CFStringRef key,
- Boolean isRegex);
+ Boolean isRegex,
+ Boolean internal);
int
__SCDynamicStoreRemoveWatchedKey (SCDynamicStoreRef store,
CFStringRef key,
- Boolean isRegex);
+ Boolean isRegex,
+ Boolean internal);
+
+int
+__SCDynamicStoreSetNotificationKeys (SCDynamicStoreRef store,
+ CFArrayRef keys,
+ CFArrayRef patterns);
int
__SCDynamicStoreCopyNotifiedKeys (SCDynamicStoreRef store,
_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
#endif /* !_S_SCD_H */
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
#include "session.h"
+__private_extern__
int
-__SCDynamicStoreAddValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value)
+__SCDynamicStoreAddValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef value)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
int sc_status = kSCStatusOK;
- CFPropertyListRef tempValue;
+ CFDataRef tempValue;
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreAddValue:"));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" value = %@"), value);
+ if (_configd_verbose) {
+ CFPropertyListRef val;
+
+ (void) _SCUnserialize(&val, value, NULL, NULL);
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreAddValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" value = %@"), val);
+ CFRelease(val);
+ }
if (!store || (storePrivate->server == MACH_PORT_NULL)) {
return kSCStatusNoStoreSession; /* you must have an open session to play */
}
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace, CFSTR("add : %5d : %@\n"), storePrivate->server, key);
+ }
+
/*
* 1. Ensure that we hold the lock.
*/
/*
* 2. Ensure that this is a new key.
*/
- sc_status = __SCDynamicStoreCopyValue(store, key, &tempValue);
+ sc_status = __SCDynamicStoreCopyValue(store, key, &tempValue, TRUE);
switch (sc_status) {
case kSCStatusNoKey :
/* store key does not exist, proceed */
goto done;
default :
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" _SCDGet(): %s"), SCErrorString(sc_status));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" __SCDynamicStoreCopyValue(): %s"), SCErrorString(sc_status));
goto done;
}
/*
* 3. Save the new key.
*/
- sc_status = __SCDynamicStoreSetValue(store, key, value);
+ sc_status = __SCDynamicStoreSetValue(store, key, value, TRUE);
/*
* 4. Release our lock.
}
+__private_extern__
kern_return_t
_configadd(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
{
serverSessionRef mySession = getSession(server);
CFStringRef key; /* key (un-serialized) */
- CFPropertyListRef data; /* data (un-serialized) */
+ CFDataRef data; /* data (un-serialized) */
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Add key to configuration database."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Add key to configuration database."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
*sc_status = kSCStatusOK;
/* un-serialize the key */
- if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
+ if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
*sc_status = kSCStatusFailed;
- }
-
- if (!isA_CFString(key)) {
+ } else if (!isA_CFString(key)) {
*sc_status = kSCStatusInvalidArgument;
}
/* un-serialize the data */
- if (!_SCUnserialize((CFPropertyListRef *)&data, (void *)dataRef, dataLen)) {
+ if (!_SCUnserializeData(&data, (void *)dataRef, dataLen)) {
*sc_status = kSCStatusFailed;
}
- if (!isA_CFPropertyList(data)) {
- *sc_status = kSCStatusInvalidArgument;
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
}
if (*sc_status != kSCStatusOK) {
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
#include "session.h"
+__private_extern__
int
-__SCDynamicStoreAddTemporaryValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value)
+__SCDynamicStoreAddTemporaryValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef value)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
int sc_status = kSCStatusOK;
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 (_configd_verbose) {
+ CFPropertyListRef val;
+
+ (void) _SCUnserialize(&val, value, NULL, NULL);
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreAddTemporaryValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" value = %@"), val);
+ CFRelease(val);
+ }
if (!store || (storePrivate->server == MACH_PORT_NULL)) {
return kSCStatusNoStoreSession; /* you must have an open session to play */
}
+__private_extern__
kern_return_t
_configadd_s(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
{
serverSessionRef mySession = getSession(server);
CFStringRef key; /* key (un-serialized) */
- CFPropertyListRef data; /* data (un-serialized) */
+ CFDataRef data; /* data (un-serialized) */
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Add (session) key to configuration database."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Add (session) key to configuration database."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
*sc_status = kSCStatusOK;
/* un-serialize the key */
- if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
+ if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
*sc_status = kSCStatusFailed;
- }
-
- if (!isA_CFString(key)) {
+ } else if (!isA_CFString(key)) {
*sc_status = kSCStatusInvalidArgument;
}
/* un-serialize the data */
- if (!_SCUnserialize((CFPropertyListRef *)&data, (void *)dataRef, dataLen)) {
+ if (!_SCUnserializeData(&data, (void *)dataRef, dataLen)) {
*sc_status = kSCStatusFailed;
}
- if (!isA_CFPropertyList(data)) {
- *sc_status = kSCStatusInvalidArgument;
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
}
if (*sc_status != kSCStatusOK) {
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
#include "session.h"
+#define N_QUICK 16
+
static Boolean
isMySessionKey(CFStringRef sessionKey, CFStringRef key)
{
}
+static void
+removeAllKeys(SCDynamicStoreRef store, Boolean isRegex)
+{
+ SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
+ CFSetRef keys;
+ CFIndex n;
+
+ keys = isRegex ? storePrivate->patterns : storePrivate->keys;
+ n = CFSetGetCount(keys);
+ if (n > 0) {
+ CFIndex i;
+ CFArrayRef keysToRemove;
+ const void * watchedKeys_q[N_QUICK];
+ const void ** watchedKeys = watchedKeys_q;
+
+ if (n > (CFIndex)(sizeof(watchedKeys_q) / sizeof(CFStringRef)))
+ watchedKeys = CFAllocatorAllocate(NULL, n * sizeof(CFStringRef), 0);
+ CFSetGetValues(keys, watchedKeys);
+ keysToRemove = CFArrayCreate(NULL, watchedKeys, n, &kCFTypeArrayCallBacks);
+ if (watchedKeys != watchedKeys_q) CFAllocatorDeallocate(NULL, watchedKeys);
+ for (i = 0; i < n; i++) {
+ (void) __SCDynamicStoreRemoveWatchedKey(store,
+ CFArrayGetValueAtIndex(keysToRemove, i),
+ isRegex,
+ TRUE);
+ }
+ CFRelease(keysToRemove);
+ }
+
+ return;
+}
+
+
+__private_extern__
int
-__SCDynamicStoreClose(SCDynamicStoreRef *store)
+__SCDynamicStoreClose(SCDynamicStoreRef *store, Boolean internal)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)*store;
CFIndex keyCnt;
return kSCStatusNoStoreSession; /* you must have an open session to play */
}
- /* Remove notification keys */
- keyCnt = CFSetGetCount(storePrivate->keys);
- if (keyCnt > 0) {
- const 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);
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace,
+ CFSTR("%s : %5d\n"),
+ internal ? "*close " : "close ",
+ storePrivate->server);
}
- /* Remove regex notification keys */
- keyCnt = CFSetGetCount(storePrivate->reKeys);
- if (keyCnt > 0) {
- const 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 all notification keys and patterns */
+ removeAllKeys(*store, FALSE); // keys
+ removeAllKeys(*store, TRUE); // patterns
/* Remove/cancel any outstanding notification requests. */
(void) __SCDynamicStoreNotifyCancel(*store);
}
/* remove keys from "locked" store" */
- for (i=0; i<keyCnt; i++) {
+ for (i = 0; i < keyCnt; i++) {
if (isMySessionKey(sessionKey, CFArrayGetValueAtIndex(keys, i))) {
- (void) __SCDynamicStoreRemoveValue(*store, CFArrayGetValueAtIndex(keys, i));
+ (void) __SCDynamicStoreRemoveValue(*store, CFArrayGetValueAtIndex(keys, i), TRUE);
}
}
if (wasLocked) {
/* remove keys from "unlocked" store" */
_swapLockedStoreData();
- for (i=0; i<keyCnt; i++) {
+ for (i = 0; i < keyCnt; i++) {
if (isMySessionKey(sessionKey, CFArrayGetValueAtIndex(keys, i)))
- (void) __SCDynamicStoreRemoveValue(*store, CFArrayGetValueAtIndex(keys, i));
+ (void) __SCDynamicStoreRemoveValue(*store, CFArrayGetValueAtIndex(keys, i), TRUE);
}
_swapLockedStoreData();
}
}
+__private_extern__
kern_return_t
_configclose(mach_port_t server, int *sc_status)
{
serverSessionRef mySession = getSession(server);
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Close session."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Close session."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ return KERN_SUCCESS;
+ }
/*
* Close the session.
*/
- *sc_status = __SCDynamicStoreClose(&mySession->store);
+ *sc_status = __SCDynamicStoreClose(&mySession->store, FALSE);
if (*sc_status != kSCStatusOK) {
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" __SCDynamicStoreClose(): %s"), SCErrorString(*sc_status));
return KERN_SUCCESS;
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
#include "session.h"
+__private_extern__
int
-__SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef *value)
+__SCDynamicStoreCopyValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef *value, Boolean internal)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
CFDictionaryRef dict;
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyValue:"));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ }
if (!store || (storePrivate->server == MACH_PORT_NULL)) {
return kSCStatusNoStoreSession; /* you must have an open session to play */
}
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace,
+ CFSTR("%s : %5d : %@\n"),
+ internal ? "*copy " : "copy ",
+ storePrivate->server,
+ key);
+ }
+
dict = CFDictionaryGetValue(storeData, key);
if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDData) == FALSE)) {
/* key doesn't exist (or data never defined) */
/* Return the data associated with the key */
*value = CFRetain(CFDictionaryGetValue(dict, kSCDData));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" value = %@"), *value);
+ if (_configd_verbose) {
+ CFPropertyListRef val;
+
+ (void) _SCUnserialize(&val, *value, NULL, NULL);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" value = %@"), val);
+ CFRelease(val);
+ }
return kSCStatusOK;
}
+__private_extern__
kern_return_t
_configget(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
CFStringRef key; /* key (un-serialized) */
serverSessionRef mySession = getSession(server);
Boolean ok;
- CFPropertyListRef value;
+ CFDataRef value;
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Get key from configuration database."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Get key from configuration database."));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
*dataRef = NULL;
*dataLen = 0;
/* un-serialize the key */
- if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
+ if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
*sc_status = kSCStatusFailed;
return KERN_SUCCESS;
}
if (!isA_CFString(key)) {
- CFRelease(key);
*sc_status = kSCStatusInvalidArgument;
+ CFRelease(key);
+ return KERN_SUCCESS;
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ CFRelease(key);
return KERN_SUCCESS;
}
- *sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value);
+ *sc_status = __SCDynamicStoreCopyValue(mySession->store, key, &value, FALSE);
CFRelease(key);
if (*sc_status != kSCStatusOK) {
return KERN_SUCCESS;
}
/* serialize the data */
- ok = _SCSerialize(value, NULL, (void **)dataRef, (CFIndex *)dataLen);
+ ok = _SCSerializeData(value, (void **)dataRef, (CFIndex *)dataLen);
CFRelease(value);
if (!ok) {
*sc_status = kSCStatusFailed;
static void
addSpecificKey(const void *value, void *context)
{
+ CFDataRef data;
CFStringRef key = (CFStringRef)value;
addSpecificRef myContextRef = (addSpecificRef)context;
int sc_status;
- CFPropertyListRef data;
if (!isA_CFString(key)) {
return;
}
- sc_status = __SCDynamicStoreCopyValue(myContextRef->store, key, &data);
+ sc_status = __SCDynamicStoreCopyValue(myContextRef->store, key, &data, TRUE);
if (sc_status == kSCStatusOK) {
CFDictionaryAddValue(myContextRef->dict, key, data);
CFRelease(data);
return;
}
+__private_extern__
+int
+__SCDynamicStoreCopyMultiple(SCDynamicStoreRef store, CFArrayRef keys, CFArrayRef patterns, CFDictionaryRef *values)
+{
+ SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
+ addSpecific myContext;
+
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyMultiple:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" keys = %@"), keys);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" patterns = %@"), patterns);
+ }
+
+ if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+ return kSCStatusNoStoreSession; /* you must have an open session to play */
+ }
+
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace,
+ CFSTR("copy m : %5d : %d keys, %d patterns\n"),
+ storePrivate->server,
+ keys ? CFArrayGetCount(keys) : 0,
+ patterns ? CFArrayGetCount(patterns) : 0);
+ }
+
+ myContext.store = store;
+ myContext.dict = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ if (keys) {
+ CFArrayApplyFunction(keys,
+ CFRangeMake(0, CFArrayGetCount(keys)),
+ addSpecificKey,
+ &myContext);
+ }
+
+ if (patterns) {
+ CFArrayApplyFunction(patterns,
+ CFRangeMake(0, CFArrayGetCount(patterns)),
+ addSpecificPattern,
+ &myContext);
+ }
+
+ /* Return the keys/values associated with the key */
+ *values = myContext.dict;
+
+ if (_configd_verbose) {
+ CFDictionaryRef expDict;
+
+ expDict = _SCUnserializeMultiple(*values);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" values = %@"), expDict);
+ CFRelease(expDict);
+ }
+
+ return kSCStatusOK;
+}
+
+__private_extern__
kern_return_t
_configget_m(mach_port_t server,
xmlData_t keysRef,
mach_msg_type_number_t *dataLen,
int *sc_status)
{
+ CFDictionaryRef dict = NULL; /* keys/values (un-serialized) */
CFArrayRef keys = NULL; /* keys (un-serialized) */
- addSpecific myContext;
serverSessionRef mySession = getSession(server);
Boolean ok;
CFArrayRef patterns = NULL; /* patterns (un-serialized) */
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Get key from configuration database."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Get keys from configuration database."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
*dataRef = NULL;
*dataLen = 0;
if (keysRef && (keysLen > 0)) {
/* un-serialize the keys */
- if (!_SCUnserialize((CFPropertyListRef *)&keys, (void *)keysRef, keysLen)) {
+ if (!_SCUnserialize((CFPropertyListRef *)&keys, NULL, (void *)keysRef, keysLen)) {
*sc_status = kSCStatusFailed;
}
if (patternsRef && (patternsLen > 0)) {
/* un-serialize the patterns */
- if (!_SCUnserialize((CFPropertyListRef *)&patterns, (void *)patternsRef, patternsLen)) {
+ if (!_SCUnserialize((CFPropertyListRef *)&patterns, NULL, (void *)patternsRef, patternsLen)) {
*sc_status = kSCStatusFailed;
}
}
}
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ }
+
if (*sc_status != kSCStatusOK) {
if (keys) CFRelease(keys);
if (patterns) CFRelease(patterns);
return KERN_SUCCESS;
}
- myContext.store = mySession->store;
- myContext.dict = CFDictionaryCreateMutable(NULL,
- 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- if (keys) {
- CFArrayApplyFunction(keys,
- CFRangeMake(0, CFArrayGetCount(keys)),
- addSpecificKey,
- &myContext);
- CFRelease(keys);
- }
-
- if (patterns) {
- CFArrayApplyFunction(patterns,
- CFRangeMake(0, CFArrayGetCount(patterns)),
- addSpecificPattern,
- &myContext);
- CFRelease(patterns);
- }
+ *sc_status = __SCDynamicStoreCopyMultiple(mySession->store, keys, patterns, &dict);
+ if (keys) CFRelease(keys);
+ if (patterns) CFRelease(patterns);
/* serialize the dictionary of matching keys/patterns */
- ok = _SCSerialize(myContext.dict, NULL, (void **)dataRef, (CFIndex *)dataLen);
- CFRelease(myContext.dict);
+ ok = _SCSerialize(dict, NULL, (void **)dataRef, (CFIndex *)dataLen);
+ CFRelease(dict);
if (!ok) {
*sc_status = kSCStatusFailed;
return KERN_SUCCESS;
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
#include "session.h"
+#include "pattern.h"
+
+#define N_QUICK 64
+__private_extern__
int
__SCDynamicStoreCopyKeyList(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex, CFArrayRef *subKeys)
{
- SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
- CFIndex storeCnt;
- const void **storeKeys;
- const void **storeValues;
+ SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
CFMutableArrayRef keyArray;
- int i;
+ regex_t preg;
+ CFIndex storeCnt;
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 (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreCopyKeyList:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, 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 */
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("$"));
- }
-
- /*
- * compile the provided regular expression using the
- * provided isRegex.
- */
- 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;
- }
+ CFStringRef reErrStr;
- reError = regcomp(&preg, regexBuf, REG_EXTENDED);
- if (reError != 0) {
- reErrStrLen = regerror(reError, &preg, reErrBuf, sizeof(reErrBuf));
- storeStr = CFStringCreateWithCString(NULL, reErrBuf, kCFStringEncodingMacRoman);
- CFArrayAppendValue(keyArray, storeStr);
- CFRelease(storeStr);
+ if (!patternCompile(key, &preg, &reErrStr)) {
+ CFArrayAppendValue(keyArray, reErrStr);
+ CFRelease(reErrStr);
*subKeys = CFArrayCreateCopy(NULL, keyArray);
CFRelease(keyArray);
- CFAllocatorDeallocate(NULL, regexBuf);
return kSCStatusFailed;
}
}
if (storeCnt > 0) {
- storeKeys = CFAllocatorAllocate(NULL, storeCnt * sizeof(CFStringRef), 0);
- storeValues = CFAllocatorAllocate(NULL, storeCnt * sizeof(CFStringRef), 0);
+ int i;
+ const void * storeKeys_q[N_QUICK];
+ const void ** storeKeys = storeKeys_q;
+ const void * storeValues_q[N_QUICK];
+ const void ** storeValues = storeValues_q;
+
+ if (storeCnt > (CFIndex)(sizeof(storeKeys_q) / sizeof(CFStringRef))) {
+ storeKeys = CFAllocatorAllocate(NULL, storeCnt * sizeof(CFStringRef), 0);
+ storeValues = CFAllocatorAllocate(NULL, storeCnt * sizeof(CFStringRef), 0);
+ }
+
CFDictionaryGetKeysAndValues(storeData, storeKeys, storeValues);
- for (i=0; i<storeCnt; i++) {
+ for (i = 0; i < storeCnt; i++) {
storeStr = (CFStringRef)storeKeys[i];
storeValue = (CFDictionaryRef)storeValues[i];
if (isRegex) {
* expression specified in the provided key.
*/
- int storeKeyLen = CFStringGetLength(storeStr) + 1;
- char *storeKey = CFAllocatorAllocate(NULL, storeKeyLen, 0);
+ int reError;
+ char storeKey_q[256];
+ char * storeKey = storeKey_q;
+ CFIndex storeKeyLen = CFStringGetLength(storeStr) + 1;
- if (!CFStringGetCString(storeStr,
- storeKey,
- storeKeyLen,
- kCFStringEncodingMacRoman)) {
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString: could not convert store key to C string"));
- CFAllocatorDeallocate(NULL, storeKey);
+ if (storeKeyLen > (CFIndex)sizeof(storeKey_q))
+ storeKey = CFAllocatorAllocate(NULL, storeKeyLen, 0);
+ if (_SC_cfstring_to_cstring(storeStr, storeKey, storeKeyLen, kCFStringEncodingASCII) == NULL) {
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("could not convert store key to C string"));
+ if (storeKey != storeKey_q) CFAllocatorDeallocate(NULL, storeKey);
continue;
}
- reError = regexec(&preg,
- storeKey,
- 0,
- NULL,
- 0);
+ reError = regexec(&preg, storeKey, 0, NULL, 0);
switch (reError) {
case 0 :
/* we've got a match */
case REG_NOMATCH :
/* no match */
break;
- default :
+ default : {
+ char reErrBuf[256];
+ int reErrStrLen;
+
reErrStrLen = regerror(reError,
&preg,
reErrBuf,
sizeof(reErrBuf));
SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
break;
+ }
}
- CFAllocatorDeallocate(NULL, storeKey);
+ if (storeKey != storeKey_q) CFAllocatorDeallocate(NULL, storeKey);
} else {
/*
* only return those keys which are prefixed by the
}
}
}
- CFAllocatorDeallocate(NULL, storeKeys);
- CFAllocatorDeallocate(NULL, storeValues);
+
+ if (storeKeys != storeKeys_q) {
+ CFAllocatorDeallocate(NULL, storeKeys);
+ CFAllocatorDeallocate(NULL, storeValues);
+ }
}
if (isRegex) {
regfree(&preg);
- CFAllocatorDeallocate(NULL, regexBuf);
}
*subKeys = keyArray;
}
+__private_extern__
kern_return_t
_configlist(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
Boolean ok;
CFArrayRef subKeys; /* array of CFStringRef's */
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("List keys in configuration database."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("List keys in configuration database."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
*listRef = NULL;
*listLen = 0;
/* un-serialize the key */
- if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
+ if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
*sc_status = kSCStatusFailed;
return KERN_SUCCESS;
}
if (!isA_CFString(key)) {
- CFRelease(key);
*sc_status = kSCStatusInvalidArgument;
+ CFRelease(key);
+ return KERN_SUCCESS;
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ CFRelease(key);
return KERN_SUCCESS;
}
- *sc_status = __SCDynamicStoreCopyKeyList(mySession->store, key, isRegex, &subKeys);
+ *sc_status = __SCDynamicStoreCopyKeyList(mySession->store, key, isRegex != 0, &subKeys);
CFRelease(key);
if (*sc_status != kSCStatusOK) {
return KERN_SUCCESS;
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "session.h"
+__private_extern__
int
__SCDynamicStoreLock(SCDynamicStoreRef store, Boolean recursive)
{
return kSCStatusAccessError;
}
+ if (!recursive && _configd_trace) {
+ SCTrace(TRUE, _configd_trace, CFSTR("lock : %5d\n"), storePrivate->server);
+ }
+
storeLocked = 1; /* global lock flag */
storePrivate->locked = TRUE; /* per-session lock flag */
*/
if (storeData_s) {
CFRelease(storeData_s);
+ CFRelease(patternData_s);
CFRelease(changedKeys_s);
CFRelease(deferredRemovals_s);
CFRelease(removedSessionKeys_s);
}
storeData_s = CFDictionaryCreateMutableCopy(NULL, 0, storeData);
+ patternData_s = CFDictionaryCreateMutableCopy(NULL, 0, patternData);
changedKeys_s = CFSetCreateMutableCopy(NULL, 0, changedKeys);
deferredRemovals_s = CFSetCreateMutableCopy(NULL, 0, deferredRemovals);
removedSessionKeys_s = CFSetCreateMutableCopy(NULL, 0, removedSessionKeys);
}
+__private_extern__
kern_return_t
_configlock(mach_port_t server, int *sc_status)
{
serverSessionRef mySession = getSession(server);
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Lock configuration database."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Lock configuration database."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ return KERN_SUCCESS;
+ }
*sc_status = __SCDynamicStoreLock(mySession->store, FALSE);
if (*sc_status != kSCStatusOK) {
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
#include "session.h"
+__private_extern__
int
-__SCDynamicStoreNotifyValue(SCDynamicStoreRef store, CFStringRef key)
+__SCDynamicStoreNotifyValue(SCDynamicStoreRef store, CFStringRef key, Boolean internal)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
int sc_status = kSCStatusOK;
CFDictionaryRef dict;
Boolean newValue = FALSE;
- CFPropertyListRef value;
+ CFDataRef value;
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreNotifyValue:"));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreNotifyValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ }
if (!store || (storePrivate->server == MACH_PORT_NULL)) {
return kSCStatusNoStoreSession; /* you must have an open session to play */
}
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace,
+ CFSTR("%s : %5d : %@\n"),
+ internal ? "*notify" : "notify ",
+ storePrivate->server,
+ key);
+ }
+
/*
* 1. Ensure that we hold the lock.
*/
dict = CFDictionaryGetValue(storeData, key);
if (!dict || !CFDictionaryGetValueIfPresent(dict, kSCDData, (const void **)&value)) {
/* key doesn't exist (or data never defined) */
- value = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
+ (void)_SCSerialize(kCFBooleanTrue, &value, NULL, NULL);
newValue = TRUE;
}
/* replace or store initial/temporary existing value */
- __SCDynamicStoreSetValue(store, key, value);
+ __SCDynamicStoreSetValue(store, key, value, TRUE);
if (newValue) {
/* remove the value we just created */
- __SCDynamicStoreRemoveValue(store, key);
+ __SCDynamicStoreRemoveValue(store, key, TRUE);
CFRelease(value);
}
}
+__private_extern__
kern_return_t
_confignotify(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
serverSessionRef mySession = getSession(server);
CFStringRef key; /* key (un-serialized) */
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Notify key in configuration database."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Notify key in configuration database."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
/* un-serialize the key */
- if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
- *sc_status = kSCStatusFailed;
- return KERN_SUCCESS;
- }
+ if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
+ *sc_status = kSCStatusFailed;
+ return KERN_SUCCESS;
+ }
if (!isA_CFString(key)) {
- CFRelease(key);
*sc_status = kSCStatusInvalidArgument;
+ CFRelease(key);
+ return KERN_SUCCESS;
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ CFRelease(key);
return KERN_SUCCESS;
}
- *sc_status = __SCDynamicStoreNotifyValue(mySession->store, key);
+ *sc_status = __SCDynamicStoreNotifyValue(mySession->store, key, FALSE);
CFRelease(key);
return KERN_SUCCESS;
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd_server.h"
#include "session.h"
+__private_extern__
int
__SCDynamicStoreOpen(SCDynamicStoreRef *store, CFStringRef name)
{
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreOpen:"));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" name = %@"), name);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreOpen:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" name = %@"), name);
+ }
/*
* allocate and initialize a new session
*/
- *store = __SCDynamicStoreCreatePrivate(NULL, name, NULL, NULL);
+ *store = (SCDynamicStoreRef)__SCDynamicStoreCreatePrivate(NULL, name, NULL, NULL);
/*
* If necessary, initialize the store and session data dictionaries
*/
if (storeData == NULL) {
+ sessionData = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
storeData = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
- sessionData = CFDictionaryCreateMutable(NULL,
+ patternData = CFDictionaryCreateMutable(NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
}
+__private_extern__
kern_return_t
_configopen(mach_port_t server,
xmlData_t nameRef, /* raw XML bytes */
CFMutableDictionaryRef newInfo;
CFMachPortRef mp;
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Open new session."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Open new session."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
/* un-serialize the name */
- if (!_SCUnserialize((CFPropertyListRef *)&name, (void *)nameRef, nameLen)) {
+ if (!_SCUnserializeString(&name, NULL, (void *)nameRef, nameLen)) {
*sc_status = kSCStatusFailed;
return KERN_SUCCESS;
}
newSession->callerEUID = mySession->callerEUID;
newSession->callerEGID = mySession->callerEGID;
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace, CFSTR("open : %5d : %@\n"), *newServer, name);
+ }
+
*sc_status = __SCDynamicStoreOpen(&newSession->store, name);
/*
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
#include "session.h"
+__private_extern__
int
-__SCDynamicStoreRemoveValue(SCDynamicStoreRef store, CFStringRef key)
+__SCDynamicStoreRemoveValue(SCDynamicStoreRef store, CFStringRef key, Boolean internal)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
int sc_status = kSCStatusOK;
CFMutableDictionaryRef newDict;
CFStringRef sessionKey;
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreRemoveValue:"));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreRemoveValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ }
if (!store || (storePrivate->server == MACH_PORT_NULL)) {
return kSCStatusNoStoreSession; /* you must have an open session to play */
}
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace,
+ CFSTR("%s : %5d : %@\n"),
+ internal ? "*remove" : "remove ",
+ storePrivate->server,
+ key);
+ }
+
/*
* 1. Ensure that we hold the lock.
*/
}
/*
- * 6. Remove data, remove instance, and update/remove
- * the dictionary store entry.
+ * 6. Remove data and update/remove the dictionary store entry.
*/
CFDictionaryRemoveValue(newDict, kSCDData);
- CFDictionaryRemoveValue(newDict, kSCDInstance);
if (CFDictionaryGetCount(newDict) > 0) {
/* this key is still being "watched" */
CFDictionarySetValue(storeData, key, newDict);
}
+__private_extern__
kern_return_t
_configremove(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
serverSessionRef mySession = getSession(server);
CFStringRef key; /* key (un-serialized) */
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Remove key from configuration database."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Remove key from configuration database."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
/* un-serialize the key */
- if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
+ if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
*sc_status = kSCStatusFailed;
return KERN_SUCCESS;
}
if (!isA_CFString(key)) {
- CFRelease(key);
*sc_status = kSCStatusInvalidArgument;
+ CFRelease(key);
+ return KERN_SUCCESS;
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ CFRelease(key);
return KERN_SUCCESS;
}
- *sc_status = __SCDynamicStoreRemoveValue(mySession->store, key);
+ *sc_status = __SCDynamicStoreRemoveValue(mySession->store, key, FALSE);
CFRelease(key);
return KERN_SUCCESS;
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
* - initial revision
*/
+
#include "configd.h"
#include "session.h"
+#include "pattern.h"
+
+__private_extern__
int
-__SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFPropertyListRef value)
+__SCDynamicStoreSetValue(SCDynamicStoreRef store, CFStringRef key, CFDataRef value, Boolean internal)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
int sc_status = kSCStatusOK;
CFStringRef sessionKey;
CFStringRef storeSessionKey;
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreSetValue:"));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" value = %@"), value);
+ if (_configd_verbose) {
+ CFPropertyListRef val;
+
+ (void) _SCUnserialize(&val, value, NULL, NULL);
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreSetValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" value = %@"), val);
+ CFRelease(val);
+ }
if (!store || (storePrivate->server == MACH_PORT_NULL)) {
return kSCStatusNoStoreSession; /* you must have an open session to play */
}
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace,
+ CFSTR("%s : %5d : %@\n"),
+ internal ? "*set " : "set ",
+ storePrivate->server,
+ key);
+ }
+
/*
* 1. Ensure that we hold the lock.
*/
if (CFSetContainsValue(deferredRemovals, key)) {
CFSetRemoveValue(deferredRemovals, key);
} else {
- CFDictionaryApplyFunction(sessionData,
- (CFDictionaryApplierFunction)_addRegexWatchersBySession,
- (void *)key);
+ patternAddKey(key);
}
}
return sc_status;
}
+__private_extern__
kern_return_t
_configset(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
{
serverSessionRef mySession = getSession(server);
CFStringRef key; /* key (un-serialized) */
- CFPropertyListRef data; /* data (un-serialized) */
+ CFDataRef data; /* data (un-serialized) */
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Set key to configuration database."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Set key to configuration database."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
*sc_status = kSCStatusOK;
/* un-serialize the key */
- if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
+ if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
*sc_status = kSCStatusFailed;
- }
-
- if (!isA_CFString(key)) {
+ } else if (!isA_CFString(key)) {
*sc_status = kSCStatusInvalidArgument;
}
/* un-serialize the data */
- if (!_SCUnserialize((CFPropertyListRef *)&data, (void *)dataRef, dataLen)) {
+ if (!_SCUnserializeData(&data, (void *)dataRef, dataLen)) {
*sc_status = kSCStatusFailed;
}
- if (!isA_CFPropertyList(data)) {
- *sc_status = kSCStatusInvalidArgument;
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
}
if (*sc_status != kSCStatusOK) {
return KERN_SUCCESS;
}
- *sc_status = __SCDynamicStoreSetValue(mySession->store, key, data);
+ *sc_status = __SCDynamicStoreSetValue(mySession->store, key, data, FALSE);
*newInstance = 0;
CFRelease(key);
setSpecificKey(const void *key, const void *value, void *context)
{
CFStringRef k = (CFStringRef)key;
- CFPropertyListRef v = (CFPropertyListRef)value;
+ CFDataRef v = (CFDataRef)value;
SCDynamicStoreRef store = (SCDynamicStoreRef)context;
if (!isA_CFString(k)) {
return;
}
- if (!isA_CFPropertyList(v)) {
+ if (!isA_CFData(v)) {
return;
}
- (void) __SCDynamicStoreSetValue(store, k, v);
+ (void) __SCDynamicStoreSetValue(store, k, v, TRUE);
return;
}
return;
}
- (void) __SCDynamicStoreRemoveValue(store, k);
+ (void) __SCDynamicStoreRemoveValue(store, k, TRUE);
return;
}
return;
}
- (void) __SCDynamicStoreNotifyValue(store, k);
+ (void) __SCDynamicStoreNotifyValue(store, k, TRUE);
return;
}
+__private_extern__
+int
+__SCDynamicStoreSetMultiple(SCDynamicStoreRef store, CFDictionaryRef keysToSet, CFArrayRef keysToRemove, CFArrayRef keysToNotify)
+{
+ SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
+ int sc_status = kSCStatusOK;
+
+ if (_configd_verbose) {
+ CFDictionaryRef expDict;
+
+ expDict = keysToSet ? _SCUnserializeMultiple(keysToSet) : NULL;
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreSetMultiple:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" keysToSet = %@"), expDict);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" keysToRemove = %@"), keysToRemove);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" keysToNotify = %@"), keysToNotify);
+ if (expDict) CFRelease(expDict);
+ }
+
+ if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+ return kSCStatusNoStoreSession; /* you must have an open session to play */
+ }
+
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace,
+ CFSTR("set m : %5d : %d set, %d remove, %d notify\n"),
+ storePrivate->server,
+ keysToSet ? CFDictionaryGetCount(keysToSet) : 0,
+ keysToRemove ? CFArrayGetCount (keysToRemove) : 0,
+ keysToNotify ? CFArrayGetCount (keysToNotify) : 0);
+ }
+
+ /*
+ * Ensure that we hold the lock
+ */
+ sc_status = __SCDynamicStoreLock(store, TRUE);
+ if (sc_status != kSCStatusOK) {
+ return sc_status;
+ }
+
+ /*
+ * Set the new/updated keys
+ */
+ if (keysToSet) {
+ CFDictionaryApplyFunction(keysToSet,
+ setSpecificKey,
+ (void *)store);
+ }
+
+ /*
+ * Remove the specified keys
+ */
+ if (keysToRemove) {
+ CFArrayApplyFunction(keysToRemove,
+ CFRangeMake(0, CFArrayGetCount(keysToRemove)),
+ removeSpecificKey,
+ (void *)store);
+ }
+
+ /*
+ * Notify the specified keys
+ */
+ if (keysToNotify) {
+ CFArrayApplyFunction(keysToNotify,
+ CFRangeMake(0, CFArrayGetCount(keysToNotify)),
+ notifySpecificKey,
+ (void *)store);
+ }
+
+ /* Release our lock */
+ __SCDynamicStoreUnlock(store, TRUE);
+
+ return sc_status;
+}
+
+__private_extern__
kern_return_t
_configset_m(mach_port_t server,
xmlData_t dictRef,
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);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Set/remove/notify keys to configuration database."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
*sc_status = kSCStatusOK;
if (dictRef && (dictLen > 0)) {
/* un-serialize the key/value pairs to set */
- if (!_SCUnserialize((CFPropertyListRef *)&dict, (void *)dictRef, dictLen)) {
+ if (!_SCUnserialize((CFPropertyListRef *)&dict, NULL, (void *)dictRef, dictLen)) {
*sc_status = kSCStatusFailed;
- }
-
- if (!isA_CFDictionary(dict)) {
+ } else if (!isA_CFDictionary(dict)) {
*sc_status = kSCStatusInvalidArgument;
}
}
if (removeRef && (removeLen > 0)) {
/* un-serialize the keys to remove */
- if (!_SCUnserialize((CFPropertyListRef *)&remove, (void *)removeRef, removeLen)) {
+ if (!_SCUnserialize((CFPropertyListRef *)&remove, NULL, (void *)removeRef, removeLen)) {
*sc_status = kSCStatusFailed;
- }
-
- if (!isA_CFArray(remove)) {
+ } else if (!isA_CFArray(remove)) {
*sc_status = kSCStatusInvalidArgument;
}
}
if (notifyRef && (notifyLen > 0)) {
/* un-serialize the keys to notify */
- if (!_SCUnserialize((CFPropertyListRef *)¬ify, (void *)notifyRef, notifyLen)) {
+ if (!_SCUnserialize((CFPropertyListRef *)¬ify, NULL, (void *)notifyRef, notifyLen)) {
*sc_status = kSCStatusFailed;
- }
-
- if (!isA_CFArray(notify)) {
+ } else if (!isA_CFArray(notify)) {
*sc_status = kSCStatusInvalidArgument;
}
}
- if (*sc_status != kSCStatusOK) {
- goto done;
+ if (!mySession) {
+ /* you must have an open session to play */
+ *sc_status = kSCStatusNoStoreSession;
}
- /*
- * 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 */
+ *sc_status = __SCDynamicStoreSetMultiple(mySession->store, dict, remove, notify);
done :
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
#include "session.h"
+__private_extern__
int
__SCDynamicStoreTouchValue(SCDynamicStoreRef store, CFStringRef key)
{
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
int sc_status;
- Boolean newValue = FALSE;
- CFPropertyListRef value;
+ CFDataRef value;
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("__SCDynamicStoreTouchValue:"));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" key = %@"), key);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreTouchValue:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ }
if (!store || (storePrivate->server == MACH_PORT_NULL)) {
return kSCStatusNoStoreSession; /* you must have an open session to play */
}
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace, CFSTR("touch : %5d : %@\n"), storePrivate->server, key);
+ }
+
/*
* 1. Ensure that we hold the lock.
*/
/*
* 2. Grab the current (or establish a new) store entry for this key.
*/
- sc_status = __SCDynamicStoreCopyValue(store, key, &value);
+ sc_status = __SCDynamicStoreCopyValue(store, key, &value, TRUE);
switch (sc_status) {
- case kSCStatusNoKey :
+ case kSCStatusNoKey : {
+ CFDateRef now;
+
/* store entry does not exist, create */
- value = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
- newValue = TRUE;
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" new time stamp = %@"), value);
+
+ now = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" new time stamp = %@"), now);
+ (void) _SCSerialize(now, &value, NULL, NULL);
+ CFRelease(now);
break;
+ }
+
+ case kSCStatusOK : {
+ CFDateRef now;
- case kSCStatusOK :
/* store entry exists */
- if (isA_CFDate(value)) {
+
+ (void) _SCUnserialize((CFPropertyListRef *)&now, value, NULL, NULL);
+ if (isA_CFDate(now)) {
/* the value is a CFDate, update the time stamp */
+ CFRelease(now);
CFRelease(value);
- value = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
- newValue = TRUE;
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" new time stamp = %@"), value);
+ now = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" new time stamp = %@"), now);
+ (void) _SCSerialize(now, &value, NULL, NULL);
} /* else, we'll just save the data (again) to bump the instance */
- break;
+ CFRelease(now);
+ break;
+ }
default :
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" __SCDynamicStoreCopyValue(): %s"), SCErrorString(sc_status));
goto done;
}
- sc_status = __SCDynamicStoreSetValue(store, key, value);
-
- if (newValue) {
- CFRelease(value);
- }
+ sc_status = __SCDynamicStoreSetValue(store, key, value, TRUE);
+ CFRelease(value);
done :
}
+__private_extern__
kern_return_t
_configtouch(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
serverSessionRef mySession = getSession(server);
CFStringRef key; /* key (un-serialized) */
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Touch key in configuration database."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Touch key in configuration database."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
/* un-serialize the key */
- if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
+ if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
*sc_status = kSCStatusFailed;
return KERN_SUCCESS;
}
if (!isA_CFString(key)) {
- CFRelease(key);
*sc_status = kSCStatusInvalidArgument;
+ CFRelease(key);
+ return KERN_SUCCESS;
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ CFRelease(key);
return KERN_SUCCESS;
}
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
#include "configd_server.h"
#include "session.h"
+#include "pattern.h"
+
+
+#define N_QUICK 32
static void
_notifyWatchers()
{
CFIndex keyCnt;
- const void **keys;
+ const void * keys_q[N_QUICK];
+ const void ** keys = keys_q;
keyCnt = CFSetGetCount(changedKeys);
if (keyCnt == 0)
return; /* if nothing to do */
- keys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
+ if (keyCnt > (CFIndex)(sizeof(keys_q) / sizeof(CFStringRef)))
+ keys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
+
CFSetGetValues(changedKeys, keys);
+
while (--keyCnt >= 0) {
+ CFArrayRef changes;
CFDictionaryRef dict;
- CFArrayRef sessionsWatchingKey;
- CFIndex watcherCnt;
- const void **watchers;
CFDictionaryRef info;
CFMutableDictionaryRef newInfo;
- CFArrayRef changes;
CFMutableArrayRef newChanges;
+ CFArrayRef sessionsWatchingKey;
+ CFIndex watcherCnt;
+ const void * watchers_q[N_QUICK];
+ const void ** watchers = watchers_q;
dict = CFDictionaryGetValue(storeData, (CFStringRef)keys[keyCnt]);
if ((dict == NULL) || (CFDictionaryContainsKey(dict, kSCDWatchers) == FALSE)) {
*/
sessionsWatchingKey = CFDictionaryGetValue(dict, kSCDWatchers);
watcherCnt = CFArrayGetCount(sessionsWatchingKey);
- if (watcherCnt > 0) {
- watchers = CFAllocatorAllocate(NULL, watcherCnt * sizeof(CFNumberRef), 0);
- CFArrayGetValues(sessionsWatchingKey,
- CFRangeMake(0, CFArrayGetCount(sessionsWatchingKey)),
- watchers);
- while (--watcherCnt >= 0) {
- CFStringRef sessionKey;
-
- sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), watchers[watcherCnt]);
- info = CFDictionaryGetValue(sessionData, sessionKey);
- if (info) {
- newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
- } else {
- newInfo = CFDictionaryCreateMutable(NULL,
- 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- }
-
- changes = CFDictionaryGetValue(newInfo, kSCDChangedKeys);
- if (changes) {
- newChanges = CFArrayCreateMutableCopy(NULL, 0, changes);
- } else {
- newChanges = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
- }
-
- if (CFArrayContainsValue(newChanges,
- CFRangeMake(0, CFArrayGetCount(newChanges)),
- (CFStringRef)keys[keyCnt]) == FALSE) {
- CFArrayAppendValue(newChanges, (CFStringRef)keys[keyCnt]);
- }
- CFDictionarySetValue(newInfo, kSCDChangedKeys, newChanges);
- CFRelease(newChanges);
- CFDictionarySetValue(sessionData, sessionKey, newInfo);
- CFRelease(newInfo);
- CFRelease(sessionKey);
-
- /*
- * flag this session as needing a kick
- */
- if (needsNotification == NULL)
- needsNotification = CFSetCreateMutable(NULL,
- 0,
- &kCFTypeSetCallBacks);
- CFSetAddValue(needsNotification, watchers[watcherCnt]);
+ if (watcherCnt == 0) {
+ /* if no watchers */
+ continue;
+ }
+
+ if (watcherCnt > (CFIndex)(sizeof(watchers_q) / sizeof(CFNumberRef)))
+ watchers = CFAllocatorAllocate(NULL, watcherCnt * sizeof(CFNumberRef), 0);
+
+ CFArrayGetValues(sessionsWatchingKey, CFRangeMake(0, watcherCnt), watchers);
+
+ while (--watcherCnt >= 0) {
+ CFStringRef sessionKey;
+
+ sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@"), watchers[watcherCnt]);
+ info = CFDictionaryGetValue(sessionData, sessionKey);
+ if (info) {
+ newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
+ } else {
+ newInfo = CFDictionaryCreateMutable(NULL,
+ 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
}
- CFAllocatorDeallocate(NULL, watchers);
+
+ changes = CFDictionaryGetValue(newInfo, kSCDChangedKeys);
+ if (changes) {
+ newChanges = CFArrayCreateMutableCopy(NULL, 0, changes);
+ } else {
+ newChanges = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ }
+
+ if (CFArrayContainsValue(newChanges,
+ CFRangeMake(0, CFArrayGetCount(newChanges)),
+ (CFStringRef)keys[keyCnt]) == FALSE) {
+ CFArrayAppendValue(newChanges, (CFStringRef)keys[keyCnt]);
+ }
+ CFDictionarySetValue(newInfo, kSCDChangedKeys, newChanges);
+ CFRelease(newChanges);
+ CFDictionarySetValue(sessionData, sessionKey, newInfo);
+ CFRelease(newInfo);
+ CFRelease(sessionKey);
+
+ /*
+ * flag this session as needing a kick
+ */
+ if (needsNotification == NULL)
+ needsNotification = CFSetCreateMutable(NULL,
+ 0,
+ &kCFTypeSetCallBacks);
+ CFSetAddValue(needsNotification, watchers[watcherCnt]);
}
+
+ if (watchers != watchers_q) CFAllocatorDeallocate(NULL, watchers);
}
- CFAllocatorDeallocate(NULL, keys);
+
+ if (keys != keys_q) CFAllocatorDeallocate(NULL, keys);
/*
* The list of changed keys have been updated for any sessions
_processDeferredRemovals()
{
CFIndex keyCnt;
- const void **keys;
+ const void * keys_q[N_QUICK];
+ const void ** keys = keys_q;
keyCnt = CFSetGetCount(deferredRemovals);
if (keyCnt == 0)
return; /* if nothing to do */
- keys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
+ if (keyCnt > (CFIndex)(sizeof(keys_q) / sizeof(CFStringRef)))
+ keys = CFAllocatorAllocate(NULL, keyCnt * sizeof(CFStringRef), 0);
+
CFSetGetValues(deferredRemovals, keys);
+
while (--keyCnt >= 0) {
- CFDictionaryApplyFunction(sessionData,
- (CFDictionaryApplierFunction)_removeRegexWatchersBySession,
- (void *)keys[keyCnt]);
+ patternRemoveKey((CFStringRef)keys[keyCnt]);
}
- CFAllocatorDeallocate(NULL, keys);
+
+ if (keys != keys_q) CFAllocatorDeallocate(NULL, keys);
/*
* All regex keys associated with removed store dictionary keys have
}
+__private_extern__
int
__SCDynamicStoreUnlock(SCDynamicStoreRef store, Boolean recursive)
{
return kSCStatusOK;
}
+ if (!recursive && _configd_trace) {
+ SCTrace(TRUE, _configd_trace, CFSTR("unlock : %5d\n"), storePrivate->server);
+ }
+
/*
* all of the changes can be committed to the (real) store.
*/
CFDictionaryRemoveAllValues(storeData_s);
+ CFDictionaryRemoveAllValues(patternData_s);
CFSetRemoveAllValues (changedKeys_s);
CFSetRemoveAllValues (deferredRemovals_s);
CFSetRemoveAllValues (removedSessionKeys_s);
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);
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("patterns I'm watching = %@"), storePrivate->patterns);
#endif /* DEBUG */
/*
}
+__private_extern__
kern_return_t
_configunlock(mach_port_t server, int *sc_status)
{
serverSessionRef mySession = getSession(server);
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Unlock configuration database."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Unlock configuration database."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ return KERN_SUCCESS;
+ }
*sc_status = __SCDynamicStoreUnlock(mySession->store, FALSE);
if (*sc_status != kSCStatusOK) {
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
#include "session.h"
+#include "pattern.h"
static __inline__ void
-my_CFDictionaryApplyFunction(CFDictionaryRef theDict,
- CFDictionaryApplierFunction applier,
- void *context)
+my_CFSetApplyFunction(CFSetRef theSet,
+ CFSetApplierFunction applier,
+ void *context)
{
CFAllocatorRef myAllocator;
- CFDictionaryRef myDict;
+ CFSetRef mySet;
- myAllocator = CFGetAllocator(theDict);
- myDict = CFDictionaryCreateCopy(myAllocator, theDict);
- CFDictionaryApplyFunction(myDict, applier, context);
- CFRelease(myDict);
+ myAllocator = CFGetAllocator(theSet);
+ mySet = CFSetCreateCopy(myAllocator, theSet);
+ CFSetApplyFunction(mySet, applier, context);
+ CFRelease(mySet);
return;
}
+__private_extern__
int
-__SCDynamicStoreAddWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex)
+__SCDynamicStoreAddWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex, Boolean internal)
{
- SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
+ int sc_status = kSCStatusOK;
+ CFNumberRef sessionNum = NULL;
+ SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
- 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 (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreAddWatchedKey:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, 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 */
}
- /*
- * add new key after checking if key has already been defined
- */
- 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(storePrivate->keys, key))
- return kSCStatusKeyExists; /* sorry, key already exists in notifier list */
- CFSetAddValue(storePrivate->keys, key); /* add key to this sessions notifier list */
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace,
+ CFSTR("%s : %5d : %s : %@\n"),
+ internal ? "*watch+" : "watch+ ",
+ storePrivate->server,
+ isRegex ? "pattern" : "key",
+ key);
}
- if (isRegex) {
- CFStringRef sessionKey;
- int regexStrLen;
- char *regexStr;
- CFMutableDataRef regexData;
- int reError;
- char reErrBuf[256];
- int reErrStrLen;
- addContext context;
- CFDictionaryRef info;
- CFMutableDictionaryRef newInfo;
- CFArrayRef rKeys;
- CFMutableArrayRef newRKeys;
- CFArrayRef rData;
- CFMutableArrayRef newRData;
-
- /*
- * We are adding a regex key. As such, we need to flag
- * any keys currently in the store.
- */
-
- /* 1. Extract a C String version of the key pattern string. */
-
- regexStrLen = CFStringGetLength(key) + 1;
- regexStr = CFAllocatorAllocate(NULL, regexStrLen, 0);
- if (!CFStringGetCString(key,
- regexStr,
- regexStrLen,
- kCFStringEncodingMacRoman)) {
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("CFStringGetCString: could not convert regex key to C string"));
- CFAllocatorDeallocate(NULL, regexStr);
- return kSCStatusFailed;
- }
+ sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
- /* 2. Compile the regular expression from the pattern string. */
-
- regexData = CFDataCreateMutable(NULL, sizeof(regex_t));
- CFDataSetLength(regexData, sizeof(regex_t));
- reError = regcomp((regex_t *)CFDataGetBytePtr(regexData),
- regexStr,
- REG_EXTENDED);
- CFAllocatorDeallocate(NULL, regexStr);
- if (reError != 0) {
- reErrStrLen = regerror(reError,
- (regex_t *)CFDataGetBytePtr(regexData),
- reErrBuf,
- sizeof(reErrBuf));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regcomp() key: %s"), reErrBuf);
- CFRelease(regexData);
- return kSCStatusFailed;
+ if (isRegex) {
+ if (CFSetContainsValue(storePrivate->patterns, key)) {
+ /* sorry, pattern already exists in notifier list */
+ sc_status = kSCStatusKeyExists;
+ goto done;
}
/*
- * 3. Iterate over the current keys and add this session as a "watcher"
- * for any key already defined in the store.
- */
-
- 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.
+ * add this session as a pattern watcher
*/
- sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
-
- info = CFDictionaryGetValue(sessionData, sessionKey);
- if (info) {
- newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
- } else {
- newInfo = CFDictionaryCreateMutable(NULL,
- 0,
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
+ if (!patternAddSession(key, sessionNum)) {
+ sc_status = kSCStatusInvalidArgument;
+ goto done;
}
- rKeys = CFDictionaryGetValue(newInfo, kSCDRegexKeys);
- if ((rKeys == NULL) ||
- (CFArrayContainsValue(rKeys,
- CFRangeMake(0, CFArrayGetCount(rKeys)),
- key) == FALSE)) {
- rData = CFDictionaryGetValue(newInfo, kSCDRegexData);
- if (rKeys) {
- newRKeys = CFArrayCreateMutableCopy(NULL, 0, rKeys);
- newRData = CFArrayCreateMutableCopy(NULL, 0, rData);
- } else {
- newRKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
- newRData = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
- }
-
- /* save the regex key */
- CFArrayAppendValue(newRKeys, key);
- CFDictionarySetValue(newInfo, kSCDRegexKeys, newRKeys);
- CFRelease(newRKeys);
- /* ...and the compiled expression */
- CFArrayAppendValue(newRData, regexData);
- CFDictionarySetValue(newInfo, kSCDRegexData, newRData);
- CFRelease(newRData);
- CFDictionarySetValue(sessionData, sessionKey, newInfo);
- }
- CFRelease(regexData);
- CFRelease(newInfo);
- CFRelease(sessionKey);
+ /* add pattern to this sessions notifier list */
+ CFSetAddValue(storePrivate->patterns, key);
} else {
- CFNumberRef sessionNum;
+ if (CFSetContainsValue(storePrivate->keys, key)) {
+ /* sorry, key already exists in notifier list */
+ sc_status = kSCStatusKeyExists;
+ goto done;
+ }
/*
* We are watching a specific key. As such, update the
* store to mark our interest in any changes.
*/
- sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
_addWatcher(sessionNum, key);
- CFRelease(sessionNum);
+
+ /* add key to this sessions notifier list */
+ CFSetAddValue(storePrivate->keys, key);
}
- return kSCStatusOK;
+ done :
+
+ if (sessionNum) CFRelease(sessionNum);
+ return sc_status;
}
+__private_extern__
kern_return_t
_notifyadd(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
serverSessionRef mySession = getSession(server);
CFStringRef key; /* key (un-serialized) */
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Add notification key for this session."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Add notification key for this session."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
/* un-serialize the key */
- if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
+ if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
*sc_status = kSCStatusFailed;
return KERN_SUCCESS;
}
if (!isA_CFString(key)) {
- CFRelease(key);
*sc_status = kSCStatusInvalidArgument;
+ CFRelease(key);
+ return KERN_SUCCESS;
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ CFRelease(key);
return KERN_SUCCESS;
}
- *sc_status = __SCDynamicStoreAddWatchedKey(mySession->store, key, isRegex);
+ *sc_status = __SCDynamicStoreAddWatchedKey(mySession->store, key, isRegex != 0, FALSE);
CFRelease(key);
return KERN_SUCCESS;
}
+
+
+/*
+ * "context" argument for removeOldKey() and addNewKey()
+ */
+typedef struct {
+ SCDynamicStoreRef store;
+ CFSetRef oldKeys; /* for addNewKey */
+ CFArrayRef newKeys; /* for removeOldKey */
+ Boolean isRegex;
+ int sc_status;
+} updateKeysContext, *updateKeysContextRef;
+
+
+static void
+removeOldKey(const void *value, void *context)
+{
+ CFStringRef oldKey = (CFStringRef)value;
+ updateKeysContextRef myContextRef = (updateKeysContextRef)context;
+
+ if (myContextRef->sc_status != kSCStatusOK) {
+ return;
+ }
+
+ if (!myContextRef->newKeys ||
+ !CFArrayContainsValue(myContextRef->newKeys,
+ CFRangeMake(0, CFArrayGetCount(myContextRef->newKeys)),
+ oldKey)) {
+ /* the old notification key is not being retained, remove it */
+ myContextRef->sc_status = __SCDynamicStoreRemoveWatchedKey(myContextRef->store,
+ oldKey,
+ myContextRef->isRegex,
+ TRUE);
+ }
+
+ return;
+}
+
+
+static void
+addNewKey(const void *value, void *context)
+{
+ CFStringRef newKey = (CFStringRef)value;
+ updateKeysContextRef myContextRef = (updateKeysContextRef)context;
+
+ if (myContextRef->sc_status != kSCStatusOK) {
+ return;
+ }
+
+ if (!myContextRef->oldKeys ||
+ !CFSetContainsValue(myContextRef->oldKeys, newKey)) {
+ /* if this is a new notification key */
+ myContextRef->sc_status = __SCDynamicStoreAddWatchedKey(myContextRef->store,
+ newKey,
+ myContextRef->isRegex,
+ TRUE);
+ }
+
+ return;
+}
+
+
+__private_extern__
+int
+__SCDynamicStoreSetNotificationKeys(SCDynamicStoreRef store, CFArrayRef keys, CFArrayRef patterns)
+{
+ updateKeysContext myContext;
+ SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
+
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreSetNotificationKeys:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" keys = %@"), keys);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" patterns = %@"), patterns);
+ }
+
+ if (!store || (storePrivate->server == MACH_PORT_NULL)) {
+ return kSCStatusNoStoreSession; /* you must have an open session to play */
+ }
+
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace,
+ CFSTR("watch : %5d : %d keys, %d patterns\n"),
+ storePrivate->server,
+ keys ? CFArrayGetCount(keys) : 0,
+ patterns ? CFArrayGetCount(patterns) : 0);
+ }
+
+ myContext.store = store;
+ myContext.sc_status = kSCStatusOK;
+
+ /* remove any previously registered keys, register any new keys */
+ myContext.oldKeys = CFSetCreateCopy(NULL, storePrivate->keys);
+ myContext.newKeys = keys;
+ myContext.isRegex = FALSE;
+ my_CFSetApplyFunction(storePrivate->keys, removeOldKey, &myContext);
+ if (keys) {
+ CFArrayApplyFunction(keys,
+ CFRangeMake(0, CFArrayGetCount(keys)),
+ addNewKey,
+ &myContext);
+ }
+ CFRelease(myContext.oldKeys);
+
+ /* remove any previously registered patterns, register any new patterns */
+ myContext.oldKeys = CFSetCreateCopy(NULL, storePrivate->patterns);
+ myContext.newKeys = patterns;
+ myContext.isRegex = TRUE;
+ my_CFSetApplyFunction(storePrivate->patterns, removeOldKey, &myContext);
+ if (patterns) {
+ CFArrayApplyFunction(patterns,
+ CFRangeMake(0, CFArrayGetCount(patterns)),
+ addNewKey,
+ &myContext);
+ }
+ CFRelease(myContext.oldKeys);
+
+ return myContext.sc_status;
+}
+
+
+__private_extern__
+kern_return_t
+_notifyset(mach_port_t server,
+ xmlData_t keysRef, /* raw XML bytes */
+ mach_msg_type_number_t keysLen,
+ xmlData_t patternsRef, /* raw XML bytes */
+ mach_msg_type_number_t patternsLen,
+ int *sc_status
+)
+{
+ serverSessionRef mySession = getSession(server);
+ CFArrayRef keys = NULL; /* key (un-serialized) */
+ CFArrayRef patterns = NULL; /* patterns (un-serialized) */
+
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Add notification key for this session."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
+
+ *sc_status = kSCStatusOK;
+
+ if (keysRef && (keysLen > 0)) {
+ /* un-serialize the keys */
+ if (!_SCUnserialize((CFPropertyListRef *)&keys, NULL, (void *)keysRef, keysLen)) {
+ *sc_status = kSCStatusFailed;
+ } else if (!isA_CFArray(keys)) {
+ *sc_status = kSCStatusInvalidArgument;
+ }
+ }
+
+ if (patternsRef && (patternsLen > 0)) {
+ /* un-serialize the patterns */
+ if (!_SCUnserialize((CFPropertyListRef *)&patterns, NULL, (void *)patternsRef, patternsLen)) {
+ *sc_status = kSCStatusFailed;
+ } else if (!isA_CFArray(patterns)) {
+ *sc_status = kSCStatusInvalidArgument;
+ }
+ }
+
+ if (!mySession) {
+ /* you must have an open session to play */
+ *sc_status = kSCStatusNoStoreSession;
+ }
+
+ if (*sc_status == kSCStatusOK) {
+ *sc_status = __SCDynamicStoreSetNotificationKeys(mySession->store, keys, patterns);
+ }
+
+ if (keys) CFRelease(keys);
+ if (patterns) CFRelease(patterns);
+
+ return KERN_SUCCESS;
+}
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "session.h"
+__private_extern__
int
__SCDynamicStoreNotifyCancel(SCDynamicStoreRef store)
{
}
+__private_extern__
kern_return_t
_notifycancel(mach_port_t server,
int *sc_status)
{
serverSessionRef mySession = getSession(server);
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Cancel requested notifications."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Cancel requested notifications."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ return KERN_SUCCESS;
+ }
*sc_status = __SCDynamicStoreNotifyCancel(mySession->store);
if (*sc_status != kSCStatusOK) {
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
#include "session.h"
+__private_extern__
int
__SCDynamicStoreCopyNotifiedKeys(SCDynamicStoreRef store, CFArrayRef *notifierKeys)
{
}
+__private_extern__
kern_return_t
_notifychanges(mach_port_t server,
xmlDataOut_t *listRef, /* raw XML bytes */
CFArrayRef notifierKeys; /* array of CFStringRef's */
Boolean ok;
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("List notification keys which have changed."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("List notification keys which have changed."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
*listRef = NULL;
*listLen = 0;
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ return KERN_SUCCESS;
+ }
+
*sc_status = __SCDynamicStoreCopyNotifiedKeys(mySession->store, ¬ifierKeys);
if (*sc_status != kSCStatusOK) {
return KERN_SUCCESS;
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
* - initial revision
*/
+
#include "configd.h"
#include "session.h"
+#include "pattern.h"
-static __inline__ void
-my_CFDictionaryApplyFunction(CFDictionaryRef theDict,
- CFDictionaryApplierFunction applier,
- void *context)
-{
- CFAllocatorRef myAllocator;
- CFDictionaryRef myDict;
-
- myAllocator = CFGetAllocator(theDict);
- myDict = CFDictionaryCreateCopy(myAllocator, theDict);
- CFDictionaryApplyFunction(myDict, applier, context);
- CFRelease(myDict);
- return;
-}
-
-
+__private_extern__
int
-__SCDynamicStoreRemoveWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex)
+__SCDynamicStoreRemoveWatchedKey(SCDynamicStoreRef store, CFStringRef key, Boolean isRegex, Boolean internal)
{
+ CFNumberRef sessionNum;
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
- 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 (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("__SCDynamicStoreRemoveWatchedKey:"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" key = %@"), key);
+ SCLog(TRUE, 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 */
}
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace,
+ CFSTR("%s : %5d : %s : %@\n"),
+ internal ? "*watch-" : "watch- ",
+ storePrivate->server,
+ isRegex ? "pattern" : "key",
+ key);
+ }
+
/*
* remove key from this sessions notifier list after checking that
* it was previously defined.
*/
if (isRegex) {
- if (!CFSetContainsValue(storePrivate->reKeys, key))
+ if (!CFSetContainsValue(storePrivate->patterns, key))
return kSCStatusNoKey; /* sorry, key does not exist in notifier list */
- CFSetRemoveValue(storePrivate->reKeys, key); /* remove key from this sessions notifier list */
+
+ /* remove key from this sessions notifier list */
+ CFSetRemoveValue(storePrivate->patterns, key);
+
+ /* remove this session as a pattern watcher */
+ sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
+ patternRemoveSession(key, sessionNum);
+ CFRelease(sessionNum);
} else {
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 (isRegex) {
- CFStringRef sessionKey;
- CFDictionaryRef info;
- CFMutableDictionaryRef newInfo;
- CFArrayRef rKeys;
- CFMutableArrayRef newRKeys;
- CFArrayRef rData;
- CFMutableArrayRef newRData;
- CFIndex i;
- CFDataRef regexData;
- removeContext context;
-
- sessionKey = CFStringCreateWithFormat(NULL, NULL, CFSTR("%d"), storePrivate->server);
-
- info = CFDictionaryGetValue(sessionData, sessionKey);
- newInfo = CFDictionaryCreateMutableCopy(NULL, 0, info);
-
- rKeys = CFDictionaryGetValue(newInfo, kSCDRegexKeys);
- newRKeys = CFArrayCreateMutableCopy(NULL, 0, rKeys);
-
- rData = CFDictionaryGetValue(newInfo, kSCDRegexData);
- newRData = CFArrayCreateMutableCopy(NULL, 0, rData);
-
- i = CFArrayGetFirstIndexOfValue(newRKeys,
- CFRangeMake(0, CFArrayGetCount(newRData)),
- key);
- regexData = CFArrayGetValueAtIndex(newRData, i);
-
- context.store = storePrivate;
- context.preg = (regex_t *)CFDataGetBytePtr(regexData);
- my_CFDictionaryApplyFunction(storeData,
- (CFDictionaryApplierFunction)_removeRegexWatcherByKey,
- &context);
-
- /* remove the regex key */
- CFArrayRemoveValueAtIndex(newRKeys, i);
- if (CFArrayGetCount(newRKeys) > 0) {
- CFDictionarySetValue(newInfo, kSCDRegexKeys, newRKeys);
- } else {
- CFDictionaryRemoveValue(newInfo, kSCDRegexKeys);
- }
- CFRelease(newRKeys);
-
- /* ...and the compiled expression */
- regfree((regex_t *)CFDataGetBytePtr(regexData));
- CFArrayRemoveValueAtIndex(newRData, i);
- if (CFArrayGetCount(newRData) > 0) {
- CFDictionarySetValue(newInfo, kSCDRegexData, newRData);
- } else {
- CFDictionaryRemoveValue(newInfo, kSCDRegexData);
- }
- CFRelease(newRData);
-
- /* save the updated session data */
- CFDictionarySetValue(sessionData, sessionKey, newInfo);
- CFRelease(newInfo);
-
- CFRelease(sessionKey);
- } else {
- CFNumberRef sessionNum;
+ /* remove key from this sessions notifier list */
+ CFSetRemoveValue(storePrivate->keys, key);
/*
* We are watching a specific key. As such, update the
* store to mark our interest in any changes.
*/
-
sessionNum = CFNumberCreate(NULL, kCFNumberIntType, &storePrivate->server);
_removeWatcher(sessionNum, key);
CFRelease(sessionNum);
}
+__private_extern__
kern_return_t
_notifyremove(mach_port_t server,
xmlData_t keyRef, /* raw XML bytes */
serverSessionRef mySession = getSession(server);
CFStringRef key; /* key (un-serialized) */
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Remove notification key for this session."));
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" server = %d"), server);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Remove notification key for this session."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ }
/* un-serialize the key */
- if (!_SCUnserialize((CFPropertyListRef *)&key, (void *)keyRef, keyLen)) {
+ if (!_SCUnserializeString(&key, NULL, (void *)keyRef, keyLen)) {
*sc_status = kSCStatusFailed;
return KERN_SUCCESS;
}
if (!isA_CFString(key)) {
- CFRelease(key);
*sc_status = kSCStatusInvalidArgument;
+ CFRelease(key);
+ return KERN_SUCCESS;
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ CFRelease(key);
return KERN_SUCCESS;
}
- *sc_status = __SCDynamicStoreRemoveWatchedKey(mySession->store, key, isRegex);
+ *sc_status = __SCDynamicStoreRemoveWatchedKey(mySession->store,
+ key,
+ isRegex != 0,
+ FALSE);
CFRelease(key);
return KERN_SUCCESS;
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "session.h"
+__private_extern__
int
__SCDynamicStoreNotifyFileDescriptor(SCDynamicStoreRef store,
int32_t identifier,
}
+__private_extern__
kern_return_t
_notifyviafd(mach_port_t server,
xmlData_t pathRef,
int bufSiz = sizeof(storePrivate->notifyFileIdentifier);
int nbioYes = 1;
- 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 (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Send message via UNIX domain socket when a notification key changes."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" path = %s"), pathRef);
+ }
/*
* if socket currently open, close it!
/* non-fatal???, proceed */
}
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ return KERN_SUCCESS;
+ }
+
/* do common sanity checks, get socket */
*sc_status = __SCDynamicStoreNotifyFileDescriptor(mySession->store, identifier, &sock);
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd.h"
#include "session.h"
+__private_extern__
int
__SCDynamicStoreNotifyMachPort(SCDynamicStoreRef store,
mach_msg_id_t identifier,
}
+__private_extern__
kern_return_t
_notifyviaport(mach_port_t server,
mach_port_t port,
serverSessionRef mySession = getSession(server);
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)mySession->store;
- 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 (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Send mach message when a notification key changes."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" port = %d"), port);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" message id = %d"), identifier);
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ return KERN_SUCCESS;
+ }
if (storePrivate->notifyPort != MACH_PORT_NULL) {
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" destroying old callback mach port %d"), storePrivate->notifyPort);
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "configd_server.h"
#include "session.h"
+__private_extern__
int
__SCDynamicStoreNotifySignal(SCDynamicStoreRef store, pid_t pid, int sig)
{
}
+__private_extern__
kern_return_t
_notifyviasignal(mach_port_t server,
task_t task,
mach_port_t oldNotify;
#endif /* NOTYET */
- 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);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("Send signal when a notification key changes."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" server = %d"), server);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" task = %d"), task);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" signal = %d"), sig);
+ }
status = pid_for_task(task, &pid);
if (status != KERN_SUCCESS) {
- /* could not determine pid for task */
- *sc_status = kSCStatusFailed;
+ *sc_status = kSCStatusFailed; /* could not determine pid for task */
+ return KERN_SUCCESS;
+ }
+
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
return KERN_SUCCESS;
}
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#define SNAPSHOT_PATH_STORE _PATH_VARTMP "configd-store.xml"
+#define SNAPSHOT_PATH_PATTERN _PATH_VARTMP "configd-pattern.xml"
#define SNAPSHOT_PATH_SESSION _PATH_VARTMP "configd-session.xml"
+#define N_QUICK 100
+
+static CFDictionaryRef
+_expandStore(CFDictionaryRef storeData)
+{
+ const void * keys_q[N_QUICK];
+ const void ** keys = keys_q;
+ CFIndex nElements;
+ CFDictionaryRef newStoreData = NULL;
+ const void * nValues_q[N_QUICK];
+ const void ** nValues = nValues_q;
+ const void * oValues_q[N_QUICK];
+ const void ** oValues = oValues_q;
+
+ nElements = CFDictionaryGetCount(storeData);
+ if (nElements > 0) {
+ CFIndex i;
+
+ if (nElements > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
+ keys = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ oValues = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ nValues = CFAllocatorAllocate(NULL, nElements * sizeof(CFTypeRef), 0);
+ }
+ bzero(nValues, nElements * sizeof(CFTypeRef));
+
+ CFDictionaryGetKeysAndValues(storeData, keys, oValues);
+ for (i = 0; i < nElements; i++) {
+ CFDataRef data;
+
+ data = CFDictionaryGetValue(oValues[i], kSCDData);
+ if (data) {
+ CFPropertyListRef plist;
+
+ if (!_SCUnserialize(&plist, data, NULL, NULL)) {
+ goto done;
+ }
+
+ nValues[i] = CFDictionaryCreateMutableCopy(NULL, 0, oValues[i]);
+ CFDictionarySetValue((CFMutableDictionaryRef)nValues[i],
+ kSCDData,
+ plist);
+ CFRelease(plist);
+ } else {
+ nValues[i] = CFRetain(oValues[i]);
+ }
+ }
+ }
+
+ newStoreData = CFDictionaryCreate(NULL,
+ keys,
+ nValues,
+ nElements,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ done :
+
+ if (nElements > 0) {
+ CFIndex i;
+
+ for (i = 0; i < nElements; i++) {
+ if (nValues[i]) CFRelease(nValues[i]);
+ }
+
+ if (keys != keys_q) {
+ CFAllocatorDeallocate(NULL, keys);
+ CFAllocatorDeallocate(NULL, oValues);
+ CFAllocatorDeallocate(NULL, nValues);
+ }
+ }
+
+ return newStoreData;
+}
+
+
+__private_extern__
int
__SCDynamicStoreSnapshot(SCDynamicStoreRef store)
{
+ CFDictionaryRef expandedStoreData;
int fd;
serverSessionRef mySession;
SCDynamicStorePrivateRef storePrivate = (SCDynamicStorePrivateRef)store;
return kSCStatusFailed;
}
- xmlData = CFPropertyListCreateXMLData(NULL, storeData);
+ expandedStoreData = _expandStore(storeData);
+ xmlData = CFPropertyListCreateXMLData(NULL, expandedStoreData);
+ CFRelease(expandedStoreData);
+ if (!xmlData) {
+ SCLog(TRUE, LOG_ERR, CFSTR("CFPropertyListCreateXMLData() failed"));
+ close(fd);
+ return kSCStatusFailed;
+ }
+ (void) write(fd, CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData));
+ (void) close(fd);
+ CFRelease(xmlData);
+
+ /* Save a snapshot of the "pattern" data */
+
+ (void) unlink(SNAPSHOT_PATH_PATTERN);
+ fd = open(SNAPSHOT_PATH_PATTERN, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ if (fd < 0) {
+ return kSCStatusFailed;
+ }
+
+ xmlData = CFPropertyListCreateXMLData(NULL, patternData);
if (!xmlData) {
SCLog(TRUE, LOG_ERR, CFSTR("CFPropertyListCreateXMLData() failed"));
close(fd);
return kSCStatusFailed;
}
- /* Save a snapshot of the "session" data */
-
xmlData = CFPropertyListCreateXMLData(NULL, sessionData);
if (!xmlData) {
SCLog(TRUE, LOG_ERR, CFSTR("CFPropertyListCreateXMLData() failed"));
}
+__private_extern__
kern_return_t
_snapshot(mach_port_t server, int *sc_status)
{
SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Snapshot configuration database."));
+ if (!mySession) {
+ *sc_status = kSCStatusNoStoreSession; /* you must have an open session to play */
+ return KERN_SUCCESS;
+ }
+
*sc_status = __SCDynamicStoreSnapshot(mySession->store);
if (*sc_status != kSCStatusOK) {
SCLog(_configd_verbose, LOG_DEBUG, CFSTR(" __SCDynamicStoreSnapshot(): %s"), SCErrorString(*sc_status));
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
/*
* Import the real "config.defs" file from the framework.
*
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "config_types.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 FILE *_configd_trace; /* non-NULL if tracing enabled */
extern CFMutableSetRef _plugins_exclude; /* bundle identifiers to exclude from loading */
extern CFMutableSetRef _plugins_verbose; /* bundle identifiers to enable verbose logging */
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
* - created
*/
+#include <getopt.h>
#include <stdio.h>
#include <sysexits.h>
#include <syslog.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 */
+
+__private_extern__
+FILE *_configd_trace = NULL; /* non-NULL if tracing enabled */
+
+__private_extern__
CFMutableSetRef _plugins_exclude = NULL; /* bundle identifiers to exclude from loading */
+
+__private_extern__
CFMutableSetRef _plugins_verbose = NULL; /* bundle identifiers to enable verbose logging */
-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" ,
- "XCPU", "XFSZ", "VTALRM", "PROF", "WINCH", "INFO", "USR1", "USR2"
+static CFMachPortRef termRequested = NULL; /* Mach port used to notify runloop of a shutdown request */
+
+
+static struct option longopts[] = {
+// { "no-bundles", no_argument, 0, 'b' },
+// { "exclude-plugin", required_argument, 0, 'B' },
+// { "no-fork", no_argument, 0, 'd' },
+// { "test-bundle", required_argument, 0, 't' },
+// { "verbose", no_argument, 0, 'v' },
+// { "verbose-bundle", required_argument, 0, 'V' },
+ { "help", no_argument, 0, '?' },
+ { 0, 0, 0, 0 }
};
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);
+ SCPrint(TRUE, stderr, CFSTR("\t\t (Note: only the plug-in will be started)\n"));
exit (EX_USAGE);
}
static void
catcher(int signum)
{
- /*
- * log the signal
- *
- * Note: we can't use SCLog() since the signal may be received while the
- * logging thread lock is held.
- */
- if (_configd_verbose) {
- syslog (LOG_INFO, "caught SIG%s" , signames[signum]);
- } else {
- fprintf(stderr, "caught SIG%s\n", signames[signum]);
- fflush (stderr);
+ switch (signum) {
+ case SIGTERM :
+ if (termRequested) {
+ mach_msg_empty_send_t msg;
+ mach_msg_option_t options;
+ kern_return_t status;
+
+ /*
+ * send message to indicate that a request has been made
+ * for the daemon to be shutdown.
+ */
+ msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
+ msg.header.msgh_size = sizeof(msg);
+ msg.header.msgh_remote_port = CFMachPortGetPort(termRequested);
+ msg.header.msgh_local_port = MACH_PORT_NULL;
+ msg.header.msgh_id = 0;
+ options = MACH_SEND_TIMEOUT;
+ status = mach_msg(&msg.header, /* msg */
+ MACH_SEND_MSG|options, /* options */
+ msg.header.msgh_size, /* send_size */
+ 0, /* rcv_size */
+ MACH_PORT_NULL, /* rcv_name */
+ 0, /* timeout */
+ MACH_PORT_NULL); /* notify */
+ }
+ break;
}
return;
}
+
+static void
+term(CFMachPortRef port, void *msg, CFIndex size, void *info)
+{
+ server_shutdown();
+}
+
+
static void
parent_exit(int i)
{
_exit (0);
}
+
+static void
+init_fds()
+{
+ int fd;
+ int i;
+
+ /* close any open FDs */
+ for (i = getdtablesize()-1; i>=0; i--) close(i);
+
+ /* set stdin, stdout, stderr */
+ fd = open(_PATH_DEVNULL, O_RDWR, 0);
+ if (fd != -1) {
+ int ofd;
+
+ // stdin
+ (void) dup2(fd, STDIN_FILENO);
+
+ // stdout, stderr
+ ofd = open("/var/log/configd.log", O_WRONLY|O_APPEND, 0);
+ if (ofd != -1) {
+ if (fd > STDIN_FILENO) {
+ (void) close(fd);
+ }
+ fd = ofd;
+ }
+ (void) dup2(fd, STDOUT_FILENO);
+ (void) dup2(fd, STDERR_FILENO);
+ if (fd > STDERR_FILENO) {
+ (void) close(fd);
+ }
+ }
+
+ return;
+}
+
+
+static void
+set_trace()
+{
+ int fd;
+
+ /* set _configd_trace */
+ fd = open("/var/log/configd.trace", O_WRONLY|O_APPEND, 0);
+ if (fd != -1) {
+ _configd_trace = fdopen(fd, "a");
+ }
+
+ return;
+}
+
+
static int
fork_child()
{
int child_pid;
- int fd;
signal(SIGTERM, parent_exit);
child_pid = fork();
(void) chdir("/");
- fd = open(_PATH_DEVNULL, O_RDWR, 0);
- if (fd != -1) {
- int ofd;
-
- // stdin
- (void) dup2(fd, STDIN_FILENO);
-
- // stdout, stderr
- ofd = open("/var/log/configd.log", O_WRONLY|O_APPEND, 0);
- if (ofd != -1) {
- if (fd > STDIN_FILENO) {
- (void) close(fd);
- }
- fd = ofd;
- }
- (void) dup2(fd, STDOUT_FILENO);
- (void) dup2(fd, STDERR_FILENO);
- if (fd > STDERR_FILENO) {
- (void) close(fd);
- }
- }
-
return 0;
}
int
main(int argc, char * const argv[])
{
- Boolean loadBundles = TRUE;
+ Boolean enableRestart = (argc <= 1); /* only if there are no arguments */
+ Boolean forceForeground = FALSE;
+ Boolean loadBundles = TRUE;
struct sigaction nact;
int opt;
extern int optind;
- const char *prog = argv[0];
+ const char *prog = argv[0];
+ mach_port_t service_port = MACH_PORT_NULL;
CFStringRef str;
- const char *testBundle = NULL;
+ const char *testBundle = NULL;
_plugins_exclude = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
_plugins_verbose = CFSetCreateMutable(NULL, 0, &kCFTypeSetCallBacks);
/* process any arguments */
- while ((opt = getopt(argc, argv, "bB:dt:vV:")) != -1) {
+ while ((opt = getopt_long(argc, argv, "bB:dt:vV:", longopts, NULL)) != -1) {
switch(opt) {
case 'b':
loadBundles = FALSE;
CFRelease(str);
break;
case 'd':
- _configd_fork = FALSE;
+ forceForeground = TRUE;
break;
case 't':
testBundle = optarg;
if (strcmp(optarg, "com.apple.SystemConfiguration") == 0) {
_sc_verbose = TRUE;
} else {
- str = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingMacRoman);
- CFSetSetValue(_plugins_verbose, str);
- CFRelease(str);
+ str = CFStringCreateWithCString(NULL, optarg, kCFStringEncodingMacRoman);
+ CFSetSetValue(_plugins_verbose, str);
+ CFRelease(str);
}
break;
case '?':
/*
* display an error if configd is already running and we are
- * not executing/testing a bundle.
+ * not solely executing/testing a bundle.
*/
- if ((testBundle == NULL) && (server_active() == TRUE)) {
- exit (EX_UNAVAILABLE);
+ if (testBundle == NULL) {
+ if (server_active(&service_port)) {
+ exit (EX_UNAVAILABLE);
+ }
}
/* check credentials */
exit (EX_NOPERM);
}
- if (_configd_fork) {
+ if (!forceForeground && (service_port == MACH_PORT_NULL)) {
+ /*
+ * if we haven't been asked to run in the foreground
+ * and have not been started by mach_init (i.e. we're
+ * not already running as a Foreground process) then
+ * daemonize ourself.
+ */
if (fork_child() == -1) {
fprintf(stderr, "configd: fork() failed, %s\n", strerror(errno));
exit (1);
}
- /* now the child process, parent waits in fork_child */
- }
- /* record process id */
- if (testBundle == NULL) {
- writepid();
+ /*
+ * Note: we are now the child process. The parent
+ * waits/exits in fork_child.
+ */
}
- /* open syslog() facility */
- if (_configd_fork) {
+ /*
+ * close file descriptors, establish stdin/stdout/stderr,
+ * setup logging.
+ */
+ if (!forceForeground) {
int logopt = LOG_NDELAY|LOG_PID;
+ init_fds();
+
if (_configd_verbose)
logopt |= LOG_CONS;
openlog("configd", logopt, LOG_DAEMON);
_sc_log = FALSE; /* redirect SCLog() to stdout/stderr */
}
- /* add signal handler to catch a SIGHUP */
+ /* check/enable trace logging */
+ set_trace();
+ /* record process id */
+ if (testBundle == NULL) {
+ writepid();
+ }
+
+ /* 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"),
}
/* add signal handler to catch a SIGPIPE */
-
if (sigaction(SIGPIPE, &nact, NULL) == -1) {
SCLog(_configd_verbose, LOG_ERR,
CFSTR("sigaction(SIGPIPE, ...) failed: %s"),
strerror(errno));
}
- /* get set */
+ /* add signal handler to catch a SIGTERM (if dynamic store) */
+ if (testBundle == NULL) {
+ if (enableRestart) {
+ mach_port_limits_t limits;
+ CFRunLoopSourceRef rls;
+ kern_return_t status;
+
+ /* add signal handler */
+ if (sigaction(SIGTERM, &nact, NULL) == -1) {
+ SCLog(_configd_verbose, LOG_ERR,
+ CFSTR("sigaction(SIGTERM, ...) failed: %s"),
+ strerror(errno));
+ }
- objc_setMultithreaded(YES);
+ /* create the "shutdown requested" notification port */
+ termRequested = CFMachPortCreate(NULL, term, NULL, NULL);
+
+ // set queue limit
+ limits.mpl_qlimit = 1;
+ status = mach_port_set_attributes(mach_task_self(),
+ CFMachPortGetPort(termRequested),
+ MACH_PORT_LIMITS_INFO,
+ (mach_port_info_t)&limits,
+ MACH_PORT_LIMITS_INFO_COUNT);
+ if (status != KERN_SUCCESS) {
+ perror("mach_port_set_attributes");
+ }
+
+ // add to our runloop
+ rls = CFMachPortCreateRunLoopSource(NULL, termRequested, 0);
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
+ CFRelease(rls);
+ }
- if (testBundle == NULL) {
/* initialize primary (store management) thread */
- server_init();
+ server_init(service_port, enableRestart);
+
+ if (!forceForeground && (service_port == MACH_PORT_NULL)) {
+ /* synchronize with parent process */
+ kill(getppid(), SIGTERM);
+ }
/* load/initialize/start bundles into the secondary thread */
if (loadBundles) {
+ objc_setMultithreaded(YES);
plugin_init();
- } else {
- if (_configd_fork) {
- /* synchronize with parent process */
- kill(getppid(), SIGTERM);
- }
}
- }
-
- /* go */
- if (testBundle == NULL) {
/* start primary (store management) thread */
server_loop();
} else {
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>ServiceName</key>
+ <string>com.apple.SystemConfiguration.configd</string>
+ <key>Command</key>
+ <string>/usr/sbin/configd</string>
+ <key>OnDemand</key>
+ <false/>
+</dict>
+</plist>
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
extern struct rpc_subsystem _config_subsystem;
extern boolean_t config_server(mach_msg_header_t *, mach_msg_header_t *);
-/* server state information */
-CFMachPortRef configd_port; /* configd server port (for new session requests) */
+/* configd server port (for new session requests) */
+static CFMachPortRef configd_port = NULL;
+/* priviledged bootstrap port (for registering/unregistering w/mach_init) */
+static mach_port_t priv_bootstrap_port = MACH_PORT_NULL;
+__private_extern__
boolean_t
config_demux(mach_msg_header_t *request, mach_msg_header_t *reply)
{
Boolean processed = FALSE;
+ serverSessionRef thisSession;
mach_msg_format_0_trailer_t *trailer;
- /* Feed the request into the ("MiG" generated) server */
- if (!processed &&
- (request->msgh_id >= _config_subsystem.start && request->msgh_id < _config_subsystem.end)) {
- serverSessionRef thisSession;
-
- thisSession = getSession(request->msgh_local_port);
- if (thisSession) {
- /*
- * Get the caller's credentials (eUID/eGID) from the message trailer.
- */
- trailer = (mach_msg_security_trailer_t *)((vm_offset_t)request +
- round_msg(request->msgh_size));
-
- if ((trailer->msgh_trailer_type == MACH_MSG_TRAILER_FORMAT_0) &&
- (trailer->msgh_trailer_size >= MACH_MSG_TRAILER_FORMAT_0_SIZE)) {
- thisSession->callerEUID = trailer->msgh_sender.val[0];
- thisSession->callerEGID = trailer->msgh_sender.val[1];
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("caller has eUID = %d, eGID = %d"),
- thisSession->callerEUID,
- thisSession->callerEGID);
- } else {
- static Boolean warned = FALSE;
-
- if (!warned) {
- SCLog(_configd_verbose, LOG_WARNING, CFSTR("caller's credentials not available."));
- warned = TRUE;
- }
- thisSession->callerEUID = 0;
- thisSession->callerEGID = 0;
- }
- }
-
+ thisSession = getSession(request->msgh_local_port);
+ if (thisSession) {
/*
- * Process configd requests.
+ * Get the caller's credentials (eUID/eGID) from the message trailer.
*/
- processed = config_server(request, reply);
+ trailer = (mach_msg_security_trailer_t *)((vm_offset_t)request +
+ round_msg(request->msgh_size));
+
+ if ((trailer->msgh_trailer_type == MACH_MSG_TRAILER_FORMAT_0) &&
+ (trailer->msgh_trailer_size >= MACH_MSG_TRAILER_FORMAT_0_SIZE)) {
+ thisSession->callerEUID = trailer->msgh_sender.val[0];
+ thisSession->callerEGID = trailer->msgh_sender.val[1];
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("caller has eUID = %d, eGID = %d"),
+ thisSession->callerEUID,
+ thisSession->callerEGID);
+ } else {
+ static Boolean warned = FALSE;
+
+ if (!warned) {
+ SCLog(_configd_verbose, LOG_WARNING, CFSTR("caller's credentials not available."));
+ warned = TRUE;
+ }
+ thisSession->callerEUID = 0;
+ thisSession->callerEGID = 0;
+ }
}
- if (!processed &&
- (request->msgh_id >= MACH_NOTIFY_FIRST && request->msgh_id < MACH_NOTIFY_LAST)) {
+ /*
+ * (attemp to) process configd requests.
+ */
+ processed = config_server(request, reply);
+
+ if (!processed) {
+ /*
+ * (attempt to) process (NO MORE SENDERS) notification messages.
+ */
processed = notify_server(request, reply);
}
if (!processed) {
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_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;
+ reply->msgh_size = sizeof(mig_reply_error_t); /* Minimal size */
+ reply->msgh_local_port = MACH_PORT_NULL;
+ reply->msgh_id = request->msgh_id + 100;
((mig_reply_error_t *)reply)->NDR = NDR_record;
((mig_reply_error_t *)reply)->RetCode = MIG_BAD_ID;
}
}
+#define MACH_MSG_BUFFER_SIZE 128
+
+
+__private_extern__
void
configdCallback(CFMachPortRef port, void *msg, CFIndex size, void *info)
{
- mig_reply_error_t *bufRequest = msg;
- mig_reply_error_t *bufReply = CFAllocatorAllocate(NULL, _config_subsystem.maxsize, 0);
+ mig_reply_error_t * bufRequest = msg;
+ uint32_t bufReply_q[MACH_MSG_BUFFER_SIZE/sizeof(uint32_t)];
+ mig_reply_error_t * bufReply = (mig_reply_error_t *)bufReply_q;
mach_msg_return_t mr;
int options;
+ if (_config_subsystem.maxsize > sizeof(bufReply_q)) {
+ static Boolean warned = FALSE;
+
+ if (!warned) {
+ SCLog(_configd_verbose, LOG_NOTICE,
+ CFSTR("configdCallback(): buffer size should be increased > %d"),
+ _config_subsystem.maxsize);
+ warned = TRUE;
+ }
+ bufReply = CFAllocatorAllocate(NULL, _config_subsystem.maxsize, 0);
+ }
+
/* we have a request message */
(void) config_demux(&bufRequest->Head, &bufReply->Head);
- if (!(bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) && (bufReply->RetCode != KERN_SUCCESS)) {
-
+ if (!(bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)) {
if (bufReply->RetCode == MIG_NO_REPLY) {
+ bufReply->Head.msgh_remote_port = MACH_PORT_NULL;
+ } else if ((bufReply->RetCode != KERN_SUCCESS) &&
+ (bufRequest->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX)) {
/*
- * This return code is a little tricky -- it appears that the
- * demux routine found an error of some sort, but since that
- * error would not normally get returned either to the local
- * user or the remote one, we pretend it's ok.
+ * destroy the request - but not the reply port
*/
- CFAllocatorDeallocate(NULL, bufReply);
- return;
+ bufRequest->Head.msgh_remote_port = MACH_PORT_NULL;
+ mach_msg_destroy(&bufRequest->Head);
}
+ }
+ if (bufReply->Head.msgh_remote_port != MACH_PORT_NULL) {
/*
- * destroy any out-of-line data in the request buffer but don't destroy
- * the reply port right (since we need that to send an error message).
+ * send reply.
+ *
+ * We don't want to block indefinitely because the client
+ * isn't receiving messages from the reply port.
+ * If we have a send-once right for the reply port, then
+ * this isn't a concern because the send won't block.
+ * If we have a send right, we need to use MACH_SEND_TIMEOUT.
+ * To avoid falling off the kernel's fast RPC path unnecessarily,
+ * we only supply MACH_SEND_TIMEOUT when absolutely necessary.
*/
- bufRequest->Head.msgh_remote_port = MACH_PORT_NULL;
- mach_msg_destroy(&bufRequest->Head);
- }
- if (bufReply->Head.msgh_remote_port == MACH_PORT_NULL) {
- /* no reply port, so destroy the reply */
- if (bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) {
- mach_msg_destroy(&bufReply->Head);
+ options = MACH_SEND_MSG;
+ if (MACH_MSGH_BITS_REMOTE(bufReply->Head.msgh_bits) != MACH_MSG_TYPE_MOVE_SEND_ONCE) {
+ options |= MACH_SEND_TIMEOUT;
+ }
+ mr = mach_msg(&bufReply->Head, /* msg */
+ options, /* option */
+ bufReply->Head.msgh_size, /* send_size */
+ 0, /* rcv_size */
+ MACH_PORT_NULL, /* rcv_name */
+ MACH_MSG_TIMEOUT_NONE, /* timeout */
+ MACH_PORT_NULL); /* notify */
+
+ /* Has a message error occurred? */
+ switch (mr) {
+ case MACH_SEND_INVALID_DEST:
+ case MACH_SEND_TIMED_OUT:
+ break;
+ default :
+ /* Includes success case. */
+ goto done;
}
- CFAllocatorDeallocate(NULL, bufReply);
- return;
}
- /*
- * send reply.
- *
- * We don't want to block indefinitely because the client
- * isn't receiving messages from the reply port.
- * If we have a send-once right for the reply port, then
- * this isn't a concern because the send won't block.
- * If we have a send right, we need to use MACH_SEND_TIMEOUT.
- * To avoid falling off the kernel's fast RPC path unnecessarily,
- * we only supply MACH_SEND_TIMEOUT when absolutely necessary.
- */
-
- options = MACH_SEND_MSG;
- if (MACH_MSGH_BITS_REMOTE(bufReply->Head.msgh_bits) == MACH_MSG_TYPE_MOVE_SEND_ONCE) {
- options |= MACH_SEND_TIMEOUT;
+ if (bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) {
+ mach_msg_destroy(&bufReply->Head);
}
- mr = mach_msg(&bufReply->Head, /* msg */
- options, /* option */
- bufReply->Head.msgh_size, /* send_size */
- 0, /* rcv_size */
- MACH_PORT_NULL, /* rcv_name */
- MACH_MSG_TIMEOUT_NONE, /* timeout */
- MACH_PORT_NULL); /* notify */
-
-
- /* Has a message error occurred? */
- switch (mr) {
- case MACH_SEND_INVALID_DEST:
- case MACH_SEND_TIMED_OUT:
- /* the reply can't be delivered, so destroy it */
- mach_msg_destroy(&bufReply->Head);
- break;
- default :
- /* Includes success case. */
- break;
- }
+ done :
- CFAllocatorDeallocate(NULL, bufReply);
+ if (bufReply != (mig_reply_error_t *)bufReply_q)
+ CFAllocatorDeallocate(NULL, bufReply);
return;
}
+__private_extern__
boolean_t
-server_active()
+server_active(mach_port_t *restart_service_port)
{
- boolean_t active;
mach_port_t bootstrap_port;
- char *server_name;
+ char *service_name;
kern_return_t status;
- server_name = getenv("SCD_SERVER");
- if (!server_name) {
- server_name = SCD_SERVER;
+ service_name = getenv("SCD_SERVER");
+ if (!service_name) {
+ service_name = SCD_SERVER;
}
/* Getting bootstrap server port */
}
/* Check "configd" server status */
- status = bootstrap_status(bootstrap_port, server_name, &active);
+ status = bootstrap_check_in(bootstrap_port, service_name, restart_service_port);
switch (status) {
case BOOTSTRAP_SUCCESS :
- if (active) {
- fprintf(stderr, "configd: '%s' server already active\n",
- server_name);
- return TRUE;
- }
+ /* if we are being restarted by mach_init */
+ priv_bootstrap_port = bootstrap_port;
break;
+ case BOOTSTRAP_SERVICE_ACTIVE :
+ case BOOTSTRAP_NOT_PRIVILEGED :
+ /* if another instance of the server is active (or starting) */
+ fprintf(stderr, "'%s' server already active\n",
+ service_name);
+ return TRUE;
case BOOTSTRAP_UNKNOWN_SERVICE :
+ /* if the server is not currently registered/active */
+ *restart_service_port = MACH_PORT_NULL;
break;
default :
- fprintf(stderr, "bootstrap_status(): %s\n",
- mach_error_string(status));
+ fprintf(stderr, "bootstrap_check_in() failed: status=%d\n", status);
exit (EX_UNAVAILABLE);
}
+
return FALSE;
}
+
+__private_extern__
void
-server_init()
+server_init(mach_port_t restart_service_port, Boolean enableRestart)
{
- boolean_t active;
mach_port_t bootstrap_port;
CFRunLoopSourceRef rls;
- char *server_name;
+ char *service_name;
+ mach_port_t service_port = restart_service_port;
kern_return_t status;
- server_name = getenv("SCD_SERVER");
- if (!server_name) {
- server_name = SCD_SERVER;
+ service_name = getenv("SCD_SERVER");
+ if (!service_name) {
+ service_name = SCD_SERVER;
}
/* Getting bootstrap server port */
status = task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
if (status != KERN_SUCCESS) {
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("task_get_bootstrap_port(): %s"), mach_error_string(status));
+ SCLog(TRUE, LOG_ERR, CFSTR("task_get_bootstrap_port(): %s"), mach_error_string(status));
exit (EX_UNAVAILABLE);
}
- /* Check "configd" server status */
- status = bootstrap_status(bootstrap_port, server_name, &active);
- switch (status) {
- case BOOTSTRAP_SUCCESS :
- if (active) {
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("\"%s\" is currently active, exiting."), server_name);
+ if (service_port == MACH_PORT_NULL) {
+ mach_port_t service_send_port;
+
+ /* Check "configd" server status */
+ status = bootstrap_check_in(bootstrap_port, service_name, &service_port);
+ switch (status) {
+ case BOOTSTRAP_SUCCESS :
+ /* if we are being restarted by mach_init */
+ priv_bootstrap_port = bootstrap_port;
+ break;
+ case BOOTSTRAP_NOT_PRIVILEGED :
+ /* if another instance of the server is starting */
+ SCLog(TRUE, LOG_ERR, CFSTR("'%s' server already starting"), service_name);
exit (EX_UNAVAILABLE);
- }
- break;
- case BOOTSTRAP_UNKNOWN_SERVICE :
- /* service not currently registered, "a good thing" (tm) */
- break;
- default :
- fprintf(stderr, "bootstrap_status(): %s\n", mach_error_string(status));
- exit (EX_UNAVAILABLE);
+ case BOOTSTRAP_UNKNOWN_SERVICE :
+ /* service not currently registered, "a good thing" (tm) */
+ if (enableRestart) {
+ status = bootstrap_create_server(bootstrap_port,
+ "/usr/sbin/configd",
+ geteuid(),
+ FALSE, /* not onDemand == restart now */
+ &priv_bootstrap_port);
+ if (status != BOOTSTRAP_SUCCESS) {
+ SCLog(TRUE, LOG_ERR, CFSTR("bootstrap_create_server() failed: status=%d"), status);
+ exit (EX_UNAVAILABLE);
+ }
+ } else {
+ priv_bootstrap_port = bootstrap_port;
+ }
+
+ status = bootstrap_create_service(priv_bootstrap_port, service_name, &service_send_port);
+ if (status != BOOTSTRAP_SUCCESS) {
+ SCLog(TRUE, LOG_ERR, CFSTR("bootstrap_create_service() failed: status=%d"), status);
+ exit (EX_UNAVAILABLE);
+ }
+
+ status = bootstrap_check_in(priv_bootstrap_port, service_name, &service_port);
+ if (status != BOOTSTRAP_SUCCESS) {
+ SCLog(TRUE, LOG_ERR, CFSTR("bootstrap_check_in() failed: status=%d"), status);
+ exit (EX_UNAVAILABLE);
+ }
+ break;
+ case BOOTSTRAP_SERVICE_ACTIVE :
+ /* if another instance of the server is active */
+ SCLog(TRUE, LOG_ERR, CFSTR("'%s' server already active"), service_name);
+ exit (EX_UNAVAILABLE);
+ default :
+ SCLog(TRUE, LOG_ERR, CFSTR("bootstrap_check_in() failed: status=%d"), status);
+ exit (EX_UNAVAILABLE);
+ }
+
+ }
+
+ /* we don't want to pass our priviledged bootstrap port along to any spawned helpers so... */
+ status = bootstrap_unprivileged(priv_bootstrap_port, &bootstrap_port);
+ if (status != BOOTSTRAP_SUCCESS) {
+ SCLog(TRUE, LOG_ERR, CFSTR("bootstrap_unprivileged() failed: status=%d"), status);
+ exit (EX_UNAVAILABLE);
+ }
+
+ status = task_set_bootstrap_port(mach_task_self(), bootstrap_port);
+ if (status != BOOTSTRAP_SUCCESS) {
+ SCLog(TRUE, LOG_ERR, CFSTR("task_set_bootstrap_port(): %s"),
+ mach_error_string(status));
+ exit (EX_UNAVAILABLE);
}
/* Create the primary / new connection port */
- configd_port = CFMachPortCreate(NULL, configdCallback, NULL, NULL);
+ configd_port = CFMachPortCreateWithPort(NULL, service_port, configdCallback, NULL, NULL);
/*
* Create and add a run loop source for the port and add this source
/* Create a session for the primary / new connection port */
(void) addSession(configd_port);
- SCLog(_configd_verbose, LOG_DEBUG, CFSTR("Registering service \"%s\""), server_name);
- status = bootstrap_register(bootstrap_port, server_name, CFMachPortGetPort(configd_port));
+ return;
+}
+
+
+__private_extern__
+void
+server_shutdown()
+{
+ char *service_name;
+ mach_port_t service_port;
+ kern_return_t status;
+
+ /*
+ * Note: we can't use SCLog() since the signal may be received while the
+ * logging thread lock is held.
+ */
+ if ((priv_bootstrap_port == MACH_PORT_NULL) || (configd_port == NULL)) {
+ return;
+ }
+
+ service_name = getenv("SCD_SERVER");
+ if (!service_name) {
+ service_name = SCD_SERVER;
+ }
+
+ service_port = CFMachPortGetPort(configd_port);
+ if (service_port != MACH_PORT_NULL) {
+ (void) mach_port_destroy(mach_task_self(), service_port);
+ }
+
+ status = bootstrap_register(priv_bootstrap_port, service_name, MACH_PORT_NULL);
switch (status) {
case BOOTSTRAP_SUCCESS :
- /* service not currently registered, "a good thing" (tm) */
break;
- case BOOTSTRAP_NOT_PRIVILEGED :
- SCLog(_configd_verbose, LOG_ERR, CFSTR("bootstrap_register(): bootstrap not privileged"));
- exit (EX_OSERR);
- case BOOTSTRAP_SERVICE_ACTIVE :
- SCLog(_configd_verbose, LOG_ERR, CFSTR("bootstrap_register(): bootstrap service active"));
- exit (EX_OSERR);
+ case MACH_SEND_INVALID_DEST :
+ case MIG_SERVER_DIED :
+ /* something happened to mach_init */
+ break;
default :
- SCLog(_configd_verbose, LOG_ERR, CFSTR("bootstrap_register(): %s"), mach_error_string(status));
- exit (EX_OSERR);
+ if (_configd_verbose) {
+ syslog (LOG_ERR, "bootstrap_register() failed: status=%d" , status);
+ } else {
+ fprintf(stderr, "bootstrap_register() failed: status=%d\n", status);
+ fflush (stderr);
+ }
+ exit (EX_UNAVAILABLE);
}
- return;
+ exit(EX_OK);
}
+__private_extern__
void
server_loop()
{
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include <CoreFoundation/CFRunLoop.h>
#include <CoreFoundation/CFMachPort.h>
-extern CFMachPortRef configd_port; /* configd server port (for new session requests) */
-
__BEGIN_DECLS
void configdCallback (CFMachPortRef port,
CFIndex size,
void *info);
-boolean_t server_active ();
+boolean_t server_active (mach_port_t *service_port);
+
+void server_init (mach_port_t service_port,
+ Boolean enableRestart);
-void server_init ();
+void server_shutdown ();
void server_loop ();
kern_return_t _notifycancel (mach_port_t server,
int *sc_status);
+kern_return_t _notifyset (mach_port_t server,
+ xmlData_t keysRef,
+ mach_msg_type_number_t keysLen,
+ xmlData_t patternsRef,
+ mach_msg_type_number_t patternsLen,
+ int *sc_status);
+
__END_DECLS
#endif /* !_S_CONFIGD_SERVER_H */
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "session.h"
+__private_extern__
void
pushNotifications()
{
/*
* Post notification as mach message
*/
- 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);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("sending mach message notification."));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" port = %d"), storePrivate->notifyPort);
+ SCLog(TRUE, 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 = storePrivate->notifyPort;
(storePrivate->notifyFile >= 0)) {
ssize_t written;
- 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);
+ if (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("sending (UNIX domain) socket notification"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" fd = %d"), storePrivate->notifyFile);
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" msgid = %d"), storePrivate->notifyFileIdentifier);
+ }
written = write(storePrivate->notifyFile,
&storePrivate->notifyFileIdentifier,
*/
status = pid_for_task(storePrivate->notifySignalTask, &pid);
if (status == KERN_SUCCESS) {
- 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 (_configd_verbose) {
+ SCLog(TRUE, LOG_DEBUG, CFSTR("sending signal notification"));
+ SCLog(TRUE, LOG_DEBUG, CFSTR(" pid = %d"), pid);
+ SCLog(TRUE, 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;
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "session.h"
#include "notify.h"
+__private_extern__
boolean_t
notify_server(mach_msg_header_t *request, mach_msg_header_t *reply)
{
- mach_no_senders_notification_t *notify = (mach_no_senders_notification_t *)request;
+ mach_no_senders_notification_t *Request = (mach_no_senders_notification_t *)request;
+ mig_reply_error_t *Reply = (mig_reply_error_t *)reply;
+
+ 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: update as needed */
+ reply->msgh_local_port = MACH_PORT_NULL;
+ reply->msgh_id = request->msgh_id + 100;
- if ((notify->not_header.msgh_id > MACH_NOTIFY_LAST) ||
- (notify->not_header.msgh_id < MACH_NOTIFY_FIRST)) {
+ if ((Request->not_header.msgh_id > MACH_NOTIFY_LAST) ||
+ (Request->not_header.msgh_id < MACH_NOTIFY_FIRST)) {
+ Reply->NDR = NDR_record;
+ Reply->RetCode = MIG_BAD_ID;
return FALSE; /* if this is not a notification message */
}
- switch (notify->not_header.msgh_id) {
+ switch (Request->not_header.msgh_id) {
case MACH_NOTIFY_NO_SENDERS :
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);
-
- (void) mach_port_destroy(mach_task_self(), notify->not_header.msgh_local_port);
-
- notify->not_header.msgh_remote_port = MACH_PORT_NULL;
- return TRUE;
- case MACH_NOTIFY_DEAD_NAME :
- 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);
+ Request->not_header.msgh_local_port);
+ cleanupSession(Request->not_header.msgh_local_port);
- (void) mach_port_destroy(mach_task_self(), notify->not_header.msgh_local_port);
+ (void) mach_port_mod_refs(mach_task_self(),
+ Request->not_header.msgh_local_port,
+ MACH_PORT_RIGHT_RECEIVE, -1);
- notify->not_header.msgh_remote_port = MACH_PORT_NULL;
+ Reply->Head.msgh_bits = 0;
+ Reply->Head.msgh_remote_port = MACH_PORT_NULL;
+ Reply->RetCode = KERN_SUCCESS;
return TRUE;
default :
break;
}
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);
+ Request->not_header.msgh_local_port,
+ Request->not_header.msgh_id);
- return FALSE;
+ Reply->NDR = NDR_record;
+ Reply->RetCode = MIG_BAD_ID;
+ return FALSE; /* if this is not a notification we are handling */
}
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Modification History
+ *
+ * April 23, 2003 Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+
+#include "configd.h"
+#include "pattern.h"
+
+
+/*
+ * Notes:
+ *
+ * - pattern matching information is maintained in a dictionary (patternData).
+ * - the dictionary "key" is the regular expression being matched
+ * - the dictionary "value" is a CFArray with the following contents
+ * [0] = CFData consisting of the pre-compiled regular expression
+ * [1] = CFArray[CFNumber] consisting of the sessions watching this pattern
+ * [2-n] = dynamic store keys which match this pattern
+ */
+
+
+typedef struct {
+ CFMutableArrayRef pInfo;
+ regex_t *preg;
+} addContext, *addContextRef;
+
+
+static __inline__ void
+my_CFDictionaryApplyFunction(CFDictionaryRef theDict,
+ CFDictionaryApplierFunction applier,
+ void *context)
+{
+ CFAllocatorRef myAllocator;
+ CFDictionaryRef myDict;
+
+ myAllocator = CFGetAllocator(theDict);
+ myDict = CFDictionaryCreateCopy(myAllocator, theDict);
+ CFDictionaryApplyFunction(myDict, applier, context);
+ CFRelease(myDict);
+ return;
+}
+
+
+static void
+identifyKeyForPattern(const void *key, void *val, void *context)
+{
+ CFStringRef storeKey = (CFStringRef)key;
+ CFDictionaryRef storeValue = (CFDictionaryRef)val;
+ CFMutableArrayRef pInfo = ((addContextRef)context)->pInfo;
+ regex_t * preg = ((addContextRef)context)->preg;
+
+ CFIndex len;
+ int reError;
+ char str_q[256];
+ char * str = str_q;
+
+ if (!CFDictionaryContainsKey(storeValue, kSCDData)) {
+ /* if no data (yet) */
+ return;
+ }
+
+ /* convert store key to C string */
+ len = CFStringGetLength(storeKey) + 1;
+ if (len > (CFIndex)sizeof(str_q))
+ str = CFAllocatorAllocate(NULL, len, 0);
+ if (_SC_cfstring_to_cstring(storeKey, str, len, kCFStringEncodingASCII) == NULL) {
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("could not convert store key to C string"));
+ goto done;
+ }
+
+ /* compare store key to new notification keys regular expression pattern */
+ reError = regexec(preg, str, 0, NULL, 0);
+ switch (reError) {
+ case 0 :
+ /* we've got a match */
+ CFArrayAppendValue(pInfo, storeKey);
+ break;
+ case REG_NOMATCH :
+ /* no match */
+ break;
+ default : {
+ char reErrBuf[256];
+
+ (void)regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
+ break;
+ }
+ }
+
+ done :
+
+ if (str != str_q) CFAllocatorDeallocate(NULL, str);
+ return;
+}
+
+
+__private_extern__ Boolean
+patternCompile(CFStringRef pattern, regex_t *preg, CFStringRef *error)
+{
+ Boolean append = FALSE;
+ Boolean insert = FALSE;
+ CFIndex len = 0;
+ Boolean ok;
+ char str_q[256];
+ char * str = str_q;
+
+ if (!CFStringHasPrefix(pattern, CFSTR("^"))) {
+ insert = TRUE;
+ }
+
+ if (!CFStringHasSuffix(pattern, CFSTR("$")) ||
+ CFStringHasSuffix(pattern, CFSTR("\\$"))) {
+ append = TRUE;
+ }
+
+ /* if regex pattern is not bounded at both ends */
+ if (insert || append) {
+ pattern = CFStringCreateWithFormat(NULL,
+ NULL,
+ CFSTR("%s%@%s"),
+ insert ? "^" : "",
+ pattern,
+ append ? "$" : "");
+ }
+
+ (void)CFStringGetBytes(pattern,
+ CFRangeMake(0, CFStringGetLength(pattern)),
+ kCFStringEncodingASCII,
+ 0,
+ FALSE,
+ NULL,
+ 0,
+ &len);
+ if (++len > (CFIndex)sizeof(str_q)) {
+ str = CFAllocatorAllocate(NULL, len, 0);
+ }
+ ok = (_SC_cfstring_to_cstring(pattern, str, len, kCFStringEncodingASCII) != NULL);
+ if (insert || append) {
+ CFRelease(pattern);
+ }
+ if (ok) {
+ int reError;
+
+ reError = regcomp(preg, str, REG_EXTENDED);
+ if (reError != 0) {
+ char reErrBuf[256];
+
+ (void)regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
+ *error = CFStringCreateWithCString(NULL, reErrBuf, kCFStringEncodingASCII);
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regcomp(%s) failed: %s"), str, reErrBuf);
+ ok = FALSE;
+ }
+ } else {
+ *error = CFRetain(CFSTR("could not convert pattern to regex string"));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("%@"), *error);
+ }
+
+ if (str != str_q) CFAllocatorDeallocate(NULL, str);
+ return ok;
+}
+
+
+__private_extern__
+CFMutableArrayRef
+patternCopy(CFStringRef pattern)
+{
+ CFArrayRef pInfo;
+
+ pInfo = CFDictionaryGetValue(patternData, pattern);
+ return pInfo ? CFArrayCreateMutableCopy(NULL, 0, pInfo) : NULL;
+}
+
+
+__private_extern__
+CFMutableArrayRef
+patternNew(CFStringRef pattern)
+{
+ addContext context;
+ CFStringRef err;
+ CFMutableArrayRef pInfo;
+ CFMutableDataRef pRegex;
+ CFArrayRef pSessions;
+
+ /* create the pattern info */
+ pInfo = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+ /* compile the regular expression from the pattern string. */
+ pRegex = CFDataCreateMutable(NULL, sizeof(regex_t));
+ CFDataSetLength(pRegex, sizeof(regex_t));
+ if (!patternCompile(pattern, (regex_t *)CFDataGetBytePtr(pRegex), &err)) {
+ CFRelease(err);
+ CFRelease(pRegex);
+ CFRelease(pInfo);
+ return NULL;
+ }
+
+ /* add the compiled regular expression to the pattern info */
+ CFArrayAppendValue(pInfo, pRegex);
+
+ /* add the initial (empty) list of sessions watching this pattern */
+ pSessions = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
+ CFArrayAppendValue(pInfo, pSessions);
+ CFRelease(pSessions);
+
+ /* identify/add all existing keys that match the specified pattern */
+ context.pInfo = pInfo;
+ context.preg = (regex_t *)CFDataGetBytePtr(pRegex);
+ my_CFDictionaryApplyFunction(storeData,
+ (CFDictionaryApplierFunction)identifyKeyForPattern,
+ &context);
+
+ CFRelease(pRegex);
+ return pInfo;
+}
+
+
+__private_extern__
+Boolean
+patternAddSession(CFStringRef pattern, CFNumberRef sessionNum)
+{
+ CFIndex i;
+ CFIndex n;
+ CFMutableArrayRef pInfo;
+ CFMutableArrayRef pSessions;
+
+ /* find (or create new instance of) this pattern */
+ pInfo = patternCopy(pattern);
+ if (!pInfo) {
+ /* if new pattern */
+ pInfo = patternNew(pattern);
+ if (!pInfo) {
+ return FALSE;
+ }
+ }
+
+ /* add this session as a pattern watcher */
+ pSessions = (CFMutableArrayRef)CFArrayGetValueAtIndex(pInfo, 1);
+ pSessions = CFArrayCreateMutableCopy(NULL, 0, pSessions);
+ CFArrayAppendValue(pSessions, sessionNum);
+ CFArraySetValueAtIndex(pInfo, 1, pSessions);
+ CFRelease(pSessions);
+
+ /* update pattern watcher info */
+ CFDictionarySetValue(patternData, pattern, pInfo);
+
+ /* add this session as a watcher of any existing keys */
+ n = CFArrayGetCount(pInfo);
+ for (i = 2; i < n; i++) {
+ CFStringRef matchingKey;
+
+ matchingKey = CFArrayGetValueAtIndex(pInfo, i);
+ _addWatcher(sessionNum, matchingKey);
+ }
+
+ CFRelease(pInfo);
+ return TRUE;
+}
+
+
+__private_extern__
+void
+patternRemoveSession(CFStringRef pattern, CFNumberRef sessionNum)
+{
+ CFIndex i;
+ CFIndex n;
+ CFMutableArrayRef pInfo;
+ CFDataRef pRegex;
+ CFMutableArrayRef pSessions;
+
+ /* find instance of this pattern */
+ pInfo = patternCopy(pattern);
+
+ /* remove this session as a watcher from all matching keys */
+ n = CFArrayGetCount(pInfo);
+ for (i = 2; i < n; i++) {
+ CFStringRef matchingKey;
+
+ matchingKey = CFArrayGetValueAtIndex(pInfo, i);
+ _removeWatcher(sessionNum, matchingKey);
+ }
+
+ /* remove session from watchers */
+ pSessions = (CFMutableArrayRef)CFArrayGetValueAtIndex(pInfo, 1);
+ n = CFArrayGetCount(pSessions);
+ if (n > 1) {
+ /* if other sessions are watching this pattern */
+
+ pSessions = CFArrayCreateMutableCopy(NULL, 0, pSessions);
+ i = CFArrayGetFirstIndexOfValue(pSessions, CFRangeMake(0, n), sessionNum);
+ CFArrayRemoveValueAtIndex(pSessions, i);
+ CFArraySetValueAtIndex(pInfo, 1, pSessions);
+ CFRelease(pSessions);
+
+ CFDictionarySetValue(patternData, pattern, pInfo);
+ } else {
+ /* if no other sessions are watching this pattern */
+
+ pRegex = CFArrayGetValueAtIndex(pInfo, 0);
+ regfree((regex_t *)CFDataGetBytePtr(pRegex));
+ CFDictionaryRemoveValue(patternData, pattern);
+ }
+
+ CFRelease(pInfo);
+ return;
+}
+
+
+static void
+addKeyForPattern(const void *key, void *val, void *context)
+{
+ CFStringRef pattern = (CFStringRef)key;
+ CFArrayRef pInfo = (CFArrayRef)val;
+ CFStringRef storeKey = (CFStringRef)context;
+
+ CFIndex len;
+ regex_t *preg;
+ int reError;
+ char str_q[256];
+ char * str = str_q;
+
+ /* convert store key to C string */
+ len = CFStringGetLength(storeKey) + 1;
+ if (len > (CFIndex)sizeof(str_q))
+ str = CFAllocatorAllocate(NULL, len, 0);
+ if (_SC_cfstring_to_cstring(storeKey, str, len, kCFStringEncodingASCII) == NULL) {
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("could not convert store key to C string"));
+ goto done;
+ }
+
+ /* compare new store key to regular expression pattern */
+ preg = (regex_t *)CFDataGetBytePtr(CFArrayGetValueAtIndex(pInfo, 0));
+ reError = regexec(preg, str, 0, NULL, 0);
+ switch (reError) {
+ case 0 : {
+ /*
+ * we've got a match
+ */
+ CFIndex i;
+ CFIndex n;
+ CFMutableArrayRef pInfo_new;
+ CFArrayRef pSessions;
+
+ /* add watchers */
+ pSessions = CFArrayGetValueAtIndex(pInfo, 1);
+ n = CFArrayGetCount(pSessions);
+ for (i = 0; i < n; i++) {
+ CFNumberRef sessionNum = CFArrayGetValueAtIndex(pSessions, i);
+
+ _addWatcher(sessionNum, storeKey);
+ }
+
+ /* add key, update pattern watcher info */
+ pInfo_new = CFArrayCreateMutableCopy(NULL, 0, pInfo);
+ CFArrayAppendValue(pInfo_new, storeKey);
+ CFDictionarySetValue(patternData, pattern, pInfo_new);
+ CFRelease(pInfo_new);
+ break;
+ }
+ case REG_NOMATCH :
+ /* no match */
+ break;
+ default : {
+ char reErrBuf[256];
+
+ (void)regerror(reError, preg, reErrBuf, sizeof(reErrBuf));
+ SCLog(_configd_verbose, LOG_DEBUG, CFSTR("regexec(): %s"), reErrBuf);
+ break;
+ }
+ }
+
+ done :
+
+ if (str != str_q) CFAllocatorDeallocate(NULL, str);
+ return;
+}
+
+
+__private_extern__
+void
+patternAddKey(CFStringRef key)
+{
+ my_CFDictionaryApplyFunction(patternData,
+ (CFDictionaryApplierFunction)addKeyForPattern,
+ (void *)key);
+
+ return;
+}
+
+
+static void
+removeKeyFromPattern(const void *key, void *val, void *context)
+{
+ CFStringRef pattern = (CFStringRef)key;
+ CFArrayRef pInfo = (CFArrayRef)val;
+ CFStringRef storeKey = (CFStringRef)context;
+
+ CFIndex i;
+ CFIndex n;
+ CFMutableArrayRef pInfo_new;
+ CFArrayRef pSessions;
+
+ n = CFArrayGetCount(pInfo);
+ if (n <= 2) {
+ /* if no keys match this pattern */
+ return;
+ }
+
+ i = CFArrayGetFirstIndexOfValue(pInfo, CFRangeMake(2, n-2), storeKey);
+ if (i == -1) {
+ /* if this key wasn't matched by this pattern */
+ return;
+ }
+
+ /* remove key from pattern info */
+ pInfo_new = CFArrayCreateMutableCopy(NULL, 0, pInfo);
+ CFArrayRemoveValueAtIndex(pInfo_new, i);
+
+ /* remove watchers */
+ pSessions = CFArrayGetValueAtIndex(pInfo_new, 1);
+ n = CFArrayGetCount(pSessions);
+ for (i = 0; i < n; i++) {
+ CFNumberRef sessionNum = CFArrayGetValueAtIndex(pSessions, i);
+
+ _removeWatcher(sessionNum, storeKey);
+ }
+
+ CFDictionarySetValue(patternData, pattern, pInfo_new);
+ CFRelease(pInfo_new);
+ return;
+}
+
+
+__private_extern__
+void
+patternRemoveKey(CFStringRef key)
+{
+ my_CFDictionaryApplyFunction(patternData,
+ (CFDictionaryApplierFunction)removeKeyFromPattern,
+ (void *)key);
+
+ return;
+}
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * Modification History
+ *
+ * April 23, 2003 Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+
+#ifndef _S_PATTERN_H
+#define _S_PATTERN_H
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+Boolean patternCompile (CFStringRef pattern,
+ regex_t *preg,
+ CFStringRef *error);
+
+CFMutableArrayRef patternCopy (CFStringRef pattern);
+
+CFMutableArrayRef patternNew (CFStringRef pattern);
+
+Boolean patternAddSession (CFStringRef pattern,
+ CFNumberRef sessionNum);
+
+void patternRemoveSession (CFStringRef pattern,
+ CFNumberRef sessionNum);
+
+void patternAddKey (CFStringRef key);
+
+void patternRemoveKey (CFStringRef key);
+
+__END_DECLS
+
+#endif /* !_S_PATTERN_H */
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/* check if this directory entry is a valid bundle name */
len = strlen(cp);
- if (len <= sizeof(BUNDLE_DIR_EXTENSION)) {
+ if (len <= (int)sizeof(BUNDLE_DIR_EXTENSION)) {
/* if entry name isn't long enough */
return;
}
new = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
while (CFArrayGetCount(orig) > 0) {
int i;
- Boolean inserted = FALSE;
+ Boolean inserted = FALSE;
+ int nOrig = CFArrayGetCount(orig);
- for (i = 0; i < CFArrayGetCount(orig); i++) {
+ for (i = 0; i < nOrig; i++) {
CFBundleRef bundle1 = (CFBundleRef)CFArrayGetValueAtIndex(orig, i);
CFStringRef bundleID1 = CFBundleGetIdentifier(bundle1);
int count;
CFDictionaryRef dict;
int j;
+ int nRequires;
CFArrayRef requires = NULL;
dict = isA_CFDictionary(CFBundleGetInfoDictionary(bundle1));
inserted = TRUE;
break;
}
- count = CFArrayGetCount(requires);
- for (j = 0; j < CFArrayGetCount(requires); j++) {
+ count = nRequires = CFArrayGetCount(requires);
+ for (j = 0; j < nRequires; j++) {
int k;
+ int nNew;
CFStringRef r = CFArrayGetValueAtIndex(requires, j);
- for (k = 0; k < CFArrayGetCount(new); k++) {
+ nNew = CFArrayGetCount(new);
+ for (k = 0; k < nNew; k++) {
CFBundleRef bundle2 = (CFBundleRef)CFArrayGetValueAtIndex(new, k);
CFStringRef bundleID2 = CFBundleGetIdentifier(bundle2);
}
+__private_extern__
void *
plugin_exec(void *arg)
{
/* keep track of bundles */
allBundles = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
- /* allow plug-ins to exec child/helper processes */
- _SCDPluginExecInit();
+ /* allow plug-ins to exec child/helper processes */
+ _SCDPluginExecInit();
if (arg == NULL) {
char path[MAXPATHLEN];
}
#endif /* DEBUG */
- if (_configd_fork) {
- /* synchronize with parent process */
- kill(getppid(), SIGTERM);
- }
-
/*
* The assumption is that each loaded plugin will establish CFMachPortRef,
* CFSocketRef, and CFRunLoopTimerRef input sources to handle any events
}
+__private_extern__
void
plugin_init()
{
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
static int nSessions = 0;
+__private_extern__
serverSessionRef
getSession(mach_port_t server)
{
return NULL;
}
- if (nSessions > 0) {
- for (i=0; i<nSessions; i++) {
- serverSessionRef thisSession = sessions[i];
-
- if (thisSession == NULL) {
- /* found an empty slot, skip it */
- continue;
- } else if (thisSession->key == server) {
- return thisSession; /* we've seen this server before */
- } else if (thisSession->store &&
- (((SCDynamicStorePrivateRef)thisSession->store)->notifySignalTask == server)) {
- return thisSession;
- }
+ for (i = 0; i < nSessions; i++) {
+ serverSessionRef thisSession = sessions[i];
+
+ if (thisSession == NULL) {
+ /* found an empty slot, skip it */
+ continue;
+ } else if (thisSession->key == server) {
+ return thisSession; /* we've seen this server before */
+ } else if (thisSession->store &&
+ (((SCDynamicStorePrivateRef)thisSession->store)->notifySignalTask == server)) {
+ return thisSession;
}
}
}
+__private_extern__
serverSessionRef
addSession(CFMachPortRef server)
{
n = 0;
nSessions = 1;
} else {
- for (i=0; i<nSessions; i++) {
+ for (i = 0; i < nSessions; i++) {
if (sessions[i] == NULL) {
/* found an empty slot, use it */
n = i;
}
+__private_extern__
void
removeSession(mach_port_t server)
{
serverSessionRef thisSession;
CFStringRef sessionKey;
- for (i=0; i<nSessions; i++) {
+ for (i = 0; i < nSessions; i++) {
thisSession = sessions[i];
if (thisSession == NULL) {
}
+__private_extern__
void
cleanupSession(mach_port_t server)
{
int i;
- for (i=0; i<nSessions; i++) {
+ for (i = 0; i < nSessions; i++) {
serverSessionRef thisSession = sessions[i];
if ((thisSession != NULL) && (thisSession->key == server)) {
* session entry still exists.
*/
+ if (_configd_trace) {
+ SCTrace(TRUE, _configd_trace, CFSTR("cleanup : %5d\n"), server);
+ }
+
/*
* Ensure that any changes made while we held the "lock"
* are discarded.
* Close any open connections including cancelling any outstanding
* notification requests and releasing any locks.
*/
- (void) __SCDynamicStoreClose(&thisSession->store);
+ (void) __SCDynamicStoreClose(&thisSession->store, TRUE);
/*
* Lastly, remove the session entry.
}
+__private_extern__
void
listSessions()
{
int i;
fprintf(stderr, "Current sessions:");
- for (i=0; i<nSessions; i++) {
+ for (i = 0; i < nSessions; i++) {
serverSessionRef thisSession = sessions[i];
if (thisSession == 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
-<plist version="0.9">
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
<dict>
<key>CurrentSet</key>
<string>/Sets/0</string>
<key>DNS</key>
<dict/>
<key>Ethernet</key>
- <dict>
- </dict>
+ <dict/>
<key>IPv4</key>
<dict>
<key>ConfigMethod</key>
<string>DHCP</string>
</dict>
+ <key>IPv6</key>
+ <dict>
+ <key>ConfigMethod</key>
+ <string>Automatic</string>
+ </dict>
<key>Interface</key>
<dict>
<key>DeviceName</key>
</dict>
</dict>
<key>System</key>
- <dict>
- </dict>
+ <dict/>
</dict>
</plist>
# the include path (defaults to -I.)
# DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
# passed to ld/libtool (defaults to nothing)
+WARNING_CFLAGS=-Wall
# Library and Framework projects only:
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
* - initial revision
*/
+#include <getopt.h>
#include <unistd.h>
+#include <sysexits.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <SystemConfiguration/SCPrivate.h>
Boolean apply = TRUE;
+static struct option longopts[] = {
+// { "debug", no_argument, 0, 'd' },
+// { "verbose", no_argument, 0, 'v' },
+// { "do-not-apply", no_argument, 0, 'n' },
+ { "help", no_argument, 0, '?' },
+ { 0, 0, 0, 0 }
+};
+
+
void
usage(const char *command)
{
SCPrint(TRUE, stderr, CFSTR("usage: %s [-n] new-set-name\n"), command);
- return;
+ exit (EX_USAGE);
}
/* process any arguments */
- while ((opt = getopt(argc, argv, "dvn")) != -1)
+ while ((opt = getopt_long(argc, argv, "dvn", longopts, NULL)) != -1)
switch(opt) {
case 'd':
_sc_debug = TRUE;
}
/* check for set with matching name */
- for (i=0; i<nSets; i++) {
+ for (i = 0; i < nSets; i++) {
CFStringRef key = (CFStringRef) setKeys[i];
CFDictionaryRef dict = (CFDictionaryRef)setVals[i];
}
/* check for set with matching user-defined name */
- for (i=0; i<nSets; i++) {
+ for (i = 0; i < nSets; i++) {
CFStringRef key = (CFStringRef) setKeys[i];
CFDictionaryRef dict = (CFDictionaryRef)setVals[i];
}
}
- if (argc == 2) {
- SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available.\n"), newSet);
- } else {
- usage(command);
+ if (argc == 1) {
+ SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available.\n\n"), newSet);
}
- SCPrint(TRUE, stderr, CFSTR("\n"));
SCPrint(TRUE, stderr,
CFSTR("Defined sets include:%s\n"),
(currentMatched > 0) ? " (* == current set)" : "");
- for (i=0; i<nSets; i++) {
+ for (i = 0; i < nSets; i++) {
CFStringRef key = (CFStringRef) setKeys[i];
CFDictionaryRef dict = (CFDictionaryRef)setVals[i];
CFStringRef udn = CFDictionaryGetValue(dict, kSCPropUserDefinedName);
PROJECT_TYPE = Tool
HFILES = scutil.h commands.h dictionary.h session.h cache.h notify.h\
- tests.h
+ tests.h prefs.h
CFILES = scutil.c commands.c dictionary.c session.c cache.c notify.c\
- tests.c
+ tests.c prefs.c
OTHERSRCS = Makefile.preamble Makefile Makefile.postamble m.template\
h.template
PROF_LIBS = $(LIBS)
+NEXTSTEP_PB_LDFLAGS = -ledit
FRAMEWORKS = -framework CoreFoundation -framework SystemConfiguration
# the include path (defaults to -I.)
# DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
# passed to ld/libtool (defaults to nothing)
+WARNING_CFLAGS=-Wall
# Library and Framework projects only:
{
- DYNAMIC_CODE_GEN = YES;
+ "DYNAMIC_CODE_GEN" = YES;
FILESTABLE = {
- FRAMEWORKS = (CoreFoundation.framework, SystemConfiguration.framework);
+ 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 = ();
+ "H_FILES" = (
+ "scutil.h",
+ "commands.h",
+ "dictionary.h",
+ "session.h",
+ "cache.h",
+ "notify.h",
+ "tests.h",
+ "prefs.h"
+ );
+ "OTHER_LINKED" = (
+ "scutil.c",
+ "commands.c",
+ "dictionary.c",
+ "session.c",
+ "cache.c",
+ "notify.c",
+ "tests.c",
+ "prefs.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_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";
+ "NEXTSTEP_BUILDTOOL" = "/usr/bin/gnumake";
+ "NEXTSTEP_INSTALLDIR" = "/usr/sbin";
+ "NEXTSTEP_JAVA_COMPILER" = "/usr/bin/javac";
+ "NEXTSTEP_LINKEROPTIONS" = "-ledit";
+ "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";
+ 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";
}
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include <sys/types.h>
#include "scutil.h"
+#include "cache.h"
static CFComparisonResult
NULL);
if (listCnt > 0) {
- for (i=0; i<listCnt; i++) {
+ for (i = 0; i < listCnt; i++) {
SCPrint(TRUE,
stdout,
CFSTR(" subKey [%d] = %@\n"),
CFStringRef key;
CFPropertyListRef newValue;
- key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
- newValue = SCDynamicStoreCopyValue(store, key);
+ key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
+
+ if (argc == 1) {
+ newValue = SCDynamicStoreCopyValue(store, key);
+ } else {
+ CFArrayRef patterns;
+
+ patterns = CFArrayCreate(NULL, (const void **)&key, 1, &kCFTypeArrayCallBacks);
+ newValue = SCDynamicStoreCopyMultiple(store, NULL, patterns);
+ CFRelease(patterns);
+ }
+
CFRelease(key);
if (!newValue) {
SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#include "notify.h"
#include "tests.h"
-#include <SystemConfiguration/SCPrivate.h>
+#include "SCDynamicStoreInternal.h"
const cmdInfo commands[] = {
{ "set", 1, 1, do_set, 4, 0,
" set key : set key in data store w/current dict" },
- { "show", 1, 1, do_show, 4, 1,
- " show key : show dict in data store w/key" },
+ { "show", 1, 2, do_show, 4, 0,
+ " show key [\"pattern\"] : show values in data store w/key" },
{ "remove", 1, 1, do_remove, 4, 0,
" remove key : remove key from data store" },
int i;
char *cmd = argv[0];
- for (i=0; i<nCommands; i++) {
+ for (i = 0; i < nCommands; i++) {
if ((commands[i].ctype > 1) && !enablePrivateAPI) {
continue; /* if "private" API and access has not been enabled */
}
int i;
SCPrint(TRUE, stdout, CFSTR("\nAvailable commands:\n"));
- for (i=0; i<nCommands; i++) {
+ for (i = 0; i < nCommands; i++) {
if ((commands[i].ctype > 0) && !enablePrivateAPI) {
continue; /* if "private" API and access has not been enabled */
}
void
do_readFile(int argc, char **argv)
{
- CFSocketContext context;
- FILE *fp = fopen(argv[0], "r");
- CFSocketRef in;
- CFRunLoopSourceRef rls;
+ InputRef src;
- if (fp == NULL) {
+ /* allocate command input stream */
+ src = (InputRef)CFAllocatorAllocate(NULL, sizeof(Input), 0);
+ src->el = NULL;
+ src->fp = fopen(argv[0], "r");
+
+ if (src->fp == NULL) {
SCPrint(TRUE, stdout, CFSTR("f.read: could not open file (%s).\n"), strerror(errno));
+ CFAllocatorDeallocate(NULL, src);
return;
}
SCPrint(TRUE, stdout, CFSTR("f.read: reading file (%s).\n"), argv[0]);
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);
+ while (process_line(src) == TRUE) {
+ /* debug information, diagnostics */
+ __showMachPortStatus();
+ }
+
+ (void)fclose(src->fp);
+ CFAllocatorDeallocate(NULL, src);
return;
}
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
*/
#include "scutil.h"
+#include "dictionary.h"
//#include <stdlib.h>
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
* - initial revision
*/
+#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include "scutil.h"
-
-#include <SystemConfiguration/SCPrivate.h>
-#include "v1Compatibility.h"
+#include "notify.h"
static int osig;
n = CFArrayGetCount(changedKeys);
if (n > 0) {
- for (i=0; i<n; i++) {
+ for (i = 0; i < n; i++) {
SCPrint(TRUE,
stdout,
CFSTR(" changed key [%d] = %@\n"),
Boolean isRegex = FALSE;
CFMutableArrayRef sortedList;
+ if (!store) {
+ SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(kSCStatusNoStoreSession));
+ return;
+ }
+
if (argc == 1)
isRegex = TRUE;
- list = SCDynamicStoreCopyWatchedKeyList(store, isRegex);
+ list = isRegex ? watchedPatterns : watchedKeys;
if (!list) {
- if (SCError() != kSCStatusOK) {
- SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
- } else {
- SCPrint(TRUE,
- stdout,
- CFSTR(" no notifier %s.\n"),
- isRegex ? "patterns" : "keys");
- }
+ SCPrint(TRUE,
+ stdout,
+ CFSTR(" no notifier %s.\n"),
+ isRegex ? "patterns" : "keys");
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++) {
+ for (i = 0; i < listCnt; i++) {
SCPrint(TRUE,
stdout,
CFSTR(" notifier %s [%d] = %@\n"),
void
do_notify_add(int argc, char **argv)
{
- CFStringRef key;
- Boolean isRegex = FALSE;
+ CFStringRef key;
+ CFMutableArrayRef keys;
+ Boolean isRegex = FALSE;
+
+ if (!store) {
+ SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(kSCStatusNoStoreSession));
+ return;
+ }
key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
if (argc == 2)
isRegex = TRUE;
- if (!SCDynamicStoreAddWatchedKey(store, key, isRegex)) {
- SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
+ keys = isRegex ? watchedPatterns : watchedKeys;
+ if (CFArrayContainsValue(keys, CFRangeMake(0, CFArrayGetCount(keys)), key)) {
+ SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(kSCStatusKeyExists));
+ CFRelease(key);
+ return;
}
+
+ CFArrayAppendValue(keys, key);
CFRelease(key);
+
+ if (!SCDynamicStoreSetNotificationKeys(store, watchedKeys, watchedPatterns)) {
+ SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
+ }
+
return;
}
void
do_notify_remove(int argc, char **argv)
{
- CFStringRef key;
- Boolean isRegex = FALSE;
+ CFStringRef key;
+ CFMutableArrayRef keys;
+ CFIndex i;
+ Boolean isRegex = FALSE;
+
+ if (!store) {
+ SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(kSCStatusNoStoreSession));
+ return;
+ }
key = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman);
if (argc == 2)
isRegex = TRUE;
- if (!SCDynamicStoreRemoveWatchedKey(store, key, isRegex)) {
+ keys = isRegex ? watchedPatterns : watchedKeys;
+ i = CFArrayGetFirstIndexOfValue(keys, CFRangeMake(0, CFArrayGetCount(keys)), key);
+ CFRelease(key);
+
+ if (i == kCFNotFound) {
+ SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(kSCStatusNoKey));
+ return;
+ }
+
+ CFArrayRemoveValueAtIndex(keys, i);
+
+ if (!SCDynamicStoreSetNotificationKeys(store, watchedKeys, watchedPatterns)) {
SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
}
- CFRelease(key);
+
return;
}
listCnt = CFArrayGetCount(list);
if (listCnt > 0) {
- for (i=0; i<listCnt; i++) {
+ for (i = 0; i < listCnt; i++) {
SCPrint(TRUE,
stdout,
CFSTR(" changedKey [%d] = %@\n"),
}
-void
-do_notify_watch(int argc, char **argv)
+static void *
+_watcher(void *arg)
{
+ notifyRl = CFRunLoopGetCurrent();
+ if (!notifyRl) {
+ SCPrint(TRUE, stdout, CFSTR(" CFRunLoopGetCurrent() failed\n"));
+ return NULL;
+ }
+
notifyRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
if (!notifyRls) {
SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
+ return NULL;
+ }
+ CFRunLoopAddSource(notifyRl, notifyRls, kCFRunLoopDefaultMode);
+
+ CFRunLoopRun();
+ return NULL;
+}
+
+void
+do_notify_watch(int argc, char **argv)
+{
+ pthread_attr_t tattr;
+ pthread_t tid;
+
+ if (notifyRl) {
return;
}
- CFRunLoopAddSource(CFRunLoopGetCurrent(), notifyRls, kCFRunLoopDefaultMode);
+ 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, _watcher, NULL);
+ pthread_attr_destroy(&tattr);
+
return;
}
return;
}
} else {
- for (sig=1; sig<NSIG; sig++) {
+ for (sig = 1; sig < NSIG; sig++) {
if (strcasecmp(argv[0], sys_signame[sig]) == 0)
break;
}
SCPrint(TRUE, stdout, CFSTR("Signal must be one of the following:\n"));
str = CFStringCreateMutable(NULL, 0);
- for (sig=1; sig<NSIG; sig++) {
+ for (sig = 1; sig < NSIG; sig++) {
CFStringAppendFormat(str, NULL, CFSTR(" %-6s"), sys_signame[sig]);
if ((sig % 10) == 0) {
CFStringAppendFormat(str, NULL, CFSTR("\n"));
int ret;
if (notifyRls) {
- CFRunLoopRemoveSource(CFRunLoopGetCurrent(), notifyRls, kCFRunLoopDefaultMode);
+ CFRunLoopRemoveSource(notifyRl, notifyRls, kCFRunLoopDefaultMode);
CFRelease(notifyRls);
notifyRls = NULL;
}
+ if (notifyRl) {
+ CFRunLoopStop(notifyRl);
+ notifyRl = NULL;
+ }
+
if (!SCDynamicStoreNotifyCancel(store)) {
SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
return;
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT 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 29, 2003 Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+#include "scutil.h"
+#include "prefs.h"
+
+#include <SCPreferencesSetSpecific.h>
+
+
+static SCPreferencesRef
+_open()
+{
+ SCPreferencesRef prefs;
+
+ prefs = SCPreferencesCreate(NULL, CFSTR("scutil"), NULL);
+ if (!prefs) {
+ SCPrint(TRUE,
+ stdout,
+ CFSTR("SCPreferencesCreate() failed: %s\n"),
+ SCErrorString(SCError()));
+ exit (1);
+ }
+
+ return prefs;
+}
+
+
+static void
+_save(SCPreferencesRef prefs)
+{
+ if (!SCPreferencesCommitChanges(prefs)) {
+ switch (SCError()) {
+ case kSCStatusAccessError :
+ SCPrint(TRUE, stderr, CFSTR("Permission denied.\n"));
+ break;
+ default :
+ SCPrint(TRUE,
+ stdout,
+ CFSTR("SCPreferencesCommitChanges() failed: %s\n"),
+ SCErrorString(SCError()));
+ break;
+ }
+ exit (1);
+ }
+
+ if (!SCPreferencesApplyChanges(prefs)) {
+ SCPrint(TRUE,
+ stdout,
+ CFSTR("SCPreferencesApplyChanges() failed: %s\n"),
+ SCErrorString(SCError()));
+ exit (1);
+ }
+
+ return;
+}
+
+
+static CFStringRef
+_copyStringFromSTDIN()
+{
+ char buf[1024];
+ size_t len;
+ CFStringRef utf8;
+
+ if (fgets(buf, sizeof(buf), stdin) == NULL) {
+ return NULL;
+ }
+
+ len = strlen(buf);
+ if (buf[len-1] == '\n') {
+ buf[--len] = '\0';
+ }
+
+ utf8 = CFStringCreateWithBytes(NULL, buf, len, kCFStringEncodingUTF8, TRUE);
+ return utf8;
+}
+
+
+static void
+get_ComputerName(int argc, char **argv)
+{
+ CFStringEncoding encoding;
+ CFStringRef hostname;
+ CFDataRef utf8;
+
+ hostname = SCDynamicStoreCopyComputerName(NULL, &encoding);
+ if (!hostname) {
+ int sc_status = SCError();
+
+ switch (sc_status) {
+ case kSCStatusNoKey :
+ SCPrint(TRUE,
+ stderr,
+ CFSTR("ComputerName: not set\n"));
+ break;
+ default :
+ SCPrint(TRUE,
+ stderr,
+ CFSTR("SCDynamicStoreCopyComputerName() failed: %s\n"),
+ SCErrorString(SCError()));
+ break;
+ }
+ exit (1);
+ }
+
+ utf8 = CFStringCreateExternalRepresentation(NULL, hostname, kCFStringEncodingUTF8, 0);
+ if (!utf8) {
+ SCPrint(TRUE,
+ stderr,
+ CFSTR("ComputerName: could not convert to external representation\n"));
+ exit(1);
+ }
+ SCPrint(TRUE, stdout, CFSTR("%.*s\n"), CFDataGetLength(utf8), CFDataGetBytePtr(utf8));
+
+ CFRelease(utf8);
+ CFRelease(hostname);
+ exit(0);
+}
+
+
+static void
+set_ComputerName(int argc, char **argv)
+{
+ CFStringEncoding encoding;
+ CFStringRef hostname;
+ SCPreferencesRef prefs;
+
+ if (argc == 0) {
+ hostname = _copyStringFromSTDIN();
+ encoding = kCFStringEncodingUTF8;
+ } else {
+ hostname = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingASCII);
+ encoding = kCFStringEncodingASCII;
+ }
+
+ prefs = _open();
+ if (!SCPreferencesSetComputerName(prefs, hostname, encoding)) {
+ SCPrint(TRUE,
+ stdout,
+ CFSTR("SCPreferencesSetComputerName() failed: %s\n"),
+ SCErrorString(SCError()));
+ exit (1);
+ }
+ _save(prefs);
+ CFRelease(prefs);
+ CFRelease(hostname);
+ exit(0);
+}
+
+
+static void
+get_LocalHostName(int argc, char **argv)
+{
+ CFStringRef hostname;
+
+ hostname = SCDynamicStoreCopyLocalHostName(NULL);
+ if (!hostname) {
+ int sc_status = SCError();
+
+ switch (sc_status) {
+ case kSCStatusNoKey :
+ SCPrint(TRUE,
+ stderr,
+ CFSTR("LocalHostName: not set\n"));
+ break;
+ default :
+ SCPrint(TRUE,
+ stderr,
+ CFSTR("SCDynamicStoreCopyLocalHostName() failed: %s\n"),
+ SCErrorString(SCError()));
+ break;
+ }
+ exit (1);
+ }
+
+ SCPrint(TRUE, stdout, CFSTR("%@\n"), hostname);
+ CFRelease(hostname);
+ exit(0);
+}
+
+
+static void
+set_LocalHostName(int argc, char **argv)
+{
+ CFStringRef hostname = NULL;
+ SCPreferencesRef prefs;
+
+ if (argc == 0) {
+ hostname = _copyStringFromSTDIN();
+ } else {
+ hostname = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingASCII);
+ }
+
+ prefs = _open();
+ if (!SCPreferencesSetLocalHostName(prefs, hostname)) {
+ SCPrint(TRUE,
+ stderr,
+ CFSTR("SCPreferencesSetLocalHostName() failed: %s\n"),
+ SCErrorString(SCError()));
+ exit (1);
+ }
+ _save(prefs);
+ CFRelease(prefs);
+ CFRelease(hostname);
+ exit(0);
+}
+
+
+typedef void (*pref_func) (int argc, char **argv);
+
+static struct {
+ char *pref;
+ pref_func get;
+ pref_func set;
+} prefs[] = {
+ { "ComputerName", get_ComputerName, set_ComputerName },
+ { "LocalHostName", get_LocalHostName, set_LocalHostName }
+};
+#define N_PREFS (sizeof(prefs) / sizeof(prefs[0]))
+
+
+int
+findPref(char *pref)
+{
+ int i;
+
+ for (i = 0; i < (int)N_PREFS; i++) {
+ if (strcmp(pref, prefs[i].pref) == 0) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+
+void
+do_getPref(char *pref, int argc, char **argv)
+{
+ int i;
+
+ i = findPref(pref);
+ if (i >= 0) {
+ (*prefs[i].get)(argc, argv);
+ }
+ return;
+}
+
+
+void
+do_setPref(char *pref, int argc, char **argv)
+{
+ int i;
+
+ i = findPref(pref);
+ if (i >= 0) {
+ (*prefs[i].set)(argc, argv);
+ }
+ return;
+}
--- /dev/null
+/*
+ * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT 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 29, 2003 Allan Nathanson <ajn@apple.com>
+ * - initial revision
+ */
+
+#ifndef _PREFS_H
+#define _PREFS_H
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+int findPref (char *pref);
+void do_getPref (char *pref, int argc, char **argv);
+void do_setPref (char *pref, int argc, char **argv);
+
+__END_DECLS
+
+#endif /* !_PREFS_H */
/*
- * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Modification History
*
+ * September 25, 2002 Allan Nathanson <ajn@apple.com>
+ * - added command line history & editing
+ *
* 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
*/
#include <ctype.h>
+#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <termios.h>
#include <unistd.h>
#include <sysexits.h>
#include "commands.h"
#include "dictionary.h"
#include "tests.h"
+#include "prefs.h"
-#include <SystemConfiguration/SCPrivate.h>
#include "SCDynamicStoreInternal.h"
int nesting = 0;
+CFRunLoopRef notifyRl = NULL;
CFRunLoopSourceRef notifyRls = NULL;
-CFMutableArrayRef sources = NULL;
SCDynamicStoreRef store = NULL;
CFPropertyListRef value = NULL;
+CFMutableArrayRef watchedKeys = NULL;
+CFMutableArrayRef watchedPatterns = NULL;
+
+static struct option longopts[] = {
+// { "debug", no_argument, NULL, 'd' },
+// { "verbose", no_argument, NULL, 'v' },
+// { "SPI", no_argument, NULL, 'p' },
+// { "check-reachability", required_argument, NULL, 'r' },
+// { "timeout", required_argument, NULL, 't' },
+// { "wait-key", required_argument, NULL, 'w' },
+ { "get", required_argument, NULL, 0 },
+ { "help", no_argument, NULL, '?' },
+ { "set", required_argument, NULL, 0 },
+ { NULL, 0, NULL, 0 }
+};
static char *
-getLine(char *buf, int len, FILE *fp)
+getLine(char *buf, int len, InputRef src)
{
- int x;
+ int n;
- if (fgets(buf, len, fp) == NULL)
- return NULL;
+ if (src->el) {
+ int count;
+ const char *line;
- x = strlen(buf);
- if (buf[x-1] == '\n') {
- /* the entire line fit in the buffer, remove the newline */
- buf[x-1] = '\0';
+ line = el_gets(src->el, &count);
+ if (line == NULL)
+ return NULL;
+
+ strncpy(buf, line, len);
} else {
+ if (fgets(buf, len, src->fp) == NULL)
+ return NULL;
+ }
+
+ n = strlen(buf);
+ if (buf[n-1] == '\n') {
+ /* the entire line fit in the buffer, remove the newline */
+ buf[n-1] = '\0';
+ } else if (!src->el) {
/* eat the remainder of the line */
do {
- x = fgetc(fp);
- } while ((x != '\n') && (x != EOF));
+ n = fgetc(src->fp);
+ } while ((n != '\n') && (n != EOF));
+ }
+
+ if (src->h) {
+ HistEvent ev;
+
+ history(src->h, &ev, H_ENTER, buf);
}
return buf;
Boolean
-process_line(FILE *fp)
+process_line(InputRef src)
{
char line[LINE_LENGTH], *s, *arg, **argv = NULL;
int i, argc;
/* if end-of-file, exit */
- if (getLine(line, sizeof(line), fp) == NULL)
+ if (getLine(line, sizeof(line), src) == NULL)
return FALSE;
if (nesting > 0) {
}
-void
-runLoopProcessInput(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info)
-{
- FILE *fp = info;
-
- if (process_line(fp) == FALSE) {
- /* we don't want any more input from this stream, stop listening */
- CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
- (CFRunLoopSourceRef)CFArrayGetValueAtIndex(sources, 0),
- kCFRunLoopDefaultMode);
-
- /* we no longer need the fd (socket) */
- CFSocketInvalidate(s);
-
- /* we no longer need to track this source */
- CFArrayRemoveValueAtIndex(sources, 0);
-
- if (CFArrayGetCount(sources) > 0) {
- /* add the previous input source to the run loop */
- CFRunLoopAddSource(CFRunLoopGetCurrent(),
- (CFRunLoopSourceRef)CFArrayGetValueAtIndex(sources, 0),
- kCFRunLoopDefaultMode);
- } else {
- /* no more input sources, we're done! */
- exit (EX_OK);
- }
-
- /* decrement the nesting level */
- nesting--;
- }
-
- /* debug information, diagnostics */
- __showMachPortStatus();
-
- /* 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("\tinteractive access to the dynamic store.\n"));
+ SCPrint(TRUE, stderr, CFSTR("\n"));
+ SCPrint(TRUE, stderr, CFSTR(" or: %s -r nodename\n"), command);
+ SCPrint(TRUE, stderr, CFSTR(" or: %s -r address\n"), command);
+ SCPrint(TRUE, stderr, CFSTR(" or: %s -r local-address remote-address\n"), command);
+ SCPrint(TRUE, stderr, CFSTR("\tcheck reachability of node, address, or address pair.\n"));
+ SCPrint(TRUE, stderr, CFSTR("\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"));
+ SCPrint(TRUE, stderr, CFSTR(" or: %s --get pref\n"), command);
+ SCPrint(TRUE, stderr, CFSTR(" or: %s --set pref [newval]\n"), command);
+ SCPrint(TRUE, stderr, CFSTR("\tpref\tdisplay (or set) the specified preference. Valid preferences\n"));
+ SCPrint(TRUE, stderr, CFSTR("\t\tinclude:\n"));
+ SCPrint(TRUE, stderr, CFSTR("\t\t\tComputerName, LocalHostName\n"));
+ SCPrint(TRUE, stderr, CFSTR("\tnewval\tNew preference value to be set. If not specified,\n"));
+ SCPrint(TRUE, stderr, CFSTR("\t\tthe new value will be read from standard input.\n"));
exit (EX_USAGE);
}
+static char *
+prompt(EditLine *el)
+{
+ return "> ";
+}
+
+
int
main(int argc, char * const argv[])
{
- CFSocketContext context = { 0, stdin, NULL, NULL, NULL };
- char *dest = NULL;
- CFSocketRef in;
+ char *get = NULL;
extern int optind;
int opt;
+ int opti;
const char *prog = argv[0];
- CFRunLoopSourceRef rls;
+ Boolean reach = FALSE;
+ char *set = NULL;
+ InputRef src;
int timeout = 15; /* default timeout (in seconds) */
char *wait = NULL;
+ int xStore = 0; /* non dynamic store command line options */
/* process any arguments */
- while ((opt = getopt(argc, argv, "dvpr:t:w:")) != -1)
+ while ((opt = getopt_long(argc, argv, "dvprt:w:", longopts, &opti)) != -1)
switch(opt) {
case 'd':
_sc_debug = TRUE;
enablePrivateAPI = TRUE;
break;
case 'r':
- dest = optarg;
+ reach = TRUE;
+ xStore++;
break;
case 't':
timeout = atoi(optarg);
break;
case 'w':
wait = optarg;
+ xStore++;
+ break;
+ case 0:
+ if (strcmp(longopts[opti].name, "get") == 0) {
+ get = optarg;
+ xStore++;
+ } else if (strcmp(longopts[opti].name, "set") == 0) {
+ set = optarg;
+ xStore++;
+ }
break;
case '?':
default :
argc -= optind;
argv += optind;
- if (dest && wait) {
+ if (xStore > 1) {
+ // if we are attempting to process more than one type of request
usage(prog);
}
/* are we checking the reachability of a host/address */
- if (dest) {
- do_checkReachability(dest);
+ if (reach) {
+ if ((argc < 1) || (argc > 2)) {
+ usage(prog);
+ }
+ do_checkReachability(argc, (char **)argv);
/* NOT REACHED */
}
/* NOT REACHED */
}
+ /* are we looking up a preference value */
+ if (get) {
+ if (findPref(get) < 0) {
+ usage(prog);
+ }
+ do_getPref(get, argc, (char **)argv);
+ /* NOT REACHED */
+ }
+
+ /* are we changing a preference value */
+ if (set) {
+ if (findPref(set) < 0) {
+ usage(prog);
+ }
+ do_setPref(set, argc, (char **)argv);
+ /* NOT REACHED */
+ }
+
/* start with an empty dictionary */
do_dictInit(0, NULL);
- /* create a "socket" reference with the file descriptor associated with stdin */
- in = CFSocketCreateWithNative(NULL,
- STDIN_FILENO,
- kCFSocketReadCallBack,
- runLoopProcessInput,
- &context);
+ /* allocate command input stream */
+ src = (InputRef)CFAllocatorAllocate(NULL, sizeof(Input), 0);
+ src->fp = stdin;
+ src->el = NULL;
+ src->h = NULL;
+
+ if (isatty(fileno(src->fp))) {
+ int editmode = 1;
+ HistEvent ev;
+ struct termios t;
+
+ if (tcgetattr(fileno(src->fp), &t) != -1) {
+ if ((t.c_lflag & ECHO) == 0) {
+ editmode = 0;
+ }
+ }
+ src->el = el_init(prog, src->fp, stdout, stderr);
+ src->h = history_init();
+
+ (void)history(src->h, &ev, H_SETSIZE, INT_MAX);
+ el_set(src->el, EL_HIST, history, src->h);
- /* Create a run loop source for the (stdin) file descriptor */
- rls = CFSocketCreateRunLoopSource(NULL, in, nesting);
+ if (!editmode) {
+ el_set(src->el, EL_EDITMODE, 0);
+ }
- /* keep track of input file sources */
- sources = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
- CFArrayAppendValue(sources, rls);
+ el_set(src->el, EL_EDITOR, "emacs");
+ el_set(src->el, EL_PROMPT, prompt);
- /* add this source to the run loop */
- CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
- CFRelease(rls);
- CFRelease(in);
+ el_source(src->el, NULL);
- /* show (initial) debug information, diagnostics */
- __showMachPortStatus();
+ if ((el_get(src->el, EL_EDITMODE, &editmode) != -1) && editmode != 0) {
+ el_set(src->el, EL_SIGNAL, 1);
+ } else {
+ history_end(src->h);
+ src->h = NULL;
+ el_end(src->el);
+ src->el = NULL;
+ }
+ }
- /* issue (initial) prompt */
- if (isatty(STDIN_FILENO)) {
- printf("> ");
- fflush(stdout);
+ while (process_line(src) == TRUE) {
+ /* debug information, diagnostics */
+ __showMachPortStatus();
}
- CFRunLoopRun(); /* process input, process events */
+ /* close the socket, free resources */
+ if (src->h) history_end(src->h);
+ if (src->el) el_end(src->el);
+ (void)fclose(src->fp);
+ CFAllocatorDeallocate(NULL, src);
exit (EX_OK); // insure the process exit status is 0
return 0; // ...and make main fit the ANSI spec.
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
#define _SC_H
#include <sys/cdefs.h>
+#include <histedit.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <SystemConfiguration/SCValidation.h>
#include <SystemConfiguration/SCPrivate.h>
+typedef struct {
+ FILE *fp;
+ EditLine *el;
+ History *h;
+} Input, *InputRef;
+
+
extern int nesting;
+extern CFRunLoopRef notifyRl;
extern CFRunLoopSourceRef notifyRls;
-extern CFMutableArrayRef sources;
extern SCDynamicStoreRef store;
extern CFPropertyListRef value;
+extern CFMutableArrayRef watchedKeys;
+extern CFMutableArrayRef watchedPatterns;
__BEGIN_DECLS
-Boolean process_line (FILE *fp);
-
-void runLoopProcessInput (CFSocketRef s,
- CFSocketCallBackType type,
- CFDataRef address,
- const void *data,
- void *info);
+Boolean process_line (InputRef src);
__END_DECLS
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
*/
#include "scutil.h"
+#include "session.h"
#include "notify.h"
void
do_open(int argc, char **argv)
{
- if (store) CFRelease(store);
+ if (store) {
+ CFRelease(store);
+ CFRelease(watchedKeys);
+ CFRelease(watchedPatterns);
+ }
store = SCDynamicStoreCreate(NULL, CFSTR("scutil"), storeCallback, NULL);
if (!store) {
return;
}
+ watchedKeys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ watchedPatterns = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
return;
}
notifyRls = NULL;
}
+ if (notifyRl) {
+ CFRunLoopStop(notifyRl);
+ notifyRl = NULL;
+ }
+
if (store) {
CFRelease(store);
store = NULL;
+ CFRelease(watchedKeys);
+ watchedKeys = NULL;
+ CFRelease(watchedPatterns);
+ watchedPatterns = NULL;
}
return;
}
* 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
*/
#include "scutil.h"
+#include "tests.h"
-#include <SystemConfiguration/SCPrivate.h>
#include <sys/time.h>
+#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void
-do_checkReachability(char *node)
+do_checkReachability(int argc, char **argv)
{
SCNetworkConnectionFlags flags = 0;
- Boolean ok = FALSE;
+ SCNetworkReachabilityRef target = NULL;
- if (isdigit(node[0])) {
+ if (argc == 1) {
struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
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);
+
+ bzero(&sin6, sizeof(sin6));
+ sin6.sin6_len = sizeof(sin6);
+ sin6.sin6_family = AF_INET6;
+
+ if (inet_aton(argv[0], &sin.sin_addr) == 1) {
+ target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin);
+ } else if (inet_pton(AF_INET6, argv[0], &sin6.sin6_addr) == 1) {
+ char *p;
+
+ p = strchr(argv[0], '%');
+ if (p != NULL) {
+ sin6.sin6_scope_id = if_nametoindex(p+1);
+ }
+
+ target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin6);
+ } else {
+ target = SCNetworkReachabilityCreateWithName(NULL, argv[0]);
+ }
+ } else /* if (argc == 2) */ {
+ struct sockaddr_in l_sin;
+ struct sockaddr_in r_sin;
+
+ bzero(&l_sin, sizeof(l_sin));
+ l_sin.sin_len = sizeof(l_sin);
+ l_sin.sin_family = AF_INET;
+ if (inet_aton(argv[0], &l_sin.sin_addr) == 0) {
+ SCPrint(TRUE, stderr, CFSTR("Could not interpret address \"%s\"\n"), argv[0]);
exit(1);
}
- ok = SCNetworkCheckReachabilityByAddress((struct sockaddr *)&sin,
- sizeof(sin),
- &flags);
- } else {
- ok = SCNetworkCheckReachabilityByName(node,
- &flags);
+ bzero(&r_sin, sizeof(r_sin));
+ r_sin.sin_len = sizeof(r_sin);
+ r_sin.sin_family = AF_INET;
+ if (inet_aton(argv[1], &r_sin.sin_addr) == 0) {
+ SCPrint(TRUE, stderr, CFSTR("Could not interpret address \"%s\"\n"), argv[1]);
+ exit(1);
+ }
+
+ target = SCNetworkReachabilityCreateWithAddressPair(NULL,
+ (struct sockaddr *)&l_sin,
+ (struct sockaddr *)&r_sin);
+ }
+
+ if (!target) {
+ SCPrint(TRUE, stderr, CFSTR(" Could not determine status: %s\n"), SCErrorString(SCError()));
+ exit(1);
}
- if (!ok) {
+ if (!SCNetworkReachabilityGetFlags(target, &flags)) {
SCPrint(TRUE, stderr, CFSTR(" Could not determine status: %s\n"), SCErrorString(SCError()));
exit(1);
}
flags &= ~kSCNetworkFlagsInterventionRequired;
SCPrint(flags != 0, stdout, CFSTR(","));
}
+ if (flags & kSCNetworkFlagsIsLocalAddress) {
+ SCPrint(TRUE, stdout, CFSTR("Local Address"));
+ flags &= ~kSCNetworkFlagsIsLocalAddress;
+ SCPrint(flags != 0, stdout, CFSTR(","));
+ }
+ if (flags & kSCNetworkFlagsIsDirect) {
+ SCPrint(TRUE, stdout, CFSTR("Directly Reachable Address"));
+ flags &= ~kSCNetworkFlagsIsDirect;
+ SCPrint(flags != 0, stdout, CFSTR(","));
+ }
SCPrint(_sc_debug, stdout, CFSTR(")"));
} else {
SCPrint(_sc_debug, stdout, CFSTR(" ("));
/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 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
+ *
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
* @APPLE_LICENSE_HEADER_END@
*/
__BEGIN_DECLS
-void do_checkReachability (char *node);
+void do_checkReachability (int argc, char **argv);
void do_snapshot (int argc, char **argv);
void do_wait (char *waitKey, int timeout);