--- a/dav/sync.c Wed Nov 20 08:44:26 2019 +0100 +++ b/dav/sync.c Wed Nov 20 11:57:45 2019 +0100 @@ -143,7 +143,7 @@ // ignore sigpipe to make sure the program doesn't exit // if stdout will be closed (for example by using dav-sync ... | head) struct sigaction act; - ZERO(&act, sizeof(struct sigaction)); + memset(&act, 0, sizeof(struct sigaction)); act.sa_handler = SIG_IGN; sigaction(SIGPIPE, &act, NULL); @@ -578,7 +578,7 @@ } int ret = 0; - DavResource *ls = dav_query(sn, "select D:getetag,idav:status,idav:split,`idav:content-hash`,idavprops:tags,idavprops:finfo,idavprops:xattributes,idavprops:link from / with depth = infinity"); + DavResource *ls = dav_query(sn, "select D:getetag,idav:split,idav:status,`idav:content-hash`,idavprops:tags,idavprops:finfo,idavprops:xattributes,idavprops:link from / with depth = infinity"); if(!ls) { print_resource_error(sn, "/"); if(locked) { @@ -975,7 +975,7 @@ return REMOTE_NO_CHANGE; } char *hash = sync_get_content_hash(res); - + DavBool issplit = dav_get_property(res, "idav:split") ? TRUE : FALSE; if(issplit) { util_remove_trailing_pathseparator(res->path); @@ -1017,6 +1017,11 @@ if(SYNC_SYMLINK(dir) && nullstrcmp(link, local->link_target)) { ret = REMOTE_CHANGE_LINK; nochange = TRUE; + } else if(issplit && local->hash && hash) { + if(!strcmp(local->hash, hash)) { + // resource is already up-to-date on the client + nochange = TRUE; + } } else if(local->etag) { sstr_t e = sstr(etag); if(sstrprefix(e, S("W/"))) { @@ -1545,7 +1550,9 @@ } // set metadata from stat - local_resource_set_etag(local, etag); + if(!issplit) { + local_resource_set_etag(local, etag); + } if(content_hash) { local->hash = content_hash; } @@ -2822,21 +2829,7 @@ { LocalResource *db_res = ucx_map_cstr_get(db->resources, res->path); res->tags_updated = 0; - if(db_res) { - if(svrres) { - DavResource *remote = ucx_map_cstr_get(svrres, res->path); - if(restore_removed && !remote) { - return 1; - } - if(!res->isdirectory && restore_modified && remote) { - char *etag = dav_get_string_property(remote, "D:getetag"); - if(!etag || (db_res->etag && strcmp(etag, db_res->etag))) { - res->restore = TRUE; - return 1; - } - } - } - + if(db_res) { // copy some metadata from db_res, that localscan does not deliver res->tags_updated = db_res->tags_updated; if(db_res->etag) { @@ -2855,13 +2848,25 @@ res->prev_hash = strdup(db_res->hash); } - // if the resource is splitted, move the part infos to the new + // if the resource is splitted, copy the part info to the new // LocalResource obj, because we need it later if(db_res->parts) { - res->parts = db_res->parts; - res->numparts = db_res->numparts; - db_res->parts = NULL; - db_res->numparts = 0; + local_resource_copy_parts(db_res, res); + } + + // check if the file must be restored on the server + if(svrres) { + DavResource *remote = ucx_map_cstr_get(svrres, res->path); + if(restore_removed && !remote) { + return 1; + } + if(!res->isdirectory && restore_modified && remote) { + char *etag = dav_get_string_property(remote, "D:getetag"); + if(!etag || (db_res->etag && strcmp(etag, db_res->etag))) { + res->restore = TRUE; + return 1; + } + } } // check if metadata has changed @@ -2996,7 +3001,7 @@ return 0; } - if(remote->iscollection) { + if(remote->iscollection && !res->parts) { return 1; } @@ -3116,7 +3121,7 @@ } } - if(local_blocksize > 0 && svr_blocksize > 0) { + if(local_blocksize > 0 && svr_blocksize > 0 && local_blocksize != svr_blocksize) { fprintf(stderr, "Warning: Blocksize mismatch: %s: local: %zu server: %zu\n", local->path, local_blocksize, svr_blocksize); return svr_blocksize; } else if(local_blocksize > 0) {