cURL / Mailing Lists / curl-users / Single Mail

curl-users

Patch to make curl support file://upload/ resume

From: ·å Í¿ <tu0151034_at_yahoo.com.cn>
Date: Tue, 29 May 2007 14:08:07 +0800 (CST)

hi, Daniel Stenberg
   
  I am using curl with version 7.16.1 and I have finished a patch to make curl support upload resume over file protocol.
   
  I have tested this patch as follows:
   
  $ curl file://upload/file1 -T /path/file2 -C 20
  $ curl file://upload/file1 -T /path/file2 -C 2000000 ( very huge parameter)
  $ curl file://upload/ -T /path/file2 -C -
  $ curl file://upload/ -T /path/file2 -C -200 ( a negative parameter )
  $ curl file://upload/file1 -T /path/file2 -C - ( file1 is bigger than file2 )
  
In the five cases above , curl works well and as expected.
   
  Best Regards
   
  Feng Tu

       
---------------------------------
ÇÀ×¢ÑÅ»¢Ãâ·ÑÓÊÏä3.5GÈÝÁ¿£¬20M¸½¼þ£¡

--- ../lib/file.c 2007-05-29 13:33:29.000000000 +0800
+++ ../file.c 2007-05-29 13:40:12.000000000 +0800
@@ -204,6 +204,8 @@
   size_t nwrite;
   curl_off_t bytecount = 0;
   struct timeval now = Curl_tvnow();
+ struct stat* file_stat;
+ char* buf;
 
   /*
    * Since FILE: doesn't do the full init, we need to provide some extra
@@ -218,8 +220,12 @@
 
   if(!dir[1])
      return CURLE_FILE_COULDNT_READ_FILE; /* fix: better error code */
-
- fp = fopen(file->path, "wb");
+
+ if( data->reqdata.resume_from )
+ fp = fopen( file->path, "ab" );
+ else
+ fp = fopen(file->path, "wb");
+
   if(!fp) {
     failf(data, "Can't open %s for writing", file->path);
     return CURLE_WRITE_ERROR;
@@ -228,20 +234,54 @@
   if(-1 != data->set.infilesize)
     /* known size of data to "upload" */
     Curl_pgrsSetUploadSize(data, data->set.infilesize);
+
+ /* treat the negative resume offset value as the case of "-" */
+ if( data->reqdata.resume_from < 0 )
+ {
+ file_stat = ( struct stat* )calloc( sizeof(struct stat), 1 );
+ if( !file_stat)
+ return CURLE_OUT_OF_MEMORY;
+
+ if( stat( file->path, file_stat ) ){
+ failf( data, "Can't get the size of %s", file->path );
+ free( file_stat );
+ return CURLE_WRITE_ERROR;
+ }
+ else{
+ data->reqdata.resume_from = ( curl_off_t )file_stat->st_size;
+ free( file_stat );
+ }
+ }
 
   while (res == CURLE_OK) {
     int readcount;
     res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount);
     if(res)
       break;
-
+
     if (readcount <= 0) /* fix questionable compare error. curlvms */
       break;
 
     nread = (size_t)readcount;
-
+
     /* write the data to the target */
- nwrite = fwrite(buf, 1, nread, fp);
+ if( data->reqdata.resume_from )
+ {
+ if( nread <= data->reqdata.resume_from )
+ {
+ data->reqdata.resume_from -= nread;
+ nread = 0;
+ }
+ else
+ {
+ buf2 = buf + data->reqdata.resume_from;
+ nread -= data->reqdata.resume_from;
+ data->reqdata.resume_from = 0;
+ }
+ }
+ else
+ buf2 = buf;
+ nwrite = fwrite(buf2, 1, nread, fp);
     if(nwrite != nread) {
       res = CURLE_SEND_ERROR;
       break;
Received on 2007-05-29