# HG changeset patch # User Olaf Wintermann # Date 1552581811 -3600 # Node ID 923a4528a2ae51f6cfc896fa0c639cd2386e5e2a # Parent 46f96dcd6eab4d1e57572fa667adb80721f2540c adds support for pushing metadata updates diff -r 46f96dcd6eab -r 923a4528a2ae dav/db.c --- a/dav/db.c Wed Mar 13 18:43:30 2019 +0100 +++ b/dav/db.c Thu Mar 14 17:43:31 2019 +0100 @@ -180,6 +180,7 @@ } case 5: { char *end; + errno = 0; long int mode = strtol((char*)value, &end, 8); if(errno == 0) { res->mode = (mode_t)mode; @@ -196,7 +197,7 @@ case 7: { uint64_t gid = 0; if(util_strtouint((char*)value, &gid)) { - res->uid = (gid_t)gid; + res->gid = (gid_t)gid; } break; } diff -r 46f96dcd6eab -r 923a4528a2ae dav/db.h --- a/dav/db.h Wed Mar 13 18:43:30 2019 +0100 +++ b/dav/db.h Thu Mar 14 17:43:31 2019 +0100 @@ -37,6 +37,8 @@ #include +#include "finfo.h" + #ifdef __cplusplus extern "C" { #endif @@ -58,11 +60,16 @@ off_t size; DavBool isdirectory; DavBool skipped; - DavBool tags_updated; UcxBuffer *cached_tags; + XAttributes *xattr; char *tags_hash; char *xattr_hash; + DavBool tags_updated; + DavBool finfo_updated; + DavBool xattr_updated; + DavBool metadata_updated; + DavBool keep; DavBool restore; }; diff -r 46f96dcd6eab -r 923a4528a2ae dav/scfg.c --- a/dav/scfg.c Wed Mar 13 18:43:30 2019 +0100 +++ b/dav/scfg.c Thu Mar 14 17:43:31 2019 +0100 @@ -36,7 +36,6 @@ #include "scfg.h" #include "config.h" -#include "finfo.h" #define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b) diff -r 46f96dcd6eab -r 923a4528a2ae dav/sync.c --- a/dav/sync.c Wed Mar 13 18:43:30 2019 +0100 +++ b/dav/sync.c Thu Mar 14 17:43:31 2019 +0100 @@ -1236,7 +1236,7 @@ restore_modified); if(is_changed) { ls_put = ucx_list_append(ls_put, local_res); - } else if(local_res->tags_updated) { + } else if(local_res->metadata_updated) { ls_update = ucx_list_append(ls_update, local_res); } } @@ -1312,7 +1312,7 @@ } if(dir->tagconfig && local_res->tags_updated && !abort) { - sync_update_tags(dir, sn, res, local_res); + sync_update_metadata(dir, sn, res, local_res); } } else if(sn->error != DAV_OK) { // dav_exists() failed @@ -1350,8 +1350,11 @@ DavResource *res = dav_resource_new(sn, local_res->path); - if(dir->tagconfig && local_res->tags_updated) { - sync_update_tags(dir, sn, res, local_res); + if(local_res->metadata_updated) { + if(!sync_update_metadata(dir, sn, res, local_res)) { + LocalResource *dbres = ucx_map_cstr_remove(db->resources, local_res->path); + ucx_map_cstr_put(db->resources, local_res->path, local_res); + } } } @@ -1769,6 +1772,35 @@ } else if(db_res->tags_hash) { res->tags_updated = 1; // tags removed } + res->metadata_updated = res->tags_updated; + } + + if(dir->metadata & FINFO_MODE == FINFO_MODE) { + if(db_res->mode != res->mode) { + res->finfo_updated = 1; + res->metadata_updated = 1; + } + } + if(dir->metadata & FINFO_OWNER == FINFO_OWNER) { + if(db_res->uid != res->uid || db_res->gid != res->gid) { + res->finfo_updated = 1; + res->metadata_updated = 1; + } + } + + if(dir->metadata & FINFO_XATTR == FINFO_XATTR) { + char *path = util_concat_path(dir->path, db_res->path); + XAttributes *xattr = file_get_attributes(path); + if((db_res->xattr_hash && !xattr) || + (!db_res->xattr_hash && xattr) || + strcmp(xattr->hash, db_res->xattr_hash)) + { + res->metadata_updated = 1; + res->xattr_updated = 1; + res->xattr = xattr; + } else if(xattr) { + xattributes_free(xattr); + } } if(db_res->last_modified == res->last_modified && db_res->size == res->size) { @@ -2442,42 +2474,63 @@ return ret; } -int sync_update_tags(SyncDirectory *dir, DavSession *sn, DavResource *res, LocalResource *local) { - if(!dir->tagconfig || !local->tags_updated) { - return 0; +int sync_update_metadata(SyncDirectory *dir, DavSession *sn, DavResource *res, LocalResource *local) { + if(dir->tagconfig && local->tags_updated) { + // get local tags + UcxList *tags = sync_get_file_tags(dir, local, NULL); + + DavXmlNode *prop = create_xml_taglist(tags); + if(prop) { + dav_set_property_ns(res, DAV_NS, "tags", prop); + } else { + dav_remove_property_ns(res, DAV_NS, "tags"); + } } - // get local tags - UcxList *tags = sync_get_file_tags(dir, local, NULL); - - DavXmlNode *prop = create_xml_taglist(tags); - if(prop) { - dav_set_property_ns(res, DAV_NS, "tags", prop); - } else { - dav_remove_property_ns(res, DAV_NS, "tags"); + if(local->finfo_updated) { + struct stat s; + s.st_mode = local->mode; + s.st_mtime = local->last_modified; + s.st_uid = local->uid; + s.st_gid = local->gid; + resource_set_finfo_s(&s, res, dir->metadata); } + if(local->xattr_updated) { + if(local->xattr) { + resource_set_xattr(res, local->xattr); + } else { + dav_remove_property(res, "idav:xattributes"); + } + } + + int err = 0; printf("update: %s\n", local->path); if(dav_store(res)) { print_resource_error(sn, local->path); + err = 1; } else { - UcxBuffer *tag_data = local->cached_tags; - if(local->tags_hash) { - free(local->tags_hash); - local->tags_hash = NULL; + if(dir->tagconfig && local->tags_updated) { + UcxBuffer *tag_data = local->cached_tags; + if(local->tags_hash) { + free(local->tags_hash); + local->tags_hash = NULL; + } + if(tag_data) { + char *hash = dav_create_hash(tag_data->space, tag_data->size); + local->tags_hash = hash; + } + local->tags_updated = FALSE; } - if(tag_data) { - char *hash = dav_create_hash(tag_data->space, tag_data->size); - local->tags_hash = hash; + if(local->xattr) { + local->xattr_hash = strdup(local->xattr->hash); } - local->tags_updated = FALSE; } - + // TODO: free stuff - return 0; + return err; } - void remove_deleted_conflicts(SyncDirectory *dir, SyncDatabase *db) { char **dc = calloc(sizeof(void*), db->conflict->count); int numdc = 0; diff -r 46f96dcd6eab -r 923a4528a2ae dav/sync.h --- a/dav/sync.h Wed Mar 13 18:43:30 2019 +0100 +++ b/dav/sync.h Thu Mar 14 17:43:31 2019 +0100 @@ -138,7 +138,7 @@ int *counter); int sync_mkdir(SyncDirectory *dir, DavResource *res, LocalResource *local); int sync_delete_remote_resource(SyncDirectory *dir, DavSession *sn, LocalResource *res, int *counter, UcxList **cols); -int sync_update_tags(SyncDirectory *dir, DavSession *sn, DavResource *res, LocalResource *local); +int sync_update_metadata(SyncDirectory *dir, DavSession *sn, DavResource *res, LocalResource *local); void remove_deleted_conflicts(SyncDirectory *dir, SyncDatabase *db);