# HG changeset patch # User Olaf Wintermann # Date 1536227820 -7200 # Node ID 22522ff52a62208d8907b3b29894fe0722cbacc3 # Parent 2c112cbaa08e96f7f61cf6e2b1bca1946e99dca2 adds check to make sure dav-sync doesn't delete collections when children are modified diff -r 2c112cbaa08e -r 22522ff52a62 dav/sync.c --- a/dav/sync.c Wed Sep 05 07:02:04 2018 +0200 +++ b/dav/sync.c Thu Sep 06 11:57:00 2018 +0200 @@ -1197,13 +1197,15 @@ // delete all removed files if(ret == 0 && !archive) { + UcxList *cols = NULL; + UcxMapIterator i = ucx_map_iterator(db->resources); LocalResource *local; UCX_MAP_FOREACH(key, local, i) { if (!local->keep && !res_matches_filter(dir, local->path+1)) { if(sync_shutdown) { ucx_map_cstr_put(lclres, local->path, local_resource_copy(local)); - } else if(sync_delete_remote_resource(sn, local, &sync_delete)) { + } else if(sync_delete_remote_resource(sn, local, &sync_delete, &cols)) { ucx_map_cstr_put(lclres, local->path, local_resource_copy(local)); if(sn->error != DAV_NOT_FOUND) { print_resource_error(sn, local->path); @@ -1213,6 +1215,26 @@ } } } + + cols = ucx_list_sort(cols, (cmp_func)resource_pathlen_cmp, NULL); + + UCX_FOREACH(elm, cols) { + local = elm->data; + if (!local->keep && !res_matches_filter(dir, local->path+1)) { + if(sync_shutdown) { + ucx_map_cstr_put(lclres, local->path, local_resource_copy(local)); + } else if(sync_delete_remote_resource(sn, local, &sync_delete, NULL)) { + ucx_map_cstr_put(lclres, local->path, local_resource_copy(local)); + if(sn->error != DAV_NOT_FOUND) { + print_resource_error(sn, local->path); + sync_error++; + break; + } + } + } + } + + ucx_list_free(cols); } ucx_map_free_content(db->resources, (ucx_destructor)local_resource_free); ucx_map_free(db->resources); @@ -1500,6 +1522,18 @@ return ret; } +int resource_pathlen_cmp(LocalResource *res1, LocalResource *res2, void *n) { + size_t s1 = strlen(res1->path); + size_t s2 = strlen(res2->path); + if(s1 < s2) { + return 1; + } else if(s1 > s2) { + return -1; + } else { + return 0; + } +} + int sync_set_status(DavResource *res, char *status) { DavResource *resource = dav_resource_new(res->session, res->path); @@ -1891,7 +1925,8 @@ int sync_delete_remote_resource( DavSession *sn, LocalResource *local_res, - int *counter) + int *counter, + UcxList **cols) { DavResource *res = dav_get(sn, local_res->path, "D:getetag"); if(!res) { @@ -1899,11 +1934,18 @@ } int ret = 0; + sn->error = DAV_OK; if(res->iscollection) { - printf("delete: %s\n", res->path); - if(dav_delete(res)) { - ret = 1; - fprintf(stderr, "Cannot delete resource %s\n", res->path); + if(cols) { + *cols = ucx_list_append(*cols, local_res); + } else if(!res->children) { + printf("delete: %s\n", res->path); + if(dav_delete(res)) { + ret = 1; + fprintf(stderr, "Cannot delete collection %s\n", res->path); + } else { + (*counter)++; + } } } else { char *etag = dav_get_string_property(res, "D:getetag"); diff -r 2c112cbaa08e -r 22522ff52a62 dav/sync.h --- a/dav/sync.h Wed Sep 05 07:02:04 2018 +0200 +++ b/dav/sync.h Thu Sep 06 11:57:00 2018 +0200 @@ -96,6 +96,8 @@ SyncDatabase *db, LocalResource *res); +int resource_pathlen_cmp(LocalResource *res1, LocalResource *res2, void *n); + int sync_set_status(DavResource *res, char *status); int sync_remove_status(DavResource *res); UcxBuffer* sync_get_file_tag_data(SyncDirectory *dir, LocalResource *res); @@ -110,7 +112,7 @@ LocalResource *local, int *counter); int sync_mkdir(SyncDirectory *dir, DavResource *res, LocalResource *local); -int sync_delete_remote_resource(DavSession *sn, LocalResource *res, int *counter); +int sync_delete_remote_resource(DavSession *sn, LocalResource *res, int *counter, UcxList **cols); int sync_update_tags(SyncDirectory *dir, DavSession *sn, DavResource *res, LocalResource *local); void remove_deleted_conflicts(SyncDirectory *dir, SyncDatabase *db);