cURL / Mailing Lists / curl-library / Single Mail

curl-library

libcurl: using sftp or ftp upload, changing file name after upload is done...

From: Miguel Costa <mkos7a_at_gmail.com>
Date: Tue, 24 Mar 2009 12:50:18 +0000

base on a the examples from the ftpupload.c file and
http://curl.haxx.se/mail/lib-2008-04/0161.html

i've tried to do an upload function to upload a file and then change
the name of the file.

it should be pretty simple, but i have some errors.

i use the same function for SFTP or FTP but what i really want is SFTP
so i will be fine if FTP doesn't work.

using SFTP

-------------------- Main Menu ----------------------
        1 Set server ip address (default 172.22.219.74):
        2 Download File:
        3 Put File:
        4 Quit:
---------------------------------------------------------
3
file to upload: yumlist
name during upload: newfile_sftp
name after upload is done: file_done_ok
Local file size: 625703 bytes.
        (put) yumlist (to) sftp://172.22.219.74/~/newfile_sftp

* About to connect() to 172.22.219.74 port 22 (#0)
* Trying 172.22.219.74... * connected
* Connected to 172.22.219.74 (172.22.219.74) port 22 (#0)
* SSH authentication methods available: publickey,gssapi-with-mic,password
* Initialized password authentication
* Authentication complete
* Sending quote commands
* Unknown SFTP command
* Connection #0 to host 172.22.219.74 left intact
        NO
                        Error 21: Unknown SFTP command
* Closing connection #0

---------------------------------------------------------

so the file get's there, but the name change doesn't happen and that
is the error for Unknown SFTP command

using FTP and the same file

i don't get the file, but that maybe about permissions to write in the
local folder...

-------------------- Main Menu ----------------------
        1 Set server ip address (default 172.22.219.74):
        2 Download File:
        3 Put File:
        4 Quit:
---------------------------------------------------------
3
file to upload: yumlist
name during upload: yumlist_with_ftp
name after upload is done: done_ftp_yumlist
Local file size: 625703 bytes.
        (put) yumlist (to) ftp://172.22.219.74/~/yumlist_with_ftp

* About to connect() to 172.22.219.74 port 21 (#0)
* Trying 172.22.219.74... * connected
* Connected to 172.22.219.74 (172.22.219.74) port 21 (#0)
< 220 Welcome to MneDev FTP service
> USER ftpuser
< 331 Please specify the password.
> PASS ftpuser
< 230 Login successful.
> PWD
< 257 "/"
* Entry path is '/'
> CWD ~
< 250 Directory successfully changed.
> EPSV
* Connect data stream passively
< 229 Entering Extended Passive Mode (|||26019|)
* Trying 172.22.219.74... * connected
* Connecting to 172.22.219.74 (172.22.219.74) port 26019
> TYPE I
< 200 Switching to Binary mode.
> STOR yumlist_with_ftp
< 553 Could not create file.
* Failed FTP upload: 553
* Remembering we are in dir "~/"
* Uploaded unaligned file size (0 out of 625703 bytes)
* Connection #0 to host 172.22.219.74 left intact
        NO
                        Error 25: Failed FTP upload: 553
> QUIT
< 221 Goodbye.
* Closing connection #0

here is the function code:

int sendFile(CURL* curlpointer)
{

  CURLcode code = 0;
  FILE *file = NULL;
  struct stat file_info;
  struct curl_slist *headerlist = NULL;
  static char upfile[DEFAULT_IMPUT_SIZE] = "file.txt";
  static char renamefile[DEFAULT_IMPUT_SIZE] = "file.txt";
  static char buf_1 [DEFAULT_IMPUT_SIZE + 15] = "RNFR ";
  static char buf_2 [DEFAULT_IMPUT_SIZE+ 15] = "RNTO ";

  printf("file to upload: ");
  getInput_CMM(filename, DEFAULT_IMPUT_SIZE);

  printf("name during upload: ");
  getInput_CMM(upfile, DEFAULT_IMPUT_SIZE);

  printf("name after upload is done: ");
  getInput_CMM(renamefile, DEFAULT_IMPUT_SIZE);

  /* commands to change the file num after upload is done */
  sprintf(buf_1, "RNFR %s", upfile);
  sprintf(buf_2, "RNTO %s", renamefile);

  /* get the file size of the local file */
  if(stat(filename, &file_info)) {
    printf("Couldnt open '%s': %s\n", filename, strerror(errno));
    return 1;
  }
  printf("Local file size: %ld bytes.\n", file_info.st_size);

  file = fopen(filename, "r");

  curlpointer = curl_easy_init();
  if (curlpointer != NULL && file != NULL)
  {
    /* build a list of commands to pass to libcurl */
    headerlist = curl_slist_append(headerlist, buf_1);
    headerlist = curl_slist_append(headerlist, buf_2);

    /* set to TRUE when debug is needed */
    curl_easy_setopt(curlpointer, CURLOPT_VERBOSE, TRUE);
    curl_easy_setopt(curlpointer, CURLOPT_ERRORBUFFER, error_code_text);

    /* authentication type when using password is, weirdly, keyboard */
    curl_easy_setopt(curlpointer, CURLOPT_SSH_AUTH_TYPES,
                     CURLSSH_AUTH_PASSWORD);
    curl_easy_setopt(curlpointer, CURLOPT_USERPWD, userpass);

    curl_easy_setopt(curlpointer, CURLOPT_UPLOAD, TRUE);

    /* set sftp url */
    if (transfer_mode == SFTP_MODE)
    {
      sprintf(host_server, "sftp://%s/~/%s", server_ip, upfile);
    }
    else
    {
      sprintf(host_server, "ftp://%s/~/%s", server_ip, upfile);
    }

    printf("\t(put) %s (to) %s\n\n", filename, host_server);
    curl_easy_setopt(curlpointer, CURLOPT_URL, host_server);

    curl_easy_setopt(curlpointer, CURLOPT_READFUNCTION, NULL);
    curl_easy_setopt(curlpointer, CURLOPT_READDATA, file);

    curl_easy_setopt(curlpointer, CURLOPT_INFILESIZE_LARGE,
                     (curl_off_t)file_info.st_size);

    /*
     * pass in that last of FTP commands to run after the transfer
     * change the name of the file in the server...
     */
    curl_easy_setopt(curlpointer, CURLOPT_POSTQUOTE, headerlist);

    code = curl_easy_perform(curlpointer);

    fclose(file);
    if (code != 0)
          printf("\tNO\n\t\t\tError %d: %s\n", code, error_code_text);
    else
          printf("\tOK [remote:%s]\n",renamefile);

    /* clean up the FTP commands list */
    curl_slist_free_all (headerlist);
    curl_easy_cleanup(curlpointer);

  }

  return code;
}

--
Miguel Costa
Received on 2009-03-24