diff -r 0e45b04236a7 -r d10194a51304 dav/sync.c --- a/dav/sync.c Fri Feb 26 20:54:42 2016 +0100 +++ b/dav/sync.c Sat Feb 27 17:18:00 2016 +0100 @@ -194,10 +194,17 @@ DavResource *ls = dav_query(sn, "select D:getetag,idav:status from / with depth = infinity"); if(!ls) { print_resource_error(sn, "/"); + fprintf(stderr, "Abort\n"); + + dav_session_destroy(sn); // TODO: free return -1; } + int sync_success = 0; + int sync_delete = 0; + int sync_error = 0; + if(!ls->children) { // TODO: free fprintf(stderr, "Repository is empty\n"); @@ -224,8 +231,9 @@ } // download the resource - if(sync_get_resource(a, dir, res, db)) { + if(sync_get_resource(a, dir, res, db, &sync_success)) { fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); + sync_error++; } // add every resource from the server to svrres @@ -251,8 +259,11 @@ continue; } // sync_remove_resource does all necessary tests - if(sync_remove_local_resource(dir, local)) { + int ret = sync_remove_local_resource(dir, local); + if(ret == -1) { rmdirs = ucx_list_append(rmdirs, local); + } else if(ret == 0) { + sync_delete++; } } UCX_FOREACH(elm, rmdirs) { @@ -262,18 +273,35 @@ ucx_map_free(db->resources); db->resources = svrres; - // TODO: cleanup - BUT DONT CLEANUP SYNC CONFIG (do this in main!) - // store db if(store_db(db, dir->database)) { fprintf(stderr, "Cannot store sync db\n"); - return -1; + fprintf(stderr, "Abort\n"); + return -1; // TODO: don't return here } + // TODO: cleanup - BUT DONT CLEANUP SYNC CONFIG (do this in main!) + dav_session_destroy(sn); + + // Report + char *str_success = sync_success == 1 ? "file" : "files"; + char *str_delete = sync_delete == 1 ? "file" : "files"; + char *str_error = sync_error == 1 ? "error" : "errors"; + printf("Result: %d %s pulled, %d %s deleted, %d %s\n", + sync_success, str_success, + sync_delete,str_delete, + sync_error, str_error); + return 0; } -int sync_get_resource(CmdArgs *a, SyncDirectory *dir, DavResource *res, SyncDatabase *db) { +int sync_get_resource( + CmdArgs *a, + SyncDirectory *dir, + DavResource *res, + SyncDatabase *db, + int *counter) +{ int cdt = cmd_getoption(a, "conflict") ? 0 : 1; // conflict detection LocalResource *local = ucx_map_cstr_get(db->resources, res->path); @@ -361,6 +389,8 @@ fclose(out); if(ret == 0) { + (*counter)++; + if(dir->trash && dir->backuppull) { move_to_trash(dir, local_path); } @@ -412,29 +442,30 @@ struct stat s; if(stat(local_path, &s)) { free(local_path); - return 0; + return -2; } if(S_ISDIR(s.st_mode)) { free(local_path); - return 1; + return -1; } if(s.st_mtime != res->last_modified) { free(local_path); - return 0; + return -2; } printf("delete: %s\n", res->path); - + int ret = 0; if(dir->trash) { move_to_trash(dir, local_path); } else if(unlink(local_path)) { fprintf(stderr, "Cannot remove file %s\n", local_path); + ret = -2; } free(local_path); - return 0; + return ret; } void sync_remove_local_directory(SyncDirectory *dir, LocalResource *res) { @@ -583,11 +614,24 @@ curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr); } + DavResource *testsvr = dav_query(sn, "select - from / with depth = 0"); + if(!testsvr) { + print_resource_error(sn, "/"); + dav_session_destroy(sn); + fprintf(stderr, "Abort\n"); + return -1; + } + + int sync_success = 0; + int sync_delete = 0; + int sync_error = 0; + // upload all changed files UcxList *resources = cmd_getoption(a, "read") ? read_changes(dir, db) : local_scan(dir, db); UcxMap *lclres = ucx_map_new(db->resources->count); + int ret = 0; UCX_FOREACH(elm, resources) { LocalResource *local_res = elm->data; if (!res_matches_filter(dir, local_res->path+1)) { @@ -596,22 +640,24 @@ DavResource *res = dav_resource_new(sn, local_res->path); if(!res) { print_resource_error(sn, local_res->path); - break; + ret = -1; + sync_error++; } if(local_res->isdirectory) { printf("mkcol: %s\n", local_res->path); - if(sync_mkdir(dir, res, local_res)) { + if(sync_mkdir(dir, res, local_res) && sn->error != DAV_METHOD_NOT_ALLOWED) { print_resource_error(sn, res->path); - dav_resource_free(res); - break; + ret = -1; + sync_error++; } } else { printf("put: %s\n", local_res->path); - if(sync_put_resource(dir, res, local_res)) { + if(sync_put_resource(dir, res, local_res, &sync_success)) { + sync_error++; print_resource_error(sn, res->path); - dav_resource_free(res); - break; + ret = -1; + sync_error++; } } dav_resource_free(res); @@ -626,15 +672,18 @@ ucx_list_free(resources); // delete all removed files - UcxMapIterator i = ucx_map_iterator(db->resources); - LocalResource *local; - UCX_MAP_FOREACH(key, local, i) { - if (!res_matches_filter(dir, local->path+1)) { - if(sync_delete_remote_resource(sn, local)) { - ucx_map_cstr_put(lclres, local->path, local); - if(sn->error != DAV_NOT_FOUND) { - print_resource_error(sn, local->path); - break; + if(ret == 0) { + UcxMapIterator i = ucx_map_iterator(db->resources); + LocalResource *local; + UCX_MAP_FOREACH(key, local, i) { + if (!res_matches_filter(dir, local->path+1)) { + if(sync_delete_remote_resource(sn, local, &sync_delete)) { + ucx_map_cstr_put(lclres, local->path, local); + if(sn->error != DAV_NOT_FOUND) { + print_resource_error(sn, local->path); + sync_error++; + break; + } } } } @@ -642,14 +691,23 @@ ucx_map_free(db->resources); db->resources = lclres; - // TODO: free res - // store db if(store_db(db, dir->database)) { fprintf(stderr, "Cannot store sync db\n"); return -1; } + // TODO: free res + + // Report + char *str_success = sync_success == 1 ? "file" : "files"; + char *str_delete = sync_delete == 1 ? "file" : "files"; + char *str_error = sync_error == 1 ? "error" : "errors"; + printf("Result: %d %s pushed, %d %s deleted, %d %s\n", + sync_success, str_success, + sync_delete,str_delete, + sync_error, str_error); + return 0; } @@ -811,7 +869,12 @@ return ret; } -int sync_put_resource(SyncDirectory *dir, DavResource *res, LocalResource *local) { +int sync_put_resource( + SyncDirectory *dir, + DavResource *res, + LocalResource *local, + int *counter) +{ char *local_path = util_concat_path(dir->path, res->path); struct stat s; @@ -847,7 +910,9 @@ - if(ret == 0) { + if(ret == 0) { + (*counter)++; + // check contentlength and get new etag DavResource *up_res = dav_get(res->session, res->path, "D:getetag"); @@ -905,7 +970,11 @@ return ret; } -int sync_delete_remote_resource(DavSession *sn, LocalResource *local_res) { +int sync_delete_remote_resource( + DavSession *sn, + LocalResource *local_res, + int *counter) +{ DavResource *res = dav_get(sn, local_res->path, "D:getetag"); if(!res) { return sn->error == DAV_NOT_FOUND ? 0 : 1; @@ -933,10 +1002,11 @@ if(dav_delete(res)) { if(sn->error != DAV_NOT_FOUND) { fprintf(stderr, "Cannot delete resource %s\n", res->path); + ret = 1; } + } else { + (*counter)++; } - } else { - ret = 1; } }