+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/* CFPlatform.c
- Copyright 1999-2002, Apple, Inc. All rights reserved.
- Responsibility: Christopher Kane
-*/
-
-#include "CFInternal.h"
-#include "CFPriv.h"
-#if defined(__WIN32__)
- #include <windows.h>
- #include <stdlib.h>
-#else
- #include <sys/stat.h>
- #include <string.h>
- #include <unistd.h>
- #include <pwd.h>
-#endif
-#if defined(__MACH__)
- #include <crt_externs.h>
-#endif
-
-extern char *getenv(const char *name);
-
-#if defined(__MACH__)
-#define kCFPlatformInterfaceStringEncoding kCFStringEncodingUTF8
-#else
-#define kCFPlatformInterfaceStringEncoding CFStringGetSystemEncoding()
-#endif
-
-#if defined(__MACH__)
-char **_CFArgv(void) {
- return *_NSGetArgv();
-}
-
-int _CFArgc(void) {
- return *_NSGetArgc();
-}
-#endif
-
-
-__private_extern__ Boolean _CFGetCurrentDirectory(char *path, int maxlen) {
-#if defined(__WIN32__)
- DWORD len = GetCurrentDirectoryA(maxlen, path);
- return (0 != len && len + 1 <= maxlen);
-#else
- return getcwd(path, maxlen) != NULL;
-#endif
-}
-
-static Boolean __CFIsCFM = false;
-
-// If called super early, we just return false
-__private_extern__ Boolean _CFIsCFM(void) {
- return __CFIsCFM;
-}
-
-#if defined(__WIN32__)
-#define PATH_SEP '\\'
-#else
-#define PATH_SEP '/'
-#endif
-
-#if !defined(__WIN32__)
-#define PATH_LIST_SEP ':'
-
-static char *_CFSearchForNameInPath(CFAllocatorRef alloc, const char *name, char *path) {
- struct stat statbuf;
- char *nname = CFAllocatorAllocate(alloc, strlen(name) + strlen(path) + 2, 0);
- if (__CFOASafe) __CFSetLastAllocationEventName(nname, "CFUtilities (temp)");
- for (;;) {
- char *p = (char *)strchr(path, PATH_LIST_SEP);
- if (NULL != p) {
- *p = '\0';
- }
- nname[0] = '\0';
- strcat(nname, path);
- strcat(nname, "/");
- strcat(nname, name);
- // Could also do access(us, X_OK) == 0 in next condition,
- // for executable-only searching
- if (0 == stat(nname, &statbuf) && (statbuf.st_mode & S_IFMT) == S_IFREG) {
- if (p != NULL) {
- *p = PATH_LIST_SEP;
- }
- return nname;
- }
- if (NULL == p) {
- break;
- }
- *p = PATH_LIST_SEP;
- path = p + 1;
- }
- CFAllocatorDeallocate(alloc, nname);
- return NULL;
-}
-
-#endif
-
-
-#if defined(__WIN32__)
-// Returns the path to the CF DLL, which we can then use to find resources like char sets
-
-__private_extern__ const char *_CFDLLPath(void) {
- static TCHAR cachedPath[MAX_PATH+1] = "";
-
- if ('\0' == cachedPath[0]) {
-#if defined(DEBUG)
- char *DLLFileName = "CoreFoundation_debug";
-#elif defined(PROFILE)
- char *DLLFileName = "CoreFoundation_profile";
-#else
- char *DLLFileName = "CoreFoundation";
-#endif
- HMODULE ourModule = GetModuleHandle(DLLFileName);
- CFAssert(ourModule, __kCFLogAssertion, "GetModuleHandle failed");
-
- DWORD wResult = GetModuleFileName(ourModule, cachedPath, MAX_PATH+1);
- CFAssert1(wResult > 0, __kCFLogAssertion, "GetModuleFileName failed: %d", GetLastError());
- CFAssert1(wResult < MAX_PATH+1, __kCFLogAssertion, "GetModuleFileName result truncated: %s", cachedPath);
-
- // strip off last component, the DLL name
- CFIndex idx;
- for (idx = wResult - 1; idx; idx--) {
- if ('\\' == cachedPath[idx]) {
- cachedPath[idx] = '\0';
- break;
- }
- }
- }
- return cachedPath;
-}
-#endif
-
-static const char *__CFProcessPath = NULL;
-static const char *__CFprogname = NULL;
-
-const char **_CFGetProgname(void) {
- if (!__CFprogname)
- _CFProcessPath(); // sets up __CFprogname as a side-effect
- return &__CFprogname;
-}
-
-const char **_CFGetProcessPath(void) {
- if (!__CFProcessPath)
- _CFProcessPath(); // sets up __CFProcessPath as a side-effect
- return &__CFProcessPath;
-}
-
-const char *_CFProcessPath(void) {
- CFAllocatorRef alloc = NULL;
- char *thePath = NULL;
-
- if (__CFProcessPath) return __CFProcessPath;
- if (!__CFProcessPath) {
- thePath = getenv("CFProcessPath");
-
- alloc = CFRetain(__CFGetDefaultAllocator());
-
- if (thePath) {
- int len = strlen(thePath);
- __CFProcessPath = CFAllocatorAllocate(alloc, len+1, 0);
- if (__CFOASafe) __CFSetLastAllocationEventName((void *)__CFProcessPath, "CFUtilities (process-path)");
- memmove((char *)__CFProcessPath, thePath, len + 1);
- }
- }
-
-#if defined(__MACH__)
- int execIndex = 0;
- {
- struct stat exec, lcfm;
- uint32_t size = CFMaxPathSize;
- char buffer[CFMaxPathSize];
- if (0 == _NSGetExecutablePath(buffer, &size) &&
- strcasestr(buffer, "LaunchCFMApp") != NULL &&
- 0 == stat("/System/Library/Frameworks/Carbon.framework/Versions/Current/Support/LaunchCFMApp", &lcfm) &&
- 0 == stat(buffer, &exec) &&
- (lcfm.st_dev == exec.st_dev) &&
- (lcfm.st_ino == exec.st_ino)) {
- // Executable is LaunchCFMApp, take special action
- execIndex = 1;
- __CFIsCFM = true;
- }
- }
-#endif
-
-#if defined(__WIN32__)
- if (!__CFProcessPath) {
- char buf[CFMaxPathSize] = {0};
- DWORD rlen = GetModuleFileName(NULL, buf, 1028);
- thePath = rlen ? buf : NULL;
-#else
- if (!__CFProcessPath && NULL != (*_NSGetArgv())[execIndex]) {
- char buf[CFMaxPathSize] = {0};
- struct stat statbuf;
- const char *arg0 = (*_NSGetArgv())[execIndex];
- if (arg0[0] == '/') {
- // We've got an absolute path; look no further;
- thePath = (char *)arg0;
- } else {
- char *theList = getenv("PATH");
- if (NULL != theList && NULL == strrchr(arg0, '/')) {
- thePath = _CFSearchForNameInPath(alloc, arg0, theList);
- if (thePath) {
- // User could have "." or "../bin" or other relative path in $PATH
- if (('/' != thePath[0]) && _CFGetCurrentDirectory(buf, CFMaxPathSize)) {
- strlcat(buf, "/", CFMaxPathSize);
- strlcat(buf, thePath, CFMaxPathSize);
- if (0 == stat(buf, &statbuf)) {
- CFAllocatorDeallocate(alloc, (void *)thePath);
- thePath = buf;
- }
- }
- if (thePath != buf) {
- strlcpy(buf, thePath, CFMaxPathSize);
- CFAllocatorDeallocate(alloc, (void *)thePath);
- thePath = buf;
- }
- }
- }
- }
-
- // After attempting a search through $PATH, if existant,
- // try prepending the current directory to argv[0].
- if (!thePath && _CFGetCurrentDirectory(buf, CFMaxPathSize)) {
- if (buf[strlen(buf)-1] != '/') {
- strlcat(buf, "/", CFMaxPathSize);
- }
- strlcat(buf, arg0, CFMaxPathSize);
- if (0 == stat(buf, &statbuf)) {
- thePath = buf;
- }
- }
-
- if (thePath) {
- // We are going to process the buffer replacing all "/./" and "//" with "/"
- CFIndex srcIndex = 0, dstIndex = 0;
- CFIndex len = strlen(thePath);
- for (srcIndex=0; srcIndex<len; srcIndex++) {
- thePath[dstIndex] = thePath[srcIndex];
- dstIndex++;
- while (srcIndex < len-1 && thePath[srcIndex] == '/' && (thePath[srcIndex+1] == '/' || (thePath[srcIndex+1] == '.' && srcIndex < len-2 && thePath[srcIndex+2] == '/'))) srcIndex += (thePath[srcIndex+1] == '/' ? 1 : 2);
- }
- thePath[dstIndex] = 0;
- }
- if (!thePath) {
- thePath = (*_NSGetArgv())[execIndex];
- }
-#endif
- if (thePath) {
- int len = strlen(thePath);
- __CFProcessPath = CFAllocatorAllocate(alloc, len + 1, 0);
- if (__CFOASafe) __CFSetLastAllocationEventName((void *)__CFProcessPath, "CFUtilities (process-path)");
- memmove((char *)__CFProcessPath, thePath, len + 1);
- }
- if (__CFProcessPath) {
-
- const char *p = 0;
- int i;
- for (i = 0; __CFProcessPath[i] != 0; i++){
- if (__CFProcessPath[i] == PATH_SEP)
- p = __CFProcessPath + i;
- }
- if (p != 0)
- __CFprogname = p + 1;
- else
- __CFprogname = __CFProcessPath;
- }
- }
- if (!__CFProcessPath) {
- __CFProcessPath = "";
- __CFprogname = __CFProcessPath;
- } else {
- const char *p = 0;
- int i;
- for (i = 0; __CFProcessPath[i] != 0; i++){
- if (__CFProcessPath[i] == PATH_SEP)
- p = __CFProcessPath + i;
- }
- if (p != 0)
- __CFprogname = p + 1;
- else
- __CFprogname = __CFProcessPath;
- }
- return __CFProcessPath;
-}
-
-__private_extern__ CFStringRef _CFProcessNameString(void) {
- static CFStringRef __CFProcessNameString = NULL;
- if (!__CFProcessNameString) {
- const char *processName = *_CFGetProgname();
- if (!processName) processName = "";
- __CFProcessNameString = CFStringCreateWithCString(__CFGetDefaultAllocator(), processName, kCFPlatformInterfaceStringEncoding);
- }
- return __CFProcessNameString;
-}
-
-static CFStringRef __CFUserName = NULL;
-
-#if defined(__MACH__) || defined(__svr4__) || defined(__hpux__) || defined(__LINUX__) || defined(__FREEBSD__)
-static CFURLRef __CFHomeDirectory = NULL;
-static uint32_t __CFEUID = -1;
-static uint32_t __CFUID = -1;
-
-static CFURLRef _CFCopyHomeDirURLForUser(struct passwd *upwd) {
- CFURLRef home = NULL;
- if (upwd && upwd->pw_dir) {
- home = CFURLCreateFromFileSystemRepresentation(NULL, upwd->pw_dir, strlen(upwd->pw_dir), true);
- }
- return home;
-}
-
-static void _CFUpdateUserInfo(void) {
- struct passwd *upwd;
-
- __CFEUID = geteuid();
- __CFUID = getuid();
- if (__CFHomeDirectory) CFRelease(__CFHomeDirectory);
- __CFHomeDirectory = NULL;
- if (__CFUserName) CFRelease(__CFUserName);
- __CFUserName = NULL;
-
- upwd = getpwuid(__CFEUID ? __CFEUID : __CFUID);
- __CFHomeDirectory = _CFCopyHomeDirURLForUser(upwd);
- if (!__CFHomeDirectory) {
- const char *cpath = getenv("HOME");
- if (cpath) {
- __CFHomeDirectory = CFURLCreateFromFileSystemRepresentation(NULL, cpath, strlen(cpath), true);
- }
- }
-
- // This implies that UserManager stores directory info in CString
- // rather than FileSystemRep. Perhaps this is wrong & we should
- // expect NeXTSTEP encodings. A great test of our localized system would
- // be to have a user "O-umlat z e r". XXX
- if (upwd && upwd->pw_name) {
- __CFUserName = CFStringCreateWithCString(NULL, upwd->pw_name, kCFPlatformInterfaceStringEncoding);
- } else {
- const char *cuser = getenv("USER");
- if (cuser)
- __CFUserName = CFStringCreateWithCString(NULL, cuser, kCFPlatformInterfaceStringEncoding);
- }
-}
-#endif
-
-static CFURLRef _CFCreateHomeDirectoryURLForUser(CFStringRef uName) {
-#if defined(__MACH__) || defined(__svr4__) || defined(__hpux__) || defined(__LINUX__) || defined(__FREEBSD__)
- if (!uName) {
- if (geteuid() != __CFEUID || getuid() != __CFUID || !__CFHomeDirectory)
- _CFUpdateUserInfo();
- if (__CFHomeDirectory) CFRetain(__CFHomeDirectory);
- return __CFHomeDirectory;
- } else {
- struct passwd *upwd = NULL;
- char buf[128], *user;
- SInt32 len = CFStringGetLength(uName), size = CFStringGetMaximumSizeForEncoding(len, kCFPlatformInterfaceStringEncoding);
- CFIndex usedSize;
- if (size < 127) {
- user = buf;
- } else {
- user = CFAllocatorAllocate(kCFAllocatorDefault, size+1, 0);
- if (__CFOASafe) __CFSetLastAllocationEventName(user, "CFUtilities (temp)");
- }
- if (CFStringGetBytes(uName, CFRangeMake(0, len), kCFPlatformInterfaceStringEncoding, 0, true, user, size, &usedSize) == len) {
- user[usedSize] = '\0';
- upwd = getpwnam(user);
- }
- if (buf != user) {
- CFAllocatorDeallocate(kCFAllocatorDefault, user);
- }
- return _CFCopyHomeDirURLForUser(upwd);
- }
-#elif defined(__WIN32__)
-#warning CF: Windows home directory goop disabled
- return NULL;
-#if 0
- CFString *user = !uName ? CFUserName() : uName;
-
- if (!uName || CFEqual(user, CFUserName())) {
- const char *cpath = getenv("HOMEPATH");
- const char *cdrive = getenv("HOMEDRIVE");
- if (cdrive && cpath) {
- char fullPath[CFMaxPathSize];
- CFStringRef str;
- strcpy(fullPath, cdrive);
- strncat(fullPath, cpath, CFMaxPathSize-strlen(cdrive)-1);
- str = CFStringCreateWithCString(NULL, fullPath, kCFPlatformInterfaceStringEncoding);
- home = CFURLCreateWithFileSystemPath(NULL, str, kCFURLWindowsPathStyle, true);
- CFRelease(str);
- }
- }
- if (!home) {
- struct _USER_INFO_2 *userInfo;
- HINSTANCE hinstDll = GetModuleHandleA("NETAPI32");
- if (!hinstDll)
- hinstDll = LoadLibraryEx("NETAPI32", NULL, 0);
- if (hinstDll) {
- FARPROC lpfn = GetProcAddress(hinstDll, "NetUserGetInfo");
- if (lpfn) {
- unsigned namelen = CFStringGetLength(user);
- UniChar *username;
- username = CFAllocatorAllocate(kCFAllocatorDefault, sizeof(UniChar) * (namelen + 1), 0);
- if (__CFOASafe) __CFSetLastAllocationEventName(username, "CFUtilities (temp)");
- CFStringGetCharacters(user, CFRangeMake(0, namelen), username);
- if (!(*lpfn)(NULL, (LPWSTR)username, 2, (LPBYTE *)&userInfo)) {
- UInt32 len = 0;
- CFMutableStringRef str;
- while (userInfo->usri2_home_dir[len] != 0) len ++;
- str = CFStringCreateMutable(NULL, len+1);
- CFStringAppendCharacters(str, userInfo->usri2_home_dir, len);
- home = CFURLCreateWithFileSystemPath(NULL, str, kCFURLWindowsPathStyle, true);
- CFRelease(str);
- }
- CFAllocatorDeallocate(kCFAllocatorDefault, username);
- }
- } else {
- }
- }
- // We could do more here (as in KB Article Q101507). If that article is to
- // be believed, we should only run into this case on Win95, or through
- // user error.
- if (CFStringGetLength(CFURLGetPath(home)) == 0) {
- CFRelease(home);
- home=NULL;
- }
-#endif
-
-#else
-#error Dont know how to compute users home directories on this platform
-#endif
-}
-
-static CFStringRef _CFUserName(void) {
-#if defined(__MACH__) || defined(__svr4__) || defined(__hpux__) || defined(__LINUX__) || defined(__FREEBSD__)
- if (geteuid() != __CFEUID || getuid() != __CFUID)
- _CFUpdateUserInfo();
-#elif defined(__WIN32__)
- if (!__CFUserName) {
- char username[1040];
- DWORD size = 1040;
- username[0] = 0;
- if (GetUserNameA(username, &size)) {
- __CFUserName = CFStringCreateWithCString(NULL, username, kCFPlatformInterfaceStringEncoding);
- } else {
- const char *cname = getenv("USERNAME");
- if (cname)
- __CFUserName = CFStringCreateWithCString(NULL, cname, kCFPlatformInterfaceStringEncoding);
- }
- }
-#else
-#error Dont know how to compute user name on this platform
-#endif
- if (!__CFUserName)
- __CFUserName = CFRetain(CFSTR(""));
- return __CFUserName;
-}
-
-__private_extern__ CFStringRef _CFGetUserName(void) {
- return CFStringCreateCopy(NULL, _CFUserName());
-}
-
-#define CFMaxHostNameLength 256
-#define CFMaxHostNameSize (CFMaxHostNameLength+1)
-
-__private_extern__ CFStringRef _CFStringCreateHostName(void) {
- char myName[CFMaxHostNameSize];
-
- // return @"" instead of nil a la CFUserName() and Ali Ozer
- if (0 != gethostname(myName, CFMaxHostNameSize)) myName[0] = '\0';
- return CFStringCreateWithCString(NULL, myName, kCFPlatformInterfaceStringEncoding);
-}
-
-/* These are sanitized versions of the above functions. We might want to eliminate the above ones someday.
- These can return NULL.
-*/
-CF_EXPORT CFStringRef CFGetUserName(void) {
- return _CFUserName();
-}
-
-CF_EXPORT CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName) {
- return _CFCreateHomeDirectoryURLForUser(uName);
-}
-
-#undef CFMaxHostNameLength
-#undef CFMaxHostNameSize
-