dav/sync.c

changeset 444
761dc4867208
parent 417
f340460a8b5d
child 445
c525f049c8b7
equal deleted inserted replaced
443:2f019a4bc78a 444:761dc4867208
169 void print_usage(char *cmd) { 169 void print_usage(char *cmd) {
170 fprintf(stderr, "Usage: %s command [options] arguments...\n\n", cmd); 170 fprintf(stderr, "Usage: %s command [options] arguments...\n\n", cmd);
171 171
172 fprintf(stderr, "Commands:\n"); 172 fprintf(stderr, "Commands:\n");
173 fprintf(stderr, " pull [-cldr] [-t <tags>] <directory>\n"); 173 fprintf(stderr, " pull [-cldr] [-t <tags>] <directory>\n");
174 fprintf(stderr, " push [-cldr] [-t <tags>] <directory>\n"); 174 fprintf(stderr, " push [-cldrDM] [-t <tags>] <directory>\n");
175 fprintf(stderr, " archive [-cld] [-t <tags>] <directory>\n"); 175 fprintf(stderr, " archive [-cldDM] [-t <tags>] <directory>\n");
176 fprintf(stderr, " resolve-conflicts <directory>\n"); 176 fprintf(stderr, " resolve-conflicts <directory>\n");
177 fprintf(stderr, " delete-conflicts <directory>\n"); 177 fprintf(stderr, " delete-conflicts <directory>\n");
178 fprintf(stderr, " trash-info <directory>\n"); 178 fprintf(stderr, " trash-info <directory>\n");
179 fprintf(stderr, " empty-trash <directory>\n"); 179 fprintf(stderr, " empty-trash <directory>\n");
180 fprintf(stderr, " add-tag [-s <syncdir>] <file> <tag>\n"); 180 fprintf(stderr, " add-tag [-s <syncdir>] <file> <tag>\n");
188 fprintf(stderr, " -d Don't lock the repository\n"); 188 fprintf(stderr, " -d Don't lock the repository\n");
189 fprintf(stderr, " -t <tags> " 189 fprintf(stderr, " -t <tags> "
190 "Only sync files which have the specified tags\n"); 190 "Only sync files which have the specified tags\n");
191 fprintf(stderr, " -r " 191 fprintf(stderr, " -r "
192 "Remove resources not matching the tag filter\n"); 192 "Remove resources not matching the tag filter\n");
193 fprintf(stderr, " -D restore deleted files\n");
194 fprintf(stderr, " -M restore modified files\n");
193 fprintf(stderr, " -v verbose output (all commands)\n\n"); 195 fprintf(stderr, " -v verbose output (all commands)\n\n");
194 196
195 fprintf(stderr, "Config commands:\n"); 197 fprintf(stderr, "Config commands:\n");
196 fprintf(stderr, " add-directory\n"); 198 fprintf(stderr, " add-directory\n");
197 fprintf(stderr, " list-directories\n"); 199 fprintf(stderr, " list-directories\n");
355 LocalResource *local = ucx_map_cstr_remove(db->resources, path); 357 LocalResource *local = ucx_map_cstr_remove(db->resources, path);
356 if(local) { 358 if(local) {
357 local->keep = TRUE; 359 local->keep = TRUE;
358 } 360 }
359 361
362 }
363
364 void res2map(DavResource *root, UcxMap *map) {
365 UcxList *stack = ucx_list_prepend(NULL, root->children);
366 while(stack) {
367 DavResource *res = stack->data;
368 stack = ucx_list_remove(stack, stack);
369
370 while(res) {
371 ucx_map_cstr_put(map, res->path, res);
372
373 if(res->children) {
374 stack = ucx_list_prepend(stack, res->children);
375 }
376 res = res->next;
377 }
378 }
360 } 379 }
361 380
362 int cmd_pull(CmdArgs *a) { 381 int cmd_pull(CmdArgs *a) {
363 if(a->argc != 1) { 382 if(a->argc != 1) {
364 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many"); 383 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many");
995 if (cmd_getoption(a, "verbose")) { 1014 if (cmd_getoption(a, "verbose")) {
996 curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L); 1015 curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L);
997 curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr); 1016 curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr);
998 } 1017 }
999 1018
1000 DavResource *root = dav_query(sn, "select - from / with depth = 0"); 1019 DavBool restore_deleted = cmd_getoption(a, "restore-deleted") ? 1 : 0;
1020 DavBool restore_modified = cmd_getoption(a, "restore-modified") ? 1 : 0;
1021 DavBool restore = restore_deleted || restore_modified;
1022 int depth = restore ? -1 : 0;
1023
1024 DavResource *root = dav_query(sn, "select D:getetag,idav:status from / with depth = %d", depth);
1001 if(!root) { 1025 if(!root) {
1002 print_resource_error(sn, "/"); 1026 print_resource_error(sn, "/");
1003 dav_session_destroy(sn); 1027 dav_session_destroy(sn);
1004 fprintf(stderr, "Abort\n"); 1028 fprintf(stderr, "Abort\n");
1005 return -1; 1029 return -1;
1030 }
1031
1032 UcxMap *svrres = NULL;
1033 if(restore) {
1034 svrres = ucx_map_new(1024);
1035 res2map(root, svrres);
1006 } 1036 }
1007 1037
1008 int cdt = cmd_getoption(a, "conflict") ? 0 : 1; // conflict detection 1038 int cdt = cmd_getoption(a, "conflict") ? 0 : 1; // conflict detection
1009 1039
1010 // lock repository 1040 // lock repository
1081 sync_skipped++; 1111 sync_skipped++;
1082 continue; 1112 continue;
1083 } 1113 }
1084 1114
1085 // upload every changed file 1115 // upload every changed file
1086 int is_changed = local_resource_is_changed(dir, db, local_res); 1116 int is_changed = local_resource_is_changed(
1117 dir,
1118 db,
1119 local_res,
1120 svrres,
1121 restore_deleted,
1122 restore_modified);
1087 if (is_changed || local_res->tags_updated) { 1123 if (is_changed || local_res->tags_updated) {
1088 DavResource *res = dav_resource_new(sn, local_res->path); 1124 DavResource *res = dav_resource_new(sn, local_res->path);
1089 if(!res) { 1125 if(!res) {
1090 print_resource_error(sn, local_res->path); 1126 print_resource_error(sn, local_res->path);
1091 ret = -1; 1127 ret = -1;
1371 } 1407 }
1372 newres->tags_updated = res->tags_updated; 1408 newres->tags_updated = res->tags_updated;
1373 return newres; 1409 return newres;
1374 } 1410 }
1375 1411
1376 int local_resource_is_changed(SyncDirectory *dir, SyncDatabase *db, LocalResource *res) { 1412 int local_resource_is_changed(
1413 SyncDirectory *dir,
1414 SyncDatabase *db,
1415 LocalResource *res,
1416 UcxMap *svrres,
1417 DavBool restore_deleted,
1418 DavBool restore_modified)
1419 {
1377 LocalResource *db_res = ucx_map_cstr_get(db->resources, res->path); 1420 LocalResource *db_res = ucx_map_cstr_get(db->resources, res->path);
1378 res->tags_updated = 0; 1421 res->tags_updated = 0;
1379 if(db_res) { 1422 if(db_res) {
1423 if(svrres) {
1424 DavResource *remote = ucx_map_cstr_get(svrres, res->path);
1425 if(restore_deleted && !remote) {
1426 return 1;
1427 }
1428 if(!res->isdirectory && restore_modified && remote) {
1429 char *etag = dav_get_string_property(remote, "D:getetag");
1430 if(!etag || (db_res->etag && strcmp(etag, db_res->etag))) {
1431 res->restore = TRUE;
1432 return 1;
1433 }
1434 }
1435 }
1436
1380 res->tags_updated = db_res->tags_updated; 1437 res->tags_updated = db_res->tags_updated;
1381 if(db_res->etag) { 1438 if(db_res->etag) {
1382 res->etag = strdup(db_res->etag); 1439 res->etag = strdup(db_res->etag);
1383 } 1440 }
1384 if(db_res->tags_hash) { 1441 if(db_res->tags_hash) {
1413 DavSession *sn, 1470 DavSession *sn,
1414 SyncDirectory *dir, 1471 SyncDirectory *dir,
1415 SyncDatabase *db, 1472 SyncDatabase *db,
1416 LocalResource *res) 1473 LocalResource *res)
1417 { 1474 {
1475 if(res->restore) {
1476 return 0;
1477 }
1478
1418 DavResource *remote = dav_get(sn, res->path, "D:getetag"); 1479 DavResource *remote = dav_get(sn, res->path, "D:getetag");
1419 int ret = 0; 1480 int ret = 0;
1420 if(remote) { 1481 if(remote) {
1421 char *etag = dav_get_string_property(remote, "D:getetag"); 1482 char *etag = dav_get_string_property(remote, "D:getetag");
1422 if(!res->etag) { 1483 if(!res->etag) {

mercurial