cURL / Mailing Lists / curl-library / Single Mail

curl-library

Problems with CURLOPT_PORT in FTP code

From: Dave Halbakken <YetAnotherDev_at_netscape.net>
Date: Tue, 22 Apr 2003 13:44:07 -0700

Hi All,

I was unable to make libcurl act correctly when a port number was set
(and, of course, PASV was turned off) on WinXP using VC6 compiler. Not
being a network programmer, I'm stumped trying to understanding how the
code in ftp.c could have ever worked. It looks as if the code was using
the port number as an IP address. I modified the code so that it works
for me, as shown below. I've used "#if 0" to remove the old code and an
"else" to make mine compile and run. Have I completely misunderstood the
original code, and my changes are unnecessary?

Here's the clip of code from ftp.c

CURLcode ftp_use_port(struct connectdata *conn)
{
   struct SessionHandle *data=conn->data;
   int portsock=-1;
   ssize_t nread;
   int ftpcode; /* receive FTP response codes in this */
   CURLcode result;
#ifdef ENABLE_IPV6
...stuff not shown here...
#else
   /******************************************************************
    *
    * Here's a piece of IPv4-specific code coming up
    *
    */
   struct sockaddr_in sa;
   struct Curl_dns_entry *h=NULL;
   unsigned short porttouse;
   char myhost[256] = "";
   bool sa_filled_in = FALSE;

   if(data->set.ftpport) {
vvvvvvvvvvvvvvvvvvvvvvvvvvv
#if 0 /* previous code */
     if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {
       h = Curl_resolv(data, myhost, 0);
     }
     else {
       int len = strlen(data->set.ftpport);
       if(len>1)
         h = Curl_resolv(data, data->set.ftpport, 0);
       if(h)
         strcpy(myhost, data->set.ftpport); /* buffer overflow risk */
     }
   }
   if(! *myhost) {
     /* pick a suitable default here */

     socklen_t sslen;

     sslen = sizeof(sa);
     if (getsockname(conn->firstsocket, (struct sockaddr *)&sa, &sslen)
< 0) {
       failf(data, "getsockname() failed");
       return CURLE_FTP_PORT_FAILED;
     }

     sa_filled_in = TRUE; /* the sa struct is filled in */
   }
vvvvvvvvvvvvvvvvvvvvvvvvvvv
#else /* code as modified by dhalbakken */
     socklen_t sslen;

     sslen = sizeof(sa);
     if (getsockname(conn->firstsocket, (struct sockaddr *)&sa, &sslen)
< 0) {
       failf(data, "getsockname() failed");
       return CURLE_FTP_PORT_FAILED;
    }
     sa_filled_in = TRUE; /* the sa struct is filled in */
   }
vvvvvvvvvvvvvvvvvvvvvvvvvvv
#endif

   if(h)
     /* when we return from here, we can forget about this */
     Curl_resolv_unlock(h);

   if ( h || sa_filled_in) {
     if( (portsock = socket(AF_INET, SOCK_STREAM, 0)) >= 0 ) {
       int size;

       /* we set the secondary socket variable to this for now, it
          is only so that the cleanup function will close it in case
          we fail before the true secondary stuff is made */
       conn->secondarysocket = portsock;

       if(!sa_filled_in) {
         memset((char *)&sa, 0, sizeof(sa));
         memcpy((char *)&sa.sin_addr,
                h->addr->h_addr,
                h->addr->h_length);
         sa.sin_family = AF_INET;
         sa.sin_addr.s_addr = INADDR_ANY;
       }
vvvvvvvvvvvvvvvvvvvvvvvvvvv
#if 0 /* previous code */
       sa.sin_port = 0;
vvvvvvvvvvvvvvvvvvvvvvvvvvv
#else /* code as modified by dhalbakken */
       if(strlen(data->set.ftpport)>1)
      {
         sscanf(data->set.ftpport, "%hd", &sa.sin_port);
        sa.sin_port = htons(sa.sin_port);
      }
      else
      {
         sa.sin_port = 0;
      }
vvvvvvvvvvvvvvvvvvvvvvvvvvv
#endif
       size = sizeof(sa);

       if(bind(portsock, (struct sockaddr *)&sa, size) >= 0) {

-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
Received on 2003-04-22