dav/sync.c

changeset 630
046b869a1c49
parent 629
bc2cdbf5e68f
child 633
b7de5ecc30fa
equal deleted inserted replaced
629:bc2cdbf5e68f 630:046b869a1c49
532 return -1; 532 return -1;
533 } 533 }
534 remove_deleted_conflicts(dir, db); 534 remove_deleted_conflicts(dir, db);
535 535
536 UcxMap *hashes = NULL; 536 UcxMap *hashes = NULL;
537 if(dir->hashing) { 537 if(SYNC_HASHING(dir)) {
538 hashes = create_hash_index(db); 538 hashes = create_hash_index(db);
539 } 539 }
540 540
541 DavSession *sn = create_session(ctx, repo, dir->collection); 541 DavSession *sn = create_session(ctx, repo, dir->collection);
542 ucx_mempool_reg_destr(sn->mp, db, (ucx_destructor)destroy_db); 542 ucx_mempool_reg_destr(sn->mp, db, (ucx_destructor)destroy_db);
740 UCX_FOREACH(elm, res_conflict) { 740 UCX_FOREACH(elm, res_conflict) {
741 DavResource *res = elm->data; 741 DavResource *res = elm->data;
742 ucx_map_cstr_put(conflicts, res->path, res); 742 ucx_map_cstr_put(conflicts, res->path, res);
743 } 743 }
744 744
745 if(dir->hashing) { 745 if(SYNC_HASHING(dir)) {
746 // check for moved/copied files 746 // check for moved/copied files
747 UcxList *elm = res_new; 747 UcxList *elm = res_new;
748 UcxList *prev = NULL; 748 UcxList *prev = NULL;
749 UcxList *next = NULL; 749 UcxList *next = NULL;
750 SYS_STAT s; 750 SYS_STAT s;
1389 perror("symlink"); 1389 perror("symlink");
1390 ret = 1; 1390 ret = 1;
1391 } 1391 }
1392 } 1392 }
1393 1393
1394 if((issplit || dir->hashing) && !link) { 1394 if(issplit || (SYNC_HASHING(dir) && !link)) {
1395 if(truncate_file >= 0) { 1395 if(truncate_file >= 0) {
1396 // only true if issplit is true 1396 // only true if issplit is true
1397 if(truncate(local_path, truncate_file)) { 1397 if(truncate(local_path, truncate_file)) {
1398 perror("truncate"); 1398 perror("truncate");
1399 } 1399 }
1771 ucx_mempool_reg_destr(sn->mp, db, (ucx_destructor)destroy_db); 1771 ucx_mempool_reg_destr(sn->mp, db, (ucx_destructor)destroy_db);
1772 if (cmd_getoption(a, "verbose")) { 1772 if (cmd_getoption(a, "verbose")) {
1773 curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L); 1773 curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L);
1774 curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr); 1774 curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr);
1775 } 1775 }
1776 if(dir->hashing) { 1776 if(SYNC_STORE_HASH(dir)) {
1777 sn->flags |= DAV_SESSION_STORE_HASH; 1777 sn->flags |= DAV_SESSION_STORE_HASH;
1778 } 1778 }
1779 1779
1780 DavBool restore_removed = cmd_getoption(a, "restore-removed") ? 1 : 0; 1780 DavBool restore_removed = cmd_getoption(a, "restore-removed") ? 1 : 0;
1781 DavBool restore_modified = cmd_getoption(a, "restore-modified") ? 1 : 0; 1781 DavBool restore_modified = cmd_getoption(a, "restore-modified") ? 1 : 0;
1817 } 1817 }
1818 1818
1819 DavBool remove_file = cmd_getoption(a, "remove") ? 1 : 0; 1819 DavBool remove_file = cmd_getoption(a, "remove") ? 1 : 0;
1820 1820
1821 UcxMap *db_hashes = NULL; 1821 UcxMap *db_hashes = NULL;
1822 if(dir->hashing) { 1822 if(SYNC_HASHING(dir)) {
1823 db_hashes = create_hash_index(db); 1823 db_hashes = create_hash_index(db);
1824 } 1824 }
1825 1825
1826 int sync_success = 0; 1826 int sync_success = 0;
1827 int sync_delete = 0; 1827 int sync_delete = 0;
1909 local_resource_path(local_res)); 1909 local_resource_path(local_res));
1910 } 1910 }
1911 } 1911 }
1912 } 1912 }
1913 1913
1914 if(dir->hashing) { 1914 if(SYNC_STORE_HASH(dir)) {
1915 // calculate hashes of all new files and check if a file 1915 // calculate hashes of all new files and check if a file
1916 // was moved or is a copy 1916 // was moved or is a copy
1917 UcxList *elm = ls_new; 1917 UcxList *elm = ls_new;
1918 while(elm) { 1918 while(elm) {
1919 LocalResource *local = elm->data; 1919 LocalResource *local = elm->data;
2727 return 1; 2727 return 1;
2728 } 2728 }
2729 } 2729 }
2730 } 2730 }
2731 2731
2732 // copy some metadata from db_res, that localscan does not deliver
2732 res->tags_updated = db_res->tags_updated; 2733 res->tags_updated = db_res->tags_updated;
2733 if(db_res->etag) { 2734 if(db_res->etag) {
2734 res->etag = strdup(db_res->etag); 2735 res->etag = strdup(db_res->etag);
2735 } 2736 }
2736 if(db_res->tags_hash) { 2737 if(db_res->tags_hash) {
2741 } 2742 }
2742 if(db_res->xattr_hash) { 2743 if(db_res->xattr_hash) {
2743 res->xattr_hash = strdup(db_res->xattr_hash); 2744 res->xattr_hash = strdup(db_res->xattr_hash);
2744 } 2745 }
2745 2746
2747 // if the resource is splitted, move the part infos to the new
2748 // LocalResource obj, because we need it later
2749 if(db_res->parts) {
2750 res->parts = db_res->parts;
2751 res->numparts = db_res->numparts;
2752 db_res->parts = NULL;
2753 db_res->numparts = 0;
2754 }
2755
2756 // check if metadata has changed
2757 // metadata are tags, mode, owner, xattr
2758 // set res->metadata_updated to 1 in case any metadata has changed
2759
2760 // check if tags have changed
2746 if(dir->tagconfig && dir->tagconfig->detect_changes && !res->tags_updated) { 2761 if(dir->tagconfig && dir->tagconfig->detect_changes && !res->tags_updated) {
2747 UcxBuffer *tags = sync_get_file_tag_data(dir, res); 2762 UcxBuffer *tags = sync_get_file_tag_data(dir, res);
2748 if(tags) { 2763 if(tags) {
2749 if(db_res->tags_hash) { 2764 if(db_res->tags_hash) {
2750 char *hash = dav_create_hash(tags->space, tags->size); 2765 char *hash = dav_create_hash(tags->space, tags->size);
2759 res->tags_updated = 1; // tags removed 2774 res->tags_updated = 1; // tags removed
2760 } 2775 }
2761 res->metadata_updated = res->tags_updated; 2776 res->metadata_updated = res->tags_updated;
2762 } 2777 }
2763 2778
2779 // check if mode has changed
2764 if((dir->metadata & FINFO_MODE) == FINFO_MODE) { 2780 if((dir->metadata & FINFO_MODE) == FINFO_MODE) {
2765 if(db_res->mode != res->mode) { 2781 if(db_res->mode != res->mode) {
2766 res->finfo_updated = 1; 2782 res->finfo_updated = 1;
2767 res->metadata_updated = 1; 2783 res->metadata_updated = 1;
2768 } 2784 }
2769 } 2785 }
2786 // check if owner has changed
2770 if((dir->metadata & FINFO_OWNER) == FINFO_OWNER) { 2787 if((dir->metadata & FINFO_OWNER) == FINFO_OWNER) {
2771 if(db_res->uid != res->uid || db_res->gid != res->gid) { 2788 if(db_res->uid != res->uid || db_res->gid != res->gid) {
2772 res->finfo_updated = 1; 2789 res->finfo_updated = 1;
2773 res->metadata_updated = 1; 2790 res->metadata_updated = 1;
2774 } 2791 }
2775 } 2792 }
2776 2793
2794 // check if xattr have changed
2777 if((dir->metadata & FINFO_XATTR) == FINFO_XATTR) { 2795 if((dir->metadata & FINFO_XATTR) == FINFO_XATTR) {
2778 char *path = create_local_path(dir, local_resource_path(db_res)); 2796 char *path = create_local_path(dir, local_resource_path(db_res));
2779 XAttributes *xattr = file_get_attributes(path, (xattr_filter_func)xattr_filter, dir); 2797 XAttributes *xattr = file_get_attributes(path, (xattr_filter_func)xattr_filter, dir);
2780 // test if xattr are added, removed or changed 2798 // test if xattr are added, removed or changed
2781 if((db_res->xattr_hash && !xattr) || 2799 if((db_res->xattr_hash && !xattr) ||
2788 } else if(xattr) { 2806 } else if(xattr) {
2789 xattributes_free(xattr); 2807 xattributes_free(xattr);
2790 } 2808 }
2791 } 2809 }
2792 2810
2811 // check if the content of the file was modified
2812 // in case of links, just check if the link target has changed
2813 // for normal files, check last modified and size
2814 // or compare content hashes
2793 if(nullstrcmp(db_res->link_target, res->link_target)) { 2815 if(nullstrcmp(db_res->link_target, res->link_target)) {
2794 res->link_updated = 1; 2816 res->link_updated = 1;
2795 } else if( 2817 } else {
2818 if(db_res->hash && res->hash) {
2819 // we already have hashes
2820 if(!strcmp(db_res->hash, res->hash)) {
2821 return 0; // hashes equal -> file content unchanged
2822 }
2823 } else if(
2796 db_res->last_modified == res->last_modified && 2824 db_res->last_modified == res->last_modified &&
2797 db_res->size == res->size && 2825 db_res->size == res->size &&
2798 db_res->isdirectory == res->isdirectory) 2826 db_res->isdirectory == res->isdirectory)
2799 { 2827 {
2800 return 0; 2828 // mtime and size unchanged, content also likely unchanged
2801 } 2829 return 0;
2802 2830 } else if(SYNC_HASHING(dir) && db_res->hash) {
2803 if(db_res->parts) { 2831 // in case of activated hashing, we check if the content
2804 // if the resource is splitted, move the part infos to the new 2832 // has really changed
2805 // LocalResource obj, because we need it later 2833
2806 res->parts = db_res->parts; 2834 // res->hash missing (see above)
2807 res->numparts = db_res->numparts; 2835 char *local_path = util_concat_path(dir->path, local_resource_path(res));
2808 db_res->parts = NULL; 2836 res->hash = util_file_hash(local_path);
2809 db_res->numparts = 0; 2837 free(local_path);
2838 if(res->hash && !strcmp(res->hash, db_res->hash)) {
2839 return 0;
2840 }
2841 }
2810 } 2842 }
2811 } else { 2843 } else {
2812 res->tags_updated = 1; 2844 res->tags_updated = 1;
2813 res->finfo_updated = 1; 2845 res->finfo_updated = 1;
2814 res->xattr_updated = 1; 2846 res->xattr_updated = 1;
3875 } else { 3907 } else {
3876 // everything seems fine, we can update the local resource 3908 // everything seems fine, we can update the local resource
3877 char *etag = dav_get_string_property(up_res, "D:getetag"); 3909 char *etag = dav_get_string_property(up_res, "D:getetag");
3878 local_resource_set_etag(local, etag); 3910 local_resource_set_etag(local, etag);
3879 3911
3880 if(!issplit && dir->hashing) { 3912 if(!issplit && SYNC_STORE_HASH(dir)) {
3881 if(local->hash) { 3913 if(local->hash) {
3882 free(local->hash); 3914 free(local->hash);
3883 } 3915 }
3884 // TODO: calculate hash on upload 3916 // TODO: calculate hash on upload
3885 local->hash = util_file_hash(local_path); 3917 local->hash = util_file_hash(local_path);

mercurial