963 char *etag = dav_get_string_property(res, "D:getetag"); |
963 char *etag = dav_get_string_property(res, "D:getetag"); |
964 if(!etag) { |
964 if(!etag) { |
965 fprintf(stderr, "Error: resource %s has no etag\n", res->path); |
965 fprintf(stderr, "Error: resource %s has no etag\n", res->path); |
966 return REMOTE_NO_CHANGE; |
966 return REMOTE_NO_CHANGE; |
967 } |
967 } |
|
968 char *hash = sync_get_content_hash(res); |
968 |
969 |
969 DavBool issplit = dav_get_property(res, "idav:split") ? TRUE : FALSE; |
970 DavBool issplit = dav_get_property(res, "idav:split") ? TRUE : FALSE; |
970 if(issplit) { |
971 if(issplit) { |
971 util_remove_trailing_pathseparator(res->path); |
972 util_remove_trailing_pathseparator(res->path); |
972 } |
973 } |
1002 // set change to REMOTE_CHANGE_MKDIR, which will fail later |
1003 // set change to REMOTE_CHANGE_MKDIR, which will fail later |
1003 ret = REMOTE_CHANGE_MKDIR; |
1004 ret = REMOTE_CHANGE_MKDIR; |
1004 } |
1005 } |
1005 } else if(local) { |
1006 } else if(local) { |
1006 DavBool nochange = FALSE; |
1007 DavBool nochange = FALSE; |
1007 char *content_hash = sync_get_content_hash(res); |
|
1008 |
|
1009 if(SYNC_SYMLINK(dir) && nullstrcmp(link, local->link_target)) { |
1008 if(SYNC_SYMLINK(dir) && nullstrcmp(link, local->link_target)) { |
1010 ret = REMOTE_CHANGE_LINK; |
1009 ret = REMOTE_CHANGE_LINK; |
1011 nochange = TRUE; |
1010 nochange = TRUE; |
1012 } else if(content_hash && local->hash) { |
|
1013 if(!strcmp(content_hash, local->hash)) { |
|
1014 nochange = TRUE; |
|
1015 } |
|
1016 } else if(local->etag) { |
1011 } else if(local->etag) { |
1017 sstr_t e = sstr(etag); |
1012 sstr_t e = sstr(etag); |
1018 if(sstrprefix(e, S("W/"))) { |
1013 if(sstrprefix(e, S("W/"))) { |
1019 e = sstrsubs(e, 2); |
1014 e = sstrsubs(e, 2); |
1020 } |
1015 } |
1039 } else if(exists) { |
1034 } else if(exists) { |
1040 ret = type; |
1035 ret = type; |
1041 } else { |
1036 } else { |
1042 ret = REMOTE_CHANGE_NEW; |
1037 ret = REMOTE_CHANGE_NEW; |
1043 } |
1038 } |
1044 |
1039 |
|
1040 // if hashing is enabled we can compare the hash of the remote file |
|
1041 // with the local file to test if a file is really modified |
|
1042 if (!iscollection && |
|
1043 !link && |
|
1044 (ret == REMOTE_CHANGE_MODIFIED || ret == REMOTE_CHANGE_CONFLICT_LOCAL_MODIFIED) && |
|
1045 exists && |
|
1046 hash && |
|
1047 !dir->pull_skip_hashing) |
|
1048 { |
|
1049 // because rehashing a file is slow, there is a config element for |
|
1050 // disabling this (pull-skip-hashing) |
|
1051 char *local_hash = util_file_hash(local_path); |
|
1052 if(local_hash) { |
|
1053 if(!strcmp(hash, local_hash)) { |
|
1054 ret = REMOTE_NO_CHANGE; |
|
1055 } |
|
1056 } |
|
1057 free(local_hash); |
|
1058 } |
|
1059 |
|
1060 // if a file is not modified, check if the metadata has changed |
1045 while(ret == REMOTE_NO_CHANGE && local) { |
1061 while(ret == REMOTE_NO_CHANGE && local) { |
1046 // check if tags have changed |
1062 // check if tags have changed |
1047 if(dir->tagconfig) { |
1063 if(dir->tagconfig) { |
1048 DavXmlNode *tagsprop = dav_get_property_ns(res, DAV_PROPS_NS, "tags"); |
1064 DavXmlNode *tagsprop = dav_get_property_ns(res, DAV_PROPS_NS, "tags"); |
1049 UcxList *remote_tags = NULL; |
1065 UcxList *remote_tags = NULL; |
2907 if(err == 0) { |
2923 if(err == 0) { |
2908 char *etag = dav_get_string_property(remote, "D:getetag"); |
2924 char *etag = dav_get_string_property(remote, "D:getetag"); |
2909 char *hash = sync_get_content_hash(remote); |
2925 char *hash = sync_get_content_hash(remote); |
2910 |
2926 |
2911 if(hash && res->hash && equal) { |
2927 if(hash && res->hash && equal) { |
2912 // if requested, check if the local and remote are equal |
2928 // if requested, check if the local and remote res are equal |
2913 if(!strcmp(hash, res->hash)) { |
2929 if(!strcmp(hash, res->hash)) { |
2914 *equal = TRUE; |
2930 *equal = TRUE; |
2915 return 0; |
2931 return 0; |
2916 } |
2932 } |
2917 } |
2933 } |