2 * Copyright (c) 2000-2008 Apple 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 * June 1, 2001 Allan Nathanson <ajn@apple.com>
28 * - public API conversion
30 * January 8, 2001 Allan Nathanson <ajn@apple.com>
35 #include <CoreFoundation/CoreFoundation.h>
36 #include <CoreFoundation/CFStringDefaultEncoding.h> // for __CFStringGetUserDefaultEncoding
37 #include <SystemConfiguration/SystemConfiguration.h>
38 #include <SystemConfiguration/SCValidation.h>
39 #include <SystemConfiguration/SCPrivate.h>
42 #pragma mark ComputerName
46 _SCPreferencesCopyComputerName(SCPreferencesRef prefs
,
47 CFStringEncoding
*nameEncoding
)
50 CFStringRef name
= NULL
;
52 Boolean tempPrefs
= FALSE
;
55 prefs
= SCPreferencesCreate(NULL
, CFSTR("_SCPreferencesCopyComputerName"), NULL
);
62 path
= CFStringCreateWithFormat(NULL
,
67 dict
= SCPreferencesPathGetValue(prefs
, path
);
71 if (isA_CFDictionary(dict
)) {
72 name
= CFDictionaryGetValue(dict
, kSCPropSystemComputerName
);
73 name
= isA_CFString(name
);
79 if (nameEncoding
!= NULL
) {
82 num
= CFDictionaryGetValue(dict
,
83 kSCPropSystemComputerNameEncoding
);
84 if (isA_CFNumber(num
)) {
85 CFNumberGetValue(num
, kCFNumberIntType
, nameEncoding
);
87 *nameEncoding
= CFStringGetSystemEncoding();
92 if (tempPrefs
) CFRelease(prefs
);
94 _SCErrorSet(kSCStatusNoKey
);
101 SCDynamicStoreKeyCreateComputerName(CFAllocatorRef allocator
)
103 return SCDynamicStoreKeyCreate(allocator
,
105 kSCDynamicStoreDomainSetup
,
111 SCDynamicStoreCopyComputerName(SCDynamicStoreRef store
,
112 CFStringEncoding
*nameEncoding
)
114 CFDictionaryRef dict
;
116 CFStringRef name
= NULL
;
117 Boolean tempSession
= FALSE
;
120 store
= SCDynamicStoreCreate(NULL
,
121 CFSTR("SCDynamicStoreCopyComputerName"),
130 key
= SCDynamicStoreKeyCreateComputerName(NULL
);
131 dict
= SCDynamicStoreCopyValue(store
, key
);
135 * Let's try looking in the preferences.plist file until
136 * (a) we add an API to retrieve the name regardless of
137 * where it is stored and
138 * (b) this API is deprecated
140 name
= _SCPreferencesCopyComputerName(NULL
, nameEncoding
);
143 if (!isA_CFDictionary(dict
)) {
144 _SCErrorSet(kSCStatusNoKey
);
148 name
= isA_CFString(CFDictionaryGetValue(dict
, kSCPropSystemComputerName
));
150 _SCErrorSet(kSCStatusNoKey
);
155 if (nameEncoding
!= NULL
) {
158 num
= CFDictionaryGetValue(dict
,
159 kSCPropSystemComputerNameEncoding
);
160 if (isA_CFNumber(num
)) {
161 CFNumberGetValue(num
, kCFNumberIntType
, nameEncoding
);
163 *nameEncoding
= CFStringGetSystemEncoding();
169 if (tempSession
) CFRelease(store
);
170 if (dict
!= NULL
) CFRelease(dict
);
176 SCPreferencesSetComputerName(SCPreferencesRef prefs
,
178 CFStringEncoding encoding
)
180 CFDictionaryRef dict
;
181 CFMutableDictionaryRef newDict
;
189 if (!isA_CFString(name
)) {
190 _SCErrorSet(kSCStatusInvalidArgument
);
194 len
= CFStringGetLength(name
);
200 path
= CFStringCreateWithFormat(NULL
,
206 dict
= SCPreferencesPathGetValue(prefs
, path
);
208 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
210 newDict
= CFDictionaryCreateMutable(NULL
,
212 &kCFTypeDictionaryKeyCallBacks
,
213 &kCFTypeDictionaryValueCallBacks
);
216 if ((name
!= NULL
) && (CFStringGetLength(name
) > 0)) {
217 CFDictionarySetValue(newDict
, kSCPropSystemComputerName
, name
);
219 num
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &encoding
);
220 CFDictionarySetValue(newDict
, kSCPropSystemComputerNameEncoding
, num
);
223 CFDictionaryRemoveValue(newDict
, kSCPropSystemComputerNameRegion
);
224 if (encoding
== kCFStringEncodingMacRoman
) {
225 UInt32 userEncoding
= 0;
226 UInt32 userRegion
= 0;
228 __CFStringGetUserDefaultEncoding(&userEncoding
, &userRegion
);
229 if ((userEncoding
== kCFStringEncodingMacRoman
) && (userRegion
!= 0)) {
230 num
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &userRegion
);
231 CFDictionarySetValue(newDict
, kSCPropSystemComputerNameRegion
, num
);
236 CFDictionaryRemoveValue(newDict
, kSCPropSystemComputerName
);
237 CFDictionaryRemoveValue(newDict
, kSCPropSystemComputerNameEncoding
);
238 CFDictionaryRemoveValue(newDict
, kSCPropSystemComputerNameRegion
);
241 if (CFDictionaryGetCount(newDict
) > 0) {
242 ok
= SCPreferencesPathSetValue(prefs
, path
, newDict
);
244 ok
= SCPreferencesPathRemoveValue(prefs
, path
);
255 #pragma mark HostName
259 SCPreferencesGetHostName(SCPreferencesRef prefs
)
261 CFDictionaryRef dict
;
265 path
= CFStringCreateWithFormat(NULL
,
270 dict
= SCPreferencesPathGetValue(prefs
, path
);
273 if (!isA_CFDictionary(dict
)) {
274 _SCErrorSet(kSCStatusNoKey
);
278 name
= isA_CFString(CFDictionaryGetValue(dict
, kSCPropSystemHostName
));
280 _SCErrorSet(kSCStatusNoKey
);
289 SCPreferencesSetHostName(SCPreferencesRef prefs
,
292 CFDictionaryRef dict
;
293 CFMutableDictionaryRef newDict
;
300 if (!isA_CFString(name
)) {
301 _SCErrorSet(kSCStatusInvalidArgument
);
305 len
= CFStringGetLength(name
);
311 path
= CFStringCreateWithFormat(NULL
,
317 dict
= SCPreferencesPathGetValue(prefs
, path
);
319 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
321 newDict
= CFDictionaryCreateMutable(NULL
,
323 &kCFTypeDictionaryKeyCallBacks
,
324 &kCFTypeDictionaryValueCallBacks
);
328 CFDictionarySetValue(newDict
, kSCPropSystemHostName
, name
);
330 CFDictionaryRemoveValue(newDict
, kSCPropSystemHostName
);
333 if (CFDictionaryGetCount(newDict
) > 0) {
334 ok
= SCPreferencesPathSetValue(prefs
, path
, newDict
);
336 ok
= SCPreferencesPathRemoveValue(prefs
, path
);
347 #pragma mark LocalHostName
351 _SCPreferencesCopyLocalHostName(SCPreferencesRef prefs
)
353 CFDictionaryRef dict
;
354 CFStringRef name
= NULL
;
356 Boolean tempPrefs
= FALSE
;
359 prefs
= SCPreferencesCreate(NULL
, CFSTR("_SCPreferencesCopyLocalHostName"), NULL
);
366 path
= CFStringCreateWithFormat(NULL
,
372 dict
= SCPreferencesPathGetValue(prefs
, path
);
376 if (isA_CFDictionary(dict
)) {
377 name
= CFDictionaryGetValue(dict
, kSCPropNetLocalHostName
);
378 name
= isA_CFString(name
);
385 if (tempPrefs
) CFRelease(prefs
);
387 _SCErrorSet(kSCStatusNoKey
);
394 SCDynamicStoreKeyCreateHostNames(CFAllocatorRef allocator
)
396 return SCDynamicStoreKeyCreate(allocator
,
398 kSCDynamicStoreDomainSetup
,
405 SCDynamicStoreCopyLocalHostName(SCDynamicStoreRef store
)
407 CFDictionaryRef dict
;
409 CFStringRef name
= NULL
;
410 Boolean tempSession
= FALSE
;
413 store
= SCDynamicStoreCreate(NULL
,
414 CFSTR("SCDynamicStoreCopyLocalHostName"),
423 key
= SCDynamicStoreKeyCreateHostNames(NULL
);
424 dict
= SCDynamicStoreCopyValue(store
, key
);
428 * Let's try looking in the preferences.plist file until
429 * (a) we add an API to retrieve the name regardless of
430 * where it is stored and
431 * (b) this API is deprecated
433 name
= _SCPreferencesCopyLocalHostName(NULL
);
436 if (!isA_CFDictionary(dict
)) {
437 _SCErrorSet(kSCStatusNoKey
);
441 name
= isA_CFString(CFDictionaryGetValue(dict
, kSCPropNetLocalHostName
));
443 _SCErrorSet(kSCStatusNoKey
);
450 if (tempSession
) CFRelease(store
);
451 if (dict
!= NULL
) CFRelease(dict
);
457 _SC_stringIsValidDNSName(const char *name
)
460 int len
= strlen(name
);
468 for (scan
= name
, i
= 0; i
< len
; i
++, scan
++) {
470 char next
= *(scan
+ 1);
472 if (prev
== '.' || prev
== '\0') {
473 if (isalnum(ch
) == 0) {
474 /* a label must begin with a letter or digit */
477 } else if (next
== '\0' || next
== '.') {
478 if (isalnum(ch
) == 0) {
479 /* a label must end with a letter or digit */
482 } else if (isalnum(ch
) == 0) {
486 /* no empty labels */
491 /* hyphens are OK within a label */
494 /* an invalid character */
507 _SC_CFStringIsValidDNSName(CFStringRef name
)
509 Boolean clean
= FALSE
;
512 if (!isA_CFString(name
)) {
516 str
= _SC_cfstring_to_cstring(name
, NULL
, 0, kCFStringEncodingASCII
);
521 clean
= _SC_stringIsValidDNSName(str
);
523 if (str
!= NULL
) CFAllocatorDeallocate(NULL
, str
);
529 SCPreferencesSetLocalHostName(SCPreferencesRef prefs
,
532 CFDictionaryRef dict
;
533 CFMutableDictionaryRef newDict
;
540 if (!isA_CFString(name
)) {
541 _SCErrorSet(kSCStatusInvalidArgument
);
545 len
= CFStringGetLength(name
);
547 if (!_SC_CFStringIsValidDNSName(name
)) {
548 _SCErrorSet(kSCStatusInvalidArgument
);
552 if (CFStringFindWithOptions(name
, CFSTR("."), CFRangeMake(0, len
), 0, NULL
)) {
553 _SCErrorSet(kSCStatusInvalidArgument
);
561 path
= CFStringCreateWithFormat(NULL
,
568 dict
= SCPreferencesPathGetValue(prefs
, path
);
570 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
572 newDict
= CFDictionaryCreateMutable(NULL
,
574 &kCFTypeDictionaryKeyCallBacks
,
575 &kCFTypeDictionaryValueCallBacks
);
579 CFDictionarySetValue(newDict
, kSCPropNetLocalHostName
, name
);
581 CFDictionaryRemoveValue(newDict
, kSCPropNetLocalHostName
);
584 if (CFDictionaryGetCount(newDict
) > 0) {
585 ok
= SCPreferencesPathSetValue(prefs
, path
, newDict
);
587 ok
= SCPreferencesPathRemoveValue(prefs
, path
);
598 _SC_CFStringIsValidNetBIOSName(CFStringRef name
)
600 if (!isA_CFString(name
)) {
604 if (CFStringGetLength(name
) > 15) {