723 "Cannot write output to stdout " |
729 "Cannot write output to stdout " |
724 "if the requested resource is a collection.\n"); |
730 "if the requested resource is a collection.\n"); |
725 return -1; |
731 return -1; |
726 } |
732 } |
727 |
733 |
728 int ret = get_resource(repo, res, a, outfile); |
734 // get list of resources |
729 |
735 UcxList *reslist = NULL; |
|
736 uint64_t totalsize = 0; |
|
737 uint64_t rescount = 0; |
|
738 |
|
739 GetResource *getres = malloc(sizeof(GetResource)); |
|
740 getres->res = res; |
|
741 getres->path = strdup(outfile); |
|
742 |
|
743 char *structure = cmd_getoption(a, "structure"); |
|
744 |
|
745 // iterate over resource tree |
|
746 UcxList *stack = ucx_list_prepend(NULL, getres); |
|
747 while(stack) { |
|
748 GetResource *g = stack->data; |
|
749 stack = ucx_list_remove(stack, stack); |
|
750 |
|
751 if(g->res->iscollection) { |
|
752 DavResource *child = g->res->children; |
|
753 while(child) { |
|
754 // add resource to stack |
|
755 size_t pathlen = strlen(g->path); |
|
756 GetResource *newres = malloc(sizeof(GetResource)); |
|
757 newres->res = child; |
|
758 newres->path = pathlen > 0 ? |
|
759 util_concat_path(g->path, child->name) : child->name; |
|
760 |
|
761 stack = ucx_list_prepend(stack, newres); |
|
762 |
|
763 child = child->next; |
|
764 } |
|
765 } else { |
|
766 if(structure) { |
|
767 // download only directory structure |
|
768 // this is a hidden feature and will be replaced in the future |
|
769 continue; // skip non-collection resource |
|
770 } |
|
771 totalsize += g->res->contentlength; |
|
772 rescount++; |
|
773 } |
|
774 |
|
775 if(strlen(g->path) == 0) { |
|
776 free_getres(g); |
|
777 } else { |
|
778 reslist = ucx_list_append(reslist, g); |
|
779 } |
|
780 } |
|
781 |
|
782 int ret; |
|
783 UCX_FOREACH(elm, reslist) { |
|
784 GetResource *getres = elm->data; |
|
785 |
|
786 ret = get_resource(repo, getres->res, a, getres->path); |
|
787 if(ret) { |
|
788 break; |
|
789 } |
|
790 } |
|
791 |
|
792 ucx_list_free_content(reslist, free_getres); |
|
793 ucx_list_free(reslist); |
730 free(path); |
794 free(path); |
|
795 |
731 return ret; |
796 return ret; |
732 } |
797 } |
733 |
798 |
734 int get_resource(Repository *repo, DavResource *res, CmdArgs *a, char *out) { |
799 int get_resource(Repository *repo, DavResource *res, CmdArgs *a, char *out) { |
735 size_t outlen = strlen(out); |
800 size_t outlen = strlen(out); |
736 |
801 |
737 if(res->iscollection) { |
802 if(res->iscollection) { |
738 printf("get: %s\n", res->path); |
803 printf("get: %s\n", res->path); |
739 |
804 |
740 // create directory |
805 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; |
741 if(outlen != 0) { |
806 int ret = util_mkdir(out, mode); |
742 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; |
807 if(ret != 0 && errno != EEXIST) { |
743 int ret = util_mkdir(out, mode); |
808 fprintf(stderr, "Cannot create directory '%s': ", out); |
744 if(ret != 0 && errno != EEXIST) { |
809 perror(""); |
745 return 1; |
810 return 1; |
746 } |
|
747 } |
811 } |
748 |
812 |
749 DavResource *child = res->children; |
|
750 while(child) { |
|
751 char *newout = outlen > 0 ? |
|
752 util_concat_path(out, child->name) : child->name; |
|
753 int ret = get_resource(repo, child, a, newout); |
|
754 if(outlen > 0) { |
|
755 free(newout); |
|
756 } |
|
757 if(ret) { |
|
758 return 1; |
|
759 } |
|
760 child = child->next; |
|
761 } |
|
762 |
|
763 return 0; |
|
764 } else if(cmd_getoption(a, "structure")) { |
|
765 // download only directory structure |
|
766 // this is a hidden feature and will be replaced in the future |
|
767 return 0; |
813 return 0; |
768 } |
814 } |
769 |
815 |
770 int isstdout = !strcmp(out, "-"); |
816 int isstdout = !strcmp(out, "-"); |
771 if(cmd_getoption(a, "keep") && !isstdout) { |
817 if(cmd_getoption(a, "keep") && !isstdout) { |