adds support for pushing metadata updates

Thu, 14 Mar 2019 17:43:31 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 14 Mar 2019 17:43:31 +0100
changeset 523
923a4528a2ae
parent 522
46f96dcd6eab
child 524
d53fd1006485

adds support for pushing metadata updates

dav/db.c file | annotate | diff | comparison | revisions
dav/db.h file | annotate | diff | comparison | revisions
dav/scfg.c file | annotate | diff | comparison | revisions
dav/sync.c file | annotate | diff | comparison | revisions
dav/sync.h file | annotate | diff | comparison | revisions
--- 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;
                 }
--- 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 <libxml/xmlreader.h>
 
+#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;
 };
--- 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)
 
--- 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;
--- 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);
 

mercurial