dav/sync.c

changeset 144
c2c02c9b3be4
parent 135
664aeaec8d25
child 145
82475dc12dd4
equal deleted inserted replaced
143:d8b01bed3d83 144:c2c02c9b3be4
180 if (cmd_getoption(a, "verbose")) { 180 if (cmd_getoption(a, "verbose")) {
181 curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L); 181 curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L);
182 curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr); 182 curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr);
183 } 183 }
184 184
185 DavResource *ls = dav_query(sn, "select D:getetag from / depth -1 where lastmodified > 0 with"); 185 DavResource *ls = dav_query(sn, "select D:getetag,idav:status from / with depth = infinity");
186 if(!ls) { 186 if(!ls) {
187 fprintf(stderr, "Error\n"); 187 fprintf(stderr, "Error\n");
188 // TODO: free 188 // TODO: free
189 return -1; 189 return -1;
190 } 190 }
201 DavResource *res = stack->data; 201 DavResource *res = stack->data;
202 stack = ucx_list_remove(stack, stack); 202 stack = ucx_list_remove(stack, stack);
203 203
204 while(res) { 204 while(res) {
205 if (res_matches_filter(dir, res->path)) { 205 if (res_matches_filter(dir, res->path)) {
206 res = res->next;
207 continue;
208 }
209
210 char *status = dav_get_property(res, "idav:status");
211 if(status && !strcmp(status, "broken")) {
206 res = res->next; 212 res = res->next;
207 continue; 213 continue;
208 } 214 }
209 215
210 // download the resource 216 // download the resource
663 } 669 }
664 return 1; 670 return 1;
665 } 671 }
666 672
667 673
674 int sync_set_status(DavResource *res, char *status) {
675 DavResource *resource = dav_resource_new(res->session, res->path);
676 dav_set_property(resource, "idav:status", status);
677 int ret = dav_store(resource);
678 dav_resource_free(resource);
679 return ret;
680 }
681
682 int sync_remove_status(DavResource *res) {
683 DavResource *resource = dav_resource_new(res->session, res->path);
684 dav_remove_property(resource, "idav:status");
685 int ret = dav_store(resource);
686 dav_resource_free(resource);
687 return ret;
688 }
689
668 int sync_put_resource(SyncDirectory *dir, DavResource *res, LocalResource *local) { 690 int sync_put_resource(SyncDirectory *dir, DavResource *res, LocalResource *local) {
669 char *local_path = util_concat_path(dir->path, res->path); 691 char *local_path = util_concat_path(dir->path, res->path);
692
693 struct stat s;
694 if(stat(local_path, &s)) {
695 fprintf(stderr, "cannot stat file: %s\n", local_path);
696 perror("");
697 free(local_path);
698 return -1;
699 }
700
670 FILE *in = fopen(local_path, "rb"); 701 FILE *in = fopen(local_path, "rb");
671 if(!in) { 702 if(!in) {
672 fprintf(stderr, "Cannot open file %s\n", local_path); 703 fprintf(stderr, "Cannot open file %s\n", local_path);
673 free(local_path); 704 free(local_path);
674 return -1; 705 return -1;
675 } 706 }
676 free(local_path);
677 707
678 dav_set_content(res, in, (dav_read_func)fread); 708 dav_set_content(res, in, (dav_read_func)fread);
679 709
680 int ret = -1; 710 int ret = -1;
681 for(;;) { 711 int created = 0;
682 if(dav_create(res)) { 712 for(int i=0;i<dir->max_retry;i++) {
683 break; 713 if(!created && dav_create(res)) {
684 } 714 continue;
715 }
716 created = 1;
685 if(dav_store(res)) { 717 if(dav_store(res)) {
686 break; 718 continue;
687 } 719 }
688 ret = 0; 720 ret = 0;
689 break; 721 break;
690 } 722 }
691 723
724
725
692 if(ret == 0) { 726 if(ret == 0) {
693 // get new etag 727 // check contentlength and get new etag
694 DavResource *up_res = dav_get(res->session, res->path, "D:getetag"); 728 DavResource *up_res = dav_get(res->session, res->path, "D:getetag");
695 char *etag = dav_get_property(up_res, "D:getetag"); 729
696 if(etag) { 730 if(up_res) {
697 if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') { 731 // the new content length must be equal or greater than the file size
698 etag = etag + 2; 732 if(up_res->contentlength < s.st_size) {
699 } 733 fprintf(stderr, "Incomplete Upload: %s", local_path);
700 } 734 ret = -1;
701 735 // try to set the resource status to 'broken'
702 if(local->etag) { 736 sync_set_status(res, "broken");
703 free(local->etag); 737 } else {
704 } 738 // everything seems fine, we can update the local resource
705 739 char *etag = dav_get_property(up_res, "D:getetag");
706 if(etag) { 740 if(etag) {
707 local->etag = strdup(etag); 741 if(strlen(etag) > 2 && etag[0] == 'W' && etag[1] == '/') {
708 } else { 742 etag = etag + 2;
709 local->etag = NULL; 743 }
710 } 744 }
711 dav_resource_free(up_res); 745
746 if(local->etag) {
747 free(local->etag);
748 }
749
750 if(etag) {
751 local->etag = strdup(etag);
752 } else {
753 local->etag = NULL;
754 }
755 dav_resource_free(up_res);
756
757 sync_remove_status(res);
758 }
759 }
760 } else {
761 ret = -1;
762 sync_set_status(res, "broken");
712 } 763 }
713 764
714 fclose(in); 765 fclose(in);
766 free(local_path);
715 767
716 return ret; 768 return ret;
717 } 769 }
718 770
719 int sync_delete_remote_resource(DavSession *sn, LocalResource *local_res) { 771 int sync_delete_remote_resource(DavSession *sn, LocalResource *local_res) {

mercurial