diff options
-rw-r--r-- | src/gateleen_resclone/gateleen_resclone.c | 614 | ||||
-rw-r--r-- | src/log/log.c | 32 | ||||
-rw-r--r-- | src/log/log.h | 25 |
3 files changed, 316 insertions, 355 deletions
diff --git a/src/gateleen_resclone/gateleen_resclone.c b/src/gateleen_resclone/gateleen_resclone.c index a49990f..4501125 100644 --- a/src/gateleen_resclone/gateleen_resclone.c +++ b/src/gateleen_resclone/gateleen_resclone.c @@ -19,7 +19,6 @@ /* Project */ #include "array.h" -#include "log.h" #include "mime.h" #include "util_string.h" @@ -151,8 +150,7 @@ printHelp( void ) static int parseArgs( int argc, char**argv, opMode_t*mode, char**url, regex_t**filter, size_t*filter_cnt, - bool*isFilterFull, char**file ) -{ + bool*isFilterFull, char**file ){ ssize_t err, ret=0; char *filterRaw = NULL; if( argc == -1 ){ // -1 indicates the call to free our resources. So simply jump @@ -236,8 +234,7 @@ parseArgs( int argc, char**argv, opMode_t*mode, char**url, regex_t**filter, size (*url)[url_len-1] = '/'; (*url)[url_len] = '\0'; }else{ - *url = strdup( *url ); // Make our own string (so we've no fear to call - // free on it later) + *url = strdup(*url); } if( filterRaw ){ @@ -259,103 +256,111 @@ parseArgs( int argc, char**argv, opMode_t*mode, char**url, regex_t**filter, size end[1] = '\0'; // <- Temporary terminate to compile segment only. if( iSegm >= filter_cap ){ filter_cap += 8; - *filter = realloc( *filter, filter_cap*sizeof(**filter) ); - //LOG_DEBUG("%s%u%s%p\n", "realloc( NULL, ", filter_cap*sizeof(**filter)," ) -> ", *filter ); - if( !*filter ){ LOG_ERROR("%s%d%s\n","realloc(",filter_cap*sizeof(**filter),")"); ret=-ENOMEM; goto fail; } + void *tmp = realloc(*filter, filter_cap*sizeof**filter); + //fprintf(stderr, "%s%u%s%p\n", + // "[DEBUG] realloc(NULL, ", filter_cap*sizeof**filter," ) -> ", tmp); + if( tmp == NULL ){ + fprintf(stderr, "%s%d%s\n", "[ERROR] realloc(", filter_cap*sizeof**filter, ")"); + ret = -ENOMEM; goto fail; } + *filter = tmp; } - //LOG_DEBUG("%s%d%s%s%s\n", "filter[", iSegm, "] -> '", beg-1, "'"); + //fprintf(stderr, "%s%d%s%s%s\n", "[DEBUG] filter[", iSegm, "] -> '", beg-1, "'"); err = regcomp( (*filter)+iSegm, beg-1, REG_EXTENDED); - if( err ){ LOG_ERROR("%s%s%s%d\n","regcomp(",beg,") -> ", err); return -1; } + if( err ){ + fprintf(stderr, "%s%s%s%d\n", "[ERROR] regcomp(", beg, ") -> ", err); + ret = -1; goto fail; } // Restore surrounding stuff. beg[-1] = origBeg; *end = origSep; // <- Restore tmp 'end-of-match' ($). end[1] = origNext; // <- Restore tmp termination. if( *end=='\0' ){ // EOF *filter_cnt = iSegm +1; - *filter = realloc( *filter, *filter_cnt *sizeof(**filter) ); // Trim result. - free( buf ); buf=NULL; + *filter = realloc(*filter, *filter_cnt *sizeof(**filter)); // Trim result. + assert(*filter != NULL); + free(buf); buf = NULL; break; } } } - if( *mode==MODE_PUSH && *filter ){ - printf("%s\n", "ERROR: Filtering not supported for push mode."); + if( *mode == MODE_PUSH && *filter ){ + fprintf(stderr, "%s\n", "[ERROR] Filtering not supported for push mode."); ret = -1; goto fail; } return 0; - fail: - free( *url ); *url=NULL; +fail: + free(*url); *url = NULL; for( uint_t i=0 ; i<*filter_cnt ; ++i ){ regfree( &(filter[0][i]) ); } *filter_cnt = 0; - free( *filter ); *filter=NULL; + free(*filter); *filter = NULL; return ret; } static size_t -onCurlDirRsp( char*buf , size_t size , size_t nmemb , void*cls_resourceDir_ ) -{ - //LOG_DEBUG( "%s%s%p%s%ld%s%ld%s%p%s\n" , __func__, "( buf=", buf, ", size=", size, ", nmemb=", nmemb, ", cls=", cls_resourceDir_, " )" ); - ssize_t err, ret = size*nmemb; +onCurlDirRsp( char*buf, size_t size, size_t nmemb, void*cls_resourceDir_ ){ + fprintf(stderr, "%s%s%s%p%s%ld%s%ld%s%p%s\n", "[TRACE] ", __func__, "( buf=", buf, + ", size=", size, ", nmemb=", nmemb, ", cls=", cls_resourceDir_, " )"); cls_resourceDir_t *resourceDir = cls_resourceDir_; cls_dload_t *dload = resourceDir->dload; CURL *curl = dload->curl; const size_t buf_len = size * nmemb; long rspCode; - curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &rspCode ); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &rspCode); resourceDir->rspCode = rspCode; if( rspCode != 200 ){ - goto endFn; - } + return size * nmemb; } // Collect whole response body into one buf (as cJSON seems unable to parse // partially) if( resourceDir->rspBody_cap < resourceDir->rspBody_len + buf_len +1 ){ - // Enlarge buf + /* Enlarge buf */ resourceDir->rspBody_cap = resourceDir->rspBody_len + buf_len + 1024; - resourceDir->rspBody = realloc( resourceDir->rspBody, resourceDir->rspBody_cap ); + void *tmp = realloc(resourceDir->rspBody, resourceDir->rspBody_cap); + if( tmp == NULL ){ + err = size*nmemb/*TODO could we return anything better here?*/; goto endFn; } + resourceDir->rspBody = tmp; } - memcpy( resourceDir->rspBody+resourceDir->rspBody_len, buf, buf_len ); + memcpy(resourceDir->rspBody+resourceDir->rspBody_len, buf, buf_len); resourceDir->rspBody_len += buf_len; resourceDir->rspBody[resourceDir->rspBody_len] = '\0'; // Parsing occurs in the caller, as soon we processed whole response. - endFn: - return ret; + err = size*nmemb; +endFn: + return err; } static size_t -onResourceChunk( char*buf , size_t size , size_t nmemb , void*cls_resourceFile_ ) -{ - int buf_len = size * nmemb; - int ret = buf_len; +onResourceChunk( char*buf, size_t size, size_t nmemb, void*cls_resourceFile_ ){ + const int buf_len = size * nmemb; cls_resourceFile_t *resourceFile = cls_resourceFile_; - int avail = resourceFile->buf_memSz - resourceFile->buf_len; + const int avail = resourceFile->buf_memSz - resourceFile->buf_len; if( avail <= buf_len ){ resourceFile->buf_memSz += buf_len - avail +1; - resourceFile->buf = realloc( resourceFile->buf , resourceFile->buf_memSz ); + void *tmp = realloc(resourceFile->buf , resourceFile->buf_memSz); + assert(tmp != NULL); /* TODO error handling */ + resourceFile->buf = tmp; } char *it = resourceFile->buf + resourceFile->buf_len; - memcpy( it , buf , buf_len ); it+=buf_len; + memcpy(it, buf, buf_len); it += buf_len; *it = '\0'; resourceFile->buf_len = it - resourceFile->buf; - return ret; + return buf_len; } static ssize_t -collectResourceIntoMemory( cls_resourceFile_t*resourceFile , char*url ) -{ - ssize_t err, ret=0; +collectResourceIntoMemory( cls_resourceFile_t*resourceFile, char*url ){ + ssize_t err; cls_dload_t *dload = resourceFile->dload; CURL *curl = dload->curl; @@ -364,69 +369,74 @@ collectResourceIntoMemory( cls_resourceFile_t*resourceFile , char*url ) || CURLE_OK!= curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onResourceChunk) || CURLE_OK!= curl_easy_setopt(curl, CURLOPT_WRITEDATA, resourceFile) ; - if( err ){ assert(!err); ret=-1; goto finally; } + if( err ){ assert(!err); err=-1; goto endFn; } - err = curl_easy_perform( curl ); - if( err!=CURLE_OK ){ - LOG_ERROR("%s%s%s%s%ld%s%s\n", __func__, "(): '",url,"' (code ", err, "): ", curl_easy_strerror(err)); - ret=-1; goto finally; + err = curl_easy_perform(curl); + if( err != CURLE_OK ){ + fprintf(stderr, "%s%s%s%s%s%ld%s%s\n", "[ERROR] ", __func__, "(): '", + url, "' (code ", err, "): ", curl_easy_strerror(err)); + err = -1; goto endFn; } - finally: - return ret; + err = 0; +endFn: + return err; } static ssize_t -copyBufToArchive( cls_resourceFile_t*resourceFile ) -{ - ssize_t err, ret=0; +copyBufToArchive( cls_resourceFile_t*resourceFile ){ + ssize_t err; cls_dload_t *dload = resourceFile->dload; char *fileName = resourceFile->url + strlen(resourceFile->dload->rootUrl); if( ! dload->dstArchive ){ // Setup archive if not setup yet. dload->dstArchive = archive_write_new(); - err = archive_write_set_format_pax_restricted( dload->dstArchive ) - || archive_write_open_filename( dload->dstArchive , dload->archiveFile ) + err = archive_write_set_format_pax_restricted(dload->dstArchive) + || archive_write_open_filename(dload->dstArchive, dload->archiveFile) ; if( err ){ - LOG_ERROR("%s%s%s\n", __func__, "(): Failed to setup tar output: ", archive_error_string(dload->dstArchive)); - ret = -1; goto endFn; + fprintf(stderr, "%s%s\n", "[ERROR] Failed to setup tar output: ", + archive_error_string(dload->dstArchive)); + err = -1; goto endFn; } } if( ! dload->tmpEntry ){ dload->tmpEntry = archive_entry_new(); }else{ - dload->tmpEntry = archive_entry_clear( dload->tmpEntry ); + dload->tmpEntry = archive_entry_clear(dload->tmpEntry); } archive_entry_set_pathname(dload->tmpEntry, fileName); archive_entry_set_filetype(dload->tmpEntry, AE_IFREG); archive_entry_set_size(dload->tmpEntry, resourceFile->buf_len); archive_entry_set_perm(dload->tmpEntry, 0644); err = archive_write_header(dload->dstArchive, dload->tmpEntry); - if( err ){ ret=-1; goto endFn; } + if( err ){ + err=-1; goto endFn; } - ssize_t written = archive_write_data( dload->dstArchive , resourceFile->buf , resourceFile->buf_len ); + ssize_t written = archive_write_data(dload->dstArchive, resourceFile->buf, resourceFile->buf_len); if( written < 0 ){ - LOG_ERROR("%s%s%s\n", __func__, "Failed to archive_write_data: ", archive_error_string(dload->dstArchive)); - ret = -1; goto endFn; + fprintf(stderr, "%s%s\n", "[ERROR] Failed to archive_write_data: ", + archive_error_string(dload->dstArchive)); + err = -1; goto endFn; }else if( written != resourceFile->buf_len ){ - LOG_ERROR("%s%s%u%s%lu\n", __func__, "(): archive_write_data failed to write all ", resourceFile->buf_len, " bytes. Instead it wrote ", written); - ret = -1; goto endFn; + fprintf(stderr, "%s%u%s%lu\n", "[ERROR] archive_write_data failed to write all ", + resourceFile->buf_len, " bytes. Instead it wrote ", written); + err = -1; goto endFn; } resourceFile->buf_len = 0; - endFn: - return ret; + err = 0; +endFn: + return err; } /** @return 0:Reject, 1:Accept, <0:ERROR */ -static ssize_t pathFilterAcceptsEntry( cls_dload_t*dload, cls_resourceDir_t*resourceDir, const char*nameOrig ) -{ - ssize_t err, ret=1; // <- Accept per default. +static ssize_t pathFilterAcceptsEntry( cls_dload_t*dload, cls_resourceDir_t*resourceDir, const char*nameOrig ){ + ssize_t err; char *name = strdup( nameOrig ); uint_t name_len = strlen( name ); @@ -437,11 +447,11 @@ static ssize_t pathFilterAcceptsEntry( cls_dload_t*dload, cls_resourceDir_t*reso // Check if we even have such a long filter at all. if( idx >= dload->this->filter_len ){ if( dload->this->isFilterFull ){ - //LOG_DEBUG("%s\n", "Path longer than --filter-full -> reject."); - ret = 0; goto finally; + //fprintf(stderr, "%s\n", "[DEBUG] Path longer than --filter-full -> reject."); + err = 0; goto endFn; }else{ - //LOG_DEBUG("%s\n", "Path longer than --filter-part -> accept."); - ret = 1; goto finally; + //fprintf(stderr, "%s\n", "[DEBUG] Path longer than --filter-part -> accept."); + err = 1; goto endFn; } } // We have a regex. Setup the check. @@ -450,38 +460,37 @@ static ssize_t pathFilterAcceptsEntry( cls_dload_t*dload, cls_resourceDir_t*reso restoreEndSlash = true; name[name_len-1] = '\0'; } - //LOG_DEBUG("%s%u%s%s%s\n", "idx=",idx," name='", name, "'"); + //fprintf(stderr, "%s%u%s%s%s\n", "[DEBUG] idx=", idx," name='", name, "'"); regex_t *filterArr = dload->this->filter; regex_t *r = filterArr + (idx); - err = regexec( r, name, 0, 0, 0 ); - if( ! err ){ - //LOG_DEBUG("%s\n", "Segment accepted by filter."); - ret = 1; - }else if( err==REG_NOMATCH ){ - //LOG_DEBUG("%s\n", "Segment rejected by filter."); - ret = 0; + err = regexec(r, name, 0, 0, 0); + if( !err ){ + //fprintf(stderr, "%s\n", "[DEBUG] Segment accepted by filter."); + err = 1; /* fall to restoreEndSlash */ + }else if( err == REG_NOMATCH ){ + //fprintf(stderr, "%s\n", "[DEBUG] Segment rejected by filter."); + err = 0; /* fall to restoreEndSlash */ }else{ - LOG_ERROR("%s%.*s%s%d\n", "regexec(rgx, '",(int)name_len,name,"') -> ", err ); - ret = -1; + fprintf(stderr, "%s%.*s%s%d\n", "[ERROR] regexec(rgx, '", (int)name_len, name, "') -> ", err); + err = -1; /* fall to restoreEndSlash */ } if( restoreEndSlash ){ name[name_len-1] = '/'; } - goto finally; + goto endFn; } - finally: - free( name ); - return ret; + err = 1; /* accept by default */ +endFn: + free(name); + return err; } /** Gets called for every resource to scan/download. * HINT: Gets called recursively. */ -static ssize_t -gateleenResclone_download( cls_dload_t*dload , cls_resourceDir_t*parentResourceDir , char*entryName ) -{ - ssize_t err, ret=0; +static ssize_t gateleenResclone_download( cls_dload_t*dload , cls_resourceDir_t*parentResourceDir , char*entryName ){ + ssize_t err; char *url = NULL; int url_len = 0; cJSON *jsonRoot = NULL; @@ -489,8 +498,8 @@ gateleenResclone_download( cls_dload_t*dload , cls_resourceDir_t*parentResourceD cls_resourceDir_t *resourceDir = NULL; cls_resourceFile_t *resourceFile = NULL; - if( !entryName ){ - // Is the case when its the root call and not a recursive one. + if( entryName == NULL ){ + /* Is the case when its the root call and not a recursive one */ entryName = dload->rootUrl; } @@ -498,7 +507,7 @@ gateleenResclone_download( cls_dload_t*dload , cls_resourceDir_t*parentResourceD cls_resourceDir_t _1={0}; resourceDir =&_1; resourceDir->dload = dload; resourceDir->parentDir = parentResourceDir; - resourceDir->name = strdup( entryName ); + resourceDir->name = strdup(entryName); // Configure client { @@ -507,231 +516,229 @@ gateleenResclone_download( cls_dload_t*dload , cls_resourceDir_t*parentResourceD int len = strlen(d->name) - strspn(d->name, "/"); url_len += len; } - url = malloc( url_len +1 /*MightPreventReallocLaterForName*/+24 ); + url = malloc(url_len +1 /*MayPreventReallocLaterForName*/+24); char *u = url + url_len; for( cls_resourceDir_t*d=resourceDir ; d ; d=d->parentDir ){ - char *name = d->name + strspn( d->name , "/" ); + char *name = d->name + strspn(d->name, "/"); int name_len = strlen(name); - memcpy( u-name_len , name , name_len ); u-=name_len; + memcpy(u-name_len, name, name_len); u -= name_len; } url[url_len] = '\0'; - //LOG_DEBUG("%s%s%s%s\n", __func__, "(): URL '",url,"'"); + //fprintf(stderr, "%s%s%s\n", "[DEBUG] URL '", url, "'"); err = CURLE_OK != curl_easy_setopt(dload->curl, CURLOPT_URL, url) - || CURLE_OK != curl_easy_setopt(dload->curl, CURLOPT_FOLLOWLOCATION, 0L ) + || CURLE_OK != curl_easy_setopt(dload->curl, CURLOPT_FOLLOWLOCATION, 0L) || CURLE_OK != curl_easy_setopt(dload->curl, CURLOPT_WRITEFUNCTION, onCurlDirRsp) || CURLE_OK != curl_easy_setopt(dload->curl, CURLOPT_WRITEDATA, resourceDir) ; - if( err ){ assert(!err); ret=-1; goto finally; } + if( err ){ + assert(!err); err = -1; goto endFn; } } - err = curl_easy_perform( dload->curl ); - if( err!=CURLE_OK ){ - LOG_ERROR("%s%s%s%s%ld%s%s\n", __func__, "(): '",url,"' (code ", err, "): ", curl_easy_strerror(err)); - ret=-1; goto finally; + err = curl_easy_perform(dload->curl); + if( err != CURLE_OK ){ + fprintf(stderr, "%s%s%s%ld%s%s\n", + "[ERROR] '", url, "' (code ", err, "): ", curl_easy_strerror(err)); + err = -1; goto endFn; } if( resourceDir->rspCode == ERR_PARSE_DIR_LIST ){ - goto finally; // Already logged by sub-ctxt. Simply skip to next entry. + err = 0; goto endFn; /* Already logged by sub-ctxt. Simply skip to next entry. */ } if( resourceDir->rspCode != 200 ){ // Ugh? Just one request earlier, server said there's a directory on - // that URL. Never mind. Just skip it and at least download the other + // that URL. Nevermind. Just skip it and at least download the other // stuff. - LOG_WARN("%s%d%s%s%s\n", "Skip HTTP ", resourceDir->rspCode ," -> '",url,"'"); - goto finally; + fprintf(stderr, "%s%d%s%s%s\n", "[INFO ] Skip HTTP ", resourceDir->rspCode, " -> '", url, "'"); + err = 0; goto endFn; } // Parse the collected response body. - // I would like to NOT rely on zero-terminated strings. But did not find any - // better API for this yet. - jsonRoot = cJSON_Parse( resourceDir->rspBody ); + jsonRoot = cJSON_Parse(resourceDir->rspBody); if( ! cJSON_IsObject(jsonRoot) ){ // TODO: Handle case - LOG_ERROR("%s\n", "JSON root expected to be object but is not."); - err = -1; goto finally; + fprintf(stderr, "%s\n", "[ERROR] JSON root expected to be object but is not."); + err = -1; goto endFn; } - // Do some validations to get to the payload we're interested in. + /* Do some validations to get to the payload we're interested in. */ if( cJSON_GetArraySize(jsonRoot) != 1 ){ - LOG_ERROR("%s%d\n", "JSON root expected ONE child but got ", cJSON_GetArraySize(jsonRoot) ); - err = -1; goto finally; + fprintf(stderr, "%s%d\n", "[ERROR] JSON root expected ONE child but got ", + cJSON_GetArraySize(jsonRoot)); + err = -1; goto endFn; } cJSON *data = jsonRoot->child; - //LOG_DEBUG( "%s%s%s\n", "Processing json['", data->string, "']" ); + //fprintf(stderr, "%s%s%s\n", "[DEBUG] Processing json['", data->string, "']"); if( ! cJSON_IsArray(data) ){ - LOG_ERROR("%s%s%s\n", "json['", data->string,"'] expected to be an array. But is not." ); - err = -1; goto finally; + fprintf(stderr, "%s%s%s\n", "[ERROR] json['", data->string, + "'] expected to be an array. But is not."); + err = -1; goto endFn; } // Iterate all the entries we have to process. - cls_resourceFile_t _2={0}; resourceFile =&_2; + cls_resourceFile_t _2 = {0}; resourceFile =&_2; resourceFile->dload = dload; uint_t iDirEntry = 0; for( cJSON *arrEntry=data->child ; arrEntry!=NULL ; arrEntry=arrEntry->next ){ if( ! cJSON_IsString(arrEntry) ){ - LOG_ERROR("%s%s%u%s\n", data->string,"['", iDirEntry,"'] expected to be a string. But is not." ); - err = -1; goto finally; + fprintf(stderr, "%s%s%s%u%s\n", "[ERROR] ", data->string, "['", iDirEntry, + "'] expected to be a string. But is not." ); + err = -1; goto endFn; } - //LOG_DEBUG("%s%s%u%s%s%s\n", data->string, "[", iDirEntry, "] -> ", arrEntry->valuestring, ""); + //fprintf(stderr, "%s%s%s%u%s%s\n", "[DEBUG] ", data->string, "[", iDirEntry, "] -> ", arrEntry->valuestring); char *name = arrEntry->valuestring; - int name_len = strlen( name ); + int name_len = strlen(name); - err = pathFilterAcceptsEntry( dload, resourceDir, name ); - if( err<0 ){ // ERROR - ret = err; goto finally; - }else if( err==0 ){ // REJECT - LOG_INFO("%s%s%s%s\n", "Skip '", url, name, "' (filtered)"); + err = pathFilterAcceptsEntry(dload, resourceDir, name); + if( err < 0 ){ // ERROR + goto endFn; + }else if( err == 0 ){ // REJECT + fprintf(stderr, "%s%s%s%s\n", "[INFO ] Skip '", url, name, "' (filtered)"); continue; }else{ // ACCEPT // Go ahead. } - if( name[name_len-1]=='/' ){ // Gateleen reports a 'directory' - //LOG_DEBUG("%s%s%s%s\n", "Scan '", url, name,"'"); - err = gateleenResclone_download( dload , resourceDir , name ); - if( err ){ ret=err; goto finally; } - } - else{ // Not a 'dir'? Then assume 'file' + if( name[name_len-1] == '/' ){ // Gateleen reports a 'directory' + //fprintf(stderr, "%s%s%s%s\n", "[DEBUG] Scan '", url, name,"'"); + err = gateleenResclone_download(dload, resourceDir, name); + if( err ){ + goto endFn; } + }else{ // Not a 'dir'? Then assume 'file' int requiredLen = url_len + 1/*slash*/ + name_len; if( resUrl_len < requiredLen ){ - resourceFile->url = realloc( resourceFile->url , requiredLen +1 ); + void *tmp = realloc(resourceFile->url, requiredLen +1); + if( tmp == NULL ){ + err = -ENOMEM; goto endFn; } + resourceFile->url = tmp; resUrl_len = requiredLen; } - sprintf(resourceFile->url, "%s%s", url , name ); - LOG_INFO("%s%s%s\n", "Download '", resourceFile->url, "'"); + sprintf(resourceFile->url, "%s%s", url, name); + fprintf(stderr, "%s%s%s\n", "[INFO ] Download '", resourceFile->url, "'"); resourceFile->buf_len = 0; // <- Reset before use. - collectResourceIntoMemory( resourceFile , resourceFile->url ); - copyBufToArchive( resourceFile ); + collectResourceIntoMemory(resourceFile, resourceFile->url); + copyBufToArchive(resourceFile); } iDirEntry += 1; } - finally: + err = 0; /* OK */ +endFn: if( jsonRoot != NULL ){ cJSON_Delete(jsonRoot); } if( resourceFile ){ free(resourceFile->buf); resourceFile->buf = NULL; - free( resourceFile->url ); resourceFile->url = NULL; + free(resourceFile->url); resourceFile->url = NULL; } if( resourceDir ){ - free( resourceDir->name ); resourceDir->name = NULL; - free( resourceDir->rspBody ); resourceDir->rspBody = NULL; + free(resourceDir->name); resourceDir->name = NULL; + free(resourceDir->rspBody); resourceDir->rspBody = NULL; } - free( url ); - return ret; + free(url); + return err; } -static void -this_free( this_t*this ) -{ - if( this==NULL ) return; - +static void this_free( this_t*this ){ + if( this == NULL ) return; // TODO need free? -> char *url; // TODO need free? -> regex_t *filter; // TODO need free? -> char *file; - - free( this ); + free(this); } -static this_t* -this_alloc() -{ + +static this_t* this_alloc(){ ssize_t err; this_t *this = NULL; - err = curl_global_init( CURL_GLOBAL_ALL ); - if( err ){ assert(!err); goto fail; } + err = curl_global_init(CURL_GLOBAL_ALL); + if( err ){ + assert(!err); goto fail; } - this = calloc(1, sizeof(*this) ); + this = calloc(1, sizeof*this); return this; fail: - this_free( this ); + this_free(this); return NULL; } -static size_t -onUploadChunkRequested( char*buf , size_t size , size_t count , void*cls_put_ ) -{ +static size_t onUploadChunkRequested( char*buf, size_t size, size_t count, void*cls_put_ ){ + int err; cls_put_t *put = cls_put_; cls_upload_t *upload = put->upload; const size_t buf_len = size * count; - ssize_t ret = buf_len; ssize_t readLen = archive_read_data(upload->srcArchive, buf, buf_len); - //LOG_DEBUG("%s%lu%s\n", "Cpy ",readLen," bytes."); - if( readLen<0 ){ - LOG_ERROR("%s%ld%s%s\n", "Failed to read from archive (code ",readLen,"): ", archive_error_string(upload->srcArchive)); - assert(0); ret=-1; goto endFn; - } - else if( readLen>0 ){ + //fprintf(stderr, "%s%lu%s\n", "[DEBUG] Cpy ", readLen, " bytes."); + if( readLen < 0 ){ + fprintf(stderr, "%s%ld%s%s\n", "[ERROR] Failed to read from archive (code ", + readLen, "): ", archive_error_string(upload->srcArchive)); + err = -1; goto endFn; + }else if( readLen > 0 ){ // Regular read. Data already written to 'buf'. Only need to adjust // return val. - ret = readLen; - } - else{ // readLen==0 -> EOF - ret = 0; // Nothing more to read. + err = readLen; goto endFn; + }else{ // EOF + assert(readLen == 0); + err = 0; goto endFn; } - - endFn: - //LOG_DEBUG("%s%s%ld\n", __func__, "() -> ", ret); - return ret>=0 ? ret : CURL_READFUNC_ABORT; + assert(!"Unreachable code"); +endFn: + //fprintf(stderr, "%s%s%s%ld\n", "[DEBUG] ", __func__, "() -> ", err); + return err >= 0 ? err : CURL_READFUNC_ABORT; } -static ssize_t -addContentTypeHeader( cls_put_t*put , struct curl_slist *reqHdrs ) -{ - ssize_t err, ret=0; +static ssize_t addContentTypeHeader( cls_put_t*put, struct curl_slist *reqHdrs ){ + ssize_t err; char *contentTypeHdr = NULL; cls_upload_t *upload = put->upload; const char *name = put->name; - uint_t name_len = strlen( put->name ); + uint_t name_len = strlen(put->name); // Find file extension. const char *ext = name + name_len; for(; ext>name && *ext!='.' && *ext!='/' ; --ext ); // Convert it to mime type. const char *mimeType; - if( *ext=='.' ){ - mimeType = fileExtToMime( ext+1 ); // <- +1, to skip the (useless) dot. + if( *ext == '.' ){ + mimeType = fileExtToMime(ext +1); // <- +1, to skip the (useless) dot. if( mimeType ){ - //LOG_DEBUG("%s%s%s%s%s\n", "Resolved file ext '", ext+1,"' to mime '", mimeType?mimeType:"<null>", "'."); + //fprintf(stderr, "%s%s%s%s%s\n", "[DEBUG] Resolved file ext '", ext+1,"' to mime '", mimeType?mimeType:"<null>", "'."); } - } - else if( *ext=='/' || ext==name || *ext=='\0' ){ // TODO Explain why 0x00. + }else if( *ext=='/' || ext==name || *ext=='\0' ){ // TODO Explain why 0x00. mimeType = "application/json"; - //LOG_DEBUG("%s\n", "No file extension. Fallback to json (gateleen default)"); - } - else{ + //fprintf(stderr, "%s\n", "[DEBUG] No file extension. Fallback to json (gateleen default)"); + }else{ mimeType = NULL; } - if( mimeType==NULL ){ - //LOG_DEBUG("%s%s%s\n", "Unknown file extension '", ext+1, "'. Will NOT add Content-Type header."); + if( mimeType == NULL ){ + //fprintf(stderr, "%s%s%s\n", "[DEBUG] Unknown file extension '", ext+1, "'. Will NOT add Content-Type header."); mimeType = ""; // <- Need to 'remove' header. To do this, pass an empty value to curl. } - uint_t mimeType_len = strlen( mimeType ); + uint_t mimeType_len = strlen(mimeType); static const char contentTypePrefix[] = "Content-Type: "; static const uint_t contentTypePrefix_len = sizeof(contentTypePrefix)-1; contentTypeHdr = malloc( contentTypePrefix_len + mimeType_len +1 ); - memcpy( contentTypeHdr , contentTypePrefix , contentTypePrefix_len ); - memcpy( contentTypeHdr+contentTypePrefix_len , mimeType , mimeType_len+1 ); - reqHdrs = curl_slist_append( reqHdrs, contentTypeHdr ); - err = curl_easy_setopt( upload->curl, CURLOPT_HTTPHEADER, reqHdrs ); - if( err ){ assert(!err); ret=-1; goto endFn; } - - endFn: - free( contentTypeHdr ); - return ret; + memcpy(contentTypeHdr , contentTypePrefix , contentTypePrefix_len); + memcpy(contentTypeHdr+contentTypePrefix_len , mimeType , mimeType_len+1); + reqHdrs = curl_slist_append(reqHdrs, contentTypeHdr); + err = curl_easy_setopt(upload->curl, CURLOPT_HTTPHEADER, reqHdrs); + if( err ){ + fprintf(stderr, "%s\n", "[ERROR] curl_easy_setopt(_, HTTPHEADER, _)", err); + assert(!err); err = -1; goto endFn; } + + err = 0; +endFn: + free(contentTypeHdr); + return err; } -static ssize_t -httpPutEntry( cls_put_t*put ) -{ - ssize_t err, ret = 0; +static ssize_t httpPutEntry( cls_put_t*put ){ + ssize_t err; cls_upload_t *upload = put->upload; char *url = NULL; struct curl_slist *reqHdrs = NULL; @@ -741,125 +748,134 @@ httpPutEntry( cls_put_t*put ) rootUrl_len -= 1; } int url_len = strlen(upload->rootUrl) + strlen(put->name); - url = malloc( url_len +2 ); + url = malloc(url_len +2); + if( url = NULL ){ + err = -ENOMEM; goto endFn; } sprintf(url, "%.*s/%s", rootUrl_len,upload->rootUrl, put->name); - err = CURLE_OK != curl_easy_setopt(upload->curl, CURLOPT_URL, url ) - || addContentTypeHeader( put , reqHdrs ) + err = CURLE_OK != curl_easy_setopt(upload->curl, CURLOPT_URL, url) + || addContentTypeHeader(put, reqHdrs) ; - if( err ){ assert(!err); ret=-1; goto endFn; } + if( err ){ + assert(!err); err = -1; goto endFn; } - LOG_INFO("%s%s%s\n", "Upload '",url,"'"); - err = curl_easy_perform( upload->curl ); - if( err!=CURLE_OK ){ - LOG_ERROR("%s%s%s%ld%s%s\n", "PUT '",url,"' (code ", err, "): ", curl_easy_strerror(err)); - ret=-1; goto endFn; + fprintf(stderr, "%s%s%s\n", "[INFO ] Upload '", url, "'"); + err = curl_easy_perform(upload->curl); + if( err != CURLE_OK ){ + fprintf(stderr, "%s%s%s%ld%s%s\n", + "[ERROR] PUT '", url, "' (code ", err, "): ", curl_easy_strerror(err)); + err = -1; goto endFn; } long rspCode; curl_easy_getinfo(upload->curl, CURLINFO_RESPONSE_CODE, &rspCode); - if( rspCode<=199 || rspCode>=300 ){ - LOG_WARN("%s%ld%s%s%s\n", "Got RspCode ", rspCode, " for 'PUT ", url, "'"); + if( rspCode <= 199 || rspCode >= 300 ){ + fprintf(stderr, "%s%ld%s%s%s\n", + "[WARN ] Got RspCode ", rspCode, " for 'PUT ", url, "'"); }else{ - //LOG_DEBUG("%s%ld%s%s%s\n", "Got RspCode ", rspCode, " for 'PUT ", url, "'"); + //fprintf(stderr, "%s%ld%s%s%s\n", "[DEBUG] Got RspCode ", rspCode, " for 'PUT ", url, "'"); } - endFn: - curl_slist_free_all( reqHdrs ); - free( url ); - return ret; + err = 0; +endFn: + curl_slist_free_all(reqHdrs); + free(url); + return err; } -static ssize_t -readArchive( cls_upload_t*upload ) -{ - ssize_t err, ret=0; +static ssize_t readArchive( cls_upload_t*upload ){ + ssize_t err; cls_put_t *put = NULL; upload->srcArchive = archive_read_new(); - if( ! upload->srcArchive ){ assert(upload->srcArchive); ret=-1; goto endFn; } + if( ! upload->srcArchive ){ + assert(upload->srcArchive); err = -1; goto endFn; } - const int blockSize = 16384; // <- Because curl examples use this value too. - err = archive_read_support_format_all( upload->srcArchive ) - || archive_read_open_filename( upload->srcArchive , upload->archiveFile , blockSize ) + const int blockSize = (1<<14); + err = archive_read_support_format_all(upload->srcArchive) + || archive_read_open_filename(upload->srcArchive, upload->archiveFile, blockSize) ; if( err ){ - LOG_ERROR("%s%ld%s%s\n", "Failed to open src archive (code ",err,"): ", curl_easy_strerror(err) ); - ret=-1; goto endFn; + fprintf(stderr, "%s%ld%s%s\n", "[ERROR] Failed to open src archive (code ", err, "): ", + curl_easy_strerror(err)); + err = -1; goto endFn; } - err = curl_easy_setopt( upload->curl, CURLOPT_UPLOAD, 1L) - || curl_easy_setopt( upload->curl, CURLOPT_READFUNCTION, onUploadChunkRequested ) + err = curl_easy_setopt(upload->curl, CURLOPT_UPLOAD, 1L) + || curl_easy_setopt(upload->curl, CURLOPT_READFUNCTION, onUploadChunkRequested) ; - if( err ){ assert(!err); ret=-1; goto endFn; } - for( struct archive_entry*entry ; archive_read_next_header(upload->srcArchive,&entry)==ARCHIVE_OK ;){ - const char *name = archive_entry_pathname( entry ); - int ftype = archive_entry_filetype( entry ); + if( err ){ + assert(!err); err = -1; goto endFn; } + for( struct archive_entry*entry ; archive_read_next_header(upload->srcArchive,&entry) == ARCHIVE_OK ;){ + const char *name = archive_entry_pathname(entry); + int ftype = archive_entry_filetype(entry); if( ftype == AE_IFDIR ){ continue; // Ignore dirs because gateleen doesn't know 'dirs' as such. } if( ftype != AE_IFREG ){ - LOG_WARN("%s%s%s\n", "Ignore non-regular file '", name, "'"); + fprintf(stderr, "%s%s%s\n", "[WARN ] Ignore non-regular file '", name, "'"); continue; } - //LOG_DEBUG("%s%s%s\n", "Reading '",name,"'"); - cls_put_t _1={ + //fprintf(stderr, "%s%s%s\n", "[DEBUG] Reading '",name,"'"); + cls_put_t _1 = { .upload = upload, .name = (char*)name - }; put =&_1; - err = curl_easy_setopt( upload->curl, CURLOPT_READDATA, put ) - || httpPutEntry( put ); + }; put = &_1; + err = curl_easy_setopt(upload->curl, CURLOPT_READDATA, put) + || httpPutEntry(put); //curl = upload->curl; // Sync back. TODO: Still needed? - if( err ){ ret=-1; goto endFn; } + if( err ){ + assert(!err); err = -1; goto endFn; } } - endFn: - return ret; + err = 0; +endFn: + return err; } -static ssize_t -pull( this_t*this ) -{ - ssize_t err, ret = 0; +static ssize_t pull( this_t*this ){ + ssize_t err; cls_dload_t *dload = NULL; - if( this->file==NULL && isatty(1) ){ - LOG_ERROR("%s\n", "Are you sure you wanna write binary content to tty?"); - ret = -1; goto finally; + if( this->file == NULL && isatty(1) ){ + fprintf(stderr, "%s\n", + "[ERROR] Are you sure you wanna write binary content to tty?"); + err = -1; goto endFn; } - cls_dload_t _1={0}; dload =&_1; + cls_dload_t _1 = {0}; dload =&_1; dload->this = this; dload->rootUrl = this->url; dload->archiveFile = this->file; dload->curl = curl_easy_init(); if( ! dload->curl ){ - LOG_ERROR("%s\n", "curl_easy_init() -> NULL"); - ret = -1; goto finally; + fprintf(stderr, "%s\n", "[ERROR] curl_easy_init() -> NULL"); + err = -1; goto endFn; } - err = gateleenResclone_download( dload , NULL , NULL ); - if( err ){ ret=-1; goto finally; } + err = gateleenResclone_download(dload, NULL, NULL); + if( err ){ + err = -1; goto endFn; } if( dload->dstArchive && archive_write_close(dload->dstArchive) ){ - LOG_ERROR("%s%s%ld%s%s\n", __func__, "(): archive_write_close failed (code ", err, "): ", archive_error_string(dload->dstArchive)); - ret = -1; goto finally; + fprintf(stderr, "%s%ld%s%s\n", "[ERROR] archive_write_close failed (code ", + err, "): ", archive_error_string(dload->dstArchive)); + err = -1; goto endFn; } - finally: + err = 0; +endFn: if( dload ){ - curl_easy_cleanup( dload->curl ); - archive_entry_free( dload->tmpEntry ); dload->tmpEntry = NULL; - archive_write_free( dload->dstArchive ); dload->dstArchive = NULL; + curl_easy_cleanup(dload->curl); + archive_entry_free(dload->tmpEntry); dload->tmpEntry = NULL; + archive_write_free(dload->dstArchive); dload->dstArchive = NULL; } - return ret; + return err; } -static ssize_t -push( this_t*this ) -{ - ssize_t err, ret = 0; +static ssize_t push( this_t*this ){ + ssize_t err; cls_upload_t *upload = NULL; cls_upload_t _1={0}; upload =&_1; @@ -868,57 +884,59 @@ push( this_t*this ) upload->rootUrl = this->url; upload->curl = curl_easy_init(); if( ! upload->curl ){ - LOG_ERROR("%s\n", "curl_easy_init() -> NULL" ); - ret = -1; goto finally; + fprintf(stderr, "%s\n", "[ERROR] curl_easy_init() -> NULL"); + err = -1; goto endFn; } - err = readArchive( upload ); - if( err ){ ret=-1; goto finally; } + err = readArchive(upload); + if( err ){ + err = -1; goto endFn; } - finally: + err = 0; +endFn: if( upload ){ - curl_easy_cleanup( upload->curl ); - archive_read_free( upload->srcArchive ); + curl_easy_cleanup(upload->curl); + archive_read_free(upload->srcArchive); } - return ret; + return err; } -ssize_t -gateleenResclone_run( int argc , char**argv ) -{ - ssize_t err, ret=0; +ssize_t gateleenResclone_run( int argc, char**argv ){ + ssize_t err; this_t *this = NULL; this = this_alloc(); - if( this==NULL ){ ret=-1; goto finally; } + if( this == NULL ){ + err = -1; goto endFn; } - err = parseArgs( argc, argv, &this->mode, &this->url, &this->filter, &this->filter_len, - &this->isFilterFull, &this->file ); - if( err ){ ret=-1; goto finally; } + err = parseArgs(argc, argv, &this->mode, &this->url, &this->filter, + &this->filter_len, &this->isFilterFull, &this->file); + if( err ){ + err = -1; goto endFn; } if( this->mode == MODE_FETCH ){ - ret = pull(this); goto finally; + err = pull(this); goto endFn; }else if( this->mode == MODE_PUSH ){ - ret = push(this); goto finally; + err = push(this); goto endFn; }else{ - ret = -1; goto finally; + err = -1; goto endFn; } - finally: - parseArgs( -1, argv, &this->mode, &this->url, &this->filter, &this->filter_len, - &this->isFilterFull, &this->file ); - this->mode=MODE_NULL; this->url=NULL; this->file=NULL; - this_free( this ); - return ret; + assert(!"Unreachable"); +endFn: + parseArgs(-1, argv, &this->mode, &this->url, &this->filter, &this->filter_len, + &this->isFilterFull, &this->file); + this->mode = MODE_NULL; this->url = NULL; this->file = NULL; + this_free(this); + return err; } -int -gateleenResclone_main( int argc , char**argv ) -{ +int gateleenResclone_main( int argc, char**argv ){ int ret; - ret = gateleenResclone_run( argc , argv ); - return ret<0||ret>127 ? 1 : ret; + ret = gateleenResclone_run(argc, argv); + if( ret < 0 ){ ret = 0 - ret; } + return (ret > 127) ? 1 : ret; } diff --git a/src/log/log.c b/src/log/log.c deleted file mode 100644 index f6660cc..0000000 --- a/src/log/log.c +++ /dev/null @@ -1,32 +0,0 @@ -/* By using this work you agree to the terms and conditions in 'LICENCE.txt' */ - -#include "log.h" - -/* System */ -#include <stdarg.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <unistd.h> - - -void log_asdfghjklqwertzu( const char*level, const char*cLvl, const char*file, int line, const char*fmt, ... ) -{ - va_list args; - va_start( args, fmt ); - int isTTY = isatty(2); - const char *cRst = isTTY ? "\033[0m" : ""; - char *cTxt = isTTY ? "\033[90m" : ""; - cLvl = isTTY ? cLvl : ""; - char tBuf[20]; - const time_t t = time(0); - const char *tfmt = "%Y-%m-%d_%H:%M:%S"; - if( isTTY ){ tfmt += 9; } - strftime( tBuf,sizeof(tBuf), tfmt, localtime(&t) ); - const char *fileOnly = strrchr(file, '/') +1; - fprintf( stderr, "[%s%s%s %s%s%s %s%s:%d%s] ", - cTxt,tBuf,cRst, cLvl,level,cRst , cTxt,fileOnly,line,cRst ); - vfprintf( stderr, fmt, args ); - va_end( args ); -} - diff --git a/src/log/log.h b/src/log/log.h deleted file mode 100644 index e6520d2..0000000 --- a/src/log/log.h +++ /dev/null @@ -1,25 +0,0 @@ -/* By using this work you agree to the terms and conditions in 'LICENCE.txt' */ - -#ifndef INCGUARD_540e2cd36c1ba21909b922d45a94b7f7 -#define INCGUARD_540e2cd36c1ba21909b922d45a94b7f7 - -#include "commonbase.h" - - -#define LOG_FATAL( ... ) log_asdfghjklqwertzu("FATAL","\033[31m",__FILE__,__LINE__,__VA_ARGS__) -#define LOG_ERROR( ... ) log_asdfghjklqwertzu("ERROR","\033[31m",__FILE__,__LINE__,__VA_ARGS__) -#define LOG_WARN( ... ) log_asdfghjklqwertzu("WARN ","\033[33m",__FILE__,__LINE__,__VA_ARGS__) -#define LOG_INFO( ... ) log_asdfghjklqwertzu("INFO ","\033[36m",__FILE__,__LINE__,__VA_ARGS__) -#ifndef NDEBUG - #define LOG_DEBUG( ... ) log_asdfghjklqwertzu("DEBUG","\033[35m",__FILE__,__LINE__,__VA_ARGS__ ) - #define LOG_TRACE( ... ) log_asdfghjklqwertzu("TRACE","\033[94m",__FILE__,__LINE__,__VA_ARGS__ ) -#else - #define LOG_DEBUG( ... ) /* Debugging not enabled. Therefore ignore that log level. */ - #define LOG_TRACE( ... ) /* Debugging not enabled. Therefore ignore that log level. */ -#endif - - -void log_asdfghjklqwertzu( const char*level, const char*cLvl, const char*file, int line, const char*fmt, ... ); - - -#endif /* INCGUARD_540e2cd36c1ba21909b922d45a94b7f7 */ |