dav/sync.c

changeset 783
36a7f2ea7d12
parent 782
3cfe65695a8c
child 784
592ff4ca2aaa
equal deleted inserted replaced
782:3cfe65695a8c 783:36a7f2ea7d12
115 fprintf(synclog, "%s", str.ptr); 115 fprintf(synclog, "%s", str.ptr);
116 } 116 }
117 free(str.ptr); 117 free(str.ptr);
118 118
119 va_end(ap); 119 va_end(ap);
120 }
121
122 void log_resource_error(DavSession *sn, const char *path) {
123 print_resource_error(sn, path);
124 if(synclog) {
125 print_resource_error_to_file(synclog, sn, path);
126 }
120 } 127 }
121 128
122 129
123 int logfile_open(SyncDirectory *dir) { 130 int logfile_open(SyncDirectory *dir) {
124 int ret = 0; 131 int ret = 0;
702 DavBool locked = FALSE; 709 DavBool locked = FALSE;
703 DavResource *root = dav_resource_new(sn, "/"); 710 DavResource *root = dav_resource_new(sn, "/");
704 root->iscollection = TRUE; 711 root->iscollection = TRUE;
705 if((dir->lockpush || cmd_getoption(a, "lock")) && !cmd_getoption(a, "nolock")) { 712 if((dir->lockpush || cmd_getoption(a, "lock")) && !cmd_getoption(a, "nolock")) {
706 if(dav_lock_t(root, dir->lock_timeout)) { 713 if(dav_lock_t(root, dir->lock_timeout)) {
707 print_resource_error(sn, "/"); 714 log_resource_error(sn, "/");
708 dav_session_destroy(sn); 715 dav_session_destroy(sn);
709 fprintf(stderr, "Abort\n"); 716 log_error("Abort\n");
710 return -1; 717 return -1;
711 } 718 }
712 DavLock *lock = dav_get_lock(sn, "/"); 719 DavLock *lock = dav_get_lock(sn, "/");
713 if(lock) { 720 if(lock) {
714 log_printf("Lock-Token: %s\n", lock->token); 721 log_printf("Lock-Token: %s\n", lock->token);
718 } 725 }
719 726
720 int ret = 0; 727 int ret = 0;
721 DavResource *ls = dav_query(sn, "select D:getetag,idav:split,idav:status,`idav:content-hash`,idavprops:tags,idavprops:finfo,idavprops:xattributes,idavprops:link from / with depth = infinity"); 728 DavResource *ls = dav_query(sn, "select D:getetag,idav:split,idav:status,`idav:content-hash`,idavprops:tags,idavprops:finfo,idavprops:xattributes,idavprops:link from / with depth = infinity");
722 if(!ls) { 729 if(!ls) {
723 print_resource_error(sn, "/"); 730 log_resource_error(sn, "/");
724 if(locked) { 731 if(locked) {
725 if(dav_unlock(root)) { 732 if(dav_unlock(root)) {
726 print_resource_error(sn, "/"); 733 log_resource_error(sn, "/");
727 } else { 734 } else {
728 locked = FALSE; 735 locked = FALSE;
729 } 736 }
730 } 737 }
731 738
732 fprintf(stderr, "Abort\n"); 739 log_error("Abort\n");
733 740
734 dav_session_destroy(sn); 741 dav_session_destroy(sn);
735 // TODO: free 742 // TODO: free
736 return -1; 743 return -1;
737 } 744 }
738 if(!ls->iscollection) { 745 if(!ls->iscollection) {
739 fprintf(stderr, "%s is not a collection.\nAbort.\n", ls->path); 746 fprintf(stderr, "%s is not a collection.\nAbort.\n", ls->path);
740 if(locked) { 747 if(locked) {
741 if(dav_unlock(root)) { 748 if(dav_unlock(root)) {
742 print_resource_error(sn, "/"); 749 log_resource_error(sn, "/");
743 } else { 750 } else {
744 locked = FALSE; 751 locked = FALSE;
745 } 752 }
746 } 753 }
747 // TODO: free 754 // TODO: free
1059 } 1066 }
1060 1067
1061 // unlock repository 1068 // unlock repository
1062 if(locked) { 1069 if(locked) {
1063 if(dav_unlock(root)) { 1070 if(dav_unlock(root)) {
1064 print_resource_error(sn, "/"); 1071 log_resource_error(sn, "/");
1065 ret = -1; 1072 ret = -1;
1066 } else { 1073 } else {
1067 locked = FALSE; 1074 locked = FALSE;
1068 } 1075 }
1069 } 1076 }
2039 DavBool restore = restore_removed || restore_modified; 2046 DavBool restore = restore_removed || restore_modified;
2040 int depth = restore ? -1 : 0; 2047 int depth = restore ? -1 : 0;
2041 2048
2042 DavResource *root = dav_query(sn, "select D:getetag,idav:status from / with depth = %d", depth); 2049 DavResource *root = dav_query(sn, "select D:getetag,idav:status from / with depth = %d", depth);
2043 if(!root) { 2050 if(!root) {
2044 print_resource_error(sn, "/"); 2051 log_resource_error(sn, "/");
2045 dav_session_destroy(sn); 2052 dav_session_destroy(sn);
2046 fprintf(stderr, "Abort\n"); 2053 log_error("Abort\n");
2047 return -1; 2054 return -1;
2048 } 2055 }
2049 2056
2050 CxMap *svrres = NULL; 2057 CxMap *svrres = NULL;
2051 if(restore) { 2058 if(restore) {
2058 // lock repository 2065 // lock repository
2059 DavBool locked = FALSE; 2066 DavBool locked = FALSE;
2060 char *locktokenfile = NULL; 2067 char *locktokenfile = NULL;
2061 if((dir->lockpush || cmd_getoption(a, "lock")) && !cmd_getoption(a, "nolock") && !outgoing) { 2068 if((dir->lockpush || cmd_getoption(a, "lock")) && !cmd_getoption(a, "nolock") && !outgoing) {
2062 if(dav_lock_t(root, dir->lock_timeout)) { 2069 if(dav_lock_t(root, dir->lock_timeout)) {
2063 print_resource_error(sn, "/"); 2070 log_resource_error(sn, "/");
2064 dav_session_destroy(sn); 2071 dav_session_destroy(sn);
2065 fprintf(stderr, "Abort\n"); 2072 log_error("Abort\n");
2066 return -1; 2073 return -1;
2067 } 2074 }
2068 DavLock *lock = dav_get_lock(sn, "/"); 2075 DavLock *lock = dav_get_lock(sn, "/");
2069 if(lock) { 2076 if(lock) {
2070 log_printf("Lock-Token: %s\n", lock->token); 2077 log_printf("Lock-Token: %s\n", lock->token);
2162 cxListAdd(ls_update, local_res); 2169 cxListAdd(ls_update, local_res);
2163 } 2170 }
2164 2171
2165 if(local_res->isnew) { 2172 if(local_res->isnew) {
2166 if(local_resource_load_metadata(dir, local_res)) { 2173 if(local_resource_load_metadata(dir, local_res)) {
2167 fprintf( 2174 log_error(
2168 stderr,
2169 "Failed to load metadata: %s\n", 2175 "Failed to load metadata: %s\n",
2170 local_resource_path(local_res)); 2176 local_resource_path(local_res));
2171 } 2177 }
2172 } 2178 }
2173 } 2179 }
2278 break; 2284 break;
2279 } 2285 }
2280 2286
2281 DavResource *res = dav_resource_new(sn, local_res->path); 2287 DavResource *res = dav_resource_new(sn, local_res->path);
2282 if(!res) { 2288 if(!res) {
2283 print_resource_error(sn, local_res->path); 2289 log_resource_error(sn, local_res->path);
2284 ret = -1; 2290 ret = -1;
2285 sync_error++; 2291 sync_error++;
2286 } 2292 }
2287 2293
2288 int abort = 0; 2294 int abort = 0;
2291 if(sn->error == DAV_NOT_FOUND) { 2297 if(sn->error == DAV_NOT_FOUND) {
2292 // create collection 2298 // create collection
2293 // TODO: show 405 2299 // TODO: show 405
2294 log_printf("mkcol: %s\n", local_res->path); 2300 log_printf("mkcol: %s\n", local_res->path);
2295 if(sync_mkdir(dir, res, local_res) && sn->error != DAV_METHOD_NOT_ALLOWED) { 2301 if(sync_mkdir(dir, res, local_res) && sn->error != DAV_METHOD_NOT_ALLOWED) {
2296 print_resource_error(sn, res->path); 2302 log_resource_error(sn, res->path);
2297 ret = -1; 2303 ret = -1;
2298 sync_error++; 2304 sync_error++;
2299 error = 1; 2305 error = 1;
2300 abort = 1; 2306 abort = 1;
2301 } 2307 }
2302 } else if(sn->error != DAV_OK) { 2308 } else if(sn->error != DAV_OK) {
2303 // dav_exists() failed 2309 // dav_exists() failed
2304 print_resource_error(sn, local_res->path); 2310 log_resource_error(sn, local_res->path);
2305 ret = -1; 2311 ret = -1;
2306 sync_error++; 2312 sync_error++;
2307 error = 1; 2313 error = 1;
2308 abort = 1; 2314 abort = 1;
2309 } 2315 }
2372 } 2378 }
2373 } 2379 }
2374 2380
2375 if(err) { 2381 if(err) {
2376 sync_error++; 2382 sync_error++;
2377 print_resource_error(sn, res->path); 2383 log_resource_error(sn, res->path);
2378 ret = -1; 2384 ret = -1;
2379 error = 1; 2385 error = 1;
2380 } else { 2386 } else {
2381 LocalResource *dbres = cxMapGet(db->resources, cx_hash_key_str(local->path)); 2387 LocalResource *dbres = cxMapGet(db->resources, cx_hash_key_str(local->path));
2382 cxMapPut(db->resources, cx_hash_key_str(local->path), local); 2388 cxMapPut(db->resources, cx_hash_key_str(local->path), local);
2397 2403
2398 int err = 0; 2404 int err = 0;
2399 2405
2400 DavResource *res = dav_resource_new(sn, local_res->path); 2406 DavResource *res = dav_resource_new(sn, local_res->path);
2401 if(!res) { 2407 if(!res) {
2402 print_resource_error(sn, local_res->path); 2408 log_resource_error(sn, local_res->path);
2403 ret = -1; 2409 ret = -1;
2404 sync_error++; 2410 sync_error++;
2405 } else { 2411 } else {
2406 DavBool equal = FALSE; 2412 DavBool equal = FALSE;
2407 DavBool res_conflict = FALSE; 2413 DavBool res_conflict = FALSE;
2443 } else { 2449 } else {
2444 log_printf("put: %s\n", local_res->path); 2450 log_printf("put: %s\n", local_res->path);
2445 } 2451 }
2446 if(sync_put_resource(dir, res, local_res, &sync_success)) { 2452 if(sync_put_resource(dir, res, local_res, &sync_success)) {
2447 sync_error++; 2453 sync_error++;
2448 print_resource_error(sn, res->path); 2454 log_resource_error(sn, res->path);
2449 ret = -1; 2455 ret = -1;
2450 error = 1; 2456 error = 1;
2451 2457
2452 err = 1; 2458 err = 1;
2453 } 2459 }
2504 if(local->keep) { 2510 if(local->keep) {
2505 continue; 2511 continue;
2506 } 2512 }
2507 if(sync_delete_remote_resource(dir, sn, local, &sync_delete, col_list)) { 2513 if(sync_delete_remote_resource(dir, sn, local, &sync_delete, col_list)) {
2508 if(sn->error != DAV_NOT_FOUND) { 2514 if(sn->error != DAV_NOT_FOUND) {
2509 print_resource_error(sn, local->path); 2515 log_resource_error(sn, local->path);
2510 sync_error++; 2516 sync_error++;
2511 break; 2517 break;
2512 } 2518 }
2513 } else { 2519 } else {
2514 LocalResource *dbres = cxMapRemoveAndGet(db->resources, cx_hash_key_str(local->path)); 2520 LocalResource *dbres = cxMapRemoveAndGet(db->resources, cx_hash_key_str(local->path));
2523 cxListDestroy(cols_del); 2529 cxListDestroy(cols_del);
2524 2530
2525 // unlock repository 2531 // unlock repository
2526 if(locked) { 2532 if(locked) {
2527 if(dav_unlock(root)) { 2533 if(dav_unlock(root)) {
2528 print_resource_error(sn, "/"); 2534 log_resource_error(sn, "/");
2529 ret = -1; 2535 ret = -1;
2530 } else { 2536 } else {
2531 locked = FALSE; 2537 locked = FALSE;
2532 } 2538 }
2533 } 2539 }
2534 2540
2535 // store db 2541 // store db
2536 if(store_db(db, dir->database, dir->db_settings)) { 2542 if(store_db(db, dir->database, dir->db_settings)) {
2537 fprintf(stderr, "Cannot store sync db\n"); 2543 log_error("Cannot store sync db\n");
2538 ret = -2; 2544 ret = -2;
2539 } 2545 }
2540 2546
2541 // cleanup 2547 // cleanup
2542 if(!locked && locktokenfile) { 2548 if(!locked && locktokenfile) {
2635 restore_removed = 1; 2641 restore_removed = 1;
2636 } 2642 }
2637 2643
2638 SyncDatabase *db = load_db(dir->database); 2644 SyncDatabase *db = load_db(dir->database);
2639 if(!db) { 2645 if(!db) {
2640 fprintf(stderr, "Cannot load database file: %s\n", dir->database); 2646 log_error("Cannot load database file: %s\n", dir->database);
2641 return -1; 2647 return -1;
2642 } 2648 }
2643 remove_deleted_conflicts(dir, db); 2649 remove_deleted_conflicts(dir, db);
2644 2650
2645 CxList *modified = cxLinkedListCreate(cxDefaultAllocator, (cx_compare_func)localres_cmp_path, CX_STORE_POINTERS); 2651 CxList *modified = cxLinkedListCreate(cxDefaultAllocator, (cx_compare_func)localres_cmp_path, CX_STORE_POINTERS);
2663 if(errno == ENOENT) { 2669 if(errno == ENOENT) {
2664 if(restore_removed) { 2670 if(restore_removed) {
2665 cxListAdd(deleted, resource); 2671 cxListAdd(deleted, resource);
2666 } 2672 }
2667 } else { 2673 } else {
2668 fprintf(stderr, "Cannot stat file: %s\n", file_path); 2674 log_error("Cannot stat file: %s\n", file_path);
2669 perror(""); 2675 log_error("%s\n", strerror(errno));
2670 } 2676 }
2671 } else { 2677 } else {
2672 if(files) { 2678 if(files) {
2673 cxListAdd(modified, resource); 2679 cxListAdd(modified, resource);
2674 } else if(!resource->isdirectory && !S_ISDIR(s.st_mode)) { 2680 } else if(!resource->isdirectory && !S_ISDIR(s.st_mode)) {
2690 int ret = 0; 2696 int ret = 0;
2691 2697
2692 // create DavSession 2698 // create DavSession
2693 Repository *repo = get_repository(cx_str(dir->repository)); 2699 Repository *repo = get_repository(cx_str(dir->repository));
2694 if(!repo) { 2700 if(!repo) {
2695 fprintf(stderr, "Unkown repository %s\n", dir->name); 2701 log_error("Unkown repository %s\n", dir->name);
2696 return -1; 2702 return -1;
2697 } 2703 }
2698 DavSession *sn = create_session(a, ctx, repo, dir->collection); 2704 DavSession *sn = create_session(a, ctx, repo, dir->collection);
2699 cxMempoolRegister(sn->mp, db, (cx_destructor_func)destroy_db); 2705 cxMempoolRegister(sn->mp, db, (cx_destructor_func)destroy_db);
2700 if (cmd_getoption(a, "verbose")) { 2706 if (cmd_getoption(a, "verbose")) {
2707 DavBool locked = FALSE; 2713 DavBool locked = FALSE;
2708 DavResource *root = dav_resource_new(sn, "/"); 2714 DavResource *root = dav_resource_new(sn, "/");
2709 root->iscollection = TRUE; 2715 root->iscollection = TRUE;
2710 if((dir->lockpush || cmd_getoption(a, "lock")) && !cmd_getoption(a, "nolock")) { 2716 if((dir->lockpush || cmd_getoption(a, "lock")) && !cmd_getoption(a, "nolock")) {
2711 if(dav_lock_t(root, dir->lock_timeout)) { 2717 if(dav_lock_t(root, dir->lock_timeout)) {
2712 print_resource_error(sn, "/"); 2718 log_resource_error(sn, "/");
2713 dav_session_destroy(sn); 2719 dav_session_destroy(sn);
2714 fprintf(stderr, "Abort\n"); 2720 log_error("Abort\n");
2715 return -1; 2721 return -1;
2716 } 2722 }
2717 DavLock *lock = dav_get_lock(sn, "/"); 2723 DavLock *lock = dav_get_lock(sn, "/");
2718 if(lock) { 2724 if(lock) {
2719 log_printf("Lock-Token: %s\n", lock->token); 2725 log_printf("Lock-Token: %s\n", lock->token);
2738 log_printf("skip: %s\n", resource->path); 2744 log_printf("skip: %s\n", resource->path);
2739 continue; 2745 continue;
2740 } 2746 }
2741 char *status = dav_get_string_property(res, "idav:status"); 2747 char *status = dav_get_string_property(res, "idav:status");
2742 if(status && !strcmp(status, "broken")) { 2748 if(status && !strcmp(status, "broken")) {
2743 fprintf(stderr, "Resource %s broken\n", res->path); 2749 log_error("Resource %s broken\n", res->path);
2744 continue; 2750 continue;
2745 } 2751 }
2746 2752
2747 DavResource *vres = NULL; 2753 DavResource *vres = NULL;
2748 DavBool update_local_entry = TRUE; 2754 DavBool update_local_entry = TRUE;
2751 vres = versioning_simple_find(res, version); 2757 vres = versioning_simple_find(res, version);
2752 } else if(dir->versioning->type == VERSIONING_DELTAV) { 2758 } else if(dir->versioning->type == VERSIONING_DELTAV) {
2753 vres = versioning_deltav_find(res, version); 2759 vres = versioning_deltav_find(res, version);
2754 } 2760 }
2755 if(!vres) { 2761 if(!vres) {
2756 fprintf(stderr, "Cannot find specified version for resource %s\n", res->path); 2762 log_error("Cannot find specified version for resource %s\n", res->path);
2757 ret = 1; 2763 ret = 1;
2758 break; 2764 break;
2759 } 2765 }
2760 2766
2761 // By restoring an old version of a file, the local dir is not 2767 // By restoring an old version of a file, the local dir is not
2770 // download the resource 2776 // download the resource
2771 if(!sync_shutdown) { 2777 if(!sync_shutdown) {
2772 if(resource->isdirectory) { 2778 if(resource->isdirectory) {
2773 char *local_path = create_local_path(dir, res->path); 2779 char *local_path = create_local_path(dir, res->path);
2774 if(sys_mkdir(local_path) && errno != EEXIST) { 2780 if(sys_mkdir(local_path) && errno != EEXIST) {
2775 fprintf(stderr, 2781 log_error(
2776 "Cannot create directory %s: %s", 2782 "Cannot create directory %s: %s",
2777 local_path, strerror(errno)); 2783 local_path, strerror(errno));
2778 } 2784 }
2779 free(local_path); 2785 free(local_path);
2780 } else { 2786 } else {
2781 if(sync_get_resource(a, dir, res->path, vres, db, update_local_entry, &sync_success)) { 2787 if(sync_get_resource(a, dir, res->path, vres, db, update_local_entry, &sync_success)) {
2782 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); 2788 log_error("sync_get_resource failed for resource: %s\n", res->path);
2783 sync_error++; 2789 sync_error++;
2784 } else if(!update_local_entry) { 2790 } else if(!update_local_entry) {
2785 LocalResource *lr = cxMapGet(db->resources, cx_hash_key_str(res->path)); 2791 LocalResource *lr = cxMapGet(db->resources, cx_hash_key_str(res->path));
2786 if(lr) { 2792 if(lr) {
2787 lr->last_modified = 0; 2793 lr->last_modified = 0;
2796 } 2802 }
2797 2803
2798 // unlock repository 2804 // unlock repository
2799 if(locked) { 2805 if(locked) {
2800 if(dav_unlock(root)) { 2806 if(dav_unlock(root)) {
2801 print_resource_error(sn, "/"); 2807 log_resource_error(sn, "/");
2802 ret = -1; 2808 ret = -1;
2803 } else { 2809 } else {
2804 locked = FALSE; 2810 locked = FALSE;
2805 } 2811 }
2806 } 2812 }
2807 2813
2808 // store db 2814 // store db
2809 if(store_db(db, dir->database, dir->db_settings)) { 2815 if(store_db(db, dir->database, dir->db_settings)) {
2810 fprintf(stderr, "Cannot store sync db\n"); 2816 log_error("Cannot store sync db\n");
2811 ret = -2; 2817 ret = -2;
2812 } 2818 }
2813 2819
2814 // cleanup 2820 // cleanup
2815 dav_session_destroy(sn); 2821 dav_session_destroy(sn);
2867 } 2873 }
2868 2874
2869 log_printf("%s\n", "File Last Modified Size"); 2875 log_printf("%s\n", "File Last Modified Size");
2870 log_printf("%s\n", "=============================================================================="); 2876 log_printf("%s\n", "==============================================================================");
2871 2877
2872 if(ls_mkcol) { 2878 if(ls_mkcol->size > 0) {
2873 log_printf("Directories:\n"); 2879 log_printf("Directories:\n");
2874 CxIterator i = cxListIterator(ls_mkcol); 2880 CxIterator i = cxListIterator(ls_mkcol);
2875 cx_foreach(LocalResource *, res, i) { 2881 cx_foreach(LocalResource *, res, i) {
2876 log_printf(" %-49s\n", res->path+1); 2882 log_printf(" %-49s\n", res->path+1);
2877 total_size += res->size; 2883 total_size += res->size;
2878 } 2884 }
2879 } 2885 }
2880 if(ls_new) { 2886 if(ls_new->size > 0) {
2881 log_printf("New:\n"); 2887 log_printf("New:\n");
2882 CxIterator i = cxListIterator(ls_new); 2888 CxIterator i = cxListIterator(ls_new);
2883 cx_foreach(LocalResource *, res, i) { 2889 cx_foreach(LocalResource *, res, i) {
2884 print_outgoging_file(res); 2890 print_outgoging_file(res);
2885 total_size += res->size; 2891 total_size += res->size;
2886 } 2892 }
2887 } 2893 }
2888 if(ls_modified) { 2894 if(ls_modified->size > 0) {
2889 log_printf("Modified:\n"); 2895 log_printf("Modified:\n");
2890 CxIterator i = cxListIterator(ls_modified); 2896 CxIterator i = cxListIterator(ls_modified);
2891 cx_foreach(LocalResource *, res, i) { 2897 cx_foreach(LocalResource *, res, i) {
2892 print_outgoging_file(res); 2898 print_outgoging_file(res);
2893 total_size += res->size; 2899 total_size += res->size;
2894 } 2900 }
2895 } 2901 }
2896 if(ls_update) { 2902 if(ls_update->size > 0) {
2897 log_printf("Update:\n"); 2903 log_printf("Update:\n");
2898 CxIterator i = cxListIterator(ls_update); 2904 CxIterator i = cxListIterator(ls_update);
2899 cx_foreach(LocalResource *, res, i) { 2905 cx_foreach(LocalResource *, res, i) {
2900 char *lastmodified = util_date_str(res->last_modified); 2906 char *lastmodified = util_date_str(res->last_modified);
2901 log_printf(" %-49s %12s\n", res->path+1, lastmodified); 2907 log_printf(" %-49s %12s\n", res->path+1, lastmodified);
2902 free(lastmodified); 2908 free(lastmodified);
2903 } 2909 }
2904 } 2910 }
2905 if(ls_delete) { 2911 if(ls_delete->size > 0) {
2906 log_printf("Delete:\n"); 2912 log_printf("Delete:\n");
2907 CxIterator i = cxListIterator(ls_delete); 2913 CxIterator i = cxListIterator(ls_delete);
2908 cx_foreach(LocalResource *, res, i) { 2914 cx_foreach(LocalResource *, res, i) {
2909 log_printf(" %s\n", res->path+1); 2915 log_printf(" %s\n", res->path+1);
2910 } 2916 }
2911 } 2917 }
2912 if(ls_copy) { 2918 if(ls_copy->size > 0) {
2913 log_printf("Copy:\n"); 2919 log_printf("Copy:\n");
2914 CxIterator i = cxListIterator(ls_copy); 2920 CxIterator i = cxListIterator(ls_copy);
2915 cx_foreach(LocalResource *, res, i) { 2921 cx_foreach(LocalResource *, res, i) {
2916 log_printf("%s -> %s\n", res->origin->path+1, res->path); 2922 log_printf("%s -> %s\n", res->origin->path+1, res->path);
2917 } 2923 }
2918 } 2924 }
2919 if(ls_move) { 2925 if(ls_move->size > 0) {
2920 log_printf("Move:\n"); 2926 log_printf("Move:\n");
2921 CxIterator i = cxListIterator(ls_move); 2927 CxIterator i = cxListIterator(ls_move);
2922 cx_foreach(LocalResource *, res, i) { 2928 cx_foreach(LocalResource *, res, i) {
2923 log_printf("%s -> %s\n", res->origin->path+1, res->path); 2929 log_printf("%s -> %s\n", res->origin->path+1, res->path);
2924 } 2930 }
2925 } 2931 }
2926 if(ls_conflict) { 2932 if(ls_conflict->size > 0) {
2927 log_printf("Conflict\n"); 2933 log_printf("Conflict\n");
2928 CxIterator i = cxListIterator(ls_conflict); 2934 CxIterator i = cxListIterator(ls_conflict);
2929 cx_foreach(LocalResource *, res, i) { 2935 cx_foreach(LocalResource *, res, i) {
2930 log_printf(" %s\n", res->path+1); 2936 log_printf(" %s\n", res->path+1);
2931 } 2937 }
2960 cxListRemove(stack, 0); 2966 cxListRemove(stack, 0);
2961 char *local_path = create_local_path(dir, p); 2967 char *local_path = create_local_path(dir, p);
2962 SYS_DIR local_dir = sys_opendir(local_path); 2968 SYS_DIR local_dir = sys_opendir(local_path);
2963 2969
2964 if(!local_dir) { 2970 if(!local_dir) {
2965 fprintf(stderr, "Cannot open directory %s\n", local_path); 2971 log_error("Cannot open directory %s: %s\n", local_path, strerror(errno));
2966 } else { 2972 } else {
2967 SysDirEnt *ent; 2973 SysDirEnt *ent;
2968 while((ent = sys_readdir(local_dir)) != NULL) { 2974 while((ent = sys_readdir(local_dir)) != NULL) {
2969 if(!strcmp(ent->name, ".") || !strcmp(ent->name, "..")) { 2975 if(!strcmp(ent->name, ".") || !strcmp(ent->name, "..")) {
2970 continue; 2976 continue;
2999 3005
3000 LocalResource* local_resource_new(SyncDirectory *dir, SyncDatabase *db, char *path) { 3006 LocalResource* local_resource_new(SyncDirectory *dir, SyncDatabase *db, char *path) {
3001 char *file_path = create_local_path(dir, path); 3007 char *file_path = create_local_path(dir, path);
3002 SYS_STAT s; 3008 SYS_STAT s;
3003 if(sys_lstat(file_path, &s)) { 3009 if(sys_lstat(file_path, &s)) {
3004 fprintf(stderr, "Cannot stat file %s\n", file_path); 3010 log_error("Cannot stat file %s: %s\n", file_path, strerror(errno));
3005 free(file_path); 3011 free(file_path);
3006 return NULL; 3012 return NULL;
3007 } 3013 }
3008 3014
3009 LocalResource *res = calloc(1, sizeof(LocalResource)); 3015 LocalResource *res = calloc(1, sizeof(LocalResource));
3470 return NULL; 3476 return NULL;
3471 } 3477 }
3472 3478
3473 3479
3474 if(dav_load_prop(vcol, defprops, numdefprops)) { 3480 if(dav_load_prop(vcol, defprops, numdefprops)) {
3475 print_resource_error(res->session, vcol->path); 3481 log_resource_error(res->session, vcol->path);
3476 dav_resource_free(vcol); 3482 dav_resource_free(vcol);
3477 return NULL; 3483 return NULL;
3478 } 3484 }
3479 3485
3480 DavResource *ret = NULL; 3486 DavResource *ret = NULL;
3540 // set mtime 3546 // set mtime
3541 struct utimbuf t; 3547 struct utimbuf t;
3542 t.actime = f.last_modified; 3548 t.actime = f.last_modified;
3543 t.modtime = f.last_modified; 3549 t.modtime = f.last_modified;
3544 if(utime(path, &t)) { 3550 if(utime(path, &t)) {
3545 fprintf(stderr, "utime failed for file: %s : %s\n", path, strerror(errno)); 3551 log_error("utime failed for file: %s : %s\n", path, strerror(errno));
3546 ret = 1; 3552 ret = 1;
3547 } else { 3553 } else {
3548 local->last_modified = f.last_modified; 3554 local->last_modified = f.last_modified;
3549 } 3555 }
3550 } 3556 }
3551 if((dir->metadata & FINFO_MODE) == FINFO_MODE && f.mode_set) { 3557 if((dir->metadata & FINFO_MODE) == FINFO_MODE && f.mode_set) {
3552 // set mode 3558 // set mode
3553 if(chmod(path, f.mode)) { 3559 if(chmod(path, f.mode)) {
3554 fprintf(stderr, "chmod failed for file: %s : %s\n", path, strerror(errno)); 3560 log_error("chmod failed for file: %s : %s\n", path, strerror(errno));
3555 ret = 1; 3561 ret = 1;
3556 } else { 3562 } else {
3557 local->mode = f.mode; 3563 local->mode = f.mode;
3558 } 3564 }
3559 } 3565 }
3599 // store extended attributes 3605 // store extended attributes
3600 size_t nattr = xattr ? xattr->nattr : 0; 3606 size_t nattr = xattr ? xattr->nattr : 0;
3601 for(int i=0;i<nattr;i++) { 3607 for(int i=0;i<nattr;i++) {
3602 cxmutstr value = xattr->values[i]; 3608 cxmutstr value = xattr->values[i];
3603 if(xattr_set(path, xattr->names[i], value.ptr, value.length)) { 3609 if(xattr_set(path, xattr->names[i], value.ptr, value.length)) {
3604 fprintf(stderr, 3610 log_error(
3605 "Cannot store xattr '%s' for file: %s\n", 3611 "Cannot store xattr '%s' for file: %s\n",
3606 xattr->names[i], 3612 xattr->names[i],
3607 path); 3613 path);
3608 } 3614 }
3609 3615
4062 // Make sure the resource is a collection. If it was a normal 4068 // Make sure the resource is a collection. If it was a normal
4063 // resource until now, delete it and recreate it as collection 4069 // resource until now, delete it and recreate it as collection
4064 if(res->exists) { 4070 if(res->exists) {
4065 if(!res->iscollection) { 4071 if(!res->iscollection) {
4066 if(dav_delete(res)) { 4072 if(dav_delete(res)) {
4067 print_resource_error(res->session, res->path); 4073 log_resource_error(res->session, res->path);
4068 *err = 1; 4074 *err = 1;
4069 return NULL; 4075 return NULL;
4070 } 4076 }
4071 res->exists = 0; 4077 res->exists = 0;
4072 return upload_parts(local, res, in, filesize, blocksize, blockcount, err); 4078 return upload_parts(local, res, in, filesize, blocksize, blockcount, err);
4073 } 4079 }
4074 } else { 4080 } else {
4075 res->iscollection = 1; 4081 res->iscollection = 1;
4076 if(dav_create(res)) { 4082 if(dav_create(res)) {
4077 print_resource_error(res->session, res->path); 4083 log_resource_error(res->session, res->path);
4078 *err = 1; 4084 *err = 1;
4079 return NULL; 4085 return NULL;
4080 } 4086 }
4081 } 4087 }
4082 res->exists = 1; 4088 res->exists = 1;
4083 4089
4084 if(!res->href) { 4090 if(!res->href) {
4085 // this should never happen, but just make sure it doesn't crash 4091 // this should never happen, but just make sure it doesn't crash
4086 fprintf(stderr, "href is NULL\n"); 4092 log_error("href is NULL\n");
4087 *err = 1; 4093 *err = 1;
4088 return NULL; 4094 return NULL;
4089 } 4095 }
4090 4096
4091 char *buffer = malloc(blocksize); 4097 char *buffer = malloc(blocksize);
4098 // calculate the maximal length of resource names 4104 // calculate the maximal length of resource names
4099 // names should have all the same length and contain the block number 4105 // names should have all the same length and contain the block number
4100 int nblocks = filesize / blocksize; 4106 int nblocks = filesize / blocksize;
4101 int digits = LOG10((double)nblocks) + 1; 4107 int digits = LOG10((double)nblocks) + 1;
4102 if(digits > 127) { 4108 if(digits > 127) {
4103 fprintf(stderr, "Too many parts\n"); 4109 log_error("Too many parts\n");
4104 *err = 1; 4110 *err = 1;
4105 free(buffer); 4111 free(buffer);
4106 return NULL; 4112 return NULL;
4107 } 4113 }
4108 4114
4150 4156
4151 // upload part 4157 // upload part
4152 dav_set_content_data(part, buffer, r); 4158 dav_set_content_data(part, buffer, r);
4153 if(dav_store(part)) { 4159 if(dav_store(part)) {
4154 *err = 1; 4160 *err = 1;
4155 print_resource_error(res->session, part->path); 4161 log_resource_error(res->session, part->path);
4156 } else { 4162 } else {
4157 // successfully uploaded part 4163 // successfully uploaded part
4158 4164
4159 // store the FilePart in a map 4165 // store the FilePart in a map
4160 // later we do a propfind and add the etag 4166 // later we do a propfind and add the etag
4191 // get etags from uploaded resources 4197 // get etags from uploaded resources
4192 // also delete everything, that is not part of the file 4198 // also delete everything, that is not part of the file
4193 CxList *updated_parts = cxLinkedListCreateSimple(CX_STORE_POINTERS); 4199 CxList *updated_parts = cxLinkedListCreateSimple(CX_STORE_POINTERS);
4194 DavResource *parts = dav_query(res->session, "select D:getetag from %s order by name", res->path); 4200 DavResource *parts = dav_query(res->session, "select D:getetag from %s order by name", res->path);
4195 if(!parts) { 4201 if(!parts) {
4196 print_resource_error(res->session, parts->path); 4202 log_resource_error(res->session, parts->path);
4197 *err = 1; 4203 *err = 1;
4198 cxMapDestroy(updated_parts_map); 4204 cxMapDestroy(updated_parts_map);
4199 return NULL; 4205 return NULL;
4200 } 4206 }
4201 DavResource *part = parts->children; 4207 DavResource *part = parts->children;
4228 } 4234 }
4229 } 4235 }
4230 4236
4231 if(delete_part) { 4237 if(delete_part) {
4232 if(dav_delete(part)) { 4238 if(dav_delete(part)) {
4233 print_resource_error(part->session, part->path); 4239 log_resource_error(part->session, part->path);
4234 } 4240 }
4235 } 4241 }
4236 } 4242 }
4237 part = part->next; 4243 part = part->next;
4238 } 4244 }
4302 { 4308 {
4303 char *local_path = create_local_path(dir, local_resource_path(local)); 4309 char *local_path = create_local_path(dir, local_resource_path(local));
4304 4310
4305 SYS_STAT s; 4311 SYS_STAT s;
4306 if(sys_stat(local_path, &s)) { 4312 if(sys_stat(local_path, &s)) {
4307 fprintf(stderr, "Cannot stat file: %s\n", local_path); 4313 log_error("Cannot stat file: %s: %s\n", local_path, strerror(errno));
4308 perror("");
4309 free(local_path); 4314 free(local_path);
4310 return -1; 4315 return -1;
4311 } 4316 }
4312 4317
4313 DavBool islink = local->link_target ? 1 : 0; 4318 DavBool islink = local->link_target ? 1 : 0;
4317 4322
4318 size_t split_blocksize = resource_get_blocksize(dir, local, res, s.st_size); 4323 size_t split_blocksize = resource_get_blocksize(dir, local, res, s.st_size);
4319 4324
4320 FILE *in = sys_fopen(local_path, "rb"); 4325 FILE *in = sys_fopen(local_path, "rb");
4321 if(!in) { 4326 if(!in) {
4322 fprintf(stderr, "Cannot open file %s\n", local_path); 4327 log_error("Cannot open file %s: %s\n", local_path, strerror(errno));
4323 free(local_path); 4328 free(local_path);
4324 return -1; 4329 return -1;
4325 } 4330 }
4326 4331
4327 DavBool issplit = split_blocksize == 0 ? FALSE : TRUE; 4332 DavBool issplit = split_blocksize == 0 ? FALSE : TRUE;
4366 if(dir->versioning && dir->versioning->always && !issplit) { 4371 if(dir->versioning && dir->versioning->always && !issplit) {
4367 // in case the file exists, we need to put the file under 4372 // in case the file exists, we need to put the file under
4368 // versioncontrol (DeltaV only, does nothing with simple versioning) 4373 // versioncontrol (DeltaV only, does nothing with simple versioning)
4369 if(exists && versioning_init(dir, local, res)) { 4374 if(exists && versioning_init(dir, local, res)) {
4370 // init failed 4375 // init failed
4371 fprintf(stderr, "Cannot activate versioncontrol for resource: %s\n", res->href); 4376 log_error("Cannot activate versioncontrol for resource: %s\n", res->href);
4372 free(local_path); 4377 free(local_path);
4373 return -1; 4378 return -1;
4374 } else { 4379 } else {
4375 int err = versioning_begin(dir, res, &exists, &vend_required); 4380 int err = versioning_begin(dir, res, &exists, &vend_required);
4376 if(err) { 4381 if(err) {
4377 fprintf(stderr, "Cannot store version for resource: %s\n", res->href); 4382 log_error("Cannot store version for resource: %s\n", res->href);
4378 free(local_path); 4383 free(local_path);
4379 return -1; 4384 return -1;
4380 } 4385 }
4381 } 4386 }
4382 } 4387 }
4395 break; 4400 break;
4396 } 4401 }
4397 4402
4398 if(vend_required) { 4403 if(vend_required) {
4399 if(versioning_end(dir, res)) { 4404 if(versioning_end(dir, res)) {
4400 fprintf(stderr, "Cannot checkin resource\n"); 4405 log_error("Cannot checkin resource\n");
4401 ret = 1; 4406 ret = 1;
4402 } 4407 }
4403 } 4408 }
4404 4409
4405 if(ret == 0) { 4410 if(ret == 0) {
4414 DavResource *up_res = dav_get(res->session, res->path, "D:getetag,idav:status"); 4419 DavResource *up_res = dav_get(res->session, res->path, "D:getetag,idav:status");
4415 4420
4416 if(up_res) { 4421 if(up_res) {
4417 // the new content length must be equal or greater than the file size 4422 // the new content length must be equal or greater than the file size
4418 if(up_res->contentlength < s.st_size && !issplit && !islink) { 4423 if(up_res->contentlength < s.st_size && !issplit && !islink) {
4419 fprintf(stderr, "Incomplete Upload: %s\n", local_path); 4424 log_error("Incomplete Upload: %s\n", local_path);
4420 ret = -1; 4425 ret = -1;
4421 // try to set the resource status to 'broken' 4426 // try to set the resource status to 'broken'
4422 sync_set_status(res, "broken"); 4427 sync_set_status(res, "broken");
4423 } else { 4428 } else {
4424 // everything seems fine, we can update the local resource 4429 // everything seems fine, we can update the local resource
4474 { 4479 {
4475 char *local_path = create_local_path(dir, local->path); 4480 char *local_path = create_local_path(dir, local->path);
4476 4481
4477 SYS_STAT s; 4482 SYS_STAT s;
4478 if(sys_stat(local_path, &s)) { 4483 if(sys_stat(local_path, &s)) {
4479 fprintf(stderr, "Cannot stat file: %s\n", local_path); 4484 log_error("Cannot stat file: %s: %s\n", local_path, strerror(errno));
4480 perror("");
4481 free(local_path); 4485 free(local_path);
4482 return -1; 4486 return -1;
4483 } 4487 }
4484 free(local_path); 4488 free(local_path);
4485 4489
4507 4511
4508 sync_set_metadata_from_stat(local, &s); 4512 sync_set_metadata_from_stat(local, &s);
4509 MetadataHashes hashes; 4513 MetadataHashes hashes;
4510 hashes = sync_set_metadata_properties(dir, up_res->session, up_res, local, TRUE); 4514 hashes = sync_set_metadata_properties(dir, up_res->session, up_res, local, TRUE);
4511 if(dav_store(up_res)) { 4515 if(dav_store(up_res)) {
4512 fprintf(stderr, "Error: cannot store resource metadata\n"); 4516 log_error("Error: cannot store resource metadata\n");
4513 } 4517 }
4514 4518
4515 // get new etag 4519 // get new etag
4516 DavPropName p; 4520 DavPropName p;
4517 p.ns = "DAV:"; 4521 p.ns = "DAV:";
4552 cxListAdd(cols, local_res); 4556 cxListAdd(cols, local_res);
4553 } else if(split || !res->children) { 4557 } else if(split || !res->children) {
4554 log_printf("delete: %s\n", res->path); 4558 log_printf("delete: %s\n", res->path);
4555 if(dav_delete(res)) { 4559 if(dav_delete(res)) {
4556 ret = 1; 4560 ret = 1;
4557 fprintf(stderr, "Cannot delete collection %s\n", res->path); 4561 log_error("Cannot delete collection %s\n", res->path);
4558 } else { 4562 } else {
4559 (*counter)++; 4563 (*counter)++;
4560 } 4564 }
4561 } 4565 }
4562 } else { 4566 } else {
4573 log_printf("delete: %s\n", res->path); 4577 log_printf("delete: %s\n", res->path);
4574 int exists = 1; 4578 int exists = 1;
4575 int vend_required = 0; 4579 int vend_required = 0;
4576 if(dir->versioning && dir->versioning->always) { 4580 if(dir->versioning && dir->versioning->always) {
4577 if(versioning_delete_begin(dir, res, &exists, &vend_required)) { 4581 if(versioning_delete_begin(dir, res, &exists, &vend_required)) {
4578 fprintf( 4582 log_error("Cannot save resource version before deletion\n");
4579 stderr,
4580 "Cannot save resource version before deletion\n");
4581 ret = 1; 4583 ret = 1;
4582 } 4584 }
4583 } 4585 }
4584 4586
4585 if(!ret && dav_delete(res) && exists) { 4587 if(!ret && dav_delete(res) && exists) {
4586 if(sn->error != DAV_NOT_FOUND) { 4588 if(sn->error != DAV_NOT_FOUND) {
4587 fprintf(stderr, "Cannot delete resource %s\n", res->path); 4589 log_error("Cannot delete resource %s\n", res->path);
4588 ret = 1; 4590 ret = 1;
4589 } 4591 }
4590 } else { 4592 } else {
4591 (*counter)++; 4593 (*counter)++;
4592 } 4594 }
4631 // get remote tags 4633 // get remote tags
4632 DavPropName p; 4634 DavPropName p;
4633 p.ns = DAV_PROPS_NS; 4635 p.ns = DAV_PROPS_NS;
4634 p.name = "tags"; 4636 p.name = "tags";
4635 if(dav_load_prop(res, &p, 1) && sn->error != DAV_NOT_FOUND) { 4637 if(dav_load_prop(res, &p, 1) && sn->error != DAV_NOT_FOUND) {
4636 print_resource_error(sn, res->path); 4638 log_resource_error(sn, res->path);
4637 } 4639 }
4638 CxList *remote_tags = NULL; 4640 CxList *remote_tags = NULL;
4639 DavXmlNode *tagsprop = dav_get_property_ns(res, DAV_PROPS_NS, "tags"); 4641 DavXmlNode *tagsprop = dav_get_property_ns(res, DAV_PROPS_NS, "tags");
4640 if(tagsprop) { 4642 if(tagsprop) {
4641 remote_tags = parse_dav_xml_taglist(tagsprop); 4643 remote_tags = parse_dav_xml_taglist(tagsprop);
4734 { 4736 {
4735 MetadataHashes hashes = sync_set_metadata_properties(dir, sn, res, local, FALSE); 4737 MetadataHashes hashes = sync_set_metadata_properties(dir, sn, res, local, FALSE);
4736 4738
4737 int err = 0; 4739 int err = 0;
4738 if(dav_store(res)) { 4740 if(dav_store(res)) {
4739 print_resource_error(sn, local->path); 4741 log_resource_error(sn, local->path);
4740 err = 1; 4742 err = 1;
4741 } else { 4743 } else {
4742 update_metadata_hashes(local, hashes); 4744 update_metadata_hashes(local, hashes);
4743 local->tags_updated = 0; 4745 local->tags_updated = 0;
4744 } 4746 }
4757 if(sys_stat(path, &s)) { 4759 if(sys_stat(path, &s)) {
4758 if(errno == ENOENT) { 4760 if(errno == ENOENT) {
4759 dc[numdc] = res->path; 4761 dc[numdc] = res->path;
4760 numdc++; 4762 numdc++;
4761 } else { 4763 } else {
4762 fprintf(stderr, "Cannot stat file: %s\n", path); 4764 log_error("Cannot stat file: %s: %s\n", path, strerror(errno));
4763 perror("");
4764 } 4765 }
4765 } 4766 }
4766 free(path); 4767 free(path);
4767 } 4768 }
4768 4769
4777 CxIterator i = cxMapIteratorValues(db->resources); 4778 CxIterator i = cxMapIteratorValues(db->resources);
4778 int skipped = 0; 4779 int skipped = 0;
4779 cx_foreach(LocalResource *, res, i) { 4780 cx_foreach(LocalResource *, res, i) {
4780 if(res->skipped) { 4781 if(res->skipped) {
4781 skipped++; 4782 skipped++;
4782 fprintf(stderr, "skipped from push: %s\n", res->path); 4783 log_error("skipped from push: %s\n", res->path);
4783 } 4784 }
4784 } 4785 }
4785 if(skipped > 0) { 4786 if(skipped > 0) {
4786 fprintf(stderr, 4787 log_error(
4787 " To resolve conflict resources skipped by push run dav-sync pull first\n" 4788 " To resolve conflict resources skipped by push run dav-sync pull first\n"
4788 " before resolve-conflicts or delete-conflicts.\n\n"); 4789 " before resolve-conflicts or delete-conflicts.\n\n");
4789 } 4790 }
4790 } 4791 }
4791 4792
4792 int cmd_resolve_conflicts(CmdArgs *a) { 4793 int cmd_resolve_conflicts(CmdArgs *a) {
4793 if(a->argc != 1) { 4794 if(a->argc != 1) {
4794 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many"); 4795 log_error("Too %s arguments\n", a->argc < 1 ? "few" : "many");
4795 return -1; 4796 return -1;
4796 } 4797 }
4797 4798
4798 SyncDirectory *dir = scfg_get_dir(a->argv[0]); 4799 SyncDirectory *dir = scfg_get_dir(a->argv[0]);
4799 if(!dir) { 4800 if(!dir) {
4800 fprintf(stderr, "Unknown sync dir: %s\n", a->argv[0]); 4801 log_error("Unknown sync dir: %s\n", a->argv[0]);
4801 return -1; 4802 return -1;
4802 } 4803 }
4803 if(scfg_check_dir(dir)) { 4804 if(scfg_check_dir(dir)) {
4804 return -1; 4805 return -1;
4805 } 4806 }
4807 return -1; 4808 return -1;
4808 } 4809 }
4809 4810
4810 SyncDatabase *db = load_db(dir->database); 4811 SyncDatabase *db = load_db(dir->database);
4811 if(!db) { 4812 if(!db) {
4812 fprintf(stderr, "Cannot load database file: %s\n", dir->database); 4813 log_error("Cannot load database file: %s\n", dir->database);
4813 return -1; 4814 return -1;
4814 } 4815 }
4815 4816
4816 resolve_skipped(db); 4817 resolve_skipped(db);
4817 4818
4822 //ucx_map_free_content(db->conflict, (ucx_destructor)local_resource_free); 4823 //ucx_map_free_content(db->conflict, (ucx_destructor)local_resource_free);
4823 cxMapClear(db->conflict); 4824 cxMapClear(db->conflict);
4824 4825
4825 // store db 4826 // store db
4826 if(store_db(db, dir->database, dir->db_settings)) { 4827 if(store_db(db, dir->database, dir->db_settings)) {
4827 fprintf(stderr, "Cannot store sync db\n"); 4828 log_error("Cannot store sync db\n");
4828 fprintf(stderr, "Abort\n"); 4829 log_error("Abort\n");
4829 ret = -2; 4830 ret = -2;
4830 } 4831 }
4831 4832
4832 // cleanup 4833 // cleanup
4833 destroy_db(db); 4834 destroy_db(db);
4859 return -1; 4860 return -1;
4860 } 4861 }
4861 4862
4862 SyncDatabase *db = load_db(dir->database); 4863 SyncDatabase *db = load_db(dir->database);
4863 if(!db) { 4864 if(!db) {
4864 fprintf(stderr, "Cannot load database file: %s\n", dir->database); 4865 log_error("Cannot load database file: %s\n", dir->database);
4865 return -1; 4866 return -1;
4866 } 4867 }
4867 4868
4868 resolve_skipped(db); 4869 resolve_skipped(db);
4869 4870
4877 cx_foreach(LocalResource*, res, i) { 4878 cx_foreach(LocalResource*, res, i) {
4878 log_printf("delete: %s\n", res->path); 4879 log_printf("delete: %s\n", res->path);
4879 char *path = create_local_path(dir, res->path); 4880 char *path = create_local_path(dir, res->path);
4880 if(sys_unlink(path)) { 4881 if(sys_unlink(path)) {
4881 if(errno != ENOENT) { 4882 if(errno != ENOENT) {
4882 perror("unlink"); 4883 log_error("unlink: %s", strerror(errno));
4883 num_err++; 4884 num_err++;
4884 } 4885 }
4885 } else { 4886 } else {
4886 num_del++; 4887 num_del++;
4887 } 4888 }
4890 //ucx_map_free_content(db->conflict, (ucx_destructor)local_resource_free); 4891 //ucx_map_free_content(db->conflict, (ucx_destructor)local_resource_free);
4891 cxMapClear(db->conflict); 4892 cxMapClear(db->conflict);
4892 4893
4893 // store db 4894 // store db
4894 if(store_db(db, dir->database, dir->db_settings)) { 4895 if(store_db(db, dir->database, dir->db_settings)) {
4895 fprintf(stderr, "Cannot store sync db\n"); 4896 log_error("Cannot store sync db\n");
4896 fprintf(stderr, "Abort\n"); 4897 log_error("Abort\n");
4897 ret = -1; 4898 ret = -1;
4898 } 4899 }
4899 4900
4900 // cleanup 4901 // cleanup
4901 destroy_db(db); 4902 destroy_db(db);
5233 if(logfile_open(syncdir)) { 5234 if(logfile_open(syncdir)) {
5234 return -1; 5235 return -1;
5235 } 5236 }
5236 5237
5237 if(!syncdir->trash) { 5238 if(!syncdir->trash) {
5238 fprintf(stderr, "trash not configured for %s\n", syncdir->name); 5239 log_error("trash not configured for %s\n", syncdir->name);
5239 return -1; 5240 return -1;
5240 } 5241 }
5241 5242
5242 SYS_DIR dir = sys_opendir(syncdir->trash); 5243 SYS_DIR dir = sys_opendir(syncdir->trash);
5243 if(!dir) { 5244 if(!dir) {
5244 fprintf(stderr, "cannot open trash directory: %s\n", syncdir->trash); 5245 log_error("cannot open trash directory: %s\n", syncdir->trash);
5245 perror("opendir"); 5246 log_error("opendir: %s\n", strerror(errno));
5246 return -1; 5247 return -1;
5247 } 5248 }
5248 5249
5249 SysDirEnt *ent; 5250 SysDirEnt *ent;
5250 while((ent = sys_readdir(dir)) != NULL) { 5251 while((ent = sys_readdir(dir)) != NULL) {
5255 char *path = util_concat_path(syncdir->trash, ent->name); 5256 char *path = util_concat_path(syncdir->trash, ent->name);
5256 log_printf("delete: %s\n", path); 5257 log_printf("delete: %s\n", path);
5257 5258
5258 SYS_STAT s; 5259 SYS_STAT s;
5259 if(sys_stat(path, &s)) { 5260 if(sys_stat(path, &s)) {
5260 perror("stat"); 5261 log_error("stat: %s\n", strerror(errno));
5261 free(path); 5262 free(path);
5262 continue; 5263 continue;
5263 } 5264 }
5264 if(S_ISDIR(s.st_mode)) { 5265 if(S_ISDIR(s.st_mode)) {
5265 if(rmdir(path)) { 5266 if(rmdir(path)) {
5266 perror("rmdir"); 5267 log_error("rmdir: %s\n", strerror(errno));
5267 } 5268 }
5268 } else { 5269 } else {
5269 if(sys_unlink(path)) { 5270 if(sys_unlink(path)) {
5270 perror("unlink"); 5271 log_error("unlink: %s\n", strerror(errno));
5271 } 5272 }
5272 } 5273 }
5273 5274
5274 free(path); 5275 free(path);
5275 } 5276 }
5532 return 0; 5533 return 0;
5533 } 5534 }
5534 5535
5535 void sync_print_get_file_err(const char *path, int err) { 5536 void sync_print_get_file_err(const char *path, int err) {
5536 switch(err) { 5537 switch(err) {
5537 case 1: fprintf(stderr, "File %s: not found\n", path); break; 5538 case 1: log_error("File %s: not found\n", path); break;
5538 case 2: fprintf(stderr, "File %s: permission denied\n", path); break; 5539 case 2: log_error("File %s: permission denied\n", path); break;
5539 case 3: fprintf(stderr, "File %s: stat failed: %s\n", path, strerror(errno)); break; 5540 case 3: log_error("File %s: stat failed: %s\n", path, strerror(errno)); break;
5540 case 4: fprintf(stderr, "File %s is not in any syncdir\n", path); break; 5541 case 4: log_error("File %s is not in any syncdir\n", path); break;
5541 case 5: fprintf(stderr, "File %s is in multiple syncdirs\n", path); break; 5542 case 5: log_error("File %s is in multiple syncdirs\n", path); break;
5542 case 6: fprintf(stderr, "Syncdir not found\n"); break; 5543 case 6: log_error("Syncdir not found\n"); break;
5543 } 5544 }
5544 } 5545 }
5545 5546
5546 5547
5547 int cmd_add_directory(CmdArgs *args) { 5548 int cmd_add_directory(CmdArgs *args) {
5699 char *path = config_file_path(fname.ptr); 5700 char *path = config_file_path(fname.ptr);
5700 free(fname.ptr); 5701 free(fname.ptr);
5701 5702
5702 FILE *file = sys_fopen(path, "w"); 5703 FILE *file = sys_fopen(path, "w");
5703 if(file) { 5704 if(file) {
5704 fprintf(file, "%s\n", locktoken); 5705 log_error("%s\n", locktoken);
5705 fclose(file); 5706 fclose(file);
5706 return path; 5707 return path;
5707 } else { 5708 } else {
5708 perror("Cannot create locktoken file"); 5709 log_error("Cannot create locktoken file: %s", strerror(errno));
5709 free(path); 5710 free(path);
5710 return NULL; 5711 return NULL;
5711 } 5712 }
5712 } 5713 }
5713 5714

mercurial