* Fixed some minor bugs and inconsistencies in kaoupload.c.
authorUrban Wallasch <urban.wallasch@freenet.de>
Sat, 17 Apr 2021 23:46:13 +0000 (01:46 +0200)
committerUrban Wallasch <urban.wallasch@freenet.de>
Sat, 17 Apr 2021 23:46:13 +0000 (01:46 +0200)
kaoupload.c

index 472dbebfeed26b690b2337de79c35f38b770ce61..6f4734cc3fd2efeb6b1e37b6d7c7d877c683a281 100644 (file)
@@ -47,7 +47,7 @@ struct membuf_t {
 static sig_atomic_t gotsig = 0;
 
 static void sig_handler( int signum ){
-  gotsig = 1;
+  gotsig = signum;
   fprintf( stderr, "\nReceived signal %d, wrapping up gracefully.\n", signum );
 }
 
@@ -159,13 +159,15 @@ static size_t write_memory_cb( void *contents, size_t size, size_t nmemb, void *
 #define RESP_HAVE       "Have "
 #define RESP_COMPLETE   "Upload complete, "
 #define RESP_SKIP       "Skip-to-position: "
+#define RESP_MISMATCH   "Partfile initial sequence mismatch"
+#define RESP_NOPERM     "<x-alert><h1>No permission!</h1></x-alert>"
 
 static int upload_chunk( CURL *curl, struct file_info_t *fi, off_t csize ) {
     int res = -1;
     int response_code;
     ssize_t br;
     char url[2048];
-    void *slice;
+    void *chunk;
     off_t completed = 0;
     CURLcode error;
     struct membuf_t reply;
@@ -175,10 +177,10 @@ static int upload_chunk( CURL *curl, struct file_info_t *fi, off_t csize ) {
 
     if ( csize > fi->remn )
         csize = fi->remn;
-    if ( NULL == ( slice = malloc( csize ) ) )
+    if ( NULL == ( chunk = malloc( csize ) ) )
         die( "malloc", errno );
     lseek( fi->fd, fi->coff, SEEK_SET );
-    if ( 0 > ( br = read( fi->fd, slice, csize ) ) ) {
+    if ( 0 > ( br = read( fi->fd, chunk, csize ) ) ) {
         err( "read", errno );
         goto err_out;
     }
@@ -189,7 +191,7 @@ static int upload_chunk( CURL *curl, struct file_info_t *fi, off_t csize ) {
     curl_easy_reset( curl );
     error = curl_easy_setopt( curl, CURLOPT_POST, 1L );
     error |= curl_easy_setopt( curl, CURLOPT_POSTFIELDSIZE, (long)csize );
-    error |= curl_easy_setopt( curl, CURLOPT_POSTFIELDS, slice );
+    error |= curl_easy_setopt( curl, CURLOPT_POSTFIELDS, chunk );
     error |= curl_easy_setopt( curl, CURLOPT_URL, url );
     error |= curl_easy_setopt( curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
     error |= curl_easy_setopt( curl, CURLOPT_USERNAME, cfg.user );
@@ -216,9 +218,7 @@ static int upload_chunk( CURL *curl, struct file_info_t *fi, off_t csize ) {
     // puts(reply.memory);
 
     switch ( response_code ) {
-    case 100:
     case 200:
-    case 201:
         // simplest case, uploaded one chunk
         if ( 0 == strncmp( reply.memory, RESP_HAVE, strlen( RESP_HAVE ) ) ) {
             fi->coff += csize;
@@ -234,8 +234,21 @@ static int upload_chunk( CURL *curl, struct file_info_t *fi, off_t csize ) {
             if ( completed == fi->coff && 0 == fi->remn )
                 res = 0;
         }
+        else if ( NULL != strstr( reply.memory, RESP_NOPERM ) ) {
+            // this really should be a 401 or 403 ...
+            err( "no permission, check credentials!", 0 );
+        }
         else
-            err( "unexpected response, check credentials?", 0 );
+            fprintf( stderr, "ERROR: unexpected response: %s", reply.memory );
+        break;
+    case 201:
+        // upon receiving the first chunk, remote detected a partfile initial
+        // sequence mismatch, refused to skip and scrapped the old partfile
+        if ( 0 == strncmp( reply.memory, RESP_MISMATCH, strlen( RESP_MISMATCH ) ) ) {
+            fi->coff += csize;
+            fi->remn -= csize;
+            res = 0;
+        }
         break;
     case 428:
         // remote already has data up to Skip-to-position
@@ -248,13 +261,13 @@ static int upload_chunk( CURL *curl, struct file_info_t *fi, off_t csize ) {
             err( "response code 428 w/o 'Skip-to-position'", 0 );
         break;
     default:
-        fprintf( stderr, "ERROR: unexpected response code: %d\n", response_code );
+        fprintf( stderr, "REMOTE ERROR: %d: %s\n", response_code, reply.memory );
         break;
     }
 
   err_out:
     free( reply.memory );
-    free( slice );
+    free( chunk );
     return res;
 }
 
@@ -282,7 +295,7 @@ static int upload_file( const char *fn ) {
     }
     fi.remn = fi.size = stbuf.st_size;
     fi.coff = 0;
-    printf( "File: %s, %lu bytes\n", fi.name, (unsigned long)fi.size );
+    printf( "File: %s (%lu bytes)\n", fi.name, (unsigned long)fi.size );
 
     while ( fi.remn ) {
         if ( gotsig ) {
@@ -295,9 +308,9 @@ static int upload_file( const char *fn ) {
             csize = 2 * fi.speed;
         if ( CSIZE_HARDLIMIT < csize )
             csize = CSIZE_HARDLIMIT;
-        printf( "\r%3.f%% (%5.1f kB/s) ", (double)fi.coff * 100 / fi.size, (double)fi.speed / 1024 );
-        // printf( "[csize: %ld] {offset: %ld} ", (long)csize, (long)fi.coff );
-        fflush( stdout );
+        fprintf( stderr, "\r%3.f%% (%5.1f kB/s) ", (double)fi.coff * 100 / fi.size, (double)fi.speed / 1024 );
+        // fprintf( stderr, "[csize: %ld] {offset: %ld} ", (long)csize, (long)fi.coff );
+        fflush( stderr );
     }
     if ( res < 0 ) {
         puts( "" );
@@ -340,7 +353,7 @@ int main( int argc, char *argv[] ) {
     cfg.url = strdup( getenv( "URL" ) ? getenv( "URL" ) : URL_BASE );
     cfg.bwlup = str_to_bwl( getenv( "BWLUP" ) ? getenv( "BWLUP" ) : "0" );
     snprintf( confpath, sizeof confpath, "%s/%s", getenv( "HOME" ), CFG_BASE );
-    while ( ( c = getopt( argc, argv, ":c:" ) ) != -1 ) {
+    while ( ( c = getopt( argc, argv, "+:c:" ) ) != -1 ) {
         switch (c) {
         case 'c':
             snprintf( confpath, sizeof confpath, "%s", optarg );
@@ -355,8 +368,8 @@ int main( int argc, char *argv[] ) {
     }
     parse_cfg( confpath );
 
-    optind = 1;
-    while ( ( c = getopt( argc, argv, ":c:hl:p:u:U:" ) ) != -1 ) {
+    optind = 0;
+    while ( ( c = getopt( argc, argv, "+:c:hl:p:u:U:" ) ) != -1 ) {
         switch (c) {
         case 'c':
             // already handled above