Beispiel #1
0
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);
    }
}
Beispiel #2
0
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
}
Beispiel #3
0
CF_EXPORT CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName) {
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
    if (!uName) {
        uid_t euid;
        __CFGetUGIDs(&euid, NULL);
        struct passwd *upwd = getpwuid(euid ? euid : getuid());
        return _CFCopyHomeDirURLForUser(upwd, true);
    } 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(kCFAllocatorSystemDefault, size+1, 0);
        }
        if (CFStringGetBytes(uName, CFRangeMake(0, len), kCFPlatformInterfaceStringEncoding, 0, true, (uint8_t *)user, size, &usedSize) == len) {
            user[usedSize] = '\0';
            upwd = getpwnam(user);
        }
        if (buf != user) {
            CFAllocatorDeallocate(kCFAllocatorSystemDefault, user);
        }
        return _CFCopyHomeDirURLForUser(upwd, false);
    }
#elif DEPLOYMENT_TARGET_WINDOWS
    // This code can only get the directory for the current user
    CFStringRef userName = uName ? CFCopyUserName() : NULL;
    if (uName && !CFEqual(uName, userName)) {
        CFLog(kCFLogLevelError, CFSTR("CFCopyHomeDirectoryURLForUser(): Unable to get home directory for other user"));
        if (userName) CFRelease(userName);
        return NULL;
    }
    if (userName) CFRelease(userName);
    return CFCopyHomeDirectoryURL();
#else
#error Dont know how to compute users home directories on this platform
#endif
}
Beispiel #4
0
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
}