dav/sync.c

changeset 552
e1a12762bf0a
parent 551
99ef8202cd82
child 553
891823d8dd7b
equal deleted inserted replaced
551:99ef8202cd82 552:e1a12762bf0a
1593 char *hash = util_file_hash(local_path); 1593 char *hash = util_file_hash(local_path);
1594 local->hash = hash; 1594 local->hash = hash;
1595 // check if a file with this hash already exists 1595 // check if a file with this hash already exists
1596 LocalResource *origin = ucx_map_cstr_get(db_hashes, hash); 1596 LocalResource *origin = ucx_map_cstr_get(db_hashes, hash);
1597 if(origin) { 1597 if(origin) {
1598 local->origin = strdup(origin->path); 1598 local->origin = local_resource_copy(origin, origin->path);
1599 // the file is a copied/moved file 1599 // the file is a copied/moved file
1600 // check if the file is in the resources_map, because then 1600 // check if the file is in the resources_map, because then
1601 // it still exists 1601 // it still exists
1602 if(ucx_map_cstr_get(resources_map, origin->path)) { 1602 if(ucx_map_cstr_get(resources_map, origin->path)) {
1603 ls_copy = ucx_list_append(ls_copy, local); 1603 ls_copy = ucx_list_append(ls_copy, local);
1730 } 1730 }
1731 1731
1732 DavBool copy = TRUE; 1732 DavBool copy = TRUE;
1733 for(UcxList *elm=ls_copy;elm && !sync_shutdown;elm=elm->next) { 1733 for(UcxList *elm=ls_copy;elm && !sync_shutdown;elm=elm->next) {
1734 LocalResource *local = elm->data; 1734 LocalResource *local = elm->data;
1735 DavResource *res = dav_resource_new(sn, local->origin); 1735
1736 int err = 0; 1736 int err = 0;
1737 if(copy) { 1737 DavResource *res = dav_resource_new(sn, local->path);
1738 printf("copy: %s -> %s\n", local->origin, local->path); 1738 if(dav_exists(res)) {
1739 err = dav_copy_o(res, local->path, FALSE); 1739 printf("conflict: %s\n", local->path);
1740 1740 sync_skipped++;
1741 if(!elm->next) {
1742 // finished copy, begin move
1743 elm->next = ls_move;
1744 copy = FALSE;
1745 }
1746 } else { 1741 } else {
1747 printf("move: %s -> %s\n", local->origin, local->path); 1742 DavResource *origin_res = dav_resource_new(sn, local->origin->path);
1748 err = dav_move_o(res, local->path, FALSE); 1743 int origin_changed = remote_resource_is_changed(
1744 sn,
1745 dir,
1746 db,
1747 origin_res,
1748 local->origin);
1749 if(origin_changed) {
1750 // upload with put
1751 printf("put: %s\n", local->path);
1752 err = sync_put_resource(dir, res, local, &sync_success);
1753 } else {
1754 printf("%s: %s -> %s\n", copy ? "copy":"move", local->origin->path, local->path);
1755 err = sync_move_remote_resource(
1756 dir,
1757 origin_res,
1758 local,
1759 copy,
1760 &sync_success);
1761 }
1749 } 1762 }
1750 1763
1751 if(err) { 1764 if(err) {
1752 if(sn->error == DAV_PRECONDITION_FAILED) { 1765 sync_error++;
1753 printf("conflict: %s\n", local->path); 1766 print_resource_error(sn, res->path);
1754 local->last_modified = 0; 1767 ret = -1;
1755 local->skipped = TRUE; 1768 error = 1;
1756 sync_skipped++; 1769 }
1757 } else { 1770
1758 sync_error++;
1759 print_resource_error(sn, res->path);
1760 ret = -1;
1761 error = 1;
1762 }
1763 }
1764
1765 dav_resource_free(res);
1766 LocalResource *dbres = ucx_map_cstr_remove(db->resources, local->path); 1771 LocalResource *dbres = ucx_map_cstr_remove(db->resources, local->path);
1767 ucx_map_cstr_put(db->resources, local->path, local); 1772 ucx_map_cstr_put(db->resources, local->path, local);
1773
1774 if(copy && !elm->next) {
1775 // finished copy, begin move
1776 elm->next = ls_move;
1777 copy = FALSE;
1778 }
1768 } 1779 }
1769 1780
1770 // metadata updates 1781 // metadata updates
1771 for(UcxList *elm=ls_update;elm && !sync_shutdown;elm=elm->next) { 1782 for(UcxList *elm=ls_update;elm && !sync_shutdown;elm=elm->next) {
1772 LocalResource *local_res = elm->data; 1783 LocalResource *local_res = elm->data;
2224 res->uid = s.st_uid; 2235 res->uid = s.st_uid;
2225 res->gid = s.st_gid; 2236 res->gid = s.st_gid;
2226 res->isdirectory = 1; 2237 res->isdirectory = 1;
2227 return res; 2238 return res;
2228 } 2239 }
2229 }
2230
2231 LocalResource* local_resource_copy(LocalResource *res) {
2232 LocalResource *newres = calloc(1, sizeof(LocalResource));
2233 if(res->name) {
2234 newres->name = strdup(res->name);
2235 }
2236 if(res->path) {
2237 newres->path = strdup(res->path);
2238 }
2239 if(res->etag) {
2240 newres->etag = strdup(res->etag);
2241 }
2242 newres->skipped = res->skipped;
2243 newres->size = res->size;
2244 newres->last_modified = res->last_modified;
2245 newres->isdirectory = res->isdirectory;
2246 if(res->tags_hash) {
2247 newres->tags_hash = strdup(res->tags_hash);
2248 }
2249 newres->tags_updated = res->tags_updated;
2250 return newres;
2251 } 2240 }
2252 2241
2253 int local_resource_is_changed( 2242 int local_resource_is_changed(
2254 SyncDirectory *dir, 2243 SyncDirectory *dir,
2255 SyncDatabase *db, 2244 SyncDatabase *db,
3404 break; 3393 break;
3405 } 3394 }
3406 return ret; 3395 return ret;
3407 } 3396 }
3408 3397
3398 int sync_move_remote_resource(
3399 SyncDirectory *dir,
3400 DavResource *origin,
3401 LocalResource *local,
3402 DavBool copy,
3403 int *counter)
3404 {
3405 char *local_path = create_local_path(dir, local->path);
3406
3407 SYS_STAT s;
3408 if(sys_stat(local_path, &s)) {
3409 fprintf(stderr, "Cannot stat file: %s\n", local_path);
3410 perror("");
3411 free(local_path);
3412 return -1;
3413 }
3414 free(local_path);
3415
3416 int result = 0;
3417 if(copy) {
3418 result = dav_copy_o(origin, local->path, FALSE);
3419 } else {
3420 result = dav_move_o(origin, local->path, FALSE);
3421 }
3422
3423 if(result != 0) {
3424 return result;
3425 }
3426
3427 // replace LocalResource with origin content
3428 LocalResource *local_origin = local->origin;
3429 local->origin = NULL;
3430 char *path = strdup(local->path);
3431 // TODO: free stuff before replacing it
3432 memcpy(local, local_origin, sizeof(LocalResource));
3433 local->path = path;
3434
3435 free(local_origin); // only free origin pointer
3436
3437 // get new etag
3438 DavResource *up_res = dav_get(origin->session, origin->path, "D:getetag");
3439 if(up_res) {
3440 (*counter)++;
3441
3442 // everything seems fine, we can update the local resource
3443 char *etag = dav_get_string_property(up_res, "D:getetag");
3444 if(etag) {
3445 if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') {
3446 etag = etag + 2;
3447 }
3448 }
3449
3450 if(local->etag) {
3451 free(local->etag);
3452 }
3453
3454 if(etag) {
3455 local->etag = strdup(etag);
3456 } else {
3457 local->etag = NULL;
3458 }
3459
3460 local->last_modified = s.st_mtime;
3461
3462 dav_resource_free(up_res);
3463 } else {
3464 result = 1;
3465 }
3466
3467 return result;
3468 }
3469
3409 int sync_delete_remote_resource( 3470 int sync_delete_remote_resource(
3410 SyncDirectory *dir, 3471 SyncDirectory *dir,
3411 DavSession *sn, 3472 DavSession *sn,
3412 LocalResource *local_res, 3473 LocalResource *local_res,
3413 int *counter, 3474 int *counter,
3438 if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') { 3499 if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') {
3439 etag = etag + 2; 3500 etag = etag + 2;
3440 } 3501 }
3441 } 3502 }
3442 3503
3443 if(etag && !strcmp(etag, local_res->etag)) { 3504 if(nullstrcmp(etag, local_res->etag)) {
3444 // local resource metadata == remote resource metadata 3505 // local resource metadata == remote resource metadata
3445 // resource can be deleted 3506 // resource can be deleted
3446 printf("delete: %s\n", res->path); 3507 printf("delete: %s\n", res->path);
3447 3508
3448 if(dir->versioning && dir->versioning->always) { 3509 if(dir->versioning && dir->versioning->always) {

mercurial