CF_EXPORT CFStringRef CFCopyUserName(void) { CFStringRef result = NULL; #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD uid_t euid; __CFGetUGIDs(&euid, NULL); struct passwd *upwd = getpwuid(euid ? euid : getuid()); if (upwd && upwd->pw_name) { result = CFStringCreateWithCString(kCFAllocatorSystemDefault, upwd->pw_name, kCFPlatformInterfaceStringEncoding); } else { const char *cuser = __CFgetenv("USER"); if (cuser) { result = CFStringCreateWithCString(kCFAllocatorSystemDefault, cuser, kCFPlatformInterfaceStringEncoding); } } #elif DEPLOYMENT_TARGET_WINDOWS wchar_t username[1040]; DWORD size = 1040; username[0] = 0; if (GetUserNameW(username, &size)) { // discount the extra NULL by decrementing the size result = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (const UniChar *)username, size - 1); } else { const char *cname = __CFgetenv("USERNAME"); if (cname) { result = CFStringCreateWithCString(kCFAllocatorSystemDefault, cname, kCFPlatformInterfaceStringEncoding); } } #else #error Dont know how to compute user name on this platform #endif if (!result) result = (CFStringRef)CFRetain(CFSTR("")); return result; }
// Set the fallBackToHome parameter to true if we should fall back to the HOME environment variable if all else fails. Otherwise return NULL. static CFURLRef _CFCopyHomeDirURLForUser(const char *username, bool fallBackToHome) { const char *fixedHomePath = issetugid() ? NULL : __CFgetenv("CFFIXED_USER_HOME"); const char *homePath = NULL; // Calculate the home directory we will use // First try CFFIXED_USER_HOME (only if not setugid), then fall back to the upwd, then fall back to HOME environment variable CFURLRef home = NULL; if (!issetugid() && fixedHomePath) home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)fixedHomePath, strlen(fixedHomePath), true); if (!home) { struct passwd *upwd = NULL; if (username) { upwd = getpwnam(username); } else { uid_t euid; __CFGetUGIDs(&euid, NULL); upwd = getpwuid(euid ?: getuid()); } if (upwd && upwd->pw_dir) { home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)upwd->pw_dir, strlen(upwd->pw_dir), true); } } if (fallBackToHome && !home) homePath = __CFgetenv("HOME"); if (fallBackToHome && !home && homePath) home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)homePath, strlen(homePath), true); return home; }
CFURLRef CFCopyHomeDirectoryURL(void) { #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD uid_t euid; __CFGetUGIDs(&euid, NULL); struct passwd *upwd = getpwuid(euid ? euid : getuid()); return _CFCopyHomeDirURLForUser(upwd, true); #elif DEPLOYMENT_TARGET_WINDOWS CFURLRef retVal = NULL; CFIndex len = 0; CFStringRef str = NULL; UniChar pathChars[MAX_PATH]; if (S_OK == SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, (wchar_t *)pathChars)) { len = (CFIndex)wcslen((wchar_t *)pathChars); str = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, pathChars, len); retVal = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str, kCFURLWindowsPathStyle, true); CFRelease(str); } if (!retVal) { // Fall back to environment variable, but this will not be unicode compatible const char *cpath = __CFgetenv("HOMEPATH"); const char *cdrive = __CFgetenv("HOMEDRIVE"); if (cdrive && cpath) { char fullPath[CFMaxPathSize]; strlcpy(fullPath, cdrive, sizeof(fullPath)); strlcat(fullPath, cpath, sizeof(fullPath)); str = CFStringCreateWithCString(kCFAllocatorSystemDefault, fullPath, kCFPlatformInterfaceStringEncoding); retVal = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str, kCFURLWindowsPathStyle, true); CFRelease(str); } } if (!retVal) { // Last resort: We have to get "some" directory location, so fall-back to the processes current directory. UniChar currDir[MAX_PATH]; DWORD dwChars = GetCurrentDirectoryW(MAX_PATH + 1, (wchar_t *)currDir); if (dwChars > 0) { len = (CFIndex)wcslen((wchar_t *)currDir); str = CFStringCreateWithCharacters(kCFAllocatorDefault, currDir, len); retVal = CFURLCreateWithFileSystemPath(NULL, str, kCFURLWindowsPathStyle, true); CFRelease(str); } } // 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. CFStringRef testPath = CFURLCopyFileSystemPath(retVal, kCFURLWindowsPathStyle); if (CFStringGetLength(testPath) == 0) { CFRelease(retVal); retVal = NULL; } if (testPath) CFRelease(testPath); return retVal; #else #error Dont know how to compute users home directories on this platform #endif }
const char *_CFProcessPath(void) { if (__CFProcessPath) return __CFProcessPath; #if DEPLOYMENT_TARGET_MACOSX if (!issetugid()) { const char *path = (char *)__CFgetenv("CFProcessPath"); if (path) { __CFProcessPath = strdup(path); __CFprogname = strrchr(__CFProcessPath, PATH_SEP); __CFprogname = (__CFprogname ? __CFprogname + 1 : __CFProcessPath); return __CFProcessPath; } } #endif uint32_t size = CFMaxPathSize; char buffer[size]; if (0 == _NSGetExecutablePath(buffer, &size)) { __CFProcessPath = strdup(buffer); __CFprogname = strrchr(__CFProcessPath, PATH_SEP); __CFprogname = (__CFprogname ? __CFprogname + 1 : __CFProcessPath); } if (!__CFProcessPath) { __CFProcessPath = ""; __CFprogname = __CFProcessPath; } return __CFProcessPath; }