enum stype rs; /* remote system reported by ftp server */
char *id; /* initial directory */
char *target; /* target file name */
+ struct url *proxy; /* FTWK-style proxy */
} ccon;
FILE *fp;
char *user, *passwd, *respline;
char *tms, *tmrate;
- unsigned char pasv_addr[6];
int cmd = con->cmd;
- int passive_mode_open = 0;
+ int pasv_mode_open = 0;
long expected_bytes = 0L;
assert (con != NULL);
char type_char;
struct address_list *al;
+ char *host = con->proxy ? con->proxy->host : u->host;
+ int port = con->proxy ? con->proxy->port : u->port;
+ char *logname = user;
+
+ if (con->proxy)
+ {
+ /* If proxy is in use, log in as username@target-site. */
+ logname = xmalloc (strlen (user) + 1 + strlen (u->host) + 1);
+ sprintf (logname, "%s@%s", user, u->host);
+ }
+
/* Login to the server: */
/* First: Establish the control connection. */
- al = lookup_host (u->host, 0);
+ al = lookup_host (host, 0);
if (!al)
return HOSTERR;
- set_connection_host_name (u->host);
- csock = connect_to_many (al, u->port, 0);
+ set_connection_host_name (host);
+ csock = connect_to_many (al, port, 0);
set_connection_host_name (NULL);
address_list_release (al);
logprintf (LOG_VERBOSE, _("Logging in as %s ... "), user);
if (opt.server_response)
logputs (LOG_ALWAYS, "\n");
- err = ftp_login (&con->rbuf, user, passwd);
+ err = ftp_login (&con->rbuf, logname, passwd);
+
+ if (con->proxy)
+ xfree (logname);
+
/* FTPRERR, FTPSRVERR, WRITEFAILED, FTPLOGREFUSED, FTPLOGINC */
switch (err)
{
{
if (opt.ftp_pasv > 0)
{
+ ip_address passive_addr;
+ unsigned short passive_port;
if (!opt.server_response)
logputs (LOG_VERBOSE, "==> PASV ... ");
- err = ftp_pasv (&con->rbuf, pasv_addr);
+ err = ftp_pasv (&con->rbuf, &passive_addr, &passive_port);
/* FTPRERR, WRITEFAILED, FTPNOPASV, FTPINVPASV */
switch (err)
{
default:
abort ();
break;
- }
+ } /* switch(err) */
if (err==FTPOK)
{
- unsigned short tport;
-
- tport = (pasv_addr[4] << 8) + pasv_addr[5];
- dtsock = connect_to_one (pasv_addr, tport, 1);
-
+ dtsock = connect_to_one (&passive_addr, passive_port, 1);
if (dtsock < 0)
{
int save_errno = errno;
CLOSE (csock);
rbuf_uninitialize (&con->rbuf);
logprintf (LOG_VERBOSE, _("couldn't connect to %s:%hu: %s\n"),
- pretty_print_address (pasv_addr), tport,
+ pretty_print_address (&passive_addr), passive_port,
strerror (save_errno));
return save_errno == ECONNREFUSED ? CONREFUSED : CONERROR;
}
- passive_mode_open = 1; /* Flag to avoid accept port */
+ pasv_mode_open = 1; /* Flag to avoid accept port */
if (!opt.server_response)
logputs (LOG_VERBOSE, _("done. "));
} /* err==FTP_OK */
}
- if (!passive_mode_open) /* Try to use a port command if PASV failed */
+ if (!pasv_mode_open) /* Try to use a port command if PASV failed */
{
if (!opt.server_response)
logputs (LOG_VERBOSE, "==> PORT ... ");
if (!(cmd & (DO_LIST | DO_RETR)))
return RETRFINISHED;
- if (!passive_mode_open) /* we are not using pasive mode so we need
+ if (!pasv_mode_open) /* we are not using pasive mode so we need
to accept */
{
/* Open the data transmission socket by calling acceptport(). */
/* Else, get it from the file. */
local_size = st.st_size;
tml = st.st_mtime;
+#ifdef WINDOWS
+ /* Modification time granularity is 2 seconds for Windows, so
+ increase local time by 1 second for later comparison. */
+ tml++;
+#endif
/* Compare file sizes only for servers that tell us correct
values. Assumme sizes being equal for servers that lie
about file size. */
of URL. Inherently, its capabilities are limited on what can be
encoded into a URL. */
uerr_t
-ftp_loop (struct url *u, int *dt)
+ftp_loop (struct url *u, int *dt, struct url *proxy)
{
ccon con; /* FTP connection */
uerr_t res;
con.st = ON_YOUR_OWN;
con.rs = ST_UNIX;
con.id = NULL;
+ con.proxy = proxy;
res = RETROK; /* in case it's not used */
/* If the file name is empty, the user probably wants a directory
/* ftp_retrieve_glob is a catch-all function that gets called
if we need globbing, time-stamping or recursion. Its
third argument is just what we really need. */
- ftp_retrieve_glob (u, &con,
- (opt.ftp_glob && wild) ? GLOBALL : GETONE);
+ res = ftp_retrieve_glob (u, &con,
+ (opt.ftp_glob && wild) ? GLOBALL : GETONE);
}
else
res = ftp_loop_internal (u, NULL, &con);