# HG changeset patch # User Olaf Wintermann # Date 1555778760 -7200 # Node ID bb1e60fada74297f28ae9bea8461012a9ed4fe6b # Parent f49964cf72286edd8082d0625cd990fc4463001c create symlinks on pull diff -r f49964cf7228 -r bb1e60fada74 dav/sync.c --- 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); diff -r f49964cf7228 -r bb1e60fada74 dav/system.c --- 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 #include #include +#include #ifndef _WIN32 #include @@ -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 diff -r f49964cf7228 -r bb1e60fada74 dav/system.h --- 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 diff -r f49964cf7228 -r bb1e60fada74 libidav/utils.c --- 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; diff -r f49964cf7228 -r bb1e60fada74 libidav/utils.h --- 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);