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 |