store relative link in LocalResource

Sat, 20 Apr 2019 12:31:08 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 20 Apr 2019 12:31:08 +0200
changeset 576
62cc92445234
parent 575
f746f601c35c
child 577
f49964cf7228

store relative link in LocalResource

dav/scfg.c file | annotate | diff | comparison | revisions
dav/scfg.h file | annotate | diff | comparison | revisions
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/scfg.c	Tue Apr 16 11:46:53 2019 +0200
+++ b/dav/scfg.c	Sat Apr 20 12:31:08 2019 +0200
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2018 Olaf Wintermann. All rights reserved.
+ * Copyright 2019 Olaf Wintermann. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -535,6 +535,7 @@
     dir->lock_timeout = lock_timeout;
     dir->metadata = metadata;
     dir->splitconfig = splitconfig;
+    dir->symlink = SYNC_SYMLINK_STORE; // TODO: add config elements
     if((metadata & FINFO_MODE) == FINFO_MODE) {
         dir->db_settings = DB_STORE_MODE;
     }
--- a/dav/scfg.h	Tue Apr 16 11:46:53 2019 +0200
+++ b/dav/scfg.h	Sat Apr 20 12:31:08 2019 +0200
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2018 Olaf Wintermann. All rights reserved.
+ * Copyright 2019 Olaf Wintermann. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -46,6 +46,10 @@
 #define SYNC_CMD_ARCHIVE 4
 #define SYNC_CMD_RESTORE 8
     
+#define SYNC_SYMLINK_STORE 1
+#define SYNC_SYMLINK_EXTERN_NOFOLLOW 2
+#define SYNC_SYMLINK_INTERN_NOFOLLOW 4
+    
 #define DEFAULT_TAG_XATTR "tags"
 #define MACOS_TAG_XATTR "com.apple.metadata:_kMDItemUserTags"
     
@@ -69,6 +73,7 @@
     uint32_t metadata;
     int max_retry;
     int allow_cmd;
+    int symlink;
     time_t lock_timeout;
     bool backuppull;
     bool lockpull;
--- a/dav/sync.c	Tue Apr 16 11:46:53 2019 +0200
+++ b/dav/sync.c	Sat Apr 20 12:31:08 2019 +0200
@@ -2421,7 +2421,8 @@
     }
     
     if(S_ISLNK(s.st_mode)) {
-        size_t lnksize = s.st_size > 256 ? s.st_size : 256;
+        off_t l_sz = s.st_size + 16;
+        size_t lnksize = l_sz > 256 ? l_sz : 256;
         char *lnkbuf = malloc(lnksize);
         
         ssize_t len = 0;
@@ -2437,10 +2438,28 @@
         }
         
         if(len > 0) {
-            res->link_target = lnkbuf;
-            res->link_target[len] = 0;
-        } else {
-            free(lnkbuf);
+            // readlink successful
+            lnkbuf[len] = 0;
+            
+            char *normalized = NULL;
+            if(lnkbuf[0] != '/') {
+                char *link_parent = util_parent_path(res->path);
+                char *abs_link_parent = util_concat_path(dir->path, link_parent);
+                char *link = util_concat_path(abs_link_parent, lnkbuf);
+                normalized = util_path_normalize(link);
+                free(abs_link_parent);
+                free(link_parent);
+                free(link);
+            } else {
+                normalized = util_path_normalize(lnkbuf);
+            }
+            
+            if(util_path_isrelated(dir->path, normalized)) {
+                // the link points to a file inside the syncdir
+                char *rel = util_create_relative_path(normalized, file_path);
+                res->link_target = rel;
+            }
+            free(normalized);
         }
         
         free(lnkbuf);
--- a/dav/system.c	Tue Apr 16 11:46:53 2019 +0200
+++ b/dav/system.c	Sat Apr 20 12:31:08 2019 +0200
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2018 Olaf Wintermann. All rights reserved.
+ * Copyright 2019 Olaf Wintermann. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
--- a/dav/system.h	Tue Apr 16 11:46:53 2019 +0200
+++ b/dav/system.h	Sat Apr 20 12:31:08 2019 +0200
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2018 Olaf Wintermann. All rights reserved.
+ * Copyright 2019 Olaf Wintermann. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
--- a/libidav/utils.c	Tue Apr 16 11:46:53 2019 +0200
+++ b/libidav/utils.c	Sat Apr 20 12:31:08 2019 +0200
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2018 Olaf Wintermann. All rights reserved.
+ * Copyright 2019 Olaf Wintermann. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -455,6 +455,68 @@
     return space;
 }
 
+char* util_create_relative_path(const char *abspath, const char *base) {
+    size_t path_len = strlen(abspath);
+    size_t base_len = strlen(base);
+    
+    if(abspath[path_len-1] == '/') {
+        path_len--;
+    }
+    if(base[base_len-1] == '/') {
+        base_len--;
+    }
+    // get base parent
+    for(int i=base_len-1;i>=0;i--) {
+        if(base[i] == '/') {
+            base_len = i+1;
+            break;
+        }
+    }
+    
+    size_t max = path_len > base_len ? base_len : path_len;
+    
+    // get prefix of abspath and base
+    // this dir is the root of the link
+    size_t i;
+    size_t last_dir = 0;
+    for(i=0;i<max;i++) {
+        char c = abspath[i];
+        if(c != base[i]) {
+            break;
+        } else if(c == '/') {
+            last_dir = i;
+        }
+    }
+    
+    char *ret = NULL;
+    UcxBuffer *out = NULL;
+    if(last_dir+1 < base_len) {
+        // base is deeper than the link root, we have to go backwards
+        int dircount = 0;
+        for(int i=last_dir+1;i<base_len;i++) {
+            if(base[i] == '/') {
+                dircount++;
+            }
+        }
+        
+        out = ucx_buffer_new(NULL, dircount*3+path_len-last_dir, UCX_BUFFER_AUTOEXTEND);
+        
+        for(int i=0;i<dircount;i++) {
+            ucx_buffer_puts(out, "../");
+        }
+    } else {
+        out = ucx_buffer_new(NULL, 1024, path_len - last_dir);
+    }
+    
+    ucx_buffer_puts(out, abspath + last_dir + 1);
+    ucx_buffer_putc(out, 0);
+    out->flags = 0;
+    ret = out->space;
+    ucx_buffer_free(out);
+    
+    return ret;
+}
+
 
 void util_capture_header(CURL *handle, UcxMap* map) {
     if(map) {
--- a/libidav/utils.h	Tue Apr 16 11:46:53 2019 +0200
+++ b/libidav/utils.h	Sat Apr 20 12:31:08 2019 +0200
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2018 Olaf Wintermann. All rights reserved.
+ * Copyright 2019 Olaf Wintermann. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -78,6 +78,7 @@
 int util_path_isrelated(const char *path1, const char *path2);
 
 char* util_path_normalize(const char *path);
+char* util_create_relative_path(const char *abspath, const char *base);
 
 void util_capture_header(CURL *handle, UcxMap* map);
 

mercurial