fix dav-sync deltav versioning

Thu, 05 Dec 2019 12:37:48 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 05 Dec 2019 12:37:48 +0100
changeset 692
56b66fe2b4f5
parent 691
48ec0ab17011
child 693
8ca795c1ae1c

fix dav-sync deltav versioning

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
libidav/crypto.c file | annotate | diff | comparison | revisions
test/main.c file | annotate | diff | comparison | revisions
--- a/dav/db.c	Thu Dec 05 10:46:39 2019 +0100
+++ b/dav/db.c	Thu Dec 05 12:37:48 2019 +0100
@@ -217,6 +217,8 @@
                 field = 12;
             } else if(xstreq(name, "localpath")) {
                 field = 13;
+            } else if(xstreq(name, "versioncontrol")) {
+                field = 14;
             } else if(xstreq(name, "skipped")) {
                 res->skipped = TRUE;
             } else if(xstreq(name, "tags-updated")) {
@@ -321,6 +323,9 @@
                 case 13: {
                     res->local_path = strdup((char*)value);
                 }
+                case 14: {
+                    res->versioncontrol = util_getboolean((char*)value);
+                }
             }
         } else if(XML_READER_TYPE_END_ELEMENT) {
             if(xstreq(name, "resource")) {
@@ -648,6 +653,18 @@
             }
         }
         
+        if(res->versioncontrol) {
+            r = xmlTextWriterWriteElement(
+                    writer,
+                    BAD_CAST "versioncontrol",
+                    BAD_CAST "true");
+            if(r < 0) {
+                fprintf(stderr, "Cannot write versioncontrol\n");
+                xmlFreeTextWriter(writer);
+                return -1;
+            }
+        }
+        
         // </resource>
         xmlTextWriterEndElement(writer);
     }
@@ -766,6 +783,7 @@
     newres->size = src->size;
     newres->isdirectory = src->isdirectory;
     newres->skipped = src->skipped;
+    newres->versioncontrol = src->versioncontrol;
     
     if(src->xattr) {
         XAttributes *xattr = calloc(1, sizeof(XAttributes));
--- a/dav/db.h	Thu Dec 05 10:46:39 2019 +0100
+++ b/dav/db.h	Thu Dec 05 12:37:48 2019 +0100
@@ -87,6 +87,8 @@
     DavBool keep;
     DavBool restore;
     
+    DavBool versioncontrol;
+    
     DavBool isnew;
     LocalResource *origin;
     char *conflict_source;
--- a/dav/scfg.c	Thu Dec 05 10:46:39 2019 +0100
+++ b/dav/scfg.c	Thu Dec 05 12:37:48 2019 +0100
@@ -374,7 +374,7 @@
     
     int err = 0;
     
-    xmlChar *attr_type = xmlGetNoNsProp(node, BAD_CAST "format");
+    xmlChar *attr_type = xmlGetNoNsProp(node, BAD_CAST "type");
     xmlChar *attr_always = xmlGetNoNsProp(node, BAD_CAST "always");
     
     if(attr_type) {
--- a/dav/sync.c	Thu Dec 05 10:46:39 2019 +0100
+++ b/dav/sync.c	Thu Dec 05 12:37:48 2019 +0100
@@ -2938,6 +2938,7 @@
         if(db_res->link_target) {
             res->link_target_db = db_res->link_target;
         }
+        res->versioncontrol = db_res->versioncontrol;
         
         // if the resource is splitted, copy the part info to the new
         // LocalResource obj, because we need it later
@@ -3690,8 +3691,9 @@
 #define VBEGIN_ERROR_MOVE      2
 #define VBEGIN_ERROR_PROPPATCH 3
 #define VBEGIN_ERROR_CHECKOUT  4
-int versioning_begin(SyncDirectory *dir, DavResource *res, int *exists) {
+int versioning_begin(SyncDirectory *dir, DavResource *res, int *exists, int *versionized) {
     int ret = 0;
+    *versionized = 0;
     
     if(dir->versioning->type == VERSIONING_SIMPLE && res->exists) {
         DavResource *history_collection = dav_resource_new(
@@ -3767,6 +3769,8 @@
         }
 
         if(!ret) {
+            *versionized = 1;
+            
             dav_set_string_property_ns(version_res, DAV_NS, "origin", res->href);
             if(dav_store(version_res)) {
                 ret = VBEGIN_ERROR_PROPPATCH;
@@ -3787,13 +3791,30 @@
         }
         
         dav_resource_free(history_collection);
-    } else if(dir->versioning->type == VERSIONING_DELTAV){
+    } else if(dir->versioning->type == VERSIONING_DELTAV && res->exists){
         // DeltaV is so much easier :) 
         if(dav_checkout(res)) {
             ret = VBEGIN_ERROR_CHECKOUT;
-        }
-    }
-    
+        } else {
+            *versionized = 1;
+        }
+    }
+    
+    return ret;
+}
+
+int versioning_init(SyncDirectory *dir, LocalResource *local, DavResource *res) {
+    if(local->versioncontrol) {
+        return 0;
+    }
+    int ret = 0;
+    if(dir->versioning->type == VERSIONING_DELTAV) {
+        if(dav_versioncontrol(res)) {
+            ret = 1;
+        } else {
+            local->versioncontrol = 1;
+        }
+    }
     return ret;
 }
 
@@ -3805,9 +3826,10 @@
     }
 }
 
-int versioning_delete_begin(SyncDirectory *dir, DavResource *res, int *exists) {
+int versioning_delete_begin(SyncDirectory *dir, DavResource *res, int *exists, int *versionized) {
+    *versionized = 0;
     if(dir->versioning->type == VERSIONING_SIMPLE) {
-        versioning_begin(dir, res, exists);
+        versioning_begin(dir, res, exists, versionized);
     } else {
         // versioning delete with DeltaV currently not supported in dav-sync
         *exists = 1;
@@ -4154,12 +4176,22 @@
     // before sync_put_resource, remote_resource_is_changed does a propfind
     // and sets res->exists
     int exists = res->exists;
+    int vend_required = 0;
     if(dir->versioning && dir->versioning->always && !issplit) {
-        int err = versioning_begin(dir, res, &exists);
-        if(err) {
-            fprintf(stderr, "Cannot store version for resource: %s\n", res->href);
+        // in case the file exists, we need to put the file under
+        // versioncontrol (DeltaV only, does nothing with simple versioning)
+        if(exists && versioning_init(dir, local, res)) {
+            // init failed
+            fprintf(stderr, "Cannot activate versioncontrol for resource: %s\n", res->href);
             free(local_path);
             return -1;
+        } else {
+            int err = versioning_begin(dir, res, &exists, &vend_required);
+            if(err) {
+                fprintf(stderr, "Cannot store version for resource: %s\n", res->href);
+                free(local_path);
+                return -1;
+            }
         }
     }
     
@@ -4176,7 +4208,7 @@
         break;
     }
     
-    if(dir->versioning && dir->versioning->always && !issplit) {
+    if(vend_required) {
         if(versioning_end(dir, res)) {
             fprintf(stderr, "Cannot checkin resource\n");
             ret = 1;
@@ -4355,13 +4387,11 @@
             int exists = 1;
             int vend_required = 0;
             if(dir->versioning && dir->versioning->always) {
-                if(versioning_delete_begin(dir, res, &exists)) {
+                if(versioning_delete_begin(dir, res, &exists, &vend_required)) {
                     fprintf(
                             stderr,
                             "Cannot save resource version before deletion\n");
                     ret = 1;
-                } else {
-                    vend_required = 1;
                 }
             }
             
--- a/libidav/crypto.c	Thu Dec 05 10:46:39 2019 +0100
+++ b/libidav/crypto.c	Thu Dec 05 12:37:48 2019 +0100
@@ -1239,7 +1239,7 @@
     
     // encrypt
     int flags = 0;
-    if(inlen % 16 != 0 || enc->end) {
+    if(inlen % 16 != 0) {
         enc->end = 1;
     }
     if(enc->end) {
--- a/test/main.c	Thu Dec 05 10:46:39 2019 +0100
+++ b/test/main.c	Thu Dec 05 12:37:48 2019 +0100
@@ -34,6 +34,8 @@
 #include "base64.h"
 #include "crypto.h"
 
+int test_main(int argc, char **argv);
+
 #ifdef _WIN32
 int wmain(int argc, wchar_t **argv) {
     return test_main(1, "davtest");

mercurial