summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
Diffstat (limited to 'win')
-rw-r--r--win/tclWinFile.c48
-rw-r--r--win/tclWinInit.c34
-rw-r--r--win/tclWinInt.h2
3 files changed, 63 insertions, 21 deletions
diff --git a/win/tclWinFile.c b/win/tclWinFile.c
index a70717e..0595e6c 100644
--- a/win/tclWinFile.c
+++ b/win/tclWinFile.c
@@ -1438,34 +1438,62 @@ TclpGetUserHome(
* name of user's home directory. */
{
char *result = NULL;
- USER_INFO_1 *uiPtr, **uiPtrPtr = &uiPtr;
+ USER_INFO_1 *uiPtr;
Tcl_DString ds;
int nameLen = -1;
- int badDomain = 0;
- char *domain;
+ int rc = 0;
+ const char *domain;
WCHAR *wName, *wHomeDir, *wDomain;
WCHAR buf[MAX_PATH];
Tcl_DStringInit(bufferPtr);
+
wDomain = NULL;
- domain = strchr(name, '@');
- if (domain != NULL) {
+ domain = Tcl_UtfFindFirst(name, '@');
+ if (domain == NULL) {
+ const char *ptr;
+
+ /* no domain - firstly check it's the current user */
+ if ( (ptr = TclpGetUserName(&ds)) != NULL
+ && strcasecmp(name, ptr) == 0
+ ) {
+ /* try safest and fastest way to get current user home */
+ ptr = TclGetEnv("HOME", &ds);
+ if (ptr != NULL) {
+ Tcl_JoinPath(1, &ptr, bufferPtr);
+ rc = 1;
+ result = Tcl_DStringValue(bufferPtr);
+ }
+ }
+ Tcl_DStringFree(&ds);
+ } else {
Tcl_DStringInit(&ds);
wName = Tcl_UtfToUniCharDString(domain + 1, -1, &ds);
- badDomain = NetGetDCName(NULL, wName, (LPBYTE *) &wDomain);
+ rc = NetGetDCName(NULL, wName, (LPBYTE *) &wDomain);
Tcl_DStringFree(&ds);
nameLen = domain - name;
}
- if (badDomain == 0) {
+ if (rc == 0) {
Tcl_DStringInit(&ds);
wName = Tcl_UtfToUniCharDString(name, nameLen, &ds);
- if (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) uiPtrPtr) == 0) {
+ while (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) &uiPtr) != 0) {
+ /*
+ * user does not exists - if domain was not specified,
+ * try again using current domain.
+ */
+ rc = 1;
+ if (domain != NULL) break;
+ /* get current domain */
+ rc = NetGetDCName(NULL, NULL, (LPBYTE *) &wDomain);
+ if (rc != 0) break;
+ domain = INT2PTR(-1); /* repeat once */
+ }
+ if (rc == 0) {
DWORD i, size = MAX_PATH;
wHomeDir = uiPtr->usri1_home_dir;
if ((wHomeDir != NULL) && (wHomeDir[0] != L'\0')) {
size = lstrlenW(wHomeDir);
- Tcl_UniCharToUtfDString(wHomeDir, size,
- bufferPtr);
+ Tcl_UniCharToUtfDString(wHomeDir, size, bufferPtr);
} else {
/*
* User exists but has no home dir. Return
diff --git a/win/tclWinInit.c b/win/tclWinInit.c
index 91f149b..b77a580 100644
--- a/win/tclWinInit.c
+++ b/win/tclWinInit.c
@@ -503,6 +503,27 @@ Tcl_GetEncodingNameFromEnvironment(
return Tcl_DStringValue(bufPtr);
}
+const char *
+TclpGetUserName(
+ Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with
+ * the name of user. */
+{
+ Tcl_DStringInit(bufferPtr);
+
+ if (TclGetEnv("USERNAME", bufferPtr) == NULL) {
+ TCHAR szUserName[UNLEN+1];
+ DWORD cchUserNameLen = UNLEN;
+
+ if (!GetUserName(szUserName, &cchUserNameLen)) {
+ return NULL;
+ }
+ cchUserNameLen--;
+ cchUserNameLen *= sizeof(TCHAR);
+ Tcl_WinTCharToUtf(szUserName, cchUserNameLen, bufferPtr);
+ }
+ return Tcl_DStringValue(bufferPtr);
+}
+
/*
*---------------------------------------------------------------------------
*
@@ -533,8 +554,6 @@ TclpSetVariables(
static OSVERSIONINFOW osInfo;
static int osInfoInitialized = 0;
Tcl_DString ds;
- TCHAR szUserName[UNLEN+1];
- DWORD cchUserNameLen = UNLEN;
Tcl_SetVar2Ex(interp, "tclDefaultLibrary", NULL,
TclGetProcessGlobalValue(&defaultLibraryDir), TCL_GLOBAL_ONLY);
@@ -609,15 +628,8 @@ TclpSetVariables(
* Note: cchUserNameLen is number of characters including nul terminator.
*/
- Tcl_DStringInit(&ds);
- if (TclGetEnv("USERNAME", &ds) == NULL) {
- if (GetUserName(szUserName, &cchUserNameLen) != 0) {
- int cbUserNameLen = cchUserNameLen - 1;
- cbUserNameLen *= sizeof(TCHAR);
- Tcl_WinTCharToUtf(szUserName, cbUserNameLen, &ds);
- }
- }
- Tcl_SetVar2(interp, "tcl_platform", "user", Tcl_DStringValue(&ds),
+ ptr = TclpGetUserName(&ds);
+ Tcl_SetVar2(interp, "tcl_platform", "user", ptr ? ptr : "",
TCL_GLOBAL_ONLY);
Tcl_DStringFree(&ds);
diff --git a/win/tclWinInt.h b/win/tclWinInt.h
index a1ccb36..63835bf 100644
--- a/win/tclWinInt.h
+++ b/win/tclWinInt.h
@@ -64,6 +64,8 @@ MODULE_SCOPE int TclWinSymLinkDelete(const TCHAR *LinkOriginal,
int linkOnly);
MODULE_SCOPE int TclWinFileOwned(Tcl_Obj *);
+MODULE_SCOPE const char*TclpGetUserName(Tcl_DString *bufferPtr);
+
/* Needed by tclWinFile.c and tclWinFCmd.c */
#ifndef FILE_ATTRIBUTE_REPARSE_POINT
#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400