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>
Этот коммит содержится в:
родитель
fcfa76be3d
Коммит
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);
|
MEDATA->supers = g_list_remove (MEDATA->supers, super);
|
||||||
|
|
||||||
CALL (free_archive) (me, super);
|
CALL (free_archive) (me, super);
|
||||||
|
#ifdef ENABLE_VFS_NET
|
||||||
|
vfs_url_free (super->url);
|
||||||
|
#endif
|
||||||
g_free (super->name);
|
g_free (super->name);
|
||||||
g_free (super);
|
g_free (super);
|
||||||
}
|
}
|
||||||
|
@ -373,85 +373,82 @@ vfs_mkstemps (char **pname, const char *prefix, const char *param_basename)
|
|||||||
* ftp://joe:password@foo.se
|
* ftp://joe:password@foo.se
|
||||||
*
|
*
|
||||||
* @param path is an input string to be parsed
|
* @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 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
|
* If the user is empty, e.g. ftp://@roxanne/private, and URL_USE_ANONYMOUS
|
||||||
* is not set, then the current login name is supplied.
|
* 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.
|
* host.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char *
|
vfs_url_t *
|
||||||
vfs_split_url (const char *path, char **host, char **user, int *port,
|
vfs_url_split (const char *path, int default_port, vfs_url_flags_t flags)
|
||||||
char **pass, int default_port, enum VFS_URL_FLAGS flags)
|
|
||||||
{
|
{
|
||||||
|
vfs_url_t *url;
|
||||||
|
|
||||||
|
char *pcopy;
|
||||||
|
const char *pend;
|
||||||
char *dir, *colon, *inner_colon, *at, *rest;
|
char *dir, *colon, *inner_colon, *at, *rest;
|
||||||
char *retval;
|
|
||||||
char *const pcopy = g_strdup (path);
|
|
||||||
const char *pend = pcopy + strlen (pcopy);
|
|
||||||
|
|
||||||
if (pass)
|
url = g_new0 (vfs_url_t, 1);
|
||||||
*pass = NULL;
|
url->port = default_port;
|
||||||
*port = default_port;
|
|
||||||
*user = NULL;
|
|
||||||
retval = NULL;
|
|
||||||
|
|
||||||
|
pcopy = g_strdup (path);
|
||||||
|
pend = pcopy + strlen (pcopy);
|
||||||
dir = pcopy;
|
dir = pcopy;
|
||||||
if (!(flags & URL_NOSLASH))
|
|
||||||
|
if ((flags & URL_NOSLASH) == 0)
|
||||||
{
|
{
|
||||||
/* locate path component */
|
/* locate path component */
|
||||||
while (*dir != PATH_SEP && *dir)
|
while (*dir != PATH_SEP && *dir != '\0')
|
||||||
dir++;
|
dir++;
|
||||||
if (*dir)
|
if (*dir == '\0')
|
||||||
{
|
url->path = g_strdup (PATH_SEP_STR);
|
||||||
retval = g_strdup (dir);
|
|
||||||
*dir = 0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
retval = g_strdup (PATH_SEP_STR);
|
{
|
||||||
|
url->path = g_strdup (dir);
|
||||||
|
*dir = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* search for any possible user */
|
/* search for any possible user */
|
||||||
at = strrchr (pcopy, '@');
|
at = strrchr (pcopy, '@');
|
||||||
|
|
||||||
/* We have a username */
|
/* We have a username */
|
||||||
if (at)
|
if (at == NULL)
|
||||||
|
rest = pcopy;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
*at = 0;
|
*at = '\0';
|
||||||
inner_colon = strchr (pcopy, ':');
|
inner_colon = strchr (pcopy, ':');
|
||||||
if (inner_colon)
|
if (inner_colon != NULL)
|
||||||
{
|
{
|
||||||
*inner_colon = 0;
|
*inner_colon = '\0';
|
||||||
inner_colon++;
|
inner_colon++;
|
||||||
if (pass)
|
url->password = g_strdup (inner_colon);
|
||||||
*pass = g_strdup (inner_colon);
|
|
||||||
}
|
}
|
||||||
if (*pcopy != 0)
|
|
||||||
*user = g_strdup (pcopy);
|
if (*pcopy != '\0')
|
||||||
|
url->user = g_strdup (pcopy);
|
||||||
|
|
||||||
if (pend == at + 1)
|
if (pend == at + 1)
|
||||||
rest = at;
|
rest = at;
|
||||||
else
|
else
|
||||||
rest = at + 1;
|
rest = at + 1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
rest = pcopy;
|
|
||||||
|
|
||||||
if (!*user && !(flags & URL_USE_ANONYMOUS))
|
if ((flags & URL_USE_ANONYMOUS) == 0)
|
||||||
*user = vfs_get_local_username ();
|
url->user = vfs_get_local_username ();
|
||||||
|
|
||||||
/* Check if the host comes with a port spec, if so, chop it */
|
/* Check if the host comes with a port spec, if so, chop it */
|
||||||
if ('[' == *rest)
|
if (*rest != '[')
|
||||||
|
colon = strchr (rest, ':');
|
||||||
|
else
|
||||||
{
|
{
|
||||||
colon = strchr (++rest, ']');
|
colon = strchr (++rest, ']');
|
||||||
if (colon)
|
if (colon != NULL)
|
||||||
{
|
{
|
||||||
colon[0] = '\0';
|
colon[0] = '\0';
|
||||||
colon[1] = '\0';
|
colon[1] = '\0';
|
||||||
@ -459,45 +456,52 @@ vfs_split_url (const char *path, char **host, char **user, int *port,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_free (pcopy);
|
vfs_url_free (url);
|
||||||
g_free (retval);
|
|
||||||
*host = NULL;
|
|
||||||
*port = 0;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
colon = strchr (rest, ':');
|
|
||||||
|
|
||||||
if (colon)
|
if (colon != NULL)
|
||||||
{
|
{
|
||||||
*colon = 0;
|
*colon = '\0';
|
||||||
if (sscanf (colon + 1, "%d", port) == 1)
|
if (sscanf (colon + 1, "%d", &url->port) == 1)
|
||||||
{
|
{
|
||||||
if (*port <= 0 || *port >= 65536)
|
if (url->port <= 0 || url->port >= 65536)
|
||||||
*port = default_port;
|
url->port = default_port;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
while (*(++colon) != '\0')
|
||||||
while (*(++colon))
|
|
||||||
{
|
{
|
||||||
switch (*colon)
|
switch (*colon)
|
||||||
{
|
{
|
||||||
case 'C':
|
case 'C':
|
||||||
*port = 1;
|
url->port = 1;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
*port = 2;
|
url->port = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (host)
|
|
||||||
*host = g_strdup (rest);
|
|
||||||
|
|
||||||
g_free (pcopy);
|
url->host = g_strdup (rest);
|
||||||
return retval;
|
|
||||||
|
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 ***************************************************************************************/
|
/*** enums ***************************************************************************************/
|
||||||
|
|
||||||
/** Bit flags for vfs_split_url()
|
/** Bit flags for vfs_url_split()
|
||||||
*
|
*
|
||||||
* Modify parsing parameters according to flag meaning.
|
* 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_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 */
|
URL_NOSLASH = 2 /**< if set, 'proto://' part in url is not searched */
|
||||||
};
|
} vfs_url_flags_t;
|
||||||
|
|
||||||
/*** structures declarations (and typedefs of structures)*****************************************/
|
/*** 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 *********************************************************/
|
/*** global variables defined in .c file *********************************************************/
|
||||||
|
|
||||||
/*** declarations of public functions ************************************************************/
|
/*** declarations of public functions ************************************************************/
|
||||||
@ -37,8 +47,8 @@ enum VFS_URL_FLAGS
|
|||||||
int vfs_finduid (const char *name);
|
int vfs_finduid (const char *name);
|
||||||
int vfs_findgid (const char *name);
|
int vfs_findgid (const char *name);
|
||||||
|
|
||||||
char *vfs_split_url (const char *path, char **host, char **user, int *port,
|
vfs_url_t *vfs_url_split (const char *path, int default_port, vfs_url_flags_t flags);
|
||||||
char **pass, int default_port, enum VFS_URL_FLAGS flags);
|
void vfs_url_free (vfs_url_t * url);
|
||||||
int vfs_split_text (char *p);
|
int vfs_split_text (char *p);
|
||||||
|
|
||||||
int vfs_mkstemps (char **pname, const char *prefix, const char *basename);
|
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 fd_usage; /* Number of open files */
|
||||||
int ino_usage; /* Usage count of this superblock */
|
int ino_usage; /* Usage count of this superblock */
|
||||||
int want_stale; /* If set, we do not flush cache properly */
|
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 */
|
void *data; /* This is for filesystem-specific use */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
shell connections.
|
shell connections.
|
||||||
|
|
||||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
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
|
Written by: 1998 Pavel Machek
|
||||||
Spaces fix: 2000 Michal Svec
|
Spaces fix: 2000 Michal Svec
|
||||||
@ -134,11 +134,8 @@ int fish_directory_timeout = 900;
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int sockr, sockw;
|
int sockr;
|
||||||
char *cwdir;
|
int sockw;
|
||||||
char *host, *user;
|
|
||||||
char *password;
|
|
||||||
int flags;
|
|
||||||
char *scr_ls;
|
char *scr_ls;
|
||||||
char *scr_chmod;
|
char *scr_chmod;
|
||||||
char *scr_exists;
|
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;
|
va_list ap;
|
||||||
char *str;
|
char *str;
|
||||||
int status;
|
ssize_t status;
|
||||||
FILE *logfile = MEDATA->logfile;
|
FILE *logfile = MEDATA->logfile;
|
||||||
|
|
||||||
va_start (ap, fmt);
|
va_start (ap, fmt);
|
||||||
@ -297,10 +294,6 @@ fish_free_archive (struct vfs_class *me, struct vfs_s_super *super)
|
|||||||
close (SUP->sockr);
|
close (SUP->sockr);
|
||||||
SUP->sockw = SUP->sockr = -1;
|
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_ls);
|
||||||
g_free (SUP->scr_exists);
|
g_free (SUP->scr_exists);
|
||||||
g_free (SUP->scr_mkdir);
|
g_free (SUP->scr_mkdir);
|
||||||
@ -437,17 +430,17 @@ fish_open_archive_pipeopen (struct vfs_s_super *super)
|
|||||||
{
|
{
|
||||||
char gbuf[10];
|
char gbuf[10];
|
||||||
const char *argv[10]; /* All of 10 is used now */
|
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;
|
int i = 0;
|
||||||
|
|
||||||
argv[i++] = xsh;
|
argv[i++] = xsh;
|
||||||
if (SUP->flags == FISH_FLAG_COMPRESSED)
|
if (super->url->port == FISH_FLAG_COMPRESSED)
|
||||||
argv[i++] = "-C";
|
argv[i++] = "-C";
|
||||||
|
|
||||||
if (SUP->flags > FISH_FLAG_RSH)
|
if (super->url->port > FISH_FLAG_RSH)
|
||||||
{
|
{
|
||||||
argv[i++] = "-p";
|
argv[i++] = "-p";
|
||||||
g_snprintf (gbuf, sizeof (gbuf), "%d", SUP->flags);
|
g_snprintf (gbuf, sizeof (gbuf), "%d", super->url->port);
|
||||||
argv[i++] = gbuf;
|
argv[i++] = gbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,18 +451,18 @@ fish_open_archive_pipeopen (struct vfs_s_super *super)
|
|||||||
* option breaks it for some)
|
* option breaks it for some)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (SUP->user)
|
if (super->url->user != NULL)
|
||||||
{
|
{
|
||||||
argv[i++] = "-l";
|
argv[i++] = "-l";
|
||||||
argv[i++] = SUP->user;
|
argv[i++] = super->url->user;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* The rest of the code assumes it to be a valid username */
|
/* 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++] = "echo FISH:; /bin/sh";
|
||||||
argv[i++] = NULL;
|
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), ':'))
|
if (!vfs_s_get_line (me, SUP->sockr, answer, sizeof (answer), ':'))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (strstr (answer, "assword"))
|
if (strstr (answer, "assword") != NULL)
|
||||||
{
|
{
|
||||||
/* Currently, this does not work. ssh reads passwords from
|
/* Currently, this does not work. ssh reads passwords from
|
||||||
/dev/tty, not from stdin :-(. */
|
/dev/tty, not from stdin :-(. */
|
||||||
@ -497,25 +490,27 @@ fish_open_archive_talk (struct vfs_class *me, struct vfs_s_super *super)
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#if 0
|
#if 0
|
||||||
if (!SUP->password)
|
if (super->url->password == NULL)
|
||||||
{
|
{
|
||||||
char *p, *op;
|
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);
|
op = vfs_get_password (p);
|
||||||
g_free (p);
|
g_free (p);
|
||||||
if (op == NULL)
|
if (op == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
SUP->password = op;
|
super->url->password = op;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf ("\n%s\n", _("fish: Sending password..."));
|
printf ("\n%s\n", _("fish: Sending password..."));
|
||||||
|
|
||||||
{
|
{
|
||||||
size_t str_len;
|
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))
|
|| (write (SUP->sockw, "\n", 1) != 1))
|
||||||
{
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
SUP->scr_env = fish_set_env (SUP->host_flags);
|
||||||
|
|
||||||
vfs_print_message (_("fish: Setting up current directory..."));
|
vfs_print_message (_("fish: Setting up current directory..."));
|
||||||
SUP->cwdir = fish_getcwd (me, super);
|
super->url->path = fish_getcwd (me, super);
|
||||||
vfs_print_message (_("fish: Connected, home %s."), SUP->cwdir);
|
vfs_print_message (_("fish: Connected, home %s."), super->url->path);
|
||||||
#if 0
|
#if 0
|
||||||
super->name = g_strconcat ("/#sh:", SUP->user, "@", SUP->host, "/", (char *) NULL);
|
super->name =
|
||||||
#endif
|
g_strconcat ("/#sh:", super->url->user, "@", super->url->host, "/", (char *) NULL);
|
||||||
|
#else
|
||||||
super->name = g_strdup (PATH_SEP_STR);
|
super->name = g_strdup (PATH_SEP_STR);
|
||||||
|
#endif
|
||||||
|
|
||||||
super->root = vfs_s_new_inode (me, super, vfs_s_default_stat (me, S_IFDIR | 0755));
|
super->root = vfs_s_new_inode (me, super, vfs_s_default_stat (me, S_IFDIR | 0755));
|
||||||
return 0;
|
return 0;
|
||||||
@ -586,41 +583,41 @@ static int
|
|||||||
fish_open_archive (struct vfs_class *me, struct vfs_s_super *super,
|
fish_open_archive (struct vfs_class *me, struct vfs_s_super *super,
|
||||||
const char *archive_name, char *op)
|
const char *archive_name, char *op)
|
||||||
{
|
{
|
||||||
char *host, *user, *password, *p;
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
(void) archive_name;
|
(void) archive_name;
|
||||||
|
|
||||||
super->data = g_new0 (fish_super_data_t, 1);
|
super->data = g_new0 (fish_super_data_t, 1);
|
||||||
p = vfs_split_url (strchr (op, ':') + 1, &host, &user, &flags,
|
super->url = vfs_url_split (strchr (op, ':') + 1, 0, URL_NOSLASH | URL_USE_ANONYMOUS);
|
||||||
&password, 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)
|
if (strncmp (op, "rsh:", 4) == 0)
|
||||||
SUP->flags = FISH_FLAG_RSH;
|
super->url->port = FISH_FLAG_RSH;
|
||||||
SUP->cwdir = NULL;
|
|
||||||
if (password != NULL)
|
SUP->scr_ls = fish_load_script_from_file (super->url->host, FISH_LS_FILE, FISH_LS_DEF_CONTENT);
|
||||||
SUP->password = password;
|
SUP->scr_exists =
|
||||||
SUP->scr_ls = fish_load_script_from_file (host, FISH_LS_FILE, FISH_LS_DEF_CONTENT);
|
fish_load_script_from_file (super->url->host, FISH_EXISTS_FILE, FISH_EXISTS_DEF_CONTENT);
|
||||||
SUP->scr_exists = fish_load_script_from_file (host, FISH_EXISTS_FILE, FISH_EXISTS_DEF_CONTENT);
|
SUP->scr_mkdir =
|
||||||
SUP->scr_mkdir = fish_load_script_from_file (host, FISH_MKDIR_FILE, FISH_MKDIR_DEF_CONTENT);
|
fish_load_script_from_file (super->url->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_unlink =
|
||||||
SUP->scr_chown = fish_load_script_from_file (host, FISH_CHOWN_FILE, FISH_CHOWN_DEF_CONTENT);
|
fish_load_script_from_file (super->url->host, FISH_UNLINK_FILE, FISH_UNLINK_DEF_CONTENT);
|
||||||
SUP->scr_chmod = fish_load_script_from_file (host, FISH_CHMOD_FILE, FISH_CHMOD_DEF_CONTENT);
|
SUP->scr_chown =
|
||||||
SUP->scr_rmdir = fish_load_script_from_file (host, FISH_RMDIR_FILE, FISH_RMDIR_DEF_CONTENT);
|
fish_load_script_from_file (super->url->host, FISH_CHOWN_FILE, FISH_CHOWN_DEF_CONTENT);
|
||||||
SUP->scr_ln = fish_load_script_from_file (host, FISH_LN_FILE, FISH_LN_DEF_CONTENT);
|
SUP->scr_chmod =
|
||||||
SUP->scr_mv = fish_load_script_from_file (host, FISH_MV_FILE, FISH_MV_DEF_CONTENT);
|
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 =
|
SUP->scr_hardlink =
|
||||||
fish_load_script_from_file (host, FISH_HARDLINK_FILE, FISH_HARDLINK_DEF_CONTENT);
|
fish_load_script_from_file (super->url->host, FISH_HARDLINK_FILE,
|
||||||
SUP->scr_get = fish_load_script_from_file (host, FISH_GET_FILE, FISH_GET_DEF_CONTENT);
|
FISH_HARDLINK_DEF_CONTENT);
|
||||||
SUP->scr_send = fish_load_script_from_file (host, FISH_SEND_FILE, FISH_SEND_DEF_CONTENT);
|
SUP->scr_get =
|
||||||
SUP->scr_append = fish_load_script_from_file (host, FISH_APPEND_FILE, FISH_APPEND_DEF_CONTENT);
|
fish_load_script_from_file (super->url->host, FISH_GET_FILE, FISH_GET_DEF_CONTENT);
|
||||||
SUP->scr_info = fish_load_script_from_file (host, FISH_INFO_FILE, FISH_INFO_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);
|
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,
|
fish_archive_same (struct vfs_class *me, struct vfs_s_super *super,
|
||||||
const char *archive_name, char *op, void *cookie)
|
const char *archive_name, char *op, void *cookie)
|
||||||
{
|
{
|
||||||
char *host, *user;
|
vfs_url_t *url;
|
||||||
int flags;
|
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
(void) me;
|
(void) me;
|
||||||
(void) archive_name;
|
(void) archive_name;
|
||||||
(void) cookie;
|
(void) cookie;
|
||||||
|
|
||||||
op = vfs_split_url (strchr (op, ':') + 1, &host, &user, &flags, 0, 0,
|
url = vfs_url_split (strchr (op, ':') + 1, 0, URL_NOSLASH | URL_USE_ANONYMOUS);
|
||||||
URL_NOSLASH | URL_USE_ANONYMOUS);
|
|
||||||
|
|
||||||
g_free (op);
|
if (url->user == NULL)
|
||||||
|
url->user = vfs_get_local_username ();
|
||||||
|
|
||||||
if (user == NULL)
|
result = ((strcmp (url->host, super->url->host) == 0)
|
||||||
user = vfs_get_local_username ();
|
&& (strcmp (url->user, super->url->user) == 0)
|
||||||
|
&& (url->port == super->url->port)) ? 1 : 0;
|
||||||
|
|
||||||
result = ((strcmp (host, SUP->host) == 0)
|
vfs_url_free (url);
|
||||||
&& (strcmp (user, SUP->user) == 0) && (flags == SUP->flags));
|
|
||||||
|
|
||||||
g_free (host);
|
|
||||||
g_free (user);
|
|
||||||
|
|
||||||
return result;
|
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);
|
reply_code = fish_decode_reply (buffer + 4, 0);
|
||||||
if (reply_code == COMPLETE)
|
if (reply_code == COMPLETE)
|
||||||
{
|
{
|
||||||
g_free (SUP->cwdir);
|
g_free (super->url->path);
|
||||||
SUP->cwdir = g_strdup (remote_path);
|
super->url->path = g_strdup (remote_path);
|
||||||
vfs_print_message (_("%s: done."), me->name);
|
vfs_print_message (_("%s: done."), me->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (reply_code == ERROR)
|
|
||||||
{
|
me->verrno = reply_code == ERROR ? EACCES : E_REMOTE;
|
||||||
me->verrno = EACCES;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
me->verrno = E_REMOTE;
|
|
||||||
}
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
vfs_print_message (_("%s: failure"), me->name);
|
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
|
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;
|
fish_fh_data_t *fish = (fish_fh_data_t *) fh->data;
|
||||||
gchar *shell_commands = NULL;
|
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;
|
char *quoted_name;
|
||||||
|
|
||||||
h = open (localname, O_RDONLY);
|
h = open (localname, O_RDONLY);
|
||||||
|
|
||||||
if (h == -1)
|
if (h == -1)
|
||||||
ERRNOR (EIO, -1);
|
ERRNOR (EIO, -1);
|
||||||
if (fstat (h, &s) < 0)
|
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 =
|
shell_commands =
|
||||||
g_strconcat (SUP->scr_env, "FISH_FILENAME=%s FISH_FILESIZE=%" PRIuMAX ";\n",
|
g_strconcat (SUP->scr_env, "FISH_FILENAME=%s FISH_FILESIZE=%" PRIuMAX ";\n",
|
||||||
SUP->scr_append, (char *) NULL);
|
SUP->scr_append, (char *) NULL);
|
||||||
|
|
||||||
n = fish_command (me, super, WAIT_REPLY, shell_commands, quoted_name,
|
n = fish_command (me, super, WAIT_REPLY, shell_commands, quoted_name,
|
||||||
(uintmax_t) s.st_size);
|
(uintmax_t) s.st_size);
|
||||||
g_free (shell_commands);
|
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);
|
close (h);
|
||||||
g_free (quoted_name);
|
g_free (quoted_name);
|
||||||
|
|
||||||
if ((fish_get_reply (me, SUP->sockr, NULL, 0) != COMPLETE) || was_error)
|
if ((fish_get_reply (me, SUP->sockr, NULL, 0) != COMPLETE) || was_error)
|
||||||
ERRNOR (E_REMOTE, -1);
|
ERRNOR (E_REMOTE, -1);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_return:
|
error_return:
|
||||||
close (h);
|
close (h);
|
||||||
fish_get_reply (me, SUP->sockr, NULL, 0);
|
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
|
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;
|
fish_fh_data_t *fish;
|
||||||
gchar *shell_commands = NULL;
|
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
|
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;
|
fish_fh_data_t *fish = (fish_fh_data_t *) fh->data;
|
||||||
struct vfs_s_super *super = FH_SUPER;
|
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;
|
int n;
|
||||||
|
|
||||||
vfs_print_message (_("Aborting transfer..."));
|
vfs_print_message (_("Aborting transfer..."));
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
n = MIN (sizeof (buffer), (size_t) (fish->total - fish->got));
|
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
|
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;
|
fish_fh_data_t *fish = (fish_fh_data_t *) fh->data;
|
||||||
struct vfs_s_super *super = FH_SUPER;
|
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
|
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;
|
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;
|
sowner = pw->pw_name;
|
||||||
sgroup = gr->gr_name;
|
sgroup = gr->gr_name;
|
||||||
|
|
||||||
{
|
{
|
||||||
gchar *shell_commands = NULL;
|
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;
|
return (fish_send_command (me, super, buf, OPT_FLUSH) == 0) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1382,9 +1372,7 @@ fish_mkdir (struct vfs_class *me, const char *path, mode_t mode)
|
|||||||
return ret_code;
|
return ret_code;
|
||||||
|
|
||||||
if (!fish_exists (me, path))
|
if (!fish_exists (me, path))
|
||||||
{
|
|
||||||
ERRNOR (EACCES, -1);
|
ERRNOR (EACCES, -1);
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1408,7 +1396,7 @@ fish_rmdir (struct vfs_class *me, const char *path)
|
|||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int
|
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;
|
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
|
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;
|
(void) me;
|
||||||
|
|
||||||
@ -1468,7 +1456,7 @@ fish_fill_names (struct vfs_class *me, fill_names_f func)
|
|||||||
char gbuf[10];
|
char gbuf[10];
|
||||||
const char *flags = "";
|
const char *flags = "";
|
||||||
|
|
||||||
switch (SUP->flags)
|
switch (super->url->port)
|
||||||
{
|
{
|
||||||
case FISH_FLAG_RSH:
|
case FISH_FLAG_RSH:
|
||||||
flags = ":r";
|
flags = ":r";
|
||||||
@ -1477,16 +1465,16 @@ fish_fill_names (struct vfs_class *me, fill_names_f func)
|
|||||||
flags = ":C";
|
flags = ":C";
|
||||||
break;
|
break;
|
||||||
default:
|
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;
|
flags = gbuf;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
name =
|
name = g_strconcat ("/#sh:", super->url->user, "@", super->url->host, flags, "/",
|
||||||
g_strconcat ("/#sh:", SUP->user, "@", SUP->host, flags, "/", SUP->cwdir, (char *) NULL);
|
super->url->path, (char *) NULL);
|
||||||
func (name);
|
func (name);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* Virtual File System: FTP file system.
|
/* Virtual File System: FTP file system.
|
||||||
Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
|
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:
|
Written by:
|
||||||
1995 Ching Hui
|
1995 Ching Hui
|
||||||
@ -9,6 +9,8 @@
|
|||||||
1997 Norbert Warmuth
|
1997 Norbert Warmuth
|
||||||
1998 Pavel Machek
|
1998 Pavel Machek
|
||||||
2010 Yury V. Zaytsev
|
2010 Yury V. Zaytsev
|
||||||
|
2010 Slava Zanko
|
||||||
|
2010 Andrew Borodin
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Library General Public License
|
modify it under the terms of the GNU Library General Public License
|
||||||
@ -197,11 +199,6 @@ typedef enum
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int sock;
|
int sock;
|
||||||
char *cwdir;
|
|
||||||
char *host;
|
|
||||||
char *user;
|
|
||||||
char *password;
|
|
||||||
int port;
|
|
||||||
|
|
||||||
char *proxy; /* proxy server, NULL if no proxy */
|
char *proxy; /* proxy server, NULL if no proxy */
|
||||||
int failed_on_login; /* used to pass the failure reason to upper levels */
|
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
|
* ftp://joe@foo.edu:11321/private
|
||||||
* If the user is empty, e.g. ftp://@roxanne/private, then your login name
|
* If the user is empty, e.g. ftp://@roxanne/private, then your login name
|
||||||
* is supplied.
|
* is supplied.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static vfs_url_t *
|
||||||
ftpfs_split_url (char *path, char **host, char **user, int *port, char **pass)
|
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 */
|
/* Look up user and password in netrc */
|
||||||
if (ftpfs_use_netrc)
|
if (ftpfs_use_netrc)
|
||||||
ftpfs_netrc_lookup (*host, user, pass);
|
ftpfs_netrc_lookup (p->host, &p->user, &p->password);
|
||||||
if (!*user)
|
|
||||||
*user = g_strdup ("anonymous");
|
|
||||||
}
|
}
|
||||||
|
if (p->user == NULL)
|
||||||
|
p->user = g_strdup ("anonymous");
|
||||||
|
|
||||||
/* Look up password in netrc for known user */
|
/* 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 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);
|
g_free (p->password);
|
||||||
*pass = NULL;
|
p->password = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (new_user);
|
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
|
static int
|
||||||
ftpfs_reconnect (struct vfs_class *me, struct vfs_s_super *super)
|
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)
|
if (sock != -1)
|
||||||
{
|
{
|
||||||
char *cwdir = SUP->cwdir;
|
char *cwdir = super->url->path;
|
||||||
|
|
||||||
close (SUP->sock);
|
close (SUP->sock);
|
||||||
SUP->sock = sock;
|
SUP->sock = sock;
|
||||||
SUP->cwdir = NULL;
|
super->url->path = NULL;
|
||||||
if (ftpfs_login_server (me, super, SUP->password))
|
|
||||||
|
|
||||||
|
if (ftpfs_login_server (me, super, super->url->password) != 0)
|
||||||
{
|
{
|
||||||
if (!cwdir)
|
if (cwdir == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
sock = ftpfs_chdir_internal (me, super, cwdir);
|
sock = ftpfs_chdir_internal (me, super, cwdir);
|
||||||
g_free (cwdir);
|
g_free (cwdir);
|
||||||
return sock == COMPLETE;
|
return sock == COMPLETE ? 1 : 0;
|
||||||
}
|
}
|
||||||
SUP->cwdir = cwdir;
|
|
||||||
|
super->url->path = cwdir;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,14 +535,10 @@ ftpfs_free_archive (struct vfs_class *me, struct vfs_s_super *super)
|
|||||||
{
|
{
|
||||||
if (SUP->sock != -1)
|
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");
|
ftpfs_command (me, super, NONE, "QUIT");
|
||||||
close (SUP->sock);
|
close (SUP->sock);
|
||||||
}
|
}
|
||||||
g_free (SUP->host);
|
|
||||||
g_free (SUP->user);
|
|
||||||
g_free (SUP->cwdir);
|
|
||||||
g_free (SUP->password);
|
|
||||||
g_free (super->data);
|
g_free (super->data);
|
||||||
super->data = NULL;
|
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;
|
SUP->isbinary = TYPE_UNKNOWN;
|
||||||
|
|
||||||
if (SUP->password != NULL) /* explicit password */
|
if (super->url->password != NULL) /* explicit password */
|
||||||
op = g_strdup (SUP->password);
|
op = g_strdup (super->url->password);
|
||||||
else if (netrcpass != NULL) /* password from netrc */
|
else if (netrcpass != NULL) /* password from netrc */
|
||||||
op = g_strdup (netrcpass);
|
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 ();
|
ftpfs_init_passwd ();
|
||||||
op = g_strdup (ftpfs_anonymous_passwd);
|
op = g_strdup (ftpfs_anonymous_passwd);
|
||||||
anon = 1;
|
anon = 1;
|
||||||
@ -587,12 +586,12 @@ ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, const char
|
|||||||
{ /* ask user */
|
{ /* ask user */
|
||||||
char *p;
|
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);
|
op = vfs_get_password (p);
|
||||||
g_free (p);
|
g_free (p);
|
||||||
if (op == NULL)
|
if (op == NULL)
|
||||||
ERRNOR (EPERM, 0);
|
ERRNOR (EPERM, 0);
|
||||||
SUP->password = g_strdup (op);
|
super->url->password = g_strdup (op);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!anon || MEDATA->logfile)
|
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 */
|
/* Proxy server accepts: username@host-we-want-to-connect */
|
||||||
if (SUP->proxy)
|
if (SUP->proxy)
|
||||||
{
|
|
||||||
name =
|
name =
|
||||||
g_strconcat (SUP->user, "@",
|
g_strconcat (super->url->user, "@",
|
||||||
SUP->host[0] == '!' ? SUP->host + 1 : SUP->host, (char *) NULL);
|
super->url->host[0] == '!' ? super->url->host + 1 : super->url->host,
|
||||||
}
|
(char *) NULL);
|
||||||
else
|
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)
|
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;
|
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, "");
|
op = input_dialog (p, _("Account:"), MC_HISTORY_FTPFS_ACCOUNT, "");
|
||||||
g_free (p);
|
g_free (p);
|
||||||
if (op == NULL)
|
if (op == NULL)
|
||||||
@ -659,14 +657,15 @@ ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, const char
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
SUP->failed_on_login = 1;
|
SUP->failed_on_login = 1;
|
||||||
if (SUP->password)
|
wipe_password (super->url->password);
|
||||||
wipe_password (SUP->password);
|
super->url->password = NULL;
|
||||||
SUP->password = 0;
|
|
||||||
|
|
||||||
goto login_fail;
|
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:
|
login_fail:
|
||||||
wipe_password (pass);
|
wipe_password (pass);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
@ -764,11 +763,12 @@ ftpfs_check_proxy (const char *host)
|
|||||||
static void
|
static void
|
||||||
ftpfs_get_proxy_host_and_port (const char *proxy, char **host, int *port)
|
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);
|
url = vfs_url_split (proxy, FTP_COMMAND_PORT, URL_USE_ANONYMOUS);
|
||||||
g_free (user);
|
*host = g_strdup (url->host);
|
||||||
g_free (dir);
|
*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;
|
struct addrinfo hints, *res, *curr_res;
|
||||||
int my_socket = 0;
|
int my_socket = 0;
|
||||||
char *host = NULL;
|
char *host = NULL;
|
||||||
char *port = NULL;
|
char port[8];
|
||||||
int tmp_port;
|
int tmp_port;
|
||||||
int e;
|
int e;
|
||||||
|
|
||||||
(void) me;
|
(void) me;
|
||||||
|
|
||||||
/* Use a proxy host? */
|
/* 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."));
|
vfs_print_message (_("ftpfs: Invalid host name."));
|
||||||
ftpfs_errno = EINVAL;
|
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 */
|
/* 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);
|
ftpfs_get_proxy_host_and_port (ftpfs_proxy_host, &host, &tmp_port);
|
||||||
}
|
|
||||||
|
|
||||||
port = g_strdup_printf ("%hu", (unsigned short) tmp_port);
|
g_snprintf (port, sizeof (port), "%hu", (unsigned short) tmp_port);
|
||||||
if (port == NULL)
|
if (port[0] == '\0')
|
||||||
{
|
{
|
||||||
g_free (host);
|
g_free (host);
|
||||||
ftpfs_errno = errno;
|
ftpfs_errno = errno;
|
||||||
@ -836,8 +834,7 @@ ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_free (port);
|
*port = '\0';
|
||||||
port = NULL;
|
|
||||||
|
|
||||||
if (e != 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)
|
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);
|
my_socket = socket (curr_res->ai_family, curr_res->ai_socktype, curr_res->ai_protocol);
|
||||||
|
|
||||||
if (my_socket < 0)
|
if (my_socket < 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (curr_res->ai_next != NULL)
|
if (curr_res->ai_next != NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -878,18 +873,12 @@ ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super)
|
|||||||
close (my_socket);
|
close (my_socket);
|
||||||
|
|
||||||
if (errno == EINTR && tty_got_interrupt ())
|
if (errno == EINTR && tty_got_interrupt ())
|
||||||
{
|
|
||||||
vfs_print_message (_("ftpfs: connection interrupted by user"));
|
vfs_print_message (_("ftpfs: connection interrupted by user"));
|
||||||
}
|
|
||||||
else if (res->ai_next == NULL)
|
else if (res->ai_next == NULL)
|
||||||
{
|
|
||||||
vfs_print_message (_("ftpfs: connection to server failed: %s"),
|
vfs_print_message (_("ftpfs: connection to server failed: %s"),
|
||||||
unix_error_string (errno));
|
unix_error_string (errno));
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
freeaddrinfo (res);
|
freeaddrinfo (res);
|
||||||
tty_disable_interrupt_key ();
|
tty_disable_interrupt_key ();
|
||||||
@ -906,13 +895,13 @@ ftpfs_open_socket (struct vfs_class *me, struct vfs_s_super *super)
|
|||||||
static int
|
static int
|
||||||
ftpfs_open_archive_int (struct vfs_class *me, struct vfs_s_super *super)
|
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 */
|
/* We do not want to use the passive if we are using proxies */
|
||||||
if (SUP->proxy)
|
if (SUP->proxy)
|
||||||
SUP->use_passive_connection = ftpfs_use_passive_connections_over_proxy;
|
SUP->use_passive_connection = ftpfs_use_passive_connections_over_proxy;
|
||||||
|
|
||||||
retry_seconds = 0;
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
SUP->failed_on_login = 0;
|
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)
|
if (SUP->sock == -1)
|
||||||
return -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 */
|
/* Logged in, no need to retry the connection */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (SUP->failed_on_login)
|
if (!SUP->failed_on_login)
|
||||||
{
|
|
||||||
/* Close only the socket descriptor */
|
|
||||||
close (SUP->sock);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
if (ftpfs_retry_seconds)
|
/* Close only the socket descriptor */
|
||||||
|
close (SUP->sock);
|
||||||
|
|
||||||
|
if (ftpfs_retry_seconds != 0)
|
||||||
{
|
{
|
||||||
retry_seconds = ftpfs_retry_seconds;
|
retry_seconds = ftpfs_retry_seconds;
|
||||||
tty_enable_interrupt_key ();
|
tty_enable_interrupt_key ();
|
||||||
for (count_down = retry_seconds; count_down; count_down--)
|
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);
|
count_down);
|
||||||
sleep (1);
|
sleep (1);
|
||||||
if (tty_got_interrupt ())
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -971,22 +958,14 @@ static int
|
|||||||
ftpfs_open_archive (struct vfs_class *me, struct vfs_s_super *super,
|
ftpfs_open_archive (struct vfs_class *me, struct vfs_s_super *super,
|
||||||
const char *archive_name, char *op)
|
const char *archive_name, char *op)
|
||||||
{
|
{
|
||||||
char *host, *user, *password;
|
|
||||||
int port;
|
|
||||||
|
|
||||||
(void) archive_name;
|
(void) archive_name;
|
||||||
|
|
||||||
ftpfs_split_url (strchr (op, ':') + 1, &host, &user, &port, &password);
|
|
||||||
|
|
||||||
super->data = g_new0 (ftp_super_data_t, 1);
|
super->data = g_new0 (ftp_super_data_t, 1);
|
||||||
SUP->host = host;
|
|
||||||
SUP->user = user;
|
super->url = ftpfs_split_url (strchr (op, ':') + 1);
|
||||||
SUP->port = port;
|
SUP->proxy = NULL;
|
||||||
SUP->cwdir = NULL;
|
if (ftpfs_check_proxy (super->url->host))
|
||||||
SUP->proxy = 0;
|
|
||||||
if (ftpfs_check_proxy (host))
|
|
||||||
SUP->proxy = ftpfs_proxy_host;
|
SUP->proxy = ftpfs_proxy_host;
|
||||||
SUP->password = password;
|
|
||||||
SUP->use_passive_connection = ftpfs_use_passive_connections;
|
SUP->use_passive_connection = ftpfs_use_passive_connections;
|
||||||
SUP->strict = ftpfs_use_unix_list_options ? RFC_AUTODETECT : RFC_STRICT;
|
SUP->strict = ftpfs_use_unix_list_options ? RFC_AUTODETECT : RFC_STRICT;
|
||||||
SUP->isbinary = TYPE_UNKNOWN;
|
SUP->isbinary = TYPE_UNKNOWN;
|
||||||
@ -1003,22 +982,21 @@ static int
|
|||||||
ftpfs_archive_same (struct vfs_class *me, struct vfs_s_super *super,
|
ftpfs_archive_same (struct vfs_class *me, struct vfs_s_super *super,
|
||||||
const char *archive_name, char *op, void *cookie)
|
const char *archive_name, char *op, void *cookie)
|
||||||
{
|
{
|
||||||
char *host, *user;
|
vfs_url_t *url;
|
||||||
int port;
|
int result;
|
||||||
|
|
||||||
(void) me;
|
(void) me;
|
||||||
(void) archive_name;
|
(void) archive_name;
|
||||||
(void) cookie;
|
(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)
|
result = ((strcmp (url->host, super->url->host) == 0)
|
||||||
&& (port == SUP->port));
|
&& (strcmp (url->user, super->url->user) == 0)
|
||||||
|
&& (url->port == super->url->port)) ? 1 : 0;
|
||||||
|
|
||||||
g_free (host);
|
vfs_url_free (url);
|
||||||
g_free (user);
|
return result;
|
||||||
|
|
||||||
return port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -1149,10 +1127,7 @@ ftpfs_setup_passive_epsv (struct vfs_class *me, struct vfs_s_super *super,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connect (my_socket, (struct sockaddr *) sa, *salen) < 0)
|
return (connect (my_socket, (struct sockaddr *) sa, *salen) < 0) ? 0 : 1;
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 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));
|
vfs_print_message (_("ftpfs: could not create socket: %s"), unix_error_string (errno));
|
||||||
return -1;
|
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)
|
if (SUP->use_passive_connection)
|
||||||
{
|
{
|
||||||
int data_sock;
|
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)
|
if (data_sock < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1333,24 +1308,22 @@ ftpfs_initconn (struct vfs_class *me, struct vfs_s_super *super)
|
|||||||
if (!SUP->use_passive_connection)
|
if (!SUP->use_passive_connection)
|
||||||
{
|
{
|
||||||
int data_sock;
|
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)
|
if (data_sock < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((bind (data_sock, (struct sockaddr *) &data_addr, data_addrlen) == 0) &&
|
if ((bind (data_sock, (struct sockaddr *) &data_addr, data_addrlen) == 0) &&
|
||||||
(getsockname (data_sock, (struct sockaddr *) &data_addr, &data_addrlen) == 0) &&
|
(getsockname (data_sock, (struct sockaddr *) &data_addr, &data_addrlen) == 0) &&
|
||||||
(listen (data_sock, 1) == 0))
|
(listen (data_sock, 1) == 0) &&
|
||||||
{
|
(ftpfs_setup_active (me, super, data_addr, data_addrlen) != 0))
|
||||||
if (ftpfs_setup_active (me, super, data_addr, data_addrlen))
|
return data_sock;
|
||||||
return data_sock;
|
|
||||||
}
|
|
||||||
|
|
||||||
close (data_sock);
|
close (data_sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the initial value of use_passive_connection (for subsequent retries) */
|
/* 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_use_passive_connections;
|
||||||
|
|
||||||
ftpfs_errno = EIO;
|
ftpfs_errno = EIO;
|
||||||
@ -1413,7 +1386,7 @@ ftpfs_open_data_connection (struct vfs_class *me, struct vfs_s_super *super, con
|
|||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void
|
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;
|
struct vfs_s_super *super = FH_SUPER;
|
||||||
static unsigned char const ipbuf[3] = { IAC, IP, IAC };
|
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
|
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;
|
int h, sock, n_read, n_written;
|
||||||
off_t n_stored;
|
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
|
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;
|
char *name;
|
||||||
|
|
||||||
@ -1900,7 +1873,7 @@ ftpfs_linear_start (struct vfs_class *me, vfs_file_handler_t *fh, off_t offset)
|
|||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int
|
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;
|
ssize_t n;
|
||||||
struct vfs_s_super *super = FH_SUPER;
|
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
|
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)
|
if (FH_SOCK != -1)
|
||||||
ftpfs_linear_abort (me, fh);
|
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;
|
(void) me;
|
||||||
|
|
||||||
if (!SUP->cwdir)
|
if (super->url->path == NULL)
|
||||||
return 0;
|
return FALSE;
|
||||||
if (strcmp (path, SUP->cwdir) == 0)
|
return (strcmp (path, super->url->path) == 0);
|
||||||
return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
@ -2071,13 +2042,11 @@ ftpfs_chdir_internal (struct vfs_class *me, struct vfs_s_super *super, const cha
|
|||||||
g_free (p);
|
g_free (p);
|
||||||
|
|
||||||
if (r != COMPLETE)
|
if (r != COMPLETE)
|
||||||
{
|
|
||||||
ftpfs_errno = EIO;
|
ftpfs_errno = EIO;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_free (SUP->cwdir);
|
g_free (super->url->path);
|
||||||
SUP->cwdir = g_strdup (remote_path);
|
super->url->path = g_strdup (remote_path);
|
||||||
SUP->cwd_deferred = 0;
|
SUP->cwd_deferred = 0;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
@ -2113,7 +2082,7 @@ ftpfs_rmdir (struct vfs_class *me, const char *path)
|
|||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static int
|
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;
|
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
|
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)
|
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;
|
const struct vfs_s_super *super = (const struct vfs_s_super *) iter->data;
|
||||||
char *name;
|
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);
|
func (name);
|
||||||
g_free (name);
|
g_free (name);
|
||||||
}
|
}
|
||||||
@ -2252,7 +2222,6 @@ ftpfs_netrc_next (void)
|
|||||||
"login", "password", "passwd", "account", "macdef", NULL
|
"login", "password", "passwd", "account", "macdef", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
netrcp = skip_separators (netrcp);
|
netrcp = skip_separators (netrcp);
|
||||||
@ -2286,15 +2255,10 @@ ftpfs_netrc_next (void)
|
|||||||
if (!*buffer)
|
if (!*buffer)
|
||||||
return NETRC_NONE;
|
return NETRC_NONE;
|
||||||
|
|
||||||
i = NETRC_DEFAULT;
|
for (i = NETRC_DEFAULT; keywords[i - 1] != NULL; i++)
|
||||||
while (keywords[i - 1])
|
if (strcmp (keywords[i - 1], buffer) == 0)
|
||||||
{
|
|
||||||
if (!strcmp (keywords[i - 1], buffer))
|
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NETRC_UNKNOWN;
|
return NETRC_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2407,11 +2371,10 @@ ftpfs_netrc_lookup (const char *host, char **login, char **pass)
|
|||||||
} *rup_cache = NULL, *rupp;
|
} *rup_cache = NULL, *rupp;
|
||||||
|
|
||||||
/* Initialize *login and *pass */
|
/* Initialize *login and *pass */
|
||||||
if (!login)
|
g_free (*login);
|
||||||
return 0;
|
|
||||||
*login = NULL;
|
*login = NULL;
|
||||||
if (pass)
|
g_free (*pass);
|
||||||
*pass = NULL;
|
*pass = NULL;
|
||||||
|
|
||||||
/* Look up in the cache first */
|
/* Look up in the cache first */
|
||||||
for (rupp = rup_cache; rupp != NULL; rupp = rupp->next)
|
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 = g_new (struct rupcache, 1);
|
||||||
rupp->host = g_strdup (host);
|
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;
|
rupp->next = rup_cache;
|
||||||
rup_cache = rupp;
|
rup_cache = rupp;
|
||||||
|
|
||||||
if (pass)
|
*pass = tmp_pass;
|
||||||
*pass = tmp_pass;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -84,11 +84,6 @@ extern FILE *dbf;
|
|||||||
#define CNV_LANG(s) dos_to_unix(s,False)
|
#define CNV_LANG(s) dos_to_unix(s,False)
|
||||||
#define GNAL_VNC(s) unix_to_dos(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? */
|
#define smbfs_lstat smbfs_stat /* no symlinks on smb filesystem? */
|
||||||
|
|
||||||
/*** file scope type declarations ****************************************************************/
|
/*** file scope type declarations ****************************************************************/
|
||||||
@ -1324,42 +1319,46 @@ smbfs_open_link (char *host, char *path, const char *user, int *port, char *this
|
|||||||
static char *
|
static char *
|
||||||
smbfs_get_path (smbfs_connection ** sc, const char *path)
|
smbfs_get_path (smbfs_connection ** sc, const char *path)
|
||||||
{
|
{
|
||||||
char *user, *host, *remote_path, *pass;
|
char *remote_path = NULL;
|
||||||
int port = SMB_PORT;
|
vfs_url_t *url;
|
||||||
|
|
||||||
DEBUG (3, ("smbfs_get_path(%s)\n", path));
|
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;
|
return NULL;
|
||||||
path += HEADER_LEN;
|
path += HEADER_LEN;
|
||||||
|
|
||||||
if (*path == '/') /* '/' leading server name */
|
if (*path == '/') /* '/' leading server name */
|
||||||
path++; /* probably came from server browsing */
|
path++; /* probably came from server browsing */
|
||||||
|
|
||||||
if ((remote_path = smbfs_get_host_and_username (&path, &host, &user, &port, &pass)))
|
url = vfs_url_split (path, SMB_PORT, URL_FLAGS_NONE);
|
||||||
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);
|
|
||||||
|
|
||||||
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;
|
return NULL;
|
||||||
|
|
||||||
/* NOTE: tildes are deprecated. See ftpfs.c */
|
/* NOTE: tildes are deprecated. See ftpfs.c */
|
||||||
{
|
{
|
||||||
int f = !strcmp (remote_path, "/~");
|
int f = strcmp (remote_path, "/~") ? 0 : 1;
|
||||||
if (f || !strncmp (remote_path, "/~/", 3))
|
|
||||||
|
if (f != 0 || strncmp (remote_path, "/~/", 3) == 0)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
s = concat_dir_and_file ((*sc)->home, remote_path + 3 - f);
|
s = concat_dir_and_file ((*sc)->home, remote_path + 3 - f);
|
||||||
g_free (remote_path);
|
g_free (remote_path);
|
||||||
return s;
|
remote_path = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return remote_path;
|
return remote_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1942,10 +1941,9 @@ smbfs_free (vfsid id)
|
|||||||
static void
|
static void
|
||||||
smbfs_forget (const char *path)
|
smbfs_forget (const char *path)
|
||||||
{
|
{
|
||||||
char *host, *user, *p;
|
vfs_url_t *p;
|
||||||
int port;
|
|
||||||
|
|
||||||
if (strncmp (path, URL_HEADER, HEADER_LEN))
|
if (strncmp (path, URL_HEADER, HEADER_LEN) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DEBUG (3, ("smbfs_forget(path:%s)\n", path));
|
DEBUG (3, ("smbfs_forget(path:%s)\n", path));
|
||||||
@ -1954,30 +1952,29 @@ smbfs_forget (const char *path)
|
|||||||
if (path[0] == '/' && path[1] == '/')
|
if (path[0] == '/' && path[1] == '/')
|
||||||
path += 2;
|
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;
|
size_t i;
|
||||||
|
|
||||||
g_free (p);
|
|
||||||
|
|
||||||
for (i = 0; i < SMBFS_MAX_CONNECTIONS; i++)
|
for (i = 0; i < SMBFS_MAX_CONNECTIONS; i++)
|
||||||
{
|
{
|
||||||
if (smbfs_connections[i].cli
|
if (smbfs_connections[i].cli
|
||||||
&& (strcmp (host, smbfs_connections[i].host) == 0)
|
&& (strcmp (p->host, smbfs_connections[i].host) == 0)
|
||||||
&& (strcmp (user, smbfs_connections[i].user) == 0)
|
&& (strcmp (p->user, smbfs_connections[i].user) == 0)
|
||||||
&& (port == smbfs_connections[i].port))
|
&& (p->port == smbfs_connections[i].port))
|
||||||
{
|
{
|
||||||
|
|
||||||
/* close socket: the child owns it now */
|
/* close socket: the child owns it now */
|
||||||
cli_shutdown (smbfs_connections[i].cli);
|
cli_shutdown (smbfs_connections[i].cli);
|
||||||
|
|
||||||
/* reopen the connection */
|
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user