dav/main.c

changeset 334
5f80c5d0e87f
parent 333
000cdd124115
child 338
c7f3fe4abdb2
equal deleted inserted replaced
333:000cdd124115 334:5f80c5d0e87f
155 return ret; 155 return ret;
156 } 156 }
157 157
158 static char *cmdusageinfo[] = { 158 static char *cmdusageinfo[] = {
159 "list [-altdepcR] [-u <date>] <url>", 159 "list [-altdepcR] [-u <date>] <url>",
160 "get [-pcRK] [-o <file>] [-u <date>] <url>", 160 "get [-pcRKA] [-o <file>] [-u <date>] <url>",
161 "put [-pcR] [-k <key>] [-L <lock>] <url> <file>", 161 "put [-pcRA] [-k <key>] [-L <lock>] <url> <file>",
162 "mkdir [-pc] [-k <key>] [-L <lock>] <url>", 162 "mkdir [-pc] [-k <key>] [-L <lock>] <url>",
163 "remove [-pc] [-L <lock>] <url>", 163 "remove [-pc] [-L <lock>] <url>",
164 "copy [-pcO] [-L <lock>] <url> <url>", 164 "copy [-pcO] [-L <lock>] <url> <url>",
165 "move [-pcO] [-L <lock>] <url> <url>", 165 "move [-pcO] [-L <lock>] <url> <url>",
166 "get-property [-pc] [-n <uri>] <url> <property>", 166 "get-property [-pc] [-n <uri>] <url> <property>",
216 fprintf(stderr, " -l print resources in long list format\n"); 216 fprintf(stderr, " -l print resources in long list format\n");
217 fprintf(stderr, " -t print content type\n"); 217 fprintf(stderr, " -t print content type\n");
218 fprintf(stderr, " -d order by last modified date\n"); 218 fprintf(stderr, " -d order by last modified date\n");
219 fprintf(stderr, " -e show extended flags\n"); 219 fprintf(stderr, " -e show extended flags\n");
220 fprintf(stderr, " -O override resources\n"); 220 fprintf(stderr, " -O override resources\n");
221 fprintf(stderr, " -A tar import/export\n");
221 fprintf(stderr, " -L <lock> specificy lock token\n"); 222 fprintf(stderr, " -L <lock> specificy lock token\n");
222 fprintf(stderr, " -T <sec> timeout in seconds\n"); 223 fprintf(stderr, " -T <sec> timeout in seconds\n");
223 fprintf(stderr, " -n <uri> specify namespace uri\n"); 224 fprintf(stderr, " -n <uri> specify namespace uri\n");
224 fprintf(stderr, " -N disable authentication prompt (all commands)\n"); 225 fprintf(stderr, " -N disable authentication prompt (all commands)\n");
225 fprintf(stderr, " -i disable cert verification (all commands)\n"); 226 fprintf(stderr, " -i disable cert verification (all commands)\n");
715 /* 716 /*
716 * determine the output file 717 * determine the output file
717 * use stdout if the output file is - 718 * use stdout if the output file is -
718 */ 719 */
719 char *outfile = cmd_getoption(a, "output"); 720 char *outfile = cmd_getoption(a, "output");
721 char *basepath = outfile;
722 char *tar = cmd_getoption(a, "tar");
720 if(!outfile) { 723 if(!outfile) {
721 if(res->iscollection) { 724 if(res->iscollection) {
722 outfile = ""; 725 basepath = "";
723 } else { 726 } else {
724 outfile = res->name; 727 basepath = res->name;
725 } 728 }
729 if(tar) {
730 outfile = "-";
731 }
732 } else if(tar) {
733 basepath = "";
726 } else if(res->iscollection && !strcmp(outfile, "-")) { 734 } else if(res->iscollection && !strcmp(outfile, "-")) {
727 fprintf( 735 fprintf(
728 stderr, 736 stderr,
729 "Cannot write output to stdout " 737 "Cannot write output to stdout "
730 "if the requested resource is a collection.\n"); 738 "if the requested resource is a collection.\n");
736 uint64_t totalsize = 0; 744 uint64_t totalsize = 0;
737 uint64_t rescount = 0; 745 uint64_t rescount = 0;
738 746
739 GetResource *getres = malloc(sizeof(GetResource)); 747 GetResource *getres = malloc(sizeof(GetResource));
740 getres->res = res; 748 getres->res = res;
741 getres->path = strdup(outfile); 749 getres->path = strdup(basepath);
742 750
743 char *structure = cmd_getoption(a, "structure"); 751 char *structure = cmd_getoption(a, "structure");
744 752
745 // iterate over resource tree 753 // iterate over resource tree
746 UcxList *stack = ucx_list_prepend(NULL, getres); 754 UcxList *stack = ucx_list_prepend(NULL, getres);
754 // add resource to stack 762 // add resource to stack
755 size_t pathlen = strlen(g->path); 763 size_t pathlen = strlen(g->path);
756 GetResource *newres = malloc(sizeof(GetResource)); 764 GetResource *newres = malloc(sizeof(GetResource));
757 newres->res = child; 765 newres->res = child;
758 newres->path = pathlen > 0 ? 766 newres->path = pathlen > 0 ?
759 util_concat_path(g->path, child->name) : child->name; 767 util_concat_path(g->path, child->name) : strdup(child->name);
760 768
761 stack = ucx_list_prepend(stack, newres); 769 stack = ucx_list_prepend(stack, newres);
762 770
763 child = child->next; 771 child = child->next;
764 } 772 }
777 } else { 785 } else {
778 reslist = ucx_list_append(reslist, g); 786 reslist = ucx_list_append(reslist, g);
779 } 787 }
780 } 788 }
781 789
790 // download resources
782 int ret; 791 int ret;
792 getfunc get;
793 TarOutputStream *tout = NULL;
794 if(tar) {
795 get = (getfunc)resource2tar;
796 FILE *tarfile = strcmp(outfile, "-") ? fopen(outfile, "wb") : stdout;
797 if(!tarfile) {
798 perror("Cannot open tar output file");
799 return -1;
800 }
801 tout = tar_open(tarfile);
802 } else {
803 get = get_resource;
804 }
783 UCX_FOREACH(elm, reslist) { 805 UCX_FOREACH(elm, reslist) {
784 GetResource *getres = elm->data; 806 GetResource *getres = elm->data;
785 807
786 ret = get_resource(repo, getres->res, a, getres->path); 808 ret = get(repo, getres, a, tout);
787 if(ret) { 809 if(ret) {
788 break; 810 break;
811 }
812 }
813 if(tar) {
814 // close tar stream
815 if(tar_close(tout)) {
816 fprintf(stderr, "tar stream broken\n");
817 ret = -1;
789 } 818 }
790 } 819 }
791 820
792 ucx_list_free_content(reslist, free_getres); 821 ucx_list_free_content(reslist, free_getres);
793 ucx_list_free(reslist); 822 ucx_list_free(reslist);
794 free(path); 823 free(path);
795 824
796 return ret; 825 return ret;
797 } 826 }
798 827
799 int get_resource(Repository *repo, DavResource *res, CmdArgs *a, char *out) { 828 int get_resource(Repository *repo, GetResource *getres, CmdArgs *a, void *unused) {
800 size_t outlen = strlen(out); 829 DavResource *res = getres->res;
830 char *out = res->path;
801 831
802 if(res->iscollection) { 832 if(res->iscollection) {
803 printf("get: %s\n", res->path); 833 printf("get: %s\n", res->path);
804 834
805 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 835 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
849 } 879 }
850 880
851 return 0; 881 return 0;
852 } 882 }
853 883
884 #define DEFAULT_DIR_MODE T_IRUSR | T_IWUSR | T_IXUSR | T_IRGRP | T_IXGRP | T_IROTH | T_IXOTH
885 #define DEFAULT_FILE_MODE T_IRUSR | T_IWUSR | T_IRGRP | T_IROTH
886
887 int resource2tar(Repository *repo, GetResource *res, CmdArgs *a, TarOutputStream *tar) {
888 DavResource *d = res->res;
889
890 if(d->iscollection) {
891 fprintf(stderr, "add d: %s\n", res->path);
892 return tar_add_dir(tar, res->path, DEFAULT_DIR_MODE, d->lastmodified);
893 }
894
895 fprintf(stderr, "add f: %s\n", res->path);
896
897 // add tar file header
898 if(tar_begin_file(tar, res->path, DEFAULT_FILE_MODE, d->contentlength, d->lastmodified)) {
899 fprintf(stderr, "TAR Error: %s\n", tar_error2str(tar->error));
900 return -1;
901 }
902
903 if(dav_get_content(d, tar, (dav_write_func)tar_fwrite)) {
904 print_resource_error(d->session, d->path);
905 return -1;
906 }
907
908 // download content
909
910 return tar_end_file(tar);
911 }
912
854 int cmd_put(CmdArgs *a) { 913 int cmd_put(CmdArgs *a) {
855 if(a->argc != 2) { 914 if(a->argc != 2) {
856 // TODO: change, when put supports multiple files (however it should do) 915 // TODO: change, when put supports multiple files (however it should do)
857 fprintf(stderr, "Too %s arguments\n", a->argc < 2 ? "few":"many"); 916 fprintf(stderr, "Too %s arguments\n", a->argc < 2 ? "few":"many");
858 fprintf(stderr, "Usage: dav %s\n", find_usage_str("put")); 917 fprintf(stderr, "Usage: dav %s\n", find_usage_str("put"));
881 // TODO: free 940 // TODO: free
882 return -1; 941 return -1;
883 } 942 }
884 } 943 }
885 944
945 char *tar = cmd_getoption(a, "tar");
886 int ret; 946 int ret;
887 if(!strcmp(file, "-")) { 947 if(!tar) {
888 FILE *in = stdin; 948 if(!strcmp(file, "-")) {
889 ret = put_file(repo, a, sn, path, "stdin", in, 0); 949 FILE *in = stdin;
950 ret = put_file(repo, a, sn, path, "stdin", in, 0);
951 } else {
952 ret = put_entry(repo, a, sn, path, file, TRUE);
953 }
890 } else { 954 } else {
891 ret = put_entry(repo, a, sn, path, file, TRUE); 955 ret = put_tar(repo, a, sn, file, path);
892 } 956 }
893 957
894 free(path); 958 free(path);
895 return ret; 959 return ret;
896 } 960 }
969 } 1033 }
970 char *filename = util_resource_name(file); 1034 char *filename = util_resource_name(file);
971 //path = util_concat_path(path, filename); 1035 //path = util_concat_path(path, filename);
972 ret = put_file(repo, a, sn, path, filename, in, s.st_size); 1036 ret = put_file(repo, a, sn, path, filename, in, s.st_size);
973 //free(path); 1037 //free(path);
1038 fclose(in);
1039 }
1040
1041 return ret;
1042 }
1043
1044 int put_tar(Repository *repo, CmdArgs *a, DavSession *sn, char *tarfile, char *path) {
1045 int isstdin = !strcmp(tarfile, "-");
1046 FILE *in = isstdin ? stdin : fopen(tarfile, "rb");
1047 if(!in) {
1048 perror("Cannot open tar file");
1049 return -1;
1050 }
1051
1052 DavResource *col = NULL;
1053 for(int i=0;i<2;i++) {
1054 col = dav_query(sn, "select - from %s", path);
1055 if(!col && sn->error == DAV_UNAUTHORIZED) {
1056 if(request_auth(repo, sn, a)) {
1057 continue;
1058 }
1059 }
1060 break;
1061 }
1062 if(!col) {
1063 if(sn->error == DAV_NOT_FOUND) {
1064 col = dav_resource_new(sn, path);
1065 col->iscollection = TRUE;
1066 if(dav_create(col)) {
1067 print_resource_error(sn, path);
1068 return -1;
1069 }
1070 } else {
1071 print_resource_error(sn, path);
1072 return -1;
1073 }
1074 } else if(!col->iscollection) {
1075 fprintf(stderr, "%s is not a collection\n", col->href);
1076 return -1;
1077 }
1078
1079
1080 int ret = 0;
1081 TarInputStream *tar = tar_inputstream_open(in);
1082 TarEntry *e = NULL;
1083 while((e = tar_read_entry(tar)) != NULL) {
1084 char *newpath = util_concat_path(path, e->path);
1085 if(e->type == TAR_TYPE_FILE) {
1086 fprintf(stderr, "put: %s\n", e->path);
1087 DavResource *res = dav_resource_new(sn, newpath);
1088 dav_set_content(res, tar, (dav_read_func)tar_fread);
1089 dav_set_content_length(res, (size_t)e->size);
1090
1091 if(dav_store(res)) {
1092 print_resource_error(sn, res->path);
1093 fprintf(stderr, "Cannot upload file.\n");
1094 if(sn->errorstr) {
1095 fprintf(stderr, "%s\n", sn->errorstr);
1096 }
1097 return -1;
1098 }
1099
1100 } else if(e->type == TAR_TYPE_DIRECTORY) {
1101 printf("mkcol: %s\n", e->path);
1102 DavResource *res = dav_resource_new(sn, newpath);
1103 res->iscollection = TRUE;
1104 if(!dav_exists(res)) {
1105 if(dav_create(res)) {
1106 fprintf(stderr, "Cannot create collection %s\n", newpath);
1107 print_resource_error(sn, res->path);
1108 ret = 1;
1109 free(newpath);
1110 break;
1111 }
1112 }
1113 } else {
1114 fprintf(stderr, "skip: %s\n", e->path);
1115 }
1116 free(newpath);
1117 }
1118 if(tar->error != TAR_OK) {
1119 ret = -1;
1120 }
1121
1122 if(!isstdin) {
974 fclose(in); 1123 fclose(in);
975 } 1124 }
976 1125
977 return ret; 1126 return ret;
978 } 1127 }

mercurial