diff -r d64ecd8d6969 -r cdaf5a3d3a50 dav/sync.c --- a/dav/sync.c Sun May 27 13:02:40 2018 +0200 +++ b/dav/sync.c Sun May 27 19:45:28 2018 +0200 @@ -177,7 +177,7 @@ fprintf(stderr, " add-tag [-s ] \n"); fprintf(stderr, " remove-tag [-s ] \n"); fprintf(stderr, " update-tags [-s ] [tags]\n"); - fprintf(stderr, " update-tags [-s ] \n\n"); + fprintf(stderr, " list-tags [-s ] \n\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -c Disable conflict detection\n"); @@ -1352,6 +1352,38 @@ return new_tags; } +int sync_tags_equal(UcxList *tags1, UcxList *tags2) { + if(!tags1) { + return tags2 ? 0 : 1; + } + if(!tags2) { + return tags1 ? 0 : 1; + } + + UcxMap *map1 = ucx_map_new(32); + UCX_FOREACH(elm, tags1) { + DavTag *t = elm->data; + ucx_map_cstr_put(map1, t->name, t); + } + + int equal = 1; + int i = 0; + UCX_FOREACH(elm, tags2) { + DavTag *t = elm->data; + if(!ucx_map_cstr_get(map1, t->name)) { + equal = 0; + break; + } + i++; + } + + if(i != map1->count) { + equal = 0; + } + ucx_map_free(map1); + return equal; +} + int sync_store_tags(SyncDirectory *dir, const char *path, LocalResource *local, DavResource *res) { if(!dir->tagconfig) { return 0; @@ -1366,36 +1398,38 @@ } } - DavBool store_empty_tags = FALSE; - if(dir->tagconfig->conflict != TAG_NO_CONFLICT) { - DavBool tags_changed = FALSE; - UcxList *local_tags = sync_get_file_tags(dir, local, &tags_changed); - if(tags_changed) { - switch(dir->tagconfig->conflict) { - case TAG_NO_CONFLICT: - case TAG_KEEP_LOCAL: { - store_empty_tags = TRUE; - tags = local_tags; - // TODO: free tags - break; - } - case TAG_KEEP_REMOTE: break; - case TAG_MERGE: { - UcxList *new_tags = sync_merge_tags(local_tags, tags); - // TODO: free tags and local_tags - tags = new_tags; - store_empty_tags = TRUE; - // make sure the merged tags will be pushed the next time - local->tags_updated = TRUE; - break; - } + DavBool store_tags = FALSE; + DavBool tags_changed = FALSE; + UcxList *local_tags = sync_get_file_tags(dir, local, &tags_changed); + if(tags_changed) { + switch(dir->tagconfig->conflict) { + case TAG_NO_CONFLICT: + case TAG_KEEP_LOCAL: { + store_tags = FALSE; + break; + } + case TAG_KEEP_REMOTE: { + store_tags = TRUE; + local->tags_updated = FALSE; } - } else { - // TODO: free local_tags + case TAG_MERGE: { + UcxList *new_tags = sync_merge_tags(local_tags, tags); + // TODO: free tags and local_tags + tags = new_tags; + store_tags = TRUE; + // make sure the merged tags will be pushed the next time + local->tags_updated = TRUE; + break; + } } + } else { + if(!sync_tags_equal(tags, local_tags)) { + store_tags = TRUE; + } + // TODO: free local_tags } - if(!tags && !store_empty_tags) { + if(!store_tags) { return 0; } @@ -1433,21 +1467,30 @@ if(local) { if(!local->tags_hash || strcmp(data_hash, local->tags_hash)) { printf("update: %s\n", local->path); - // TODO: update hash in localres?? } else { update = 0; } } if(update) { ret = xattr_set(path, dir->tagconfig->xattr_name, data->space, data->pos); + if(local) { + if(local->tags_hash) { + free(local->tags_hash); + } + local->tags_hash = data_hash; + } + } else { + free(data_hash); } ucx_buffer_free(data); } else { ret = -1; } } else { - // TODO: delete xattr - //ret = xattr_remove(path, dir->tagconfig->xattr_name); + if(local) { + printf("update: %s\n", local->path); + } + ret = xattr_remove(path, dir->tagconfig->xattr_name); } } @@ -1492,6 +1535,9 @@ if(!dir->tagconfig) { return NULL; } + if(changed && res->tags_updated) { + *changed = TRUE; + } if(dir->tagconfig->store == TAG_STORE_XATTR) { UcxBuffer *tag_buf = res->cached_tags ? res->cached_tags : @@ -2180,6 +2226,12 @@ } if(localres) { localres->tags_updated = TRUE; + if(!tags) { + if(localres->tags_hash) { + free(localres->tags_hash); + } + localres->tags_hash = NULL; + } } }