00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "klone_conf.h"
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 #include <time.h>
00015 #include <string.h>
00016 #include <ctype.h>
00017 #include <fcntl.h>
00018 #include <unistd.h>
00019 #include <dirent.h>
00020 #include <sys/stat.h>
00021 #include <u/libu.h>
00022 #include <klone/os.h>
00023 #include <klone/io.h>
00024 #include <klone/codecs.h>
00025 #include <klone/emb.h>
00026 #include <klone/mime_map.h>
00027 #include <klone/version.h>
00028 #include <klone/utils.h>
00029 #ifdef HAVE_STRINGS
00030 #include <strings.h>
00031 #endif
00032 #ifdef SSL_CYASSL
00033 #include <config.h>
00034 #include <types.h>
00035 #include <ctc_aes.h>
00036 #endif
00037
00038 enum { LF = 0xA, CR = 0xD };
00039
00040 static struct html_entities_s
00041 {
00042 int s_char;
00043 const char *entity;
00044 } entities[] = {
00045 { '&', "&" },
00046 { '"', """ },
00047 { '\'', "'" },
00048 { '<', "<" },
00049 { '>', ">" },
00050 { 0, NULL }
00051 };
00052
00053 #ifdef OS_UNIX
00054 inline int u_sig_block(int sig)
00055 {
00056 sigset_t sset;
00057
00058 sigemptyset(&sset);
00059 sigaddset(&sset, sig);
00060 dbg_err_if(sigprocmask(SIG_BLOCK, &sset, NULL));
00061
00062 return 0;
00063 err:
00064 return ~0;
00065 }
00066
00067 inline int u_sig_unblock(int sig)
00068 {
00069 sigset_t sset;
00070
00071 sigemptyset(&sset);
00072 sigaddset(&sset, sig);
00073 dbg_err_if(sigprocmask(SIG_UNBLOCK, &sset, NULL));
00074
00075 return 0;
00076 err:
00077 return ~0;
00078 }
00079 #endif
00080
00081
00082
00083
00084 const char *u_addr_get_ip (const char *a, char *d, size_t dlen)
00085 {
00086 char *e;
00087 const char *b;
00088
00089 dbg_return_if (a == NULL, NULL);
00090 dbg_return_if (d == NULL, NULL);
00091 dbg_return_if (dlen == 0, NULL);
00092
00093 switch (a[0])
00094 {
00095 case '/':
00096 dbg_if (u_strlcpy(d, a, dlen));
00097 return d;
00098 case '[':
00099 e = strchr(a, ']');
00100 b = a + 1;
00101 break;
00102 default:
00103 e = strchr(a, ':');
00104 b = a;
00105 break;
00106 }
00107
00108 if (e != NULL)
00109 {
00110 dbg_if (u_strlcpy(d, b, U_MIN((size_t) (e - b + 1), dlen)) + 1);
00111 return d;
00112 }
00113
00114 u_warn("unable to get an IP from '%s'", a);
00115 return NULL;
00116 }
00117
00118
00119
00120 const char *u_addr_get_port (const char *a, char *d, size_t dlen)
00121 {
00122 char *e, *p;
00123
00124 dbg_return_if (a == NULL, NULL);
00125 dbg_return_if (d == NULL, NULL);
00126 dbg_return_if (dlen == 0, NULL);
00127
00128
00129 if (a[0] == '/')
00130 {
00131 d[0] = '\0';
00132 return d;
00133 }
00134
00135
00136 dbg_return_if ((e = strchr(a, '\0')) == NULL, NULL);
00137
00138
00139 for (p = e; *p != ':' && p > a; --p)
00140 ;
00141
00142 dbg_if (u_strlcpy(d, (p > a) ? p + 1 : "", dlen));
00143
00144 return d;
00145 }
00146
00147
00148
00149
00150 const char *u_addr_fmt (const char *ip, const char *port, char *d, size_t dlen)
00151 {
00152 int isv6 = 1;
00153
00154 dbg_return_if (d == NULL, NULL);
00155 dbg_return_if (dlen == 0, NULL);
00156
00157
00158 if (!ip || ip[0] == '\0')
00159 {
00160 d[0] = '\0';
00161 return d;
00162 }
00163
00164
00165
00166 if (ip[0] == '/')
00167 {
00168 dbg_if (u_strlcpy(d, ip, dlen));
00169 return d;
00170 }
00171
00172
00173 if (strchr(ip, '.'))
00174 isv6 = 0;
00175
00176
00177 dbg_if (u_snprintf(d, dlen, "%s%s%s:%s",
00178 isv6 ? "[" : "", ip, isv6 ? "]" : "", port ? port : "0"));
00179
00180 return d;
00181 }
00182
00198 char *u_strnstr(const char *buf, const char *sub, size_t buflen)
00199 {
00200 ssize_t len = strlen(sub);
00201 ssize_t plen;
00202 char *p;
00203
00204 if (*sub == 0)
00205 return (char *)buf;
00206
00207 plen = buflen;
00208 for (p = (char *)buf; p != NULL; p = memchr(p + 1, *sub, plen - 1))
00209 {
00210 plen = buflen - (p - buf);
00211
00212 if (plen < len)
00213 return NULL;
00214
00215 if (strncmp(p, sub, len) == 0)
00216 return (p);
00217 }
00218
00219 return NULL;
00220 }
00221
00238 int u_foreach_dir_item(const char *path, unsigned int mask,
00239 int (*cb)(struct dirent*, const char *, void*), void* arg)
00240 {
00241 struct dirent *de;
00242 struct stat st;
00243 DIR *dir = NULL;
00244 char buf[U_FILENAME_MAX];
00245 int rc;
00246
00247 dbg_return_if (path == NULL, ~0);
00248 dbg_return_if (cb == NULL, ~0);
00249
00250
00251 dir = opendir(path);
00252 dbg_err_if(dir == NULL);
00253
00254 while((de = readdir(dir)) != NULL)
00255 {
00256
00257 if(!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
00258 continue;
00259
00260
00261 dbg_err_if(u_snprintf(buf, U_FILENAME_MAX, "%s/%s", path, de->d_name));
00262
00263 dbg_err_if( (rc = stat(buf, &st)) == -1);
00264
00265
00266 if(((st.st_mode & S_IFMT) & mask) != 0 && cb(de, path, arg))
00267 break;
00268 }
00269
00270 closedir(dir);
00271
00272 return 0;
00273 err:
00274 return ~0;
00275 }
00276
00291 int u_match_ext(const char *filename, const char *extension)
00292 {
00293 const char *fn, *ext;
00294 size_t flen, elen;
00295
00296 if(filename == NULL || extension == NULL)
00297 return 0;
00298
00299 flen = strlen(filename);
00300 elen = strlen(extension);
00301 if(elen > flen)
00302 return 0;
00303
00304 fn = filename + flen - 1;
00305 ext = extension + elen - 1;
00306 for( ; elen; --fn, --ext, --elen)
00307 {
00308 if(tolower(*fn) != tolower(*ext))
00309 return 0;
00310 }
00311 return 1;
00312 }
00313
00314
00315 static short htoi(unsigned char c)
00316 {
00317 c = tolower(c);
00318
00319 if(c >= '0' && c <= '9')
00320 return c - '0';
00321 else if(c >= 'a' && c <= 'z')
00322 return c - 'a' + 10;
00323 else
00324 return 0;
00325 }
00326
00327
00328 static ssize_t u_sqlncpy_encode(char *d, const char *s, size_t slen)
00329 {
00330 ssize_t wr = 0;
00331 unsigned char c;
00332
00333 dbg_return_if (d == NULL, -1);
00334 dbg_return_if (s == NULL, -1);
00335
00336 for(; slen; --slen)
00337 {
00338 c = *d++ = *s++;
00339 wr++;
00340 if(c == '\'')
00341 {
00342 dbg_err_if(slen < 2);
00343 *d++ = '\'';
00344 wr++;
00345 --slen;
00346 }
00347 }
00348 *d = 0;
00349
00350 return wr;
00351 err:
00352 return -1;
00353 }
00354
00355 static ssize_t u_sqlncpy_decode(char *d, const char *s, size_t slen)
00356 {
00357 unsigned char c, last = 0;
00358 ssize_t wr = 0;
00359
00360 dbg_return_if (d == NULL, -1);
00361 dbg_return_if (s == NULL, -1);
00362
00363 for(; slen; --slen)
00364 {
00365 c = *s++;
00366 if(c == '\'' && last == c)
00367 {
00368 last = 0;
00369 ;
00370 } else {
00371 *d++ = c;
00372 last = c;
00373 wr++;
00374 }
00375 }
00376 *d = 0;
00377
00378 return wr;
00379 }
00380
00397 ssize_t u_sqlncpy(char *d, const char *s, size_t slen, int flags)
00398 {
00399 dbg_return_if (d == NULL, -1);
00400 dbg_return_if (s == NULL, -1);
00401
00402 switch(flags)
00403 {
00404 case SQLCPY_ENCODE:
00405 return u_sqlncpy_encode(d, s, slen);
00406 case SQLCPY_DECODE:
00407 return u_sqlncpy_decode(d, s, slen);
00408 default:
00409 u_strlcpy(d, s, slen + 1);
00410 return slen;
00411 }
00412
00413 return -1;
00414 }
00415
00416 static ssize_t u_urlncpy_encode(char *d, const char *s, size_t slen)
00417 {
00418 const char hexc[] = "0123456789ABCDEF";
00419 ssize_t wr = 0;
00420 unsigned char c;
00421
00422 dbg_return_if (d == NULL, -1);
00423 dbg_return_if (s == NULL, -1);
00424
00425 for(; slen; --slen)
00426 {
00427 c = *s++;
00428 if(c == ' ') {
00429 *d++ = '+';
00430 wr++;
00431 } else if(isalnum(c) || c == '_' || c == '-' || c == '.') {
00432 *d++ = c;
00433 wr++;
00434 } else {
00435 *d++ = '%';
00436 *d++ = hexc[(c >> 4) & 0xF];
00437 *d++ = hexc[c & 0xF];
00438 wr += 3;
00439 }
00440 }
00441 *d = 0;
00442
00443 return wr;
00444 }
00445
00446 static ssize_t u_urlncpy_decode(char *d, const char *s, size_t slen)
00447 {
00448 unsigned char c;
00449 ssize_t wr = 0;
00450
00451 dbg_return_if (d == NULL, -1);
00452 dbg_return_if (s == NULL, -1);
00453
00454 for(; slen; --slen, ++wr)
00455 {
00456 c = *s++;
00457 if(c == '%')
00458 {
00459 dbg_err_if(slen < 2 || !isxdigit(s[0]) || !isxdigit(s[1]));
00460 c = htoi(s[0]) << 4 | htoi(s[1]);
00461
00462 *d++ = (char)c;
00463 s += 2;
00464 slen -= 2;
00465 } else if(c == '+') {
00466 *d++ = ' ';
00467 } else {
00468 *d++ = c;
00469 }
00470 }
00471 *d = 0;
00472
00473 return wr;
00474 err:
00475 return -1;
00476
00477 }
00478
00495 ssize_t u_urlncpy(char *d, const char *s, size_t slen, int flags)
00496 {
00497 dbg_return_if (d == NULL, -1);
00498 dbg_return_if (s == NULL, -1);
00499
00500 switch(flags)
00501 {
00502 case URLCPY_ENCODE:
00503 return u_urlncpy_encode(d, s, slen);
00504 case URLCPY_DECODE:
00505 return u_urlncpy_decode(d, s, slen);
00506 default:
00507 u_strlcpy(d, s, slen + 1);
00508 return slen;
00509 }
00510
00511 return -1;
00512 }
00513
00514 inline char u_tochex(int n)
00515 {
00516 if(n > 15)
00517 return '?';
00518 return ( n < 10 ? n + '0' : n-10 + 'a');
00519 }
00520
00521 static int u_hex2ch(char c)
00522 {
00523 if(c >= 'a' && c <= 'z')
00524 return c - 'a' + 10;
00525 else if(c >= 'A' && c <= 'Z')
00526 return c - 'A' + 10;
00527 else if(c >= '0' && c <= '9')
00528 return c - '0';
00529 else
00530 return -1;
00531 }
00532
00533 void u_print_version_and_exit(void)
00534 {
00535 static const char *vv =
00536 "KLone %s - Copyright (c) 2005-2012 KoanLogic s.r.l. - "
00537 "All rights reserved. \n\n";
00538
00539 fprintf(stderr, vv, klone_version());
00540
00541 exit(EXIT_FAILURE);
00542 }
00543
00544 static ssize_t u_hexncpy_decode(char *d, const char *s, size_t slen)
00545 {
00546 size_t i, t;
00547
00548 dbg_return_if (d == NULL, -1);
00549 dbg_return_if (s == NULL, -1);
00550
00551
00552 dbg_err_if((slen % 2) != 0);
00553
00554 for(i = 0, t = 0; i < slen; ++t, i += 2)
00555 d[t] = (u_hex2ch(s[i]) << 4) | u_hex2ch(s[i+1]);
00556
00557 d[t] = 0;
00558
00559 return t;
00560 err:
00561 return -1;
00562 }
00563
00564 static ssize_t u_hexncpy_encode(char *d, const char *s, size_t slen)
00565 {
00566 size_t c, i, t;
00567
00568 dbg_return_if (d == NULL, -1);
00569 dbg_return_if (s == NULL, -1);
00570
00571 for(i = 0, t = 0; i < slen; ++i, t += 2)
00572 {
00573 c = s[i];
00574 d[t] = u_tochex((c >> 4) & 0x0F);
00575 d[t+1] = u_tochex(c & 0x0F);
00576 }
00577 d[t] = 0;
00578
00579 return t;
00580 }
00581
00598 ssize_t u_hexncpy(char *d, const char *s, size_t slen, int flags)
00599 {
00600 dbg_err_if (d == NULL);
00601 dbg_err_if (s == NULL);
00602
00603 switch(flags)
00604 {
00605 case HEXCPY_ENCODE:
00606 return u_hexncpy_encode(d, s, slen);
00607 case HEXCPY_DECODE:
00608 return u_hexncpy_decode(d, s, slen);
00609 default:
00610 u_strlcpy(d, s, slen + 1);
00611 return slen;
00612 }
00613
00614 err:
00615 return -1;
00616 }
00617
00618 static ssize_t u_htmlncpy_encode(char *d, const char *s, size_t slen)
00619 {
00620 struct html_entities_s *p;
00621 const char *map[256];
00622 size_t elen;
00623 unsigned char c;
00624 ssize_t wr = 0;
00625
00626 dbg_return_if (d == NULL, -1);
00627 dbg_return_if (s == NULL, -1);
00628
00629
00630 memset(map, 0, sizeof(map));
00631 for(p = entities; p->s_char; ++p)
00632 map[p->s_char] = p->entity;
00633
00634 while(slen)
00635 {
00636 c = *s++;
00637 if(map[c] == NULL)
00638 {
00639 *d++ = c;
00640 wr++;
00641 --slen;
00642 } else {
00643 elen = strlen(map[c]);
00644 strcpy(d, map[c]);
00645 --slen;
00646 d += elen;
00647 wr += elen;
00648 }
00649 }
00650 *d = 0;
00651
00652 return wr;
00653 }
00654
00655 static ssize_t u_htmlncpy_decode(char *d, const char *s, size_t slen)
00656 {
00657 struct html_entities_s *p;
00658 char *found, *after;
00659
00660 dbg_return_if (d == NULL, -1);
00661 dbg_return_if (s == NULL, -1);
00662
00663 u_strlcpy(d, s, slen + 1);
00664
00665 for(p = entities; p->s_char; ++p)
00666 {
00667 while((found = u_stristr(d, p->entity)) != NULL)
00668 {
00669 *found = p->s_char;
00670 after = found + strlen(p->entity);
00671 memmove(++found, after, 1 + strlen(after));
00672 }
00673 }
00674
00675 return strlen(d);
00676 }
00677
00694 ssize_t u_htmlncpy(char *d, const char *s, size_t slen, int flags)
00695 {
00696 dbg_err_if (d == NULL);
00697 dbg_err_if (s == NULL);
00698
00699 switch(flags)
00700 {
00701 case HTMLCPY_ENCODE:
00702 return u_htmlncpy_encode(d, s, slen);
00703 case HTMLCPY_DECODE:
00704 return u_htmlncpy_decode(d, s, slen);
00705 default:
00706 u_strlcpy(d, s, slen + 1);
00707 return slen;
00708 }
00709 err:
00710 return -1;
00711 }
00712
00726 char *u_stristr(const char *string, const char *sub)
00727 {
00728 const char *p;
00729 size_t len;
00730
00731 dbg_err_if (sub == NULL);
00732 dbg_err_if (string == NULL);
00733
00734 len = strlen(sub);
00735 for(p = string; *p; ++p)
00736 {
00737 if(strncasecmp(p, sub, len) == 0)
00738 return (char*)p;
00739 }
00740
00741 err:
00742 return NULL;
00743 }
00744
00758 char* u_strnrchr(const char *s, char c, size_t len)
00759 {
00760 register int i = len - 1;
00761
00762 dbg_err_if (s == NULL);
00763
00764 for(; i >= 0; --i)
00765 if(s[i] == c)
00766 return (char*)s + i;
00767 err:
00768 return NULL;
00769 }
00770
00785 int u_tmpfile_open (const char *tmpdir, io_t **pio)
00786 {
00787 int fd = -1;
00788 unsigned int i;
00789 char tmpf[U_FILENAME_MAX];
00790 const char *pfx = "kloned_tmp_";
00791
00792 const char *dirs[] = {
00793 tmpdir,
00794 getenv("TMPDIR"),
00795 P_tmpdir,
00796 "/tmp",
00797 "."
00798 };
00799
00800 dbg_return_if (pio == NULL, ~0);
00801
00802 for (i = 0; i < (sizeof(dirs) / sizeof(char *)); i++)
00803 {
00804 if (dirs[i])
00805 {
00806
00807 if (u_path_snprintf(tmpf, sizeof tmpf, U_PATH_SEPARATOR,
00808 "%s/%sXXXXXXXXXX", dirs[i], pfx))
00809 continue;
00810
00811
00812 if ((fd = mkstemps(tmpf, 0)) == -1)
00813 continue;
00814
00815
00816 dbg_err_if (io_fd_create(fd, IO_FD_CLOSE, pio));
00817 dbg_err_if (io_name_set(*pio, tmpf));
00818
00819 return 0;
00820 }
00821 }
00822
00823
00824
00825 err:
00826 if (fd != -1)
00827 (void) close(fd);
00828
00829 return ~0;
00830 }
00831
00847 int u_file_open(const char *file, int flags, io_t **pio)
00848 {
00849 int fmod = 0;
00850 int fd;
00851
00852 #ifdef OS_WIN
00853 fmod = _O_BINARY;
00854 #endif
00855
00856 dbg_return_if (file == NULL, ~0);
00857 dbg_return_if (pio == NULL, ~0);
00858
00859 fd = open(file, fmod | flags, 0600);
00860 dbg_err_if(fd < 0);
00861
00862 dbg_err_if(io_fd_create(fd, IO_FD_CLOSE, pio));
00863
00864
00865 dbg_err_if(io_name_set(*pio, file));
00866
00867 return 0;
00868 err:
00869 if(fd < 0)
00870 dbg_strerror(errno);
00871 else
00872 close(fd);
00873 return ~0;
00874 }
00875
00889 int u_getline(io_t *io, u_string_t *ln)
00890 {
00891 enum { BUFSZ = 1024 };
00892 char buf[BUFSZ];
00893 ssize_t len, rc;
00894
00895 dbg_return_if (io == NULL, ~0);
00896 dbg_return_if (ln == NULL, ~0);
00897
00898 u_string_clear(ln);
00899
00900 while((rc = len = io_gets(io, buf, BUFSZ)) > 0)
00901 {
00902 dbg_err_if(u_string_append(ln, buf, --len));
00903 if(!u_isnl(buf[len]))
00904 continue;
00905 else
00906 break;
00907 }
00908
00909 dbg_if(rc < 0);
00910
00911 err:
00912 return (rc <= 0 ? ~0 : 0);
00913 }
00914
00928 int u_fgetline(FILE *in, u_string_t *ln)
00929 {
00930 enum { BUFSZ = 256 };
00931 char buf[BUFSZ];
00932 size_t len;
00933
00934 dbg_return_if (in == NULL, ~0);
00935 dbg_return_if (ln == NULL, ~0);
00936
00937 u_string_clear(ln);
00938
00939 while(!ferror(in) && !feof(in) && fgets(buf, BUFSZ, in))
00940 {
00941 len = strlen(buf);
00942 dbg_err_if(u_string_append(ln, buf, len));
00943 if(!u_isnl(buf[len-1]))
00944 continue;
00945 else
00946 break;
00947 }
00948
00949 if(ferror(in))
00950 dbg_strerror(errno);
00951 err:
00952 return (u_string_len(ln) ? 0 : ~0);
00953 }
00954
00955 int u_printf_ccstr(io_t *o, const char *buf, size_t sz)
00956 {
00957 char prev, c = 0;
00958 int pos = 0;
00959 size_t i;
00960
00961 dbg_return_if (o == NULL, ~0);
00962 dbg_return_if (buf == NULL, ~0);
00963
00964 for(i = 0; i < sz; ++i)
00965 {
00966 prev = c;
00967 c = buf[i];
00968 if(pos++ == 0)
00969 io_putc(o, '"');
00970 switch(c)
00971 {
00972 case CR:
00973 if(prev != LF)
00974 io_printf(o, "\\n\"\n");
00975 pos = 0;
00976 break;
00977 case LF:
00978 if(prev != CR)
00979 io_printf(o, "\\n\"\n");
00980 pos = 0;
00981 break;
00982 case '"':
00983 io_printf(o, "\\\"");
00984 break;
00985 case '\\':
00986 io_printf(o, "\\\\");
00987 break;
00988 default:
00989 if(isprint(c))
00990 io_putc(o, c);
00991 else {
00992 io_printf(o, "\\x%c%c", u_tochex((c >> 4) & 0x0F),
00993 u_tochex(c & 0x0F));
00994 }
00995 }
00996 }
00997 if(pos)
00998 io_putc(o, '"');
00999
01000 return 0;
01001 }
01002
01013 int u_file_exists(const char *fqn)
01014 {
01015 struct stat st;
01016
01017 dbg_return_if (fqn == NULL, 0);
01018
01019 return stat(fqn, &st) == 0 && S_ISREG(st.st_mode);
01020 }
01021
01036 void u_tohex(char *hex, const char *src, size_t sz)
01037 {
01038 size_t c, i, t;
01039
01040 dbg_ifb (hex == NULL) return;
01041 dbg_ifb (src == NULL) return;
01042
01043 for(i = 0, t = 0; i < sz; ++i, t += 2)
01044 {
01045 c = src[i];
01046 hex[t] = u_tochex((c >> 4) & 0x0F);
01047 hex[t+1] = u_tochex(c & 0x0F);
01048 }
01049
01050 hex[t] = 0;
01051 }
01052
01067 int u_md5(const char *buf, size_t sz, char out[MD5_DIGEST_BUFSZ])
01068 {
01069 md5_state_t md5ctx;
01070 md5_byte_t md5_digest[16];
01071
01072 dbg_return_if (buf == NULL, ~0);
01073 dbg_return_if (out == NULL, ~0);
01074
01075 md5_init(&md5ctx);
01076 md5_append(&md5ctx, (md5_byte_t*)buf, sz);
01077 md5_finish(&md5ctx, md5_digest);
01078
01079 u_tohex(out, (const char*)md5_digest, 16);
01080
01081 out[MD5_DIGEST_LEN] = 0;
01082
01083 return 0;
01084 }
01085
01100 int u_md5io(io_t *io, char out[MD5_DIGEST_BUFSZ])
01101 {
01102 enum { page_sz = 4096 };
01103 md5_state_t md5ctx;
01104 md5_byte_t md5_digest[16];
01105 char buf[page_sz];
01106 size_t cnt;
01107
01108 dbg_err_if (io == NULL);
01109 dbg_err_if (out == NULL);
01110
01111 md5_init(&md5ctx);
01112
01113 while((cnt = io_read(io, buf, page_sz)) > 0)
01114 md5_append(&md5ctx, (md5_byte_t*)buf, cnt);
01115
01116 md5_finish(&md5ctx, md5_digest);
01117
01118 u_tohex(out, (const char*)md5_digest, 16);
01119
01120 out[MD5_DIGEST_LEN] = 0;
01121
01122 return 0;
01123 err:
01124 return ~0;
01125 }
01126
01127 int u_signal(int sig, u_sig_t handler)
01128 {
01129 #ifdef OS_WIN
01130 dbg_err_if(signal(sig, handler) == SIG_ERR);
01131 #else
01132 struct sigaction action;
01133 sigset_t all;
01134
01135 sigfillset(&all);
01136 action.sa_mask = all;
01137 action.sa_handler = handler;
01138
01139
01140 action.sa_flags = (sig == SIGCHLD ? SA_NOCLDSTOP : 0);
01141 #ifdef HAVE_SA_RESTART
01142 action.sa_flags |= SA_RESTART;
01143 #endif
01144 dbg_err_if(sigaction(sig, &action, (struct sigaction *) 0));
01145 #endif
01146
01147 return 0;
01148 err:
01149 return ~0;
01150 }
01151
01162 const mime_map_t *u_get_mime_map(const char *file_name)
01163 {
01164 char *ext;
01165 mime_map_t *mm;
01166
01167 dbg_goto_if (file_name == NULL, notfound);
01168
01169 if((ext = strrchr(file_name, '.')) != NULL)
01170 {
01171 ++ext;
01172
01173 for(mm = mime_map; mm->ext && mm->mime_type; ++mm)
01174 {
01175 if(strcasecmp(mm->ext, ext) == 0)
01176 return mm;
01177 }
01178 }
01179
01180 notfound:
01181 return mime_map;
01182 }
01183
01195 const char *u_guess_mime_type(const char *file_name)
01196 {
01197 char *ext;
01198 mime_map_t *mm;
01199
01200 dbg_goto_if (file_name == NULL, notfound);
01201
01202 if((ext = strrchr(file_name, '.')) != NULL)
01203 {
01204 ++ext;
01205 for(mm = mime_map; mm->ext && mm->mime_type; ++mm)
01206 if(strcasecmp(mm->ext, ext) == 0)
01207 return mm->mime_type;
01208 }
01209
01210 notfound:
01211 return "application/octet-stream";
01212 }
01213
01214 #ifdef HAVE_LIBZ
01215
01230 int u_io_unzip_copy(io_t *out, const char *data, size_t sz)
01231 {
01232 codec_t *zip = NULL;
01233 io_t *ios = NULL;
01234
01235 dbg_return_if (out == NULL, ~0);
01236 dbg_return_if (data == NULL, ~0);
01237
01238
01239 dbg_err_if(io_mem_create((char*)data, sz, 0, &ios));
01240
01241
01242 dbg_err_if(codec_gzip_create(GZIP_UNCOMPRESS, &zip));
01243 dbg_err_if(io_codec_add_tail(ios, zip));
01244 zip = NULL;
01245
01246
01247 dbg_err_if(io_pipe(out, ios) < 0);
01248
01249 io_free(ios);
01250
01251 return 0;
01252 err:
01253 if(zip)
01254 codec_free(zip);
01255 if(ios)
01256 io_free(ios);
01257 return ~0;
01258 }
01259 #endif
01260
01261 #ifdef SSL_OPENSSL
01262
01284 int u_cipher_encrypt(const EVP_CIPHER *cipher, unsigned char *key,
01285 unsigned char *iv, char *dst, size_t *dcount, const char *src, size_t ssz)
01286 {
01287 EVP_CIPHER_CTX ctx;
01288 ssize_t dlen = 0;
01289 int wr;
01290
01291 dbg_return_if (cipher == NULL, ~0);
01292 dbg_return_if (key == NULL, ~0);
01293 dbg_return_if (iv == NULL, ~0);
01294 dbg_return_if (dcount == NULL, ~0);
01295 dbg_return_if (src == NULL, ~0);
01296 dbg_return_if (dst == NULL, ~0);
01297
01298
01299 EVP_CIPHER_CTX_init(&ctx);
01300
01301
01302 EVP_add_cipher(cipher);
01303
01304 dbg_err_if(!EVP_EncryptInit_ex(&ctx, cipher, NULL, key, iv));
01305
01306 dbg_err_if(!EVP_EncryptUpdate(&ctx, dst, &wr, src, ssz));
01307 dlen += wr;
01308 dst += wr;
01309
01310 dbg_err_if(!EVP_EncryptFinal_ex(&ctx, dst, &wr));
01311 dlen += wr;
01312
01313 *dcount = dlen;
01314
01315 EVP_CIPHER_CTX_cleanup(&ctx);
01316
01317 return 0;
01318 err:
01319 EVP_CIPHER_CTX_cleanup(&ctx);
01320 return ~0;
01321 }
01322
01343 int u_cipher_decrypt(const EVP_CIPHER *cipher, unsigned char *key,
01344 unsigned char *iv, char *dst, size_t *dcount, const char *src, size_t ssz)
01345 {
01346 EVP_CIPHER_CTX ctx;
01347 ssize_t dlen = 0;
01348 int wr;
01349
01350 dbg_return_if (cipher == NULL, ~0);
01351 dbg_return_if (key == NULL, ~0);
01352 dbg_return_if (iv == NULL, ~0);
01353 dbg_return_if (dcount == NULL, ~0);
01354 dbg_return_if (src == NULL, ~0);
01355 dbg_return_if (dst == NULL, ~0);
01356
01357
01358 EVP_CIPHER_CTX_init(&ctx);
01359
01360
01361 EVP_add_cipher(cipher);
01362
01363 dbg_err_if(!EVP_DecryptInit_ex(&ctx, cipher, NULL, key, iv));
01364
01365 dbg_err_if(!EVP_DecryptUpdate(&ctx, dst, &wr, src, ssz));
01366 dlen += wr;
01367 dst += wr;
01368
01369 dbg_err_if(!EVP_DecryptFinal_ex(&ctx, dst, &wr));
01370 dlen += wr;
01371
01372 *dcount = dlen;
01373
01374 EVP_CIPHER_CTX_cleanup(&ctx);
01375
01376 return 0;
01377 err:
01378 EVP_CIPHER_CTX_cleanup(&ctx);
01379 return ~0;
01380 }
01381
01382 #endif
01383
01384 #ifdef SSL_CYASSL
01385 static int u_cipher_op(int op, const EVP_CIPHER *cipher, unsigned char *key,
01386 unsigned char *iv, char *dst, size_t *dcount, const char *src, size_t ssz)
01387 {
01388 io_t *io = NULL;
01389 codec_t *codec = NULL;
01390 size_t avail;
01391 ssize_t rd;
01392
01393 dbg_return_if (cipher == NULL, ~0);
01394 dbg_return_if (key == NULL, ~0);
01395 dbg_return_if (iv == NULL, ~0);
01396 dbg_return_if (dcount == NULL, ~0);
01397 dbg_return_if (src == NULL, ~0);
01398 dbg_return_if (dst == NULL, ~0);
01399 dbg_return_if (*dcount < ssz, ~0);
01400
01401 dbg_err_if(io_mem_create(src, ssz, 0, &io));
01402
01403 dbg_err_if(codec_cipher_create(op, cipher, key, iv, &codec));
01404 dbg_err_if(io_codec_add_tail(io, codec));
01405 codec = NULL;
01406
01407 avail = *dcount;
01408 *dcount = 0;
01409
01410 while(avail > 0)
01411 {
01412 dbg_err_if((rd = io_read(io, dst, avail)) < 0);
01413
01414 if(rd == 0)
01415 break;
01416
01417 dbg_err_if(avail < rd);
01418
01419 avail -= rd;
01420 dst += rd;
01421 *dcount += rd;
01422 }
01423
01424 io_free(io);
01425
01426 return 0;
01427 err:
01428 if(codec)
01429 codec_free(codec);
01430 if(io)
01431 io_free(io);
01432 return ~0;
01433 }
01434
01435 int u_cipher_encrypt(const EVP_CIPHER *cipher, unsigned char *key,
01436 unsigned char *iv, char *dst, size_t *dcount, const char *src, size_t ssz)
01437 {
01438 return u_cipher_op(CIPHER_ENCRYPT, cipher, key, iv, dst, dcount, src, ssz);
01439 }
01440
01441 int u_cipher_decrypt(const EVP_CIPHER *cipher, unsigned char *key,
01442 unsigned char *iv, char *dst, size_t *dcount, const char *src, size_t ssz)
01443 {
01444 return u_cipher_op(CIPHER_DECRYPT, cipher, key, iv, dst, dcount, src, ssz);
01445 }
01446
01447 #endif