2 * Copyright (c) 2000-2008, 2011 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
= NULL
;
116 CFStringRef name
= NULL
;
118 key
= SCDynamicStoreKeyCreateComputerName(NULL
);
119 dict
= SCDynamicStoreCopyValue(store
, key
);
123 * Let's try looking in the preferences.plist file until
124 * (a) we add an API to retrieve the name regardless of
125 * where it is stored and
126 * (b) this API is deprecated
128 name
= _SCPreferencesCopyComputerName(NULL
, nameEncoding
);
131 if (!isA_CFDictionary(dict
)) {
132 _SCErrorSet(kSCStatusNoKey
);
136 name
= isA_CFString(CFDictionaryGetValue(dict
, kSCPropSystemComputerName
));
138 _SCErrorSet(kSCStatusNoKey
);
143 if (nameEncoding
!= NULL
) {
146 num
= CFDictionaryGetValue(dict
,
147 kSCPropSystemComputerNameEncoding
);
148 if (isA_CFNumber(num
)) {
149 CFNumberGetValue(num
, kCFNumberIntType
, nameEncoding
);
151 *nameEncoding
= CFStringGetSystemEncoding();
157 if (dict
!= NULL
) CFRelease(dict
);
163 SCPreferencesSetComputerName(SCPreferencesRef prefs
,
165 CFStringEncoding encoding
)
167 CFDictionaryRef dict
;
168 CFMutableDictionaryRef newDict
;
176 if (!isA_CFString(name
)) {
177 _SCErrorSet(kSCStatusInvalidArgument
);
181 len
= CFStringGetLength(name
);
187 path
= CFStringCreateWithFormat(NULL
,
193 dict
= SCPreferencesPathGetValue(prefs
, path
);
195 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
197 newDict
= CFDictionaryCreateMutable(NULL
,
199 &kCFTypeDictionaryKeyCallBacks
,
200 &kCFTypeDictionaryValueCallBacks
);
203 if ((name
!= NULL
) && (CFStringGetLength(name
) > 0)) {
204 CFDictionarySetValue(newDict
, kSCPropSystemComputerName
, name
);
206 num
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &encoding
);
207 CFDictionarySetValue(newDict
, kSCPropSystemComputerNameEncoding
, num
);
210 CFDictionaryRemoveValue(newDict
, kSCPropSystemComputerNameRegion
);
211 if (encoding
== kCFStringEncodingMacRoman
) {
212 UInt32 userEncoding
= 0;
213 UInt32 userRegion
= 0;
215 __CFStringGetUserDefaultEncoding(&userEncoding
, &userRegion
);
216 if ((userEncoding
== kCFStringEncodingMacRoman
) && (userRegion
!= 0)) {
217 num
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &userRegion
);
218 CFDictionarySetValue(newDict
, kSCPropSystemComputerNameRegion
, num
);
223 CFDictionaryRemoveValue(newDict
, kSCPropSystemComputerName
);
224 CFDictionaryRemoveValue(newDict
, kSCPropSystemComputerNameEncoding
);
225 CFDictionaryRemoveValue(newDict
, kSCPropSystemComputerNameRegion
);
228 if (CFDictionaryGetCount(newDict
) > 0) {
229 ok
= SCPreferencesPathSetValue(prefs
, path
, newDict
);
231 ok
= SCPreferencesPathRemoveValue(prefs
, path
);
242 #pragma mark HostName
246 SCPreferencesGetHostName(SCPreferencesRef prefs
)
248 CFDictionaryRef dict
;
252 path
= CFStringCreateWithFormat(NULL
,
257 dict
= SCPreferencesPathGetValue(prefs
, path
);
260 if (!isA_CFDictionary(dict
)) {
261 _SCErrorSet(kSCStatusNoKey
);
265 name
= isA_CFString(CFDictionaryGetValue(dict
, kSCPropSystemHostName
));
267 _SCErrorSet(kSCStatusNoKey
);
276 SCPreferencesSetHostName(SCPreferencesRef prefs
,
279 CFDictionaryRef dict
;
280 CFMutableDictionaryRef newDict
;
287 if (!isA_CFString(name
)) {
288 _SCErrorSet(kSCStatusInvalidArgument
);
292 len
= CFStringGetLength(name
);
298 path
= CFStringCreateWithFormat(NULL
,
304 dict
= SCPreferencesPathGetValue(prefs
, path
);
306 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
308 newDict
= CFDictionaryCreateMutable(NULL
,
310 &kCFTypeDictionaryKeyCallBacks
,
311 &kCFTypeDictionaryValueCallBacks
);
315 CFDictionarySetValue(newDict
, kSCPropSystemHostName
, name
);
317 CFDictionaryRemoveValue(newDict
, kSCPropSystemHostName
);
320 if (CFDictionaryGetCount(newDict
) > 0) {
321 ok
= SCPreferencesPathSetValue(prefs
, path
, newDict
);
323 ok
= SCPreferencesPathRemoveValue(prefs
, path
);
334 #pragma mark LocalHostName
338 _SCPreferencesCopyLocalHostName(SCPreferencesRef prefs
)
340 CFDictionaryRef dict
;
341 CFStringRef name
= NULL
;
343 Boolean tempPrefs
= FALSE
;
346 prefs
= SCPreferencesCreate(NULL
, CFSTR("_SCPreferencesCopyLocalHostName"), NULL
);
353 path
= CFStringCreateWithFormat(NULL
,
359 dict
= SCPreferencesPathGetValue(prefs
, path
);
363 if (isA_CFDictionary(dict
)) {
364 name
= CFDictionaryGetValue(dict
, kSCPropNetLocalHostName
);
365 name
= isA_CFString(name
);
372 if (tempPrefs
) CFRelease(prefs
);
374 _SCErrorSet(kSCStatusNoKey
);
381 SCDynamicStoreKeyCreateHostNames(CFAllocatorRef allocator
)
383 return SCDynamicStoreKeyCreate(allocator
,
385 kSCDynamicStoreDomainSetup
,
392 SCDynamicStoreCopyLocalHostName(SCDynamicStoreRef store
)
394 CFDictionaryRef dict
= NULL
;
396 CFStringRef name
= NULL
;
398 key
= SCDynamicStoreKeyCreateHostNames(NULL
);
399 dict
= SCDynamicStoreCopyValue(store
, key
);
403 * Let's try looking in the preferences.plist file until
404 * (a) we add an API to retrieve the name regardless of
405 * where it is stored and
406 * (b) this API is deprecated
408 name
= _SCPreferencesCopyLocalHostName(NULL
);
411 if (!isA_CFDictionary(dict
)) {
412 _SCErrorSet(kSCStatusNoKey
);
416 name
= isA_CFString(CFDictionaryGetValue(dict
, kSCPropNetLocalHostName
));
418 _SCErrorSet(kSCStatusNoKey
);
425 if (dict
!= NULL
) CFRelease(dict
);
431 _SC_stringIsValidDNSName(const char *name
)
434 int len
= strlen(name
);
442 for (scan
= name
, i
= 0; i
< len
; i
++, scan
++) {
444 char next
= *(scan
+ 1);
446 if (prev
== '.' || prev
== '\0') {
447 if (isalnum(ch
) == 0) {
448 /* a label must begin with a letter or digit */
451 } else if (next
== '\0' || next
== '.') {
452 if (isalnum(ch
) == 0) {
453 /* a label must end with a letter or digit */
456 } else if (isalnum(ch
) == 0) {
460 /* no empty labels */
465 /* hyphens are OK within a label */
468 /* an invalid character */
481 _SC_CFStringIsValidDNSName(CFStringRef name
)
483 Boolean clean
= FALSE
;
486 if (!isA_CFString(name
)) {
490 str
= _SC_cfstring_to_cstring(name
, NULL
, 0, kCFStringEncodingASCII
);
495 clean
= _SC_stringIsValidDNSName(str
);
497 if (str
!= NULL
) CFAllocatorDeallocate(NULL
, str
);
503 SCPreferencesSetLocalHostName(SCPreferencesRef prefs
,
506 CFDictionaryRef dict
;
507 CFMutableDictionaryRef newDict
;
514 if (!isA_CFString(name
)) {
515 _SCErrorSet(kSCStatusInvalidArgument
);
519 len
= CFStringGetLength(name
);
521 if (!_SC_CFStringIsValidDNSName(name
)) {
522 _SCErrorSet(kSCStatusInvalidArgument
);
526 if (CFStringFindWithOptions(name
, CFSTR("."), CFRangeMake(0, len
), 0, NULL
)) {
527 _SCErrorSet(kSCStatusInvalidArgument
);
535 path
= CFStringCreateWithFormat(NULL
,
542 dict
= SCPreferencesPathGetValue(prefs
, path
);
544 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
546 newDict
= CFDictionaryCreateMutable(NULL
,
548 &kCFTypeDictionaryKeyCallBacks
,
549 &kCFTypeDictionaryValueCallBacks
);
553 CFDictionarySetValue(newDict
, kSCPropNetLocalHostName
, name
);
555 CFDictionaryRemoveValue(newDict
, kSCPropNetLocalHostName
);
558 if (CFDictionaryGetCount(newDict
) > 0) {
559 ok
= SCPreferencesPathSetValue(prefs
, path
, newDict
);
561 ok
= SCPreferencesPathRemoveValue(prefs
, path
);
572 _SC_CFStringIsValidNetBIOSName(CFStringRef name
)
574 if (!isA_CFString(name
)) {
578 if (CFStringGetLength(name
) > 15) {