aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/ftp.c253
-rw-r--r--lib/hostip.c42
2 files changed, 170 insertions, 125 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index 012373ec5..200cddc47 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -316,6 +316,11 @@ int Curl_GetFTPResponse(int sockfd,
return nread; /* total amount of bytes read */
}
+#ifndef ENABLE_IPV6
+/*
+ * This function is only used by code that works on IPv4. When we add proper
+ * support for that functionality with IPv6, this function can go in again.
+ */
/* -- who are we? -- */
static char *getmyhost(char *buf, int buf_size)
{
@@ -333,6 +338,9 @@ static char *getmyhost(char *buf, int buf_size)
return buf;
}
+#endif /* ipv4-only function */
+
+
/* ftp_connect() should do everything that is to be considered a part
of the connection phase. */
CURLcode Curl_ftp_connect(struct connectdata *conn)
@@ -722,6 +730,129 @@ CURLcode _ftp_getsize(struct connectdata *conn, char *file,
return CURLE_OK;
}
+/***************************************************************************
+ *
+ * ftp_pasv_verbose()
+ *
+ * This function only outputs some informationals about this second connection
+ * when we've issued a PASV command before and thus we have connected to a
+ * possibly new IP address.
+ *
+ */
+static void
+ftp_pasv_verbose(struct connectdata *conn,
+#ifdef ENABLE_IPV6
+ struct addrinfo *newhost
+#else
+ char *newhost /* ipv4 */
+#endif
+)
+{
+#ifndef ENABLE_IPV6
+ /*****************************************************************
+ *
+ * IPv4-only code section
+ */
+
+ struct in_addr in;
+ struct hostent * answer;
+
+#if defined (HAVE_INET_NTOA_R)
+ char ntoa_buf[64];
+#endif
+#ifndef ENABLE_IPV6
+ struct sockaddr_in serv_addr;
+ char hostent_buf[8192];
+#endif
+
+#if defined(HAVE_INET_ADDR)
+ unsigned long address;
+# if defined(HAVE_GETHOSTBYADDR_R)
+ int h_errnop;
+# endif
+
+ address = inet_addr(newhost);
+# ifdef HAVE_GETHOSTBYADDR_R
+
+# ifdef HAVE_GETHOSTBYADDR_R_5
+ /* AIX, Digital Unix style:
+ extern int gethostbyaddr_r(char *addr, size_t len, int type,
+ struct hostent *htent, struct hostent_data *ht_data); */
+
+ /* Fred Noz helped me try this out, now it at least compiles! */
+
+ if(gethostbyaddr_r((char *) &address,
+ sizeof(address), AF_INET,
+ (struct hostent *)hostent_buf,
+ hostent_buf + sizeof(*answer)))
+ answer=NULL;
+
+# endif
+# ifdef HAVE_GETHOSTBYADDR_R_7
+ /* Solaris and IRIX */
+ answer = gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,
+ (struct hostent *)hostent_buf,
+ hostent_buf + sizeof(*answer),
+ sizeof(hostent_buf) - sizeof(*answer),
+ &h_errnop);
+# endif
+# ifdef HAVE_GETHOSTBYADDR_R_8
+ /* Linux style */
+ if(gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,
+ (struct hostent *)hostent_buf,
+ hostent_buf + sizeof(*answer),
+ sizeof(hostent_buf) - sizeof(*answer),
+ &answer,
+ &h_errnop))
+ answer=NULL; /* error */
+# endif
+
+# else
+ answer = gethostbyaddr((char *) &address, sizeof(address), AF_INET);
+# endif
+#else
+ answer = NULL;
+#endif
+ (void) memcpy(&in.s_addr, *addr->h_addr_list, sizeof (in.s_addr));
+ infof(conn->data, "Connecting to %s (%s) port %u\n",
+ answer?answer->h_name:newhost,
+#if defined(HAVE_INET_NTOA_R)
+ inet_ntoa_r(in, ip_addr=ntoa_buf, sizeof(ntoa_buf)),
+#else
+ ip_addr = inet_ntoa(in),
+#endif
+ connectport);
+
+#else
+ /*****************************************************************
+ *
+ * IPv6-only code section
+ */
+ char hbuf[NI_MAXHOST]; /* ~1KB */
+ char nbuf[NI_MAXHOST]; /* ~1KB */
+ char sbuf[NI_MAXSERV]; /* around 32 */
+#ifdef NI_WITHSCOPEID
+ const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
+#else
+ const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
+#endif
+ if (getnameinfo(newhost->ai_addr, newhost->ai_addrlen,
+ nbuf, sizeof(nbuf), sbuf, sizeof(sbuf), niflags)) {
+ snprintf(nbuf, sizeof(nbuf), "?");
+ snprintf(sbuf, sizeof(sbuf), "?");
+ }
+
+ if (getnameinfo(newhost->ai_addr, newhost->ai_addrlen,
+ hbuf, sizeof(hbuf), NULL, 0, 0)) {
+ infof(conn->data, "Connecting to %s port %s\n", nbuf, sbuf);
+ }
+ else {
+ infof(conn->data, "Connecting to %s (%s) port %s\n", hbuf, nbuf, sbuf);
+ }
+#endif
+
+}
+
static
CURLcode _ftp(struct connectdata *conn)
@@ -733,16 +864,6 @@ CURLcode _ftp(struct connectdata *conn)
char *buf = data->state.buffer; /* this is our buffer */
/* for the ftp PORT mode */
int portsock=-1;
-#if defined (HAVE_INET_NTOA_R)
- char ntoa_buf[64];
-#endif
-#ifdef ENABLE_IPV6
- struct addrinfo *ai;
-#else
- struct sockaddr_in serv_addr;
- char hostent_buf[8192];
-#endif
-
/* the ftp struct is already inited in ftp_connect() */
struct FTP *ftp = conn->proto.ftp;
@@ -901,7 +1022,7 @@ CURLcode _ftp(struct connectdata *conn)
return CURLE_FTP_PORT_FAILED;
}
- for (modep = (char *)mode; modep && *modep; modep++) {
+ for (modep = (char **)mode; modep && *modep; modep++) {
int lprtaf, eprtaf;
switch (sa->sa_family) {
@@ -1152,11 +1273,13 @@ CURLcode _ftp(struct connectdata *conn)
unsigned short connectport; /* the local port connect() should use! */
char newhost[32];
- Curl_addrinfo *he;
+ Curl_addrinfo *addr;
char *hostdataptr=NULL;
#ifndef ENABLE_IPV6
char *ip_addr;
+#else
+ struct addrinfo *ai;
#endif
char *str=buf;
@@ -1192,14 +1315,14 @@ CURLcode _ftp(struct connectdata *conn)
* proxy again here. We already have the name info for it since the
* previous lookup.
*/
- he = conn->hp;
+ addr = conn->hp;
connectport =
(unsigned short)conn->port; /* we connect to the proxy's port */
}
else {
/* normal, direct, ftp connection */
- he = Curl_getaddrinfo(data, newhost, newport, &hostdataptr);
- if(!he) {
+ addr = Curl_getaddrinfo(data, newhost, newport, &hostdataptr);
+ if(!addr) {
failf(data, "Can't resolve new host %s", newhost);
return CURLE_FTP_CANT_GET_HOST;
}
@@ -1208,7 +1331,7 @@ CURLcode _ftp(struct connectdata *conn)
#ifdef ENABLE_IPV6
conn->secondarysocket = -1;
- for (ai = res; ai; ai = ai->ai_next) {
+ for (ai = addr; ai; ai = ai->ai_next) {
/* XXX for now, we can do IPv4 only */
if (ai->ai_family != AF_INET)
continue;
@@ -1218,35 +1341,15 @@ CURLcode _ftp(struct connectdata *conn)
if (conn->secondarysocket < 0)
continue;
- if(data->set.verbose) {
- char hbuf[NI_MAXHOST];
- char nbuf[NI_MAXHOST];
- char sbuf[NI_MAXSERV];
-#ifdef NI_WITHSCOPEID
- const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
-#else
- const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
-#endif
- if (getnameinfo(res->ai_addr, res->ai_addrlen, nbuf, sizeof(nbuf),
- sbuf, sizeof(sbuf), niflags)) {
- snprintf(nbuf, sizeof(nbuf), "?");
- snprintf(sbuf, sizeof(sbuf), "?");
- }
-
- if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
- NULL, 0, 0)) {
- infof(data, "Connecting to %s port %s\n", nbuf, sbuf);
- } else {
- infof(data, "Connecting to %s (%s) port %s\n", hbuf, nbuf, sbuf);
- }
- }
-
if (connect(conn->secondarysocket, ai->ai_addr, ai->ai_addrlen) < 0) {
close(conn->secondarysocket);
conn->secondarysocket = -1;
continue;
}
+ if(data->set.verbose)
+ /* this just dumps information about this second connection */
+ ftp_pasv_verbose(conn, ai);
break;
}
@@ -1255,76 +1358,18 @@ CURLcode _ftp(struct connectdata *conn)
return CURLE_FTP_CANT_RECONNECT;
}
#else
+ /* IPv4 code */
conn->secondarysocket = socket(AF_INET, SOCK_STREAM, 0);
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
- memcpy((char *)&(serv_addr.sin_addr), he->h_addr, he->h_length);
- serv_addr.sin_family = he->h_addrtype;
+ memcpy((char *)&(serv_addr.sin_addr), addr->h_addr, addr->h_length);
+ serv_addr.sin_family = addr->h_addrtype;
serv_addr.sin_port = htons(connectport);
- if(data->set.verbose) {
- struct in_addr in;
- struct hostent * answer;
-
-#if defined(HAVE_INET_ADDR)
- unsigned long address;
-# if defined(HAVE_GETHOSTBYADDR_R)
- int h_errnop;
-# endif
-
- address = inet_addr(newhost);
-# ifdef HAVE_GETHOSTBYADDR_R
-
-# ifdef HAVE_GETHOSTBYADDR_R_5
- /* AIX, Digital Unix style:
- extern int gethostbyaddr_r(char *addr, size_t len, int type,
- struct hostent *htent, struct hostent_data *ht_data); */
-
- /* Fred Noz helped me try this out, now it at least compiles! */
-
- if(gethostbyaddr_r((char *) &address,
- sizeof(address), AF_INET,
- (struct hostent *)hostent_buf,
- hostent_buf + sizeof(*answer)))
- answer=NULL;
-
-# endif
-# ifdef HAVE_GETHOSTBYADDR_R_7
- /* Solaris and IRIX */
- answer = gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,
- (struct hostent *)hostent_buf,
- hostent_buf + sizeof(*answer),
- sizeof(hostent_buf) - sizeof(*answer),
- &h_errnop);
-# endif
-# ifdef HAVE_GETHOSTBYADDR_R_8
- /* Linux style */
- if(gethostbyaddr_r((char *) &address, sizeof(address), AF_INET,
- (struct hostent *)hostent_buf,
- hostent_buf + sizeof(*answer),
- sizeof(hostent_buf) - sizeof(*answer),
- &answer,
- &h_errnop))
- answer=NULL; /* error */
-# endif
-
-# else
- answer = gethostbyaddr((char *) &address, sizeof(address), AF_INET);
-# endif
-#else
- answer = NULL;
-#endif
- (void) memcpy(&in.s_addr, *he->h_addr_list, sizeof (in.s_addr));
- infof(data, "Connecting to %s (%s) port %u\n",
- answer?answer->h_name:newhost,
-#if defined(HAVE_INET_NTOA_R)
- inet_ntoa_r(in, ip_addr=ntoa_buf, sizeof(ntoa_buf)),
-#else
- ip_addr = inet_ntoa(in),
-#endif
- connectport);
- }
+ if(data->set.verbose)
+ /* this just dumps information about this second connection */
+ ftp_pasv_verbose(conn, newhost);
if(hostdataptr)
free(hostdataptr);
@@ -1349,7 +1394,7 @@ CURLcode _ftp(struct connectdata *conn)
}
return CURLE_FTP_CANT_RECONNECT;
}
-#endif /*ENABLE_IPV6*/
+#endif /* end of IPv4-specific code*/
if (data->set.tunnel_thru_httpproxy) {
/* We want "seamless" FTP operations through HTTP proxy tunnel */
diff --git a/lib/hostip.c b/lib/hostip.c
index 557a7b921..7177554af 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -68,27 +68,6 @@
/* --- resolve name or IP-number --- */
-static char *MakeIP(unsigned long num,char *addr, int addr_len)
-{
-#if defined(HAVE_INET_NTOA) || defined(HAVE_INET_NTOA_R)
- struct in_addr in;
- in.s_addr = htonl(num);
-
-#if defined(HAVE_INET_NTOA_R)
- inet_ntoa_r(in,addr,addr_len);
-#else
- strncpy(addr,inet_ntoa(in),addr_len);
-#endif
-#else
- unsigned char *paddr;
-
- num = htonl(num); /* htonl() added to avoid endian probs */
- paddr = (unsigned char *)&num;
- sprintf(addr, "%u.%u.%u.%u", paddr[0], paddr[1], paddr[2], paddr[3]);
-#endif
- return (addr);
-}
-
#ifdef ENABLE_IPV6
Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
char *hostname,
@@ -115,6 +94,27 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
}
#else /* following code is IPv4-only */
+static char *MakeIP(unsigned long num,char *addr, int addr_len)
+{
+#if defined(HAVE_INET_NTOA) || defined(HAVE_INET_NTOA_R)
+ struct in_addr in;
+ in.s_addr = htonl(num);
+
+#if defined(HAVE_INET_NTOA_R)
+ inet_ntoa_r(in,addr,addr_len);
+#else
+ strncpy(addr,inet_ntoa(in),addr_len);
+#endif
+#else
+ unsigned char *paddr;
+
+ num = htonl(num); /* htonl() added to avoid endian probs */
+ paddr = (unsigned char *)&num;
+ sprintf(addr, "%u.%u.%u.%u", paddr[0], paddr[1], paddr[2], paddr[3]);
+#endif
+ return (addr);
+}
+
/* The original code to this function was once stolen from the Dancer source
code, written by Bjorn Reese, it has since been patched and modified
considerably. */