+#if !TARGET_OS_IPHONE
+static SCBridgeInterfaceRef
+copyAutoBridgeInterface(SCPreferencesRef prefs, CFStringRef bridgeName)
+{
+ SCBridgeInterfaceRef bridge = NULL;
+ CFArrayRef interfaces;
+
+ // exclude Bridge [member] interfaces
+ interfaces = SCBridgeInterfaceCopyAll(prefs);
+ if (interfaces != NULL) {
+ CFIndex i;
+ CFIndex n;
+
+ n = CFArrayGetCount(interfaces);
+ for (i = 0; i < n; i++) {
+ SCBridgeInterfaceRef interface;
+ CFStringRef name = NULL;
+ CFDictionaryRef options;
+
+ interface = CFArrayGetValueAtIndex(interfaces, i);
+ options = SCBridgeInterfaceGetOptions(interface);
+ if ((options != NULL) &&
+ CFDictionaryGetValueIfPresent(options,
+ CFSTR("__AUTO__"),
+ (const void **)&name) &&
+ _SC_CFEqual(name, bridgeName)) {
+ bridge = interface;
+ CFRetain(bridge);
+ break;
+ }
+ }
+
+ CFRelease(interfaces);
+ }
+
+ if (bridge == NULL) {
+ bridge = SCBridgeInterfaceCreate(prefs);
+ if (bridge != NULL) {
+ CFMutableDictionaryRef newOptions;
+ Boolean ok;
+
+ newOptions = CFDictionaryCreateMutable(NULL, 0,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ CFDictionarySetValue(newOptions, CFSTR("__AUTO__"), bridgeName);
+ ok = SCBridgeInterfaceSetOptions(bridge, newOptions);
+ CFRelease(newOptions);
+ if (!ok) {
+ CFRelease(bridge);
+ bridge = NULL;
+ }
+ }
+ }
+
+ return bridge;
+}
+#endif // !TARGET_OS_IPHONE
+
+
+static CFArrayRef
+copyServices(SCNetworkSetRef set)
+{
+ CFArrayRef services;
+ SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set;
+
+ // first, assume that we only want to add new services
+ // for those interfaces that are not represented in the
+ // current set.
+ services = SCNetworkSetCopyServices(set);
+ if ((services != NULL) && setPrivate->established) {
+ // but, if we are given an existing (or "established") set
+ // than we only want to add new services for those interfaces
+ // that are not represented in *any* set.
+ CFRelease(services);
+ services = SCNetworkServiceCopyAll(setPrivate->prefs);
+ }
+
+ return services;
+}
+
+
+#if !TARGET_OS_IPHONE
+static CF_RETURNS_RETAINED CFArrayRef
+updateServices(CFArrayRef services, SCNetworkInterfaceRef interface)
+{
+ CFStringRef bsdName;
+ CFIndex i;
+ CFIndex n;
+ CFMutableArrayRef newServices;
+
+ if (services == NULL) {
+ return NULL;
+ }
+
+ bsdName = SCNetworkInterfaceGetBSDName(interface);
+
+ newServices = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+
+ n = CFArrayGetCount(services);
+ for (i = 0; i < n; i++) {
+ SCNetworkInterfaceRef interface;
+ CFStringRef interfaceName;
+ SCNetworkServiceRef newService;
+ SCNetworkServiceRef service;
+ CFStringRef serviceID;
+ SCNetworkServicePrivateRef servicePrivate;
+
+ service = CFArrayGetValueAtIndex(services, i);
+ interface = SCNetworkServiceGetInterface(service);
+ interfaceName = SCNetworkInterfaceGetBSDName(interface);
+ if (!_SC_CFEqual(interfaceName, bsdName)) {
+ // if not a match, retain
+ CFArrayAppendValue(newServices, service);
+ continue;
+ }
+
+ // if a match, update
+ serviceID = SCNetworkServiceGetServiceID(service);
+ servicePrivate = (SCNetworkServicePrivateRef)service;
+ newService = SCNetworkServiceCopy(servicePrivate->prefs, serviceID);
+ if (newService != NULL) {
+ CFArrayAppendValue(newServices, newService);
+ CFRelease(newService);
+ }
+ }
+
+ return newServices;
+}
+#endif // !TARGET_OS_IPHONE
+
+
+static __inline__ Boolean
+skipInterface(SCNetworkInterfaceRef interface)
+{
+ CFStringRef action;
+
+ action = _SCNetworkInterfaceGetConfigurationAction(interface);
+ if (isA_CFString(action) &&
+ CFEqual(action, kSCNetworkInterfaceConfigurationActionValueNone)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+CFComparisonResult
+_SCNetworkSetCompare(const void *val1, const void *val2, void *context)
+{
+#pragma unused(context)
+ CFStringRef id1;
+ CFStringRef id2;
+ CFStringRef name1;
+ CFStringRef name2;
+ SCNetworkSetRef s1 = (SCNetworkSetRef)val1;
+ SCNetworkSetRef s2 = (SCNetworkSetRef)val2;
+
+ name1 = SCNetworkSetGetName(s1);
+ name2 = SCNetworkSetGetName(s2);
+
+ if (name1 != NULL) {
+ if (name2 != NULL) {
+ return CFStringCompare(name1, name2, 0);
+ } else {
+ return kCFCompareLessThan;
+ }
+ }
+
+ if (name2 != NULL) {
+ return kCFCompareGreaterThan;
+ }
+
+ id1 = SCNetworkSetGetSetID(s1);
+ id2 = SCNetworkSetGetSetID(s2);
+ return CFStringCompare(id1, id2, 0);
+}
+
+