dav/sync.c

changeset 574
c36eddf167a8
parent 573
b8f798d240ab
child 576
62cc92445234
--- a/dav/sync.c	Sun Apr 14 19:39:08 2019 +0200
+++ b/dav/sync.c	Sun Apr 14 20:08:18 2019 +0200
@@ -2401,33 +2401,54 @@
 LocalResource* local_resource_new(SyncDirectory *dir, SyncDatabase *db, char *path) {
     char *file_path = create_local_path(dir, path);
     SYS_STAT s;
-    if(sys_stat(file_path, &s)) {
+    if(sys_lstat(file_path, &s)) {
         fprintf(stderr, "Cannot stat file %s\n", file_path);
         free(file_path);
         return NULL;
     }
-    free(file_path);
 
+    LocalResource *res = calloc(1, sizeof(LocalResource));
+    res->mode = s.st_mode & 07777;
+    res->uid = s.st_uid;
+    res->gid = s.st_gid;
+    res->last_modified = s.st_mtime;
     if(!S_ISDIR(s.st_mode)) {
-        LocalResource *res = calloc(1, sizeof(LocalResource));
         res->path = strdup(path);
-        res->etag = NULL;
-        res->last_modified = s.st_mtime;
         res->size = s.st_size;
-        res->mode = s.st_mode & 07777;
-        res->uid = s.st_uid;
-        res->gid = s.st_gid;
-        return res;
     } else {
-        LocalResource *res = calloc(1, sizeof(LocalResource));
         res->path = util_concat_path(path, "/");
-        res->last_modified = s.st_mtime;
-        res->mode = s.st_mode & 07777;
-        res->uid = s.st_uid;
-        res->gid = s.st_gid;
         res->isdirectory = 1;
-        return res;
-    }
+    }
+    
+    if(S_ISLNK(s.st_mode)) {
+        size_t lnksize = s.st_size > 256 ? s.st_size : 256;
+        char *lnkbuf = malloc(lnksize);
+        
+        ssize_t len = 0;
+        for(int i=0;i<4;i++) {
+            // we try to read the link at most 4 times
+            // only repeat if the buffer is too small
+            len = sys_readlink(file_path, lnkbuf, lnksize);
+            if(len != lnksize) {
+                break;
+            }
+            lnksize *= 2;
+            lnkbuf = realloc(lnkbuf, lnksize);
+        }
+        
+        if(len > 0) {
+            res->link_target = lnkbuf;
+            res->link_target[len] = 0;
+        } else {
+            free(lnkbuf);
+        }
+        
+        free(lnkbuf);
+    }
+    
+    free(file_path);
+    
+    return res;
 }
 
 int local_resource_is_changed(

mercurial