mirror of https://github.com/MidnightCommander/mc
Ticket #2361: VFS URI reimplementation
Created vfs_url_t structure ...and use it to parse and store network VFS options. vfs_s_super structure now has a special member for network VFS options. Signed-off-by: Andrew Borodin <aborodin@vmail.ru> Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
parent
fcfa76be3d
commit
42bc3171c3
|
@ -384,6 +384,9 @@ vfs_s_free_super (struct vfs_class *me, struct vfs_s_super *super)
|
|||
MEDATA->supers = g_list_remove (MEDATA->supers, super);
|
||||
|
||||
CALL (free_archive) (me, super);
|
||||
#ifdef ENABLE_VFS_NET
|
||||
vfs_url_free (super->url);
|
||||
#endif
|
||||
g_free (super->name);
|
||||
g_free (super);
|
||||
}
|
||||
|
|
|
@ -373,85 +373,82 @@ vfs_mkstemps (char **pname, const char *prefix, const char *param_basename)
|
|||
* ftp://joe:password@foo.se
|
||||
*
|
||||
* @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)
|
||||
* @param flags are parsing modifier flags (@see vfs_url_flags_t)
|
||||
*
|
||||
* @return g_malloc()ed host, user and pass if they are present.
|
||||
* @return g_malloc()ed url info.
|
||||
* 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
|
||||
* Return value is a g_malloc()ed structure with the pathname relative to the
|
||||
* host.
|
||||
*/
|
||||
|
||||
char *
|
||||
vfs_split_url (const char *path, char **host, char **user, int *port,
|
||||
char **pass, int default_port, enum VFS_URL_FLAGS flags)
|
||||
vfs_url_t *
|
||||
vfs_url_split (const char *path, int default_port, vfs_url_flags_t flags)
|
||||
{
|
||||
vfs_url_t *url;
|
||||
|
||||
char *pcopy;
|
||||
const char *pend;
|
||||
char *dir, *colon, *inner_colon, *at, *rest;
|
||||
char *retval;
|
||||
char *const pcopy = g_strdup (path);
|
||||
const char *pend = pcopy + strlen (pcopy);
|
||||
|
||||
if (pass)
|
||||
*pass = NULL;
|
||||
*port = default_port;
|
||||
*user = NULL;
|
||||
retval = NULL;
|
||||
url = g_new0 (vfs_url_t, 1);
|
||||
url->port = default_port;
|
||||
|
||||
pcopy = g_strdup (path);
|
||||
pend = pcopy + strlen (pcopy);
|
||||
dir = pcopy;
|
||||
if (!(flags & URL_NOSLASH))
|
||||
|
||||
if ((flags & URL_NOSLASH) == 0)
|
||||
{
|
||||
/* locate path component */
|
||||
while (*dir != PATH_SEP && *dir)
|
||||
while (*dir != PATH_SEP && *dir != '\0')
|
||||
dir++;
|
||||
if (*dir)
|
||||
{
|
||||
retval = g_strdup (dir);
|
||||
*dir = 0;
|
||||
}
|
||||
if (*dir == '\0')
|
||||
url->path = g_strdup (PATH_SEP_STR);
|
||||
else
|
||||
retval = g_strdup (PATH_SEP_STR);
|
||||
{
|
||||
url->path = g_strdup (dir);
|
||||
*dir = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* search for any possible user */
|
||||
at = strrchr (pcopy, '@');
|
||||
|
||||
/* We have a username */
|
||||
if (at)
|
||||
if (at == NULL)
|
||||
rest = pcopy;
|
||||
else
|
||||
{
|
||||
*at = 0;
|
||||
*at = '\0';
|
||||
inner_colon = strchr (pcopy, ':');
|
||||
if (inner_colon)
|
||||
if (inner_colon != NULL)
|
||||
{
|
||||
*inner_colon = 0;
|
||||
*inner_colon = '\0';
|
||||
inner_colon++;
|
||||
if (pass)
|
||||
*pass = g_strdup (inner_colon);
|
||||
url->password = g_strdup (inner_colon);
|
||||
}
|
||||
if (*pcopy != 0)
|
||||
*user = g_strdup (pcopy);
|
||||
|
||||
if (*pcopy != '\0')
|
||||
url->user = g_strdup (pcopy);
|
||||
|
||||
if (pend == at + 1)
|
||||
rest = at;
|
||||
else
|
||||
rest = at + 1;
|
||||
}
|
||||
else
|
||||
rest = pcopy;
|
||||
|
||||
if (!*user && !(flags & URL_USE_ANONYMOUS))
|
||||
*user = vfs_get_local_username ();
|
||||
if ((flags & URL_USE_ANONYMOUS) == 0)
|
||||
url->user = vfs_get_local_username ();
|
||||
|
||||
/* Check if the host comes with a port spec, if so, chop it */
|
||||
if ('[' == *rest)
|
||||
if (*rest != '[')
|
||||
colon = strchr (rest, ':');
|
||||
else
|
||||
{
|
||||
colon = strchr (++rest, ']');
|
||||
if (colon)
|
||||
if (colon != NULL)
|
||||
{
|
||||
colon[0] = '\0';
|
||||
colon[1] = '\0';
|
||||
|
@ -459,45 +456,52 @@ vfs_split_url (const char *path, char **host, char **user, int *port,
|
|||
}
|
||||
else
|
||||
{
|
||||
g_free (pcopy);
|
||||
g_free (retval);
|
||||
*host = NULL;
|
||||
*port = 0;
|
||||
vfs_url_free (url);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
colon = strchr (rest, ':');
|
||||
|
||||
if (colon)
|
||||
if (colon != NULL)
|
||||
{
|
||||
*colon = 0;
|
||||
if (sscanf (colon + 1, "%d", port) == 1)
|
||||
*colon = '\0';
|
||||
if (sscanf (colon + 1, "%d", &url->port) == 1)
|
||||
{
|
||||
if (*port <= 0 || *port >= 65536)
|
||||
*port = default_port;
|
||||
if (url->port <= 0 || url->port >= 65536)
|
||||
url->port = default_port;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*(++colon))
|
||||
while (*(++colon) != '\0')
|
||||
{
|
||||
switch (*colon)
|
||||
{
|
||||
case 'C':
|
||||
*port = 1;
|
||||
url->port = 1;
|
||||
break;
|
||||
case 'r':
|
||||
*port = 2;
|
||||
url->port = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (host)
|
||||
*host = g_strdup (rest);
|
||||
|
||||
g_free (pcopy);
|
||||
return retval;
|
||||
url->host = g_strdup (rest);
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
void
|
||||
vfs_url_free (vfs_url_t * url)
|
||||
{
|
||||
if (url != NULL)
|
||||
{
|
||||
g_free (url->user);
|
||||
g_free (url->password);
|
||||
g_free (url->host);
|
||||
g_free (url->path);
|
||||
g_free (url);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
|
|
@ -17,19 +17,29 @@
|
|||
|
||||
/*** enums ***************************************************************************************/
|
||||
|
||||
/** Bit flags for vfs_split_url()
|
||||
/** Bit flags for vfs_url_split()
|
||||
*
|
||||
* Modify parsing parameters according to flag meaning.
|
||||
* @see vfs_split_url()
|
||||
* @see vfs_url_split()
|
||||
*/
|
||||
enum VFS_URL_FLAGS
|
||||
typedef enum
|
||||
{
|
||||
URL_FLAGS_NONE = 0,
|
||||
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 */
|
||||
};
|
||||
} vfs_url_flags_t;
|
||||
|
||||
/*** structures declarations (and typedefs of structures)*****************************************/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *user;
|
||||
char *password;
|
||||
char *host;
|
||||
int port;
|
||||
char *path;
|
||||
} vfs_url_t;
|
||||
|
||||
/*** global variables defined in .c file *********************************************************/
|
||||
|
||||
/*** declarations of public functions ************************************************************/
|
||||
|
@ -37,8 +47,8 @@ enum VFS_URL_FLAGS
|
|||
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, enum VFS_URL_FLAGS flags);
|
||||
vfs_url_t *vfs_url_split (const char *path, int default_port, vfs_url_flags_t flags);
|
||||
void vfs_url_free (vfs_url_t * url);
|
||||
int vfs_split_text (char *p);
|
||||
|
||||
int vfs_mkstemps (char **pname, const char *prefix, const char *basename);
|
||||
|
|
|
@ -60,6 +60,10 @@ struct vfs_s_super
|
|||
int fd_usage; /* Number of open files */
|
||||
int ino_usage; /* Usage count of this superblock */
|
||||
int want_stale; /* If set, we do not flush cache properly */
|
||||
#ifdef ENABLE_VFS_NET
|
||||
vfs_url_t *url;
|
||||
#endif /* ENABLE_VFS_NET */
|
||||
|
||||
void *data; /* This is for filesystem-specific use */
|
||||
};
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
shell connections.
|
||||
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2007 Free Software Foundation, Inc.
|
||||
2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
|
||||
Written by: 1998 Pavel Machek
|
||||
Spaces fix: 2000 Michal Svec
|
||||
|
@ -134,11 +134,8 @@ int fish_directory_timeout = 900;
|
|||
|
||||
typedef struct
|
||||
{
|
||||
int sockr, sockw;
|
||||
char *cwdir;
|
||||
char *host, *user;
|
||||
char *password;
|
||||
int flags;
|
||||
int sockr;
|
||||
int sockw;
|
||||
char *scr_ls;
|
||||
char *scr_chmod;
|
||||
char *scr_exists;
|
||||
|
@ -253,7 +250,7 @@ fish_command (struct vfs_class *me, struct vfs_s_super *super, int wait_reply, c
|
|||
{
|
||||
va_list ap;
|
||||
char *str;
|
||||
int status;
|
||||
ssize_t status;
|
||||
FILE *logfile = MEDATA->logfile;
|
||||
|
||||
va_start (ap, fmt);
|
||||
|
@ -297,10 +294,6 @@ fish_free_archive (struct vfs_class *me, struct vfs_s_super *super)
|
|||
close (SUP->sockr);
|
||||
SUP->sockw = SUP->sockr = -1;
|
||||
}
|
||||
g_free (SUP->host);
|
||||
g_free (SUP->user);
|
||||
g_free (SUP->cwdir);
|
||||
g_free (SUP->password);
|
||||
g_free (SUP->scr_ls);
|
||||
g_free (SUP->scr_exists);
|
||||
g_free (SUP->scr_mkdir);
|
||||
|
@ -437,17 +430,17 @@ fish_open_archive_pipeopen (struct vfs_s_super *super)
|
|||
{
|
||||
char gbuf[10];
|
||||
const char *argv[10]; /* All of 10 is used now */
|
||||
const char *xsh = (SUP->flags == FISH_FLAG_RSH ? "rsh" : "ssh");
|
||||
const char *xsh = (super->url->port == FISH_FLAG_RSH ? "rsh" : "ssh");
|
||||
int i = 0;
|
||||
|
||||
argv[i++] = xsh;
|
||||
if (SUP->flags == FISH_FLAG_COMPRESSED)
|
||||
if (super->url->port == FISH_FLAG_COMPRESSED)
|
||||
argv[i++] = "-C";
|
||||
|
||||
if (SUP->flags > FISH_FLAG_RSH)
|
||||
if (super->url->port > FISH_FLAG_RSH)
|
||||
{
|
||||
argv[i++] = "-p";
|
||||
g_snprintf (gbuf, sizeof (gbuf), "%d", SUP->flags);
|
||||
g_snprintf (gbuf, sizeof (gbuf), "%d", super->url->port);
|
||||
argv[i++] = gbuf;
|
||||
}
|
||||
|
||||
|
@ -458,18 +451,18 @@ fish_open_archive_pipeopen (struct vfs_s_super *super)
|
|||
* option breaks it for some)
|
||||
*/
|
||||
|
||||
if (SUP->user)
|
||||
if (super->url->user != NULL)
|
||||
{
|
||||
argv[i++] = "-l";
|
||||
argv[i++] = SUP->user;
|
||||
argv[i++] = super->url->user;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The rest of the code assumes it to be a valid username */
|
||||
SUP->user = vfs_get_local_username ();
|
||||
super->url->user = vfs_get_local_username ();
|
||||
}
|
||||
|
||||
argv[i++] = SUP->host;
|
||||
argv[i++] = super->url->host;
|
||||
argv[i++] = "echo FISH:; /bin/sh";
|
||||
argv[i++] = NULL;
|
||||
|
||||
|
@ -488,7 +481,7 @@ fish_open_archive_talk (struct vfs_class *me, struct vfs_s_super *super)
|
|||
if (!vfs_s_get_line (me, SUP->sockr, answer, sizeof (answer), ':'))
|
||||
return FALSE;
|
||||
|
||||
if (strstr (answer, "assword"))
|
||||
if (strstr (answer, "assword") != NULL)
|
||||
{
|
||||
/* Currently, this does not work. ssh reads passwords from
|
||||
/dev/tty, not from stdin :-(. */
|
||||
|
@ -497,25 +490,27 @@ fish_open_archive_talk (struct vfs_class *me, struct vfs_s_super *super)
|
|||
|
||||
return FALSE;
|
||||
#if 0
|
||||
if (!SUP->password)
|
||||
if (super->url->password == NULL)
|
||||
{
|
||||
char *p, *op;
|
||||
p = g_strdup_printf (_("fish: Password is required for %s"), SUP->user);
|
||||
p = g_strdup_printf (_("fish: Password is required for %s"), super->url->user);
|
||||
op = vfs_get_password (p);
|
||||
g_free (p);
|
||||
if (op == NULL)
|
||||
return FALSE;
|
||||
SUP->password = op;
|
||||
super->url->password = op;
|
||||
|
||||
}
|
||||
|
||||
printf ("\n%s\n", _("fish: Sending password..."));
|
||||
|
||||
{
|
||||
size_t str_len;
|
||||
str_len = strlen (SUP->password);
|
||||
if ((write (SUP->sockw, SUP->password, str_len) != (ssize_t) str_len)
|
||||
|
||||
str_len = strlen (super->url->password);
|
||||
if ((write (SUP.sockw, super->url->password, str_len) != (ssize_t) str_len)
|
||||
|| (write (SUP->sockw, "\n", 1) != 1))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -569,12 +564,14 @@ fish_open_archive_int (struct vfs_class *me, struct vfs_s_super *super)
|
|||
SUP->scr_env = fish_set_env (SUP->host_flags);
|
||||
|
||||
vfs_print_message (_("fish: Setting up current directory..."));
|
||||
SUP->cwdir = fish_getcwd (me, super);
|
||||
vfs_print_message (_("fish: Connected, home %s."), SUP->cwdir);
|
||||
super->url->path = fish_getcwd (me, super);
|
||||
vfs_print_message (_("fish: Connected, home %s."), super->url->path);
|
||||
#if 0
|
||||
super->name = g_strconcat ("/#sh:", SUP->user, "@", SUP->host, "/", (char *) NULL);
|
||||
#endif
|
||||
super->name =
|
||||
g_strconcat ("/#sh:", super->url->user, "@", super->url->host, "/", (char *) NULL);
|
||||
#else
|
||||
super->name = g_strdup (PATH_SEP_STR);
|
||||
#endif
|
||||
|
||||
super->root = vfs_s_new_inode (me, super, vfs_s_default_stat (me, S_IFDIR | 0755));
|
||||
return 0;
|
||||
|
@ -586,41 +583,41 @@ static int
|
|||
fish_open_archive (struct vfs_class *me, struct vfs_s_super *super,
|
||||
const char *archive_name, char *op)
|
||||
{
|
||||
char *host, *user, *password, *p;
|
||||
int flags;
|
||||
|
||||
(void) archive_name;
|
||||
|
||||
super->data = g_new0 (fish_super_data_t, 1);
|
||||
p = vfs_split_url (strchr (op, ':') + 1, &host, &user, &flags,
|
||||
&password, 0, URL_NOSLASH | URL_USE_ANONYMOUS);
|
||||
super->url = vfs_url_split (strchr (op, ':') + 1, 0, URL_NOSLASH | URL_USE_ANONYMOUS);
|
||||
|
||||
g_free (p);
|
||||
|
||||
super->data = g_new0 (fish_super_data_t, 1);
|
||||
SUP->host = host;
|
||||
SUP->user = user;
|
||||
SUP->flags = flags;
|
||||
if (strncmp (op, "rsh:", 4) == 0)
|
||||
SUP->flags = FISH_FLAG_RSH;
|
||||
SUP->cwdir = NULL;
|
||||
if (password != NULL)
|
||||
SUP->password = password;
|
||||
SUP->scr_ls = fish_load_script_from_file (host, FISH_LS_FILE, FISH_LS_DEF_CONTENT);
|
||||
SUP->scr_exists = fish_load_script_from_file (host, FISH_EXISTS_FILE, FISH_EXISTS_DEF_CONTENT);
|
||||
SUP->scr_mkdir = fish_load_script_from_file (host, FISH_MKDIR_FILE, FISH_MKDIR_DEF_CONTENT);
|
||||
SUP->scr_unlink = fish_load_script_from_file (host, FISH_UNLINK_FILE, FISH_UNLINK_DEF_CONTENT);
|
||||
SUP->scr_chown = fish_load_script_from_file (host, FISH_CHOWN_FILE, FISH_CHOWN_DEF_CONTENT);
|
||||
SUP->scr_chmod = fish_load_script_from_file (host, FISH_CHMOD_FILE, FISH_CHMOD_DEF_CONTENT);
|
||||
SUP->scr_rmdir = fish_load_script_from_file (host, FISH_RMDIR_FILE, FISH_RMDIR_DEF_CONTENT);
|
||||
SUP->scr_ln = fish_load_script_from_file (host, FISH_LN_FILE, FISH_LN_DEF_CONTENT);
|
||||
SUP->scr_mv = fish_load_script_from_file (host, FISH_MV_FILE, FISH_MV_DEF_CONTENT);
|
||||
super->url->port = FISH_FLAG_RSH;
|
||||
|
||||
SUP->scr_ls = fish_load_script_from_file (super->url->host, FISH_LS_FILE, FISH_LS_DEF_CONTENT);
|
||||
SUP->scr_exists =
|
||||
fish_load_script_from_file (super->url->host, FISH_EXISTS_FILE, FISH_EXISTS_DEF_CONTENT);
|
||||
SUP->scr_mkdir =
|
||||
fish_load_script_from_file (super->url->host, FISH_MKDIR_FILE, FISH_MKDIR_DEF_CONTENT);
|
||||
SUP->scr_unlink =
|
||||
fish_load_script_from_file (super->url->host, FISH_UNLINK_FILE, FISH_UNLINK_DEF_CONTENT);
|
||||
SUP->scr_chown =
|
||||
fish_load_script_from_file (super->url->host, FISH_CHOWN_FILE, FISH_CHOWN_DEF_CONTENT);
|
||||
SUP->scr_chmod =
|
||||
fish_load_script_from_file (super->url->host, FISH_CHMOD_FILE, FISH_CHMOD_DEF_CONTENT);
|
||||
SUP->scr_rmdir =
|
||||
fish_load_script_from_file (super->url->host, FISH_RMDIR_FILE, FISH_RMDIR_DEF_CONTENT);
|
||||
SUP->scr_ln = fish_load_script_from_file (super->url->host, FISH_LN_FILE, FISH_LN_DEF_CONTENT);
|
||||
SUP->scr_mv = fish_load_script_from_file (super->url->host, FISH_MV_FILE, FISH_MV_DEF_CONTENT);
|
||||
SUP->scr_hardlink =
|
||||
fish_load_script_from_file (host, FISH_HARDLINK_FILE, FISH_HARDLINK_DEF_CONTENT);
|
||||
SUP->scr_get = fish_load_script_from_file (host, FISH_GET_FILE, FISH_GET_DEF_CONTENT);
|
||||
SUP->scr_send = fish_load_script_from_file (host, FISH_SEND_FILE, FISH_SEND_DEF_CONTENT);
|
||||
SUP->scr_append = fish_load_script_from_file (host, FISH_APPEND_FILE, FISH_APPEND_DEF_CONTENT);
|
||||
SUP->scr_info = fish_load_script_from_file (host, FISH_INFO_FILE, FISH_INFO_DEF_CONTENT);
|
||||
fish_load_script_from_file (super->url->host, FISH_HARDLINK_FILE,
|
||||
FISH_HARDLINK_DEF_CONTENT);
|
||||
SUP->scr_get =
|
||||
fish_load_script_from_file (super->url->host, FISH_GET_FILE, FISH_GET_DEF_CONTENT);
|
||||
SUP->scr_send =
|
||||
fish_load_script_from_file (super->url->host, FISH_SEND_FILE, FISH_SEND_DEF_CONTENT);
|
||||
SUP->scr_append =
|
||||
fish_load_script_from_file (super->url->host, FISH_APPEND_FILE, FISH_APPEND_DEF_CONTENT);
|
||||
SUP->scr_info =
|
||||
fish_load_script_from_file (super->url->host, FISH_INFO_FILE, FISH_INFO_DEF_CONTENT);
|
||||
|
||||
return fish_open_archive_int (me, super);
|
||||
}
|
||||
|
||||
|
@ -630,27 +627,23 @@ static int
|
|||
fish_archive_same (struct vfs_class *me, struct vfs_s_super *super,
|
||||
const char *archive_name, char *op, void *cookie)
|
||||
{
|
||||
char *host, *user;
|
||||
int flags;
|
||||
vfs_url_t *url;
|
||||
int result;
|
||||
|
||||
(void) me;
|
||||
(void) archive_name;
|
||||
(void) cookie;
|
||||
|
||||
op = vfs_split_url (strchr (op, ':') + 1, &host, &user, &flags, 0, 0,
|
||||
URL_NOSLASH | URL_USE_ANONYMOUS);
|
||||
url = vfs_url_split (strchr (op, ':') + 1, 0, URL_NOSLASH | URL_USE_ANONYMOUS);
|
||||
|
||||
g_free (op);
|
||||
if (url->user == NULL)
|
||||
url->user = vfs_get_local_username ();
|
||||
|
||||
if (user == NULL)
|
||||
user = vfs_get_local_username ();
|
||||
result = ((strcmp (url->host, super->url->host) == 0)
|
||||
&& (strcmp (url->user, super->url->user) == 0)
|
||||
&& (url->port == super->url->port)) ? 1 : 0;
|
||||
|
||||
result = ((strcmp (host, SUP->host) == 0)
|
||||
&& (strcmp (user, SUP->user) == 0) && (flags == SUP->flags));
|
||||
|
||||
g_free (host);
|
||||
g_free (user);
|
||||
vfs_url_free (url);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -843,19 +836,13 @@ fish_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path)
|
|||
reply_code = fish_decode_reply (buffer + 4, 0);
|
||||
if (reply_code == COMPLETE)
|
||||
{
|
||||
g_free (SUP->cwdir);
|
||||
SUP->cwdir = g_strdup (remote_path);
|
||||
g_free (super->url->path);
|
||||
super->url->path = g_strdup (remote_path);
|
||||
vfs_print_message (_("%s: done."), me->name);
|
||||
return 0;
|
||||
}
|
||||
else if (reply_code == ERROR)
|
||||
{
|
||||
me->verrno = EACCES;
|
||||
}
|
||||
else
|
||||
{
|
||||
me->verrno = E_REMOTE;
|
||||
}
|
||||
|
||||
me->verrno = reply_code == ERROR ? EACCES : E_REMOTE;
|
||||
|
||||
error:
|
||||
vfs_print_message (_("%s: failure"), me->name);
|
||||
|
@ -865,7 +852,7 @@ fish_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path)
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
fish_file_store (struct vfs_class *me, vfs_file_handler_t *fh, char *name, char *localname)
|
||||
fish_file_store (struct vfs_class *me, vfs_file_handler_t * fh, char *name, char *localname)
|
||||
{
|
||||
fish_fh_data_t *fish = (fish_fh_data_t *) fh->data;
|
||||
gchar *shell_commands = NULL;
|
||||
|
@ -878,7 +865,6 @@ fish_file_store (struct vfs_class *me, vfs_file_handler_t *fh, char *name, char
|
|||
char *quoted_name;
|
||||
|
||||
h = open (localname, O_RDONLY);
|
||||
|
||||
if (h == -1)
|
||||
ERRNOR (EIO, -1);
|
||||
if (fstat (h, &s) < 0)
|
||||
|
@ -925,6 +911,7 @@ fish_file_store (struct vfs_class *me, vfs_file_handler_t *fh, char *name, char
|
|||
shell_commands =
|
||||
g_strconcat (SUP->scr_env, "FISH_FILENAME=%s FISH_FILESIZE=%" PRIuMAX ";\n",
|
||||
SUP->scr_append, (char *) NULL);
|
||||
|
||||
n = fish_command (me, super, WAIT_REPLY, shell_commands, quoted_name,
|
||||
(uintmax_t) s.st_size);
|
||||
g_free (shell_commands);
|
||||
|
@ -978,9 +965,11 @@ fish_file_store (struct vfs_class *me, vfs_file_handler_t *fh, char *name, char
|
|||
}
|
||||
close (h);
|
||||
g_free (quoted_name);
|
||||
|
||||
if ((fish_get_reply (me, SUP->sockr, NULL, 0) != COMPLETE) || was_error)
|
||||
ERRNOR (E_REMOTE, -1);
|
||||
return 0;
|
||||
|
||||
error_return:
|
||||
close (h);
|
||||
fish_get_reply (me, SUP->sockr, NULL, 0);
|
||||
|
@ -991,7 +980,7 @@ fish_file_store (struct vfs_class *me, vfs_file_handler_t *fh, char *name, char
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
fish_linear_start (struct vfs_class *me, vfs_file_handler_t *fh, off_t offset)
|
||||
fish_linear_start (struct vfs_class *me, vfs_file_handler_t * fh, off_t offset)
|
||||
{
|
||||
fish_fh_data_t *fish;
|
||||
gchar *shell_commands = NULL;
|
||||
|
@ -1042,7 +1031,7 @@ fish_linear_start (struct vfs_class *me, vfs_file_handler_t *fh, off_t offset)
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
fish_linear_abort (struct vfs_class *me, vfs_file_handler_t *fh)
|
||||
fish_linear_abort (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
{
|
||||
fish_fh_data_t *fish = (fish_fh_data_t *) fh->data;
|
||||
struct vfs_s_super *super = FH_SUPER;
|
||||
|
@ -1050,6 +1039,7 @@ fish_linear_abort (struct vfs_class *me, vfs_file_handler_t *fh)
|
|||
int n;
|
||||
|
||||
vfs_print_message (_("Aborting transfer..."));
|
||||
|
||||
do
|
||||
{
|
||||
n = MIN (sizeof (buffer), (size_t) (fish->total - fish->got));
|
||||
|
@ -1072,7 +1062,7 @@ fish_linear_abort (struct vfs_class *me, vfs_file_handler_t *fh)
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
fish_linear_read (struct vfs_class *me, vfs_file_handler_t *fh, void *buf, size_t len)
|
||||
fish_linear_read (struct vfs_class *me, vfs_file_handler_t * fh, void *buf, size_t len)
|
||||
{
|
||||
fish_fh_data_t *fish = (fish_fh_data_t *) fh->data;
|
||||
struct vfs_s_super *super = FH_SUPER;
|
||||
|
@ -1101,7 +1091,7 @@ fish_linear_read (struct vfs_class *me, vfs_file_handler_t *fh, void *buf, size_
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
fish_linear_close (struct vfs_class *me, vfs_file_handler_t *fh)
|
||||
fish_linear_close (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
{
|
||||
fish_fh_data_t *fish = (fish_fh_data_t *) fh->data;
|
||||
|
||||
|
@ -1304,6 +1294,7 @@ fish_chown (struct vfs_class *me, const char *path, uid_t owner, gid_t group)
|
|||
|
||||
sowner = pw->pw_name;
|
||||
sgroup = gr->gr_name;
|
||||
|
||||
{
|
||||
gchar *shell_commands = NULL;
|
||||
|
||||
|
@ -1357,7 +1348,6 @@ fish_exists (struct vfs_class *me, const char *path)
|
|||
return (fish_send_command (me, super, buf, OPT_FLUSH) == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
|
@ -1382,9 +1372,7 @@ fish_mkdir (struct vfs_class *me, const char *path, mode_t mode)
|
|||
return ret_code;
|
||||
|
||||
if (!fish_exists (me, path))
|
||||
{
|
||||
ERRNOR (EACCES, -1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1408,7 +1396,7 @@ fish_rmdir (struct vfs_class *me, const char *path)
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
fish_fh_open (struct vfs_class *me, vfs_file_handler_t *fh, int flags, mode_t mode)
|
||||
fish_fh_open (struct vfs_class *me, vfs_file_handler_t * fh, int flags, mode_t mode)
|
||||
{
|
||||
fish_fh_data_t *fish;
|
||||
|
||||
|
@ -1445,7 +1433,7 @@ fish_fh_open (struct vfs_class *me, vfs_file_handler_t *fh, int flags, mode_t mo
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
fish_fh_close (struct vfs_class *me, vfs_file_handler_t *fh)
|
||||
fish_fh_close (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
{
|
||||
(void) me;
|
||||
|
||||
|
@ -1468,7 +1456,7 @@ fish_fill_names (struct vfs_class *me, fill_names_f func)
|
|||
char gbuf[10];
|
||||
const char *flags = "";
|
||||
|
||||
switch (SUP->flags)
|
||||
switch (super->url->port)
|
||||
{
|
||||
case FISH_FLAG_RSH:
|
||||
flags = ":r";
|
||||
|
@ -1477,16 +1465,16 @@ fish_fill_names (struct vfs_class *me, fill_names_f func)
|
|||
flags = ":C";
|
||||
break;
|
||||
default:
|
||||
if (SUP->flags > FISH_FLAG_RSH)
|
||||
if (super->url->port > FISH_FLAG_RSH)
|
||||
{
|
||||
g_snprintf (gbuf, sizeof (gbuf), ":%d", SUP->flags);
|
||||
g_snprintf (gbuf, sizeof (gbuf), ":%d", super->url->port);
|
||||
flags = gbuf;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
name =
|
||||
g_strconcat ("/#sh:", SUP->user, "@", SUP->host, flags, "/", SUP->cwdir, (char *) NULL);
|
||||
name = g_strconcat ("/#sh:", super->url->user, "@", super->url->host, flags, "/",
|
||||
super->url->path, (char *) NULL);
|
||||
func (name);
|
||||
g_free (name);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Virtual File System: FTP file system.
|
||||
Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||
2006, 2007 Free Software Foundation, Inc.
|
||||
2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
|
||||
Written by:
|
||||
1995 Ching Hui
|
||||
|
@ -9,6 +9,8 @@
|
|||
1997 Norbert Warmuth
|
||||
1998 Pavel Machek
|
||||
2010 Yury V. Zaytsev
|
||||
2010 Slava Zanko
|
||||
2010 Andrew Borodin
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License
|
||||
|
@ -197,11 +199,6 @@ typedef enum
|
|||
typedef struct
|
||||
{
|
||||
int sock;
|
||||
char *cwdir;
|
||||
char *host;
|
||||
char *user;
|
||||
char *password;
|
||||
int port;
|
||||
|
||||
char *proxy; /* proxy server, NULL if no proxy */
|
||||
int failed_on_login; /* used to pass the failure reason to upper levels */
|
||||
|
@ -322,43 +319,42 @@ ftpfs_translate_path (struct vfs_class *me, struct vfs_s_super *super, const cha
|
|||
* ftp://joe@foo.edu:11321/private
|
||||
* If the user is empty, e.g. ftp://@roxanne/private, then your login name
|
||||
* is supplied.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ftpfs_split_url (char *path, char **host, char **user, int *port, char **pass)
|
||||
static vfs_url_t *
|
||||
ftpfs_split_url (const char *path)
|
||||
{
|
||||
char *p;
|
||||
vfs_url_t *p;
|
||||
|
||||
p = vfs_split_url (path, host, user, port, pass, FTP_COMMAND_PORT, URL_USE_ANONYMOUS);
|
||||
p = vfs_url_split (path, FTP_COMMAND_PORT, URL_USE_ANONYMOUS);
|
||||
|
||||
if (!*user)
|
||||
if (p->user != NULL)
|
||||
{
|
||||
/* Look up user and password in netrc */
|
||||
if (ftpfs_use_netrc)
|
||||
ftpfs_netrc_lookup (*host, user, pass);
|
||||
if (!*user)
|
||||
*user = g_strdup ("anonymous");
|
||||
ftpfs_netrc_lookup (p->host, &p->user, &p->password);
|
||||
}
|
||||
if (p->user == NULL)
|
||||
p->user = g_strdup ("anonymous");
|
||||
|
||||
/* Look up password in netrc for known user */
|
||||
if (ftpfs_use_netrc && *user && pass && !*pass)
|
||||
if (ftpfs_use_netrc && p->user != NULL && p->password != NULL)
|
||||
{
|
||||
char *new_user;
|
||||
char *new_user = NULL;
|
||||
|
||||
ftpfs_netrc_lookup (*host, &new_user, pass);
|
||||
ftpfs_netrc_lookup (p->host, &new_user, &p->password);
|
||||
|
||||
/* If user is different, remove password */
|
||||
if (new_user && strcmp (*user, new_user))
|
||||
if (new_user != NULL && strcmp (p->user, new_user) != 0)
|
||||
{
|
||||
g_free (*pass);
|
||||
*pass = NULL;
|
||||
g_free (p->password);
|
||||
p->password = NULL;
|
||||
}
|
||||
|
||||
g_free (new_user);
|
||||
}
|
||||
|
||||
g_free (p);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -414,23 +410,30 @@ ftpfs_get_reply (struct vfs_class *me, int sock, char *string_buf, int string_le
|
|||
static int
|
||||
ftpfs_reconnect (struct vfs_class *me, struct vfs_s_super *super)
|
||||
{
|
||||
int sock = ftpfs_open_socket (me, super);
|
||||
int sock;
|
||||
|
||||
sock = ftpfs_open_socket (me, super);
|
||||
if (sock != -1)
|
||||
{
|
||||
char *cwdir = SUP->cwdir;
|
||||
char *cwdir = super->url->path;
|
||||
|
||||
close (SUP->sock);
|
||||
SUP->sock = sock;
|
||||
SUP->cwdir = NULL;
|
||||
if (ftpfs_login_server (me, super, SUP->password))
|
||||
super->url->path = NULL;
|
||||
|
||||
|
||||
if (ftpfs_login_server (me, super, super->url->password) != 0)
|
||||
{
|
||||
if (!cwdir)
|
||||
if (cwdir == NULL)
|
||||
return 1;
|
||||
sock = ftpfs_chdir_internal (me, super, cwdir);
|
||||
g_free (cwdir);
|
||||
return sock == COMPLETE;
|
||||
return sock == COMPLETE ? 1 : 0;
|
||||
}
|
||||
SUP->cwdir = cwdir;
|
||||
|
||||
super->url->path = cwdir;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -532,14 +535,10 @@ ftpfs_free_archive (struct vfs_class *me, struct vfs_s_super *super)
|
|||
{
|
||||
if (SUP->sock != -1)
|
||||
{
|
||||
vfs_print_message (_("ftpfs: Disconnecting from %s"), SUP->host);
|
||||
vfs_print_message (_("ftpfs: Disconnecting from %s"), super->url->host);
|
||||
ftpfs_command (me, super, NONE, "QUIT");
|
||||
close (SUP->sock);
|
||||
}
|
||||
g_free (SUP->host);
|
||||
g_free (SUP->user);
|
||||
g_free (SUP->cwdir);
|
||||
g_free (SUP->password);
|
||||
g_free (super->data);
|
||||
super->data = NULL;
|
||||
}
|
||||
|
@ -572,13 +571,13 @@ ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, const char
|
|||
|
||||
SUP->isbinary = TYPE_UNKNOWN;
|
||||
|
||||
if (SUP->password != NULL) /* explicit password */
|
||||
op = g_strdup (SUP->password);
|
||||
if (super->url->password != NULL) /* explicit password */
|
||||
op = g_strdup (super->url->password);
|
||||
else if (netrcpass != NULL) /* password from netrc */
|
||||
op = g_strdup (netrcpass);
|
||||
else if (strcmp (SUP->user, "anonymous") == 0 || strcmp (SUP->user, "ftp") == 0)
|
||||
else if (strcmp (super->url->user, "anonymous") == 0 || strcmp (super->url->user, "ftp") == 0)
|
||||
{
|
||||
if (!ftpfs_anonymous_passwd) /* default anonymous password */
|
||||
if (ftpfs_anonymous_passwd == NULL) /* default anonymous password */
|
||||
ftpfs_init_passwd ();
|
||||
op = g_strdup (ftpfs_anonymous_passwd);
|
||||
anon = 1;
|
||||
|
@ -587,12 +586,12 @@ ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, const char
|
|||
{ /* ask user */
|
||||
char *p;
|
||||
|
||||
p = g_strdup_printf (_("FTP: Password required for %s"), SUP->user);
|
||||
p = g_strdup_printf (_("FTP: Password required for %s"), super->url->user);
|
||||
op = vfs_get_password (p);
|
||||
g_free (p);
|
||||
if (op == NULL)
|
||||
ERRNOR (EPERM, 0);
|
||||
SUP->password = g_strdup (op);
|
||||
super->url->password = g_strdup (op);
|
||||
}
|
||||
|
||||
if (!anon || MEDATA->logfile)
|
||||
|
@ -605,13 +604,12 @@ ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, const char
|
|||
|
||||
/* Proxy server accepts: username@host-we-want-to-connect */
|
||||
if (SUP->proxy)
|
||||
{
|
||||
name =
|
||||
g_strconcat (SUP->user, "@",
|
||||
SUP->host[0] == '!' ? SUP->host + 1 : SUP->host, (char *) NULL);
|
||||
}
|
||||
g_strconcat (super->url->user, "@",
|
||||
super->url->host[0] == '!' ? super->url->host + 1 : super->url->host,
|
||||
(char *) NULL);
|
||||
else
|
||||
name = g_strdup (SUP->user);
|
||||
name = g_strdup (super->url->user);
|
||||
|
||||
if (ftpfs_get_reply (me, SUP->sock, reply_string, sizeof (reply_string) - 1) == COMPLETE)
|
||||
{
|
||||
|
@ -638,7 +636,7 @@ ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, const char
|
|||
{
|
||||
char *p;
|
||||
|
||||
p = g_strdup_printf (_("FTP: Account required for user %s"), SUP->user);
|
||||
p = g_strdup_printf (_("FTP: Account required for user %s"), super->url->user);
|
||||
op = input_dialog (p, _("Account:"), MC_HISTORY_FTPFS_ACCOUNT, "");
|
||||
g_free (p);
|
||||
if (op == NULL)
|
||||
|
@ -659,14 +657,15 @@ ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, const char
|
|||
|
||||
default:
|
||||
SUP->failed_on_login = 1;
|
||||
if (SUP->password)
|
||||
wipe_password (SUP->password);
|
||||
SUP->password = 0;
|
||||
wipe_password (super->url->password);
|
||||
super->url->password = NULL;
|
||||
|
||||
goto login_fail;
|
||||
}
|
||||
}
|
||||
message (D_ERROR, MSG_ERROR, _("ftpfs: Login incorrect for user %s "), SUP->user);
|
||||
|
||||
message (D_ERROR, MSG_ERROR, _("ftpfs: Login incorrect for user %s "), super->url->user);
|
||||
|
||||
login_fail:
|
||||
wipe_password (pass);
|
||||
g_free (name);
|
||||
|
@ -764,11 +763,12 @@ ftpfs_check_proxy (const char *host)
|
|||
static void
|
||||
ftpfs_get_proxy_host_and_port (const char *proxy, char **host, int *port)
|
||||
{
|
||||
char *user, *dir;
|
||||
vfs_url_t *url;
|
||||
|
||||
dir = vfs_split_url (proxy, host, &user, port, 0, FTP_COMMAND_PORT, URL_USE_ANONYMOUS);
|
||||
g_free (user);
|
||||
g_free (dir);
|
||||
url = vfs_url_split (proxy, FTP_COMMAND_PORT, URL_USE_ANONYMOUS);
|
||||
*host = g_strdup (url->host);
|
||||
*port = url->port;
|
||||
vfs_url_free (url);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -779,16 +779,16 @@ ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super)
|
|||
struct addrinfo hints, *res, *curr_res;
|
||||
int my_socket = 0;
|
||||
char *host = NULL;
|
||||
char *port = NULL;
|
||||
char port[8];
|
||||
int tmp_port;
|
||||
int e;
|
||||
|
||||
(void) me;
|
||||
|
||||
/* Use a proxy host? */
|
||||
host = g_strdup (SUP->host);
|
||||
host = g_strdup (super->url->host);
|
||||
|
||||
if (!host || !*host)
|
||||
if (host == NULL || *host == '\0')
|
||||
{
|
||||
vfs_print_message (_("ftpfs: Invalid host name."));
|
||||
ftpfs_errno = EINVAL;
|
||||
|
@ -797,15 +797,13 @@ ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super)
|
|||
}
|
||||
|
||||
/* Hosts to connect to that start with a ! should use proxy */
|
||||
tmp_port = SUP->port;
|
||||
tmp_port = super->url->port;
|
||||
|
||||
if (SUP->proxy)
|
||||
{
|
||||
if (SUP->proxy != NULL)
|
||||
ftpfs_get_proxy_host_and_port (ftpfs_proxy_host, &host, &tmp_port);
|
||||
}
|
||||
|
||||
port = g_strdup_printf ("%hu", (unsigned short) tmp_port);
|
||||
if (port == NULL)
|
||||
g_snprintf (port, sizeof (port), "%hu", (unsigned short) tmp_port);
|
||||
if (port[0] == '\0')
|
||||
{
|
||||
g_free (host);
|
||||
ftpfs_errno = errno;
|
||||
|
@ -836,8 +834,7 @@ ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super)
|
|||
}
|
||||
#endif
|
||||
|
||||
g_free (port);
|
||||
port = NULL;
|
||||
*port = '\0';
|
||||
|
||||
if (e != 0)
|
||||
{
|
||||
|
@ -850,12 +847,10 @@ ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super)
|
|||
|
||||
for (curr_res = res; curr_res != NULL; curr_res = curr_res->ai_next)
|
||||
{
|
||||
|
||||
my_socket = socket (curr_res->ai_family, curr_res->ai_socktype, curr_res->ai_protocol);
|
||||
|
||||
if (my_socket < 0)
|
||||
{
|
||||
|
||||
if (curr_res->ai_next != NULL)
|
||||
continue;
|
||||
|
||||
|
@ -878,18 +873,12 @@ ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super)
|
|||
close (my_socket);
|
||||
|
||||
if (errno == EINTR && tty_got_interrupt ())
|
||||
{
|
||||
vfs_print_message (_("ftpfs: connection interrupted by user"));
|
||||
}
|
||||
else if (res->ai_next == NULL)
|
||||
{
|
||||
vfs_print_message (_("ftpfs: connection to server failed: %s"),
|
||||
unix_error_string (errno));
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
freeaddrinfo (res);
|
||||
tty_disable_interrupt_key ();
|
||||
|
@ -906,13 +895,13 @@ ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super)
|
|||
static int
|
||||
ftpfs_open_archive_int (struct vfs_class *me, struct vfs_s_super *super)
|
||||
{
|
||||
int retry_seconds, count_down;
|
||||
int retry_seconds = 0;
|
||||
int count_down;
|
||||
|
||||
/* We do not want to use the passive if we are using proxies */
|
||||
if (SUP->proxy)
|
||||
SUP->use_passive_connection = ftpfs_use_passive_connections_over_proxy;
|
||||
|
||||
retry_seconds = 0;
|
||||
do
|
||||
{
|
||||
SUP->failed_on_login = 0;
|
||||
|
@ -921,29 +910,26 @@ ftpfs_open_archive_int (struct vfs_class *me, struct vfs_s_super *super)
|
|||
if (SUP->sock == -1)
|
||||
return -1;
|
||||
|
||||
if (ftpfs_login_server (me, super, NULL))
|
||||
if (ftpfs_login_server (me, super, NULL) != 0)
|
||||
{
|
||||
/* Logged in, no need to retry the connection */
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SUP->failed_on_login)
|
||||
{
|
||||
/* Close only the socket descriptor */
|
||||
close (SUP->sock);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!SUP->failed_on_login)
|
||||
return -1;
|
||||
}
|
||||
if (ftpfs_retry_seconds)
|
||||
|
||||
/* Close only the socket descriptor */
|
||||
close (SUP->sock);
|
||||
|
||||
if (ftpfs_retry_seconds != 0)
|
||||
{
|
||||
retry_seconds = ftpfs_retry_seconds;
|
||||
tty_enable_interrupt_key ();
|
||||
for (count_down = retry_seconds; count_down; count_down--)
|
||||
{
|
||||
vfs_print_message (_("Waiting to retry... %d (Control-C to cancel)"),
|
||||
vfs_print_message (_("Waiting to retry... %d (Control-G to cancel)"),
|
||||
count_down);
|
||||
sleep (1);
|
||||
if (tty_got_interrupt ())
|
||||
|
@ -957,11 +943,12 @@ ftpfs_open_archive_int (struct vfs_class *me, struct vfs_s_super *super)
|
|||
}
|
||||
}
|
||||
}
|
||||
while (retry_seconds);
|
||||
while (retry_seconds != 0);
|
||||
|
||||
super->url->path = ftpfs_get_current_directory (me, super);
|
||||
if (super->url->path == NULL)
|
||||
super->url->path = g_strdup (PATH_SEP_STR);
|
||||
|
||||
SUP->cwdir = ftpfs_get_current_directory (me, super);
|
||||
if (!SUP->cwdir)
|
||||
SUP->cwdir = g_strdup (PATH_SEP_STR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -971,22 +958,14 @@ static int
|
|||
ftpfs_open_archive (struct vfs_class *me, struct vfs_s_super *super,
|
||||
const char *archive_name, char *op)
|
||||
{
|
||||
char *host, *user, *password;
|
||||
int port;
|
||||
|
||||
(void) archive_name;
|
||||
|
||||
ftpfs_split_url (strchr (op, ':') + 1, &host, &user, &port, &password);
|
||||
|
||||
super->data = g_new0 (ftp_super_data_t, 1);
|
||||
SUP->host = host;
|
||||
SUP->user = user;
|
||||
SUP->port = port;
|
||||
SUP->cwdir = NULL;
|
||||
SUP->proxy = 0;
|
||||
if (ftpfs_check_proxy (host))
|
||||
|
||||
super->url = ftpfs_split_url (strchr (op, ':') + 1);
|
||||
SUP->proxy = NULL;
|
||||
if (ftpfs_check_proxy (super->url->host))
|
||||
SUP->proxy = ftpfs_proxy_host;
|
||||
SUP->password = password;
|
||||
SUP->use_passive_connection = ftpfs_use_passive_connections;
|
||||
SUP->strict = ftpfs_use_unix_list_options ? RFC_AUTODETECT : RFC_STRICT;
|
||||
SUP->isbinary = TYPE_UNKNOWN;
|
||||
|
@ -1003,22 +982,21 @@ static int
|
|||
ftpfs_archive_same (struct vfs_class *me, struct vfs_s_super *super,
|
||||
const char *archive_name, char *op, void *cookie)
|
||||
{
|
||||
char *host, *user;
|
||||
int port;
|
||||
vfs_url_t *url;
|
||||
int result;
|
||||
|
||||
(void) me;
|
||||
(void) archive_name;
|
||||
(void) cookie;
|
||||
|
||||
ftpfs_split_url (strchr (op, ':') + 1, &host, &user, &port, 0);
|
||||
url = ftpfs_split_url (strchr (op, ':') + 1);
|
||||
|
||||
port = ((strcmp (host, SUP->host) == 0) && (strcmp (user, SUP->user) == 0)
|
||||
&& (port == SUP->port));
|
||||
result = ((strcmp (url->host, super->url->host) == 0)
|
||||
&& (strcmp (url->user, super->url->user) == 0)
|
||||
&& (url->port == super->url->port)) ? 1 : 0;
|
||||
|
||||
g_free (host);
|
||||
g_free (user);
|
||||
|
||||
return port;
|
||||
vfs_url_free (url);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -1149,10 +1127,7 @@ ftpfs_setup_passive_epsv (struct vfs_class *me, struct vfs_s_super *super,
|
|||
break;
|
||||
}
|
||||
|
||||
if (connect (my_socket, (struct sockaddr *) sa, *salen) < 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return (connect (my_socket, (struct sockaddr *) sa, *salen) < 0) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -1292,8 +1267,8 @@ ftpfs_init_data_socket (struct vfs_class *me, struct vfs_s_super *super,
|
|||
vfs_print_message (_("ftpfs: could not create socket: %s"), unix_error_string (errno));
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
return result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -1315,8 +1290,8 @@ ftpfs_initconn (struct vfs_class *me, struct vfs_s_super *super)
|
|||
if (SUP->use_passive_connection)
|
||||
{
|
||||
int data_sock;
|
||||
data_sock = ftpfs_init_data_socket (me, super, &data_addr, &data_addrlen);
|
||||
|
||||
data_sock = ftpfs_init_data_socket (me, super, &data_addr, &data_addrlen);
|
||||
if (data_sock < 0)
|
||||
return -1;
|
||||
|
||||
|
@ -1333,24 +1308,22 @@ ftpfs_initconn (struct vfs_class *me, struct vfs_s_super *super)
|
|||
if (!SUP->use_passive_connection)
|
||||
{
|
||||
int data_sock;
|
||||
data_sock = ftpfs_init_data_socket (me, super, &data_addr, &data_addrlen);
|
||||
|
||||
data_sock = ftpfs_init_data_socket (me, super, &data_addr, &data_addrlen);
|
||||
if (data_sock < 0)
|
||||
return -1;
|
||||
|
||||
if ((bind (data_sock, (struct sockaddr *) &data_addr, data_addrlen) == 0) &&
|
||||
(getsockname (data_sock, (struct sockaddr *) &data_addr, &data_addrlen) == 0) &&
|
||||
(listen (data_sock, 1) == 0))
|
||||
{
|
||||
if (ftpfs_setup_active (me, super, data_addr, data_addrlen))
|
||||
return data_sock;
|
||||
}
|
||||
(listen (data_sock, 1) == 0) &&
|
||||
(ftpfs_setup_active (me, super, data_addr, data_addrlen) != 0))
|
||||
return data_sock;
|
||||
|
||||
close (data_sock);
|
||||
}
|
||||
|
||||
/* Restore the initial value of use_passive_connection (for subsequent retries) */
|
||||
SUP->use_passive_connection = SUP->proxy ? ftpfs_use_passive_connections_over_proxy :
|
||||
SUP->use_passive_connection = SUP->proxy != NULL ? ftpfs_use_passive_connections_over_proxy :
|
||||
ftpfs_use_passive_connections;
|
||||
|
||||
ftpfs_errno = EIO;
|
||||
|
@ -1413,7 +1386,7 @@ ftpfs_open_data_connection (struct vfs_class *me, struct vfs_s_super *super, con
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
ftpfs_linear_abort (struct vfs_class *me, vfs_file_handler_t *fh)
|
||||
ftpfs_linear_abort (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
{
|
||||
struct vfs_s_super *super = FH_SUPER;
|
||||
static unsigned char const ipbuf[3] = { IAC, IP, IAC };
|
||||
|
@ -1786,7 +1759,7 @@ ftpfs_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
ftpfs_file_store (struct vfs_class *me, vfs_file_handler_t *fh, char *name, char *localname)
|
||||
ftpfs_file_store (struct vfs_class *me, vfs_file_handler_t * fh, char *name, char *localname)
|
||||
{
|
||||
int h, sock, n_read, n_written;
|
||||
off_t n_stored;
|
||||
|
@ -1877,7 +1850,7 @@ ftpfs_file_store (struct vfs_class *me, vfs_file_handler_t *fh, char *name, char
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
ftpfs_linear_start (struct vfs_class *me, vfs_file_handler_t *fh, off_t offset)
|
||||
ftpfs_linear_start (struct vfs_class *me, vfs_file_handler_t * fh, off_t offset)
|
||||
{
|
||||
char *name;
|
||||
|
||||
|
@ -1900,7 +1873,7 @@ ftpfs_linear_start (struct vfs_class *me, vfs_file_handler_t *fh, off_t offset)
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
ftpfs_linear_read (struct vfs_class *me, vfs_file_handler_t *fh, void *buf, size_t len)
|
||||
ftpfs_linear_read (struct vfs_class *me, vfs_file_handler_t * fh, void *buf, size_t len)
|
||||
{
|
||||
ssize_t n;
|
||||
struct vfs_s_super *super = FH_SUPER;
|
||||
|
@ -1930,7 +1903,7 @@ ftpfs_linear_read (struct vfs_class *me, vfs_file_handler_t *fh, void *buf, size
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
ftpfs_linear_close (struct vfs_class *me, vfs_file_handler_t *fh)
|
||||
ftpfs_linear_close (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
{
|
||||
if (FH_SOCK != -1)
|
||||
ftpfs_linear_abort (me, fh);
|
||||
|
@ -2048,11 +2021,9 @@ ftpfs_is_same_dir (struct vfs_class *me, struct vfs_s_super *super, const char *
|
|||
{
|
||||
(void) me;
|
||||
|
||||
if (!SUP->cwdir)
|
||||
return 0;
|
||||
if (strcmp (path, SUP->cwdir) == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
if (super->url->path == NULL)
|
||||
return FALSE;
|
||||
return (strcmp (path, super->url->path) == 0);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -2071,13 +2042,11 @@ ftpfs_chdir_internal (struct vfs_class *me, struct vfs_s_super *super, const cha
|
|||
g_free (p);
|
||||
|
||||
if (r != COMPLETE)
|
||||
{
|
||||
ftpfs_errno = EIO;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free (SUP->cwdir);
|
||||
SUP->cwdir = g_strdup (remote_path);
|
||||
g_free (super->url->path);
|
||||
super->url->path = g_strdup (remote_path);
|
||||
SUP->cwd_deferred = 0;
|
||||
}
|
||||
return r;
|
||||
|
@ -2113,7 +2082,7 @@ ftpfs_rmdir (struct vfs_class *me, const char *path)
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
ftpfs_fh_open (struct vfs_class *me, vfs_file_handler_t *fh, int flags, mode_t mode)
|
||||
ftpfs_fh_open (struct vfs_class *me, vfs_file_handler_t * fh, int flags, mode_t mode)
|
||||
{
|
||||
ftp_fh_data_t *ftp;
|
||||
|
||||
|
@ -2187,7 +2156,7 @@ ftpfs_fh_open (struct vfs_class *me, vfs_file_handler_t *fh, int flags, mode_t m
|
|||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static int
|
||||
ftpfs_fh_close (struct vfs_class *me, vfs_file_handler_t *fh)
|
||||
ftpfs_fh_close (struct vfs_class *me, vfs_file_handler_t * fh)
|
||||
{
|
||||
if (fh->handle != -1 && !fh->ino->localname)
|
||||
{
|
||||
|
@ -2235,7 +2204,8 @@ ftpfs_fill_names (struct vfs_class *me, fill_names_f func)
|
|||
const struct vfs_s_super *super = (const struct vfs_s_super *) iter->data;
|
||||
char *name;
|
||||
|
||||
name = g_strconcat ("/#ftp:", SUP->user, "@", SUP->host, "/", SUP->cwdir, (char *) NULL);
|
||||
name = g_strconcat ("/#ftp:", super->url->user, "@", super->url->host, "/",
|
||||
super->url->path, (char *) NULL);
|
||||
func (name);
|
||||
g_free (name);
|
||||
}
|
||||
|
@ -2252,7 +2222,6 @@ ftpfs_netrc_next (void)
|
|||
"login", "password", "passwd", "account", "macdef", NULL
|
||||
};
|
||||
|
||||
|
||||
while (1)
|
||||
{
|
||||
netrcp = skip_separators (netrcp);
|
||||
|
@ -2286,15 +2255,10 @@ ftpfs_netrc_next (void)
|
|||
if (!*buffer)
|
||||
return NETRC_NONE;
|
||||
|
||||
i = NETRC_DEFAULT;
|
||||
while (keywords[i - 1])
|
||||
{
|
||||
if (!strcmp (keywords[i - 1], buffer))
|
||||
for (i = NETRC_DEFAULT; keywords[i - 1] != NULL; i++)
|
||||
if (strcmp (keywords[i - 1], buffer) == 0)
|
||||
return i;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return NETRC_UNKNOWN;
|
||||
}
|
||||
|
||||
|
@ -2407,11 +2371,10 @@ ftpfs_netrc_lookup (const char *host, char **login, char **pass)
|
|||
} *rup_cache = NULL, *rupp;
|
||||
|
||||
/* Initialize *login and *pass */
|
||||
if (!login)
|
||||
return 0;
|
||||
g_free (*login);
|
||||
*login = NULL;
|
||||
if (pass)
|
||||
*pass = NULL;
|
||||
g_free (*pass);
|
||||
*pass = NULL;
|
||||
|
||||
/* Look up in the cache first */
|
||||
for (rupp = rup_cache; rupp != NULL; rupp = rupp->next)
|
||||
|
@ -2521,19 +2484,13 @@ ftpfs_netrc_lookup (const char *host, char **login, char **pass)
|
|||
|
||||
rupp = g_new (struct rupcache, 1);
|
||||
rupp->host = g_strdup (host);
|
||||
rupp->login = rupp->pass = 0;
|
||||
rupp->login = g_strdup (*login);
|
||||
rupp->pass = g_strdup (tmp_pass);
|
||||
|
||||
if (*login != NULL)
|
||||
{
|
||||
rupp->login = g_strdup (*login);
|
||||
}
|
||||
if (tmp_pass != NULL)
|
||||
rupp->pass = g_strdup (tmp_pass);
|
||||
rupp->next = rup_cache;
|
||||
rup_cache = rupp;
|
||||
|
||||
if (pass)
|
||||
*pass = tmp_pass;
|
||||
*pass = tmp_pass;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -84,11 +84,6 @@ extern FILE *dbf;
|
|||
#define CNV_LANG(s) dos_to_unix(s,False)
|
||||
#define GNAL_VNC(s) unix_to_dos(s,False)
|
||||
|
||||
/* Extract the hostname and username from the path */
|
||||
/* path is in the form: [user@]hostname/share/remote-dir */
|
||||
#define smbfs_get_host_and_username(path, host, user, port, pass) \
|
||||
vfs_split_url (*path, host, user, port, pass, SMB_PORT, 0)
|
||||
|
||||
#define smbfs_lstat smbfs_stat /* no symlinks on smb filesystem? */
|
||||
|
||||
/*** file scope type declarations ****************************************************************/
|
||||
|
@ -1324,42 +1319,46 @@ smbfs_open_link (char *host, char *path, const char *user, int *port, char *this
|
|||
static char *
|
||||
smbfs_get_path (smbfs_connection ** sc, const char *path)
|
||||
{
|
||||
char *user, *host, *remote_path, *pass;
|
||||
int port = SMB_PORT;
|
||||
char *remote_path = NULL;
|
||||
vfs_url_t *url;
|
||||
|
||||
DEBUG (3, ("smbfs_get_path(%s)\n", path));
|
||||
if (strncmp (path, URL_HEADER, HEADER_LEN))
|
||||
if (strncmp (path, URL_HEADER, HEADER_LEN) != 0)
|
||||
return NULL;
|
||||
path += HEADER_LEN;
|
||||
|
||||
if (*path == '/') /* '/' leading server name */
|
||||
path++; /* probably came from server browsing */
|
||||
|
||||
if ((remote_path = smbfs_get_host_and_username (&path, &host, &user, &port, &pass)))
|
||||
if ((*sc = smbfs_open_link (host, remote_path, user, &port, pass)) == NULL)
|
||||
{
|
||||
g_free (remote_path);
|
||||
remote_path = NULL;
|
||||
}
|
||||
g_free (host);
|
||||
g_free (user);
|
||||
if (pass)
|
||||
wipe_password (pass);
|
||||
url = vfs_url_split (path, SMB_PORT, URL_FLAGS_NONE);
|
||||
|
||||
if (!remote_path)
|
||||
if (url != NULL)
|
||||
{
|
||||
*sc = smbfs_open_link (url->host, url->path, url->user, &url->port, url->password);
|
||||
wipe_password (url->password);
|
||||
|
||||
if (*sc != NULL)
|
||||
remote_path = g_strdup (url->path);
|
||||
|
||||
vfs_url_free (url);
|
||||
}
|
||||
|
||||
if (remote_path == NULL)
|
||||
return NULL;
|
||||
|
||||
/* NOTE: tildes are deprecated. See ftpfs.c */
|
||||
{
|
||||
int f = !strcmp (remote_path, "/~");
|
||||
if (f || !strncmp (remote_path, "/~/", 3))
|
||||
int f = strcmp (remote_path, "/~") ? 0 : 1;
|
||||
|
||||
if (f != 0 || strncmp (remote_path, "/~/", 3) == 0)
|
||||
{
|
||||
char *s;
|
||||
s = concat_dir_and_file ((*sc)->home, remote_path + 3 - f);
|
||||
g_free (remote_path);
|
||||
return s;
|
||||
remote_path = s;
|
||||
}
|
||||
}
|
||||
|
||||
return remote_path;
|
||||
}
|
||||
|
||||
|
@ -1942,10 +1941,9 @@ smbfs_free (vfsid id)
|
|||
static void
|
||||
smbfs_forget (const char *path)
|
||||
{
|
||||
char *host, *user, *p;
|
||||
int port;
|
||||
vfs_url_t *p;
|
||||
|
||||
if (strncmp (path, URL_HEADER, HEADER_LEN))
|
||||
if (strncmp (path, URL_HEADER, HEADER_LEN) != 0)
|
||||
return;
|
||||
|
||||
DEBUG (3, ("smbfs_forget(path:%s)\n", path));
|
||||
|
@ -1954,30 +1952,29 @@ smbfs_forget (const char *path)
|
|||
if (path[0] == '/' && path[1] == '/')
|
||||
path += 2;
|
||||
|
||||
if ((p = smbfs_get_host_and_username (&path, &host, &user, &port, NULL)))
|
||||
p = vfs_url_split (path, SMB_PORT, URL_FLAGS_NONE);
|
||||
if (p != NULL)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
g_free (p);
|
||||
|
||||
for (i = 0; i < SMBFS_MAX_CONNECTIONS; i++)
|
||||
{
|
||||
if (smbfs_connections[i].cli
|
||||
&& (strcmp (host, smbfs_connections[i].host) == 0)
|
||||
&& (strcmp (user, smbfs_connections[i].user) == 0)
|
||||
&& (port == smbfs_connections[i].port))
|
||||
&& (strcmp (p->host, smbfs_connections[i].host) == 0)
|
||||
&& (strcmp (p->user, smbfs_connections[i].user) == 0)
|
||||
&& (p->port == smbfs_connections[i].port))
|
||||
{
|
||||
|
||||
/* close socket: the child owns it now */
|
||||
cli_shutdown (smbfs_connections[i].cli);
|
||||
|
||||
/* reopen the connection */
|
||||
smbfs_connections[i].cli = smbfs_do_connect (host, smbfs_connections[i].service);
|
||||
smbfs_connections[i].cli = smbfs_do_connect (p->host, smbfs_connections[i].service);
|
||||
}
|
||||
}
|
||||
|
||||
vfs_url_free (p);
|
||||
}
|
||||
g_free (host);
|
||||
g_free (user);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
|
Loading…
Reference in New Issue