]> granicus.if.org Git - curl/commitdiff
Stephen More pointed out that CURLOPT_FTPPORT and the -P option didn't work
authorDaniel Stenberg <daniel@haxx.se>
Fri, 28 Jan 2005 08:26:36 +0000 (08:26 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 28 Jan 2005 08:26:36 +0000 (08:26 +0000)
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.

CHANGES
RELEASE-NOTES
lib/ftp.c

diff --git a/CHANGES b/CHANGES
index 77b770f712d6773795720e1573ce430d55ae6fad..5aa5a84eb90b08653af1a93abe4dcf1e365df3ab 100644 (file)
--- 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
index 5e57b22314b7d9bc13fad7b59632685e3fb17897..74609e5f84c30d07b7191fa4bfe3165d8efeccd7 100644 (file)
@@ -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)
index caca95e953d754a847df9197da4e034952687bad..e5ad8bde11aff5507a52726b2e90ae5ddd0170b2 100644 (file)
--- 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;