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