]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/SCDHostName.c
configd-84.1.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCDHostName.c
1 /*
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25
26 /*
27 * Modification History
28 *
29 * June 1, 2001 Allan Nathanson <ajn@apple.com>
30 * - public API conversion
31 *
32 * January 8, 2001 Allan Nathanson <ajn@apple.com>
33 * - initial revision
34 */
35
36 #include <SystemConfiguration/SystemConfiguration.h>
37 #include <SystemConfiguration/SCValidation.h>
38 #include <SystemConfiguration/SCPrivate.h>
39
40 CFStringRef
41 SCDynamicStoreKeyCreateComputerName(CFAllocatorRef allocator)
42 {
43 return SCDynamicStoreKeyCreate(allocator,
44 CFSTR("%@/%@"),
45 kSCDynamicStoreDomainSetup,
46 kSCCompSystem);
47 }
48
49
50 CFStringRef
51 SCDynamicStoreCopyComputerName(SCDynamicStoreRef store,
52 CFStringEncoding *nameEncoding)
53 {
54 CFDictionaryRef dict = NULL;
55 CFStringRef key;
56 CFStringRef name = NULL;
57 Boolean tempSession = FALSE;
58
59 if (!store) {
60 store = SCDynamicStoreCreate(NULL,
61 CFSTR("SCDynamicStoreCopyComputerName"),
62 NULL,
63 NULL);
64 if (!store) {
65 SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
66 return NULL;
67 }
68 tempSession = TRUE;
69 }
70
71 key = SCDynamicStoreKeyCreateComputerName(NULL);
72 dict = SCDynamicStoreCopyValue(store, key);
73 CFRelease(key);
74 if (!dict) {
75 goto done;
76 }
77 if (!isA_CFDictionary(dict)) {
78 _SCErrorSet(kSCStatusNoKey);
79 goto done;
80 }
81
82 name = isA_CFString(CFDictionaryGetValue(dict, kSCPropSystemComputerName));
83 if (!name) {
84 _SCErrorSet(kSCStatusNoKey);
85 goto done;
86 }
87 CFRetain(name);
88
89 if (nameEncoding) {
90 CFNumberRef num;
91
92 num = CFDictionaryGetValue(dict,
93 kSCPropSystemComputerNameEncoding);
94 if (isA_CFNumber(num)) {
95 CFNumberGetValue(num, kCFNumberIntType, nameEncoding);
96 } else {
97 *nameEncoding = CFStringGetSystemEncoding();
98 }
99 }
100
101 done :
102
103 if (tempSession) CFRelease(store);
104 if (dict) CFRelease(dict);
105 return name;
106 }
107
108
109 Boolean
110 SCPreferencesSetComputerName(SCPreferencesRef session,
111 CFStringRef name,
112 CFStringEncoding encoding)
113 {
114 CFDictionaryRef dict;
115 CFMutableDictionaryRef newDict = NULL;
116 CFNumberRef num;
117 Boolean ok = FALSE;
118 CFStringRef path = NULL;
119
120 if (!isA_CFString(name)) {
121 _SCErrorSet(kSCStatusInvalidArgument);
122 return FALSE;
123 }
124
125 path = CFStringCreateWithFormat(NULL,
126 NULL,
127 CFSTR("/%@/%@"),
128 kSCPrefSystem,
129 kSCCompSystem);
130
131 dict = SCPreferencesPathGetValue(session, path);
132 if (dict) {
133 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
134 } else {
135 newDict = CFDictionaryCreateMutable(NULL,
136 0,
137 &kCFTypeDictionaryKeyCallBacks,
138 &kCFTypeDictionaryValueCallBacks);
139 }
140
141 CFDictionarySetValue(newDict, kSCPropSystemComputerName, name);
142
143 num = CFNumberCreate(NULL, kCFNumberIntType, &encoding);
144 CFDictionarySetValue(newDict, kSCPropSystemComputerNameEncoding, num);
145 CFRelease(num);
146
147 ok = SCPreferencesPathSetValue(session, path, newDict);
148 if (!ok) {
149 SCLog(_sc_verbose, LOG_ERR, CFSTR("SCPreferencesPathSetValue() failed"));
150 }
151
152 if (path) CFRelease(path);
153 if (newDict) CFRelease(newDict);
154
155 return ok;
156 }
157
158
159 CFStringRef
160 SCDynamicStoreKeyCreateHostNames(CFAllocatorRef allocator)
161 {
162 return SCDynamicStoreKeyCreate(allocator,
163 CFSTR("%@/%@/%@"),
164 kSCDynamicStoreDomainSetup,
165 kSCCompNetwork,
166 kSCCompHostNames);
167 }
168
169
170 CFStringRef
171 SCDynamicStoreCopyLocalHostName(SCDynamicStoreRef store)
172 {
173 CFDictionaryRef dict = NULL;
174 CFStringRef key;
175 CFStringRef name = NULL;
176 Boolean tempSession = FALSE;
177
178 if (!store) {
179 store = SCDynamicStoreCreate(NULL,
180 CFSTR("SCDynamicStoreCopyLocalHostName"),
181 NULL,
182 NULL);
183 if (!store) {
184 SCLog(_sc_verbose, LOG_INFO, CFSTR("SCDynamicStoreCreate() failed"));
185 return NULL;
186 }
187 tempSession = TRUE;
188 }
189
190 key = SCDynamicStoreKeyCreateHostNames(NULL);
191 dict = SCDynamicStoreCopyValue(store, key);
192 CFRelease(key);
193 if (!dict) {
194 goto done;
195 }
196 if (!isA_CFDictionary(dict)) {
197 _SCErrorSet(kSCStatusNoKey);
198 goto done;
199 }
200
201 name = isA_CFString(CFDictionaryGetValue(dict, kSCPropNetLocalHostName));
202 if (!name) {
203 _SCErrorSet(kSCStatusNoKey);
204 goto done;
205 }
206 CFRetain(name);
207
208 done :
209
210 if (tempSession) CFRelease(store);
211 if (dict) CFRelease(dict);
212 return name;
213 }
214
215
216 Boolean
217 _SC_stringIsValidDNSName(const char *name)
218 {
219 int i;
220 int len = strlen(name);
221 char prev = '\0';
222 const char *scan;
223
224 if (len == 0) {
225 return FALSE;
226 }
227
228 for (scan = name, i = 0; i < len; i++, scan++) {
229 char ch = *scan;
230 char next = *(scan + 1);
231
232 if (prev == '.' || prev == '\0') {
233 if (isalnum(ch) == 0) {
234 /* a label must begin with a letter or digit */
235 return FALSE;
236 }
237 } else if (next == '\0' || next == '.') {
238 if (isalnum(ch) == 0) {
239 /* a label must end with a letter or digit */
240 return FALSE;
241 }
242 } else if (isalnum(ch) == 0) {
243 switch (ch) {
244 case '.':
245 case '-':
246 if (prev == '.' || prev == '-') {
247 /* a label cannot begin or end with a hyphen */
248 return FALSE;
249 }
250 break;
251 default:
252 /* an invalid character */
253 return FALSE;
254 break;
255 }
256 }
257 prev = ch;
258 }
259
260 return TRUE;
261 }
262
263 Boolean
264 _SC_CFStringIsValidDNSName(CFStringRef name)
265 {
266 Boolean clean = FALSE;
267 char *str = NULL;
268
269 if (!isA_CFString(name)) {
270 return FALSE;
271 }
272
273 str = _SC_cfstring_to_cstring(name, NULL, 0, kCFStringEncodingASCII);
274 if (str == NULL) {
275 return FALSE;
276 }
277
278 clean = _SC_stringIsValidDNSName(str);
279
280 if (str) CFAllocatorDeallocate(NULL, str);
281 return clean;
282 }
283
284
285 Boolean
286 SCPreferencesSetLocalHostName(SCPreferencesRef session,
287 CFStringRef name)
288 {
289 CFDictionaryRef dict;
290 CFMutableDictionaryRef newDict = NULL;
291 Boolean ok = FALSE;
292 CFStringRef path = NULL;
293
294 if (name) {
295 CFIndex len;
296
297 if (!isA_CFString(name)) {
298 _SCErrorSet(kSCStatusInvalidArgument);
299 return FALSE;
300 }
301
302 len = CFStringGetLength(name);
303 if (len > 0) {
304 if (!_SC_CFStringIsValidDNSName(name)) {
305 _SCErrorSet(kSCStatusInvalidArgument);
306 return FALSE;
307 }
308
309 if (CFStringFindWithOptions(name, CFSTR("."), CFRangeMake(0, len), 0, NULL)) {
310 _SCErrorSet(kSCStatusInvalidArgument);
311 return FALSE;
312 }
313 } else {
314 name = NULL;
315 }
316 }
317
318 path = CFStringCreateWithFormat(NULL,
319 NULL,
320 CFSTR("/%@/%@/%@"),
321 kSCPrefSystem,
322 kSCCompNetwork,
323 kSCCompHostNames);
324
325 dict = SCPreferencesPathGetValue(session, path);
326 if (dict) {
327 newDict = CFDictionaryCreateMutableCopy(NULL, 0, dict);
328 } else {
329 newDict = CFDictionaryCreateMutable(NULL,
330 0,
331 &kCFTypeDictionaryKeyCallBacks,
332 &kCFTypeDictionaryValueCallBacks);
333 }
334
335 if (name) {
336 CFDictionarySetValue(newDict, kSCPropNetLocalHostName, name);
337 } else {
338 CFDictionaryRemoveValue(newDict, kSCPropNetLocalHostName);
339 }
340
341 if (CFDictionaryGetCount(newDict) > 0) {
342 ok = SCPreferencesPathSetValue(session, path, newDict);
343 if (!ok) {
344 SCLog(_sc_verbose, LOG_ERR, CFSTR("SCPreferencesPathSetValue() failed"));
345 }
346 } else {
347 ok = SCPreferencesPathRemoveValue(session, path);
348 if (!ok) {
349 SCLog(_sc_verbose, LOG_ERR, CFSTR("SCPreferencesPathRemoveValue() failed"));
350 }
351 }
352
353 if (path) CFRelease(path);
354 if (newDict) CFRelease(newDict);
355
356 return ok;
357 }