X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=fish%2Ftilde.c;h=ee87ce1b29ce13d188a6378fe06f8ba3bc61a9ab;hp=64b5b399f0e5546abb3bdfdf48f5f5421828bb20;hb=1fdd0193fd63af71359748915a0326d623a3d6ad;hpb=3e70b34eed5a48640e20fbf6dcba774aaace1f3c diff --git a/fish/tilde.c b/fish/tilde.c index 64b5b39..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,11 +57,11 @@ 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"); - exit (1); + exit (EXIT_FAILURE); } strcpy (str, home); strcat (str, rest); @@ -76,20 +75,27 @@ 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); + len = strlen (home) + (append ? strlen (append) : 0) + 1; str = malloc (len); if (str == NULL) { perror ("malloc"); - exit (1); + exit (EXIT_FAILURE); } strcpy (str, home); @@ -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; +}