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 <signal.h>
00015 #include <time.h>
00016 #include <string.h>
00017 #include <ctype.h>
00018 #include <fcntl.h>
00019 #include <unistd.h>
00020 #include <dirent.h>
00021 #include <sys/stat.h>
00022 #include <u/libu.h>
00023 #include <klone/os.h>
00024 #include <klone/io.h>
00025 #include <klone/codecs.h>
00026 #include <klone/emb.h>
00027 #include <klone/mime_map.h>
00028 #include <klone/version.h>
00029 #include <klone/utils.h>
00030 #ifdef HAVE_STRINGS
00031 #include <strings.h>
00032 #endif
00033
00034 enum { LF = 0xA, CR = 0xD };
00035
00036 static struct html_entities_s
00037 {
00038 int s_char;
00039 const char *entity;
00040 } entities[] = {
00041 { '&', "&" },
00042 { '"', """ },
00043 { '\'', "'" },
00044 { '<', "<" },
00045 { '>', ">" },
00046 { 0, NULL }
00047 };
00048
00049 #ifdef OS_UNIX
00050 inline int u_sig_block(int sig)
00051 {
00052 sigset_t sset;
00053
00054 sigemptyset(&sset);
00055 sigaddset(&sset, sig);
00056 dbg_err_if(sigprocmask(SIG_BLOCK, &sset, NULL));
00057
00058 return 0;
00059 err:
00060 return ~0;
00061 }
00062
00063 inline int u_sig_unblock(int sig)
00064 {
00065 sigset_t sset;
00066
00067 sigemptyset(&sset);
00068 sigaddset(&sset, sig);
00069 dbg_err_if(sigprocmask(SIG_UNBLOCK, &sset, NULL));
00070
00071 return 0;
00072 err:
00073 return ~0;
00074 }
00075 #endif
00076
00077
00093 char *u_strnstr(const char *buf, const char *sub, size_t buflen)
00094 {
00095 ssize_t len = strlen(sub);
00096 ssize_t plen;
00097 char *p;
00098
00099 if (*sub == 0)
00100 return (char *)buf;
00101
00102 plen = buflen;
00103 for (p = (char *)buf; p != NULL; p = memchr(p + 1, *sub, plen - 1))
00104 {
00105 plen = buflen - (p - buf);
00106
00107 if (plen < len)
00108 return NULL;
00109
00110 if (strncmp(p, sub, len) == 0)
00111 return (p);
00112 }
00113
00114 return NULL;
00115 }
00116
00133 int u_foreach_dir_item(const char *path, unsigned int mask,
00134 int (*cb)(struct dirent*, const char *, void*), void* arg)
00135 {
00136 struct dirent *de;
00137 struct stat st;
00138 DIR *dir = NULL;
00139 char buf[U_FILENAME_MAX];
00140 int rc;
00141
00142 dbg_return_if (path == NULL, ~0);
00143 dbg_return_if (cb == NULL, ~0);
00144
00145
00146 dir = opendir(path);
00147 dbg_err_if(dir == NULL);
00148
00149 while((de = readdir(dir)) != NULL)
00150 {
00151
00152 if(!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
00153 continue;
00154
00155
00156 dbg_err_if(u_snprintf(buf, U_FILENAME_MAX, "%s/%s", path, de->d_name));
00157
00158 dbg_err_if( (rc = stat(buf, &st)) == -1);
00159
00160
00161 if(((st.st_mode & S_IFMT) & mask) != 0 && cb(de, path, arg))
00162 break;
00163 }
00164
00165 closedir(dir);
00166
00167 return 0;
00168 err:
00169 return ~0;
00170 }
00171
00186 int u_match_ext(const char *filename, const char *extension)
00187 {
00188 const char *fn, *ext;
00189 size_t flen, elen;
00190
00191 if(filename == NULL || extension == NULL)
00192 return 0;
00193
00194 flen = strlen(filename);
00195 elen = strlen(extension);
00196 if(elen > flen)
00197 return 0;
00198
00199 fn = filename + flen - 1;
00200 ext = extension + elen - 1;
00201 for( ; elen; --fn, --ext, --elen)
00202 {
00203 if(tolower(*fn) != tolower(*ext))
00204 return 0;
00205 }
00206 return 1;
00207 }
00208
00209
00210 static short htoi(unsigned char c)
00211 {
00212 c = tolower(c);
00213
00214 if(c >= '0' && c <= '9')
00215 return c - '0';
00216 else if(c >= 'a' && c <= 'z')
00217 return c - 'a' + 10;
00218 else
00219 return 0;
00220 }
00221
00222
00223 static ssize_t u_sqlncpy_encode(char *d, const char *s, size_t slen)
00224 {
00225 ssize_t wr = 0;
00226 unsigned char c;
00227
00228 dbg_return_if (d == NULL, -1);
00229 dbg_return_if (s == NULL, -1);
00230
00231 for(; slen; --slen)
00232 {
00233 c = *d++ = *s++;
00234 wr++;
00235 if(c == '\'')
00236 {
00237 dbg_err_if(slen < 2);
00238 *d++ = '\'';
00239 wr++;
00240 --slen;
00241 }
00242 }
00243 *d = 0;
00244
00245 return wr;
00246 err:
00247 return -1;
00248 }
00249
00250 static ssize_t u_sqlncpy_decode(char *d, const char *s, size_t slen)
00251 {
00252 unsigned char c, last = 0;
00253 ssize_t wr = 0;
00254
00255 dbg_return_if (d == NULL, -1);
00256 dbg_return_if (s == NULL, -1);
00257
00258 for(; slen; --slen)
00259 {
00260 c = *s++;
00261 if(c == '\'' && last == c)
00262 {
00263 last = 0;
00264 ;
00265 } else {
00266 *d++ = c;
00267 last = c;
00268 wr++;
00269 }
00270 }
00271 *d = 0;
00272
00273 return wr;
00274 }
00275
00292 ssize_t u_sqlncpy(char *d, const char *s, size_t slen, int flags)
00293 {
00294 dbg_return_if (d == NULL, -1);
00295 dbg_return_if (s == NULL, -1);
00296
00297 switch(flags)
00298 {
00299 case SQLCPY_ENCODE:
00300 return u_sqlncpy_encode(d, s, slen);
00301 case SQLCPY_DECODE:
00302 return u_sqlncpy_decode(d, s, slen);
00303 default:
00304 strncpy(d, s, slen);
00305 d[slen] = 0;
00306 return slen;
00307 }
00308
00309 return -1;
00310 }
00311
00312 static ssize_t u_urlncpy_encode(char *d, const char *s, size_t slen)
00313 {
00314 const char hexc[] = "0123456789ABCDEF";
00315 ssize_t wr = 0;
00316 unsigned char c;
00317
00318 dbg_return_if (d == NULL, -1);
00319 dbg_return_if (s == NULL, -1);
00320
00321 for(; slen; --slen)
00322 {
00323 c = *s++;
00324 if(c == ' ') {
00325 *d++ = '+';
00326 wr++;
00327 } else if(isalnum(c) || c == '_' || c == '-' || c == '.') {
00328 *d++ = c;
00329 wr++;
00330 } else {
00331 *d++ = '%';
00332 *d++ = hexc[(c >> 4) & 0xF];
00333 *d++ = hexc[c & 0xF];
00334 wr += 3;
00335 }
00336 }
00337 *d = 0;
00338
00339 return wr;
00340 }
00341
00342 static ssize_t u_urlncpy_decode(char *d, const char *s, size_t slen)
00343 {
00344 unsigned char c;
00345 ssize_t wr = 0;
00346
00347 dbg_return_if (d == NULL, -1);
00348 dbg_return_if (s == NULL, -1);
00349
00350 for(; slen; --slen, ++wr)
00351 {
00352 c = *s++;
00353 if(c == '%')
00354 {
00355 dbg_err_if(slen < 2 || !isxdigit(s[0]) || !isxdigit(s[1]));
00356 c = htoi(s[0]) << 4 | htoi(s[1]);
00357
00358 *d++ = (char)c;
00359 s += 2;
00360 slen -= 2;
00361 } else if(c == '+') {
00362 *d++ = ' ';
00363 } else {
00364 *d++ = c;
00365 }
00366 }
00367 *d = 0;
00368
00369 return wr;
00370 err:
00371 return -1;
00372
00373 }
00374
00391 ssize_t u_urlncpy(char *d, const char *s, size_t slen, int flags)
00392 {
00393 dbg_return_if (d == NULL, -1);
00394 dbg_return_if (s == NULL, -1);
00395
00396 switch(flags)
00397 {
00398 case URLCPY_ENCODE:
00399 return u_urlncpy_encode(d, s, slen);
00400 case URLCPY_DECODE:
00401 return u_urlncpy_decode(d, s, slen);
00402 default:
00403 strncpy(d, s, slen);
00404 d[slen] = 0;
00405 return slen;
00406 }
00407
00408 return -1;
00409 }
00410
00411 inline char u_tochex(int n)
00412 {
00413 if(n > 15)
00414 return '?';
00415 return ( n < 10 ? n + '0' : n-10 + 'a');
00416 }
00417
00418 static int u_hex2ch(char c)
00419 {
00420 if(c >= 'a' && c <= 'z')
00421 return c - 'a' + 10;
00422 else if(c >= 'A' && c <= 'Z')
00423 return c - 'A' + 10;
00424 else if(c >= '0' && c <= '9')
00425 return c - '0';
00426 else
00427 return -1;
00428 }
00429
00430 void u_print_version_and_exit(void)
00431 {
00432 static const char *vv =
00433 "KLone %s - Copyright (c) 2005, 2006, 2007 KoanLogic s.r.l. - "
00434 "All rights reserved. \n\n";
00435
00436 fprintf(stderr, vv, klone_version());
00437
00438 exit(EXIT_FAILURE);
00439 }
00440
00441 static ssize_t u_hexncpy_decode(char *d, const char *s, size_t slen)
00442 {
00443 size_t i, t;
00444
00445 dbg_return_if (d == NULL, -1);
00446 dbg_return_if (s == NULL, -1);
00447
00448
00449 dbg_err_if((slen % 2) != 0);
00450
00451 for(i = 0, t = 0; i < slen; ++t, i += 2)
00452 d[t] = (u_hex2ch(s[i]) << 4) | u_hex2ch(s[i+1]);
00453
00454 d[t] = 0;
00455
00456 return t;
00457 err:
00458 return -1;
00459 }
00460
00461 static ssize_t u_hexncpy_encode(char *d, const char *s, size_t slen)
00462 {
00463 size_t c, i, t;
00464
00465 dbg_return_if (d == NULL, -1);
00466 dbg_return_if (s == NULL, -1);
00467
00468 for(i = 0, t = 0; i < slen; ++i, t += 2)
00469 {
00470 c = s[i];
00471 d[t] = u_tochex((c >> 4) & 0x0F);
00472 d[t+1] = u_tochex(c & 0x0F);
00473 }
00474 d[t] = 0;
00475
00476 return t;
00477 }
00478
00495 ssize_t u_hexncpy(char *d, const char *s, size_t slen, int flags)
00496 {
00497 dbg_err_if (d == NULL);
00498 dbg_err_if (s == NULL);
00499
00500 switch(flags)
00501 {
00502 case HEXCPY_ENCODE:
00503 return u_hexncpy_encode(d, s, slen);
00504 case HEXCPY_DECODE:
00505 return u_hexncpy_decode(d, s, slen);
00506 default:
00507 strncpy(d, s, slen);
00508 d[slen] = 0;
00509 return slen;
00510 }
00511
00512 err:
00513 return -1;
00514 }
00515
00516 static ssize_t u_htmlncpy_encode(char *d, const char *s, size_t slen)
00517 {
00518 struct html_entities_s *p;
00519 const char *map[256];
00520 size_t elen;
00521 unsigned char c;
00522 ssize_t wr = 0;
00523
00524 dbg_return_if (d == NULL, -1);
00525 dbg_return_if (s == NULL, -1);
00526
00527
00528 memset(map, 0, sizeof(map));
00529 for(p = entities; p->s_char; ++p)
00530 map[p->s_char] = p->entity;
00531
00532 while(slen)
00533 {
00534 c = *s++;
00535 if(map[c] == NULL)
00536 {
00537 *d++ = c;
00538 wr++;
00539 --slen;
00540 } else {
00541 elen = strlen(map[c]);
00542 strcpy(d, map[c]);
00543 --slen;
00544 d += elen;
00545 wr += elen;
00546 }
00547 }
00548 *d = 0;
00549
00550 return wr;
00551 }
00552
00553 static ssize_t u_htmlncpy_decode(char *d, const char *s, size_t slen)
00554 {
00555 struct html_entities_s *p;
00556 char *found, *after;
00557
00558 dbg_return_if (d == NULL, -1);
00559 dbg_return_if (s == NULL, -1);
00560
00561 strncpy(d, s, slen);
00562 d[slen] = 0;
00563
00564 for(p = entities; p->s_char; ++p)
00565 {
00566 while((found = u_stristr(d, p->entity)) != NULL)
00567 {
00568 *found = p->s_char;
00569 after = found + strlen(p->entity);
00570 memmove(++found, after, 1 + strlen(after));
00571 }
00572 }
00573
00574 return strlen(d);
00575 }
00576
00593 ssize_t u_htmlncpy(char *d, const char *s, size_t slen, int flags)
00594 {
00595 dbg_err_if (d == NULL);
00596 dbg_err_if (s == NULL);
00597
00598 switch(flags)
00599 {
00600 case HTMLCPY_ENCODE:
00601 return u_htmlncpy_encode(d, s, slen);
00602 case HTMLCPY_DECODE:
00603 return u_htmlncpy_decode(d, s, slen);
00604 default:
00605 strncpy(d, s, slen);
00606 d[slen] = 0;
00607 return slen;
00608 }
00609 err:
00610 return -1;
00611 }
00612
00626 char *u_stristr(const char *string, const char *sub)
00627 {
00628 const char *p;
00629 size_t len;
00630
00631 dbg_err_if (sub == NULL);
00632 dbg_err_if (string == NULL);
00633
00634 len = strlen(sub);
00635 for(p = string; *p; ++p)
00636 {
00637 if(strncasecmp(p, sub, len) == 0)
00638 return (char*)p;
00639 }
00640
00641 err:
00642 return NULL;
00643 }
00644
00658 char* u_strnrchr(const char *s, char c, size_t len)
00659 {
00660 register int i = len - 1;
00661
00662 dbg_err_if (s == NULL);
00663
00664 for(; i >= 0; --i)
00665 if(s[i] == c)
00666 return (char*)s + i;
00667 err:
00668 return NULL;
00669 }
00670
00683 int u_tmpfile_open(io_t **pio)
00684 {
00685 char tmp[U_FILENAME_MAX];
00686 io_t *io = NULL;
00687
00688 dbg_return_if (pio == NULL, ~0);
00689
00690 if(tmpnam(tmp) != NULL)
00691 {
00692 dbg_err_if(u_file_open(tmp, O_CREAT | O_EXCL | O_RDWR, &io));
00693
00694 dbg_err_if(io_name_set(io, tmp));
00695
00696 *pio = io;
00697
00698 return 0;
00699 }
00700
00701 err:
00702 if(io)
00703 io_free(io);
00704 return ~0;
00705 }
00706
00722 int u_file_open(const char *file, int flags, io_t **pio)
00723 {
00724 int fmod = 0;
00725 int fd;
00726
00727 #ifdef OS_WIN
00728 fmod = _O_BINARY;
00729 #endif
00730
00731 dbg_return_if (file == NULL, ~0);
00732 dbg_return_if (pio == NULL, ~0);
00733
00734 fd = open(file, fmod | flags, 0600);
00735 dbg_err_if(fd < 0);
00736
00737 dbg_err_if(io_fd_create(fd, IO_FD_CLOSE, pio));
00738
00739
00740 dbg_err_if(io_name_set(*pio, file));
00741
00742 return 0;
00743 err:
00744 if(fd < 0)
00745 dbg_strerror(errno);
00746 else
00747 close(fd);
00748 return ~0;
00749 }
00750
00764 int u_getline(io_t *io, u_string_t *ln)
00765 {
00766 enum { BUFSZ = 1024 };
00767 char buf[BUFSZ];
00768 ssize_t len, rc;
00769
00770 dbg_return_if (io == NULL, ~0);
00771 dbg_return_if (ln == NULL, ~0);
00772
00773 u_string_clear(ln);
00774
00775 while((rc = len = io_gets(io, buf, BUFSZ)) > 0)
00776 {
00777 dbg_err_if(u_string_append(ln, buf, --len));
00778 if(!u_isnl(buf[len]))
00779 continue;
00780 else
00781 break;
00782 }
00783
00784 dbg_if(rc < 0);
00785
00786 err:
00787 return (rc <= 0 ? ~0 : 0);
00788 }
00789
00803 int u_fgetline(FILE *in, u_string_t *ln)
00804 {
00805 enum { BUFSZ = 256 };
00806 char buf[BUFSZ];
00807 size_t len;
00808
00809 dbg_return_if (in == NULL, ~0);
00810 dbg_return_if (ln == NULL, ~0);
00811
00812 u_string_clear(ln);
00813
00814 while(!ferror(in) && !feof(in) && fgets(buf, BUFSZ, in))
00815 {
00816 len = strlen(buf);
00817 dbg_err_if(u_string_append(ln, buf, len));
00818 if(!u_isnl(buf[len-1]))
00819 continue;
00820 else
00821 break;
00822 }
00823
00824 if(ferror(in))
00825 dbg_strerror(errno);
00826 err:
00827 return (u_string_len(ln) ? 0 : ~0);
00828 }
00829
00830 int u_printf_ccstr(io_t *o, const char *buf, size_t sz)
00831 {
00832 char prev, c = 0;
00833 int pos = 0;
00834 size_t i;
00835
00836 dbg_return_if (o == NULL, ~0);
00837 dbg_return_if (buf == NULL, ~0);
00838
00839 for(i = 0; i < sz; ++i)
00840 {
00841 prev = c;
00842 c = buf[i];
00843 if(pos++ == 0)
00844 io_putc(o, '"');
00845 switch(c)
00846 {
00847 case CR:
00848 if(prev != LF)
00849 io_printf(o, "\\n\"\n");
00850 pos = 0;
00851 break;
00852 case LF:
00853 if(prev != CR)
00854 io_printf(o, "\\n\"\n");
00855 pos = 0;
00856 break;
00857 case '"':
00858 io_printf(o, "\\\"");
00859 break;
00860 case '\\':
00861 io_printf(o, "\\\\");
00862 break;
00863 default:
00864 if(isprint(c))
00865 io_putc(o, c);
00866 else {
00867 io_printf(o, "\\x%c%c", u_tochex((c >> 4) & 0x0F),
00868 u_tochex(c & 0x0F));
00869 }
00870 }
00871 }
00872 if(pos)
00873 io_putc(o, '"');
00874
00875 return 0;
00876 }
00877
00888 int u_file_exists(const char *fqn)
00889 {
00890 struct stat st;
00891
00892 dbg_return_if (fqn == NULL, 0);
00893
00894 return stat(fqn, &st) == 0 && S_ISREG(st.st_mode);
00895 }
00896
00911 void u_tohex(char *hex, const char *src, size_t sz)
00912 {
00913 size_t c, i, t;
00914
00915 dbg_ifb (hex == NULL) return;
00916 dbg_ifb (src == NULL) return;
00917
00918 for(i = 0, t = 0; i < sz; ++i, t += 2)
00919 {
00920 c = src[i];
00921 hex[t] = u_tochex((c >> 4) & 0x0F);
00922 hex[t+1] = u_tochex(c & 0x0F);
00923 }
00924
00925 hex[t] = 0;
00926 }
00927
00942 int u_md5(char *buf, size_t sz, char out[MD5_DIGEST_BUFSZ])
00943 {
00944 md5_state_t md5ctx;
00945 md5_byte_t md5_digest[16];
00946
00947 dbg_return_if (buf == NULL, ~0);
00948 dbg_return_if (out == NULL, ~0);
00949
00950 md5_init(&md5ctx);
00951 md5_append(&md5ctx, (md5_byte_t*)buf, sz);
00952 md5_finish(&md5ctx, md5_digest);
00953
00954 u_tohex(out, (const char*)md5_digest, 16);
00955
00956 out[MD5_DIGEST_LEN] = 0;
00957
00958 return 0;
00959 }
00960
00975 int u_md5io(io_t *io, char out[MD5_DIGEST_BUFSZ])
00976 {
00977 enum { page_sz = 4096 };
00978 md5_state_t md5ctx;
00979 md5_byte_t md5_digest[16];
00980 char buf[page_sz];
00981 size_t cnt;
00982
00983 dbg_err_if (io == NULL);
00984 dbg_err_if (out == NULL);
00985
00986 md5_init(&md5ctx);
00987
00988 while((cnt = io_read(io, buf, page_sz)) > 0)
00989 md5_append(&md5ctx, (md5_byte_t*)buf, cnt);
00990
00991 md5_finish(&md5ctx, md5_digest);
00992
00993 u_tohex(out, (const char*)md5_digest, 16);
00994
00995 out[MD5_DIGEST_LEN] = 0;
00996
00997 return 0;
00998 err:
00999 return ~0;
01000 }
01001
01002 int u_signal(int sig, u_sig_t handler)
01003 {
01004 #ifdef OS_WIN
01005 dbg_err_if(signal(sig, handler) == SIG_ERR);
01006 #else
01007 struct sigaction action;
01008 sigset_t all;
01009
01010 sigfillset(&all);
01011 action.sa_mask = all;
01012 action.sa_handler = handler;
01013
01014
01015 action.sa_flags = SA_RESTART | (sig == SIGCHLD ? SA_NOCLDSTOP : 0);
01016 dbg_err_if(sigaction(sig, &action, (struct sigaction *) 0));
01017 #endif
01018
01019 return 0;
01020 err:
01021 return ~0;
01022 }
01023
01034 const mime_map_t *u_get_mime_map(const char *file_name)
01035 {
01036 char *ext;
01037 mime_map_t *mm;
01038
01039 dbg_goto_if (file_name == NULL, notfound);
01040
01041 if((ext = strrchr(file_name, '.')) != NULL)
01042 {
01043 ++ext;
01044
01045 for(mm = mime_map; mm->ext && mm->mime_type; ++mm)
01046 {
01047 if(strcasecmp(mm->ext, ext) == 0)
01048 return mm;
01049 }
01050 }
01051
01052 notfound:
01053 return mime_map;
01054 }
01055
01067 const char *u_guess_mime_type(const char *file_name)
01068 {
01069 char *ext;
01070 mime_map_t *mm;
01071
01072 dbg_goto_if (file_name == NULL, notfound);
01073
01074 if((ext = strrchr(file_name, '.')) != NULL)
01075 {
01076 ++ext;
01077 for(mm = mime_map; mm->ext && mm->mime_type; ++mm)
01078 if(strcmp(mm->ext, ext) == 0)
01079 return mm->mime_type;
01080 }
01081
01082 notfound:
01083 return "application/octet-stream";
01084 }
01085
01086 #ifdef HAVE_LIBZ
01087
01102 int u_io_unzip_copy(io_t *out, const char *data, size_t sz)
01103 {
01104 codec_t *zip = NULL;
01105 io_t *ios = NULL;
01106
01107 dbg_return_if (out == NULL, ~0);
01108 dbg_return_if (data == NULL, ~0);
01109
01110
01111 dbg_err_if(io_mem_create((char*)data, sz, 0, &ios));
01112
01113
01114 dbg_err_if(codec_gzip_create(GZIP_UNCOMPRESS, &zip));
01115 dbg_err_if(io_codec_add_tail(ios, zip));
01116 zip = NULL;
01117
01118
01119 dbg_err_if(io_pipe(out, ios) < 0);
01120
01121 io_free(ios);
01122
01123 return 0;
01124 err:
01125 if(zip)
01126 codec_free(zip);
01127 if(ios)
01128 io_free(ios);
01129 return ~0;
01130 }
01131 #endif
01132
01133 #ifdef HAVE_LIBOPENSSL
01134
01156 int u_cipher_encrypt(const EVP_CIPHER *cipher, unsigned char *key,
01157 unsigned char *iv, char *dst, size_t *dcount, const char *src, size_t ssz)
01158 {
01159 EVP_CIPHER_CTX ctx;
01160 ssize_t dlen = 0;
01161 int wr;
01162
01163 dbg_return_if (cipher == NULL, ~0);
01164 dbg_return_if (key == NULL, ~0);
01165 dbg_return_if (iv == NULL, ~0);
01166 dbg_return_if (dcount == NULL, ~0);
01167 dbg_return_if (src == NULL, ~0);
01168 dbg_return_if (dst == NULL, ~0);
01169
01170
01171 EVP_CIPHER_CTX_init(&ctx);
01172
01173
01174 EVP_add_cipher(cipher);
01175
01176 dbg_err_if(!EVP_EncryptInit_ex(&ctx, cipher, NULL, key, iv));
01177
01178 dbg_err_if(!EVP_EncryptUpdate(&ctx, dst, &wr, src, ssz));
01179 dlen += wr;
01180 dst += wr;
01181
01182 dbg_err_if(!EVP_EncryptFinal_ex(&ctx, dst, &wr));
01183 dlen += wr;
01184
01185 *dcount = dlen;
01186
01187 EVP_CIPHER_CTX_cleanup(&ctx);
01188
01189 return 0;
01190 err:
01191 EVP_CIPHER_CTX_cleanup(&ctx);
01192 return ~0;
01193 }
01194
01215 int u_cipher_decrypt(const EVP_CIPHER *cipher, unsigned char *key,
01216 unsigned char *iv, char *dst, size_t *dcount, const char *src, size_t ssz)
01217 {
01218 EVP_CIPHER_CTX ctx;
01219 ssize_t dlen = 0;
01220 int wr;
01221
01222 dbg_return_if (cipher == NULL, ~0);
01223 dbg_return_if (key == NULL, ~0);
01224 dbg_return_if (iv == NULL, ~0);
01225 dbg_return_if (dcount == NULL, ~0);
01226 dbg_return_if (src == NULL, ~0);
01227 dbg_return_if (dst == NULL, ~0);
01228
01229
01230 EVP_CIPHER_CTX_init(&ctx);
01231
01232
01233 EVP_add_cipher(cipher);
01234
01235 dbg_err_if(!EVP_DecryptInit_ex(&ctx, cipher, NULL, key, iv));
01236
01237 dbg_err_if(!EVP_DecryptUpdate(&ctx, dst, &wr, src, ssz));
01238 dlen += wr;
01239 dst += wr;
01240
01241 dbg_err_if(!EVP_DecryptFinal_ex(&ctx, dst, &wr));
01242 dlen += wr;
01243
01244 *dcount = dlen;
01245
01246 EVP_CIPHER_CTX_cleanup(&ctx);
01247
01248 return 0;
01249 err:
01250 EVP_CIPHER_CTX_cleanup(&ctx);
01251 return ~0;
01252 }
01253
01254 #endif