65 |
70 |
66 void print_usage() { |
71 void print_usage() { |
67 |
72 |
68 } |
73 } |
69 |
74 |
70 void get_file(CURL *curl, char *url, char *path) { |
75 void url_get_parts(char *url, char **root, char **path) { |
71 curl_easy_setopt(curl, CURLOPT_URL, url); |
76 size_t ulen = strlen(url); |
72 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); |
77 *root = NULL; |
73 |
78 *path = NULL; |
74 FILE *out = fopen(path, "w"); |
79 |
75 |
80 int s; |
76 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); |
81 if(ulen > 7 && !strncmp(url, "http://", 7)) { |
77 curl_easy_setopt(curl, CURLOPT_WRITEDATA, out); |
82 s = 7; |
78 |
83 } else if(ulen > 8 && !strncmp(url, "https://", 8)) { |
79 CURLcode res = curl_easy_perform(curl); |
84 s = 8; |
80 |
85 } else { |
81 fclose(out); |
86 s = 1; |
82 // handle some errors (http://curl.haxx.se/libcurl/c/libcurl-errors.html) |
87 } |
83 switch(res) { |
88 |
84 case CURLE_OK: { |
89 for(int i=s;i<ulen;i++) { |
|
90 char c = url[i]; |
|
91 if(c == '/') { |
|
92 sstr_t r = sstrn(url, i); |
|
93 sstr_t p = sstrsubs(sstr(url), i); |
|
94 if(p.length == 0) { |
|
95 p = sstrn("/", 1); |
|
96 } |
|
97 *root = sstrdup(r).ptr; |
|
98 *path = sstrdup(p).ptr; |
85 return; |
99 return; |
86 } |
100 } |
87 case CURLE_REMOTE_ACCESS_DENIED: { |
101 } |
88 |
102 |
89 break; |
103 *root = strdup(url); |
90 } |
104 *path = strdup("/"); |
91 case CURLE_SSL_CONNECT_ERROR: { |
105 } |
92 |
106 |
93 break; |
|
94 } |
|
95 case CURLE_LOGIN_DENIED: { |
|
96 |
|
97 break; |
|
98 } |
|
99 case CURLE_REMOTE_FILE_NOT_FOUND: { |
|
100 |
|
101 break; |
|
102 } |
|
103 default: { |
|
104 |
|
105 break; |
|
106 } |
|
107 } |
|
108 |
|
109 unlink(path); |
|
110 } |
|
111 |
|
112 void put_file(CURL *curl, char *url, char *path) { |
|
113 curl_easy_setopt(curl, CURLOPT_URL, url); |
|
114 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); |
|
115 |
|
116 curl_easy_setopt(curl, CURLOPT_PUT, 1L); |
|
117 |
|
118 struct stat s; |
|
119 if(stat(path, &s) != 0) { |
|
120 perror("stat"); |
|
121 fprintf(stderr, "file: %s\n", path); |
|
122 return; |
|
123 } |
|
124 |
|
125 FILE *in = fopen(path, "r"); |
|
126 |
|
127 curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); |
|
128 curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread); |
|
129 curl_easy_setopt(curl, CURLOPT_READDATA, in); |
|
130 curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)s.st_size); |
|
131 |
|
132 CURLcode res = curl_easy_perform(curl); |
|
133 fclose(in); |
|
134 |
|
135 if(res != CURLE_OK) { |
|
136 fprintf(stderr, "put_file: %s\n", curl_easy_strerror(res)); |
|
137 } |
|
138 } |
|
139 |
107 |
140 int cmd_list(int argc, char **argv) { |
108 int cmd_list(int argc, char **argv) { |
141 if(argc == 0) { |
109 if(argc == 0) { |
142 return -1; |
110 return -1; |
143 } |
111 } |
144 |
112 |
145 char *url = argv[0]; // TODO: use arg as url or alias |
113 |
146 |
114 DavContext *ctx = dav_context_new(); |
147 CURL *curl = curl_easy_init(); |
115 DavSession *sn = NULL; |
148 curl_easy_setopt(curl, CURLOPT_URL, url); |
116 char *url = argv[0]; |
149 Propfind *propfind = dav_propfind(curl); |
117 char *root = NULL; |
150 |
118 char *path = NULL; |
151 UCX_FOREACH(UcxDlist*, propfind->children, ch) { |
119 url_get_parts(url, &root, &path); |
152 DavResource *resource = ch->data; |
120 |
153 printf("%s\n", resource->name); |
121 Repository *repo = get_repository(root); |
154 } |
122 if(repo) { |
155 |
123 sn = dav_session_new_auth(ctx, repo->url, repo->user, repo->password); |
156 // TODO: free propfind stuff |
124 } else { |
157 curl_easy_cleanup(curl); |
125 sn = dav_session_new(ctx, root); |
|
126 } |
|
127 |
|
128 //printf("baseurl: %s\n", sn->base_url); |
|
129 |
|
130 DavResource *ls = dav_get(sn, path, NULL); |
|
131 if(!ls) { |
|
132 fprintf(stderr, "error\n"); |
|
133 return -1; |
|
134 } |
|
135 DavResource *child = ls->children; |
|
136 while(child) { |
|
137 printf("%s\n", child->name); |
|
138 child = child->next; |
|
139 } |
158 |
140 |
159 return 0; |
141 return 0; |
160 } |
142 } |
161 |
143 |
162 int cmd_get(int argc, char **argv) { |
144 int cmd_get(int argc, char **argv) { |
163 if(argc == 0) { |
145 if(argc == 0) { |
164 return -1; |
146 return -1; |
165 } |
147 } |
166 |
148 |
167 char *url = argv[0]; // TODO: use arg as url or alias |
149 DavContext *ctx = dav_context_new(); |
168 |
150 dav_add_namespace(ctx, "U", "http://www.uap-core.de/"); |
169 CURL *curl = curl_easy_init(); |
151 DavSession *sn = NULL; |
170 curl_easy_setopt(curl, CURLOPT_URL, url); |
152 char *url = argv[0]; |
171 Propfind *propfind = dav_propfind(curl); |
153 char *root = NULL; |
172 |
154 char *path = NULL; |
173 if(propfind->resource->collection) { |
155 url_get_parts(url, &root, &path); |
174 UCX_FOREACH(UcxDlist*, propfind->children, chd) { |
156 |
175 DavResource *resource = chd->data; |
157 Repository *repo = get_repository(root); |
176 if(!resource->collection) { |
158 if(repo) { |
177 char *resurl = util_child_url(propfind->url, resource->href); |
159 sn = dav_session_new_auth(ctx, repo->url, repo->user, repo->password); |
178 get_file(curl, resurl, resource->name); |
160 } else { |
179 } |
161 sn = dav_session_new(ctx, root); |
|
162 } |
|
163 |
|
164 DavResource *res = dav_get(sn, path, "U:crypto-key"); |
|
165 if(!res) { |
|
166 fprintf(stderr, "error\n"); |
|
167 return -1; |
|
168 } |
|
169 FILE *out = fopen(res->name, "w"); |
|
170 if(!out) { |
|
171 fprintf(stderr, "cannot open output file\n"); |
|
172 return -1; |
|
173 } |
|
174 |
|
175 AESDecrypter *dec = NULL; |
|
176 char *keyprop = dav_get_property_ns(res, "http://www.uap-core.de/", "crypto-key"); |
|
177 if(repo) { |
|
178 Key *key = get_key(keyprop); |
|
179 if(repo->encrypt && key) { |
|
180 dec = aes_decrypter_new(key, out, (dav_write_func)fwrite); |
180 } |
181 } |
181 } else { |
182 } |
182 get_file(curl, propfind->url, propfind->resource->name); |
183 |
183 } |
184 int ret; |
184 |
185 if(dec && keyprop) { |
185 // TODO: free propfind stuff |
186 ret = dav_get_content(res, dec, (dav_write_func)aes_write); |
186 curl_easy_cleanup(curl); |
187 } else { |
|
188 ret = dav_get_content(res, out, (dav_write_func)fwrite); |
|
189 } |
|
190 if(dec) { |
|
191 aes_decrypter_close(dec); |
|
192 } |
|
193 fclose(out); |
|
194 if(ret) { |
|
195 unlink(res->name); |
|
196 } |
187 |
197 |
188 return 0; |
198 return 0; |
189 } |
199 } |
190 |
200 |
191 int cmd_put(int argc, char **argv) { |
201 int cmd_put(int argc, char **argv) { |
192 if(argc == 0) { |
202 if(argc < 2) { |
193 return -1; |
203 return -1; |
194 } |
204 } |
195 |
205 |
196 char *url = argv[0]; // TODO: use arg as url or alias |
206 DavContext *ctx = dav_context_new(); |
197 char *path; |
207 DavSession *sn = NULL; |
198 if(argc > 0) { |
208 char *url = argv[0]; |
199 path = argv[1]; |
209 char *file = argv[1]; |
200 } else { |
210 char *root = NULL; |
201 fprintf(stderr, "put: missing file argument\n"); |
211 char *path = NULL; |
202 return -1; |
212 url_get_parts(url, &root, &path); |
203 } |
213 |
204 |
214 Repository *repo = get_repository(root); |
205 char *uploadurl = util_upload_url(url, path); |
215 if(repo) { |
206 |
216 sn = dav_session_new_auth(ctx, repo->url, repo->user, repo->password); |
207 CURL *curl = curl_easy_init(); |
217 } else { |
208 |
218 sn = dav_session_new(ctx, root); |
209 // TODO: check possible name conflicts |
219 } |
210 |
220 |
211 put_file(curl, uploadurl, path); |
221 DavResource *res = dav_resource_new(sn, path); |
212 |
222 if(!res) { |
213 curl_easy_cleanup(curl); |
223 fprintf(stderr, "error\n"); |
214 } |
224 return -1; |
|
225 } |
|
226 FILE *in = fopen(file, "r"); |
|
227 if(!in) { |
|
228 fprintf(stderr, "cannot open input file\n"); |
|
229 return -1; |
|
230 } |
|
231 AESEncrypter *enc = NULL; |
|
232 if(repo) { |
|
233 Key *key = get_key(repo->default_key); |
|
234 if(repo->encrypt && key) { |
|
235 enc = aes_encrypter_new(key, in, (dav_read_func)fread); |
|
236 } |
|
237 } |
|
238 if(enc) { |
|
239 dav_set_content(res, enc, (dav_read_func)aes_read); |
|
240 dav_set_property_ns(res, "http://www.uap-core.de/", "crypto-key", repo->default_key); |
|
241 } else { |
|
242 dav_set_content(res, in, (dav_read_func)fread); |
|
243 } |
|
244 |
|
245 if(dav_store(res)) { |
|
246 fprintf(stderr, "cannot upload file\n"); |
|
247 fclose(in); |
|
248 return -1; |
|
249 } |
|
250 fclose(in); |
|
251 return 0; |
|
252 } |