X-Git-Url: http://sjero.net/git/?a=blobdiff_plain;f=src%2Fftp-basic.c;h=7a512c6ed607478ea39373c88196ba773aa07a29;hb=8624553a31b148f9051cc11725bc01d9760fa07b;hp=4920f72523052679d049103bf4d04e8f2f55654f;hpb=68740f10dd55cb272bcad0bd0c5199bbdef5b26e;p=wget
diff --git a/src/ftp-basic.c b/src/ftp-basic.c
index 4920f725..7a512c6e 100644
--- a/src/ftp-basic.c
+++ b/src/ftp-basic.c
@@ -1,6 +1,7 @@
/* Basic FTP routines.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+ 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+ Inc.
This file is part of GNU Wget.
@@ -17,17 +18,18 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Wget. If not, see .
-In addition, as a special exception, the Free Software Foundation
-gives permission to link the code of its release of Wget with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version. */
+Additional permission under GNU GPL version 3 section 7
-#include
+If you modify this program, or any covered work, by linking or
+combining it with the OpenSSL project's OpenSSL library (or a
+modified version of that library), containing parts covered by the
+terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
+grants you additional permission to convey the resulting work.
+Corresponding Source for a non-source form of such a combination
+shall include the source code for the parts of OpenSSL used as well
+as that of the covered work. */
+
+#include "wget.h"
#include
#include
@@ -35,11 +37,7 @@ so, delete this exception statement from your version. */
#include
#include
-#ifdef HAVE_UNISTD_H
-# include
-#endif
-
-#include "wget.h"
+#include
#include "utils.h"
#include "connect.h"
#include "host.h"
@@ -69,7 +67,7 @@ ftp_response (int fd, char **ret_line)
return FTPRERR;
/* Strip trailing CRLF before printing the line, so that
- escnonprint doesn't include bogus \012 and \015. */
+ quotting doesn't include bogus \012 and \015. */
p = strchr (line, '\0');
if (p > line && p[-1] == '\n')
*--p = '\0';
@@ -77,9 +75,10 @@ ftp_response (int fd, char **ret_line)
*--p = '\0';
if (opt.server_response)
- logprintf (LOG_NOTQUIET, "%s\n", escnonprint (line));
+ logprintf (LOG_NOTQUIET, "%s\n",
+ quotearg_style (escape_quoting_style, line));
else
- DEBUGP (("%s\n", escnonprint (line)));
+ DEBUGP (("%s\n", quotearg_style (escape_quoting_style, line)));
/* The last line of output is the one that begins with "ddd ". */
if (c_isdigit (line[0]) && c_isdigit (line[1]) && c_isdigit (line[2])
@@ -117,7 +116,8 @@ ftp_request (const char *command, const char *value)
if (*p == '\r' || *p == '\n')
*p = ' ';
DEBUGP (("\nDetected newlines in %s \"%s\"; changing to %s \"%s\"\n",
- command, escnonprint (value), command, escnonprint (defanged)));
+ command, quotearg_style (escape_quoting_style, value),
+ command, quotearg_style (escape_quoting_style, defanged)));
/* Make VALUE point to the defanged copy of the string. */
value = defanged;
}
@@ -188,7 +188,7 @@ ftp_login (int csock, const char *acc, const char *pass)
"331 s/key ",
"331 opiekey "
};
- int i;
+ size_t i;
const char *seed = NULL;
for (i = 0; i < countof (skey_head); i++)
@@ -245,7 +245,7 @@ ftp_login (int csock, const char *acc, const char *pass)
}
static void
-ip_address_to_port_repr (const ip_address *addr, int port, char *buf,
+ip_address_to_port_repr (const ip_address *addr, int port, char *buf,
size_t buflen)
{
unsigned char *ptr;
@@ -321,7 +321,7 @@ ftp_port (int csock, int *local_sock)
#ifdef ENABLE_IPV6
static void
-ip_address_to_lprt_repr (const ip_address *addr, int port, char *buf,
+ip_address_to_lprt_repr (const ip_address *addr, int port, char *buf,
size_t buflen)
{
unsigned char *ptr = IP_INADDR_DATA (addr);
@@ -330,18 +330,18 @@ ip_address_to_lprt_repr (const ip_address *addr, int port, char *buf,
assert (buflen >= 21 * 4);
/* Construct the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */
- switch (addr->family)
+ switch (addr->family)
{
- case AF_INET:
- snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 4, 4,
+ case AF_INET:
+ snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 4, 4,
ptr[0], ptr[1], ptr[2], ptr[3], 2,
(port & 0xff00) >> 8, port & 0xff);
break;
- case AF_INET6:
+ case AF_INET6:
snprintf (buf, buflen,
"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
6, 16,
- ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7],
+ ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7],
ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15],
2, (port & 0xff00) >> 8, port & 0xff);
break;
@@ -409,15 +409,15 @@ ftp_lprt (int csock, int *local_sock)
}
static void
-ip_address_to_eprt_repr (const ip_address *addr, int port, char *buf,
+ip_address_to_eprt_repr (const ip_address *addr, int port, char *buf,
size_t buflen)
{
int afnum;
- /* buf must contain the argument of EPRT (of the form |af|addr|port|).
- * 4 chars for the | separators, INET6_ADDRSTRLEN chars for addr
+ /* buf must contain the argument of EPRT (of the form |af|addr|port|).
+ * 4 chars for the | separators, INET6_ADDRSTRLEN chars for addr
* 1 char for af (1-2) and 5 chars for port (0-65535) */
- assert (buflen >= 4 + INET6_ADDRSTRLEN + 1 + 5);
+ assert (buflen >= 4 + INET6_ADDRSTRLEN + 1 + 5);
/* Construct the argument of EPRT (of the form |af|addr|port|). */
afnum = (addr->family == AF_INET ? 1 : 2);
@@ -436,8 +436,8 @@ ftp_eprt (int csock, int *local_sock)
ip_address addr;
int nwritten;
int port;
- /* Must contain the argument of EPRT (of the form |af|addr|port|).
- * 4 chars for the | separators, INET6_ADDRSTRLEN chars for addr
+ /* Must contain the argument of EPRT (of the form |af|addr|port|).
+ * 4 chars for the | separators, INET6_ADDRSTRLEN chars for addr
* 1 char for af (1-2) and 5 chars for port (0-65535) */
char bytes[4 + INET6_ADDRSTRLEN + 1 + 5 + 1];
@@ -524,7 +524,10 @@ ftp_pasv (int csock, ip_address *addr, int *port)
for (s += 4; *s && !c_isdigit (*s); s++)
;
if (!*s)
- return FTPINVPASV;
+ {
+ xfree (respline);
+ return FTPINVPASV;
+ }
for (i = 0; i < 6; i++)
{
tmp[i] = 0;
@@ -586,14 +589,17 @@ ftp_lpsv (int csock, ip_address *addr, int *port)
{
xfree (respline);
return FTPNOPASV;
- }
+ }
/* Parse the response. */
s = respline;
for (s += 4; *s && !c_isdigit (*s); s++)
;
if (!*s)
- return FTPINVPASV;
+ {
+ xfree (respline);
+ return FTPINVPASV;
+ }
/* First, get the address family */
af = 0;
@@ -749,22 +755,19 @@ ftp_epsv (int csock, ip_address *ip, int *port)
{
xfree (respline);
return FTPNOPASV;
- }
+ }
assert (respline != NULL);
DEBUGP(("respline is %s\n", respline));
- /* Parse the response. */
- s = respline;
-
/* Skip the useless stuff and get what's inside the parentheses */
start = strchr (respline, '(');
if (start == NULL)
{
xfree (respline);
return FTPINVPASV;
- }
+ }
/* Skip the first two void fields */
s = start + 1;
@@ -773,26 +776,26 @@ ftp_epsv (int csock, ip_address *ip, int *port)
{
xfree (respline);
return FTPINVPASV;
- }
+ }
for (i = 0; i < 2; i++)
{
- if (*s++ != delim)
+ if (*s++ != delim)
{
xfree (respline);
return FTPINVPASV;
- }
+ }
}
/* Finally, get the port number */
- tport = 0;
- for (i = 1; c_isdigit (*s); s++)
+ tport = 0;
+ for (i = 1; c_isdigit (*s); s++)
{
if (i > 5)
{
xfree (respline);
return FTPINVPASV;
- }
+ }
tport = (*s - '0') + 10 * tport;
}
@@ -801,13 +804,13 @@ ftp_epsv (int csock, ip_address *ip, int *port)
{
xfree (respline);
return FTPINVPASV;
- }
+ }
- if (*s++ != ')')
+ if (*s != ')')
{
xfree (respline);
return FTPINVPASV;
- }
+ }
*port = tport;
@@ -957,17 +960,33 @@ ftp_retr (int csock, const char *file)
/* Sends the LIST command to the server. If FILE is NULL, send just
`LIST' (no space). */
uerr_t
-ftp_list (int csock, const char *file)
+ftp_list (int csock, const char *file, bool avoid_list_a, bool avoid_list,
+ bool *list_a_used)
{
char *request, *respline;
int nwritten;
uerr_t err;
bool ok = false;
- int i = 0;
- /* Try `LIST -a' first and revert to `LIST' in case of failure. */
- const char *list_commands[] = { "LIST -a",
+ size_t i = 0;
+
+ *list_a_used = false;
+
+ /* 2013-10-12 Andrea Urbani (matfanjol)
+ For more information about LIST and "LIST -a" please look at ftp.c,
+ function getftp, text "__LIST_A_EXPLANATION__".
+
+ If somebody changes the following commands, please, checks also the
+ later "i" variable. */
+ const char *list_commands[] = { "LIST -a",
"LIST" };
+ if (avoid_list_a)
+ {
+ i = countof (list_commands)- 1;
+ DEBUGP (("(skipping \"LIST -a\")"));
+ }
+
+
do {
/* Send request. */
request = ftp_request (list_commands[i], file);
@@ -990,22 +1009,30 @@ ftp_list (int csock, const char *file)
{
err = FTPOK;
ok = true;
+ /* Which list command was used? */
+ *list_a_used = (i == 0);
}
- else
+ else
{
err = FTPRERR;
}
xfree (respline);
}
++i;
+ if ((avoid_list) && (i == 1))
+ {
+ /* I skip LIST */
+ ++i;
+ DEBUGP (("(skipping \"LIST\")"));
+ }
} while (i < countof (list_commands) && !ok);
-
+
return err;
}
/* Sends the SYST command to the server. */
uerr_t
-ftp_syst (int csock, enum stype *server_type)
+ftp_syst (int csock, enum stype *server_type, enum ustype *unix_type)
{
char *request, *respline;
int nwritten;
@@ -1038,12 +1065,23 @@ ftp_syst (int csock, enum stype *server_type)
first word of the server response)? */
request = strtok (NULL, " ");
+ *unix_type = UST_OTHER;
+
if (request == NULL)
*server_type = ST_OTHER;
else if (!strcasecmp (request, "VMS"))
*server_type = ST_VMS;
else if (!strcasecmp (request, "UNIX"))
- *server_type = ST_UNIX;
+ {
+ *server_type = ST_UNIX;
+ /* 2013-10-17 Andrea Urbani (matfanjol)
+ I check more in depth the system type */
+ if (!strncasecmp (ftp_last_respline, "215 UNIX Type: L8", 17))
+ *unix_type = UST_TYPE_L8;
+ else if (!strncasecmp (ftp_last_respline,
+ "215 UNIX MultiNet Unix Emulation V5.3(93)", 41))
+ *unix_type = UST_MULTINET;
+ }
else if (!strcasecmp (request, "WINDOWS_NT")
|| !strcasecmp (request, "WINDOWS2000"))
*server_type = ST_WINNT;
@@ -1134,9 +1172,9 @@ ftp_size (int csock, const char *file, wgint *size)
}
if (*respline == '5')
{
- /*
+ /*
* Probably means SIZE isn't supported on this server.
- * Error is nonfatal since SIZE isn't in RFC 959
+ * Error is nonfatal since SIZE isn't in RFC 959
*/
xfree (respline);
*size = 0;
@@ -1147,7 +1185,7 @@ ftp_size (int csock, const char *file, wgint *size)
*size = str_to_wgint (respline + 4, NULL, 10);
if (errno)
{
- /*
+ /*
* Couldn't parse the response for some reason. On the (few)
* tests I've done, the response is 213 with nothing else -
* maybe something a bit more resilient is necessary. It's not a