Skip to content
Snippets Groups Projects
ftp.c 123 KiB
Newer Older
  • Learn to ignore specific revisions
  •     dlen = strlen(path) - (ftpc->file?strlen(ftpc->file):0);
    
        if((dlen == strlen(ftpc->prevpath)) &&
           curl_strnequal(path, ftpc->prevpath, dlen)) {
    
          infof(data, "Request has same path as previous transfer\n");
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
        }
    
      return CURLE_OK;
    
    /* call this when the DO phase has completed */
    static CURLcode ftp_dophase_done(struct connectdata *conn,
                                     bool connected)
    {
      CURLcode result = CURLE_OK;
    
      struct FTP *ftp = conn->data->reqdata.proto.ftp;
      struct ftp_conn *ftpc = &conn->proto.ftpc;
    
    
      if(connected)
        result = Curl_ftp_nextconnect(conn);
    
      if(result && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) {
        /* Failure detected, close the second socket if it was created already */
        sclose(conn->sock[SECONDARYSOCKET]);
        conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
    
      if(ftp->transfer != FTPTRANSFER_BODY)
    
        result=Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
    
      else if(!connected)
        /* since we didn't connect now, we want do_more to get called */
        conn->bits.do_more = TRUE;
    
    
      ftpc->ctl_valid = TRUE; /* seems good */
    
    static CURLcode Curl_ftp_doing(struct connectdata *conn,
                                   bool *dophase_done)
    
    {
      CURLcode result;
      result = Curl_ftp_multi_statemach(conn, dophase_done);
    
      if(*dophase_done) {
        result = ftp_dophase_done(conn, FALSE /* not connected */);
    
    
        DEBUGF(infof(conn->data, "DO phase is complete\n"));
    
    
    /***********************************************************************
     *
     * ftp_regular_transfer()
     *
     * The input argument is already checked for validity.
    
     *
     * Performs all commands done before a regular transfer between a local and a
     * remote host.
    
     *
     * ftp->ctl_valid starts out as FALSE, and gets set to TRUE if we reach the
     * Curl_ftp_done() function without finding any major problem.
     */
    static
    
    CURLcode ftp_regular_transfer(struct connectdata *conn,
                                  bool *dophase_done)
    
      bool connected=0;
      struct SessionHandle *data = conn->data;
    
      struct ftp_conn *ftpc = &conn->proto.ftpc;
      data->reqdata.size = -1; /* make sure this is unknown at this point */
    
    
      Curl_pgrsSetUploadCounter(data, 0);
      Curl_pgrsSetDownloadCounter(data, 0);
      Curl_pgrsSetUploadSize(data, 0);
      Curl_pgrsSetDownloadSize(data, 0);
    
    
      ftpc->ctl_valid = TRUE; /* starts good */
    
      result = ftp_perform(conn,
                           &connected, /* have we connected after PASV/PORT */
                           dophase_done); /* all commands in the DO-phase done? */
    
        if(!*dophase_done)
          /* the DO phase has not completed yet */
          return CURLE_OK;
    
        result = ftp_dophase_done(conn, connected);
        if(result)
          return result;
    
    static CURLcode Curl_ftp_setup_connection(struct connectdata * conn)
    {
      struct SessionHandle *data = conn->data;
      char * type;
      char command;
    
      if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
        /* Unless we have asked to tunnel ftp operations through the proxy, we
           switch and use HTTP operations only */
    #ifndef CURL_DISABLE_HTTP
    
        if (conn->handler == &Curl_handler_ftp)
          conn->handler = &Curl_handler_ftp_proxy;
        else {
    #ifdef USE_SSL
          conn->handler = &Curl_handler_ftps_proxy;
    #else
          failf(data, "FTPS not supported!");
          return CURLE_UNSUPPORTED_PROTOCOL;
    #endif
        }
    
    
    #else
        failf(data, "FTP over http proxy requires HTTP support built-in!");
        return CURLE_UNSUPPORTED_PROTOCOL;
    #endif
      }
    
      data->reqdata.path++;   /* don't include the initial slash */
    
      /* FTP URLs support an extension like ";type=<typecode>" that
       * we'll try to get now! */
      type = strstr(data->reqdata.path, ";type=");
    
      if (!type)
        type = strstr(conn->host.rawalloc, ";type=");
    
      if (type) {
        *type = 0;                     /* it was in the middle of the hostname */
        command = (char) toupper((int) type[6]);
    
        switch (command) {
        case 'A': /* ASCII mode */
          data->set.prefer_ascii = TRUE;
          break;
    
        case 'D': /* directory mode */
          data->set.ftp_list_only = TRUE;
          break;
    
        case 'I': /* binary mode */
        default:
          /* switch off ASCII */
          data->set.prefer_ascii = FALSE;
          break;
        }
      }
    
      return CURLE_OK;
    }
    
    
    static CURLcode Curl_ftps_setup_connection(struct connectdata * conn)
    {
      struct SessionHandle *data = conn->data;
    
      conn->ssl[SECONDARYSOCKET].use = data->set.ftp_ssl != CURLUSESSL_CONTROL;
      return Curl_ftp_setup_connection(conn);
    }