dav/sync.c

changeset 145
82475dc12dd4
parent 144
c2c02c9b3be4
child 147
458a8dc68048
--- a/dav/sync.c	Sat Oct 03 13:33:15 2015 +0200
+++ b/dav/sync.c	Sat Oct 03 14:36:12 2015 +0200
@@ -268,7 +268,7 @@
         int exists = 1;
         if(stat(local_path, &s)) {
             // Ignore the fact, that the file is locally removed. If the
-            // server has an updated version, we readd the file or the
+            // server has an updated version, we read the file or the
             // next push will delete it on the server.
             if(errno != ENOENT) {
                 fprintf(stderr, "Cannot stat file: %s\n", local_path);
@@ -308,16 +308,23 @@
     }
       
     int ret = 0;
+    char *tmp_path = create_tmp_download_path(local_path);
     if(res->iscollection) {
         mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
         if(util_mkdir(local_path, mode) && errno != EEXIST) {
             ret = -1;
         }
     } else {
-        FILE *out = fopen(local_path, "wb");
+        if(!tmp_path) {
+            fprintf(stderr, "Cannot create tmp path for %s\n", local_path);
+            free(local_path);
+            return -1;
+        }
+        FILE *out = fopen(tmp_path, "wb");
         if(!out) {
             fprintf(stderr, "Cannot open output file: %s\n", local_path);
             free(local_path);
+            free(tmp_path);
             return -1;
         }
         printf("get: %s\n", res->path);
@@ -326,11 +333,27 @@
         }
         fclose(out);
         
-        if(stat(local_path, &s)) {
-            fprintf(stderr, "Cannot stat file: %s\n", local_path);
-        }
-        
         if(ret == 0) {
+            if(dir->trash && dir->backuppull) {
+                move_to_trash(dir, local_path);
+            }
+            if(rename(tmp_path, local_path)) {
+                fprintf(
+                        stderr,
+                        "Cannot rename file %s to %s\n",
+                        tmp_path,
+                        local_path);
+                perror("");
+                free(tmp_path);
+                free(local_path);
+                return -1;
+            }
+            
+            if(stat(local_path, &s)) {
+                fprintf(stderr, "Cannot stat file: %s\n", local_path);
+                perror("");
+            }
+            
             if(!local) {
                 // new local resource
                 local = calloc(1, sizeof(LocalResource));
@@ -345,9 +368,14 @@
             local->etag = etag;
             local->last_modified = s.st_mtime;
             local->size = s.st_size;
+        } else {
+            if(unlink(tmp_path)) {
+                fprintf(stderr, "Cannot remove tmp file: %s\n", tmp_path);
+            }
         }
     }
     
+    free(tmp_path);
     free(local_path);
     return ret;
 }
@@ -411,6 +439,31 @@
     free(parent);
 }
 
+char* create_tmp_download_path(char *path) {
+    char *new_path = NULL;
+    char *parent = util_parent_path(path);
+    for (int i=0;;i++) {
+        sstr_t np = ucx_asprintf(
+        ucx_default_allocator(),
+            "%sdownload%d-%s",
+            parent,
+            i,
+            util_resource_name(path));
+        
+        struct stat s;
+        if(stat(np.ptr, &s)) {
+            if(errno == ENOENT) {
+                new_path = np.ptr;
+            }
+            break;
+        }
+        free(np.ptr);
+    };
+    
+    free(parent);
+    return new_path;
+}
+
 void move_to_trash(SyncDirectory *dir, char *path) {
     char *new_path = NULL;
     for (int i=0;;i++) {

mercurial