create symlinks on pull

Sat, 20 Apr 2019 18:46:00 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 20 Apr 2019 18:46:00 +0200
changeset 578
bb1e60fada74
parent 577
f49964cf7228
child 579
c80d5730c00b

create symlinks on pull

dav/sync.c file | annotate | diff | comparison | revisions
dav/system.c file | annotate | diff | comparison | revisions
dav/system.h file | annotate | diff | comparison | revisions
libidav/utils.c file | annotate | diff | comparison | revisions
libidav/utils.h file | annotate | diff | comparison | revisions
--- a/dav/sync.c	Sat Apr 20 17:47:40 2019 +0200
+++ b/dav/sync.c	Sat Apr 20 18:46:00 2019 +0200
@@ -552,7 +552,7 @@
     }
     
     int ret = 0;
-    DavResource *ls = dav_query(sn, "select D:getetag,idav:status,idav:tags,idav:finfo,idav:xattributes,idav:split,`idav:content-hash` from / with depth = infinity");
+    DavResource *ls = dav_query(sn, "select D:getetag,idav:status,idav:tags,idav:finfo,idav:xattributes,idav:split,idav:link,`idav:content-hash` from / with depth = infinity");
     if(!ls) {
         print_resource_error(sn, "/");
         if(locked) {
@@ -738,6 +738,10 @@
             prev = elm->prev;
             next = elm->next;
             
+            if(dav_get_property_ns(res, DAV_NS, "link")) {
+                continue;
+            }
+            
             char *hash = sync_get_content_hash(res);
             if(!hash) {
                 continue;
@@ -1268,6 +1272,8 @@
     LocalResource *local = ucx_map_cstr_get(db->resources, path);
     char *local_path = create_local_path(dir, path);
     
+    char *link = dav_get_string_property_ns(res, DAV_NS, "link");
+    
     char *etag = dav_get_string_property(res, "D:getetag");
     SYS_STAT s;
     memset(&s, 0, sizeof(SYS_STAT));
@@ -1285,7 +1291,7 @@
     UcxList *part_updates = NULL;
     uint64_t blockcount = 0;
     char *content_hash = NULL;
-    
+       
     if(res->iscollection && !issplit) {
         // why are we here?
         return 0;
@@ -1295,37 +1301,47 @@
     
     char *tmp_path = NULL;
     FILE *out = NULL;
-    if(!issplit) {
-        tmp_path = create_tmp_download_path(local_path);
-        if(!tmp_path) {
-            fprintf(stderr, "Cannot create tmp path for %s\n", local_path);
+    if(!link) {
+        if(!issplit) {
+            tmp_path = create_tmp_download_path(local_path);
+            if(!tmp_path) {
+                fprintf(stderr, "Cannot create tmp path for %s\n", local_path);
+                free(local_path);
+                return -1;
+            }
+            out = sys_fopen(tmp_path , "wb");
+        } else {
+            out = sys_fopen(local_path, "r+b");
+            if(!out && errno == ENOENT) {
+                out = sys_fopen(local_path, "wb");
+            }
+        }
+        if(!out) {
+            fprintf(stderr, "Cannot open output file: %s\n", local_path);
             free(local_path);
+            if(tmp_path) {
+                free(tmp_path);
+            }
             return -1;
         }
-        out = sys_fopen(tmp_path , "wb");
-    } else {
-        out = sys_fopen(local_path, "r+b");
-        if(!out && errno == ENOENT) {
-            out = sys_fopen(local_path, "wb");
-        }
-    }
-    if(!out) {
-        fprintf(stderr, "Cannot open output file: %s\n", local_path);
-        free(local_path);
-        if(tmp_path) {
-            free(tmp_path);
-        }
-        return -1;
     }
     
     int64_t truncate_file = -1;
-    printf("get: %s\n", path);
-    if(issplit) {
-        part_updates = sync_download_changed_parts(res, local, out, blocksize, &blockcount, &truncate_file, &ret);
+    if(!link) {
+        printf("get: %s\n", path);
+        if(issplit) {
+            part_updates = sync_download_changed_parts(res, local, out, blocksize, &blockcount, &truncate_file, &ret);
+        } else {
+            ret = dav_get_content(res, out, (dav_write_func)fwrite);
+        }
+        fclose(out);
     } else {
-        ret = dav_get_content(res, out, (dav_write_func)fwrite);
-    }
-    fclose(out);
+        printf("link: %s -> %s\n", path, link);
+        if(sys_symlink(link, local_path)) {
+            perror("symlink");
+            ret = 1;
+        }
+    }
     
     if(issplit || dir->hashing) {
         if(truncate_file >= 0) {
@@ -1380,6 +1396,13 @@
         if(local->hash) {
             free(local->hash);
         }
+        if(local->link_target) {
+            free(local->link_target);
+        }
+        
+        if(link) {
+            local->link_target = strdup(link);
+        }
         
         update_parts(local, part_updates, blockcount);
         
--- a/dav/system.c	Sat Apr 20 17:47:40 2019 +0200
+++ b/dav/system.c	Sat Apr 20 18:46:00 2019 +0200
@@ -32,6 +32,7 @@
 #include <dirent.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <errno.h>
 
 #ifndef _WIN32
 #include <unistd.h>
@@ -111,6 +112,17 @@
     return readlink(path, buffer, size);
 }
 
+int sys_symlink(const char *target, const char *linkpath) {
+    int err = symlink(target, linkpath);
+    if(err && errno == EEXIST) {
+        if(unlink(linkpath)) {
+            return 1;
+        }
+        return sys_symlink(target, linkpath);
+    }
+    return err;
+}
+
 #else
 /* ---------- Windows implementation ---------- */
 
@@ -294,4 +306,10 @@
     return 1;
 }
 
+int sys_symlink(const char *target, const char *linkpath) {
+    // TODO
+    fprintf(stderr, "sys_symlink: implement me\n");
+    return 1;
+}
+
 #endif
--- a/dav/system.h	Sat Apr 20 17:47:40 2019 +0200
+++ b/dav/system.h	Sat Apr 20 18:46:00 2019 +0200
@@ -84,6 +84,8 @@
 
 ssize_t sys_readlink(const char *path, char *buffer, size_t size);
 
+int sys_symlink(const char *target, const char *linkpath);
+
 #ifdef __cplusplus
 }
 #endif
--- a/libidav/utils.c	Sat Apr 20 17:47:40 2019 +0200
+++ b/libidav/utils.c	Sat Apr 20 18:46:00 2019 +0200
@@ -644,8 +644,8 @@
     return space;
 }
 
-char* util_parent_path(char *path) {
-    char *name = util_resource_name(path);
+char* util_parent_path(const char *path) {
+    char *name = util_resource_name((char*)path);
     size_t namelen = strlen(name);
     size_t pathlen = strlen(path);
     size_t parentlen = pathlen - namelen;
--- a/libidav/utils.h	Sat Apr 20 17:47:40 2019 +0200
+++ b/libidav/utils.h	Sat Apr 20 18:46:00 2019 +0200
@@ -83,7 +83,7 @@
 void util_capture_header(CURL *handle, UcxMap* map);
 
 char* util_path_to_url(DavSession *sn, char *path);
-char* util_parent_path(char *path);
+char* util_parent_path(const char *path);
 
 int util_getboolean(const char *v);
 int util_strtouint(const char *str, uint64_t *value);

mercurial