Boolean SCVLANInterfaceRemove(SCVLANInterfaceRef vlan) { CFStringRef vlan_if; SCNetworkInterfacePrivateRef interfacePrivate = (SCNetworkInterfacePrivateRef)vlan; Boolean ok; CFStringRef path; if (!isA_SCVLANInterface(vlan)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (interfacePrivate->prefs == NULL) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } vlan_if = SCNetworkInterfaceGetBSDName(vlan); path = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/%@/%@"), kSCPrefVirtualNetworkInterfaces, kSCNetworkInterfaceTypeVLAN, vlan_if); ok = SCPreferencesPathRemoveValue(interfacePrivate->prefs, path); CFRelease(path); return ok; }
Boolean SCNetworkSetRemoveService(SCNetworkSetRef set, SCNetworkServiceRef service) { SCNetworkInterfaceRef interface; CFArrayRef interface_config = NULL; Boolean ok; CFStringRef path; int sc_status = kSCStatusOK; SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef)service; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (!isA_SCNetworkService(service) || (servicePrivate->prefs == NULL)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } // remove service from ServiceOrder _serviceOrder_remove(set, service); // get the [deep] interface configuration settings interface = SCNetworkServiceGetInterface(service); if (interface != NULL) { interface_config = __SCNetworkInterfaceCopyDeepConfiguration(set, interface); if (interface_config != NULL) { // remove the interface configuration from all sets which contain this service. __SCNetworkInterfaceSetDeepConfiguration(set, interface, NULL); } } // remove the link between "set" and the "service" path = SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL, setPrivate->setID, servicePrivate->serviceID, NULL); ok = SCPreferencesPathRemoveValue(setPrivate->prefs, path); if (!ok) { sc_status = SCError(); // preserve the error } CFRelease(path); // push the [deep] interface configuration [back] into all sets which contain the service. if (interface_config != NULL) { __SCNetworkInterfaceSetDeepConfiguration(set, interface, interface_config); } if (interface_config != NULL) CFRelease(interface_config); if (!ok) { _SCErrorSet(sc_status); } return ok; }
__private_extern__ Boolean __setPrefsConfiguration(SCPreferencesRef prefs, CFStringRef path, CFDictionaryRef config, Boolean keepInactive) { CFDictionaryRef curConfig; CFMutableDictionaryRef newConfig = NULL; Boolean ok; if ((config != NULL) && !isA_CFDictionary(config)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } curConfig = SCPreferencesPathGetValue(prefs, path); if (config != NULL) { newConfig = CFDictionaryCreateMutableCopy(NULL, 0, config); } if (keepInactive) { if (config == NULL) { newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } if (isA_CFDictionary(curConfig) && CFDictionaryContainsKey(curConfig, kSCResvInactive)) { // if currently disabled CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); } else { // if currently enabled CFDictionaryRemoveValue(newConfig, kSCResvInactive); } } // set new configuration if (_SC_CFEqual(curConfig, newConfig)) { // if no change if (newConfig != NULL) CFRelease(newConfig); ok = TRUE; } else if (newConfig != NULL) { // if new configuration (or we are preserving a disabled state) ok = SCPreferencesPathSetValue(prefs, path, newConfig); CFRelease(newConfig); } else { ok = SCPreferencesPathRemoveValue(prefs, path); if (!ok && (SCError() == kSCStatusNoKey)) { ok = TRUE; } } return ok; }
__private_extern__ Boolean __setPrefsEnabled(SCPreferencesRef prefs, CFStringRef path, Boolean enabled) { CFDictionaryRef curConfig; CFMutableDictionaryRef newConfig = NULL; Boolean ok = FALSE; // preserve current configuration curConfig = SCPreferencesPathGetValue(prefs, path); if (curConfig != NULL) { if (!isA_CFDictionary(curConfig)) { _SCErrorSet(kSCStatusFailed); return FALSE; } newConfig = CFDictionaryCreateMutableCopy(NULL, 0, curConfig); if (enabled) { // enable CFDictionaryRemoveValue(newConfig, kSCResvInactive); } else { // disable CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); } } else { if (!enabled) { // disable newConfig = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(newConfig, kSCResvInactive, kCFBooleanTrue); } } // set new configuration if (_SC_CFEqual(curConfig, newConfig)) { // if no change if (newConfig != NULL) CFRelease(newConfig); ok = TRUE; } else if (newConfig != NULL) { // if updated configuration (or we are establishing as disabled) ok = SCPreferencesPathSetValue(prefs, path, newConfig); CFRelease(newConfig); } else { ok = SCPreferencesPathRemoveValue(prefs, path); if (!ok && (SCError() == kSCStatusNoKey)) { ok = TRUE; } } return ok; }
Boolean SCNetworkSetRemove(SCNetworkSetRef set) { CFStringRef currentPath; Boolean ok = FALSE; CFStringRef path; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } currentPath = SCPreferencesGetValue(setPrivate->prefs, kSCPrefCurrentSet); path = SCPreferencesPathKeyCreateSet(NULL, setPrivate->setID); if (!isA_CFString(currentPath) || !CFEqual(currentPath, path)) { ok = SCPreferencesPathRemoveValue(setPrivate->prefs, path); } else { _SCErrorSet(kSCStatusInvalidArgument); } CFRelease(path); return ok; }
Boolean SCNetworkSetAddService(SCNetworkSetRef set, SCNetworkServiceRef service) { SCNetworkInterfaceRef interface; CFArrayRef interface_config = NULL; CFStringRef link; Boolean ok; CFStringRef path; SCNetworkServicePrivateRef servicePrivate = (SCNetworkServicePrivateRef)service; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (!isA_SCNetworkService(service) || (servicePrivate->prefs == NULL)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } // make sure that we do not add an orphaned network service if its // associated interface is a member of a bond or bridge. interface = SCNetworkServiceGetInterface(service); if ((interface != NULL) && __SCNetworkInterfaceIsMember(servicePrivate->prefs, interface)) { _SCErrorSet(kSCStatusKeyExists); return FALSE; } //#define PREVENT_DUPLICATE_SETS #ifdef PREVENT_DUPLICATE_SETS CFArrayRef sets; // ensure that each service is only a member of ONE set sets = SCNetworkSetCopyAll(setPrivate->prefs); if (sets != NULL) { CFIndex i; CFIndex n; n = CFArrayGetCount(sets); for (i = 0; i < n; i++) { Boolean found; CFArrayRef services; SCNetworkSetRef set; set = CFArrayGetValueAtIndex(sets, i); services = SCNetworkSetCopyServices(set); found = CFArrayContainsValue(services, CFRangeMake(0, CFArrayGetCount(services)), service); CFRelease(services); if (found) { CFRelease(sets); _SCErrorSet(kSCStatusKeyExists); return FALSE; } } CFRelease(sets); } #endif /* PREVENT_DUPLICATE_SETS */ // get the [deep] interface configuration settings interface = SCNetworkServiceGetInterface(service); if (interface != NULL) { interface_config = __SCNetworkInterfaceCopyDeepConfiguration(set, interface); } // create the link between "set" and the "service" path = SCPreferencesPathKeyCreateSetNetworkServiceEntity(NULL, // allocator setPrivate->setID, // set servicePrivate->serviceID, // service NULL); // entity link = SCPreferencesPathKeyCreateNetworkServiceEntity(NULL, // allocator servicePrivate->serviceID, // service NULL); // entity ok = SCPreferencesPathSetLink(setPrivate->prefs, path, link); #ifdef PREVENT_DUPLICATE_SERVICE_NAMES if (ok) { ok = ensure_unique_service_name(service); if (!ok) { // if we could not ensure a unique name, remove the (just added) // link between the "set" and the "service" (void) SCPreferencesPathRemoveValue(setPrivate->prefs, path); } } #endif // PREVENT_DUPLICATE_SERVICE_NAMES CFRelease(path); CFRelease(link); if (!ok) { goto done; } // push the [deep] interface configuration into all sets which contain this service. if (interface != NULL) { __SCNetworkInterfaceSetDeepConfiguration(set, interface, interface_config); } // add service to ServiceOrder _serviceOrder_add(set, service); // mark set as no longer "new" setPrivate->established = TRUE; done : if (interface_config != NULL) CFRelease(interface_config); return ok; }
Boolean _SCNetworkSetSetSetID(SCNetworkSetRef set, CFStringRef newSetID) { SCNetworkSetRef currentSet = NULL; SCNetworkSetPrivateRef currentSetPrivate = NULL; CFDictionaryRef entity; CFStringRef newPath; Boolean ok = FALSE; CFStringRef oldPath = NULL; SCNetworkSetPrivateRef setPrivate = (SCNetworkSetPrivateRef)set; Boolean updateCurrentSet = FALSE; if (!isA_SCNetworkSet(set)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } if (!isA_CFString(newSetID)) { _SCErrorSet(kSCStatusInvalidArgument); return FALSE; } // If newSetID is equal to current setID, our work is done if (CFEqual(newSetID, setPrivate->setID)) { return TRUE; } newPath = SCPreferencesPathKeyCreateSet(NULL, newSetID); entity = SCPreferencesPathGetValue(setPrivate->prefs, newPath); if (isA_CFDictionary(entity)) { // if the new set already exists _SCErrorSet(kSCStatusKeyExists); goto done; } oldPath = SCPreferencesPathKeyCreateSet(NULL, setPrivate->setID); entity = SCPreferencesPathGetValue(setPrivate->prefs, oldPath); if (!isA_CFDictionary(entity)) { // if the set has already been removed _SCErrorSet(kSCStatusNoKey); goto done; } ok = SCPreferencesPathSetValue(setPrivate->prefs, newPath, entity); if (!ok) { goto done; } ok = SCPreferencesPathRemoveValue(setPrivate->prefs, oldPath); if (!ok) { goto done; } // update current set (if needed) currentSet = SCNetworkSetCopyCurrent(setPrivate->prefs); if (currentSet != NULL) { currentSetPrivate = (SCNetworkSetPrivateRef)currentSet; if (CFEqual(currentSetPrivate->setID, setPrivate->setID)) { updateCurrentSet = TRUE; } CFRelease(currentSet); } CFRetain(newSetID); CFRelease(setPrivate->setID); setPrivate->setID = newSetID; if (updateCurrentSet) { SCNetworkSetSetCurrent(set); } done: if (oldPath != NULL) { CFRelease(oldPath); } if (newPath != NULL) { CFRelease(newPath); } return ok; }