cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: ftp remembers wrong prevpath

From: <Zibiao.Wei_at_atxinc.com>
Date: Wed, 23 Nov 2005 11:52:18 -0500

Daniel,
Here is my fix. You can decide to use it if it is helpful. I do not
declare variables at the begining of a function. You know how to adjust.

source file ftp.c
1. insert the following code to function ftp_statemach_act:

static CURLcode ftp_statemach_act(struct connectdata *conn)

    case FTP_CWD:
      if(ftpcode/100 != 2) {
        /* failure to CWD there */
        if(conn->data->set.ftp_create_missing_dirs &&
           ftp->count1 && !ftp->count2) {
          /* try making it */
          ftp->count2++; /* counter to prevent CWD-MKD loops */
          NBFTPSENDF(conn, "MKD %s", ftp->dirs[ftp->count1 - 1]);
          state(conn, FTP_MKD);
        }
        else
          /* return failure */
          return CURLE_FTP_ACCESS_DENIED;
      }
      else {
          /* edit by Bill Wei */
        char *path;
        int cnt = 0;

        /* now store a copy of the directory we are in */
        if(ftp->prevpath)
        {
          free(ftp->prevpath);
          ftp->prevpath = NULL;
        }

        if (ftp->count1 == 0)
        {
            infof(data, "Noticing we are in dir %s\n", "/");
        }
        else
        {
            path = curl_unescape(conn->path, 0); /* get the "raw" path */
            if(!path)
                return CURLE_OUT_OF_MEMORY;

            ftp->prevpath = path;
            while((cnt < ftp->count1) && (*path != '\0'))
            {
                if(*path++ == '/') cnt++;
            }
            if (*path != '\0') *path = '\0';

            infof(data, "Remembering we are in dir %s\n", ftp->prevpath);
        }
        /* End edit by Bill Wei */

        /* success */
        ftp->count2=0;
        if(++ftp->count1 <= ftp->dirdepth) {
          /* send next CWD */
          NBFTPSENDF(conn, "CWD %s", ftp->dirs[ftp->count1 - 1]);
        }
        else {
          result = ftp_state_post_cwd(conn);
          if(result)
            return result;
        }
      }
      break;

2. Remove some code from function Curl_ftp_done:

CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
{
  struct SessionHandle *data = conn->data;
  struct FTP *ftp = conn->proto.ftp;
  ssize_t nread;
  int ftpcode;
  CURLcode result=CURLE_OK;
  bool was_ctl_valid = ftp->ctl_valid;

  /** Edit by Bill Wei **/
  //size_t flen;
  //size_t dlen;
  //char *path;

  ///* now store a copy of the directory we are in */
  //if(ftp->prevpath)
  // free(ftp->prevpath);

  //path = curl_unescape(conn->path, 0); /* get the "raw" path */
  //if(!path)
  // return CURLE_OUT_OF_MEMORY;

 
  //flen = ftp->file?strlen(ftp->file):0; /* file is "raw" already */
  //dlen = strlen(path)-flen;
  //if(dlen) {
  // ftp->prevpath = path;
  // if(flen)
  // /* if 'path' is not the whole string */
  // ftp->prevpath[dlen]=0; /* terminate */
  // infof(data, "Remembering we are in dir %s\n", ftp->prevpath);
  //}
  //else {
  // ftp->prevpath = NULL; /* no path */
  // free(path);
  //}
  /** End edit by Bill Wei **/

Daniel Stenberg <daniel_at_haxx.se>
Sent by: curl-library-bounces_at_cool.haxx.se
11/23/05 03:01 AM
Please respond to
libcurl development <curl-library_at_cool.haxx.se>

To
libcurl development <curl-library_at_cool.haxx.se>
cc

Subject
Re: ftp remembers wrong prevpath

On Tue, 22 Nov 2005, Zibiao.Wei_at_atxinc.com wrote:

> Try this ftp test using libcurl
> 1. CWD to path_a and download an existing file_a.
> 2. CWD to path_b and try to download a non-existing file_b.
> 3. CWD to path_a and download (or upload) file_c.
>
> Since step 2 fails, Curl_ftp_done is not called and ftp->prevpath still
> remembers path_a. At step 3, libcurl thinks it is already at path_a but
> really it is at path_b, therefore libcurl does not CWD to path_a and try
to
> download/upload file_c at path_b which is wrong.
>
> My question is why libcurl sets ftp->prevpath in function Curl_ftp_done
> instead of after every successful CWD?

Simple: because that's not how I did it.

The current implementation is a bit simpler than so, and expects the full
path
to work or it is not rememembered at all. Indeed room for improvements
there!

You up to fixing this?

> Another interesting thing is that I logged into a Windows ftp server
with
> anonymous user. At step3 libcurl breaks the security and successfully
> uploads file_c to path_b! If I do a normal uploading, the server denies.

It is hardly libcurl's "fault" if so, since you could easily do that with
any
client anyway.

-- 
  Commercial curl and libcurl Technical Support: http://haxx.se/curl.html
Received on 2005-11-23