# HG changeset patch # User Olaf Wintermann # Date 1555265298 -7200 # Node ID c36eddf167a86a7e9ce89f376f963b12569d41d4 # Parent b8f798d240ab6ea56f888c06318570c9ee4fb17d read link on LocalResource creation diff -r b8f798d240ab -r c36eddf167a8 dav/sync.c --- 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( diff -r b8f798d240ab -r c36eddf167a8 dav/system.c --- a/dav/system.c Sun Apr 14 19:39:08 2019 +0200 +++ b/dav/system.c Sun Apr 14 20:08:18 2019 +0200 @@ -91,6 +91,10 @@ return stat(path, s); } +int sys_lstat(const char *path, SYS_STAT *s) { + return lstat(path, s); +} + int sys_rename(const char *oldpath, const char *newpath) { return rename(oldpath, newpath); } @@ -103,6 +107,10 @@ return mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); } +ssize_t sys_readlink(const char *path, char *buffer, size_t size) { + return readlink(path, buffer, size); +} + #else /* ---------- Windows implementation ---------- */ @@ -226,6 +234,18 @@ return ret; } +int sys_lstat(const char *path, SYS_STAT *s) { + // TODO: fix + wchar_t *fpath = path2winpath(path, FALSE, NULL); + if(!fpath) { + fprintf(stderr, "Cannot convert path \"%s\" to UTF16\n", path); + return -1; + } + int ret = _wstat64(fpath, s); + free(fpath); + return ret; +} + int sys_rename(const char *oldpath, const char *newpath) { wchar_t *o = path2winpath(oldpath, FALSE, NULL); wchar_t *n = path2winpath(newpath, FALSE, NULL); @@ -268,4 +288,10 @@ return ret; } +ssize_t sys_readlink(const char *path, char *buffer, size_t size) { + // TODO + fprintf(stderr, "sys_readlink: implement me\n"); + return 1; +} + #endif diff -r b8f798d240ab -r c36eddf167a8 dav/system.h --- a/dav/system.h Sun Apr 14 19:39:08 2019 +0200 +++ b/dav/system.h Sun Apr 14 20:08:18 2019 +0200 @@ -76,11 +76,14 @@ FILE* sys_fopen(const char *path, const char *mode); int sys_stat(const char *path, SYS_STAT *s); +int sys_lstat(const char *path, SYS_STAT *s); int sys_rename(const char *oldpath, const char *newpath); int sys_unlink(const char *path); int sys_mkdir(const char *path); +ssize_t sys_readlink(const char *path, char *buffer, size_t size); + #ifdef __cplusplus } #endif