#endif
#include <sys/types.h>
-/* For inet_ntop. */
-#ifndef WINDOWS
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif
-
-#ifdef WINDOWS
-# include <winsock.h>
-#endif
-
#include "wget.h"
#include "utils.h"
#include "rbuf.h"
return res;
}
-#ifdef USE_OPIE
-const char *calculate_skey_response PARAMS ((int, const char *, const char *));
-#endif
-
/* Sends the USER and PASS commands to the server, to control
connection socket csock. */
uerr_t
xfree (respline);
/* Send USER username. */
request = ftp_request ("USER", acc);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
"331 opiekey "
};
int i;
+ const char *seed = NULL;
for (i = 0; i < countof (skey_head); i++)
{
- if (strncasecmp (skey_head[i], respline, strlen (skey_head[i])) == 0)
- break;
+ int l = strlen (skey_head[i]);
+ if (0 == strncasecmp (skey_head[i], respline, l))
+ {
+ seed = respline + l;
+ break;
+ }
}
- if (i < countof (skey_head))
+ if (seed)
{
- const char *cp;
int skey_sequence = 0;
- for (cp = respline + strlen (skey_head[i]);
- '0' <= *cp && *cp <= '9';
- cp++)
- {
- skey_sequence = skey_sequence * 10 + *cp - '0';
- }
- if (*cp == ' ')
- cp++;
+ /* Extract the sequence from SEED. */
+ for (; ISDIGIT (*seed); seed++)
+ skey_sequence = 10 * skey_sequence + *seed - '0';
+ if (*seed == ' ')
+ ++seed;
else
{
- bad:
xfree (respline);
return FTPLOGREFUSED;
}
- if ((cp = calculate_skey_response (skey_sequence, cp, pass)) == 0)
- goto bad;
- pass = cp;
+ /* Replace the password with the SKEY response to the
+ challenge. */
+ pass = skey_response (skey_sequence, seed, pass);
}
}
#endif /* USE_OPIE */
xfree (respline);
/* Send PASS password. */
request = ftp_request ("PASS", pass);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
}
static void
-ip_address_to_port_repr (const ip_address *addr, unsigned short port, char *buf,
+ip_address_to_port_repr (const ip_address *addr, int port, char *buf,
size_t buflen)
{
unsigned char *ptr;
ptr = ADDRESS_IPV4_DATA (addr);
snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d", ptr[0], ptr[1],
- ptr[2], ptr[3], (unsigned) (port & 0xff00) >> 8, port & 0xff);
+ ptr[2], ptr[3], (port & 0xff00) >> 8, port & 0xff);
buf[buflen - 1] = '\0';
}
server. Use acceptport after RETR, to get the socket of data
connection. */
uerr_t
-ftp_port (struct rbuf *rbuf)
+ftp_port (struct rbuf *rbuf, int *local_sock)
{
uerr_t err;
char *request, *respline;
ip_address addr;
int nwritten;
- unsigned short port;
+ int port;
/* Must contain the argument of PORT (of the form a,b,c,d,e,f). */
char bytes[6 * 4 + 1];
assert (rbuf_initialized_p (rbuf));
/* Get the address of this side of the connection. */
- if (!conaddr (RBUF_FD (rbuf), &addr))
- return BINDERR;
+ if (!socket_ip_address (RBUF_FD (rbuf), &addr, ENDPOINT_LOCAL))
+ return FTPSYSERR;
assert (addr.type == IPV4_ADDRESS);
port = 0;
/* Bind the port. */
- err = bindport (&addr, &port);
- if (err != BINDOK)
- return err;
+ *local_sock = bind_local (&addr, &port);
+ if (*local_sock < 0)
+ return FTPSYSERR;
/* Construct the argument of PORT (of the form a,b,c,d,e,f). */
ip_address_to_port_repr (&addr, port, bytes, sizeof (bytes));
/* Send PORT request. */
request = ftp_request ("PORT", bytes);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
- closeport (-1);
+ xclose (*local_sock);
return WRITEFAILED;
}
xfree (request);
if (err != FTPOK)
{
xfree (respline);
- closeport (-1);
+ xclose (*local_sock);
return err;
}
if (*respline != '2')
{
xfree (respline);
- closeport (-1);
+ xclose (*local_sock);
return FTPPORTERR;
}
xfree (respline);
#ifdef ENABLE_IPV6
static void
-ip_address_to_lprt_repr (const ip_address *addr, unsigned short port, char *buf,
+ip_address_to_lprt_repr (const ip_address *addr, int port, char *buf,
size_t buflen)
{
unsigned char *ptr;
ptr = ADDRESS_IPV4_DATA (addr);
snprintf (buf, buflen, "%d,%d,%d,%d,%d,%d,%d,%d,%d", 4, 4,
ptr[0], ptr[1], ptr[2], ptr[3], 2,
- (unsigned) (port & 0xff00) >> 8, port & 0xff);
+ (port & 0xff00) >> 8, port & 0xff);
buf[buflen - 1] = '\0';
break;
case IPV6_ADDRESS:
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[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15], 2,
- (unsigned) (port & 0xff00) >> 8, port & 0xff);
+ (port & 0xff00) >> 8, port & 0xff);
buf[buflen - 1] = '\0';
break;
}
server. Use acceptport after RETR, to get the socket of data
connection. */
uerr_t
-ftp_lprt (struct rbuf *rbuf)
+ftp_lprt (struct rbuf *rbuf, int *local_sock)
{
uerr_t err;
char *request, *respline;
ip_address addr;
int nwritten;
- unsigned short port;
+ int port;
/* Must contain the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */
char bytes[21 * 4 + 1];
assert (rbuf_initialized_p (rbuf));
/* Get the address of this side of the connection. */
- if (!conaddr (RBUF_FD (rbuf), &addr))
- return BINDERR;
+ if (!socket_ip_address (RBUF_FD (rbuf), &addr, ENDPOINT_LOCAL))
+ return FTPSYSERR;
assert (addr.type == IPV4_ADDRESS || addr.type == IPV6_ADDRESS);
port = 0;
/* Bind the port. */
- err = bindport (&addr, &port);
- if (err != BINDOK)
- return err;
+ *local_sock = bind_local (&addr, &port);
+ if (*local_sock < 0)
+ return FTPSYSERR;
/* Construct the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */
ip_address_to_lprt_repr (&addr, port, bytes, sizeof (bytes));
/* Send PORT request. */
request = ftp_request ("LPRT", bytes);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
- closeport (-1);
+ xclose (*local_sock);
return WRITEFAILED;
}
xfree (request);
if (err != FTPOK)
{
xfree (respline);
- closeport (-1);
+ xclose (*local_sock);
return err;
}
if (*respline != '2')
{
xfree (respline);
- closeport (-1);
+ xclose (*local_sock);
return FTPPORTERR;
}
xfree (respline);
}
static void
-ip_address_to_eprt_repr (const ip_address *addr, unsigned short port, char *buf,
+ip_address_to_eprt_repr (const ip_address *addr, int port, char *buf,
size_t buflen)
{
int afnum;
server. Use acceptport after RETR, to get the socket of data
connection. */
uerr_t
-ftp_eprt (struct rbuf *rbuf)
+ftp_eprt (struct rbuf *rbuf, int *local_sock)
{
uerr_t err;
char *request, *respline;
ip_address addr;
int nwritten;
- unsigned short port;
+ int port;
/* Must contain the argument of EPRT (of the form |af|addr|port|).
* 4 chars for the | separators, ENABLE_IPV6_ADDRSTRLEN chars for addr
* 1 char for af (1-2) and 5 chars for port (0-65535) */
assert (rbuf_initialized_p(rbuf));
/* Get the address of this side of the connection. */
- if (!conaddr (RBUF_FD (rbuf), &addr))
- return BINDERR;
+ if (!socket_ip_address (RBUF_FD (rbuf), &addr, ENDPOINT_LOCAL))
+ return FTPSYSERR;
assert (addr.type == IPV4_ADDRESS || addr.type == IPV6_ADDRESS);
port = 0;
/* Bind the port. */
- err = bindport (&addr, &port);
- if (err != BINDOK)
- return err;
+ *local_sock = bind_local (&addr, &port);
+ if (*local_sock < 0)
+ return FTPSYSERR;
/* Construct the argument of LPRT (of the form af,n,h1,h2,...,hn,p1,p2). */
ip_address_to_eprt_repr (&addr, port, bytes, sizeof (bytes));
/* Send PORT request. */
request = ftp_request ("EPRT", bytes);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
- closeport (-1);
+ xclose (*local_sock);
return WRITEFAILED;
}
xfree (request);
if (err != FTPOK)
{
xfree (respline);
- closeport (-1);
+ xclose (*local_sock);
return err;
}
if (*respline != '2')
{
xfree (respline);
- closeport (-1);
+ xclose (*local_sock);
return FTPPORTERR;
}
xfree (respline);
transfer. Reads the response from server and parses it. Reads the
host and port addresses and returns them. */
uerr_t
-ftp_pasv (struct rbuf *rbuf, ip_address *addr, unsigned short *port)
+ftp_pasv (struct rbuf *rbuf, ip_address *addr, int *port)
{
char *request, *respline, *s;
int nwritten, i;
/* Form the request. */
request = ftp_request ("PASV", NULL);
/* And send it. */
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
transfer. Reads the response from server and parses it. Reads the
host and port addresses and returns them. */
uerr_t
-ftp_lpsv (struct rbuf *rbuf, ip_address *addr, unsigned short *port)
+ftp_lpsv (struct rbuf *rbuf, ip_address *addr, int *port)
{
char *request, *respline, *s;
int nwritten, i, af, addrlen, portlen;
request = ftp_request ("LPSV", NULL);
/* And send it. */
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
transfer. Reads the response from server and parses it. Reads the
host and port addresses and returns them. */
uerr_t
-ftp_epsv (struct rbuf *rbuf, ip_address *addr, unsigned short *port)
+ftp_epsv (struct rbuf *rbuf, ip_address *ip, int *port)
{
char *request, *respline, *start, delim, *s;
int nwritten, i;
uerr_t err;
- unsigned short tport;
- socklen_t addrlen;
- struct sockaddr_storage ss;
- struct sockaddr *sa = (struct sockaddr *)&ss;
+ int tport;
assert (rbuf != NULL);
assert (rbuf_initialized_p(rbuf));
- assert (addr != NULL);
+ assert (ip != NULL);
assert (port != NULL);
- addrlen = sizeof (ss);
- if (getpeername (rbuf->fd, sa, &addrlen) < 0)
- /* Mauro Tortonesi: HOW DO WE HANDLE THIS ERROR? */
- return CONPORTERR;
-
- assert (sa->sa_family == AF_INET || sa->sa_family == AF_INET6);
-
- sockaddr_get_address (sa, NULL, addr);
+ /* IP already contains the IP address of the control connection's
+ peer, so we don't need to call socket_ip_address here. */
/* Form the request. */
/* EPSV 1 means that we ask for IPv4 and EPSV 2 means that we ask for IPv6. */
- request = ftp_request ("EPSV", (sa->sa_family == AF_INET ? "1" : "2"));
+ request = ftp_request ("EPSV", (ip->type == IPV4_ADDRESS ? "1" : "2"));
/* And send it. */
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
stype[1] = 0;
/* Send TYPE request. */
request = ftp_request ("TYPE", stype);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
/* Send CWD request. */
request = ftp_request ("CWD", dir);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
number_to_string (numbuf, offset);
request = ftp_request ("REST", numbuf);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
/* Send RETR request. */
request = ftp_request ("RETR", file);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
/* Send LIST request. */
request = ftp_request ("LIST", file);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
/* Send SYST request. */
request = ftp_request ("SYST", NULL);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
*server_type = ST_VMS;
else if (!strcasecmp (request, "UNIX"))
*server_type = ST_UNIX;
- else if (!strcasecmp (request, "WINDOWS_NT"))
+ else if (!strcasecmp (request, "WINDOWS_NT")
+ || !strcasecmp (request, "WINDOWS2000"))
*server_type = ST_WINNT;
else if (!strcasecmp (request, "MACOS"))
*server_type = ST_MACOS;
/* Send PWD request. */
request = ftp_request ("PWD", NULL);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);
request = strtok (NULL, "\"");
/* Has the `pwd' been already allocated? Free! */
- FREE_MAYBE (*pwd);
+ xfree_null (*pwd);
*pwd = xstrdup (request);
/* Send PWD request. */
request = ftp_request ("SIZE", file);
- nwritten = iwrite (RBUF_FD (rbuf), request, strlen (request));
+ nwritten = xwrite (RBUF_FD (rbuf), request, strlen (request), -1);
if (nwritten < 0)
{
xfree (request);