dav/sync.c

changeset 192
d10194a51304
parent 191
0e45b04236a7
child 198
44054c452de1
equal deleted inserted replaced
191:0e45b04236a7 192:d10194a51304
192 } 192 }
193 193
194 DavResource *ls = dav_query(sn, "select D:getetag,idav:status from / with depth = infinity"); 194 DavResource *ls = dav_query(sn, "select D:getetag,idav:status from / with depth = infinity");
195 if(!ls) { 195 if(!ls) {
196 print_resource_error(sn, "/"); 196 print_resource_error(sn, "/");
197 fprintf(stderr, "Abort\n");
198
199 dav_session_destroy(sn);
197 // TODO: free 200 // TODO: free
198 return -1; 201 return -1;
199 } 202 }
203
204 int sync_success = 0;
205 int sync_delete = 0;
206 int sync_error = 0;
200 207
201 if(!ls->children) { 208 if(!ls->children) {
202 // TODO: free 209 // TODO: free
203 fprintf(stderr, "Repository is empty\n"); 210 fprintf(stderr, "Repository is empty\n");
204 return 0; // empty repository 211 return 0; // empty repository
222 res = res->next; 229 res = res->next;
223 continue; 230 continue;
224 } 231 }
225 232
226 // download the resource 233 // download the resource
227 if(sync_get_resource(a, dir, res, db)) { 234 if(sync_get_resource(a, dir, res, db, &sync_success)) {
228 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path); 235 fprintf(stderr, "sync_get_resource failed for resource: %s\n", res->path);
236 sync_error++;
229 } 237 }
230 238
231 // add every resource from the server to svrres 239 // add every resource from the server to svrres
232 // then db-resources only contains resources which are not on the 240 // then db-resources only contains resources which are not on the
233 // server 241 // server
249 UCX_MAP_FOREACH(key, local, i) { 257 UCX_MAP_FOREACH(key, local, i) {
250 if (res_matches_filter(dir, local->path)) { 258 if (res_matches_filter(dir, local->path)) {
251 continue; 259 continue;
252 } 260 }
253 // sync_remove_resource does all necessary tests 261 // sync_remove_resource does all necessary tests
254 if(sync_remove_local_resource(dir, local)) { 262 int ret = sync_remove_local_resource(dir, local);
263 if(ret == -1) {
255 rmdirs = ucx_list_append(rmdirs, local); 264 rmdirs = ucx_list_append(rmdirs, local);
265 } else if(ret == 0) {
266 sync_delete++;
256 } 267 }
257 } 268 }
258 UCX_FOREACH(elm, rmdirs) { 269 UCX_FOREACH(elm, rmdirs) {
259 LocalResource *local_dir = elm->data; 270 LocalResource *local_dir = elm->data;
260 sync_remove_local_directory(dir, local_dir); 271 sync_remove_local_directory(dir, local_dir);
261 } 272 }
262 ucx_map_free(db->resources); 273 ucx_map_free(db->resources);
263 db->resources = svrres; 274 db->resources = svrres;
264 275
265 // TODO: cleanup - BUT DONT CLEANUP SYNC CONFIG (do this in main!)
266
267 // store db 276 // store db
268 if(store_db(db, dir->database)) { 277 if(store_db(db, dir->database)) {
269 fprintf(stderr, "Cannot store sync db\n"); 278 fprintf(stderr, "Cannot store sync db\n");
270 return -1; 279 fprintf(stderr, "Abort\n");
271 } 280 return -1; // TODO: don't return here
281 }
282
283 // TODO: cleanup - BUT DONT CLEANUP SYNC CONFIG (do this in main!)
284 dav_session_destroy(sn);
285
286 // Report
287 char *str_success = sync_success == 1 ? "file" : "files";
288 char *str_delete = sync_delete == 1 ? "file" : "files";
289 char *str_error = sync_error == 1 ? "error" : "errors";
290 printf("Result: %d %s pulled, %d %s deleted, %d %s\n",
291 sync_success, str_success,
292 sync_delete,str_delete,
293 sync_error, str_error);
272 294
273 return 0; 295 return 0;
274 } 296 }
275 297
276 int sync_get_resource(CmdArgs *a, SyncDirectory *dir, DavResource *res, SyncDatabase *db) { 298 int sync_get_resource(
299 CmdArgs *a,
300 SyncDirectory *dir,
301 DavResource *res,
302 SyncDatabase *db,
303 int *counter)
304 {
277 int cdt = cmd_getoption(a, "conflict") ? 0 : 1; // conflict detection 305 int cdt = cmd_getoption(a, "conflict") ? 0 : 1; // conflict detection
278 306
279 LocalResource *local = ucx_map_cstr_get(db->resources, res->path); 307 LocalResource *local = ucx_map_cstr_get(db->resources, res->path);
280 char *local_path = util_concat_path(dir->path, res->path); 308 char *local_path = util_concat_path(dir->path, res->path);
281 309
359 ret = -1; 387 ret = -1;
360 } 388 }
361 fclose(out); 389 fclose(out);
362 390
363 if(ret == 0) { 391 if(ret == 0) {
392 (*counter)++;
393
364 if(dir->trash && dir->backuppull) { 394 if(dir->trash && dir->backuppull) {
365 move_to_trash(dir, local_path); 395 move_to_trash(dir, local_path);
366 } 396 }
367 if(rename(tmp_path, local_path)) { 397 if(rename(tmp_path, local_path)) {
368 fprintf( 398 fprintf(
410 int sync_remove_local_resource(SyncDirectory *dir, LocalResource *res) { 440 int sync_remove_local_resource(SyncDirectory *dir, LocalResource *res) {
411 char *local_path = util_concat_path(dir->path, res->path); 441 char *local_path = util_concat_path(dir->path, res->path);
412 struct stat s; 442 struct stat s;
413 if(stat(local_path, &s)) { 443 if(stat(local_path, &s)) {
414 free(local_path); 444 free(local_path);
415 return 0; 445 return -2;
416 } 446 }
417 447
418 if(S_ISDIR(s.st_mode)) { 448 if(S_ISDIR(s.st_mode)) {
419 free(local_path); 449 free(local_path);
420 return 1; 450 return -1;
421 } 451 }
422 452
423 if(s.st_mtime != res->last_modified) { 453 if(s.st_mtime != res->last_modified) {
424 free(local_path); 454 free(local_path);
425 return 0; 455 return -2;
426 } 456 }
427 457
428 printf("delete: %s\n", res->path); 458 printf("delete: %s\n", res->path);
429 459 int ret = 0;
430 if(dir->trash) { 460 if(dir->trash) {
431 move_to_trash(dir, local_path); 461 move_to_trash(dir, local_path);
432 } else if(unlink(local_path)) { 462 } else if(unlink(local_path)) {
433 fprintf(stderr, "Cannot remove file %s\n", local_path); 463 fprintf(stderr, "Cannot remove file %s\n", local_path);
464 ret = -2;
434 } 465 }
435 free(local_path); 466 free(local_path);
436 467
437 return 0; 468 return ret;
438 } 469 }
439 470
440 void sync_remove_local_directory(SyncDirectory *dir, LocalResource *res) { 471 void sync_remove_local_directory(SyncDirectory *dir, LocalResource *res) {
441 char *local_path = util_concat_path(dir->path, res->path); 472 char *local_path = util_concat_path(dir->path, res->path);
442 473
581 if (cmd_getoption(a, "verbose")) { 612 if (cmd_getoption(a, "verbose")) {
582 curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L); 613 curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L);
583 curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr); 614 curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr);
584 } 615 }
585 616
617 DavResource *testsvr = dav_query(sn, "select - from / with depth = 0");
618 if(!testsvr) {
619 print_resource_error(sn, "/");
620 dav_session_destroy(sn);
621 fprintf(stderr, "Abort\n");
622 return -1;
623 }
624
625 int sync_success = 0;
626 int sync_delete = 0;
627 int sync_error = 0;
628
586 // upload all changed files 629 // upload all changed files
587 UcxList *resources = cmd_getoption(a, "read") ? 630 UcxList *resources = cmd_getoption(a, "read") ?
588 read_changes(dir, db) : local_scan(dir, db); 631 read_changes(dir, db) : local_scan(dir, db);
589 632
590 UcxMap *lclres = ucx_map_new(db->resources->count); 633 UcxMap *lclres = ucx_map_new(db->resources->count);
634 int ret = 0;
591 UCX_FOREACH(elm, resources) { 635 UCX_FOREACH(elm, resources) {
592 LocalResource *local_res = elm->data; 636 LocalResource *local_res = elm->data;
593 if (!res_matches_filter(dir, local_res->path+1)) { 637 if (!res_matches_filter(dir, local_res->path+1)) {
594 // upload every changed file 638 // upload every changed file
595 if (local_resource_is_changed(dir, db, local_res)) { 639 if (local_resource_is_changed(dir, db, local_res)) {
596 DavResource *res = dav_resource_new(sn, local_res->path); 640 DavResource *res = dav_resource_new(sn, local_res->path);
597 if(!res) { 641 if(!res) {
598 print_resource_error(sn, local_res->path); 642 print_resource_error(sn, local_res->path);
599 break; 643 ret = -1;
644 sync_error++;
600 } 645 }
601 646
602 if(local_res->isdirectory) { 647 if(local_res->isdirectory) {
603 printf("mkcol: %s\n", local_res->path); 648 printf("mkcol: %s\n", local_res->path);
604 if(sync_mkdir(dir, res, local_res)) { 649 if(sync_mkdir(dir, res, local_res) && sn->error != DAV_METHOD_NOT_ALLOWED) {
605 print_resource_error(sn, res->path); 650 print_resource_error(sn, res->path);
606 dav_resource_free(res); 651 ret = -1;
607 break; 652 sync_error++;
608 } 653 }
609 } else { 654 } else {
610 printf("put: %s\n", local_res->path); 655 printf("put: %s\n", local_res->path);
611 if(sync_put_resource(dir, res, local_res)) { 656 if(sync_put_resource(dir, res, local_res, &sync_success)) {
657 sync_error++;
612 print_resource_error(sn, res->path); 658 print_resource_error(sn, res->path);
613 dav_resource_free(res); 659 ret = -1;
614 break; 660 sync_error++;
615 } 661 }
616 } 662 }
617 dav_resource_free(res); 663 dav_resource_free(res);
618 } 664 }
619 665
624 } 670 }
625 } 671 }
626 ucx_list_free(resources); 672 ucx_list_free(resources);
627 673
628 // delete all removed files 674 // delete all removed files
629 UcxMapIterator i = ucx_map_iterator(db->resources); 675 if(ret == 0) {
630 LocalResource *local; 676 UcxMapIterator i = ucx_map_iterator(db->resources);
631 UCX_MAP_FOREACH(key, local, i) { 677 LocalResource *local;
632 if (!res_matches_filter(dir, local->path+1)) { 678 UCX_MAP_FOREACH(key, local, i) {
633 if(sync_delete_remote_resource(sn, local)) { 679 if (!res_matches_filter(dir, local->path+1)) {
634 ucx_map_cstr_put(lclres, local->path, local); 680 if(sync_delete_remote_resource(sn, local, &sync_delete)) {
635 if(sn->error != DAV_NOT_FOUND) { 681 ucx_map_cstr_put(lclres, local->path, local);
636 print_resource_error(sn, local->path); 682 if(sn->error != DAV_NOT_FOUND) {
637 break; 683 print_resource_error(sn, local->path);
684 sync_error++;
685 break;
686 }
638 } 687 }
639 } 688 }
640 } 689 }
641 } 690 }
642 ucx_map_free(db->resources); 691 ucx_map_free(db->resources);
643 db->resources = lclres; 692 db->resources = lclres;
644
645 // TODO: free res
646 693
647 // store db 694 // store db
648 if(store_db(db, dir->database)) { 695 if(store_db(db, dir->database)) {
649 fprintf(stderr, "Cannot store sync db\n"); 696 fprintf(stderr, "Cannot store sync db\n");
650 return -1; 697 return -1;
651 } 698 }
699
700 // TODO: free res
701
702 // Report
703 char *str_success = sync_success == 1 ? "file" : "files";
704 char *str_delete = sync_delete == 1 ? "file" : "files";
705 char *str_error = sync_error == 1 ? "error" : "errors";
706 printf("Result: %d %s pushed, %d %s deleted, %d %s\n",
707 sync_success, str_success,
708 sync_delete,str_delete,
709 sync_error, str_error);
652 710
653 return 0; 711 return 0;
654 } 712 }
655 713
656 UcxList* local_scan(SyncDirectory *dir, SyncDatabase *db) { 714 UcxList* local_scan(SyncDirectory *dir, SyncDatabase *db) {
809 int ret = dav_store(resource); 867 int ret = dav_store(resource);
810 dav_resource_free(resource); 868 dav_resource_free(resource);
811 return ret; 869 return ret;
812 } 870 }
813 871
814 int sync_put_resource(SyncDirectory *dir, DavResource *res, LocalResource *local) { 872 int sync_put_resource(
873 SyncDirectory *dir,
874 DavResource *res,
875 LocalResource *local,
876 int *counter)
877 {
815 char *local_path = util_concat_path(dir->path, res->path); 878 char *local_path = util_concat_path(dir->path, res->path);
816 879
817 struct stat s; 880 struct stat s;
818 if(stat(local_path, &s)) { 881 if(stat(local_path, &s)) {
819 fprintf(stderr, "cannot stat file: %s\n", local_path); 882 fprintf(stderr, "cannot stat file: %s\n", local_path);
845 break; 908 break;
846 } 909 }
847 910
848 911
849 912
850 if(ret == 0) { 913 if(ret == 0) {
914 (*counter)++;
915
851 // check contentlength and get new etag 916 // check contentlength and get new etag
852 DavResource *up_res = dav_get(res->session, res->path, "D:getetag"); 917 DavResource *up_res = dav_get(res->session, res->path, "D:getetag");
853 918
854 if(up_res) { 919 if(up_res) {
855 // the new content length must be equal or greater than the file size 920 // the new content length must be equal or greater than the file size
903 break; 968 break;
904 } 969 }
905 return ret; 970 return ret;
906 } 971 }
907 972
908 int sync_delete_remote_resource(DavSession *sn, LocalResource *local_res) { 973 int sync_delete_remote_resource(
974 DavSession *sn,
975 LocalResource *local_res,
976 int *counter)
977 {
909 DavResource *res = dav_get(sn, local_res->path, "D:getetag"); 978 DavResource *res = dav_get(sn, local_res->path, "D:getetag");
910 if(!res) { 979 if(!res) {
911 return sn->error == DAV_NOT_FOUND ? 0 : 1; 980 return sn->error == DAV_NOT_FOUND ? 0 : 1;
912 } 981 }
913 982
931 // resource can be deleted 1000 // resource can be deleted
932 printf("delete: %s\n", res->path); 1001 printf("delete: %s\n", res->path);
933 if(dav_delete(res)) { 1002 if(dav_delete(res)) {
934 if(sn->error != DAV_NOT_FOUND) { 1003 if(sn->error != DAV_NOT_FOUND) {
935 fprintf(stderr, "Cannot delete resource %s\n", res->path); 1004 fprintf(stderr, "Cannot delete resource %s\n", res->path);
936 } 1005 ret = 1;
937 } 1006 }
938 } else { 1007 } else {
939 ret = 1; 1008 (*counter)++;
1009 }
940 } 1010 }
941 } 1011 }
942 1012
943 // cleanup 1013 // cleanup
944 dav_resource_free(res); 1014 dav_resource_free(res);

mercurial