/*****************************************************************************
 *                                  _   _ ____  _     
 *  Project                     ___| | | |  _ \| |    
 *                             / __| | | | |_) | |    
 *                            | (__| |_| |  _ <| |___ 
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * In order to be useful for every potential user, curl and libcurl are
 * dual-licensed under the MPL and the MIT/X-derivate licenses.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the MPL or the MIT/X-derivate
 * licenses. You may pick one of these licenses.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id$
 *****************************************************************************/

#include "setup.h"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <errno.h>

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

#if defined(WIN32) && !defined(__GNUC__) || defined(__MINGW32__)
#include <winsock.h>
#else /* some kind of unix */
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#include <sys/types.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#include <sys/utsname.h>
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef	VMS
#include <in.h>
#include <inet.h>
#endif
#endif

#if defined(WIN32) && defined(__GNUC__) || defined(__MINGW32__)
#include <errno.h>
#endif

#include <curl/curl.h>
#include "urldata.h"
#include "sendf.h"

#include "if2ip.h"
#include "hostip.h"
#include "progress.h"
#include "transfer.h"
#include "escape.h"
#include "http.h" /* for HTTP proxy tunnel stuff */
#include "ftp.h"

#ifdef KRB4
#include "security.h"
#include "krb4.h"
#endif

#include "strequal.h"
#include "ssluse.h"
#include "connect.h"

#if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
#include "inet_ntoa_r.h"
#endif

#define _MPRINTF_REPLACE /* use our functions only */
#include <curl/mprintf.h>

/* The last #include file should be: */
#ifdef MALLOCDEBUG
#include "memdebug.h"
#endif

/* Local API functions */
static CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote);
static CURLcode ftp_cwd(struct connectdata *conn, char *path);

/* easy-to-use macro: */
#define FTPSENDF(x,y,z) if((result = Curl_ftpsendf(x,y,z))) return result

/***********************************************************************
 *
 * AllowServerConnect()
 *
 * When we've issue the PORT command, we have told the server to connect
 * to us. This function will sit and wait here until the server has
 * connected.
 *
 */
static CURLcode AllowServerConnect(struct SessionHandle *data,
                                   struct connectdata *conn,
                                   int sock)
{
  fd_set rdset;
  struct timeval dt;
  
  FD_ZERO(&rdset);

  FD_SET(sock, &rdset);

  /* we give the server 10 seconds to connect to us */
  dt.tv_sec = 10;
  dt.tv_usec = 0;

  switch (select(sock+1, &rdset, NULL, NULL, &dt)) {
  case -1: /* error */
    /* let's die here */
    failf(data, "Error while waiting for server connect");
    return CURLE_FTP_PORT_FAILED;
  case 0:  /* timeout */
    /* let's die here */
    failf(data, "Timeout while waiting for server connect");
    return CURLE_FTP_PORT_FAILED;
  default:
    /* we have received data here */
    {
      int s;
      size_t size = sizeof(struct sockaddr_in);
      struct sockaddr_in add;

      getsockname(sock, (struct sockaddr *) &add, (socklen_t *)&size);
      s=accept(sock, (struct sockaddr *) &add, (socklen_t *)&size);

      sclose(sock); /* close the first socket */

      if (-1 == s) {
        /* DIE! */
        failf(data, "Error accept()ing server connect");
      	return CURLE_FTP_PORT_FAILED;
      }
      infof(data, "Connection accepted from server\n");

      conn->secondarysocket = s;
    }
    break;
  }
  return CURLE_OK;
}


/* --- parse FTP server responses --- */

/*
 * Curl_GetFTPResponse() is supposed to be invoked after each command sent to
 * a remote FTP server. This function will wait and read all lines of the
 * response and extract the relevant return code for the invoking function.
 */

int Curl_GetFTPResponse(char *buf,
                        struct connectdata *conn,
                        int *ftpcode)
{
  /* Brand new implementation.
   * We cannot read just one byte per read() and then go back to select()
   * as it seems that the OpenSSL read() stuff doesn't grok that properly.
   *
   * Alas, read as much as possible, split up into lines, use the ending
   * line in a response or continue reading.  */

  int sockfd = conn->firstsocket;
  int nread;   /* total size read */
  int perline; /* count bytes per line */
  bool keepon=TRUE;
  ssize_t gotbytes;
  char *ptr;
  int timeout = 3600; /* default timeout in seconds */
  struct timeval interval;
  fd_set rkeepfd;
  fd_set readfd;
  struct SessionHandle *data = conn->data;
  char *line_start;
  int code=0; /* default "error code" to return */

#define SELECT_OK       0
#define SELECT_ERROR    1 /* select() problems */
#define SELECT_TIMEOUT  2 /* took too long */
#define SELECT_MEMORY   3 /* no available memory */
#define SELECT_CALLBACK 4 /* aborted by callback */

  int error = SELECT_OK;

  struct FTP *ftp = conn->proto.ftp;

  if (ftpcode)
    *ftpcode = 0; /* 0 for errors */

  if(data->set.timeout) {
    /* if timeout is requested, find out how much remaining time we have */
    timeout = data->set.timeout - /* timeout time */
      Curl_tvdiff(Curl_tvnow(), conn->now)/1000; /* spent time */
    if(timeout <=0 ) {
      failf(data, "Transfer aborted due to timeout");
      return -SELECT_TIMEOUT; /* already too little time */
    }
  }

  FD_ZERO (&readfd);		/* clear it */
  FD_SET (sockfd, &readfd);     /* read socket */

  /* get this in a backup variable to be able to restore it on each lap in the
     select() loop */
  rkeepfd = readfd;

  ptr=buf;
  line_start = buf;

  nread=0;
  perline=0;
  keepon=TRUE;

  while((nread<BUFSIZE) && (keepon && !error)) {
    readfd = rkeepfd;		   /* set every lap */
    interval.tv_sec = timeout;
    interval.tv_usec = 0;

    if(!ftp->cache)
      switch (select (sockfd+1, &readfd, NULL, NULL, &interval)) {
      case -1: /* select() error, stop reading */
        error = SELECT_ERROR;
        failf(data, "Transfer aborted due to select() error");
        break;
      case 0: /* timeout */
        error = SELECT_TIMEOUT;
        failf(data, "Transfer aborted due to timeout");
        break;
      default:
        error = SELECT_OK;
        break;
      }
    if(SELECT_OK == error) {
      /*
       * This code previously didn't use the kerberos sec_read() code
       * to read, but when we use Curl_read() it may do so. Do confirm
       * that this is still ok and then remove this comment!
       */
      if(ftp->cache) {
        /* we had data in the "cache", copy that instead of doing an actual
           read */
        memcpy(ptr, ftp->cache, ftp->cache_size);
        gotbytes = ftp->cache_size;
        free(ftp->cache);    /* free the cache */
        ftp->cache = NULL;   /* clear the pointer */
        ftp->cache_size = 0; /* zero the size just in case */
      }
      else {
        int res = Curl_read(conn, sockfd, ptr,
                            BUFSIZE-nread, &gotbytes);
        if(res < 0)
          /* EWOULDBLOCK */
          continue; /* go looping again */

        if(CURLE_OK != res)
          keepon = FALSE;
      }

      if(!keepon)
        ;
      else if(gotbytes <= 0) {
        keepon = FALSE;
        error = SELECT_ERROR;
        failf(data, "Connection aborted");
      }
      else {
        /* we got a whole chunk of data, which can be anything from one
         * byte to a set of lines and possible just a piece of the last
         * line */
        int i;

        nread += gotbytes;
        for(i = 0; i < gotbytes; ptr++, i++) {
          perline++;
          if(*ptr=='\n') {
            /* a newline is CRLF in ftp-talk, so the CR is ignored as
               the line isn't really terminated until the LF comes */
            CURLcode result;

            /* output debug output if that is requested */
            if(data->set.verbose) {
              fputs("< ", data->set.err);
              fwrite(line_start, perline, 1, data->set.err);
              /* no need to output LF here, it is part of the data */
            }

            /*
             * We pass all response-lines to the callback function registered
             * for "headers". The response lines can be seen as a kind of
             * headers.
             */
            result = Curl_client_write(data, CLIENTWRITE_HEADER,
                                       line_start, perline);
            if(result)
              return -SELECT_CALLBACK;
                                       
#define lastline(line) (isdigit((int)line[0]) && isdigit((int)line[1]) && \
			isdigit((int)line[2]) && (' ' == line[3]))

            if(perline>3 && lastline(line_start)) {
              /* This is the end of the last line, copy the last
               * line to the start of the buffer and zero terminate,
               * for old times sake (and krb4)! */
              char *meow;
              int n;
              for(meow=line_start, n=0; meow<ptr; meow++, n++)
                buf[n] = *meow;
              *meow=0; /* zero terminate */
              keepon=FALSE;
              line_start = ptr+1; /* advance pointer */
              i++; /* skip this before getting out */
              break;
            }
            perline=0; /* line starts over here */
            line_start = ptr+1;
          }
        }
        if(!keepon && (i != gotbytes)) {
          /* We found the end of the response lines, but we didn't parse the
             full chunk of data we have read from the server. We therefore
             need to store the rest of the data to be checked on the next
             invoke as it may actually contain another end of response
             already!  Cleverly figured out by Eric Lavigne in December
             2001. */
          ftp->cache_size = gotbytes - i;
          ftp->cache = (char *)malloc(ftp->cache_size);
          if(ftp->cache)
            memcpy(ftp->cache, line_start, ftp->cache_size);
          else
            return -SELECT_MEMORY; /**BANG**/
        }
      } /* there was data */
    } /* if(no error) */
  } /* while there's buffer left and loop is requested */

  if(!error)
    code = atoi(buf);

#ifdef KRB4
  /* handle the security-oriented responses 6xx ***/
  /* FIXME: some errorchecking perhaps... ***/
  switch(code) {
  case 631:
    Curl_sec_read_msg(conn, buf, prot_safe);
    break;
  case 632:
    Curl_sec_read_msg(conn, buf, prot_private);
    break;
  case 633:
    Curl_sec_read_msg(conn, buf, prot_confidential);
    break;
  default:
    /* normal ftp stuff we pass through! */
    break;
  }
#endif

  if(error)
    return -error;

  if(ftpcode)
    *ftpcode=code; /* return the initial number like this */

  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)
{
#if defined(HAVE_GETHOSTNAME)
  gethostname(buf, buf_size);
#elif defined(HAVE_UNAME)
  struct utsname ugnm;
  strncpy(buf, uname(&ugnm) < 0 ? "localhost" : ugnm.nodename, buf_size - 1);
  buf[buf_size - 1] = '\0';
#else
  /* We have no means of finding the local host name! */
  strncpy(buf, "localhost", buf_size);
  buf[buf_size - 1] = '\0';
#endif
  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)
{
  /* this is FTP and no proxy */
  int nread;
  struct SessionHandle *data=conn->data;
  char *buf = data->state.buffer; /* this is our buffer */
  struct FTP *ftp;
  CURLcode result;
  int ftpcode;

  ftp = (struct FTP *)malloc(sizeof(struct FTP));
  if(!ftp)
    return CURLE_OUT_OF_MEMORY;

  memset(ftp, 0, sizeof(struct FTP));
  conn->proto.ftp = ftp;

  /* We always support persistant connections on ftp */
  conn->bits.close = FALSE;

  /* get some initial data into the ftp struct */
  ftp->bytecountp = &conn->bytecount;

  /* no need to duplicate them, the data struct won't change */
  ftp->user = data->state.user;
  ftp->passwd = data->state.passwd;

  if (data->set.tunnel_thru_httpproxy) {
    /* We want "seamless" FTP operations through HTTP proxy tunnel */
    result = Curl_ConnectHTTPProxyTunnel(conn, conn->firstsocket,
                                         conn->hostname, conn->remote_port);
    if(CURLE_OK != result)
      return result;
  }

  if(conn->protocol & PROT_FTPS) {
    /* FTPS is simply ftp with SSL for the control channel */
    /* now, perform the SSL initialization for this socket */
    result = Curl_SSLConnect(conn);
    if(result)
      return result;
  }


  /* The first thing we do is wait for the "220*" line: */
  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
  if(nread < 0)
    return CURLE_OPERATION_TIMEOUTED;

  if(ftpcode != 220) {
    failf(data, "This doesn't seem like a nice ftp-server response");
    return CURLE_FTP_WEIRD_SERVER_REPLY;
  }

#ifdef KRB4
  /* if not anonymous login, try a secure login */
  if(data->set.krb4) {

    /* request data protection level (default is 'clear') */
    Curl_sec_request_prot(conn, "private");

    /* We set private first as default, in case the line below fails to
       set a valid level */
    Curl_sec_request_prot(conn, data->set.krb4_level);

    if(Curl_sec_login(conn) != 0)
      infof(data, "Logging in with password in cleartext!\n");
    else
      infof(data, "Authentication successful\n");
  }
#endif
  
  /* send USER */
  FTPSENDF(conn, "USER %s", ftp->user);

  /* wait for feedback */
  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
  if(nread < 0)
    return CURLE_OPERATION_TIMEOUTED;

  if(ftpcode == 530) {
    /* 530 User ... access denied
       (the server denies to log the specified user) */
    failf(data, "Access denied: %s", &buf[4]);
    return CURLE_FTP_ACCESS_DENIED;
  }
  else if(ftpcode == 331) {
    /* 331 Password required for ...
       (the server requires to send the user's password too) */
    FTPSENDF(conn, "PASS %s", ftp->passwd);
    nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
    if(nread < 0)
      return CURLE_OPERATION_TIMEOUTED;

    if(ftpcode == 530) {
      /* 530 Login incorrect.
         (the username and/or the password are incorrect) */
      failf(data, "the username and/or the password are incorrect");
      return CURLE_FTP_USER_PASSWORD_INCORRECT;
    }
    else if(ftpcode == 230) {
      /* 230 User ... logged in.
         (user successfully logged in) */
        
      infof(data, "We have successfully logged in\n");
    }
    else {
      failf(data, "Odd return code after PASS");
      return CURLE_FTP_WEIRD_PASS_REPLY;
    }
  }
  else if(buf[0] == '2') {
    /* 230 User ... logged in.
       (the user logged in without password) */
    infof(data, "We have successfully logged in\n");
#ifdef KRB4
	/* we are logged in (with Kerberos)
	 * now set the requested protection level
	 */
    if(conn->sec_complete)
      Curl_sec_set_protection_level(conn);

    /* we may need to issue a KAUTH here to have access to the files
     * do it if user supplied a password
     */
    if(data->state.passwd && *data->state.passwd)
      Curl_krb_kauth(conn);
#endif
  }
  else {
    failf(data, "Odd return code after USER");
    return CURLE_FTP_WEIRD_USER_REPLY;
  }

  /* send PWD to discover our entry point */
  FTPSENDF(conn, "PWD", NULL);

  /* wait for feedback */
  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
  if(nread < 0)
    return CURLE_OPERATION_TIMEOUTED;

  if(ftpcode == 257) {
    char *dir = (char *)malloc(nread+1);
    char *store=dir;
    char *ptr=&buf[4]; /* start on the first letter */
    
    /* Reply format is like
       257<space>"<directory-name>"<space><commentary> and the RFC959 says

       The directory name can contain any character; embedded double-quotes
       should be escaped by double-quotes (the "quote-doubling" convention).
    */
    if('\"' == *ptr) {
      /* it started good */
      ptr++;
      while(ptr && *ptr) {
        if('\"' == *ptr) {
          if('\"' == ptr[1]) {
            /* "quote-doubling" */
            *store = ptr[1];
            ptr++;
          }
          else {
            /* end of path */
            *store = '\0'; /* zero terminate */
            break; /* get out of this loop */
          }
        }
        else
          *store = *ptr;
        store++;
        ptr++;
      }
      ftp->entrypath =dir; /* remember this */
      infof(data, "Entry path is '%s'\n", ftp->entrypath);
    }
    else {
      /* couldn't get the path */
    }

  }
  else {
    /* We couldn't read the PWD response! */
  }

  return CURLE_OK;
}

/***********************************************************************
 *
 * Curl_ftp_done()
 *
 * The DONE function. This does what needs to be done after a single DO has
 * performed.
 *
 * Input argument is already checked for validity.
 */
CURLcode Curl_ftp_done(struct connectdata *conn)
{
  struct SessionHandle *data = conn->data;
  struct FTP *ftp = conn->proto.ftp;
  ssize_t nread;
  char *buf = data->state.buffer; /* this is our buffer */
  int ftpcode;
  CURLcode result=CURLE_OK;

  if(data->set.upload) {
    if((-1 != data->set.infilesize) && (data->set.infilesize != *ftp->bytecountp)) {
      failf(data, "Wrote only partial file (%d out of %d bytes)",
            *ftp->bytecountp, data->set.infilesize);
      return CURLE_PARTIAL_FILE;
    }
  }
  else {
    if((-1 != conn->size) && (conn->size != *ftp->bytecountp) &&
       (conn->maxdownload != *ftp->bytecountp)) {
      failf(data, "Received only partial file: %d bytes", *ftp->bytecountp);
      return CURLE_PARTIAL_FILE;
    }
    else if(!conn->bits.resume_done &&
            !data->set.no_body &&
            (0 == *ftp->bytecountp)) {
      /* We consider this an error, but there's no true FTP error received
         why we need to continue to "read out" the server response too.
         We don't want to leave a "waiting" server reply if we'll get told
         to make a second request on this same connection! */
      failf(data, "No data was received!");
      result = CURLE_FTP_COULDNT_RETR_FILE;
    }
  }

#ifdef KRB4
  Curl_sec_fflush_fd(conn, conn->secondarysocket);
#endif
  /* shut down the socket to inform the server we're done */
  sclose(conn->secondarysocket);
  conn->secondarysocket = -1;

  if(!data->set.no_body && !conn->bits.resume_done) {  
    /* now let's see what the server says about the transfer we
       just performed: */
    nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
    if(nread < 0)
      return CURLE_OPERATION_TIMEOUTED;

    /* 226 Transfer complete, 250 Requested file action okay, completed. */
    if((ftpcode != 226) && (ftpcode != 250)) {
      failf(data, "server did not report OK, got %d", ftpcode);
      return CURLE_FTP_WRITE_ERROR;
    }
  }

  conn->bits.resume_done = FALSE; /* clean this for next connection */

  /* Send any post-transfer QUOTE strings? */
  if(!result && data->set.postquote)
    result = ftp_sendquote(conn, data->set.postquote);

  return result;
}

/***********************************************************************
 *
 * ftp_sendquote()
 *
 * Where a 'quote' means a list of custom commands to send to the server.
 * The quote list is passed as an argument.
 */

static 
CURLcode ftp_sendquote(struct connectdata *conn, struct curl_slist *quote)
{
  struct curl_slist *item;
  ssize_t nread;
  int ftpcode;
  CURLcode result;

  item = quote;
  while (item) {
    if (item->data) {
      FTPSENDF(conn, "%s", item->data);

      nread = Curl_GetFTPResponse(conn->data->state.buffer, conn, &ftpcode);
      if (nread < 0)
        return CURLE_OPERATION_TIMEOUTED;

      if (ftpcode >= 400) {
        failf(conn->data, "QUOT string not accepted: %s", item->data);
        return CURLE_FTP_QUOTE_ERROR;
      }
    }

    item = item->next;
  }

  return CURLE_OK;
}

/***********************************************************************
 *
 * ftp_cwd()
 *
 * Send 'CWD' to the remote server to Change Working Directory.
 * It is the ftp version of the unix 'cd' command.
 */
static 
CURLcode ftp_cwd(struct connectdata *conn, char *path)
{
  ssize_t nread;
  int     ftpcode;
  CURLcode result;
  
  FTPSENDF(conn, "CWD %s", path);
  nread = Curl_GetFTPResponse(
                              conn->data->state.buffer, conn, &ftpcode);
  if (nread < 0)
    return CURLE_OPERATION_TIMEOUTED;

  if (ftpcode != 250) {
    failf(conn->data, "Couldn't cd to %s", path);
    return CURLE_FTP_ACCESS_DENIED;
  }

  return CURLE_OK;
}

/***********************************************************************
 *
 * ftp_getfiletime()
 *
 * Get the timestamp of the given file.
 */
static
CURLcode ftp_getfiletime(struct connectdata *conn, char *file)
{
  CURLcode result=CURLE_OK;
  int ftpcode; /* for ftp status */
  ssize_t nread;
  char *buf = conn->data->state.buffer;

  /* we have requested to get the modified-time of the file, this is yet
     again a grey area as the MDTM is not kosher RFC959 */
  FTPSENDF(conn, "MDTM %s", file);

  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
  if(nread < 0)
    return CURLE_OPERATION_TIMEOUTED;

  if(ftpcode == 213) {
    /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the
       last .sss part is optional and means fractions of a second */
    int year, month, day, hour, minute, second;
    if(6 == sscanf(buf+4, "%04d%02d%02d%02d%02d%02d",
                   &year, &month, &day, &hour, &minute, &second)) {
      /* we have a time, reformat it */
      time_t secs=time(NULL);
      sprintf(buf, "%04d%02d%02d %02d:%02d:%02d",
              year, month, day, hour, minute, second);
      /* now, convert this into a time() value: */
      conn->data->info.filetime = curl_getdate(buf, &secs);
    }
    else {
      infof(conn->data, "unsupported MDTM reply format\n");
    }
  }
  return  result;
}

/***********************************************************************
 *
 * ftp_transfertype()
 *
 * Set transfer type. We only deal with ASCII or BINARY so this function
 * sets one of them.
 */
static CURLcode ftp_transfertype(struct connectdata *conn,
                                  bool ascii)
{
  struct SessionHandle *data = conn->data;
  int ftpcode;
  ssize_t nread;
  char *buf=data->state.buffer;
  CURLcode result;

  FTPSENDF(conn, "TYPE %s", ascii?"A":"I");

  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
  if(nread < 0)
    return CURLE_OPERATION_TIMEOUTED;
  
  if(ftpcode != 200) {
    failf(data, "Couldn't set %s mode",
          ascii?"ASCII":"binary");
    return ascii? CURLE_FTP_COULDNT_SET_ASCII:CURLE_FTP_COULDNT_SET_BINARY;
  }

  return CURLE_OK;
}

/***********************************************************************
 *
 * ftp_getsize()
 *
 * Returns the file size (in bytes) of the given remote file.
 */

static
CURLcode ftp_getsize(struct connectdata *conn, char *file,
                      ssize_t *size)
{
  struct SessionHandle *data = conn->data;
  int ftpcode;
  ssize_t nread;
  char *buf=data->state.buffer;
  CURLcode result;

  FTPSENDF(conn, "SIZE %s", file);
  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
  if(nread < 0)
    return CURLE_OPERATION_TIMEOUTED;

  if(ftpcode == 213) {
    /* get the size from the ascii string: */
    *size = atoi(buf+4);
  }
  else
    return CURLE_FTP_COULDNT_GET_SIZE;

  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,
                 Curl_ipconnect *addr,
                 char *newhost, /* ascii version */
                 int port)
{
#ifndef ENABLE_IPV6
  /*****************************************************************
   *
   * IPv4-only code section
   */

  struct in_addr in;
  struct hostent * answer;

#ifdef HAVE_INET_NTOA_R
  char ntoa_buf[64];
#endif
  /* The array size trick below is to make this a large chunk of memory
     suitably 8-byte aligned on 64-bit platforms. This was thoughtfully
     suggested by Philip Gladstone. */
  long bigbuf[9000 / sizeof(long)];

#if defined(HAVE_INET_ADDR)
  in_addr_t address;
# if defined(HAVE_GETHOSTBYADDR_R)
  int h_errnop;
# endif
  char *hostent_buf = (char *)bigbuf; /* get a char * to the buffer */

  address = inet_addr(newhost);
# ifdef HAVE_GETHOSTBYADDR_R

#  ifdef HAVE_GETHOSTBYADDR_R_5
  /* AIX, Digital Unix (OSF1, Tru64) 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! */

  /* Bjorn Reese (November 28 2001):
     The Tru64 man page on gethostbyaddr_r() says that
     the hostent struct must be filled with zeroes before the call to
     gethostbyaddr_r(). */

  memset(hostent_buf, 0, sizeof(struct hostent));

  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 *)bigbuf,
                           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, sizeof (Curl_ipconnect));
  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, ntoa_buf, sizeof(ntoa_buf)),
#else
        inet_ntoa(in),
#endif
        port);

#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
  port = 0; /* unused, prevent warning */
  if (getnameinfo(addr->ai_addr, addr->ai_addrlen,
                  nbuf, sizeof(nbuf), sbuf, sizeof(sbuf), niflags)) {
    snprintf(nbuf, sizeof(nbuf), "?");
    snprintf(sbuf, sizeof(sbuf), "?");
  }
        
  if (getnameinfo(addr->ai_addr, addr->ai_addrlen,
                  hbuf, sizeof(hbuf), NULL, 0, 0)) {
    infof(conn->data, "Connecting to %s (%s) port %s\n", nbuf, newhost, sbuf);
  }
  else {
    infof(conn->data, "Connecting to %s (%s) port %s\n", hbuf, nbuf, sbuf);
  }
#endif
}

/***********************************************************************
 *
 * ftp_use_port()
 *
 * Send the proper PORT command. PORT is the ftp client's way of telling the
 * server that *WE* open a port that we listen on an awaits the server to
 * connect to. This is the opposite of PASV.
 */

static
CURLcode ftp_use_port(struct connectdata *conn)
{
  struct SessionHandle *data=conn->data;
  int portsock=-1;
  ssize_t nread;
  char *buf = data->state.buffer; /* this is our buffer */
  int ftpcode; /* receive FTP response codes in this */
  CURLcode result;

#ifdef ENABLE_IPV6
  /******************************************************************
   *
   * Here's a piece of IPv6-specific code coming up
   *
   */

  struct addrinfo hints, *res, *ai;
  struct sockaddr_storage ss;
  socklen_t sslen;
  char hbuf[NI_MAXHOST];

  struct sockaddr *sa=(struct sockaddr *)&ss;
#ifdef NI_WITHSCOPEID
  const int niflags = NI_NUMERICHOST | NI_NUMERICSERV | NI_WITHSCOPEID;
#else
  const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
#endif
  unsigned char *ap;
  unsigned char *pp;
  int alen, plen;
  char portmsgbuf[4096], tmp[4096];

  const char *mode[] = { "EPRT", "LPRT", "PORT", NULL };
  char **modep;

  /*
   * 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);
  if (getsockname(conn->firstsocket, (struct sockaddr *)&ss, &sslen) < 0)
    return CURLE_FTP_PORT_FAILED;
  
  if (getnameinfo((struct sockaddr *)&ss, sslen, hbuf, sizeof(hbuf), NULL, 0,
                  niflags))
    return CURLE_FTP_PORT_FAILED;

  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;

  if (getaddrinfo(hbuf, (char *)"0", &hints, &res))
    return CURLE_FTP_PORT_FAILED;
  
  portsock = -1;
  for (ai = res; ai; ai = ai->ai_next) {
    portsock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
    if (portsock < 0)
      continue;

    if (bind(portsock, ai->ai_addr, ai->ai_addrlen) < 0) {
      sclose(portsock);
      portsock = -1;
      continue;
    }
      
    if (listen(portsock, 1) < 0) {
      sclose(portsock);
      portsock = -1;
      continue;
    }
    
    break;
  }
  freeaddrinfo(res);
  if (portsock < 0) {
    failf(data, strerror(errno));
    return CURLE_FTP_PORT_FAILED;
  }

  sslen = sizeof(ss);
  if (getsockname(portsock, sa, &sslen) < 0) {
    failf(data, strerror(errno));
    return CURLE_FTP_PORT_FAILED;
  }

  for (modep = (char **)mode; modep && *modep; modep++) {
    int lprtaf, eprtaf;
    
    switch (sa->sa_family) {
    case AF_INET:
      ap = (unsigned char *)&((struct sockaddr_in *)&ss)->sin_addr;
      alen = sizeof(((struct sockaddr_in *)&ss)->sin_addr);
      pp = (unsigned char *)&((struct sockaddr_in *)&ss)->sin_port;
      plen = sizeof(((struct sockaddr_in *)&ss)->sin_port);
      lprtaf = 4;
      eprtaf = 1;
      break;
    case AF_INET6:
      ap = (unsigned char *)&((struct sockaddr_in6 *)&ss)->sin6_addr;
      alen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_addr);
      pp = (unsigned char *)&((struct sockaddr_in6 *)&ss)->sin6_port;
      plen = sizeof(((struct sockaddr_in6 *)&ss)->sin6_port);
      lprtaf = 6;
      eprtaf = 2;
      break;
    default:
      ap = pp = NULL;
      lprtaf = eprtaf = -1;
      break;
    }

    if (strcmp(*modep, "EPRT") == 0) {
      if (eprtaf < 0)
        continue;
      if (getnameinfo((struct sockaddr *)&ss, sslen,
                      portmsgbuf, sizeof(portmsgbuf), tmp, sizeof(tmp), niflags))
        continue;

      /* do not transmit IPv6 scope identifier to the wire */
      if (sa->sa_family == AF_INET6) {
        char *q = strchr(portmsgbuf, '%');
          if (q)
            *q = '\0';
      }

      result = Curl_ftpsendf(conn, "%s |%d|%s|%s|", *modep, eprtaf,
                             portmsgbuf, tmp);
      if(result)
        return result;
    } else if (strcmp(*modep, "LPRT") == 0 ||
               strcmp(*modep, "PORT") == 0) {
      int i;
      
      if (strcmp(*modep, "LPRT") == 0 && lprtaf < 0)
        continue;
      if (strcmp(*modep, "PORT") == 0 && sa->sa_family != AF_INET)
        continue;

      portmsgbuf[0] = '\0';
      if (strcmp(*modep, "LPRT") == 0) {
        snprintf(tmp, sizeof(tmp), "%d,%d", lprtaf, alen);
        if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >=
            sizeof(portmsgbuf)) {
          continue;
        }
      }

      for (i = 0; i < alen; i++) {
        if (portmsgbuf[0])
          snprintf(tmp, sizeof(tmp), ",%u", ap[i]);
        else
          snprintf(tmp, sizeof(tmp), "%u", ap[i]);
        
        if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >=
            sizeof(portmsgbuf)) {
          continue;
        }
      }
      
      if (strcmp(*modep, "LPRT") == 0) {
        snprintf(tmp, sizeof(tmp), ",%d", plen);
        
        if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >= sizeof(portmsgbuf))
          continue;
      }

      for (i = 0; i < plen; i++) {
        snprintf(tmp, sizeof(tmp), ",%u", pp[i]);
        
        if (strlcat(portmsgbuf, tmp, sizeof(portmsgbuf)) >=
            sizeof(portmsgbuf)) {
          continue;
        }
      }
      
      result = Curl_ftpsendf(conn, "%s %s", *modep, portmsgbuf);
      if(result)
        return result;
    }
    
    nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
    if(nread < 0)
      return CURLE_OPERATION_TIMEOUTED;
    
    if (ftpcode != 200) {
      failf(data, "Server does not grok %s", *modep);
      continue;
    }
    else
      break;
  }
  
  if (!*modep) {
    sclose(portsock);
    return CURLE_FTP_PORT_FAILED;
  }
  /* 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;
  
#else
  /******************************************************************
   *
   * Here's a piece of IPv4-specific code coming up
   *
   */
  struct sockaddr_in sa;
  struct hostent *h=NULL;
  char *hostdataptr=NULL;
  unsigned short porttouse;
  char myhost[256] = "";

  if(data->set.ftpport) {
    if(Curl_if2ip(data->set.ftpport, myhost, sizeof(myhost))) {
      h = Curl_resolv(data, myhost, 0, &hostdataptr);
    }
    else {
      int len = strlen(data->set.ftpport);
      if(len>1)
        h = Curl_resolv(data, data->set.ftpport, 0, &hostdataptr);
      if(h)
        strcpy(myhost, data->set.ftpport); /* buffer overflow risk */
    }
  }
  if(! *myhost) {
    char *tmp_host = getmyhost(myhost, sizeof(myhost));
    h=Curl_resolv(data, tmp_host, 0, &hostdataptr);
  }
  infof(data, "We connect from %s\n", myhost);
  
  if ( h ) {
    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;

      memset((char *)&sa, 0, sizeof(sa));
      memcpy((char *)&sa.sin_addr,
             h->h_addr,
             h->h_length);
      sa.sin_family = AF_INET;
      sa.sin_addr.s_addr = INADDR_ANY;
      sa.sin_port = 0;
      size = sizeof(sa);
      
      if(bind(portsock, (struct sockaddr *)&sa, size) >= 0) {
        /* we succeeded to bind */
        struct sockaddr_in add;
        socklen_t socksize = sizeof(add);

        if(getsockname(portsock, (struct sockaddr *) &add,
                       &socksize)<0) {
          failf(data, "getsockname() failed");
          return CURLE_FTP_PORT_FAILED;
        }
        porttouse = ntohs(add.sin_port);
        
        if ( listen(portsock, 1) < 0 ) {
          failf(data, "listen(2) failed on socket");
          free(hostdataptr);
          return CURLE_FTP_PORT_FAILED;
        }
      }
      else {
        failf(data, "bind(2) failed on socket");
        free(hostdataptr);
        return CURLE_FTP_PORT_FAILED;
      }
    }
    else {
      failf(data, "socket(2) failed (%s)");
      free(hostdataptr);
      return CURLE_FTP_PORT_FAILED;
    }
  }
  else {
    failf(data, "could't find my own IP address (%s)", myhost);
    return CURLE_FTP_PORT_FAILED;
  }
  {
#ifdef HAVE_INET_NTOA_R
    char ntoa_buf[64];
#endif
    struct in_addr in;
    unsigned short ip[5];
    (void) memcpy(&in.s_addr, *h->h_addr_list, sizeof (in.s_addr));
#ifdef HAVE_INET_NTOA_R
    /* ignore the return code from inet_ntoa_r() as it is int or
       char * depending on system */
    inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf));
    sscanf( ntoa_buf, "%hu.%hu.%hu.%hu",
            &ip[0], &ip[1], &ip[2], &ip[3]);
#else
    sscanf( inet_ntoa(in), "%hu.%hu.%hu.%hu",
            &ip[0], &ip[1], &ip[2], &ip[3]);
#endif
    result=Curl_ftpsendf(conn, "PORT %d,%d,%d,%d,%d,%d",
                         ip[0], ip[1], ip[2], ip[3],
                         porttouse >> 8,
                         porttouse & 255);
    if(result)
      return result;
  }

  nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
  if(nread < 0)
    return CURLE_OPERATION_TIMEOUTED;

  if(ftpcode != 200) {
    failf(data, "Server does not grok PORT, try without it!");
    return CURLE_FTP_PORT_FAILED;
  }
#endif /* end of ipv4-specific code */

  return CURLE_OK;
}

/***********************************************************************
 *
 * ftp_use_pasv()
 *
 * Send the PASV command. PASV is the ftp client's way of asking the server to
 * open a second port that we can connect to (for the data transfer). This is
 * the opposite of PORT.
 */

static
CURLcode ftp_use_pasv(struct connectdata *conn)
{
  struct SessionHandle *data = conn->data;
  ssize_t nread;
  char *buf = data->state.buffer; /* this is our buffer */
  int ftpcode; /* receive FTP response codes in this */
  CURLcode result;
  Curl_addrinfo *addr=NULL;
  Curl_ipconnect *conninfo;

  /*
    Here's the excecutive summary on what to do:

    PASV is RFC959, expect:
    227 Entering Passive Mode (a1,a2,a3,a4,p1,p2)

    LPSV is RFC1639, expect:
    228 Entering Long Passive Mode (4,4,a1,a2,a3,a4,2,p1,p2)

    EPSV is RFC2428, expect:
    229 Entering Extended Passive Mode (|||port|)

  */

#if 1
  const char *mode[] = { "EPSV", "PASV", NULL };
  int results[] = { 229, 227, 0 };
#else
#if 0
  char *mode[] = { "EPSV", "LPSV", "PASV", NULL };
  int results[] = { 229, 228, 227, 0 };
#else
  const char *mode[] = { "PASV", NULL };
  int results[] = { 227, 0 };
#endif
#endif
  int modeoff;
  unsigned short connectport; /* the local port connect() should use! */
  unsigned short newport; /* remote port, not necessary the local one */
  char *hostdataptr=NULL;
  
  /* newhost must be able to hold a full IP-style address in ASCII, which
     in the IPv6 case means 5*8-1 = 39 letters */
  char newhost[48];
  char *newhostp=NULL;
  
  for (modeoff = (data->set.ftp_use_epsv?0:1);
       mode[modeoff]; modeoff++) {
    result = Curl_ftpsendf(conn, mode[modeoff]);
    if(result)
      return result;
    nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
    if(nread < 0)
      return CURLE_OPERATION_TIMEOUTED;
    if (ftpcode == results[modeoff])
      break;
  }

  if (!mode[modeoff]) {
    failf(data, "Odd return code after PASV");
    return CURLE_FTP_WEIRD_PASV_REPLY;
  }
  else if (227 == results[modeoff]) {
    int ip[4];
    int port[2];
    char *str=buf;

    /*
     * New 227-parser June 3rd 1999.
     * It now scans for a sequence of six comma-separated numbers and
     * will take them as IP+port indicators.
     *
     * Found reply-strings include:
     * "227 Entering Passive Mode (127,0,0,1,4,51)"
     * "227 Data transfer will passively listen to 127,0,0,1,4,51"
     * "227 Entering passive mode. 127,0,0,1,4,51"
     */
      
    while(*str) {
      if (6 == sscanf(str, "%d,%d,%d,%d,%d,%d",
                      &ip[0], &ip[1], &ip[2], &ip[3],
                      &port[0], &port[1]))
        break;
      str++;
    }

    if(!*str) {
      failf(data, "Couldn't interpret this 227-reply: %s", buf);
      return CURLE_FTP_WEIRD_227_FORMAT;
    }

    sprintf(newhost, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
    newhostp = newhost;
    newport = (port[0]<<8) + port[1];
  }
#if 1
  else if (229 == results[modeoff]) {
    char *ptr = strchr(buf, '(');
    if(ptr) {
      unsigned int num;
      char separator[4];
      ptr++;
      if(5  == sscanf(ptr, "%c%c%c%u%c",
                      &separator[0],
                      &separator[1],
                      &separator[2],
                      &num,
                      &separator[3])) {
        /* the four separators should be identical */
        newport = num;

        /* we should use the same host we already are connected to */
        newhostp = conn->name;
      }                      
      else
        ptr=NULL;
    }
    if(!ptr) {
      failf(data, "Weirdly formatted EPSV reply");
      return CURLE_FTP_WEIRD_PASV_REPLY;
    }
  }
#endif
  else
    return CURLE_FTP_CANT_RECONNECT;

  if(data->change.proxy) {
    /*
     * This is a tunnel through a http proxy and we need to connect to the
     * proxy again here. We already have the name info for it since the
     * previous lookup.
     */
    addr = conn->hostaddr;
    connectport =
      (unsigned short)conn->port; /* we connect to the proxy's port */
  }
  else {
    /* normal, direct, ftp connection */
    addr = Curl_resolv(data, newhostp, newport, &hostdataptr);
    if(!addr) {
      failf(data, "Can't resolve new host %s", newhost);
      return CURLE_FTP_CANT_GET_HOST;
    }
    connectport = newport; /* we connect to the remote port */
  }
    
  result = Curl_connecthost(conn,
                            addr,
                            connectport,
                            &conn->secondarysocket,
                            &conninfo);
  
  if((CURLE_OK == result) &&       
     data->set.verbose)
    /* this just dumps information about this second connection */
    ftp_pasv_verbose(conn, conninfo, newhost, connectport);
  
  if(CURLE_OK != result)
    return result;

  if (data->set.tunnel_thru_httpproxy) {
    /* We want "seamless" FTP operations through HTTP proxy tunnel */
    result = Curl_ConnectHTTPProxyTunnel(conn, conn->secondarysocket,
                                         newhost, newport);
    if(CURLE_OK != result)
      return result;
  }

  return CURLE_OK;
}

/***********************************************************************
 *
 * ftp_perform()
 *
 * This is the actual DO function for FTP. Get a file/directory according to
 * the options previously setup.
 */

static
CURLcode ftp_perform(struct connectdata *conn)
{
  /* this is FTP and no proxy */
  ssize_t nread;
  CURLcode result;
  struct SessionHandle *data=conn->data;
  char *buf = data->state.buffer; /* this is our buffer */

  /* the ftp struct is already inited in ftp_connect() */
  struct FTP *ftp = conn->proto.ftp;

  long *bytecountp = ftp->bytecountp;
  int ftpcode; /* for ftp status */

  /* Send any QUOTE strings? */
  if(data->set.quote) {
    if ((result = ftp_sendquote(conn, data->set.quote)) != CURLE_OK)
      return result;
  }
    
  /* This is a re-used connection. Since we change directory to where the
     transfer is taking place, we must now get back to the original dir
     where we ended up after login: */
  if (conn->bits.reuse) {
    if ((result = ftp_cwd(conn, ftp->entrypath)) != CURLE_OK)
      return result;
  }

  /* change directory first! */
  if(ftp->dir && ftp->dir[0]) {
    if ((result = ftp_cwd(conn, ftp->dir)) != CURLE_OK)
        return result;
  }

  /* Requested time of file? */
  if(data->set.get_filetime && ftp->file) {
    result = ftp_getfiletime(conn, ftp->file);
    if(result)
      return result;
  }

  /* If we have selected NOBODY and HEADER, it means that we only want file
     information. Which in FTP can't be much more than the file size and
     date. */
  if(data->set.no_body && data->set.include_header) {
    /* The SIZE command is _not_ RFC 959 specified, and therefor many servers
       may not support it! It is however the only way we have to get a file's
       size! */
    ssize_t filesize;

    /* Some servers return different sizes for different modes, and thus we
       must set the proper type before we check the size */
    result = ftp_transfertype(conn, data->set.ftp_ascii);
    if(result)
      return result;

    /* failing to get size is not a serious error */
    result = ftp_getsize(conn, ftp->file, &filesize);

    if(CURLE_OK == result) {
      sprintf(buf, "Content-Length: %d\r\n", filesize);
      result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
      if(result)
        return result;
    }

    /* If we asked for a time of the file and we actually got one as
       well, we "emulate" a HTTP-style header in our output. */

#ifdef HAVE_STRFTIME
    if(data->set.get_filetime && data->info.filetime) {
      struct tm *tm;
#ifdef HAVE_LOCALTIME_R
      struct tm buffer;
      tm = (struct tm *)localtime_r(&data->info.filetime, &buffer);
#else
      tm = localtime((unsigned long *)&data->info.filetime);
#endif
      /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
      strftime(buf, BUFSIZE-1, "Last-Modified: %a, %d %b %Y %H:%M:%S %Z\r\n",
               tm);
      result = Curl_client_write(data, CLIENTWRITE_BOTH, buf, 0);
      if(result)
        return result;
    }
#endif

    return CURLE_OK;
  }

  if(data->set.no_body)
    /* don't transfer the data */
    ;
  /* Get us a second connection up and connected */
  else if(data->set.ftp_use_port) {
    /* We have chosen to use the PORT command */
    result = ftp_use_port(conn);
    if(CURLE_OK == result)
      /* we have the data connection ready */
      infof(data, "Connected the data stream with PORT!\n");
  }
  else {
    /* We have chosen (this is default) to use the PASV command */
    result = ftp_use_pasv(conn);
    if(CURLE_OK == result)
      infof(data, "Connected the data stream with PASV!\n");
  }
  
  if(result)
    return result;

  if(data->set.upload) {

    /* Set type to binary (unless specified ASCII) */
    result = ftp_transfertype(conn, data->set.ftp_ascii);
    if(result)
      return result;

    if(conn->resume_from) {
      /* we're about to continue the uploading of a file */
      /* 1. get already existing file's size. We use the SIZE
         command for this which may not exist in the server!
         The SIZE command is not in RFC959. */

      /* 2. This used to set REST. But since we can do append, we
         don't another ftp command. We just skip the source file
         offset and then we APPEND the rest on the file instead */

      /* 3. pass file-size number of bytes in the source file */
      /* 4. lower the infilesize counter */
      /* => transfer as usual */

      if(conn->resume_from < 0 ) {
        /* we could've got a specified offset from the command line,
           but now we know we didn't */
        ssize_t gottensize;

        if(CURLE_OK != ftp_getsize(conn, ftp->file, &gottensize)) {
          failf(data, "Couldn't get remote file size");
          return CURLE_FTP_COULDNT_GET_SIZE;
        }
        conn->resume_from = gottensize;
      }

      if(conn->resume_from) {
        /* do we still game? */
        int passed=0;
        /* enable append instead */
        data->set.ftp_append = 1;

        /* Now, let's read off the proper amount of bytes from the
           input. If we knew it was a proper file we could've just
           fseek()ed but we only have a stream here */
        do {
          int readthisamountnow = (conn->resume_from - passed);
          int actuallyread;

          if(readthisamountnow > BUFSIZE)
            readthisamountnow = BUFSIZE;

          actuallyread =
            data->set.fread(data->state.buffer, 1, readthisamountnow,
                            data->set.in);

          passed += actuallyread;
          if(actuallyread != readthisamountnow) {
            failf(data, "Could only read %d bytes from the input", passed);
            return CURLE_FTP_COULDNT_USE_REST;
          }
        }
        while(passed != conn->resume_from);

        /* now, decrease the size of the read */
        if(data->set.infilesize>0) {
          data->set.infilesize -= conn->resume_from;

          if(data->set.infilesize <= 0) {
            infof(data, "File already completely uploaded\n");

            /* no data to transfer */
            result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
            
            /* Set resume done so that we won't get any error in
             * Curl_ftp_done() because we didn't transfer the amount of bytes
             * that the local file file obviously is */
            conn->bits.resume_done = TRUE; 

            return CURLE_OK;
          }
        }
        /* we've passed, proceed as normal */
      }
    }

    /* Send everything on data->set.in to the socket */
    if(data->set.ftp_append) {
      /* we append onto the file instead of rewriting it */
      FTPSENDF(conn, "APPE %s", ftp->file);
    }
    else {
      FTPSENDF(conn, "STOR %s", ftp->file);
    }

    nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
    if(nread < 0)
      return CURLE_OPERATION_TIMEOUTED;

    if(ftpcode>=400) {
      failf(data, "Failed FTP upload:%s", buf+3);
      /* oops, we never close the sockets! */
      return CURLE_FTP_COULDNT_STOR_FILE;
    }

    if(data->set.ftp_use_port) {
      /* PORT means we are now awaiting the server to connect to us. */
      result = AllowServerConnect(data, conn, conn->secondarysocket);
      if( result )
        return result;
    }

    *bytecountp=0;

    /* When we know we're uploading a specified file, we can get the file
       size prior to the actual upload. */

    Curl_pgrsSetUploadSize(data, data->set.infilesize);

    result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
                      conn->secondarysocket, bytecountp);
    if(result)
      return result;
      
  }
  else if(!data->set.no_body) {
    /* Retrieve file or directory */
    bool dirlist=FALSE;
    long downloadsize=-1;

    if(conn->bits.use_range && conn->range) {
      long from, to;
      int totalsize=-1;
      char *ptr;
      char *ptr2;

      from=strtol(conn->range, &ptr, 0);
      while(ptr && *ptr && (isspace((int)*ptr) || (*ptr=='-')))
        ptr++;
      to=strtol(ptr, &ptr2, 0);
      if(ptr == ptr2) {
        /* we didn't get any digit */
        to=-1;
      }
      if((-1 == to) && (from>=0)) {
        /* X - */
        conn->resume_from = from;
        infof(data, "FTP RANGE %d to end of file\n", from);
      }
      else if(from < 0) {
        /* -Y */
        totalsize = -from;
        conn->maxdownload = -from;
        conn->resume_from = from;
        infof(data, "FTP RANGE the last %d bytes\n", totalsize);
      }
      else {
        /* X-Y */
        totalsize = to-from;
        conn->maxdownload = totalsize+1; /* include the last mentioned byte */
        conn->resume_from = from;
        infof(data, "FTP RANGE from %d getting %d bytes\n", from,
              conn->maxdownload);
      }
      infof(data, "range-download from %d to %d, totally %d bytes\n",
            from, to, totalsize);
    }

    if((data->set.ftp_list_only) || !ftp->file) {
      /* The specified path ends with a slash, and therefore we think this
         is a directory that is requested, use LIST. But before that we
         need to set ASCII transfer mode. */
      dirlist = TRUE;

      /* Set type to ASCII */
      result = ftp_transfertype(conn, TRUE /* ASCII enforced */);
      if(result)
        return result;

      /* if this output is to be machine-parsed, the NLST command will be
         better used since the LIST command output is not specified or
         standard in any way */

      FTPSENDF(conn, "%s",
            data->set.customrequest?data->set.customrequest:
            (data->set.ftp_list_only?"NLST":"LIST"));
    }
    else {
      ssize_t foundsize;

      /* Set type to binary (unless specified ASCII) */
      result = ftp_transfertype(conn, data->set.ftp_ascii);
      if(result)
        return result;

      /* Attempt to get the size, it'll be useful in some cases: for resumed
         downloads and when talking to servers that don't give away the size
         in the RETR response line. */
      result = ftp_getsize(conn, ftp->file, &foundsize);
      if(CURLE_OK == result)
        downloadsize = foundsize;

      if(conn->resume_from) {

        /* Daniel: (August 4, 1999)
         *
         * We start with trying to use the SIZE command to figure out the size
         * of the file we're gonna get. If we can get the size, this is by far
         * the best way to know if we're trying to resume beyond the EOF.
         *
         * Daniel, November 28, 2001. We *always* get the size on downloads
         * now, so it is done before this even when not doing resumes. I saved
         * the comment above for nostalgical reasons! ;-)
         */
        if(CURLE_OK != result) {
          infof(data, "ftp server doesn't support SIZE\n");
          /* We couldn't get the size and therefore we can't know if there
             really is a part of the file left to get, although the server
             will just close the connection when we start the connection so it
             won't cause us any harm, just not make us exit as nicely. */
        }
        else {
          /* We got a file size report, so we check that there actually is a
             part of the file left to get, or else we go home.  */
          if(conn->resume_from< 0) {
            /* We're supposed to download the last abs(from) bytes */
            if(foundsize < -conn->resume_from) {
              failf(data, "Offset (%d) was beyond file size (%d)",
                    conn->resume_from, foundsize);
              return CURLE_FTP_BAD_DOWNLOAD_RESUME;
            }
            /* convert to size to download */
            downloadsize = -conn->resume_from;
            /* download from where? */
            conn->resume_from = foundsize - downloadsize;
          }
          else {
            if(foundsize < conn->resume_from) {
              failf(data, "Offset (%d) was beyond file size (%d)",
                    conn->resume_from, foundsize);
              return CURLE_FTP_BAD_DOWNLOAD_RESUME;
            }
            /* Now store the number of bytes we are expected to download */
            downloadsize = foundsize-conn->resume_from;
          }
        }

        if (downloadsize == 0) {
          /* no data to transfer */
          result=Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
          infof(data, "File already completely downloaded\n");

          /* Set resume done so that we won't get any error in Curl_ftp_done()
           * because we didn't transfer the amount of bytes that the remote
           * file obviously is */
          conn->bits.resume_done = TRUE; 

          return CURLE_OK;
        }
	
        /* Set resume file transfer offset */
        infof(data, "Instructs server to resume from offset %d\n",
              conn->resume_from);

        FTPSENDF(conn, "REST %d", conn->resume_from);

        nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
        if(nread < 0)
          return CURLE_OPERATION_TIMEOUTED;

        if(ftpcode != 350) {
          failf(data, "Couldn't use REST: %s", buf+4);
          return CURLE_FTP_COULDNT_USE_REST;
        }
      }

      FTPSENDF(conn, "RETR %s", ftp->file);
    }

    nread = Curl_GetFTPResponse(buf, conn, &ftpcode);
    if(nread < 0)
      return CURLE_OPERATION_TIMEOUTED;

    if((ftpcode == 150) || (ftpcode == 125)) {

      /*
        A;
        150 Opening BINARY mode data connection for /etc/passwd (2241
        bytes).  (ok, the file is being transfered)
	
        B:
        150 Opening ASCII mode data connection for /bin/ls 

        C:
        150 ASCII data connection for /bin/ls (137.167.104.91,37445) (0 bytes).

        D:
        150 Opening ASCII mode data connection for /linux/fisk/kpanelrc (0.0.0.0,0) (545 bytes).
          
        E:
        125 Data connection already open; Transfer starting. */

      int size=-1; /* default unknown size */

      if(!dirlist &&
         !data->set.ftp_ascii &&
         (-1 == downloadsize)) {
        /*
         * It seems directory listings either don't show the size or very
         * often uses size 0 anyway. ASCII transfers may very well turn out
         * that the transfered amount of data is not the same as this line
         * tells, why using this number in those cases only confuses us.
         *
         * Example D above makes this parsing a little tricky */
        char *bytes;
        bytes=strstr(buf, " bytes");
        if(bytes--) {
          int index=bytes-buf;
          /* this is a hint there is size information in there! ;-) */
          while(--index) {
            /* scan for the parenthesis and break there */
            if('(' == *bytes)
              break;
            /* if only skip digits, or else we're in deep trouble */
            if(!isdigit((int)*bytes)) {
              bytes=NULL;
              break;
            }
            /* one more estep backwards */
            bytes--;
          }
          /* only if we have nothing but digits: */
          if(bytes++) {
            /* get the number! */
            size = atoi(bytes);
          }
            
        }
      }
      else if(downloadsize > -1)
        size = downloadsize;

      if(data->set.ftp_use_port) {
        result = AllowServerConnect(data, conn, conn->secondarysocket);
        if( result )
          return result;
      }

      infof(data, "Getting file with size: %d\n", size);

      /* FTP download: */
      result=Curl_Transfer(conn, conn->secondarysocket, size, FALSE,
                           bytecountp,
                           -1, NULL); /* no upload here */
      if(result)
        return result;
    }
    else {
      failf(data, "%s", buf+4);
      return CURLE_FTP_COULDNT_RETR_FILE;
    }
	
  }
  /* end of transfer */

  return CURLE_OK;
}

/***********************************************************************
 *
 * Curl_ftp()
 *
 * This function is registered as 'curl_do' function. It decodes the path
 * parts etc as a wrapper to the actual DO function (ftp_perform).
 *
 * The input argument is already checked for validity.
 */
CURLcode Curl_ftp(struct connectdata *conn)
{
  CURLcode retcode;

  struct SessionHandle *data = conn->data;
  struct FTP *ftp;
  int dirlength=0; /* 0 forces strlen() */

  /* the ftp struct is already inited in ftp_connect() */
  ftp = conn->proto.ftp;

  /* We split the path into dir and file parts *before* we URLdecode
     it */
  ftp->file = strrchr(conn->ppath, '/');
  if(ftp->file) {
    if(ftp->file != conn->ppath)
      dirlength=ftp->file-conn->ppath; /* don't count the traling slash */

    ftp->file++; /* point to the first letter in the file name part or
                    remain NULL */
  }
  else {
    ftp->file = conn->ppath; /* there's only a file part */
  }

  if(*ftp->file) {
    ftp->file = curl_unescape(ftp->file, 0);
    if(NULL == ftp->file) {
      failf(data, "no memory");
      return CURLE_OUT_OF_MEMORY;
    }
  }
  else
    ftp->file=NULL; /* instead of point to a zero byte, we make it a NULL
                       pointer */

  ftp->urlpath = conn->ppath;
  if(dirlength) {
    ftp->dir = curl_unescape(ftp->urlpath, dirlength);
    if(NULL == ftp->dir) {
      if(ftp->file)
        free(ftp->file);
      failf(data, "no memory");
      return CURLE_OUT_OF_MEMORY; /* failure */
    }
  }
  else
    ftp->dir = NULL;

  retcode = ftp_perform(conn);

  /* clean up here, success or error doesn't matter */
  if(ftp->file)
    free(ftp->file);
  if(ftp->dir)
    free(ftp->dir);

  ftp->file = ftp->dir = NULL; /* zero */

  return retcode;
}

/***********************************************************************
 *
 * Curl_ftpsendf()
 *
 * Sends the formated string as a ftp command to a ftp server
 *
 * NOTE: we build the command in a fixed-length buffer, which sets length
 * restrictions on the command!
 */
CURLcode Curl_ftpsendf(struct connectdata *conn,
                       const char *fmt, ...)
{
  ssize_t bytes_written;
  char s[256];
  ssize_t write_len;
  char *sptr=s;
  CURLcode res = CURLE_OK;

  va_list ap;
  va_start(ap, fmt);
  vsnprintf(s, 250, fmt, ap);
  va_end(ap);

  if(conn->data->set.verbose)
    fprintf(conn->data->set.err, "> %s\n", s);

  strcat(s, "\r\n"); /* append a trailing CRLF */

  bytes_written=0;
  write_len = strlen(s);

  do {
    res = Curl_write(conn, conn->firstsocket, sptr, write_len,
                     &bytes_written);

    if(CURLE_OK != res)
      break;

    if(bytes_written != write_len) {
      write_len -= bytes_written;
      sptr += bytes_written;
    }
    else
      break;
  } while(1);

  return res;
}

/***********************************************************************
 *
 * Curl_ftp_disconnect()
 *
 * Disconnect from an FTP server. Cleanup protocol-specific per-connection
 * resources
 */
CURLcode Curl_ftp_disconnect(struct connectdata *conn)
{
  struct FTP *ftp= conn->proto.ftp;

  /* The FTP session may or may not have been allocated/setup at this point! */
  if(ftp) {
    if(ftp->entrypath)
      free(ftp->entrypath);
    if(ftp->cache)
      free(ftp->cache);
  }
  return CURLE_OK;
}

/*
 * local variables:
 * eval: (load-file "../curl-mode.el")
 * end:
 * vim600: fdm=marker
 * vim: et sw=2 ts=2 sts=2 tw=78
 */
