]>
Commit | Line | Data |
---|---|---|
9ce05555 | 1 | /* |
d8925383 | 2 | * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. |
9ce05555 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
9ce05555 A |
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 | /* CFPlatform.c | |
24 | Copyright 1999-2002, Apple, Inc. All rights reserved. | |
25 | Responsibility: Christopher Kane | |
26 | */ | |
27 | ||
28 | #include "CFInternal.h" | |
29 | #include "CFPriv.h" | |
30 | #if defined(__WIN32__) | |
9ce05555 A |
31 | #include <windows.h> |
32 | #include <stdlib.h> | |
33 | #else | |
34 | #include <sys/stat.h> | |
35 | #include <string.h> | |
36 | #include <unistd.h> | |
37 | #include <pwd.h> | |
38 | #endif | |
39 | #if defined(__MACH__) | |
9ce05555 A |
40 | #include <crt_externs.h> |
41 | #endif | |
42 | ||
43 | extern char *getenv(const char *name); | |
44 | ||
45 | #if defined(__MACH__) | |
46 | #define kCFPlatformInterfaceStringEncoding kCFStringEncodingUTF8 | |
47 | #else | |
48 | #define kCFPlatformInterfaceStringEncoding CFStringGetSystemEncoding() | |
49 | #endif | |
50 | ||
9ce05555 | 51 | #if defined(__MACH__) |
d8925383 | 52 | char **_CFArgv(void) { |
9ce05555 | 53 | return *_NSGetArgv(); |
9ce05555 A |
54 | } |
55 | ||
56 | int _CFArgc(void) { | |
9ce05555 | 57 | return *_NSGetArgc(); |
9ce05555 | 58 | } |
d8925383 | 59 | #endif |
9ce05555 A |
60 | |
61 | ||
62 | __private_extern__ Boolean _CFGetCurrentDirectory(char *path, int maxlen) { | |
63 | #if defined(__WIN32__) | |
64 | DWORD len = GetCurrentDirectoryA(maxlen, path); | |
65 | return (0 != len && len + 1 <= maxlen); | |
66 | #else | |
67 | return getcwd(path, maxlen) != NULL; | |
68 | #endif | |
69 | } | |
70 | ||
71 | static Boolean __CFIsCFM = false; | |
72 | ||
73 | // If called super early, we just return false | |
74 | __private_extern__ Boolean _CFIsCFM(void) { | |
75 | return __CFIsCFM; | |
76 | } | |
77 | ||
9ce05555 | 78 | #if defined(__WIN32__) |
d8925383 | 79 | #define PATH_SEP '\\' |
9ce05555 | 80 | #else |
d8925383 | 81 | #define PATH_SEP '/' |
9ce05555 A |
82 | #endif |
83 | ||
d8925383 A |
84 | #if !defined(__WIN32__) |
85 | #define PATH_LIST_SEP ':' | |
86 | ||
9ce05555 A |
87 | static char *_CFSearchForNameInPath(CFAllocatorRef alloc, const char *name, char *path) { |
88 | struct stat statbuf; | |
89 | char *nname = CFAllocatorAllocate(alloc, strlen(name) + strlen(path) + 2, 0); | |
90 | if (__CFOASafe) __CFSetLastAllocationEventName(nname, "CFUtilities (temp)"); | |
91 | for (;;) { | |
92 | char *p = (char *)strchr(path, PATH_LIST_SEP); | |
93 | if (NULL != p) { | |
94 | *p = '\0'; | |
95 | } | |
96 | nname[0] = '\0'; | |
97 | strcat(nname, path); | |
98 | strcat(nname, "/"); | |
99 | strcat(nname, name); | |
100 | // Could also do access(us, X_OK) == 0 in next condition, | |
101 | // for executable-only searching | |
102 | if (0 == stat(nname, &statbuf) && (statbuf.st_mode & S_IFMT) == S_IFREG) { | |
103 | if (p != NULL) { | |
104 | *p = PATH_LIST_SEP; | |
105 | } | |
106 | return nname; | |
107 | } | |
108 | if (NULL == p) { | |
109 | break; | |
110 | } | |
111 | *p = PATH_LIST_SEP; | |
112 | path = p + 1; | |
113 | } | |
114 | CFAllocatorDeallocate(alloc, nname); | |
115 | return NULL; | |
116 | } | |
117 | ||
d8925383 | 118 | #endif |
9ce05555 A |
119 | |
120 | ||
d8925383 A |
121 | #if defined(__WIN32__) |
122 | // Returns the path to the CF DLL, which we can then use to find resources like char sets | |
123 | ||
124 | __private_extern__ const char *_CFDLLPath(void) { | |
125 | static TCHAR cachedPath[MAX_PATH+1] = ""; | |
126 | ||
127 | if ('\0' == cachedPath[0]) { | |
128 | #if defined(DEBUG) | |
129 | char *DLLFileName = "CoreFoundation_debug"; | |
130 | #elif defined(PROFILE) | |
131 | char *DLLFileName = "CoreFoundation_profile"; | |
132 | #else | |
133 | char *DLLFileName = "CoreFoundation"; | |
134 | #endif | |
135 | HMODULE ourModule = GetModuleHandle(DLLFileName); | |
136 | CFAssert(ourModule, __kCFLogAssertion, "GetModuleHandle failed"); | |
137 | ||
138 | DWORD wResult = GetModuleFileName(ourModule, cachedPath, MAX_PATH+1); | |
139 | CFAssert1(wResult > 0, __kCFLogAssertion, "GetModuleFileName failed: %d", GetLastError()); | |
140 | CFAssert1(wResult < MAX_PATH+1, __kCFLogAssertion, "GetModuleFileName result truncated: %s", cachedPath); | |
141 | ||
142 | // strip off last component, the DLL name | |
143 | CFIndex idx; | |
144 | for (idx = wResult - 1; idx; idx--) { | |
145 | if ('\\' == cachedPath[idx]) { | |
146 | cachedPath[idx] = '\0'; | |
147 | break; | |
148 | } | |
149 | } | |
150 | } | |
151 | return cachedPath; | |
152 | } | |
153 | #endif | |
154 | ||
9ce05555 | 155 | static const char *__CFProcessPath = NULL; |
d8925383 | 156 | static const char *__CFprogname = NULL; |
9ce05555 | 157 | |
d8925383 A |
158 | const char **_CFGetProgname(void) { |
159 | if (!__CFprogname) | |
160 | _CFProcessPath(); // sets up __CFprogname as a side-effect | |
9ce05555 A |
161 | return &__CFprogname; |
162 | } | |
163 | ||
d8925383 A |
164 | const char **_CFGetProcessPath(void) { |
165 | if (!__CFProcessPath) | |
166 | _CFProcessPath(); // sets up __CFProcessPath as a side-effect | |
167 | return &__CFProcessPath; | |
168 | } | |
169 | ||
9ce05555 A |
170 | const char *_CFProcessPath(void) { |
171 | CFAllocatorRef alloc = NULL; | |
172 | char *thePath = NULL; | |
9ce05555 A |
173 | |
174 | if (__CFProcessPath) return __CFProcessPath; | |
175 | if (!__CFProcessPath) { | |
176 | thePath = getenv("CFProcessPath"); | |
177 | ||
178 | alloc = CFRetain(__CFGetDefaultAllocator()); | |
179 | ||
180 | if (thePath) { | |
181 | int len = strlen(thePath); | |
182 | __CFProcessPath = CFAllocatorAllocate(alloc, len+1, 0); | |
183 | if (__CFOASafe) __CFSetLastAllocationEventName((void *)__CFProcessPath, "CFUtilities (process-path)"); | |
184 | memmove((char *)__CFProcessPath, thePath, len + 1); | |
185 | } | |
186 | } | |
187 | ||
188 | #if defined(__MACH__) | |
d8925383 | 189 | int execIndex = 0; |
9ce05555 A |
190 | { |
191 | struct stat exec, lcfm; | |
d8925383 | 192 | uint32_t size = CFMaxPathSize; |
9ce05555 A |
193 | char buffer[CFMaxPathSize]; |
194 | if (0 == _NSGetExecutablePath(buffer, &size) && | |
195 | strcasestr(buffer, "LaunchCFMApp") != NULL && | |
196 | 0 == stat("/System/Library/Frameworks/Carbon.framework/Versions/Current/Support/LaunchCFMApp", &lcfm) && | |
197 | 0 == stat(buffer, &exec) && | |
198 | (lcfm.st_dev == exec.st_dev) && | |
199 | (lcfm.st_ino == exec.st_ino)) { | |
200 | // Executable is LaunchCFMApp, take special action | |
201 | execIndex = 1; | |
202 | __CFIsCFM = true; | |
203 | } | |
204 | } | |
205 | #endif | |
206 | ||
9ce05555 | 207 | #if defined(__WIN32__) |
d8925383 A |
208 | if (!__CFProcessPath) { |
209 | char buf[CFMaxPathSize] = {0}; | |
210 | DWORD rlen = GetModuleFileName(NULL, buf, 1028); | |
9ce05555 A |
211 | thePath = rlen ? buf : NULL; |
212 | #else | |
d8925383 A |
213 | if (!__CFProcessPath && NULL != (*_NSGetArgv())[execIndex]) { |
214 | char buf[CFMaxPathSize] = {0}; | |
9ce05555 A |
215 | struct stat statbuf; |
216 | const char *arg0 = (*_NSGetArgv())[execIndex]; | |
217 | if (arg0[0] == '/') { | |
218 | // We've got an absolute path; look no further; | |
219 | thePath = (char *)arg0; | |
220 | } else { | |
221 | char *theList = getenv("PATH"); | |
222 | if (NULL != theList && NULL == strrchr(arg0, '/')) { | |
223 | thePath = _CFSearchForNameInPath(alloc, arg0, theList); | |
224 | if (thePath) { | |
225 | // User could have "." or "../bin" or other relative path in $PATH | |
226 | if (('/' != thePath[0]) && _CFGetCurrentDirectory(buf, CFMaxPathSize)) { | |
23cd3127 A |
227 | strlcat(buf, "/", CFMaxPathSize); |
228 | strlcat(buf, thePath, CFMaxPathSize); | |
9ce05555 A |
229 | if (0 == stat(buf, &statbuf)) { |
230 | CFAllocatorDeallocate(alloc, (void *)thePath); | |
231 | thePath = buf; | |
232 | } | |
233 | } | |
234 | if (thePath != buf) { | |
23cd3127 | 235 | strlcpy(buf, thePath, CFMaxPathSize); |
9ce05555 A |
236 | CFAllocatorDeallocate(alloc, (void *)thePath); |
237 | thePath = buf; | |
238 | } | |
239 | } | |
240 | } | |
241 | } | |
242 | ||
243 | // After attempting a search through $PATH, if existant, | |
244 | // try prepending the current directory to argv[0]. | |
245 | if (!thePath && _CFGetCurrentDirectory(buf, CFMaxPathSize)) { | |
246 | if (buf[strlen(buf)-1] != '/') { | |
23cd3127 | 247 | strlcat(buf, "/", CFMaxPathSize); |
9ce05555 | 248 | } |
23cd3127 | 249 | strlcat(buf, arg0, CFMaxPathSize); |
9ce05555 A |
250 | if (0 == stat(buf, &statbuf)) { |
251 | thePath = buf; | |
252 | } | |
253 | } | |
254 | ||
255 | if (thePath) { | |
d8925383 | 256 | // We are going to process the buffer replacing all "/./" and "//" with "/" |
9ce05555 A |
257 | CFIndex srcIndex = 0, dstIndex = 0; |
258 | CFIndex len = strlen(thePath); | |
259 | for (srcIndex=0; srcIndex<len; srcIndex++) { | |
260 | thePath[dstIndex] = thePath[srcIndex]; | |
261 | dstIndex++; | |
d8925383 | 262 | while (srcIndex < len-1 && thePath[srcIndex] == '/' && (thePath[srcIndex+1] == '/' || (thePath[srcIndex+1] == '.' && srcIndex < len-2 && thePath[srcIndex+2] == '/'))) srcIndex += (thePath[srcIndex+1] == '/' ? 1 : 2); |
9ce05555 A |
263 | } |
264 | thePath[dstIndex] = 0; | |
265 | } | |
9ce05555 A |
266 | if (!thePath) { |
267 | thePath = (*_NSGetArgv())[execIndex]; | |
268 | } | |
d8925383 | 269 | #endif |
9ce05555 A |
270 | if (thePath) { |
271 | int len = strlen(thePath); | |
272 | __CFProcessPath = CFAllocatorAllocate(alloc, len + 1, 0); | |
273 | if (__CFOASafe) __CFSetLastAllocationEventName((void *)__CFProcessPath, "CFUtilities (process-path)"); | |
274 | memmove((char *)__CFProcessPath, thePath, len + 1); | |
275 | } | |
276 | if (__CFProcessPath) { | |
d8925383 | 277 | |
9ce05555 A |
278 | const char *p = 0; |
279 | int i; | |
280 | for (i = 0; __CFProcessPath[i] != 0; i++){ | |
d8925383 | 281 | if (__CFProcessPath[i] == PATH_SEP) |
9ce05555 A |
282 | p = __CFProcessPath + i; |
283 | } | |
284 | if (p != 0) | |
285 | __CFprogname = p + 1; | |
286 | else | |
287 | __CFprogname = __CFProcessPath; | |
288 | } | |
289 | } | |
290 | if (!__CFProcessPath) { | |
291 | __CFProcessPath = ""; | |
d8925383 A |
292 | __CFprogname = __CFProcessPath; |
293 | } else { | |
294 | const char *p = 0; | |
295 | int i; | |
296 | for (i = 0; __CFProcessPath[i] != 0; i++){ | |
297 | if (__CFProcessPath[i] == PATH_SEP) | |
298 | p = __CFProcessPath + i; | |
299 | } | |
300 | if (p != 0) | |
301 | __CFprogname = p + 1; | |
302 | else | |
303 | __CFprogname = __CFProcessPath; | |
9ce05555 A |
304 | } |
305 | return __CFProcessPath; | |
306 | } | |
307 | ||
308 | __private_extern__ CFStringRef _CFProcessNameString(void) { | |
309 | static CFStringRef __CFProcessNameString = NULL; | |
310 | if (!__CFProcessNameString) { | |
311 | const char *processName = *_CFGetProgname(); | |
312 | if (!processName) processName = ""; | |
313 | __CFProcessNameString = CFStringCreateWithCString(__CFGetDefaultAllocator(), processName, kCFPlatformInterfaceStringEncoding); | |
314 | } | |
315 | return __CFProcessNameString; | |
316 | } | |
317 | ||
9ce05555 | 318 | static CFStringRef __CFUserName = NULL; |
d8925383 A |
319 | |
320 | #if defined(__MACH__) || defined(__svr4__) || defined(__hpux__) || defined(__LINUX__) || defined(__FREEBSD__) | |
321 | static CFURLRef __CFHomeDirectory = NULL; | |
9ce05555 A |
322 | static uint32_t __CFEUID = -1; |
323 | static uint32_t __CFUID = -1; | |
324 | ||
9ce05555 A |
325 | static CFURLRef _CFCopyHomeDirURLForUser(struct passwd *upwd) { |
326 | CFURLRef home = NULL; | |
327 | if (upwd && upwd->pw_dir) { | |
328 | home = CFURLCreateFromFileSystemRepresentation(NULL, upwd->pw_dir, strlen(upwd->pw_dir), true); | |
329 | } | |
330 | return home; | |
331 | } | |
332 | ||
333 | static void _CFUpdateUserInfo(void) { | |
334 | struct passwd *upwd; | |
335 | ||
336 | __CFEUID = geteuid(); | |
337 | __CFUID = getuid(); | |
338 | if (__CFHomeDirectory) CFRelease(__CFHomeDirectory); | |
339 | __CFHomeDirectory = NULL; | |
340 | if (__CFUserName) CFRelease(__CFUserName); | |
341 | __CFUserName = NULL; | |
342 | ||
343 | upwd = getpwuid(__CFEUID ? __CFEUID : __CFUID); | |
344 | __CFHomeDirectory = _CFCopyHomeDirURLForUser(upwd); | |
345 | if (!__CFHomeDirectory) { | |
346 | const char *cpath = getenv("HOME"); | |
347 | if (cpath) { | |
348 | __CFHomeDirectory = CFURLCreateFromFileSystemRepresentation(NULL, cpath, strlen(cpath), true); | |
349 | } | |
350 | } | |
351 | ||
352 | // This implies that UserManager stores directory info in CString | |
353 | // rather than FileSystemRep. Perhaps this is wrong & we should | |
354 | // expect NeXTSTEP encodings. A great test of our localized system would | |
355 | // be to have a user "O-umlat z e r". XXX | |
356 | if (upwd && upwd->pw_name) { | |
357 | __CFUserName = CFStringCreateWithCString(NULL, upwd->pw_name, kCFPlatformInterfaceStringEncoding); | |
358 | } else { | |
359 | const char *cuser = getenv("USER"); | |
360 | if (cuser) | |
361 | __CFUserName = CFStringCreateWithCString(NULL, cuser, kCFPlatformInterfaceStringEncoding); | |
362 | } | |
363 | } | |
364 | #endif | |
365 | ||
366 | static CFURLRef _CFCreateHomeDirectoryURLForUser(CFStringRef uName) { | |
367 | #if defined(__MACH__) || defined(__svr4__) || defined(__hpux__) || defined(__LINUX__) || defined(__FREEBSD__) | |
368 | if (!uName) { | |
369 | if (geteuid() != __CFEUID || getuid() != __CFUID || !__CFHomeDirectory) | |
370 | _CFUpdateUserInfo(); | |
371 | if (__CFHomeDirectory) CFRetain(__CFHomeDirectory); | |
372 | return __CFHomeDirectory; | |
373 | } else { | |
374 | struct passwd *upwd = NULL; | |
375 | char buf[128], *user; | |
376 | SInt32 len = CFStringGetLength(uName), size = CFStringGetMaximumSizeForEncoding(len, kCFPlatformInterfaceStringEncoding); | |
377 | CFIndex usedSize; | |
378 | if (size < 127) { | |
379 | user = buf; | |
380 | } else { | |
381 | user = CFAllocatorAllocate(kCFAllocatorDefault, size+1, 0); | |
382 | if (__CFOASafe) __CFSetLastAllocationEventName(user, "CFUtilities (temp)"); | |
383 | } | |
384 | if (CFStringGetBytes(uName, CFRangeMake(0, len), kCFPlatformInterfaceStringEncoding, 0, true, user, size, &usedSize) == len) { | |
385 | user[usedSize] = '\0'; | |
386 | upwd = getpwnam(user); | |
387 | } | |
388 | if (buf != user) { | |
389 | CFAllocatorDeallocate(kCFAllocatorDefault, user); | |
390 | } | |
391 | return _CFCopyHomeDirURLForUser(upwd); | |
392 | } | |
393 | #elif defined(__WIN32__) | |
394 | #warning CF: Windows home directory goop disabled | |
395 | return NULL; | |
396 | #if 0 | |
397 | CFString *user = !uName ? CFUserName() : uName; | |
398 | ||
399 | if (!uName || CFEqual(user, CFUserName())) { | |
400 | const char *cpath = getenv("HOMEPATH"); | |
401 | const char *cdrive = getenv("HOMEDRIVE"); | |
402 | if (cdrive && cpath) { | |
403 | char fullPath[CFMaxPathSize]; | |
404 | CFStringRef str; | |
405 | strcpy(fullPath, cdrive); | |
406 | strncat(fullPath, cpath, CFMaxPathSize-strlen(cdrive)-1); | |
407 | str = CFStringCreateWithCString(NULL, fullPath, kCFPlatformInterfaceStringEncoding); | |
408 | home = CFURLCreateWithFileSystemPath(NULL, str, kCFURLWindowsPathStyle, true); | |
409 | CFRelease(str); | |
410 | } | |
411 | } | |
412 | if (!home) { | |
413 | struct _USER_INFO_2 *userInfo; | |
414 | HINSTANCE hinstDll = GetModuleHandleA("NETAPI32"); | |
415 | if (!hinstDll) | |
416 | hinstDll = LoadLibraryEx("NETAPI32", NULL, 0); | |
417 | if (hinstDll) { | |
418 | FARPROC lpfn = GetProcAddress(hinstDll, "NetUserGetInfo"); | |
419 | if (lpfn) { | |
420 | unsigned namelen = CFStringGetLength(user); | |
421 | UniChar *username; | |
422 | username = CFAllocatorAllocate(kCFAllocatorDefault, sizeof(UniChar) * (namelen + 1), 0); | |
423 | if (__CFOASafe) __CFSetLastAllocationEventName(username, "CFUtilities (temp)"); | |
424 | CFStringGetCharacters(user, CFRangeMake(0, namelen), username); | |
425 | if (!(*lpfn)(NULL, (LPWSTR)username, 2, (LPBYTE *)&userInfo)) { | |
426 | UInt32 len = 0; | |
427 | CFMutableStringRef str; | |
428 | while (userInfo->usri2_home_dir[len] != 0) len ++; | |
429 | str = CFStringCreateMutable(NULL, len+1); | |
430 | CFStringAppendCharacters(str, userInfo->usri2_home_dir, len); | |
431 | home = CFURLCreateWithFileSystemPath(NULL, str, kCFURLWindowsPathStyle, true); | |
432 | CFRelease(str); | |
433 | } | |
434 | CFAllocatorDeallocate(kCFAllocatorDefault, username); | |
435 | } | |
436 | } else { | |
437 | } | |
438 | } | |
439 | // We could do more here (as in KB Article Q101507). If that article is to | |
440 | // be believed, we should only run into this case on Win95, or through | |
441 | // user error. | |
442 | if (CFStringGetLength(CFURLGetPath(home)) == 0) { | |
443 | CFRelease(home); | |
444 | home=NULL; | |
445 | } | |
446 | #endif | |
447 | ||
448 | #else | |
449 | #error Dont know how to compute users home directories on this platform | |
450 | #endif | |
451 | } | |
452 | ||
453 | static CFStringRef _CFUserName(void) { | |
454 | #if defined(__MACH__) || defined(__svr4__) || defined(__hpux__) || defined(__LINUX__) || defined(__FREEBSD__) | |
455 | if (geteuid() != __CFEUID || getuid() != __CFUID) | |
456 | _CFUpdateUserInfo(); | |
457 | #elif defined(__WIN32__) | |
458 | if (!__CFUserName) { | |
459 | char username[1040]; | |
460 | DWORD size = 1040; | |
461 | username[0] = 0; | |
462 | if (GetUserNameA(username, &size)) { | |
463 | __CFUserName = CFStringCreateWithCString(NULL, username, kCFPlatformInterfaceStringEncoding); | |
464 | } else { | |
465 | const char *cname = getenv("USERNAME"); | |
466 | if (cname) | |
467 | __CFUserName = CFStringCreateWithCString(NULL, cname, kCFPlatformInterfaceStringEncoding); | |
468 | } | |
469 | } | |
470 | #else | |
471 | #error Dont know how to compute user name on this platform | |
472 | #endif | |
473 | if (!__CFUserName) | |
474 | __CFUserName = CFRetain(CFSTR("")); | |
475 | return __CFUserName; | |
476 | } | |
477 | ||
478 | __private_extern__ CFStringRef _CFGetUserName(void) { | |
479 | return CFStringCreateCopy(NULL, _CFUserName()); | |
480 | } | |
481 | ||
482 | #define CFMaxHostNameLength 256 | |
483 | #define CFMaxHostNameSize (CFMaxHostNameLength+1) | |
484 | ||
485 | __private_extern__ CFStringRef _CFStringCreateHostName(void) { | |
486 | char myName[CFMaxHostNameSize]; | |
487 | ||
488 | // return @"" instead of nil a la CFUserName() and Ali Ozer | |
489 | if (0 != gethostname(myName, CFMaxHostNameSize)) myName[0] = '\0'; | |
490 | return CFStringCreateWithCString(NULL, myName, kCFPlatformInterfaceStringEncoding); | |
491 | } | |
492 | ||
493 | /* These are sanitized versions of the above functions. We might want to eliminate the above ones someday. | |
494 | These can return NULL. | |
495 | */ | |
496 | CF_EXPORT CFStringRef CFGetUserName(void) { | |
497 | return _CFUserName(); | |
498 | } | |
499 | ||
500 | CF_EXPORT CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName) { | |
501 | return _CFCreateHomeDirectoryURLForUser(uName); | |
502 | } | |
503 | ||
9ce05555 A |
504 | #undef CFMaxHostNameLength |
505 | #undef CFMaxHostNameSize | |
506 |