cURL / Mailing Lists / curl-users / Single Mail

curl-users

How to resume file download through FTP ?

From: Yuvi yuvi <testandroidos51_at_gmail.com>
Date: Thu, 23 Feb 2012 15:12:40 +0530

Hi,

I have searched a lot but don't find any sample code for resume download
through File Transfer Code. I know that curl support this feature and I can
able to do this using command prompt. But how to do it programmatically.
Even I tired to write one but no luck, this code working when connection is
closed at my lapi but if connection is closed by remote site it is not
working :

#include <stdlib.h>
#include <stdio.h>
#include <curl/curl.h>

struct FtpFile {
  const char *filename;
  FILE *stream;
};

static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
  struct FtpFile *out=(struct FtpFile *)stream;
  if(out && !out->stream) {
    /* open file for writing */
    out->stream=fopen(out->filename, "wb");
    if(!out->stream)
      return -1; /* failure, can't open file to write */
  }
  return fwrite(buffer, size, nmemb, out->stream);
}

static size_t append_fwrite(void *buffer, size_t size, size_t nmemb,
void *stream)
{
  struct FtpFile *out=(struct FtpFile *)stream;
  if(out && !out->stream) {
   // open file for writing
    out->stream=fopen(out->filename, "a+");
    if(!out->stream)
      return -1; //failure, can't open file to write
  }
  return fwrite(buffer, size, nmemb, out->stream);
}

/* parse headers for Content-Length */
size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb, void *stream)
{
  int r;
  long len = 0;

  /* _snscanf() is Win32 specific */
  r = sscanf(ptr, "Content-Length: %ld\n", &len);

  if (r) /* Microsoft: we don't read the specs */
    *((long *) stream) = len;

  return size * nmemb;
}

/* discard downloaded data */
size_t discardfunc(void *ptr, size_t size, size_t nmemb, void *stream)
{
  return size * nmemb;
}

int download(CURL *curlhandle, const char * remotepath,long timeout, long tries)
{

  long uploaded_len = 0;
  CURLcode r = CURLE_GOT_NOTHING;
  int c;
  struct FtpFile ftpfile={
    "dev.zip", //name to store the file as if succesful
    NULL
  };

  curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);

  if (timeout)
    curl_easy_setopt(curlhandle, CURLOPT_FTP_RESPONSE_TIMEOUT, timeout);

  curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);
  curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &uploaded_len);

  curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, my_fwrite);
  curl_easy_setopt(curlhandle, CURLOPT_WRITEDATA, &ftpfile);
  curl_easy_setopt(curlhandle, CURLOPT_FTPPORT, "-"); /* disable passive mode */
  curl_easy_setopt(curlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);

  curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);

  for (c = 0; (r != CURLE_OK) && (c < tries); c++) {
    /* are we resuming? */
    if (c) { /* yes */
      /* determine the length of the file already written */
        fputs("retrying.............",stderr);
      curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 1L);
      curl_easy_setopt(curlhandle, CURLOPT_HEADER, 1L);

      r = curl_easy_perform(curlhandle);
      if (r != CURLE_OK)
        continue;

      curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 0L);
      curl_easy_setopt(curlhandle, CURLOPT_HEADER, 0L);

      curl_easy_setopt(curlhandle, CURLOPT_APPEND, append_fwrite);
      curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);
    }
    else { /* no */
      curl_easy_setopt(curlhandle, CURLOPT_APPEND, 0L);
      curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);
    }

    r = curl_easy_perform(curlhandle);
  }

  if (r == CURLE_OK)
    return 1;
  else {
    fprintf(stderr, "%s\n", curl_easy_strerror(r));
    return 0;
  }
}

int main(int c, char **argv)
{
  CURL *curlhandle = NULL;

  curl_global_init(CURL_GLOBAL_ALL);
  curlhandle = curl_easy_init();

  download(curlhandle, "ftp://root:password@192.168.10.1/dev.zip", 0, 100);

  curl_easy_cleanup(curlhandle);
  curl_global_cleanup();

  return 0;
}

Any help would be highly appreciated,

Thanks,
Yuvi.

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-users
FAQ: http://curl.haxx.se/docs/faq.html
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2012-02-23