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; |
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; |
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); |