1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <time.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <ucx/string.h>
34 #include <ucx/buffer.h>
35 #include <ucx/utils.h>
36 #include <libxml/tree.h>
37 #include <curl\
38 /curl.h>
39
40 #include <openssl/sha.h>
41 #include <openssl/hmac.h>
42 #include <openssl/evp.h>
43 #include <openssl/bio.h>
44 #include <openssl/buffer.h>
45 #include <openssl/rand.h>
46
47 #include "utils.h"
48 #include "crypto.h"
49 #include "webdav.h"
50
51 #define MACRO1337 1337L
52
53 static const char* continuation_test =
"this is a string\
54 with a continuation";
55
56
57
58
59
60
61
62
63
64
65
66
67 time_t util_parse_lastmodified(
char *str) {
68
69 if(!str) {
70 return 0;
71 }
else {
72 return curl_getdate(str,
NULL);
73 }
74 }
75
76 int util_getboolean(
char *v) {
77 if(v[
0] ==
'T' || v[
0] ==
't') {
78 return 1;
79 }
80 return 0;
81 }
82
83 int util_strtoint(
char *str,
int64_t *value) {
84 char *end;
85 int64_t val = strtoll(str, &end,
0);
86 if(strlen(end) ==
0) {
87 *value = val;
88 return 1;
89 }
else {
90 return 0;
91 }
92 }
93
94 char* util_url_path(
char *url) {
95 char *path =
NULL;
96 size_t len = strlen(url);
97 int slashcount =
0;
98 int slmax;
99 if(len >
7 && !strncasecmp(url,
"http://",
7)) {
100 slmax =
3;
101 }
else if(len >
8 && !strncasecmp(url,
"https://",
8)) {
102 slmax =
3;
103 }
else {
104 slmax =
1;
105 }
106 char c;
107 for(
int i=
0;i<len;i++) {
108 c = url[i];
109 if(c ==
'/') {
110 slashcount++;
111 if(slashcount == slmax) {
112 path = url + i;
113 break;
114 }
115 }
116 }
117 return path;
118 }
119
120 char* util_url_decode(DavSession *sn,
char *url) {
121 char *unesc = curl_easy_unescape(sn->handle, url, strlen(url),
NULL);
122 char *ret = strdup(unesc);
123 curl_free(unesc);
124 return ret;
125 }
126
127 char* util_resource_name(
char *url) {
128 int si =
0;
129 int osi =
0;
130 int i =
0;
131 int p =
0;
132 char c;
133 while((c = url[i]) !=
0) {
134 if(c ==
'/') {
135 osi = si;
136 si = i;
137 p =
1;
138 }
139 i++;
140 }
141
142 char *name = url + si + p;
143 if(name[
0] ==
0) {
144 name = url + osi + p;
145 if(name[
0] ==
0) {
146 return url;
147 }
148 }
149
150 return name;
151 }
152
153 int util_mkdir(
char *path,
mode_t mode) {
154 #ifdef _WIN32
155 return mkdir(path);
156 #else
157 return mkdir(path, mode);
158 #endif
159 }
160
161 char* util_concat_path(
char *url_base,
char *p) {
162 sstr_t base = sstr(url_base);
163 sstr_t path;
164 if(p) {
165 path = sstr(p);
166 }
else {
167 path = sstrn(
"",
0);
168 }
169
170 int add_separator =
0;
171 if(base.ptr[base.length-
1] ==
'/') {
172 if(path.ptr[
0] ==
'/') {
173 base.length--;
174 }
175 }
else {
176 if(path.length ==
0 || path.ptr[
0] !=
'/') {
177 add_separator =
1;
178 }
179 }
180
181 sstr_t url;
182 if(add_separator) {
183 url = sstrcat(
3, base, sstr(
"/"), path);
184 }
else {
185 url = sstrcat(
2, base, path);
186 }
187
188 return url.ptr;
189 }
190
191 void util_set_url(DavSession *sn,
char *href) {
192 sstr_t base = sstr(sn->base_url);
193 sstr_t href_str = sstr(href);
194
195 char *base_path = util_url_path(sn->base_url);
196 base.length -= strlen(base_path);
197
198 sstr_t url = sstrcat(
2, base, href_str);
199
200 curl_easy_setopt(sn->handle,
CURLOPT_URL, url.ptr);
201 free(url.ptr);
202 }
203
204 char* util_path_to_url(DavSession *sn,
char *path) {
205 char *space = malloc(
256);
206 UcxBuffer *url = ucx_buffer_new(space,
256,
CX_BUFFER_AUTO_EXTEND);
207
208
209 ucx_buffer_write(sn->base_url,
1, strlen(sn->base_url), url);
210
211 ucx_buffer_seek(url, -
1,
SEEK_CUR);
212
213 sstr_t p = sstr(path);
214 ssize_t ntk =
0;
215 sstr_t *tks = sstrsplit(p,
S(
"/"), &ntk);
216
217 for(
int i=
0;i<ntk;i++) {
218 sstr_t node = tks[i];
219 if(node.length >
0) {
220 char *esc = curl_easy_escape(sn->handle, node.ptr, node.length);
221 ucx_buffer_putc(url,
'/');
222 ucx_buffer_write(esc,
1, strlen(esc), url);
223 curl_free(esc);
224 }
225 free(node.ptr);
226 }
227 free(tks);
228 if(path[p.length-
1] ==
'/') {
229 ucx_buffer_putc(url,
'/');
230 }
231 ucx_buffer_putc(url,
0);
232
233 space = url->space;
234 ucx_buffer_free(url);
235
236 return space;
237 }
238
239 char* util_parent_path(
char *path) {
240 char *name = util_resource_name(path);
241 size_t namelen = strlen(name);
242 size_t pathlen = strlen(path);
243 size_t parentlen = pathlen - namelen;
244 char *parent = malloc(parentlen +
1);
245 memcpy(parent, path, parentlen);
246 parent[parentlen] =
'\0';
247 return parent;
248 }
249
250
251 char* util_xml_get_text(xmlNode *elm) {
252 xmlNode *node = elm->children;
253 while(node) {
254 if(node->type ==
XML_TEXT_NODE) {
255 return (
char*)node->content;
256 }
257 node = node->next;
258 }
259 return NULL;
260 }
261
262
263 char* util_base64decode(
char *in) {
264 int len =
0;
265 return util_base64decode_len(in, &len);
266 }
267
268 char* util_base64decode_len(
char* in,
int *outlen) {
269 size_t len = strlen(in);
270 char *out = calloc(
1, len);
271
272 BIO* b = BIO_new_mem_buf(in, len);
273 BIO *d = BIO_new(BIO_f_base64());
274 BIO_set_flags(d,
BIO_FLAGS_BASE64_NO_NL);
275 b = BIO_push(d, b);
276
277 *outlen = BIO_read(b, out, len);
278 BIO_free_all(b);
279
280 return out;
281 }
282
283 char* util_base64encode(
char *in,
size_t len) {
284 BIO *b;
285 BIO *e;
286 BUF_MEM *mem;
287
288 e = BIO_new(BIO_f_base64());
289 b = BIO_new(BIO_s_mem());
290
291 e = BIO_push(e, b);
292 BIO_write(e, in, len);
293 BIO_flush(e);
294
295 BIO_get_mem_ptr(e, &mem);
296 char *out = malloc(mem->length);
297 memcpy(out, mem->data, mem->length -
1);
298 out[mem->length -
1] =
'\0';
299
300 BIO_free_all(e);
301
302 return out;
303 }
304
305 char* util_encrypt_str(DavSession *sn,
char *str,
char *key) {
306 DavKey *k = dav_context_get_key(sn->context, key);
307 if(!k) {
308
309 return NULL;
310 }
311
312 char *enc_str = aes_encrypt(str, k);
313 char *ret_str = dav_session_strdup(sn, enc_str);
314 free(enc_str);
315 return ret_str;
316 }
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333 char* util_random_str() {
334 unsigned char *str = malloc(
25);
335 str[
24] =
'\0';
336
337 sstr_t t =
S(
338 "01234567890"
339 "abcdefghijklmnopqrstuvwxyz"
340 "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
341 const unsigned char *table = (
const unsigned char*)t.ptr;
342
343 RAND_pseudo_bytes(str,
24);
344 for(
int i=
0;i<
24;i++) {
345 int c = str[i] % t.length;
346 str[i] = table[c];
347 }
348
349 return (
char*)str;
350 }
351
352
353
354
355
356
357 sstr_t util_getsubstr_until_token(
sstr_t str,
sstr_t token,
sstr_t *sub) {
358 int i;
359 int token_start = -
1;
360 int token_end = -
1;
361 for(i=
0;i<=str.length;i++) {
362 int c;
363 if(i == str.length) {
364 c =
' ';
365 }
else {
366 c = str.ptr[i];
367 }
368 if(c <
33) {
369 if(token_start != -
1) {
370 token_end = i;
371 size_t len = token_end - token_start;
372 sstr_t tk = sstrsubsl(str, token_start, len);
373
374 if(!sstrcmp(tk, token)) {
375 *sub = sstrtrim(sstrsubsl(str,
0, token_start));
376 break;
377 }
378 token_start = -
1;
379 token_end = -
1;
380 }
381 }
else {
382 if(token_start == -
1) {
383 token_start = i;
384 }
385 }
386 }
387
388 if(i < str.length) {
389 return sstrtrim(sstrsubs(str, i));
390 }
else {
391 str.ptr =
NULL;
392 str.length =
0;
393 return str;
394 }
395 }