dav/sync.c

changeset 222
7b73058d782e
parent 221
e22c29b7ee2f
child 223
cbbdf207e67e
equal deleted inserted replaced
221:e22c29b7ee2f 222:7b73058d782e
88 // copy proxy config 88 // copy proxy config
89 memcpy(ctx->http_proxy, get_http_proxy(), sizeof(Proxy)); 89 memcpy(ctx->http_proxy, get_http_proxy(), sizeof(Proxy));
90 memcpy(ctx->https_proxy, get_https_proxy(), sizeof(Proxy)); 90 memcpy(ctx->https_proxy, get_https_proxy(), sizeof(Proxy));
91 91
92 if(load_sync_config()) { 92 if(load_sync_config()) {
93 cmd_args_free(args);
94 dav_context_destroy(ctx);
93 return EXIT_FAILURE; 95 return EXIT_FAILURE;
94 } 96 }
95 } 97 }
96 98
97 if(!strcmp(cmd, "pull")) { 99 if(!strcmp(cmd, "pull")) {
111 } else if(!strcmp(cmd, "list-directories")) { 113 } else if(!strcmp(cmd, "list-directories")) {
112 ret = list_syncdirs(); 114 ret = list_syncdirs();
113 } 115 }
114 116
115 // TODO: cleanup sync config (don't forget to call regfree for regex) 117 // TODO: cleanup sync config (don't forget to call regfree for regex)
118 cmd_args_free(args);
119 dav_context_destroy(ctx);
120
121 free_config();
116 122
117 return ret; 123 return ret;
118 } 124 }
119 125
120 void print_usage(char *cmd) { 126 void print_usage(char *cmd) {
206 } 212 }
207 213
208 SyncDatabase *db = load_db(dir->database); 214 SyncDatabase *db = load_db(dir->database);
209 if(!db) { 215 if(!db) {
210 fprintf(stderr, "Cannot load database file: %s\n", dir->database); 216 fprintf(stderr, "Cannot load database file: %s\n", dir->database);
217 destroy_db(db);
211 return -1; 218 return -1;
212 } 219 }
213 remove_deleted_conflicts(dir, db); 220 remove_deleted_conflicts(dir, db);
214 221
215 char *new_url = NULL; 222 char *new_url = NULL;
216 if(dir->collection) { 223 if(dir->collection) {
217 new_url = util_concat_path(repo->url, dir->collection); 224 new_url = util_concat_path(repo->url, dir->collection);
218 } 225 }
219 DavSession *sn = create_session(ctx, repo, new_url ? new_url : repo->url); 226 DavSession *sn = create_session(ctx, repo, new_url ? new_url : repo->url);
227 ucx_mempool_reg_destr(sn->mp, db, (ucx_destructor)destroy_db);
220 if(new_url) { 228 if(new_url) {
221 free(new_url); 229 free(new_url);
222 } 230 }
223 if (cmd_getoption(a, "verbose")) { 231 if (cmd_getoption(a, "verbose")) {
224 curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L); 232 curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L);
398 if(sstrprefix(e, S("W/"))) { 406 if(sstrprefix(e, S("W/"))) {
399 e = sstrsubs(e, 2); 407 e = sstrsubs(e, 2);
400 } 408 }
401 if(!strcmp(e.ptr, local->etag)) { 409 if(!strcmp(e.ptr, local->etag)) {
402 // resource is already up-to-date on the client 410 // resource is already up-to-date on the client
411 free(local_path);
403 return 0; 412 return 0;
404 } 413 }
405 } 414 }
406 415
407 if(cdt && exists && s.st_mtime != local->last_modified) { 416 if(cdt && exists && s.st_mtime != local->last_modified) {
489 498
490 if(local->etag) { 499 if(local->etag) {
491 free(local->etag); 500 free(local->etag);
492 } 501 }
493 // set metadata from stat 502 // set metadata from stat
494 local->etag = etag; 503 local->etag = strdup(etag);
495 local->last_modified = s.st_mtime; 504 local->last_modified = s.st_mtime;
496 local->size = s.st_size; 505 local->size = s.st_size;
497 } else { 506 } else {
498 if(unlink(tmp_path)) { 507 if(unlink(tmp_path)) {
499 fprintf(stderr, "Cannot remove tmp file: %s\n", tmp_path); 508 fprintf(stderr, "Cannot remove tmp file: %s\n", tmp_path);
693 char *new_url = NULL; 702 char *new_url = NULL;
694 if(dir->collection) { 703 if(dir->collection) {
695 new_url = util_concat_path(repo->url, dir->collection); 704 new_url = util_concat_path(repo->url, dir->collection);
696 } 705 }
697 DavSession *sn = create_session(ctx, repo, new_url ? new_url : repo->url); 706 DavSession *sn = create_session(ctx, repo, new_url ? new_url : repo->url);
707 ucx_mempool_reg_destr(sn->mp, db, (ucx_destructor)destroy_db);
698 if(new_url) { 708 if(new_url) {
699 free(new_url); 709 free(new_url);
700 } 710 }
701 if (cmd_getoption(a, "verbose")) { 711 if (cmd_getoption(a, "verbose")) {
702 curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L); 712 curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L);
741 LocalResource *local_res = elm->data; 751 LocalResource *local_res = elm->data;
742 if (!res_matches_filter(dir, local_res->path+1)) { 752 if (!res_matches_filter(dir, local_res->path+1)) {
743 if(res_isconflict(db, local_res)) { 753 if(res_isconflict(db, local_res)) {
744 printf("skip: %s\n", local_res->path); 754 printf("skip: %s\n", local_res->path);
745 sync_skipped++; 755 sync_skipped++;
756 local_resource_free(local_res);
746 continue; 757 continue;
747 } 758 }
748 759
749 // upload every changed file 760 // upload every changed file
750 if (local_resource_is_changed(dir, db, local_res)) { 761 if (local_resource_is_changed(dir, db, local_res)) {
764 } 775 }
765 } else { 776 } else {
766 if(cdt && remote_resource_is_changed(sn, dir, db, local_res)) { 777 if(cdt && remote_resource_is_changed(sn, dir, db, local_res)) {
767 printf("conflict: %s\n", local_res->path); 778 printf("conflict: %s\n", local_res->path);
768 sync_skipped++; 779 sync_skipped++;
780 local_resource_free(local_res);
769 continue; 781 continue;
770 } 782 }
771 783
772 printf("put: %s\n", local_res->path); 784 printf("put: %s\n", local_res->path);
773 if(sync_put_resource(dir, res, local_res, &sync_success)) { 785 if(sync_put_resource(dir, res, local_res, &sync_success)) {
781 } 793 }
782 794
783 // remove every locally available resource from db->resource 795 // remove every locally available resource from db->resource
784 // the remaining elements are all deleted files 796 // the remaining elements are all deleted files
785 ucx_map_cstr_put(lclres, local_res->path, local_res); 797 ucx_map_cstr_put(lclres, local_res->path, local_res);
786 ucx_map_cstr_remove(db->resources, local_res->path); // TODO: element leaked 798 LocalResource *lr = ucx_map_cstr_remove(db->resources, local_res->path);
799 if(lr) {
800 local_resource_free(lr);
801 }
787 } 802 }
788 } 803 }
789 ucx_list_free(resources); 804 ucx_list_free(resources);
790 805
791 // delete all removed files 806 // delete all removed files
822 ret = -1; 837 ret = -1;
823 } 838 }
824 839
825 // cleanup 840 // cleanup
826 dav_session_destroy(sn); 841 dav_session_destroy(sn);
842 ucx_list_free(resources); // content is already freed
827 843
828 // Report 844 // Report
829 if(ret == 0) { 845 if(ret == 0) {
830 char *str_success = sync_success == 1 ? "file" : "files"; 846 char *str_success = sync_success == 1 ? "file" : "files";
831 char *str_delete = sync_delete == 1 ? "file" : "files"; 847 char *str_delete = sync_delete == 1 ? "file" : "files";
1192 } 1208 }
1193 1209
1194 for(int i=0;i<numdc;i++) { 1210 for(int i=0;i<numdc;i++) {
1195 ucx_map_cstr_remove(db->conflict, dc[i]); 1211 ucx_map_cstr_remove(db->conflict, dc[i]);
1196 } 1212 }
1213
1214 free(dc);
1197 } 1215 }
1198 1216
1199 int cmd_resolve_conflicts(CmdArgs *a) { 1217 int cmd_resolve_conflicts(CmdArgs *a) {
1200 if(a->argc != 1) { 1218 if(a->argc != 1) {
1201 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many"); 1219 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many");
1211 SyncDatabase *db = load_db(dir->database); 1229 SyncDatabase *db = load_db(dir->database);
1212 if(!db) { 1230 if(!db) {
1213 fprintf(stderr, "Cannot load database file: %s\n", dir->database); 1231 fprintf(stderr, "Cannot load database file: %s\n", dir->database);
1214 return -1; 1232 return -1;
1215 } 1233 }
1234
1235 int ret = 0;
1216 1236
1217 // remove conflicts 1237 // remove conflicts
1218 int num_conflict = db->conflict->count; 1238 int num_conflict = db->conflict->count;
1219 //TODO: ucx_map_free_content(db->conflict, destr); 1239 //TODO: ucx_map_free_content(db->conflict, destr);
1220 ucx_map_clear(db->conflict); 1240 ucx_map_clear(db->conflict);
1221 1241
1222 // store db 1242 // store db
1223 if(store_db(db, dir->database)) { 1243 if(store_db(db, dir->database)) {
1224 fprintf(stderr, "Cannot store sync db\n"); 1244 fprintf(stderr, "Cannot store sync db\n");
1225 fprintf(stderr, "Abort\n"); 1245 fprintf(stderr, "Abort\n");
1226 return -1; // TODO: don't return here 1246 ret = -1;
1227 } 1247 }
1248 destroy_db(db);
1228 1249
1229 // Report 1250 // Report
1230 char *str_conflict = num_conflict == 1 ? "conflict" : "conflicts"; 1251 if(ret == 0) {
1231 printf("Result: %d %s resolved\n", num_conflict, str_conflict); 1252 char *str_conflict = num_conflict == 1 ? "conflict" : "conflicts";
1232 1253 printf("Result: %d %s resolved\n", num_conflict, str_conflict);
1233 return 0; 1254 }
1255
1256 return ret;
1234 } 1257 }
1235 1258
1236 int cmd_delete_conflicts(CmdArgs *a) { 1259 int cmd_delete_conflicts(CmdArgs *a) {
1237 if(a->argc != 1) { 1260 if(a->argc != 1) {
1238 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many"); 1261 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many");
1251 return -1; 1274 return -1;
1252 } 1275 }
1253 1276
1254 int num_del = 0; 1277 int num_del = 0;
1255 int num_err = 0; 1278 int num_err = 0;
1279
1280 int ret = 0;
1256 1281
1257 // delete all conflict files 1282 // delete all conflict files
1258 UcxMapIterator i = ucx_map_iterator(db->conflict); 1283 UcxMapIterator i = ucx_map_iterator(db->conflict);
1259 LocalResource *res; 1284 LocalResource *res;
1260 UCX_MAP_FOREACH(key, res, i) { 1285 UCX_MAP_FOREACH(key, res, i) {
1275 1300
1276 // store db 1301 // store db
1277 if(store_db(db, dir->database)) { 1302 if(store_db(db, dir->database)) {
1278 fprintf(stderr, "Cannot store sync db\n"); 1303 fprintf(stderr, "Cannot store sync db\n");
1279 fprintf(stderr, "Abort\n"); 1304 fprintf(stderr, "Abort\n");
1280 return -1; // TODO: don't return here 1305 ret = -1;
1281 } 1306 }
1307 destroy_db(db);
1282 1308
1283 // Report 1309 // Report
1284 char *str_delete = num_del == 1 ? "file" : "files"; 1310 if(ret == 0) {
1285 char *str_error = num_err == 1 ? "error" : "errors"; 1311 char *str_delete = num_del == 1 ? "file" : "files";
1286 printf("Result: %d conflict %s deleted, %d %s\n", 1312 char *str_error = num_err == 1 ? "error" : "errors";
1287 num_del, str_delete, 1313 printf("Result: %d conflict %s deleted, %d %s\n",
1288 num_err, str_error); 1314 num_del, str_delete,
1289 1315 num_err, str_error);
1290 return 0; 1316 }
1317
1318 return ret;
1291 } 1319 }
1292 1320
1293 1321
1294 // TODO: remove code dup (main.c ls_size_str) 1322 // TODO: remove code dup (main.c ls_size_str)
1295 static char* size_str(uint64_t size) { 1323 static char* size_str(uint64_t size) {

mercurial