1037 ret = REMOTE_CHANGE_NEW; |
1037 ret = REMOTE_CHANGE_NEW; |
1038 } |
1038 } |
1039 |
1039 |
1040 // if hashing is enabled we can compare the hash of the remote file |
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 |
1041 // with the local file to test if a file is really modified |
|
1042 DavBool update_db = FALSE; |
|
1043 char *update_hash = NULL; |
1042 if (!iscollection && |
1044 if (!iscollection && |
1043 !link && |
1045 !link && |
1044 (ret == REMOTE_CHANGE_MODIFIED || ret == REMOTE_CHANGE_CONFLICT_LOCAL_MODIFIED) && |
1046 (ret == REMOTE_CHANGE_MODIFIED || ret == REMOTE_CHANGE_CONFLICT_LOCAL_MODIFIED) && |
1045 exists && |
1047 exists && |
1046 hash && |
1048 hash && |
1050 // disabling this (pull-skip-hashing) |
1052 // disabling this (pull-skip-hashing) |
1051 char *local_hash = util_file_hash(local_path); |
1053 char *local_hash = util_file_hash(local_path); |
1052 if(local_hash) { |
1054 if(local_hash) { |
1053 if(!strcmp(hash, local_hash)) { |
1055 if(!strcmp(hash, local_hash)) { |
1054 ret = REMOTE_NO_CHANGE; |
1056 ret = REMOTE_NO_CHANGE; |
1055 } |
1057 update_db = TRUE; |
1056 } |
1058 update_hash = local_hash; |
1057 free(local_hash); |
1059 |
|
1060 // if local already exists, update the hash here |
|
1061 // because it is possible that there are metadata updates |
|
1062 // and in this case the db will updated later and needs |
|
1063 // the current hash |
|
1064 if(local) { |
|
1065 if(local->hash) { |
|
1066 free(local->hash); |
|
1067 } |
|
1068 local->hash = local_hash; |
|
1069 } |
|
1070 } else { |
|
1071 free(local_hash); |
|
1072 } |
|
1073 } |
1058 } |
1074 } |
1059 |
1075 |
1060 // if a file is not modified, check if the metadata has changed |
1076 // if a file is not modified, check if the metadata has changed |
1061 while(ret == REMOTE_NO_CHANGE && local) { |
1077 while(ret == REMOTE_NO_CHANGE && local) { |
1062 // check if tags have changed |
1078 // check if tags have changed |
1102 } |
1118 } |
1103 |
1119 |
1104 break; |
1120 break; |
1105 } |
1121 } |
1106 |
1122 |
|
1123 // if update_db is set, a file was modified on the server, but we already |
|
1124 // have the file content, but we need to update the db |
|
1125 if(ret == REMOTE_NO_CHANGE && update_db) { |
|
1126 if(!local) { |
|
1127 local = calloc(1, sizeof(LocalResource)); |
|
1128 local->path = strdup(res->path); |
|
1129 |
|
1130 ucx_map_cstr_put(db->resources, local->path, local); |
|
1131 } |
|
1132 |
|
1133 // update local res |
|
1134 SYS_STAT s; |
|
1135 if(!sys_stat(local_path, &s)) { |
|
1136 sync_set_metadata_from_stat(local, &s); |
|
1137 } else { |
|
1138 fprintf(stderr, "stat failed for file: %s : %s", local_path, strerror(errno)); |
|
1139 } |
|
1140 local_resource_set_etag(local, etag); |
|
1141 if(!local->hash) { |
|
1142 local->hash = update_hash; |
|
1143 } // else: hash already updated |
|
1144 } |
|
1145 |
1107 free(local_path); |
1146 free(local_path); |
1108 return ret; |
1147 return ret; |
1109 } |
1148 } |
1110 |
1149 |
1111 void sync_set_metadata_from_stat(LocalResource *local, SYS_STAT *s) { |
1150 void sync_set_metadata_from_stat(LocalResource *local, SYS_STAT *s) { |
2149 sync_error++; |
2188 sync_error++; |
2150 } else { |
2189 } else { |
2151 DavBool equal = FALSE; |
2190 DavBool equal = FALSE; |
2152 int changed = remote_resource_is_changed(sn, dir, db, res, local_res, &equal); |
2191 int changed = remote_resource_is_changed(sn, dir, db, res, local_res, &equal); |
2153 if(equal) { |
2192 if(equal) { |
|
2193 char *etag = dav_get_string_property(res, "D:getetag"); |
2154 if(local_res->metadata_updated) { |
2194 if(local_res->metadata_updated) { |
2155 ls_update = ucx_list_prepend(ls_update, local_res); |
2195 ls_update = ucx_list_prepend(ls_update, local_res); |
|
2196 } else if(etag) { |
|
2197 // update etag in db |
|
2198 if(local_res->etag) { |
|
2199 free(local_res->etag); |
|
2200 } |
|
2201 local_res->etag = strdup(etag); |
2156 } |
2202 } |
2157 } else if(cdt && changed) { |
2203 } else if(cdt && changed) { |
2158 printf("conflict: %s\n", local_res->path); |
2204 printf("conflict: %s\n", local_res->path); |
2159 local_res->last_modified = 0; |
2205 local_res->last_modified = 0; |
2160 nullfree(local_res->etag); |
2206 nullfree(local_res->etag); |
2864 db_res->size == res->size && |
2907 db_res->size == res->size && |
2865 db_res->isdirectory == res->isdirectory) |
2908 db_res->isdirectory == res->isdirectory) |
2866 { |
2909 { |
2867 // mtime and size unchanged, content also likely unchanged |
2910 // mtime and size unchanged, content also likely unchanged |
2868 return 0; |
2911 return 0; |
2869 } else if(SYNC_HASHING(dir) && db_res->hash) { |
2912 } else if(SYNC_HASHING(dir)) { |
2870 // in case of activated hashing, we check if the content |
|
2871 // has really changed |
|
2872 |
|
2873 // res->hash missing (see above) |
2913 // res->hash missing (see above) |
2874 char *local_path = util_concat_path(dir->path, local_resource_path(res)); |
2914 char *local_path = util_concat_path(dir->path, local_resource_path(res)); |
2875 res->hash = util_file_hash(local_path); |
2915 res->hash = util_file_hash(local_path); |
2876 free(local_path); |
2916 free(local_path); |
2877 if(res->hash && !strcmp(res->hash, db_res->hash)) { |
2917 |
|
2918 // check if the content has really changed |
|
2919 if(res->hash && db_res->hash && !strcmp(res->hash, db_res->hash)) { |
2878 return 0; |
2920 return 0; |
2879 } |
2921 } |
2880 } |
2922 } |
2881 } |
2923 } |
2882 } else { |
2924 } else { |