summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2005-01-28 08:26:36 +0000
committerDaniel Stenberg <daniel@haxx.se>2005-01-28 08:26:36 +0000
commit064bc3ecbc13c877139bc4003d95bc2e3cea2ebe (patch)
tree74c8de9a1b57e2683a6f08a69ba6ac003a64ea32
parentcf38a4c47011b449c3d51aaef345bcf19ce383b7 (diff)
downloadgnurl-064bc3ecbc13c877139bc4003d95bc2e3cea2ebe.tar.gz
gnurl-064bc3ecbc13c877139bc4003d95bc2e3cea2ebe.tar.bz2
gnurl-064bc3ecbc13c877139bc4003d95bc2e3cea2ebe.zip
Stephen More pointed out that CURLOPT_FTPPORT and the -P option didn't work
when built ipv6-enabled. I've now made a fix for it. Writing test cases for custom port strings turned too tricky so unfortunately there's none.
-rw-r--r--CHANGES5
-rw-r--r--RELEASE-NOTES3
-rw-r--r--lib/ftp.c77
3 files changed, 49 insertions, 36 deletions
diff --git a/CHANGES b/CHANGES
index 77b770f71..5aa5a84eb 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,11 @@
Changelog
+Daniel (28 January 2005)
+- Stephen More pointed out that CURLOPT_FTPPORT and the -P option didn't work
+ when built ipv6-enabled. I've now made a fix for it. Writing test cases for
+ custom port hosts turned too tricky so unfortunately there's none.
+
Daniel (25 January 2005)
- Ian Ford asked about support for the FTP command ACCT, and I discovered it
is present in RFC959... so now (lib)curl supports it as well. --ftp-account
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 5e57b2231..74609e5f8 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -22,6 +22,7 @@ This release includes the following changes:
This release includes the following bugfixes:
+ o CURLOPT_FTPPORT and -P work when built ipv6-enabled
o FTP third party transfers was much improved
o proxy environment variables are now ignored when built HTTP-disabled
o CURLOPT_PROXY can now disable HTTP proxy even when built HTTP-disabled
@@ -50,6 +51,6 @@ advice from friends like these:
Werner Koch, Gisle Vanem, Alex Neblett, Kai Sommerfeld, Marty Kuhrt,
Hzhijun, Pavel Orehov, Bruce Mitchener, Cyrill Osterwalder, Dan Torop,
Martijn Koster, Alex aka WindEagle, Cody Jones, Samuel Díaz García,
- Stephan Bergmann, Philippe Hameau, Ian Ford
+ Stephan Bergmann, Philippe Hameau, Ian Ford, Stephen More
Thanks! (and sorry if I forgot to mention someone)
diff --git a/lib/ftp.c b/lib/ftp.c
index caca95e95..e5ad8bde1 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@@ -1130,50 +1130,59 @@ CURLcode ftp_use_port(struct connectdata *conn)
struct addrinfo hints, *res, *ai;
struct sockaddr_storage ss;
socklen_t sslen;
- char hbuf[NI_MAXHOST];
-
+ char hbuf[NI_MAXHOST]="";
struct sockaddr *sa=(struct sockaddr *)&ss;
unsigned char *ap;
unsigned char *pp;
char portmsgbuf[1024], tmp[1024];
-
enum ftpcommand { EPRT, LPRT, PORT, DONE } fcmd;
const char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
int rc;
int error;
+ char *host=NULL;
+ struct Curl_dns_entry *h=NULL;
+
+ if(data->set.ftpport && (strlen(data->set.ftpport) > 1)) {
+ /* attempt to get the address of the given interface name */
+ if(!Curl_if2ip(data->set.ftpport, hbuf, sizeof(hbuf)))
+ /* not an interface, use the given string as host name instead */
+ host = data->set.ftpport;
+ else
+ host = hbuf; /* use the hbuf for host name */
+ } /* data->set.ftpport */
- /*
- * we should use Curl_if2ip? given pickiness of recent ftpd,
- * I believe we should use the same address as the control connection.
- */
- sslen = sizeof(ss);
- rc = getsockname(conn->sock[FIRSTSOCKET], (struct sockaddr *)&ss, &sslen);
- if(rc < 0) {
- failf(data, "getsockname() returned %d\n", rc);
- return CURLE_FTP_PORT_FAILED;
- }
-
- rc = getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL, 0,
- NIFLAGS);
- if(rc) {
- failf(data, "getnameinfo() returned %d\n", rc);
- return CURLE_FTP_PORT_FAILED;
- }
+ if(!host) {
+ /* not an interface and not a host name, get default by extracting
+ the IP from the control connection */
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = sa->sa_family;
- /*hints.ai_family = ss.ss_family;
- this way can be used if sockaddr_storage is properly defined, as glibc
- 2.1.X doesn't do*/
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_PASSIVE;
+ sslen = sizeof(ss);
+ rc = getsockname(conn->sock[FIRSTSOCKET], (struct sockaddr *)&ss, &sslen);
+ if(rc < 0) {
+ failf(data, "getsockname() returned %d\n", rc);
+ return CURLE_FTP_PORT_FAILED;
+ }
- rc = getaddrinfo(hbuf, NULL, &hints, &res);
- if(rc) {
- failf(data, "getaddrinfo() returned %d\n", rc);
- return CURLE_FTP_PORT_FAILED;
+ rc = getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL,
+ 0, NIFLAGS);
+ if(rc) {
+ failf(data, "getnameinfo() returned %d\n", rc);
+ return CURLE_FTP_PORT_FAILED;
+ }
+ host = hbuf; /* use this host name */
}
+ rc = Curl_resolv(conn, host, 0, &h);
+ if(rc == CURLRESOLV_PENDING)
+ rc = Curl_wait_for_resolv(conn, &h);
+ if(h) {
+ res = h->addr;
+ /* when we return from this function, we can forget about this entry
+ to we can unlock it now already */
+ Curl_resolv_unlock(data, h);
+ } /* (h) */
+ else
+ res = NULL; /* failure! */
+
portsock = CURL_SOCKET_BAD;
error = 0;
for (ai = res; ai; ai = ai->ai_next) {
@@ -1188,7 +1197,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
error = Curl_ourerrno();
continue;
}
-
if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) {
error = Curl_ourerrno();
sclose(portsock);
@@ -1205,7 +1213,7 @@ CURLcode ftp_use_port(struct connectdata *conn)
break;
}
- freeaddrinfo(res);
+
if (portsock == CURL_SOCKET_BAD) {
failf(data, "%s", Curl_strerror(conn,error));
return CURLE_FTP_PORT_FAILED;
@@ -1226,7 +1234,6 @@ CURLcode ftp_use_port(struct connectdata *conn)
}
#endif
-
for (fcmd = EPRT; fcmd != DONE; fcmd++) {
int lprtaf, eprtaf;
int alen=0, plen=0;