141 int cfgret = load_config(ctx) || load_sync_config(); |
141 int cfgret = load_config(ctx) || load_sync_config(); |
142 |
142 |
143 // ignore sigpipe to make sure the program doesn't exit |
143 // ignore sigpipe to make sure the program doesn't exit |
144 // if stdout will be closed (for example by using dav-sync ... | head) |
144 // if stdout will be closed (for example by using dav-sync ... | head) |
145 struct sigaction act; |
145 struct sigaction act; |
146 ZERO(&act, sizeof(struct sigaction)); |
146 memset(&act, 0, sizeof(struct sigaction)); |
147 act.sa_handler = SIG_IGN; |
147 act.sa_handler = SIG_IGN; |
148 sigaction(SIGPIPE, &act, NULL); |
148 sigaction(SIGPIPE, &act, NULL); |
149 |
149 |
150 // prepare signal handler thread |
150 // prepare signal handler thread |
151 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |
151 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |
576 locked = TRUE; |
576 locked = TRUE; |
577 locktokenfile = create_locktoken_file(dir->name, lock->token); |
577 locktokenfile = create_locktoken_file(dir->name, lock->token); |
578 } |
578 } |
579 |
579 |
580 int ret = 0; |
580 int ret = 0; |
581 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"); |
581 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"); |
582 if(!ls) { |
582 if(!ls) { |
583 print_resource_error(sn, "/"); |
583 print_resource_error(sn, "/"); |
584 if(locked) { |
584 if(locked) { |
585 if(dav_unlock(root)) { |
585 if(dav_unlock(root)) { |
586 print_resource_error(sn, "/"); |
586 print_resource_error(sn, "/"); |
973 if(!etag) { |
973 if(!etag) { |
974 fprintf(stderr, "Error: resource %s has no etag\n", res->path); |
974 fprintf(stderr, "Error: resource %s has no etag\n", res->path); |
975 return REMOTE_NO_CHANGE; |
975 return REMOTE_NO_CHANGE; |
976 } |
976 } |
977 char *hash = sync_get_content_hash(res); |
977 char *hash = sync_get_content_hash(res); |
978 |
978 |
979 DavBool issplit = dav_get_property(res, "idav:split") ? TRUE : FALSE; |
979 DavBool issplit = dav_get_property(res, "idav:split") ? TRUE : FALSE; |
980 if(issplit) { |
980 if(issplit) { |
981 util_remove_trailing_pathseparator(res->path); |
981 util_remove_trailing_pathseparator(res->path); |
982 } |
982 } |
983 DavBool iscollection = res->iscollection && !issplit; |
983 DavBool iscollection = res->iscollection && !issplit; |
1015 } else if(local) { |
1015 } else if(local) { |
1016 DavBool nochange = FALSE; |
1016 DavBool nochange = FALSE; |
1017 if(SYNC_SYMLINK(dir) && nullstrcmp(link, local->link_target)) { |
1017 if(SYNC_SYMLINK(dir) && nullstrcmp(link, local->link_target)) { |
1018 ret = REMOTE_CHANGE_LINK; |
1018 ret = REMOTE_CHANGE_LINK; |
1019 nochange = TRUE; |
1019 nochange = TRUE; |
|
1020 } else if(issplit && local->hash && hash) { |
|
1021 if(!strcmp(local->hash, hash)) { |
|
1022 // resource is already up-to-date on the client |
|
1023 nochange = TRUE; |
|
1024 } |
1020 } else if(local->etag) { |
1025 } else if(local->etag) { |
1021 sstr_t e = sstr(etag); |
1026 sstr_t e = sstr(etag); |
1022 if(sstrprefix(e, S("W/"))) { |
1027 if(sstrprefix(e, S("W/"))) { |
1023 e = sstrsubs(e, 2); |
1028 e = sstrsubs(e, 2); |
1024 } |
1029 } |
1543 fprintf(stderr, |
1548 fprintf(stderr, |
1544 "Cannot stat file %s: %s\n", local_path, strerror(errno)); |
1549 "Cannot stat file %s: %s\n", local_path, strerror(errno)); |
1545 } |
1550 } |
1546 |
1551 |
1547 // set metadata from stat |
1552 // set metadata from stat |
1548 local_resource_set_etag(local, etag); |
1553 if(!issplit) { |
|
1554 local_resource_set_etag(local, etag); |
|
1555 } |
1549 if(content_hash) { |
1556 if(content_hash) { |
1550 local->hash = content_hash; |
1557 local->hash = content_hash; |
1551 } |
1558 } |
1552 sync_set_metadata_from_stat(local, &s); |
1559 sync_set_metadata_from_stat(local, &s); |
1553 local->skipped = FALSE; |
1560 local->skipped = FALSE; |
2820 DavBool restore_removed, |
2827 DavBool restore_removed, |
2821 DavBool restore_modified) |
2828 DavBool restore_modified) |
2822 { |
2829 { |
2823 LocalResource *db_res = ucx_map_cstr_get(db->resources, res->path); |
2830 LocalResource *db_res = ucx_map_cstr_get(db->resources, res->path); |
2824 res->tags_updated = 0; |
2831 res->tags_updated = 0; |
2825 if(db_res) { |
2832 if(db_res) { |
|
2833 // copy some metadata from db_res, that localscan does not deliver |
|
2834 res->tags_updated = db_res->tags_updated; |
|
2835 if(db_res->etag) { |
|
2836 res->etag = strdup(db_res->etag); |
|
2837 } |
|
2838 if(db_res->tags_hash) { |
|
2839 res->tags_hash = strdup(db_res->tags_hash); |
|
2840 } |
|
2841 if(db_res->remote_tags_hash) { |
|
2842 res->remote_tags_hash = strdup(db_res->remote_tags_hash); |
|
2843 } |
|
2844 if(db_res->xattr_hash) { |
|
2845 res->xattr_hash = strdup(db_res->xattr_hash); |
|
2846 } |
|
2847 if(db_res->hash) { |
|
2848 res->prev_hash = strdup(db_res->hash); |
|
2849 } |
|
2850 |
|
2851 // if the resource is splitted, copy the part info to the new |
|
2852 // LocalResource obj, because we need it later |
|
2853 if(db_res->parts) { |
|
2854 local_resource_copy_parts(db_res, res); |
|
2855 } |
|
2856 |
|
2857 // check if the file must be restored on the server |
2826 if(svrres) { |
2858 if(svrres) { |
2827 DavResource *remote = ucx_map_cstr_get(svrres, res->path); |
2859 DavResource *remote = ucx_map_cstr_get(svrres, res->path); |
2828 if(restore_removed && !remote) { |
2860 if(restore_removed && !remote) { |
2829 return 1; |
2861 return 1; |
2830 } |
2862 } |
2833 if(!etag || (db_res->etag && strcmp(etag, db_res->etag))) { |
2865 if(!etag || (db_res->etag && strcmp(etag, db_res->etag))) { |
2834 res->restore = TRUE; |
2866 res->restore = TRUE; |
2835 return 1; |
2867 return 1; |
2836 } |
2868 } |
2837 } |
2869 } |
2838 } |
|
2839 |
|
2840 // copy some metadata from db_res, that localscan does not deliver |
|
2841 res->tags_updated = db_res->tags_updated; |
|
2842 if(db_res->etag) { |
|
2843 res->etag = strdup(db_res->etag); |
|
2844 } |
|
2845 if(db_res->tags_hash) { |
|
2846 res->tags_hash = strdup(db_res->tags_hash); |
|
2847 } |
|
2848 if(db_res->remote_tags_hash) { |
|
2849 res->remote_tags_hash = strdup(db_res->remote_tags_hash); |
|
2850 } |
|
2851 if(db_res->xattr_hash) { |
|
2852 res->xattr_hash = strdup(db_res->xattr_hash); |
|
2853 } |
|
2854 if(db_res->hash) { |
|
2855 res->prev_hash = strdup(db_res->hash); |
|
2856 } |
|
2857 |
|
2858 // if the resource is splitted, move the part infos to the new |
|
2859 // LocalResource obj, because we need it later |
|
2860 if(db_res->parts) { |
|
2861 res->parts = db_res->parts; |
|
2862 res->numparts = db_res->numparts; |
|
2863 db_res->parts = NULL; |
|
2864 db_res->numparts = 0; |
|
2865 } |
2870 } |
2866 |
2871 |
2867 // check if metadata has changed |
2872 // check if metadata has changed |
2868 // metadata are tags, mode, owner, xattr |
2873 // metadata are tags, mode, owner, xattr |
2869 // set res->metadata_updated to 1 in case any metadata has changed |
2874 // set res->metadata_updated to 1 in case any metadata has changed |
3114 if(util_strtouint(svr_blocksize_str, &i)) { |
3119 if(util_strtouint(svr_blocksize_str, &i)) { |
3115 svr_blocksize = (size_t)i; |
3120 svr_blocksize = (size_t)i; |
3116 } |
3121 } |
3117 } |
3122 } |
3118 |
3123 |
3119 if(local_blocksize > 0 && svr_blocksize > 0) { |
3124 if(local_blocksize > 0 && svr_blocksize > 0 && local_blocksize != svr_blocksize) { |
3120 fprintf(stderr, "Warning: Blocksize mismatch: %s: local: %zu server: %zu\n", local->path, local_blocksize, svr_blocksize); |
3125 fprintf(stderr, "Warning: Blocksize mismatch: %s: local: %zu server: %zu\n", local->path, local_blocksize, svr_blocksize); |
3121 return svr_blocksize; |
3126 return svr_blocksize; |
3122 } else if(local_blocksize > 0) { |
3127 } else if(local_blocksize > 0) { |
3123 return local_blocksize; |
3128 return local_blocksize; |
3124 } else if(svr_blocksize > 0) { |
3129 } else if(svr_blocksize > 0) { |