dav/sync.c

changeset 550
8c700eae3eb8
parent 548
ab46acda1066
child 551
99ef8202cd82
equal deleted inserted replaced
549:af91d3c96994 550:8c700eae3eb8
1494 locktokenfile = create_locktoken_file(dir->name, lock->token); 1494 locktokenfile = create_locktoken_file(dir->name, lock->token);
1495 } 1495 }
1496 1496
1497 DavBool remove_file = cmd_getoption(a, "remove") ? 1 : 0; 1497 DavBool remove_file = cmd_getoption(a, "remove") ? 1 : 0;
1498 1498
1499 UcxMap *db_hashes = NULL;
1500 if(dir->hashing) {
1501 db_hashes = create_hash_index(db);
1502 }
1503
1499 int sync_success = 0; 1504 int sync_success = 0;
1500 int sync_delete = 0; 1505 int sync_delete = 0;
1501 int sync_skipped = 0; 1506 int sync_skipped = 0;
1502 int sync_error = 0; 1507 int sync_error = 0;
1503 1508
1504 UcxList *ls_put = NULL; 1509 UcxList *ls_new = NULL;
1510 UcxList *ls_modified = NULL;
1505 UcxList *ls_conflict = NULL; 1511 UcxList *ls_conflict = NULL;
1506 UcxList *ls_update = NULL; 1512 UcxList *ls_update = NULL;
1507 UcxList *ls_delete = NULL; 1513 UcxList *ls_delete = NULL;
1514 UcxList *ls_move = NULL;
1515 UcxList *ls_copy = NULL;
1508 1516
1509 // upload all changed files 1517 // upload all changed files
1510 //UcxList *resources = cmd_getoption(a, "read") ? 1518 //UcxList *resources = cmd_getoption(a, "read") ?
1511 // read_changes(dir, db) : local_scan(dir, db); 1519 // read_changes(dir, db) : local_scan(dir, db);
1512 UcxList *resources = local_scan(dir, db); 1520 UcxList *resources = local_scan(dir, db);
1526 if(!localres_matches_tags(dir, local_res, tf)) { 1534 if(!localres_matches_tags(dir, local_res, tf)) {
1527 continue; 1535 continue;
1528 } 1536 }
1529 } 1537 }
1530 1538
1531 // we need a fast file lookup map later 1539 // we need a fast file lookup map later to detect deleted files
1532 ucx_map_cstr_put(resources_map, local_res->path, local_res); 1540 ucx_map_cstr_put(resources_map, local_res->path, local_res);
1533 1541
1534 // dynamic tag filter 1542 // dynamic tag filter
1535 if(!localres_matches_tags(dir, local_res, tagfilter)) { 1543 if(!localres_matches_tags(dir, local_res, tagfilter)) {
1536 if(!remove_file) { 1544 if(!remove_file) {
1556 local_res, 1564 local_res,
1557 svrres, 1565 svrres,
1558 restore_removed, 1566 restore_removed,
1559 restore_modified); 1567 restore_modified);
1560 if(is_changed) { 1568 if(is_changed) {
1561 ls_put = ucx_list_append(ls_put, local_res); 1569 if(local_res->isnew) {
1570 ls_new = ucx_list_append(ls_new, local_res);
1571 } else {
1572 ls_modified = ucx_list_append(ls_modified, local_res);
1573 }
1562 } else if(local_res->metadata_updated) { 1574 } else if(local_res->metadata_updated) {
1563 ls_update = ucx_list_append(ls_update, local_res); 1575 ls_update = ucx_list_append(ls_update, local_res);
1576 }
1577 }
1578
1579 if(dir->hashing) {
1580 // calculate hashes of all new files and check if a file
1581 // was moved or is a copy
1582 UcxList *elm = ls_new;
1583 while(elm) {
1584 LocalResource *local = elm->data;
1585 UcxList *prev = elm->prev;
1586 UcxList *next = elm->next;
1587 char *local_path = util_concat_path(dir->path, local->path);
1588 char *hash = util_file_hash(local_path);
1589 // check if a file with this hash already exists
1590 LocalResource *origin = ucx_map_cstr_get(db_hashes, hash);
1591 if(origin) {
1592 local->origin = strdup(origin->path);
1593 // the file is a copied/moved file
1594 // check if the file is in the resources_map, because then
1595 // it still exists
1596 if(ucx_map_cstr_get(resources_map, origin->path)) {
1597 ls_copy = ucx_list_append(ls_copy, local);
1598 } else {
1599 ls_move = ucx_list_append(ls_move, local);
1600 // put file in resources_map to prevent deletion
1601 ucx_map_cstr_put(resources_map, origin->path, local);
1602 }
1603 // remove list elemend from ls_new
1604 if(prev) {
1605 prev->next = next;
1606 } else {
1607 ls_new = next;
1608 }
1609 if(next) {
1610 next->prev = prev;
1611 }
1612 }
1613
1614 free(hash);
1615 free(local_path);
1616
1617 elm = next;
1564 } 1618 }
1565 } 1619 }
1566 1620
1567 // find all deleted files and cleanup the database 1621 // find all deleted files and cleanup the database
1568 UcxMapIterator i = ucx_map_iterator(db->resources); 1622 UcxMapIterator i = ucx_map_iterator(db->resources);
1583 } 1637 }
1584 1638
1585 if(!ucx_map_get(resources_map, key)) { 1639 if(!ucx_map_get(resources_map, key)) {
1586 // The current LocalResource is in the database but doesn't exist 1640 // The current LocalResource is in the database but doesn't exist
1587 // in the filesystem anymore. This means the file was deleted 1641 // in the filesystem anymore. This means the file was deleted
1588 // and should be deleted on server 1642 // and should be deleted on the server
1589 if(!archive) { 1643 if(!archive) {
1590 ls_delete = ucx_list_append(ls_delete, local); 1644 ls_delete = ucx_list_append(ls_delete, local);
1591 } else { 1645 } else {
1592 removed_res = ucx_list_prepend(removed_res, local); 1646 removed_res = ucx_list_prepend(removed_res, local);
1593 } 1647 }
1603 // 1657 //
1604 // BEGIN PUSH 1658 // BEGIN PUSH
1605 // 1659 //
1606 1660
1607 // upload changed files 1661 // upload changed files
1662 ls_modified = ucx_list_concat(ls_new, ls_modified);
1663
1608 int ret = 0; 1664 int ret = 0;
1609 int error = 0; 1665 int error = 0;
1610 for(UcxList *elm=ls_put;elm && !sync_shutdown;elm=elm->next) { 1666 for(UcxList *elm=ls_modified;elm && !sync_shutdown;elm=elm->next) {
1611 LocalResource *local_res = elm->data; 1667 LocalResource *local_res = elm->data;
1612 1668
1613 DavResource *res = dav_resource_new(sn, local_res->path); 1669 DavResource *res = dav_resource_new(sn, local_res->path);
1614 if(!res) { 1670 if(!res) {
1615 print_resource_error(sn, local_res->path); 1671 print_resource_error(sn, local_res->path);
2252 } else { 2308 } else {
2253 res->tags_updated = 1; 2309 res->tags_updated = 1;
2254 res->finfo_updated = 1; 2310 res->finfo_updated = 1;
2255 res->xattr_updated = 1; 2311 res->xattr_updated = 1;
2256 res->metadata_updated = 1; 2312 res->metadata_updated = 1;
2313 res->isnew = 1;
2257 } 2314 }
2258 return 1; 2315 return 1;
2259 } 2316 }
2260 2317
2261 int remote_resource_is_changed( 2318 int remote_resource_is_changed(
3265 local->etag = strdup(etag); 3322 local->etag = strdup(etag);
3266 } else { 3323 } else {
3267 local->etag = NULL; 3324 local->etag = NULL;
3268 } 3325 }
3269 3326
3327 if(!issplit && dir->hashing) {
3328 if(local->hash) {
3329 free(local->hash);
3330 }
3331 // TODO: calculate hash on upload
3332 local->hash = util_file_hash(local_path);
3333 }
3334
3270 if(dav_get_string_property(up_res, "idav:status")) { 3335 if(dav_get_string_property(up_res, "idav:status")) {
3271 sync_remove_status(up_res); 3336 sync_remove_status(up_res);
3272 } 3337 }
3273 3338
3274 dav_resource_free(up_res); 3339 dav_resource_free(up_res);

mercurial