dav/sync.c

changeset 190
a76e43d89f55
parent 185
cd42cccee550
child 191
0e45b04236a7
--- a/dav/sync.c	Wed Feb 10 12:32:07 2016 +0100
+++ b/dav/sync.c	Fri Feb 12 18:26:58 2016 +0100
@@ -88,6 +88,12 @@
         ret = cmd_pull(args);
     } else if(!strcmp(cmd, "push")) {
         ret = cmd_push(args);
+    } else if(!strcasecmp(cmd, "version") || !strcasecmp(cmd, "-version") || !strcasecmp(cmd, "--version")) {
+#ifdef DEBUG
+        fprintf(stderr, "dav-synv %s unstable\n", DAV_VERSION);
+#else
+        fprintf(stderr, "dav-sync %s\n", DAV_VERSION);
+#endif
     }
     
     // TODO: cleanup sync config (don't forget to call regfree for regex)
@@ -236,12 +242,19 @@
     // delete every remotely removed resource
     UcxMapIterator i = ucx_map_iterator(db->resources);
     LocalResource *local;
+    UcxList *rmdirs = NULL;
     UCX_MAP_FOREACH(key, local, i) {
         if (res_matches_filter(dir, local->path)) {
             continue;
         }
         // sync_remove_resource does all necessary tests
-        sync_remove_local_resource(dir, local);
+        if(sync_remove_local_resource(dir, local)) {
+            rmdirs = ucx_list_append(rmdirs, local);
+        }
+    }
+    UCX_FOREACH(elm, rmdirs) {
+        LocalResource *local_dir = elm->data;
+        sync_remove_local_directory(dir, local_dir);
     }
     ucx_map_free(db->resources);
     db->resources = svrres;
@@ -265,7 +278,7 @@
     
     char *etag = dav_get_property(res, "D:getetag");
     struct stat s;
-    if(local) {
+    if(local && !res->iscollection) {
         int exists = 1;
         if(stat(local_path, &s)) {
             // Ignore the fact, that the file is locally removed. If the
@@ -315,6 +328,16 @@
         if(util_mkdir(local_path, mode) && errno != EEXIST) {
             ret = -1;
         }
+        
+        if(ret == 0) {
+            if(!local) {
+                // new local resource
+                local = calloc(1, sizeof(LocalResource));
+                local->path = util_concat_path(res->path, "/");
+                local->last_modified = s.st_mtime;
+                ucx_map_cstr_put(db->resources, local->path, local);
+            }
+        }
     } else {
         if(!tmp_path) {
             fprintf(stderr, "Cannot create tmp path for %s\n", local_path);
@@ -381,17 +404,22 @@
     return ret;
 }
 
-void sync_remove_local_resource(SyncDirectory *dir, LocalResource *res) {
+int sync_remove_local_resource(SyncDirectory *dir, LocalResource *res) {
     char *local_path = util_concat_path(dir->path, res->path);
     struct stat s;
     if(stat(local_path, &s)) {
         free(local_path);
-        return;
+        return 0;
+    }
+    
+    if(S_ISDIR(s.st_mode)) {
+        free(local_path);
+        return 1;
     }
     
     if(s.st_mtime != res->last_modified) {
         free(local_path);
-        return;
+        return 0;
     }
     
     printf("delete: %s\n", res->path);
@@ -402,6 +430,19 @@
         fprintf(stderr, "Cannot remove file %s\n", local_path);
     }
     free(local_path);
+    
+    return 0;
+}
+
+void sync_remove_local_directory(SyncDirectory *dir, LocalResource *res) {
+    char *local_path = util_concat_path(dir->path, res->path);
+    
+    printf("delete: %s\n", res->path);
+    if(rmdir(local_path)) {
+        // TODO
+    }
+    
+    free(local_path);
 }
 
 void rename_local_file(SyncDirectory *dir, SyncDatabase *db, char *path) {
@@ -549,10 +590,18 @@
         if (!res_matches_filter(dir, local_res->path+1)) {
             // upload every changed file
             if (local_resource_is_changed(dir, db, local_res)) {
-                printf("put: %s\n", local_res->path);
                 DavResource *res = dav_resource_new(sn, local_res->path);
-                if(sync_put_resource(dir, res, local_res)) {
-                    // TODO: I don't know what to do now
+                
+                if(local_res->isdirectory) {
+                    printf("mkcol: %s\n", local_res->path);
+                    if(sync_mkdir(dir, res, local_res)) {
+                        // TODO: I don't know what to do now
+                    }
+                } else {
+                    printf("put: %s\n", local_res->path);
+                    if(sync_put_resource(dir, res, local_res)) {
+                        // TODO: I don't know what to do now
+                    }
                 }
                 dav_resource_free(res);
             }
@@ -616,6 +665,7 @@
                 int isdir;
                 LocalResource *res = local_resource_new(dir, db, new_path, &isdir);
                 if(isdir) {
+                    resources = ucx_list_append(resources, res);
                     stack = ucx_list_prepend(stack, new_path);
                 } else if(res) {
                     resources = ucx_list_append(resources, res);
@@ -706,6 +756,11 @@
         return res;
     } else {
         *isdir = 1;
+        LocalResource *res = calloc(1, sizeof(LocalResource));
+        res->path = util_concat_path(path, "/");
+        res->last_modified = s.st_mtime;
+        res->isdirectory = 1;
+        return res;
     }
     return NULL;
 }
@@ -822,31 +877,52 @@
     return ret;
 }
 
+int sync_mkdir(SyncDirectory *dir, DavResource *res, LocalResource *local) {
+    res->iscollection = 1;
+    int ret = -1;
+    for(int i=0;i<dir->max_retry;i++) {
+        if(dav_create(res)) {
+            continue;
+        }
+        ret = 0;
+        break;
+    }
+    return ret;
+}
+
 int sync_delete_remote_resource(DavSession *sn, LocalResource *local_res) {
     DavResource *res = dav_get(sn, local_res->path, "D:getetag");
     if(!res) {
         return sn->error == DAV_NOT_FOUND ? 0 : 1;
     }
     
-    char *etag = dav_get_property(res, "D:getetag");
-    if(etag) {
-        if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') {
-            etag = etag + 2;
-        } 
-    }
-    
     int ret = 0;
-    if(etag && !strcmp(etag, local_res->etag)) {
-        // local resource metadata == remote resource metadata
-        // resource can be deleted
+    if(res->iscollection) {
         printf("delete: %s\n", res->path);
         if(dav_delete(res)) {
-            if(sn->error != DAV_NOT_FOUND) {
-                fprintf(stderr, "Cannot delete resource %s\n", res->path);
-            }
+            ret = 1;
+            fprintf(stderr, "Cannot delete resource %s\n", res->path);
         }
     } else {
-        ret = 1;
+        char *etag = dav_get_property(res, "D:getetag");
+        if(etag) {
+            if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') {
+                etag = etag + 2;
+            } 
+        }
+
+        if(etag && !strcmp(etag, local_res->etag)) {
+            // local resource metadata == remote resource metadata
+            // resource can be deleted
+            printf("delete: %s\n", res->path);
+            if(dav_delete(res)) {
+                if(sn->error != DAV_NOT_FOUND) {
+                    fprintf(stderr, "Cannot delete resource %s\n", res->path);
+                }
+            }
+        } else {
+            ret = 1;
+        }
     }
     
     // cleanup

mercurial