diff --git a/vfs/fish.c b/vfs/fish.c index 09bac1172..04c85273f 100644 --- a/vfs/fish.c +++ b/vfs/fish.c @@ -248,8 +248,23 @@ fish_open_archive_int (struct vfs_class *me, struct vfs_s_super *super) argv[i++] = gbuf; } - argv[i++] = "-l"; - argv[i++] = SUP.user; + /* + * Add the user name to the ssh command line only if it was explicitly + * set in vfs URL. rsh/ssh will get current user by default + * plus we can set convenient overrides in ~/.ssh/config (explicit -l + * option breaks it for some) + */ + + if (SUP.user) { + argv[i++] = "-l"; + argv[i++] = SUP.user; + } + else + { + /* The rest of the code assumes it to be a valid username */ + SUP.user = vfs_get_local_username(); + } + argv[i++] = SUP.host; argv[i++] = "echo FISH:; /bin/sh"; argv[i++] = NULL; @@ -337,7 +352,7 @@ fish_open_archive (struct vfs_class *me, struct vfs_s_super *super, (void) archive_name; p = vfs_split_url (strchr (op, ':') + 1, &host, &user, &flags, - &password, 0, URL_NOSLASH); + &password, 0, URL_NOSLASH | URL_USE_ANONYMOUS); g_free (p); @@ -358,22 +373,28 @@ fish_archive_same (struct vfs_class *me, struct vfs_s_super *super, { char *host, *user; int flags; + int result; (void) me; (void) archive_name; (void) cookie; op = vfs_split_url (strchr (op, ':') + 1, &host, &user, &flags, 0, 0, - URL_NOSLASH); + URL_NOSLASH | URL_USE_ANONYMOUS); g_free (op); - flags = ((strcmp (host, SUP.host) == 0) - && (strcmp (user, SUP.user) == 0) && (flags == SUP.flags)); + if (user == NULL) + user = vfs_get_local_username(); + + result = ((strcmp (host, SUP.host) == 0) + && (strcmp (user, SUP.user) == 0) + && (flags == SUP.flags)); + g_free (host); g_free (user); - return flags; + return result; } static int diff --git a/vfs/ftpfs.c b/vfs/ftpfs.c index b533c066c..c4be6bf78 100644 --- a/vfs/ftpfs.c +++ b/vfs/ftpfs.c @@ -249,7 +249,7 @@ ftpfs_split_url(char *path, char **host, char **user, int *port, char **pass) char *p; p = vfs_split_url (path, host, user, port, pass, FTP_COMMAND_PORT, - URL_ALLOW_ANON); + URL_USE_ANONYMOUS); if (!*user) { /* Look up user and password in netrc */ @@ -656,7 +656,7 @@ ftpfs_get_proxy_host_and_port (const char *proxy, char **host, int *port) dir = vfs_split_url (proxy, host, &user, port, 0, FTP_COMMAND_PORT, - URL_ALLOW_ANON); + URL_USE_ANONYMOUS); g_free (user); g_free (dir); } diff --git a/vfs/utilvfs.c b/vfs/utilvfs.c index 7abc068ac..79bec13c7 100644 --- a/vfs/utilvfs.c +++ b/vfs/utilvfs.c @@ -43,8 +43,28 @@ #include "vfs.h" #include "utilvfs.h" -/* Extract the hostname and username from the path */ -/* path is in the form: [user@]hostname:port/remote-dir, e.g.: +/** Get current username + * + * @return g_malloc()ed string with the name of the currently logged in + * user ("anonymous" if uid is not registered in the system) + */ +char * +vfs_get_local_username(void) +{ + struct passwd * p_i; + + p_i = getpwuid (geteuid ()); + + return (p_i && p_i->pw_name) + ? g_strdup (p_i->pw_name) + : g_strdup ("anonymous"); /* Unknown UID, strange */ +} + +#ifdef USE_NETCODE + +/** Extract the hostname and username from the path + * + * Format of the path is [user@]hostname:port/remote-dir, e.g.: * * ftp://sunsite.unc.edu/pub/linux * ftp://miguel@sphinx.nuclecu.unam.mx/c/nc @@ -52,20 +72,25 @@ * ftp://joe@foo.edu:11321/private * ftp://joe:password@foo.se * - * Returns g_malloc()ed host, user and pass they are present. - * If the user is empty, e.g. ftp://@roxanne/private, and URL_ALLOW_ANON - * is not set, then the current login name is supplied. + * @param path is an input string to be parsed + * @param host is an outptun g_malloc()ed hostname + * @param user is an outptut g_malloc()ed username + * (NULL if not specified) + * @param port is an outptut integer port number + * @param pass is an outptut g_malloc()ed password + * @param default_port is an input default port + * @param flags are parsing modifier flags (@see VFS_URL_FLAGS) * - * Return value is a g_malloc()ed string with the pathname relative to the - * host. + * @return g_malloc()ed host, user and pass if they are present. + * If the user is empty, e.g. ftp://@roxanne/private, and URL_USE_ANONYMOUS + * is not set, then the current login name is supplied. + * Return value is a g_malloc()ed string with the pathname relative to the + * host. */ - -#ifdef USE_NETCODE char * vfs_split_url (const char *path, char **host, char **user, int *port, - char **pass, int default_port, int flags) + char **pass, int default_port, enum VFS_URL_FLAGS flags) { - struct passwd *passwd_info; char *dir, *colon, *inner_colon, *at, *rest; char *retval; char * const pcopy = g_strdup (path); @@ -112,16 +137,8 @@ vfs_split_url (const char *path, char **host, char **user, int *port, } else rest = pcopy; - if (!*user && !(flags & URL_ALLOW_ANON)) { - passwd_info = getpwuid (geteuid ()); - if (passwd_info && passwd_info->pw_name) - *user = g_strdup (passwd_info->pw_name); - else { - /* This is very unlikely to happen */ - *user = g_strdup ("anonymous"); - } - endpwent (); - } + if (!*user && !(flags & URL_USE_ANONYMOUS)) + *user = vfs_get_local_username(); /* Check if the host comes with a port spec, if so, chop it */ if ('[' == *rest) { diff --git a/vfs/utilvfs.h b/vfs/utilvfs.h index 60b7a1a60..5e5d646b2 100644 --- a/vfs/utilvfs.h +++ b/vfs/utilvfs.h @@ -13,21 +13,29 @@ #include "../src/global.h" -/* Flags for vfs_split_url() */ -#define URL_ALLOW_ANON 1 -#define URL_NOSLASH 2 +/** Bit flags for vfs_split_url() + * + * Modify parsing parameters according to flag meaning. + * @see vfs_split_url() + */ +enum VFS_URL_FLAGS { + URL_USE_ANONYMOUS = 1, /**< if set, empty *user will contain NULL instead of current */ + URL_NOSLASH = 2 /**< if set, 'proto://' part in url is not searched */ +}; int vfs_finduid (const char *name); int vfs_findgid (const char *name); char *vfs_split_url (const char *path, char **host, char **user, int *port, - char **pass, int default_port, int flags); + char **pass, int default_port, enum VFS_URL_FLAGS flags); int vfs_split_text (char *p); int vfs_mkstemps (char **pname, const char *prefix, const char *basename); void vfs_die (const char *msg); char *vfs_get_password (const char *msg); +char * vfs_get_local_username(void); + gboolean vfs_parse_filetype (const char *s, size_t *ret_skipped, mode_t *ret_type); gboolean vfs_parse_fileperms (const char *s, size_t *ret_skipped,