cURL / Mailing Lists / curl-library / Single Mail

curl-library

ftp upload problem

From: Nicky <nickyjian_at_yahoo.com.tw>
Date: Tue, 3 Jun 2008 15:13:53 +0800 (CST)

I run the example ftpupload.c http://curl.haxx.se/lxr/source/docs/examples/ftpupload.c in CentOS release 4.6 (Final)
Kernel 2.6.9-67.EL on an i686,curl-devel-7.12.1-11.el4 but I get the failed result.The curl_easy_perform(curl) return 18.I find the error table that it means
  CURLE_PARTIAL_FILE (18) A file transfer was shorter or larger than expected. This happens when the server first reports an expected transfer size, and then delivers data that doesn't match the previously given size.
  But the file size equals the tranfer size.I don't know what's wrong.
  ###################################################
  Local file size: 8 bytes.
* About to connect() to localhost port 21
* Trying 127.0.0.1... * connected
* Connected to localhost (127.0.0.1) port 21
< 220 (vsFTPd 2.0.1)
> USER nick
< 331 Please specify the password.
> PASS nick
< 230 Login successful.
* We have successfully logged in
> PWD
< 257 "/home/nick"
* Entry path is '/home/nick'
> EPSV
< 229 Entering Extended Passive Mode (|||33519|)
* Trying 127.0.0.1... * connected
* Connecting to localhost (127.0.0.1) port 33519
* Connected the data stream with PASV!
> TYPE I
< 200 Switching to Binary mode.
> STOR while-uploading.txt
< 150 Ok to send data.
*** We read 8 bytes from file
*** We read 0 bytes from file
* Closing connection #0
curl_easy_perform(curl) res=18
  #############################################################
  /*****************************************************************************
 * _ _ ____ _
 * Project ___| | | | _ \| |
 * / __| | | | |_) | |
 * | (__| |_| | _ <| |___
 * \___|\___/|_| \_\_____|
 *
 * $Id: ftpupload.c,v 1.15 2008-05-22 21:20:09 danf Exp $
 */
  #include <stdio.h>
#include <string.h>
  #include <curl/curl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#ifdef WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
  /*
 * This example shows an FTP upload, with a rename of the file just after
 * a successful upload.
 *
 * Example based on source code provided by Erick Nuwendam. Thanks!
 */
  #define LOCAL_FILE "/tmp/uploadthis.txt"
#define UPLOAD_FILE_AS "while-uploading.txt"
#define REMOTE_URL "ftp://nick:nick@localhost/" UPLOAD_FILE_AS
#define RENAME_FILE_TO "renamed-and-fine.txt"
  /* NOTE: if you want this example to work on Windows with libcurl as a
   DLL, you MUST also provide a read callback with CURLOPT_READFUNCTION.
   Failing to do so will give you a crash since a DLL may not use the
   variable's memory when passed in to it from an app like this. */
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
  /* in real-world cases, this would probably get this data differently
     as this fread() stuff is exactly what the library already would do
     by default internally */
  size_t retcode = fread(ptr, size, nmemb, stream);
    fprintf(stderr, "*** We read %d bytes from file\n", retcode);
  return retcode;
}
  int main(int argc, char **argv)
{
  CURL *curl;
  CURLcode res;
  FILE *hd_src;
  struct stat file_info;
    struct curl_slist *headerlist=NULL;
  static const char buf_1 [] = "RNFR " UPLOAD_FILE_AS;
  static const char buf_2 [] = "RNTO " RENAME_FILE_TO;
    /* get the file size of the local file */
  if(stat(LOCAL_FILE, &file_info)) {
    printf("Couldnt open '%s': %s\n", LOCAL_FILE, strerror(errno));
    return 1;
  }
  printf("Local file size: %ld bytes.\n", file_info.st_size);
    /* get a FILE * of the same file */
  hd_src = fopen(LOCAL_FILE, "rb");
    /* In windows, this will init the winsock stuff */
  curl_global_init(CURL_GLOBAL_ALL);
    /* get a curl handle */
  curl = curl_easy_init();
  if(curl) {
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    /* build a list of commands to pass to libcurl */
    headerlist = curl_slist_append(headerlist, buf_1);
    headerlist = curl_slist_append(headerlist, buf_2);
      /* we want to use our own read function */
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
      /* enable uploading */
    curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
      /* specify target */
    curl_easy_setopt(curl,CURLOPT_URL, REMOTE_URL);
      /* pass in that last of FTP commands to run after the transfer */
    curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
      /* now specify which file to upload */
    curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
      /* Set the size of the file to upload (optional). If you give a *_LARGE
       option you MUST make sure that the type of the passed-in argument is a
       curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must
       make sure that to pass in a type 'long' argument. */
    curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
                     (curl_off_t)file_info.st_size);
      /* Now run off and do what you've been told! */
    res = curl_easy_perform(curl);
    printf("curl_easy_perform(curl) res=%d\n",res);
      /* clean up the FTP commands list */
    curl_slist_free_all (headerlist);
      /* always cleanup */
    curl_easy_cleanup(curl);
  }
  fclose(hd_src); /* close the local file */
    curl_global_cleanup();
  return 0;
}
###############################################################
  I see the target file "while-uploading.txt" but isn't renamed to "renamed-and-fine.txt".I guest that when the transfer file process fail,the proceedure terminate,so the following proceedure isn't excuted. I run many times and the result is the same.
  Thanks.

       付費才容量無上限?Yahoo!奇摩電子信箱2.0免費給你,信件永遠不必刪! - 馬上體驗!
Received on 2008-06-03