X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=fish%2Ftilde.c;h=ee87ce1b29ce13d188a6378fe06f8ba3bc61a9ab;hb=635af5be04265f845186b40e9a9fe7b102ad6909;hp=83aa70d9a6708656dfcfabb0869a82bfc47cd561;hpb=1d5ec10659d67020c5b709e4df4c49bc0d59d58c;p=libguestfs.git diff --git a/fish/tilde.c b/fish/tilde.c index 83aa70d..ee87ce1 100644 --- a/fish/tilde.c +++ b/fish/tilde.c @@ -28,8 +28,9 @@ #include "fish.h" -static char *expand_home (const char *); +static char *expand_home (char *orig, const char *append); static const char *find_home_for_username (const char *, size_t); +static const char *find_home_for_current_user (void); /* This is called from the script loop if we find a candidate for * ~username (tilde-expansion). @@ -39,13 +40,11 @@ try_tilde_expansion (char *str) { assert (str[0] == '~'); - /* Expand current user's home directory. By simple experimentation - * I found out that bash always uses $HOME. - */ + /* Expand "~" to current user's home directory. */ if (str[1] == '\0') /* ~ */ - return expand_home (NULL); + return expand_home (str, NULL); else if (str[1] == '/') /* ~/... */ - return expand_home (&str[1]); + return expand_home (str, &str[1]); /* Try expanding the part up to the following '\0' or '/' as a * username from the password file. @@ -58,7 +57,7 @@ try_tilde_expansion (char *str) home = find_home_for_username (&str[1], len); if (home) { - len = strlen (home) + strlen (rest); + len = strlen (home) + strlen (rest) + 1; str = malloc (len); if (str == NULL) { perror ("malloc"); @@ -76,14 +75,21 @@ try_tilde_expansion (char *str) /* Return $HOME + append string. */ static char * -expand_home (const char *append) +expand_home (char *orig, const char *append) { const char *home; int len; char *str; home = getenv ("HOME"); - if (!home) home = "~"; + if (!home) { + /* $HOME not set, bash can look up the current user in the + * password file and find their home that way. (RHBZ#617440). + */ + home = find_home_for_current_user (); + if (!home) + return orig; + } len = strlen (home) + (append ? strlen (append) : 0) + 1; str = malloc (len); @@ -116,3 +122,18 @@ find_home_for_username (const char *username, size_t ulen) return NULL; } + +static const char * +find_home_for_current_user (void) +{ + struct passwd *pw; + uid_t euid = geteuid (); + + setpwent (); + while ((pw = getpwent ()) != NULL) { + if (pw->pw_uid == euid) + return pw->pw_dir; + } + + return NULL; +}