837 rename_conflict_file(dir, db, res->path, issplit); |
837 rename_conflict_file(dir, db, res->path, issplit); |
838 sync_conflict++; |
838 sync_conflict++; |
839 } |
839 } |
840 |
840 |
841 // download the resource |
841 // download the resource |
842 if(sync_get_resource(a, dir, res->path, res, db, &sync_success)) { |
842 if(sync_get_resource(a, dir, res->path, res, db, TRUE, &sync_success)) { |
843 fprintf(stderr, "resource download failed: %s\n", res->path); |
843 fprintf(stderr, "resource download failed: %s\n", res->path); |
844 sync_error++; |
844 sync_error++; |
845 } |
845 } |
846 } |
846 } |
847 |
847 |
1486 free(tmp_path); |
1487 free(tmp_path); |
1487 free(local_path); |
1488 free(local_path); |
1488 return -1; |
1489 return -1; |
1489 } |
1490 } |
1490 } |
1491 } |
1491 |
1492 |
|
1493 } else if(tmp_path) { |
|
1494 if(sys_unlink(tmp_path)) { |
|
1495 fprintf(stderr, "Cannot remove tmp file: %s\n", tmp_path); |
|
1496 } |
|
1497 } |
|
1498 |
|
1499 if(update_db && ret == 0) { |
1492 if(!local) { |
1500 if(!local) { |
1493 // new local resource |
1501 // new local resource |
1494 local = calloc(1, sizeof(LocalResource)); |
1502 local = calloc(1, sizeof(LocalResource)); |
1495 local->path = strdup(path); |
1503 local->path = strdup(path); |
1496 ucx_map_cstr_put(db->resources, local->path, local); |
1504 ucx_map_cstr_put(db->resources, local->path, local); |
1533 if(content_hash) { |
1541 if(content_hash) { |
1534 local->hash = content_hash; |
1542 local->hash = content_hash; |
1535 } |
1543 } |
1536 sync_set_metadata_from_stat(local, &s); |
1544 sync_set_metadata_from_stat(local, &s); |
1537 local->skipped = FALSE; |
1545 local->skipped = FALSE; |
1538 } else if(tmp_path) { |
|
1539 if(sys_unlink(tmp_path)) { |
|
1540 fprintf(stderr, "Cannot remove tmp file: %s\n", tmp_path); |
|
1541 } |
|
1542 } |
1546 } |
1543 |
1547 |
1544 if(tmp_path) { |
1548 if(tmp_path) { |
1545 free(tmp_path); |
1549 free(tmp_path); |
1546 } |
1550 } |
2504 fprintf(stderr, "Resource %s broken\n", res->path); |
2508 fprintf(stderr, "Resource %s broken\n", res->path); |
2505 continue; |
2509 continue; |
2506 } |
2510 } |
2507 |
2511 |
2508 DavResource *vres = NULL; |
2512 DavResource *vres = NULL; |
|
2513 DavBool update_local_entry = TRUE; |
2509 if(version) { |
2514 if(version) { |
2510 if(dir->versioning->type == VERSIONING_SIMPLE) { |
2515 if(dir->versioning->type == VERSIONING_SIMPLE) { |
2511 vres = versioning_simple_find(res, version); |
2516 vres = versioning_simple_find(res, version); |
2512 } else if(dir->versioning->type == VERSIONING_DELTAV) { |
2517 } else if(dir->versioning->type == VERSIONING_DELTAV) { |
2513 vres = versioning_deltav_find(res, version); |
2518 vres = versioning_deltav_find(res, version); |
2515 if(!vres) { |
2520 if(!vres) { |
2516 fprintf(stderr, "Cannot find specified version for resource %s\n", res->path); |
2521 fprintf(stderr, "Cannot find specified version for resource %s\n", res->path); |
2517 ret = 1; |
2522 ret = 1; |
2518 break; |
2523 break; |
2519 } |
2524 } |
|
2525 |
|
2526 // By restoring an old version of a file, the local dir is not |
|
2527 // in sync with the server anymore. Mark this file to change |
|
2528 // the metadata later, to make sure, the file will be detected |
|
2529 // as locally modified, on the next push/pull |
|
2530 update_local_entry = FALSE; |
2520 } else { |
2531 } else { |
2521 vres = res; |
2532 vres = res; |
2522 } |
2533 } |
2523 |
2534 |
2524 // download the resource |
2535 // download the resource |
2530 "Cannot create directory %s: %s", |
2541 "Cannot create directory %s: %s", |
2531 local_path, strerror(errno)); |
2542 local_path, strerror(errno)); |
2532 } |
2543 } |
2533 free(local_path); |
2544 free(local_path); |
2534 } else { |
2545 } else { |
2535 if(sync_get_resource(a, dir, res->path, vres, db, &sync_success)) { |
2546 if(sync_get_resource(a, dir, res->path, vres, db, update_local_entry, &sync_success)) { |
2536 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); |
2547 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); |
2537 sync_error++; |
2548 sync_error++; |
|
2549 } else if(!update_local_entry) { |
|
2550 LocalResource *lr = ucx_map_cstr_get(db->resources, res->path); |
|
2551 if(lr) { |
|
2552 lr->last_modified = 0; |
|
2553 nullfree(lr->hash); |
|
2554 lr->hash = NULL; |
|
2555 } // else should not happen |
2538 } |
2556 } |
2539 } |
2557 } |
2540 } |
2558 } |
2541 } |
2559 } |
2542 |
2560 |
3671 } else { |
3689 } else { |
3672 return 0; |
3690 return 0; |
3673 } |
3691 } |
3674 } |
3692 } |
3675 |
3693 |
3676 int versioning_delete(SyncDirectory *dir, DavResource *res) { |
3694 int versioning_delete_begin(SyncDirectory *dir, DavResource *res, int *exists) { |
3677 if(dir->versioning->type == VERSIONING_SIMPLE) { |
3695 if(dir->versioning->type == VERSIONING_SIMPLE) { |
3678 // TODO |
3696 versioning_begin(dir, res, exists); |
3679 } |
3697 } else { |
|
3698 // versioning delete with DeltaV currently not supported in dav-sync |
|
3699 *exists = 1; |
|
3700 } |
|
3701 return 0; |
|
3702 } |
|
3703 |
|
3704 int versioning_delete_end(SyncDirectory *dir, DavResource *res) { |
3680 return 0; |
3705 return 0; |
3681 } |
3706 } |
3682 |
3707 |
3683 static void update_metadata_hashes(LocalResource *local, MetadataHashes hashes) { |
3708 static void update_metadata_hashes(LocalResource *local, MetadataHashes hashes) { |
3684 if(hashes.update_tags) { |
3709 if(hashes.update_tags) { |
4211 |
4236 |
4212 if(!nullstrcmp(etag, local_res->etag)) { |
4237 if(!nullstrcmp(etag, local_res->etag)) { |
4213 // local resource metadata == remote resource metadata |
4238 // local resource metadata == remote resource metadata |
4214 // resource can be deleted |
4239 // resource can be deleted |
4215 printf("delete: %s\n", res->path); |
4240 printf("delete: %s\n", res->path); |
4216 |
4241 int exists = 1; |
|
4242 int vend_required = 0; |
4217 if(dir->versioning && dir->versioning->always) { |
4243 if(dir->versioning && dir->versioning->always) { |
4218 if(versioning_delete(dir, res)) { |
4244 if(versioning_delete_begin(dir, res, &exists)) { |
4219 fprintf( |
4245 fprintf( |
4220 stderr, |
4246 stderr, |
4221 "Cannot save resource version before deletion\n"); |
4247 "Cannot save resource version before deletion\n"); |
4222 ret = 1; |
4248 ret = 1; |
|
4249 } else { |
|
4250 vend_required = 1; |
4223 } |
4251 } |
4224 } |
4252 } |
4225 |
4253 |
4226 if(!ret && dav_delete(res)) { |
4254 if(!ret && dav_delete(res) && exists) { |
4227 if(sn->error != DAV_NOT_FOUND) { |
4255 if(sn->error != DAV_NOT_FOUND) { |
4228 fprintf(stderr, "Cannot delete resource %s\n", res->path); |
4256 fprintf(stderr, "Cannot delete resource %s\n", res->path); |
4229 ret = 1; |
4257 ret = 1; |
4230 } |
4258 } |
4231 } else { |
4259 } else { |
4232 (*counter)++; |
4260 (*counter)++; |
|
4261 } |
|
4262 |
|
4263 if(vend_required) { |
|
4264 versioning_delete_end(dir, res); |
4233 } |
4265 } |
4234 } |
4266 } |
4235 // else TODO: should we inform the user that the file was modified on |
4267 // else TODO: should we inform the user that the file was modified on |
4236 // the server and delete was skipped? |
4268 // the server and delete was skipped? |
4237 } |
4269 } |
5360 char *hex_hash = util_hexstr((unsigned char*)dec_hash, len); |
5392 char *hex_hash = util_hexstr((unsigned char*)dec_hash, len); |
5361 free(dec_hash); |
5393 free(dec_hash); |
5362 return hex_hash; |
5394 return hex_hash; |
5363 } |
5395 } |
5364 } else { |
5396 } else { |
5365 return dav_get_string_property_ns(res, DAV_NS, "content-hash"); |
5397 char *hash = dav_get_string_property_ns(res, DAV_NS, "content-hash"); |
|
5398 if(hash) { |
|
5399 return strdup(hash); |
|
5400 } |
5366 } |
5401 } |
5367 return NULL; |
5402 return NULL; |
5368 } |
5403 } |
5369 |
5404 |
5370 void sync_set_content_hash(DavResource *res, const unsigned char *hashdata) { |
5405 void sync_set_content_hash(DavResource *res, const unsigned char *hashdata) { |