dav/sync.c

changeset 216
16d6b97fbf33
parent 215
781aee172901
child 217
12bad63cf5a8
equal deleted inserted replaced
215:781aee172901 216:16d6b97fbf33
355 } 355 }
356 } 356 }
357 357
358 if(cdt && exists && s.st_mtime != local->last_modified) { 358 if(cdt && exists && s.st_mtime != local->last_modified) {
359 // file modified on the server and on the client 359 // file modified on the server and on the client
360 rename_local_file(dir, db, local->path); 360 rename_conflict_file(dir, db, local->path);
361 } 361 }
362 } else { 362 } else {
363 if(stat(local_path, &s)) { 363 if(stat(local_path, &s)) {
364 if(errno != ENOENT) { 364 if(errno != ENOENT) {
365 fprintf(stderr, "Cannot stat file: %s\n", local_path); 365 fprintf(stderr, "Cannot stat file: %s\n", local_path);
366 } 366 }
367 } else if(S_ISDIR(s.st_mode)) { 367 } else if(S_ISDIR(s.st_mode)) {
368 //fprintf(stderr, "Error: file %s is a directory\n", local_path); 368 //fprintf(stderr, "Error: file %s is a directory\n", local_path);
369 } else if(cdt) { 369 } else if(cdt) {
370 // rename file on conflict 370 // rename file on conflict
371 rename_local_file(dir, db, res->path); 371 rename_conflict_file(dir, db, res->path);
372 } 372 }
373 } 373 }
374 374
375 int ret = 0; 375 int ret = 0;
376 char *tmp_path = create_tmp_download_path(local_path); 376 char *tmp_path = create_tmp_download_path(local_path);
497 } 497 }
498 498
499 free(local_path); 499 free(local_path);
500 } 500 }
501 501
502 void rename_local_file(SyncDirectory *dir, SyncDatabase *db, char *path) { 502 void rename_conflict_file(SyncDirectory *dir, SyncDatabase *db, char *path) {
503 char *local_path = util_concat_path(dir->path, path); 503 char *local_path = util_concat_path(dir->path, path);
504 char *parent = util_parent_path(local_path); 504 char *parent = util_parent_path(local_path);
505 505
506 int rev = 0; 506 int rev = 0;
507 struct stat s; 507 struct stat s;
508 int loop = 1; 508 int loop = 1;
509 do { 509 do {
510 sstr_t new_path = ucx_asprintf( 510 char *res_parent = util_parent_path(path);
511 ucx_default_allocator(), 511 char *res_name = util_resource_name(path);
512
513 sstr_t new_path = ucx_sprintf(
512 "%sorig.%d.%s", 514 "%sorig.%d.%s",
513 parent, 515 parent,
514 rev, 516 rev,
515 util_resource_name(path)); 517 res_name);
518 sstr_t new_res_path = ucx_sprintf(
519 "%sorig.%d.%s",
520 res_parent,
521 rev,
522 res_name);
516 523
517 524
518 if(stat(new_path.ptr, &s)) { 525 if(stat(new_path.ptr, &s)) {
519 if(errno == ENOENT) { 526 if(errno == ENOENT) {
520 loop = 0; 527 loop = 0;
524 fprintf( 531 fprintf(
525 stderr, 532 stderr,
526 "Cannot rename file %s to %s\n", 533 "Cannot rename file %s to %s\n",
527 local_path, 534 local_path,
528 new_path.ptr); 535 new_path.ptr);
536 } else {
537 LocalResource *conflict = calloc(1, sizeof(LocalResource));
538 conflict->path = strdup(new_res_path.ptr);
539 ucx_map_cstr_put(db->conflict, new_res_path.ptr, conflict);
529 } 540 }
530 } 541 }
531 } 542 }
532 rev++; 543 rev++;
544 free(res_parent);
533 free(new_path.ptr); 545 free(new_path.ptr);
546 free(new_res_path.ptr);
547
534 } while(loop); 548 } while(loop);
535 free(parent); 549 free(parent);
550 free(local_path);
536 } 551 }
537 552
538 char* create_tmp_download_path(char *path) { 553 char* create_tmp_download_path(char *path) {
539 char *new_path = NULL; 554 char *new_path = NULL;
540 char *parent = util_parent_path(path); 555 char *parent = util_parent_path(path);
595 } 610 }
596 611
597 free(new_path); 612 free(new_path);
598 } 613 }
599 614
615 static int res_isconflict(SyncDatabase *db, LocalResource *res) {
616 return ucx_map_cstr_get(db->conflict, res->path) ? 1 : 0;
617 }
618
600 int cmd_push(CmdArgs *a) { 619 int cmd_push(CmdArgs *a) {
601 if(a->argc != 1) { 620 if(a->argc != 1) {
602 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many"); 621 fprintf(stderr, "Too %s arguments\n", a->argc < 1 ? "few" : "many");
603 return -1; 622 return -1;
604 } 623 }
642 return -1; 661 return -1;
643 } 662 }
644 663
645 int sync_success = 0; 664 int sync_success = 0;
646 int sync_delete = 0; 665 int sync_delete = 0;
666 int sync_skipped = 0;
647 int sync_error = 0; 667 int sync_error = 0;
648 668
649 // upload all changed files 669 // upload all changed files
650 UcxList *resources = cmd_getoption(a, "read") ? 670 UcxList *resources = cmd_getoption(a, "read") ?
651 read_changes(dir, db) : local_scan(dir, db); 671 read_changes(dir, db) : local_scan(dir, db);
653 UcxMap *lclres = ucx_map_new(db->resources->count); 673 UcxMap *lclres = ucx_map_new(db->resources->count);
654 int ret = 0; 674 int ret = 0;
655 UCX_FOREACH(elm, resources) { 675 UCX_FOREACH(elm, resources) {
656 LocalResource *local_res = elm->data; 676 LocalResource *local_res = elm->data;
657 if (!res_matches_filter(dir, local_res->path+1)) { 677 if (!res_matches_filter(dir, local_res->path+1)) {
678 if(res_isconflict(db, local_res)) {
679 printf("skip: %s\n", local_res->path);
680 sync_skipped++;
681 continue;
682 }
683
658 // upload every changed file 684 // upload every changed file
659 if (local_resource_is_changed(dir, db, local_res)) { 685 if (local_resource_is_changed(dir, db, local_res)) {
660 DavResource *res = dav_resource_new(sn, local_res->path); 686 DavResource *res = dav_resource_new(sn, local_res->path);
661 if(!res) { 687 if(!res) {
662 print_resource_error(sn, local_res->path); 688 print_resource_error(sn, local_res->path);
720 // TODO: free res 746 // TODO: free res
721 747
722 // Report 748 // Report
723 char *str_success = sync_success == 1 ? "file" : "files"; 749 char *str_success = sync_success == 1 ? "file" : "files";
724 char *str_delete = sync_delete == 1 ? "file" : "files"; 750 char *str_delete = sync_delete == 1 ? "file" : "files";
751 char *str_skipped = sync_delete == 1 ? "file" : "files";
725 char *str_error = sync_error == 1 ? "error" : "errors"; 752 char *str_error = sync_error == 1 ? "error" : "errors";
726 printf("Result: %d %s pushed, %d %s deleted, %d %s\n", 753 printf("Result: %d %s pushed, %d %s deleted, %d %s skipped, %d %s\n",
727 sync_success, str_success, 754 sync_success, str_success,
728 sync_delete,str_delete, 755 sync_delete,str_delete,
756 sync_skipped,str_skipped,
729 sync_error, str_error); 757 sync_error, str_error);
730 758
731 return 0; 759 return 0;
732 } 760 }
733 761
813 } 841 }
814 } else if(!sstrcmp(name, S("remove"))) { 842 } else if(!sstrcmp(name, S("remove"))) {
815 LocalResource *res = calloc(1, sizeof(LocalResource)); 843 LocalResource *res = calloc(1, sizeof(LocalResource));
816 res->path = sstrdup(value).ptr; 844 res->path = sstrdup(value).ptr;
817 if(res) { 845 if(res) {
818 ucx_map_sstr_put(db->remove, value, res); 846 //ucx_map_sstr_put(db->remove, value, res);
819 ucx_map_sstr_remove(db->resources, value); 847 ucx_map_sstr_remove(db->resources, value);
820 } 848 }
821 849
822 } 850 }
823 851

mercurial