dav/sync.c

changeset 49
c5759ac76c1b
parent 48
08d5544c92fb
child 50
9c486ea25161
--- a/dav/sync.c	Sun Jun 15 20:12:48 2014 +0200
+++ b/dav/sync.c	Thu Jul 03 15:50:13 2014 +0200
@@ -109,7 +109,7 @@
         return -1;
     }
     
-    UcxMap *db = load_db(dir->database);
+    SyncDatabase *db = load_db(dir->database);
     if(!db) {
         fprintf(stderr, "Cannot load database file: %s\n", dir->database);
         return -1;
@@ -134,12 +134,12 @@
         // TODO: free
         return 0; // empty repository
     }
-    
+      
     UcxList *stack = ucx_list_prepend(NULL, ls->children);
     while(stack) {
         DavResource *res = stack->data;
         stack = ucx_list_remove(stack, stack);
-        
+         
         while(res) {
             if(sync_get_resource(dir, res, db)) {
                 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path);
@@ -163,10 +163,28 @@
     return 0;
 }
 
-int sync_get_resource(SyncDirectory *dir, DavResource *res, UcxMap *db) {
-    LocalResource *local = ucx_map_cstr_get(db, res->path);
+int sync_get_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db) {
+    LocalResource *local = ucx_map_cstr_get(db->resources, res->path);
+    char *local_path = util_concat_path(dir->path, res->path);
+    
     char *etag = dav_get_property(res, "D:getetag");
+    struct stat s;
     if(local) {
+        if(stat(local_path, &s)) {
+            if(errno == ENOENT) {
+                printf("removed %s\n", res->path);
+                // the file is in the database, but doesn't exists
+                // mark the file as removed to delete it on next push
+                ucx_map_cstr_remove(db->resources, local->path);
+                ucx_map_cstr_put(db->remove, local->path, local);
+                return 0;
+            } else {
+                fprintf(stderr, "stat failed: %s\n", local_path);
+                free(local_path);
+                return -1;
+            }
+        }
+        
         if(local->etag) {
             sstr_t e = sstr(etag);
             if(sstrprefix(e, S("W/"))) {
@@ -179,7 +197,6 @@
         }
     }
     
-    char *local_path = util_concat_path(dir->path, res->path);
     int ret = 0;
     if(res->iscollection) {
         mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
@@ -201,22 +218,17 @@
         fclose(out);
         
         if(ret == 0) {
-            // get file informations for db update
-            struct stat s;
-            if(stat(local_path, &s)) {
-                fprintf(stderr, "stat failed: %s\n", local_path);
-                ret = -1;
-            }
-            
             if(!local) {
+                // new local resource
                 local = calloc(1, sizeof(LocalResource));
                 local->path = strdup(res->path);
-                ucx_map_cstr_put(db, local->path, local);
+                ucx_map_cstr_put(db->resources, local->path, local);
             }
             
             if(local->etag) {
                 free(local->etag);
             }
+            // set metadata from stat
             local->etag = etag;
             local->last_modified = s.st_mtim.tv_sec;
             local->size = s.st_size;
@@ -245,7 +257,7 @@
         return -1;
     }
     
-    UcxMap *db = load_db(dir->database);
+    SyncDatabase *db = load_db(dir->database);
     if(!db) {
         fprintf(stderr, "Cannot load database file: %s\n", dir->database);
         return -1;
@@ -279,7 +291,7 @@
     return 0;
 }
 
-UcxList* local_scan(SyncDirectory *dir, UcxMap *db) {
+UcxList* local_scan(SyncDirectory *dir, SyncDatabase *db) {
     UcxList *resources = NULL;
     
     char *path = strdup("/");
@@ -322,7 +334,9 @@
                 if(S_ISDIR(s.st_mode)) {
                     stack = ucx_list_prepend(stack, new_path);
                 } else {
-                    LocalResource *res = ucx_map_cstr_get(db, new_path);
+                    LocalResource *res = ucx_map_cstr_get(
+                            db->resources,
+                            new_path);
                     if(res) {
                         // the file is already in the database
                         // compare length and lastmodified date
@@ -349,7 +363,7 @@
                         res->etag = NULL;
                         res->last_modified = s.st_mtim.tv_sec;
                         res->size = s.st_size;
-                        ucx_map_cstr_put(db, res->path, res);
+                        ucx_map_cstr_put(db->resources, res->path, res);
                         resources = ucx_list_append(resources, new_path);
                     }
                 }
@@ -364,7 +378,7 @@
     return resources;
 }
 
-int sync_put_resource(SyncDirectory *dir, DavResource *res, UcxMap *db) {
+int sync_put_resource(SyncDirectory *dir, DavResource *res, SyncDatabase *db) {
     char *local_path = util_concat_path(dir->path, res->path);
     FILE *in = fopen(local_path, "r");
     if(!in) {
@@ -389,25 +403,22 @@
     }
     
     if(ret == 0) {
-        LocalResource *local_res = ucx_map_cstr_get(db, res->path);
+        LocalResource *local_res = ucx_map_cstr_get(db->resources, res->path);
         if(local_res->etag) {
             free(local_res->etag);
         }
         
         DavResource *up_res = dav_get(res->session, res->path, "D:getetag");
-        char *etag_str = dav_get_property(up_res, "D:getetag");
-        sstr_t etag;
-        etag.ptr = NULL;
-        if(etag_str) {
-            etag = sstr(etag_str);
-        }
-        if(sstrprefix(etag, S("W/"))) {
-            etag = sstrsubs(etag, 2);
+        char *etag = dav_get_property(up_res, "D:getetag");
+        if(etag) {
+            if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') {
+                etag = etag + 2;
+            } 
         }
         
         
-        if(etag.ptr) {
-            local_res->etag = strdup(etag.ptr);
+        if(etag) {
+            local_res->etag = strdup(etag);
         } else {
             local_res->etag = NULL;
         }

mercurial