dav/sync.c

changeset 650
14e7101d7604
parent 649
0f4c59ac8c74
child 659
51206020cfbe
equal deleted inserted replaced
649:0f4c59ac8c74 650:14e7101d7604
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);
2253 2299
2254 // cleanup 2300 // cleanup
2255 if(!locked && locktokenfile) { 2301 if(!locked && locktokenfile) {
2256 remove(locktokenfile); 2302 remove(locktokenfile);
2257 } 2303 }
2258
2259 //ucx_map_free_content(db->resources, (ucx_destructor)local_resource_free);
2260 //ucx_map_free(db->resources);
2261 2304
2262 dav_session_destroy(sn); 2305 dav_session_destroy(sn);
2263 2306
2264 // Report 2307 // Report
2265 if(ret != -2) { 2308 if(ret != -2) {
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 {

mercurial