dav/main.c

changeset 5
88625853ae74
parent 4
ae5a98f0545c
child 8
4503498deb22
equal deleted inserted replaced
4:ae5a98f0545c 5:88625853ae74
27 */ 27 */
28 28
29 #include <stdio.h> 29 #include <stdio.h>
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <string.h> 31 #include <string.h>
32 #include <errno.h>
32 #include <unistd.h> 33 #include <unistd.h>
33 #include <libxml/xmlerror.h> 34 #include <libxml/xmlerror.h>
34 #include <sys/types.h> 35 #include <sys/types.h>
35 #include <sys/stat.h> 36 #include <sys/stat.h>
36 37 #include <ucx/string.h>
37 #include "propfind.h" 38
39 #include "webdav.h"
38 #include "utils.h" 40 #include "utils.h"
41 #include "config.h"
42 #include "crypto.h"
39 #include "main.h" 43 #include "main.h"
40 44
41 void xmlerrorfnc(void * ctx, const char * msg, ... ) { 45 void xmlerrorfnc(void * ctx, const char * msg, ... ) {
42 // nothing 46 // nothing
43 } 47 }
44 48
45 int main(int argc, char **argv) { 49 int main(int argc, char **argv) {
46 xmlGenericErrorFunc fnc = xmlerrorfnc; 50 xmlGenericErrorFunc fnc = xmlerrorfnc;
47 initGenericErrorDefaultFunc(&fnc); 51 initGenericErrorDefaultFunc(&fnc);
52 load_config();
48 53
49 if(argc < 2) { 54 if(argc < 2) {
50 print_usage(); 55 print_usage();
51 return -1; 56 return -1;
52 } 57 }
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 }

mercurial