2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * May 13, 2004 Allan Nathanson <ajn@apple.com>
32 #include <CoreFoundation/CoreFoundation.h>
33 #include <CoreFoundation/CFRuntime.h>
34 #include <SystemConfiguration/SystemConfiguration.h>
35 #include <SystemConfiguration/SCNetworkConfigurationInternal.h>
36 #include <SystemConfiguration/SCValidation.h>
37 #include <SystemConfiguration/SCPrivate.h>
42 static CFStringRef
__SCNetworkServiceCopyDescription (CFTypeRef cf
);
43 static void __SCNetworkServiceDeallocate (CFTypeRef cf
);
44 static Boolean
__SCNetworkServiceEqual (CFTypeRef cf1
, CFTypeRef cf2
);
47 static CFTypeID __kSCNetworkServiceTypeID
= _kCFRuntimeNotATypeID
;
50 static const CFRuntimeClass __SCNetworkServiceClass
= {
52 "SCNetworkService", // className
55 __SCNetworkServiceDeallocate
, // dealloc
56 __SCNetworkServiceEqual
, // equal
58 NULL
, // copyFormattingDesc
59 __SCNetworkServiceCopyDescription
// copyDebugDesc
63 static pthread_once_t initialized
= PTHREAD_ONCE_INIT
;
66 static __inline__ CFTypeRef
67 isA_SCNetworkService(CFTypeRef obj
)
69 return (isA_CFType(obj
, SCNetworkServiceGetTypeID()));
74 __SCNetworkServiceCopyDescription(CFTypeRef cf
)
76 CFAllocatorRef allocator
= CFGetAllocator(cf
);
77 CFMutableStringRef result
;
78 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)cf
;
80 result
= CFStringCreateMutable(allocator
, 0);
81 CFStringAppendFormat(result
, NULL
, CFSTR("<SCNetworkService %p [%p]> { "), cf
, allocator
);
82 CFStringAppendFormat(result
, NULL
, CFSTR("id=%@"), servicePrivate
->serviceID
);
83 // CFStringAppendFormat(result, NULL, CFSTR(", prefs=%@"), servicePrivate->prefs);
84 CFStringAppendFormat(result
, NULL
, CFSTR(" }"));
91 __SCNetworkServiceDeallocate(CFTypeRef cf
)
93 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)cf
;
95 /* release resources */
97 CFRelease(servicePrivate
->serviceID
);
98 if (servicePrivate
->interface
!= NULL
) CFRelease(servicePrivate
->interface
);
99 CFRelease(servicePrivate
->prefs
);
106 __SCNetworkServiceEqual(CFTypeRef cf1
, CFTypeRef cf2
)
108 SCNetworkServicePrivateRef s1
= (SCNetworkServicePrivateRef
)cf1
;
109 SCNetworkServicePrivateRef s2
= (SCNetworkServicePrivateRef
)cf2
;
114 if (s1
->prefs
!= s2
->prefs
)
115 return FALSE
; // if not the same prefs
117 if (!CFEqual(s1
->serviceID
, s2
->serviceID
))
118 return FALSE
; // if not the same service identifier
125 __SCNetworkServiceInitialize(void)
127 __kSCNetworkServiceTypeID
= _CFRuntimeRegisterClass(&__SCNetworkServiceClass
);
132 __private_extern__ SCNetworkServicePrivateRef
133 __SCNetworkServiceCreatePrivate(CFAllocatorRef allocator
,
134 CFStringRef serviceID
,
135 SCNetworkInterfaceRef interface
,
136 SCPreferencesRef prefs
)
138 SCNetworkServicePrivateRef servicePrivate
;
141 /* initialize runtime */
142 pthread_once(&initialized
, __SCNetworkServiceInitialize
);
144 /* allocate target */
145 size
= sizeof(SCNetworkServicePrivate
) - sizeof(CFRuntimeBase
);
146 servicePrivate
= (SCNetworkServicePrivateRef
)_CFRuntimeCreateInstance(allocator
,
147 __kSCNetworkServiceTypeID
,
150 if (servicePrivate
== NULL
) {
154 servicePrivate
->prefs
= CFRetain(prefs
);
155 servicePrivate
->serviceID
= CFStringCreateCopy(NULL
, serviceID
);
156 servicePrivate
->interface
= (interface
!= NULL
) ? CFRetain(interface
) : NULL
;
158 return servicePrivate
;
162 /* ---------- SCNetworkService APIs ---------- */
169 SCNetworkServiceAddProtocolType(SCNetworkServiceRef service
, CFStringRef protocolType
)
171 CFDictionaryRef entity
;
172 CFDictionaryRef newEntity
= NULL
;
175 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
177 if (!__SCNetworkProtocolIsValidType(protocolType
)) {
178 _SCErrorSet(kSCStatusInvalidArgument
);
182 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
183 servicePrivate
->serviceID
, // service
184 protocolType
); // entity
186 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
187 if (entity
!= NULL
) {
188 // if "protocol" already exists
189 _SCErrorSet(kSCStatusKeyExists
);
193 if (servicePrivate
->interface
!= NULL
) {
194 SCNetworkInterfaceRef childInterface
;
195 CFStringRef childInterfaceType
= NULL
;
196 CFStringRef interfaceType
;
198 interfaceType
= SCNetworkInterfaceGetInterfaceType(servicePrivate
->interface
);
199 childInterface
= SCNetworkInterfaceGetInterface(servicePrivate
->interface
);
200 if (childInterface
!= NULL
) {
201 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
204 newEntity
= __copyProtocolTemplate(interfaceType
, childInterfaceType
, protocolType
);
207 if (newEntity
== NULL
) {
208 newEntity
= CFDictionaryCreate(NULL
,
212 &kCFTypeDictionaryKeyCallBacks
,
213 &kCFTypeDictionaryValueCallBacks
);
216 ok
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
);
217 CFRelease(newEntity
);
226 CFArrayRef
/* of SCNetworkServiceRef's */
227 SCNetworkServiceCopyAll(SCPreferencesRef prefs
)
229 CFMutableArrayRef array
;
232 CFDictionaryRef services
;
234 path
= SCPreferencesPathKeyCreateNetworkServices(NULL
);
235 services
= SCPreferencesPathGetValue(prefs
, path
);
238 if ((services
!= NULL
) && !isA_CFDictionary(services
)) {
242 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
244 n
= (services
!= NULL
) ? CFDictionaryGetCount(services
) : 0;
247 const void * keys_q
[N_QUICK
];
248 const void ** keys
= keys_q
;
249 const void * vals_q
[N_QUICK
];
250 const void ** vals
= vals_q
;
252 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
253 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
254 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFPropertyListRef
), 0);
256 CFDictionaryGetKeysAndValues(services
, keys
, vals
);
257 for (i
= 0; i
< n
; i
++) {
258 CFDictionaryRef entity
;
259 SCNetworkServicePrivateRef servicePrivate
;
261 if (!isA_CFDictionary(vals
[i
])) {
264 CFSTR("SCNetworkServiceCopyAll(): error w/service \"%@\"\n"),
269 entity
= CFDictionaryGetValue(vals
[i
], kSCEntNetInterface
);
270 if (!isA_CFDictionary(entity
)) {
274 CFSTR("SCNetworkServiceCopyAll(): no \"%@\" entity for service \"%@\"\n"),
280 servicePrivate
= __SCNetworkServiceCreatePrivate(NULL
, keys
[i
], NULL
, prefs
);
281 CFArrayAppendValue(array
, (SCNetworkServiceRef
)servicePrivate
);
282 CFRelease(servicePrivate
);
284 if (keys
!= keys_q
) {
285 CFAllocatorDeallocate(NULL
, keys
);
286 CFAllocatorDeallocate(NULL
, vals
);
295 * build a list of all of a servives entity types that are associated
296 * with the services interface. The list will include :
298 * - entity types associated with the interface type (Ethernet, FireWire, PPP, ...)
299 * - entity types associated with the interface sub-type (PPPSerial, PPPoE, L2TP, PPTP, ...)
300 * - entity types associated with the hardware device (Ethernet, AirPort, FireWire, Modem, ...)
303 _copyInterfaceEntityTypes(CFDictionaryRef protocols
)
305 CFDictionaryRef interface
;
306 CFMutableSetRef interface_entity_types
;
308 interface_entity_types
= CFSetCreateMutable(NULL
, 0, &kCFTypeSetCallBacks
);
310 interface
= CFDictionaryGetValue(protocols
, kSCEntNetInterface
);
311 if (isA_CFDictionary(interface
)) {
312 CFStringRef entities
[] = { kSCPropNetInterfaceType
,
313 kSCPropNetInterfaceSubType
,
314 kSCPropNetInterfaceHardware
};
317 // include the "Interface" entity itself
318 CFSetAddValue(interface_entity_types
, kSCEntNetInterface
);
320 // include the entities associated with the interface
321 for (i
= 0; i
< sizeof(entities
)/sizeof(entities
[0]); i
++) {
324 entity
= CFDictionaryGetValue(interface
, entities
[i
]);
325 if (isA_CFString(entity
)) {
326 CFSetAddValue(interface_entity_types
, entity
);
331 * and, because we've found some misguided network preference code
332 * developers leaving [PPP] entity dictionaries around even though
333 * they are unused and/or unneeded...
335 CFSetAddValue(interface_entity_types
, kSCEntNetPPP
);
338 return interface_entity_types
;
343 SCNetworkServiceCopy(SCPreferencesRef prefs
, CFStringRef serviceID
)
345 CFDictionaryRef entity
;
347 SCNetworkServicePrivateRef servicePrivate
;
349 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
350 serviceID
, // service
351 kSCEntNetInterface
); // entity
352 entity
= SCPreferencesPathGetValue(prefs
, path
);
355 if (!isA_CFDictionary(entity
)) {
356 // a "service" must have an "interface"
357 _SCErrorSet(kSCStatusNoKey
);
361 servicePrivate
= __SCNetworkServiceCreatePrivate(NULL
, serviceID
, NULL
, prefs
);
362 return (SCNetworkServiceRef
)servicePrivate
;
367 SCNetworkServiceCopyProtocol(SCNetworkServiceRef service
, CFStringRef protocolType
)
369 CFSetRef non_protocol_entities
;
371 CFDictionaryRef protocols
;
372 SCNetworkProtocolPrivateRef protocolPrivate
= NULL
;
373 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
375 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
376 servicePrivate
->serviceID
, // service
378 protocols
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
381 if ((protocols
!= NULL
) && !isA_CFDictionary(protocols
)) {
383 _SCErrorSet(kSCStatusFailed
);
387 non_protocol_entities
= _copyInterfaceEntityTypes(protocols
);
388 if (CFSetContainsValue(non_protocol_entities
, protocolType
)) {
389 // if the "protocolType" matches an interface entity type
390 _SCErrorSet(kSCStatusInvalidArgument
);
394 if (!CFDictionaryContainsKey(protocols
, protocolType
)) {
395 // if the "protocolType" entity does not exist
396 _SCErrorSet(kSCStatusNoKey
);
400 protocolPrivate
= __SCNetworkProtocolCreatePrivate(NULL
, protocolType
, service
);
404 CFRelease(non_protocol_entities
);
406 return (SCNetworkProtocolRef
)protocolPrivate
;
410 CFArrayRef
/* of SCNetworkProtocolRef's */
411 SCNetworkServiceCopyProtocols(SCNetworkServiceRef service
)
413 CFMutableArrayRef array
;
415 CFSetRef non_protocol_entities
;
417 CFDictionaryRef protocols
;
418 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
420 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
421 servicePrivate
->serviceID
, // service
423 protocols
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
426 if (!isA_CFDictionary(protocols
)) {
430 non_protocol_entities
= _copyInterfaceEntityTypes(protocols
);
432 array
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
434 n
= CFDictionaryGetCount(protocols
);
437 const void * keys_q
[N_QUICK
];
438 const void ** keys
= keys_q
;
439 const void * vals_q
[N_QUICK
];
440 const void ** vals
= vals_q
;
442 if (n
> (CFIndex
)(sizeof(keys_q
) / sizeof(CFTypeRef
))) {
443 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFTypeRef
), 0);
444 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFPropertyListRef
), 0);
446 CFDictionaryGetKeysAndValues(protocols
, keys
, vals
);
447 for (i
= 0; i
< n
; i
++) {
448 SCNetworkProtocolPrivateRef protocolPrivate
;
450 if (!isA_CFDictionary(vals
[i
])) {
451 // if it's not a dictionary then it can't be a protocol entity
455 if (CFSetContainsValue(non_protocol_entities
, keys
[i
])) {
456 // skip any non-protocol (interface) entities
460 protocolPrivate
= __SCNetworkProtocolCreatePrivate(NULL
, keys
[i
], service
);
461 CFArrayAppendValue(array
, (SCNetworkProtocolRef
)protocolPrivate
);
463 CFRelease(protocolPrivate
);
465 if (keys
!= keys_q
) {
466 CFAllocatorDeallocate(NULL
, keys
);
467 CFAllocatorDeallocate(NULL
, vals
);
471 CFRelease(non_protocol_entities
);
478 __SCNetworkServiceSetInterfaceEntity(SCNetworkServiceRef service
,
479 SCNetworkInterfaceRef interface
)
481 CFMutableDictionaryRef entity
;
482 SCNetworkInterfacePrivateRef interfacePrivate
= (SCNetworkInterfacePrivateRef
)interface
;
485 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
487 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
488 servicePrivate
->serviceID
, // service
489 kSCEntNetInterface
); // entity
490 entity
= CFDictionaryCreateMutable(NULL
,
492 &kCFTypeDictionaryKeyCallBacks
,
493 &kCFTypeDictionaryValueCallBacks
);
494 if (interfacePrivate
->entity_type
!= NULL
) {
495 CFDictionarySetValue(entity
,
496 kSCPropNetInterfaceType
,
497 interfacePrivate
->entity_type
);
499 if (interfacePrivate
->entity_subtype
!= NULL
) {
500 CFDictionarySetValue(entity
,
501 kSCPropNetInterfaceSubType
,
502 interfacePrivate
->entity_subtype
);
504 if (interfacePrivate
->entity_device
!= NULL
) {
505 CFDictionarySetValue(entity
,
506 kSCPropNetInterfaceDeviceName
,
507 interfacePrivate
->entity_device
);
509 if (interfacePrivate
->entity_hardware
!= NULL
) {
510 CFDictionarySetValue(entity
,
511 kSCPropNetInterfaceHardware
,
512 interfacePrivate
->entity_hardware
);
514 if (CFEqual(interfacePrivate
->interface_type
, kSCNetworkInterfaceTypeModem
) &&
515 interfacePrivate
->supportsDeviceOnHold
) {
519 num
= CFNumberCreate(NULL
, kCFNumberIntType
, &one
);
520 CFDictionarySetValue(entity
,
521 kSCPropNetInterfaceSupportsModemOnHold
,
525 ok
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, entity
);
534 SCNetworkServiceCreate(SCPreferencesRef prefs
, SCNetworkInterfaceRef interface
)
536 CFArrayRef components
;
537 CFArrayRef interface_config
;
538 SCNetworkInterfaceRef newInterface
;
541 CFStringRef serviceID
;
542 SCNetworkServicePrivateRef servicePrivate
;
544 // establish the service
545 prefix
= SCPreferencesPathKeyCreateNetworkServices(NULL
);
546 path
= SCPreferencesPathCreateUniqueChild(prefs
, prefix
);
552 components
= CFStringCreateArrayBySeparatingStrings(NULL
, path
, CFSTR("/"));
555 serviceID
= CFArrayGetValueAtIndex(components
, 2);
556 servicePrivate
= __SCNetworkServiceCreatePrivate(NULL
, serviceID
, NULL
, prefs
);
557 CFRelease(components
);
559 // duplicate the interface and associate the copy with the new service
560 newInterface
= (SCNetworkInterfaceRef
)__SCNetworkInterfaceCreateCopy(NULL
,
562 (SCNetworkServiceRef
)servicePrivate
);
563 servicePrivate
->interface
= newInterface
;
565 // establish "default" configuration(s) for the interface
566 for (interface
= newInterface
;
568 interface
= SCNetworkInterfaceGetInterface(interface
)) {
569 SCNetworkInterfaceRef childInterface
;
570 CFStringRef childInterfaceType
= NULL
;
571 CFDictionaryRef config
;
572 CFStringRef interfaceType
;
574 interfaceType
= SCNetworkInterfaceGetInterfaceType(interface
);
575 childInterface
= SCNetworkInterfaceGetInterface(servicePrivate
->interface
);
576 if (childInterface
!= NULL
) {
577 childInterfaceType
= SCNetworkInterfaceGetInterfaceType(childInterface
);
580 config
= __copyInterfaceTemplate(interfaceType
, childInterfaceType
);
581 if (config
!= NULL
) {
582 (void) __SCNetworkInterfaceSetConfiguration(interface
, config
, TRUE
);
587 // add the interface [entity] to the service
588 (void) __SCNetworkServiceSetInterfaceEntity((SCNetworkServiceRef
)servicePrivate
,
589 servicePrivate
->interface
);
591 // push the [deep] interface configuration into into the service.
592 interface_config
= __SCNetworkInterfaceCopyDeepConfiguration(servicePrivate
->interface
);
593 __SCNetworkInterfaceSetDeepConfiguration(servicePrivate
->interface
, interface_config
);
595 return (SCNetworkServiceRef
)servicePrivate
;
600 SCNetworkServiceGetEnabled(SCNetworkServiceRef service
)
604 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
606 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
607 servicePrivate
->serviceID
, // service
609 enabled
= __getPrefsEnabled(servicePrivate
->prefs
, path
);
616 SCNetworkInterfaceRef
617 SCNetworkServiceGetInterface(SCNetworkServiceRef service
)
619 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
621 if (servicePrivate
->interface
== NULL
) {
622 CFDictionaryRef entity
;
625 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
626 servicePrivate
->serviceID
, // service
627 kSCEntNetInterface
); // entity
628 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
631 if (isA_CFDictionary(entity
)) {
632 servicePrivate
->interface
= __SCNetworkInterfaceCreateWithEntity(NULL
, entity
, service
);
636 return servicePrivate
->interface
;
641 SCNetworkServiceGetName(SCNetworkServiceRef service
)
643 CFDictionaryRef entity
;
644 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
645 CFStringRef name
= NULL
;
648 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
649 servicePrivate
->serviceID
, // service
651 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
654 if (isA_CFDictionary(entity
)) {
655 name
= CFDictionaryGetValue(entity
, kSCPropUserDefinedName
);
658 return isA_CFString(name
) ? name
: NULL
;
663 SCNetworkServiceGetServiceID(SCNetworkServiceRef service
)
665 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
667 return servicePrivate
->serviceID
;
672 SCNetworkServiceGetTypeID(void)
674 pthread_once(&initialized
, __SCNetworkServiceInitialize
); /* initialize runtime */
675 return __kSCNetworkServiceTypeID
;
680 SCNetworkServiceRemove(SCNetworkServiceRef service
)
683 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
687 // remove service from all sets
689 sets
= SCNetworkSetCopyAll(servicePrivate
->prefs
);
694 n
= CFArrayGetCount(sets
);
695 for (i
= 0; i
< n
; i
++) {
698 set
= CFArrayGetValueAtIndex(sets
, i
);
699 ok
= SCNetworkSetRemoveService(set
, service
);
700 if (!ok
&& (SCError() != kSCStatusNoKey
)) {
709 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
710 servicePrivate
->serviceID
, // service
712 ok
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
);
720 SCNetworkServiceRemoveProtocolType(SCNetworkServiceRef service
, CFStringRef protocolType
)
722 CFDictionaryRef entity
;
725 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
727 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
728 servicePrivate
->serviceID
, // service
729 protocolType
); // entity
731 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
732 if (entity
== NULL
) {
733 // if "protocol" does not exist
734 _SCErrorSet(kSCStatusNoKey
);
738 ok
= SCPreferencesPathRemoveValue(servicePrivate
->prefs
, path
);
748 SCNetworkServiceSetEnabled(SCNetworkServiceRef service
, Boolean enabled
)
752 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
754 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
755 servicePrivate
->serviceID
, // service
757 ok
= __setPrefsEnabled(servicePrivate
->prefs
, path
, enabled
);
765 SCNetworkServiceSetName(SCNetworkServiceRef service
, CFStringRef name
)
767 CFDictionaryRef entity
;
770 SCNetworkServicePrivateRef servicePrivate
= (SCNetworkServicePrivateRef
)service
;
772 #define PREVENT_DUPLICATE_SERVICE_NAMES
773 #ifdef PREVENT_DUPLICATE_SERVICE_NAMES
774 if (isA_CFString(name
)) {
777 // ensure that each service is uniquely named within its sets
779 sets
= SCNetworkSetCopyAll(servicePrivate
->prefs
);
784 set_count
= CFArrayGetCount(sets
);
785 for (set_index
= 0; set_index
< set_count
; set_index
++) {
786 CFIndex service_index
;
787 Boolean isDup
= FALSE
;
788 Boolean isMember
= FALSE
;
789 CFIndex service_count
;
791 SCNetworkSetRef set
= CFArrayGetValueAtIndex(sets
, set_index
);
793 services
= SCNetworkSetCopyServices(set
);
795 service_count
= CFArrayGetCount(services
);
796 for (service_index
= 0; service_index
< service_count
; service_index
++) {
798 CFStringRef otherName
;
799 SCNetworkServiceRef otherService
;
801 otherService
= CFArrayGetValueAtIndex(services
, service_index
);
803 otherID
= SCNetworkServiceGetServiceID(otherService
);
804 if (CFEqual(servicePrivate
->serviceID
, otherID
)) {
805 // if the service is a member of this set
810 otherName
= SCNetworkServiceGetName(otherService
);
811 if ((otherName
!= NULL
) && CFEqual(name
, otherName
)) {
819 if (isMember
&& isDup
) {
821 * if this service is a member of the set and
822 * the "name" is not unique.
825 _SCErrorSet(kSCStatusKeyExists
);
833 #endif /* PREVENT_DUPLICATE_SERVICE_NAMES */
835 path
= SCPreferencesPathKeyCreateNetworkServiceEntity(NULL
, // allocator
836 servicePrivate
->serviceID
, // service
838 entity
= SCPreferencesPathGetValue(servicePrivate
->prefs
, path
);
839 if ((entity
== NULL
) && (name
!= NULL
)) {
840 entity
= CFDictionaryCreate(NULL
,
844 &kCFTypeDictionaryKeyCallBacks
,
845 &kCFTypeDictionaryValueCallBacks
);
847 if (isA_CFDictionary(entity
)) {
848 CFMutableDictionaryRef newEntity
;
850 newEntity
= CFDictionaryCreateMutableCopy(NULL
, 0, entity
);
851 if (isA_CFString(name
)) {
852 CFDictionarySetValue(newEntity
, kSCPropUserDefinedName
, name
);
854 CFDictionaryRemoveValue(newEntity
, kSCPropUserDefinedName
);
856 ok
= SCPreferencesPathSetValue(servicePrivate
->prefs
, path
, newEntity
);
857 CFRelease(newEntity
);