dav/sync.c

changeset 221
e22c29b7ee2f
parent 220
f1b3873a6525
child 222
7b73058d782e
--- a/dav/sync.c	Fri Mar 18 13:00:00 2016 +0100
+++ b/dav/sync.c	Fri Mar 18 15:08:30 2016 +0100
@@ -121,8 +121,8 @@
     fprintf(stderr, "Usage: %s command [options] arguments...\n\n", cmd);
     
     fprintf(stderr, "Commands:\n");
-    fprintf(stderr, "        pull [-c] <directory>\n");
-    fprintf(stderr, "        push [-c] <directory>\n");
+    fprintf(stderr, "        pull [-cld] <directory>\n");
+    fprintf(stderr, "        push [-cld] <directory>\n");
     fprintf(stderr, "        resolve-conflicts <directory>\n");
     fprintf(stderr, "        delete-conflicts <directory>\n");
     fprintf(stderr, "        trash-info <directory>\n");
@@ -130,6 +130,8 @@
     
     fprintf(stderr, "Options:\n");
     fprintf(stderr, "        -c         Disable conflict detection\n");
+    fprintf(stderr, "        -l         Lock the repository before access\n");
+    fprintf(stderr, "        -d         Don't lock the repository\n");
     //fprintf(stderr, "        -r         Read changes from stdin\n\n");
     fprintf(stderr, "        -v         verbose output (all commands)\n\n");
     
@@ -223,9 +225,30 @@
         curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr);
     }
     
+    // lock repository
+    DavBool locked = FALSE;
+    DavResource *root = dav_resource_new(sn, "/");
+    root->iscollection = TRUE;
+    if((dir->lockpush || cmd_getoption(a, "lock")) && !cmd_getoption(a, "nolock")) {
+        if(dav_lock(root)) {
+            print_resource_error(sn, "/");
+            dav_session_destroy(sn);
+            fprintf(stderr, "Abort\n");
+            return -1;
+        }
+        locked = TRUE;
+    }
+    
+    int ret = 0;
     DavResource *ls = dav_query(sn, "select D:getetag,idav:status from / with depth = infinity");
     if(!ls) {
         print_resource_error(sn, "/");
+        if(locked) {
+            if(dav_unlock(root)) {
+                print_resource_error(sn, "/");
+            }
+        }
+        
         fprintf(stderr, "Abort\n");
         
         dav_session_destroy(sn);
@@ -240,6 +263,11 @@
     if(!ls->children) {
         // TODO: free
         fprintf(stderr, "Repository is empty\n");
+        if(locked) {
+            if(dav_unlock(root)) {
+                print_resource_error(sn, "/");
+            }
+        }
         return 0; // empty repository
     }
     
@@ -305,26 +333,35 @@
     ucx_map_free(db->resources);
     db->resources = svrres;
     
+    // unlock repository
+    if(locked) {
+        if(dav_unlock(root)) {
+            print_resource_error(sn, "/");
+            ret = -1;
+        }
+    }
+    
     // store db
     if(store_db(db, dir->database)) {
         fprintf(stderr, "Cannot store sync db\n");
-        fprintf(stderr, "Abort\n");
-        return -1; // TODO: don't return here
+        ret = -1;
     }
     
     // TODO: cleanup - BUT DONT CLEANUP SYNC CONFIG (do this in main!)
     dav_session_destroy(sn);
     
     // Report
-    char *str_success = sync_success == 1 ? "file" : "files";
-    char *str_delete = sync_delete == 1 ? "file" : "files";
-    char *str_error = sync_error == 1 ? "error" : "errors";
-    printf("Result: %d %s pulled, %d %s deleted, %d %s\n",
-            sync_success, str_success,
-            sync_delete,str_delete,
-            sync_error, str_error);
+    if(ret == 0) {
+        char *str_success = sync_success == 1 ? "file" : "files";
+        char *str_delete = sync_delete == 1 ? "file" : "files";
+        char *str_error = sync_error == 1 ? "error" : "errors";
+        printf("Result: %d %s pulled, %d %s deleted, %d %s\n",
+                sync_success, str_success,
+                sync_delete,str_delete,
+                sync_error, str_error);
+    }
     
-    return 0;
+    return ret;
 }
 
 int sync_get_resource(
@@ -666,8 +703,8 @@
         curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr);
     }
     
-    DavResource *testsvr = dav_query(sn, "select - from / with depth = 0");
-    if(!testsvr) {
+    DavResource *root = dav_query(sn, "select - from / with depth = 0");
+    if(!root) {
         print_resource_error(sn, "/");
         dav_session_destroy(sn);
         fprintf(stderr, "Abort\n");
@@ -676,6 +713,18 @@
     
     int cdt = cmd_getoption(a, "conflict") ? 0 : 1; // conflict detection
     
+    // lock repository
+    DavBool locked = FALSE;
+    if((dir->lockpush || cmd_getoption(a, "lock")) && !cmd_getoption(a, "nolock")) {
+        if(dav_lock(root)) {
+            print_resource_error(sn, "/");
+            dav_session_destroy(sn);
+            fprintf(stderr, "Abort\n");
+            return -1;
+        }
+        locked = TRUE;
+    }
+    
     int sync_success = 0;
     int sync_delete = 0;
     int sync_skipped = 0;
@@ -759,26 +808,37 @@
     ucx_map_free(db->resources);
     db->resources = lclres;
     
+    // unlock repository
+    if(locked) {
+        if(dav_unlock(root)) {
+            print_resource_error(sn, "/");
+            ret = -1;
+        }
+    }
+    
     // store db
     if(store_db(db, dir->database)) {
         fprintf(stderr, "Cannot store sync db\n");
-        return -1;
+        ret = -1;
     }
     
-    // TODO: free res
+    // cleanup
+    dav_session_destroy(sn);
     
     // Report
-    char *str_success = sync_success == 1 ? "file" : "files";
-    char *str_delete = sync_delete == 1 ? "file" : "files";
-    char *str_skipped = sync_delete == 1 ? "file" : "files";
-    char *str_error = sync_error == 1 ? "error" : "errors";
-    printf("Result: %d %s pushed, %d %s deleted, %d %s skipped, %d %s\n",
-            sync_success, str_success,
-            sync_delete,str_delete,
-            sync_skipped,str_skipped,
-            sync_error, str_error);
+    if(ret == 0) {
+        char *str_success = sync_success == 1 ? "file" : "files";
+        char *str_delete = sync_delete == 1 ? "file" : "files";
+        char *str_skipped = sync_delete == 1 ? "file" : "files";
+        char *str_error = sync_error == 1 ? "error" : "errors";
+        printf("Result: %d %s pushed, %d %s deleted, %d %s skipped, %d %s\n",
+                sync_success, str_success,
+                sync_delete,str_delete,
+                sync_skipped,str_skipped,
+                sync_error, str_error);
+    }
     
-    return 0;
+    return ret;
 }
 
 UcxList* local_scan(SyncDirectory *dir, SyncDatabase *db) {
@@ -905,7 +965,6 @@
         res->isdirectory = 1;
         return res;
     }
-    return NULL;
 }
 
 int local_resource_is_changed(SyncDirectory *dir, SyncDatabase *db, LocalResource *res) {

mercurial