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
30
31
32
33
34
35
36
37
38
39
40
41 #ifdef XP_UNIX
42 #include <sys/types.h>
43 #include <sys/wait.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <limits.h>
47 #include "prthread.h"
48 #endif
49
50
51
52 #include <errno.h>
53
54 #include "../daemon/netsite.h"
55 #include "../public/nsapi.h"
56 #include <ucx/string.h>
57 #include <ucx/mempool.h>
58
59 #include "pblock.h"
60 #include "util.h"
61
62 #include <openssl/bio.h>
63 #include <openssl/buffer.h>
64 #include <openssl/evp.h>
65
66
67
68
69 static const unsigned char pr2six[
256] = {
70 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
71 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
62,
64,
64,
64,
63,
72 52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
64,
64,
64,
64,
64,
64,
64,
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
73 10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
64,
64,
64,
64,
64,
64,
26,
27,
74 28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
75 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
76 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
77 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
78 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
79 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
80 64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64,
64
81 };
82
83
84 size_t util_base64decode(
char *bufcoded,
size_t codedbytes,
char *bufout) {
85 register char *bufin = bufcoded;
86 register int nprbytes;
87 size_t nbytesdecoded;
88
89
90 nprbytes = (
int) codedbytes;
91 while(pr2six[(
int)(bufin[nprbytes-
1])] >=
64) {
92 nprbytes--;
93 }
94 nbytesdecoded = ((nprbytes+
3)/
4) *
3;
95
96 while (nprbytes >
0) {
97 *(bufout++) = (
unsigned char)
98 (pr2six[(
int)(*bufin)] <<
2 | pr2six[(
int)bufin[
1]] >>
4);
99 *(bufout++) = (
unsigned char)
100 (pr2six[(
int)bufin[
1]] <<
4 | pr2six[(
int)bufin[
2]] >>
2);
101 *(bufout++) = (
unsigned char)
102 (pr2six[(
int)bufin[
2]] <<
6 | pr2six[(
int)bufin[
3]]);
103 bufin +=
4;
104 nprbytes -=
4;
105 }
106
107 if(nprbytes &
03) {
108 if(pr2six[(
int)bufin[-
2]] >
63)
109 nbytesdecoded -=
2;
110 else
111 nbytesdecoded -=
1;
112 }
113
114 return nbytesdecoded;
115 }
116
117 char* util_base64encode(
char *in,
size_t len) {
118 BIO *b;
119 BIO *e;
120 BUF_MEM *mem;
121
122 e = BIO_new(BIO_f_base64());
123 b = BIO_new(BIO_s_mem());
124 BIO_set_flags(e,
BIO_FLAGS_BASE64_NO_NL);
125
126 e = BIO_push(e, b);
127 BIO_write(e, in, len);
128 BIO_flush(e);
129
130 BIO_get_mem_ptr(e, &mem);
131 char *out = malloc(mem->length +
1);
132 memcpy(out, mem->data, mem->length);
133 out[mem->length] =
'\0';
134
135 BIO_free_all(e);
136
137 return out;
138 }
139
140
141
142
143
144 NSAPI_PUBLIC char **util_env_create(
char **env,
int n,
int *pos)
145 {
146 int x;
147
148 if(!env) {
149 *pos =
0;
150 return (
char **)
MALLOC((n +
1)*
sizeof(
char *));
151 }
152 else {
153 for(x =
0; (env[x]); x++);
154 env = (
char **)
REALLOC(env, (n + x +
1)*(
sizeof(
char *)));
155 *pos = x;
156 return env;
157 }
158 }
159
160
161
162
163
164 NSAPI_PUBLIC void util_env_free(
char **env)
165 {
166 register char **ep = env;
167
168 for(ep = env; *ep; ep++)
169 FREE(*ep);
170 FREE(env);
171 }
172
173
174
175
176 NSAPI_PUBLIC char *util_env_str(
const char *name,
const char *value) {
177 char *t;
178
179 size_t len = strlen(name) + strlen(value) +
2;
180 t = (
char *)
MALLOC(len);
181
182 snprintf(t, len,
"%s=%s", name, value);
183
184 return t;
185 }
186
187
188
189
190
191 NSAPI_PUBLIC void util_env_replace(
char **env,
const char *name,
const char *value)
192 {
193 int x, y, z;
194 char *i;
195
196 for(x =
0; env[x]; x++) {
197 i = strchr(env[x],
'=');
198 *i =
'\0';
199 if(!strcmp(env[x], name)) {
200 y = strlen(env[x]);
201 z = strlen(value);
202
203 env[x] = (
char *)
REALLOC(env[x], y + z +
2);
204 util_sprintf(&env[x][y],
"=%s", value);
205 return;
206 }
207 *i =
'=';
208 }
209 }
210
211
212
213
214
215 NSAPI_PUBLIC char *util_sh_escape(
char *s)
216 {
217 char *ns = (
char *)
MALLOC(strlen(s) *
2 +
1);
218 register char *t, *u;
219
220 for(t = s, u = ns; *t; ++t, ++u) {
221 if(strchr(
"&;`''\"|*?~<>^()[]{}$\\ #!", *t))
222 *u++ =
'\\';
223 *u = *t;
224 }
225 *u =
'\0';
226 return ns;
227 }
228
229
230
231
232
233 NSAPI_PUBLIC char *util_env_find(
char **env,
const char *name)
234 {
235 char *i;
236 int x, r;
237
238 for(x =
0; env[x]; x++) {
239 i = strchr(env[x],
'=');
240 *i =
'\0';
241 r = !strcmp(env[x], name);
242 *i =
'=';
243 if(r)
244 return i +
1;
245 }
246 return NULL;
247 }
248
249
250
251
252
253 NSAPI_PUBLIC char **util_env_copy(
char **src,
char **dst)
254 {
255 char **src_ptr;
256 int src_cnt;
257 int index;
258
259 if (!src)
260 return NULL;
261
262 for (src_cnt =
0, src_ptr = src; *src_ptr; src_ptr++, src_cnt++);
263
264 if (!src_cnt)
265 return NULL;
266
267 dst = util_env_create(dst, src_cnt, &index);
268
269 for (src_ptr = src; *src_ptr; index++, src_ptr++)
270 dst[index] =
STRDUP(*src_ptr);
271 dst[index] =
NULL;
272
273 return dst;
274 }
275
276
277
278 NSAPI_PUBLIC int util_vsnprintf(
char *s,
int n,
register const char *fmt,
279 va_list args)
280 {
281 return vsnprintf(s, n, fmt, args);
282 }
283
284 NSAPI_PUBLIC int util_snprintf(
char *s,
int n,
const char *fmt, ...)
285 {
286 va_list args;
287 va_start(args, fmt);
288 return vsnprintf(s, n, fmt, args);
289 }
290
291 NSAPI_PUBLIC int util_vsprintf(
char *s,
register const char *fmt, va_list args)
292 {
293 return vsprintf(s, fmt, args);
294 }
295
296 NSAPI_PUBLIC int util_sprintf(
char *s,
const char *fmt, ...)
297 {
298 va_list args;
299 va_start(args, fmt);
300 return vsprintf(s, fmt, args);
301 }
302
303
304
305
306
307
308
309 NSAPI_PUBLIC void util_uri_unescape(
char *s)
310 {
311 char *t, *u;
312
313 for(t = s, u = s; *t; ++t, ++u) {
314 if((*t ==
'%') && t[
1] && t[
2]) {
315 *u = ((t[
1] >=
'A' ? ((t[
1] & 0xdf) -
'A')+
10 : (t[
1] -
'0'))*
16) +
316 (t[
2] >=
'A' ? ((t[
2] & 0xdf) -
'A')+
10 : (t[
2] -
'0'));
317 t +=
2;
318 }
319 else
320 if(u != t)
321 *u = *t;
322 }
323 *u = *t;
324 }
325
326
327
328
329 NSAPI_PUBLIC int util_uri_unescape_strict(
char *s)
330 {
331 char *t, *u, t1, t2;
332 int rv =
1;
333
334 for(t = s, u = s; *t; ++t, ++u) {
335 if (*t ==
'%') {
336 t1 = t[
1] & 0xdf;
337 if ((t1 <
'A' || t1 >
'F') && (t[
1] <
'0' || t[
1] >
'9'))
338 rv =
0;
339
340 t2 = t[
2] & 0xdf;
341 if ((t2 <
'A' || t2 >
'F') && (t[
2] <
'0' || t[
2] >
'9'))
342 rv =
0;
343
344 *u = ((t[
1] >=
'A' ? ((t[
1] & 0xdf) -
'A')+
10 : (t[
1] -
'0'))*
16) +
345 (t[
2] >=
'A' ? ((t[
2] & 0xdf) -
'A')+
10 : (t[
2] -
'0'));
346 t +=
2;
347 }
348 else if (u != t)
349 *u = *t;
350 }
351 *u = *t;
352
353 return rv;
354 }
355
356
357 NSAPI_PUBLIC int
358 util_uri_unescape_plus (
const char *src,
char *trg,
int len)
359 {
360 const char *t = src;
361 char *u = trg ==
NULL ? (
char *)src : trg;
362 int rlen =
0;
363
364 if (len == -
1)
365 len = strlen (src);
366
367 for( ; len && *t; ++t, ++u, len--, rlen++)
368 {
369 if((*t ==
'%') && t[
1] && t[
2])
370 {
371 *u = ((t[
1] >=
'A' ? ((t[
1] & 0xdf) -
'A') +
10 : (t[
1] -
'0')) *
16) +
372 (t[
2] >=
'A' ? ((t[
2] & 0xdf) -
'A') +
10 : (t[
2] -
'0'));
373 t +=
2;
374 len-=
2;
375 }
376 else
377 if (*t ==
'+')
378 *u =
' ';
379 else
380 *u = *t;
381 }
382 *u =
0;
383 return rlen;
384 }
385
386
387 NSAPI_PUBLIC int INTutil_getboolean(
const char *v,
int def) {
388 if(v[
0] ==
'T' || v[
0] ==
't') {
389 return 1;
390 }
391 if(v[
0] ==
'F' || v[
0] ==
'f') {
392 return 0;
393 }
394 return def;
395 }
396
397 int util_getboolean_s(
sstr_t s,
int def) {
398 if(s.length ==
0) {
399 return def;
400 }
401 if(s.ptr[
0] ==
'T' || s.ptr[
0] ==
't') {
402 return 1;
403 }
404 if(s.ptr[
0] ==
'F' || s.ptr[
0] ==
'f') {
405 return 0;
406 }
407 return def;
408 }
409
410 NSAPI_PUBLIC int util_strtoint(
char *str,
int64_t *value) {
411 char *end;
412 errno =
0;
413 int64_t val = strtoll(str, &end,
0);
414 if(errno ==
0) {
415 *value = val;
416 return 1;
417 }
else {
418 return 0;
419 }
420 }
421
422
423
424
425
426
427
428
429
430
431
432
433
434 NSAPI_PUBLIC int INTutil_itoa(
int i,
char *a) {
435 return INTutil_i64toa(i, a);
436 }
437
438
439
440
441
442
443
444
445
446 NSAPI_PUBLIC int INTutil_i64toa(
int64_t i,
char *a)
447 {
448 register int x, y, p;
449 register char c;
450 int negative;
451
452 negative =
0;
453 if(i <
0) {
454 *a++ =
'-';
455 negative =
1;
456 i = -i;
457 }
458 p =
0;
459 while(i >
9) {
460 a[p++] = (i%
10) +
'0';
461 i /=
10;
462 }
463 a[p++] = i +
'0';
464
465 if(p >
1) {
466 for(x =
0, y = p -
1; x < y; ++x, --y) {
467 c = a[x];
468 a[x] = a[y];
469 a[y] = c;
470 }
471 }
472 a[p] =
'\0';
473
474
475
476 return p + negative;
477 }
478
479
480
481 #ifndef XP_WIN32
482 NSAPI_PUBLIC struct passwd *
483 util_getpwnam(
const char *name,
struct passwd *result,
char *buffer,
484 int buflen)
485 {
486 struct passwd *rv;
487
488 errno = getpwnam_r(name, result, buffer, buflen, &rv);
489 if (errno !=
0)
490 rv =
NULL;
491
492 return rv;
493 }
494 #endif
495
496
497 #ifndef XP_WIN32
498 NSAPI_PUBLIC struct passwd *
499 util_getpwuid(
uid_t uid,
struct passwd *result,
char *buffer,
int buflen)
500 {
501 struct passwd *rv;
502
503 errno = getpwuid_r(uid, result, buffer, buflen, &rv);
504 if (errno !=
0)
505 rv =
NULL;
506
507 return rv;
508 }
509 #endif
510
511
512 NSAPI_PUBLIC int util_errno2status(
int errno_value) {
513 switch(errno_value) {
514 case 0: {
515 return 200;
516 }
517 case EACCES: {
518 return 403;
519 }
520 case ENOENT: {
521 return 404;
522 break;
523 }
524 }
525 return 500;
526 }
527
528
529
530 NSAPI_PUBLIC
531 sstr_t util_path_append(
pool_handle_t *pool,
char *path,
char *ch) {
532 sstr_t parent = sstr(path);
533 sstr_t child = sstr(ch);
534 sstr_t newstr;
535
536 UcxAllocator a = util_pool_allocator(pool);
537 if(parent.ptr[parent.length-
1] ==
'/') {
538 newstr = sstrcat_a(&a,
2, parent, child);
539 }
else {
540 newstr = sstrcat_a(&a,
3, parent,
S(
"/"), child);
541 }
542
543 return newstr;
544 }
545
546 sstr_t util_path_remove_last(
sstr_t path) {
547 int i;
548 for(i=path.length-
1;i>=
0;i--) {
549 char c = path.ptr[i];
550 if(c ==
'/') {
551 path.ptr[i] =
0;
552 path.length = i;
553 break;
554 }
555 }
556 if(i <
0) {
557 path.ptr =
NULL;
558 path.length =
0;
559 }
560 return path;
561 }
562
563 void util_add_ppath(
sstr_t root,
sstr_t path, pblock *vars) {
564
565 size_t length = root.length + path.length;
566 char *translated_path = alloca(length);
567
568 memcpy(translated_path, root.ptr, root.length);
569 memcpy(translated_path + root.length, path.ptr, path.length);
570
571
572
573 pblock_kvinsert(
574 pb_key_ppath,
575 translated_path,
576 length,
577 vars);
578 }
579
580
581 UcxAllocator util_pool_allocator(
pool_handle_t *pool) {
582 UcxAllocator a;
583 a.malloc = (ucx_allocator_malloc)pool_malloc;
584 a.calloc = (ucx_allocator_calloc)pool_calloc;
585 a.realloc = (ucx_allocator_realloc)pool_realloc;
586 a.free = (ucx_allocator_free)pool_free;
587 a.pool = pool;
588 return a;
589 }
590
591
592
593 NSAPI_PUBLIC pblock* util_parse_param(
pool_handle_t *pool,
char *query) {
594 pblock *pb = pblock_create_pool(pool,
32);
595 if(!pb) {
596 return NULL;
597 }
598 if(!query || !(*query)) {
599 return pb;
600 }
601
602 int loopFlag =
1;
603 int nl =
0;
604 int vl =
0;
605 int state =
0;
606 const char *np = query;
607 const char *vp =
NULL;
608
609 while (loopFlag) {
610 char delim = *query++;
611 switch (delim) {
612 case '&':
613 case '\0': {
614 if(!delim) {
615 loopFlag =
0;
616 }
617
618 state =
0;
619
620 if(nl >
0) {
621 util_uri_unescape_plus(np,
NULL, nl);
622 util_uri_unescape_plus(vp,
NULL, vl);
623 pblock_nvlinsert(np, nl, vp, vl, pb);
624 }
625
626 nl =
0;
627 vl =
0;
628 vp =
NULL;
629 np = query;
630 break;
631 }
632 case '=': {
633 state =
1;
634 vp = query;
635 break;
636 }
637 default: {
638 if(state) {
639 vl++;
640 }
else {
641 nl++;
642 }
643 }
644 }
645 }
646
647 return pb;
648 }
649
650
651 sstr_t sstrdup_mp(UcxMempool *pool,
sstr_t s) {
652 sstr_t newstring;
653 newstring.ptr = (
char*)ucx_mempool_malloc(pool, s.length +
1);
654 if (newstring.ptr !=
NULL) {
655 newstring.length = s.length;
656 newstring.ptr[newstring.length] =
0;
657
658 memcpy(newstring.ptr, s.ptr, s.length);
659 }
660
661 return newstring;
662 }
663
664
665
666
667
668 static const int MSTR2NUM_HT_MASK = 0xf;
669
670 struct mstr2num_ht {
671 unsigned ucmstr;
672 int mnum;
673 };
674
675 struct mstr2num_ht
MSTR2NUM_HT[] = {
676 {
'A' <<
16 |
'P' <<
8 |
'R',
3 },
677 {
'S' <<
16 |
'E' <<
8 |
'P',
8 },
678 {
'M' <<
16 |
'A' <<
8 |
'Y',
4 },
679 {
0, -
1 },
680 {
'M' <<
16 |
'A' <<
8 |
'R',
2 },
681 {
'F' <<
16 |
'E' <<
8 |
'B',
1 },
682 {
0, -
1 },
683 {
'D' <<
16 |
'E' <<
8 |
'C',
11 },
684 {
'O' <<
16 |
'C' <<
8 |
'T',
9 },
685 {
'J' <<
16 |
'U' <<
8 |
'N',
5 },
686 {
0, -
1 },
687 {
'A' <<
16 |
'U' <<
8 |
'G',
7 },
688 {
'J' <<
16 |
'A' <<
8 |
'N',
0 },
689 {
'J' <<
16 |
'U' <<
8 |
'L',
6 },
690 {
0, -
1 },
691 {
'N' <<
16 |
'O' <<
8 |
'V',
10 }
692 };
693
694 static inline
int _mstr2num(
const char *s)
695 {
696 const unsigned char *mstr = (
const unsigned char *) s;
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717 unsigned char ucmstr0 = mstr[
0] & 0xdf;
718 unsigned ucmstr = ucmstr0 <<
16;
719 if (ucmstr0 !=
'\0') {
720 unsigned char ucmstr1 = mstr[
1] & 0xdf;
721 ucmstr |= ucmstr1 <<
8;
722 if (ucmstr1 !=
'\0') {
723 unsigned char ucmstr2 = mstr[
2] & 0xdf;
724 ucmstr |= ucmstr2;
725
726 unsigned hash = (ucmstr1 >>
2) ^ (ucmstr2 <<
1);
727
728 int i = hash &
MSTR2NUM_HT_MASK;
729
730 if (
MSTR2NUM_HT[i].ucmstr == ucmstr)
731 return MSTR2NUM_HT[i].mnum;
732 }
733 }
734
735 return -
1;
736 }
737
738 NSAPI_PUBLIC int util_mstr2num(
const char *s)
739 {
740 return _mstr2num(s);
741 }
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757 static inline
const char * _parse_day_month(
const char *p,
int *day,
int *month)
758 {
759 *day =
0;
760
761 if (*p ==
',') {
762
763 p++;
764 if (*p ==
' ')
765 p++;
766 while (*p >=
'0' && *p <=
'9')
767 *day = *day *
10 + (*p++ -
'0');
768 if (*p ==
' ' || *p ==
'-')
769 p++;
770 *month = _mstr2num(p);
771 if (*month != -
1)
772 p +=
3;
773 }
else {
774
775 if (*p ==
' ')
776 p++;
777 *month = _mstr2num(p);
778 if (*month != -
1)
779 p +=
3;
780 while (*p ==
' ')
781 p++;
782 while (*p >=
'0' && *p <=
'9')
783 *day = *day *
10 + (*p++ -
'0');
784 }
785
786 return p;
787 }
788
789 static inline
void _parse_year_time(
const char *p,
int *year,
const char ** time)
790 {
791 int _year =
0;
792
793 if (*p ==
'-') {
794
795 p++;
796 while (*p >=
'0' && *p <=
'9')
797 _year = _year *
10 + (*p++ -
'0');
798 if (_year <
70) {
799 _year +=
2000;
800 }
else {
801 _year +=
1900;
802 }
803 if (*p ==
' ')
804 p++;
805 *time = p;
806 }
else {
807
808 if (*p ==
' ')
809 p++;
810 if (p[
0] && p[
1] && p[
2] ==
':') {
811
812 *time = p;
813 p +=
3;
814 while (*p && *p !=
' ')
815 p++;
816 if (*p ==
' ')
817 p++;
818 while (*p >=
'0' && *p <=
'9')
819 _year = _year *
10 + (*p++ -
'0');
820 }
else {
821
822 while (*p >=
'0' && *p <=
'9')
823 _year = _year *
10 + (*p++ -
'0');
824 if (*p ==
' ')
825 p++;
826 *time = p;
827 }
828 }
829
830 *year = _year;
831 }
832
833 NSAPI_PUBLIC int util_str_time_equal(
const char *t1,
const char *t2)
834 {
835
836 while (isspace(*t1))
837 t1++;
838 while (isalpha(*t1))
839 t1++;
840 while (isspace(*t2))
841 t2++;
842 while (isalpha(*t2))
843 t2++;
844
845
846 int day1;
847 int month1;
848 t1 = _parse_day_month(t1, &day1, &month1);
849 int day2;
850 int month2;
851 t2 = _parse_day_month(t2, &day2, &month2);
852 if (day1 != day2)
853 return -
1;
854 if (month1 != month2)
855 return -
1;
856
857
858 int year1;
859 const char *time1;
860 _parse_year_time(t1, &year1, &time1);
861 int year2;
862 const char *time2;
863 _parse_year_time(t2, &year2, &time2);
864 if (year1 != year2)
865 return -
1;
866 while (*time1 && *time1 !=
' ' && *time1 == *time2) {
867 time1++;
868 time2++;
869 }
870 if (*time2 && *time2 !=
' ')
871 return -
1;
872
873 return 0;
874 }
875
876
877
878
879 static int _time_compare(
const struct tm *lms,
const char *ims)
880 {
881 while (isspace(*ims))
882 ims++;
883 while (isalpha(*ims))
884 ims++;
885
886 int day;
887 int month;
888 ims = _parse_day_month(ims, &day, &month);
889 if (month == -
1)
890 return 1;
891
892 int year;
893 const char *time;
894 _parse_year_time(ims, &year, &time);
895
896 int rv;
897
898 rv = (lms->tm_year +
1900) - year;
899 if (rv)
900 return rv;
901
902 rv = lms->tm_mon - month;
903 if (rv)
904 return rv;
905
906 rv = lms->tm_mday - day;
907 if (rv)
908 return rv;
909
910 const char *p = time;
911
912 int hour =
0;
913 while (*p >=
'0' && *p <=
'9')
914 hour = hour *
10 + (*p++ -
'0');
915 if (*p ==
':')
916 p++;
917
918 rv = lms->tm_hour - hour;
919 if (rv)
920 return rv;
921
922 int minutes =
0;
923 while (*p >=
'0' && *p <=
'9')
924 minutes = minutes *
10 + (*p++ -
'0');
925 if (*p ==
':')
926 p++;
927
928 rv = lms->tm_min - minutes;
929 if (rv)
930 return rv;
931
932 int seconds =
0;
933 while (*p >=
'0' && *p <=
'9')
934 seconds = seconds *
10 + (*p++ -
'0');
935 if (*p ==
':')
936 p++;
937
938 rv = lms->tm_sec - seconds;
939 if (rv)
940 return rv;
941
942 return 0;
943 }
944
945 NSAPI_PUBLIC int util_later_than(
const struct tm *lms,
const char *ims)
946 {
947
948
949
950
951
952
953
954 return _time_compare(lms, ims) <=
0;
955 }
956
957 NSAPI_PUBLIC int util_time_equal(
const struct tm *lms,
const char *ims)
958 {
959 return _time_compare(lms, ims) ==
0;
960 }
961
962
963 NSAPI_PUBLIC struct tm *
964 util_gmtime(
const time_t *clock,
struct tm *res)
965 {
966 return gmtime_r(clock, res);
967 }
968
969 int util_isdate(
char *str) {
970 sstr_t datestr = sstr(str);
971 sstr_t example =
S(
"Sun, 06 Nov 1994 08:49:37 GMT");
972
973 if(datestr.length != example.length) {
974 return 0;
975 }
976
977 for(
int i=
0;i<datestr.length;i++) {
978 char e = example.ptr[i];
979 if(isdigit(e)) {
980 if(!isdigit(datestr.ptr[i])) {
981 return 0;
982 }
983 }
else if(e ==
' ') {
984 if(datestr.ptr[i] !=
' ') {
985 return 0;
986 }
987 }
else if(e ==
',') {
988 if(datestr.ptr[i] !=
',') {
989 return 0;
990 }
991 }
else if(e ==
':') {
992 if(datestr.ptr[i] !=
':') {
993 return 0;
994 }
995 }
996 }
997
998 if(!sstrsuffix(datestr,
S(
"GMT"))) {
999 return 0;
1000 }
1001
1002 return 1;
1003 }
1004
1005
1006
1007
1008
1009 NSAPI_PUBLIC int util_mime_separator(
char *sep)
1010 {
1011 int size =
35;
1012 int pos =
0;
1013
1014 sep[pos++] =
CR;
1015 sep[pos++] =
LF;
1016 sep[pos++] =
'-';
1017 sep[pos++] =
'-';
1018
1019 int r[
6];
1020 for(
int i=
0;i<
6;i++) {
1021 r[i] = rand() %
10000;
1022 }
1023 pos += snprintf(
1024 sep+
4,
1025 size-
4,
1026 "X%04x%04x%04x%04x%04x%04xE",
1027 r[
0],
1028 r[
1],
1029 r[
2],
1030 r[
3],
1031 r[
4],
1032 r[
5]);
1033
1034 return pos;
1035 }
1036