00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <stdlib.h>
00012 #include <stdio.h>
00013 #include <signal.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 "klone_conf.h"
00022 #include <klone/klone.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 #include <u/libu.h>
00034
00040 enum { LF = 0xA, CR = 0xD };
00041
00042 static struct html_entities_s
00043 {
00044 int s_char;
00045 const char *entity;
00046 } entities[] = {
00047 { '"', """ },
00048 { '\'', "'" },
00049 { '<', "<" },
00050 { '>', ">" },
00051 { 0, NULL }
00052 };
00053
00054 #ifdef OS_UNIX
00055 inline int u_sig_block(int sig)
00056 {
00057 sigset_t sset;
00058
00059 sigemptyset(&sset);
00060 sigaddset(&sset, sig);
00061 dbg_err_if(sigprocmask(SIG_BLOCK, &sset, NULL));
00062
00063 return 0;
00064 err:
00065 return ~0;
00066 }
00067
00068 inline int u_sig_unblock(int sig)
00069 {
00070 sigset_t sset;
00071
00072 sigemptyset(&sset);
00073 sigaddset(&sset, sig);
00074 dbg_err_if(sigprocmask(SIG_UNBLOCK, &sset, NULL));
00075
00076 return 0;
00077 err:
00078 return ~0;
00079 }
00080 #endif
00081
00082
00097 char *u_strnstr(const char *buf, const char *sub, size_t buflen)
00098 {
00099 ssize_t len = strlen(sub);
00100 ssize_t plen;
00101 char *p;
00102
00103 if (*sub == 0)
00104 return (char *)buf;
00105
00106 plen = buflen;
00107 for (p = (char *)buf; p != NULL; p = memchr(p + 1, *sub, plen - 1))
00108 {
00109 plen = buflen - (p - buf);
00110
00111 if (plen < len)
00112 return NULL;
00113
00114 if (strncmp(p, sub, len) == 0)
00115 return (p);
00116 }
00117
00118 return NULL;
00119 }
00120
00136 int u_foreach_dir_item(const char *path, unsigned int mask,
00137 int (*cb)(struct dirent*, const char *, void*), void* arg)
00138 {
00139 struct dirent *de;
00140 struct stat st;
00141 DIR *dir = NULL;
00142 char buf[U_FILENAME_MAX];
00143 int rc;
00144
00145 dbg_return_if (path == NULL, ~0);
00146 dbg_return_if (cb == NULL, ~0);
00147
00148
00149 dir = opendir(path);
00150 dbg_err_if(dir == NULL);
00151
00152 while((de = readdir(dir)) != NULL)
00153 {
00154
00155 if(!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
00156 continue;
00157
00158
00159 dbg_err_if(u_snprintf(buf, U_FILENAME_MAX, "%s/%s", path, de->d_name));
00160
00161 dbg_err_if( (rc = stat(buf, &st)) == -1);
00162
00163
00164 if(((st.st_mode & S_IFMT) & mask) != 0 && cb(de, path, arg))
00165 break;
00166 }
00167
00168 closedir(dir);
00169
00170 return 0;
00171 err:
00172 return ~0;
00173 }
00174
00188 int u_match_ext(const char *filename, const char *extension)
00189 {
00190 const char *fn, *ext;
00191 size_t flen, elen;
00192
00193 if(filename == NULL || extension == NULL)
00194 return 0;
00195
00196 flen = strlen(filename);
00197 elen = strlen(extension);
00198 if(elen > flen)
00199 return 0;
00200
00201 fn = filename + flen - 1;
00202 ext = extension + elen - 1;
00203 for( ; elen; --fn, --ext, --elen)
00204 {
00205 if(tolower(*fn) != tolower(*ext))
00206 return 0;
00207 }
00208 return 1;
00209 }
00210
00211
00212 static short htoi(unsigned char c)
00213 {
00214 c = tolower(c);
00215
00216 if(c >= '0' && c <= '9')
00217 return c - '0';
00218 else if(c >= 'a' && c <= 'z')
00219 return c - 'a' + 10;
00220 else
00221 return 0;
00222 }
00223
00224
00225 static ssize_t u_sqlncpy_encode(char *d, const char *s, size_t slen)
00226 {
00227 ssize_t wr = 0;
00228 int c;
00229
00230 dbg_return_if (d == NULL, -1);
00231 dbg_return_if (s == NULL, -1);
00232
00233 for(; slen; --slen)
00234 {
00235 c = *d++ = *s++;
00236 wr++;
00237 if(c == '\'')
00238 {
00239 dbg_err_if(slen < 2);
00240 *d++ = '\'';
00241 wr++;
00242 --slen;
00243 }
00244 }
00245 *d = 0;
00246
00247 return ++wr;
00248 err:
00249 return -1;
00250 }
00251
00252 static ssize_t u_sqlncpy_decode(char *d, const char *s, size_t slen)
00253 {
00254 int c, last = 0;
00255 ssize_t wr = 0;
00256
00257 dbg_return_if (d == NULL, -1);
00258 dbg_return_if (s == NULL, -1);
00259
00260 for(; slen; --slen)
00261 {
00262 c = *s++;
00263 if(c == '\'' && last == c)
00264 {
00265 last = 0;
00266 ;
00267 } else {
00268 *d++ = c;
00269 last = c;
00270 wr++;
00271 }
00272 }
00273 *d = 0;
00274
00275 return ++wr;
00276 }
00277
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 + 1;
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 int 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 short 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
00389 ssize_t u_urlncpy(char *d, const char *s, size_t slen, int flags)
00390 {
00391 dbg_return_if (d == NULL, -1);
00392 dbg_return_if (s == NULL, -1);
00393
00394 switch(flags)
00395 {
00396 case URLCPY_ENCODE:
00397 return u_urlncpy_encode(d, s, slen);
00398 case URLCPY_DECODE:
00399 return u_urlncpy_decode(d, s, slen);
00400 default:
00401 strncpy(d, s, slen);
00402 d[slen] = 0;
00403 return slen + 1;
00404 }
00405
00406 return -1;
00407 }
00408
00409 inline char u_tochex(int n)
00410 {
00411 if(n > 15)
00412 return '?';
00413 return ( n < 10 ? n + '0' : n-10 + 'a');
00414 }
00415
00416 static int u_hex2ch(char c)
00417 {
00418 if(c >= 'a' && c <= 'z')
00419 return c - 'a' + 10;
00420 else if(c >= 'A' && c <= 'Z')
00421 return c - 'A' + 10;
00422 else if(c >= '0' && c <= '9')
00423 return c - '0';
00424 else
00425 return -1;
00426 }
00427
00428 void u_print_version_and_exit(void)
00429 {
00430 static const char *vv =
00431 "KLone %s - Copyright (c) 2005, 2006 KoanLogic s.r.l. - "
00432 "All rights reserved. \n\n";
00433
00434 fprintf(stderr, vv, klone_version());
00435
00436 exit(EXIT_FAILURE);
00437 }
00438
00439 static ssize_t u_hexncpy_decode(char *d, const char *s, size_t slen)
00440 {
00441 size_t i, t;
00442
00443 dbg_return_if (d == NULL, -1);
00444 dbg_return_if (s == NULL, -1);
00445
00446
00447 dbg_err_if((slen % 2) != 0);
00448
00449 for(i = 0, t = 0; i < slen; ++t, i += 2)
00450 d[t] = (u_hex2ch(s[i]) << 4) | u_hex2ch(s[i+1]);
00451
00452 d[t] = 0;
00453
00454 return ++t;
00455 err:
00456 return -1;
00457 }
00458
00459 static ssize_t u_hexncpy_encode(char *d, const char *s, size_t slen)
00460 {
00461 size_t c, i, t;
00462
00463 dbg_return_if (d == NULL, -1);
00464 dbg_return_if (s == NULL, -1);
00465
00466 for(i = 0, t = 0; i < slen; ++i, t += 2)
00467 {
00468 c = s[i];
00469 d[t] = u_tochex((c >> 4) & 0x0F);
00470 d[t+1] = u_tochex(c & 0x0F);
00471 }
00472 d[t] = 0;
00473
00474 return ++t;
00475 }
00476
00491 ssize_t u_hexncpy(char *d, const char *s, size_t slen, int flags)
00492 {
00493 dbg_err_if (d == NULL);
00494 dbg_err_if (s == NULL);
00495
00496 switch(flags)
00497 {
00498 case HEXCPY_ENCODE:
00499 return u_hexncpy_encode(d, s, slen);
00500 case HEXCPY_DECODE:
00501 return u_hexncpy_decode(d, s, slen);
00502 default:
00503 strncpy(d, s, slen);
00504 d[slen] = 0;
00505 return slen + 1;
00506 }
00507
00508 err:
00509 return -1;
00510 }
00511
00512 static ssize_t u_htmlncpy_encode(char *d, const char *s, size_t slen)
00513 {
00514 struct html_entities_s *p;
00515 const char *map[256];
00516 size_t elen;
00517 int c;
00518 ssize_t wr = 0;
00519
00520 dbg_return_if (d == NULL, -1);
00521 dbg_return_if (s == NULL, -1);
00522
00523
00524 memset(map, 0, sizeof(map));
00525 for(p = entities; p->s_char; ++p)
00526 map[p->s_char] = p->entity;
00527
00528 while(slen)
00529 {
00530 c = *s++;
00531 if(map[c] == NULL)
00532 {
00533 *d++ = c;
00534 wr++;
00535 --slen;
00536 } else {
00537 elen = strlen(map[c]);
00538 if(slen < elen)
00539 break;
00540 strncpy(d, map[c], slen);
00541 slen -= elen;
00542 d += elen;
00543 wr += elen;
00544 }
00545 }
00546 *d = 0;
00547
00548 return ++wr;
00549 }
00550
00551 static ssize_t u_htmlncpy_decode(char *d, const char *s, size_t slen)
00552 {
00553 struct html_entities_s *p;
00554 char *found, *after;
00555
00556 dbg_return_if (d == NULL, -1);
00557 dbg_return_if (s == NULL, -1);
00558
00559 strncpy(d, s, slen);
00560 d[slen] = 0;
00561
00562 for(p = entities; p->s_char; ++p)
00563 {
00564 while((found = u_stristr(d, p->entity)) != NULL)
00565 {
00566 *found = p->s_char;
00567 after = found + strlen(p->entity);
00568 memmove(++found, after, 1 + strlen(after));
00569 }
00570 }
00571
00572 return 1 + strlen(d);
00573 }
00574
00589 ssize_t u_htmlncpy(char *d, const char *s, size_t slen, int flags)
00590 {
00591 dbg_err_if (d == NULL);
00592 dbg_err_if (s == NULL);
00593
00594 switch(flags)
00595 {
00596 case HTMLCPY_ENCODE:
00597 return u_htmlncpy_encode(d, s, slen);
00598 case HTMLCPY_DECODE:
00599 return u_htmlncpy_decode(d, s, slen);
00600 default:
00601 strncpy(d, s, slen);
00602 d[slen] = 0;
00603 return slen + 1;
00604 }
00605 err:
00606 return -1;
00607 }
00608
00621 char *u_stristr(const char *string, const char *sub)
00622 {
00623 const char *p;
00624 size_t len;
00625
00626 dbg_err_if (sub == NULL);
00627 dbg_err_if (string == NULL);
00628
00629 len = strlen(sub);
00630 for(p = string; *p; ++p)
00631 {
00632 if(strncasecmp(p, sub, len) == 0)
00633 return (char*)p;
00634 }
00635
00636 err:
00637 return NULL;
00638 }
00639
00652 char* u_strnrchr(const char *s, char c, size_t len)
00653 {
00654 register int i = len - 1;
00655
00656 dbg_err_if (s == NULL);
00657 dbg_err_if (c == NULL);
00658
00659 for(; i >= 0; --i)
00660 if(s[i] == c)
00661 return (char*)s + i;
00662 err:
00663 return NULL;
00664 }
00665
00677 int u_tmpfile_open(io_t **pio)
00678 {
00679 char tmp[U_FILENAME_MAX];
00680 io_t *io = NULL;
00681
00682 dbg_return_if (pio == NULL, ~0);
00683
00684 if(tmpnam(tmp) != NULL)
00685 {
00686 dbg_err_if(u_file_open(tmp, O_CREAT | O_EXCL | O_RDWR, &io));
00687
00688 dbg_err_if(io_name_set(io, tmp));
00689
00690 *pio = io;
00691
00692 return 0;
00693 }
00694
00695 err:
00696 if(io)
00697 io_free(io);
00698 return ~0;
00699 }
00700
00715 int u_file_open(const char *file, int flags, io_t **pio)
00716 {
00717 int fmod = 0;
00718 int fd;
00719
00720 #ifdef OS_WIN
00721 fmod = _O_BINARY;
00722 #endif
00723
00724 dbg_return_if (file == NULL, ~0);
00725 dbg_return_if (pio == NULL, ~0);
00726
00727 fd = open(file, fmod | flags, 0600);
00728 dbg_err_if(fd < 0);
00729
00730 dbg_err_if(io_fd_create(fd, IO_FD_CLOSE, pio));
00731
00732
00733 dbg_err_if(io_name_set(*pio, file));
00734
00735 return 0;
00736 err:
00737 if(fd < 0)
00738 dbg_strerror(errno);
00739 else
00740 close(fd);
00741 return ~0;
00742 }
00743
00756 int u_getline(io_t *io, u_string_t *ln)
00757 {
00758 enum { BUFSZ = 1024 };
00759 char buf[BUFSZ];
00760 ssize_t len, rc;
00761
00762 dbg_return_if (io == NULL, ~0);
00763 dbg_return_if (ln == NULL, ~0);
00764
00765 u_string_clear(ln);
00766
00767 while((rc = len = io_gets(io, buf, BUFSZ)) > 0)
00768 {
00769 dbg_err_if(u_string_append(ln, buf, --len));
00770 if(!u_isnl(buf[len]))
00771 continue;
00772 else
00773 break;
00774 }
00775
00776 dbg_if(rc < 0);
00777
00778 err:
00779 return (rc <= 0 ? ~0 : 0);
00780 }
00781
00794 int u_fgetline(FILE *in, u_string_t *ln)
00795 {
00796 enum { BUFSZ = 256 };
00797 char buf[BUFSZ];
00798 size_t len;
00799
00800 dbg_return_if (in == NULL, ~0);
00801 dbg_return_if (ln == NULL, ~0);
00802
00803 u_string_clear(ln);
00804
00805 while(!ferror(in) && !feof(in) && fgets(buf, BUFSZ, in))
00806 {
00807 len = strlen(buf);
00808 dbg_err_if(u_string_append(ln, buf, len));
00809 if(!u_isnl(buf[len-1]))
00810 continue;
00811 else
00812 break;
00813 }
00814
00815 if(ferror(in))
00816 dbg_strerror(errno);
00817 err:
00818 return (u_string_len(ln) ? 0 : ~0);
00819 }
00820
00821 int u_printf_ccstr(io_t *o, const char *buf, size_t sz)
00822 {
00823 char prev, c = 0;
00824 int pos = 0;
00825 size_t i;
00826
00827 dbg_return_if (o == NULL, ~0);
00828 dbg_return_if (buf == NULL, ~0);
00829
00830 for(i = 0; i < sz; ++i)
00831 {
00832 prev = c;
00833 c = buf[i];
00834 if(pos++ == 0)
00835 io_putc(o, '"');
00836 switch(c)
00837 {
00838 case CR:
00839 if(prev != LF)
00840 io_printf(o, "\\n\"\n");
00841 pos = 0;
00842 break;
00843 case LF:
00844 if(prev != CR)
00845 io_printf(o, "\\n\"\n");
00846 pos = 0;
00847 break;
00848 case '"':
00849 io_printf(o, "\\\"");
00850 break;
00851 case '\\':
00852 io_printf(o, "\\\\");
00853 break;
00854 default:
00855 if(isprint(c))
00856 io_putc(o, c);
00857 else {
00858 io_printf(o, "\\x%c%c", u_tochex((c >> 4) & 0x0F),
00859 u_tochex(c & 0x0F));
00860 }
00861 }
00862 }
00863 if(pos)
00864 io_putc(o, '"');
00865
00866 return 0;
00867 }
00868
00878 int u_file_exists(const char *fqn)
00879 {
00880 struct stat st;
00881
00882 dbg_return_if (fqn == NULL, 0);
00883
00884 return stat(fqn, &st) == 0 && S_ISREG(st.st_mode);
00885 }
00886
00900 void u_tohex(char *hex, const char *src, size_t sz)
00901 {
00902 size_t c, i, t;
00903
00904 dbg_ifb (hex == NULL) return;
00905 dbg_ifb (src == NULL) return;
00906
00907 for(i = 0, t = 0; i < sz; ++i, t += 2)
00908 {
00909 c = src[i];
00910 hex[t] = u_tochex((c >> 4) & 0x0F);
00911 hex[t+1] = u_tochex(c & 0x0F);
00912 }
00913
00914 hex[t] = 0;
00915 }
00916
00930 int u_md5(char *buf, size_t sz, char out[MD5_DIGEST_BUFSZ])
00931 {
00932 md5_state_t md5ctx;
00933 md5_byte_t md5_digest[16];
00934
00935 dbg_return_if (buf == NULL, ~0);
00936 dbg_return_if (out == NULL, ~0);
00937
00938 md5_init(&md5ctx);
00939 md5_append(&md5ctx, (md5_byte_t*)buf, sz);
00940 md5_finish(&md5ctx, md5_digest);
00941
00942 u_tohex(out, (const char*)md5_digest, 16);
00943
00944 out[MD5_DIGEST_LEN] = 0;
00945
00946 return 0;
00947 }
00948
00962 int u_md5io(io_t *io, char out[MD5_DIGEST_BUFSZ])
00963 {
00964 enum { page_sz = 4096 };
00965 md5_state_t md5ctx;
00966 md5_byte_t md5_digest[16];
00967 char buf[page_sz];
00968 size_t cnt;
00969
00970 dbg_err_if (io == NULL);
00971 dbg_err_if (out == NULL);
00972
00973 md5_init(&md5ctx);
00974
00975 while((cnt = io_read(io, buf, page_sz)) > 0)
00976 md5_append(&md5ctx, (md5_byte_t*)buf, cnt);
00977
00978 md5_finish(&md5ctx, md5_digest);
00979
00980 u_tohex(out, (const char*)md5_digest, 16);
00981
00982 out[MD5_DIGEST_LEN] = 0;
00983
00984 return 0;
00985 err:
00986 return ~0;
00987 }
00988
00989 int u_signal(int sig, u_sig_t handler)
00990 {
00991 #ifdef OS_WIN
00992 dbg_err_if(signal(sig, handler) == SIG_ERR);
00993 #else
00994 struct sigaction action;
00995 sigset_t all;
00996
00997 sigfillset(&all);
00998 action.sa_mask = all;
00999 action.sa_handler = handler;
01000
01001
01002 action.sa_flags = SA_RESTART | (sig == SIGCHLD ? SA_NOCLDSTOP : 0);
01003 dbg_err_if(sigaction(sig, &action, (struct sigaction *) 0));
01004 #endif
01005
01006 return 0;
01007 err:
01008 return ~0;
01009 }
01010
01020 const mime_map_t *u_get_mime_map(const char *file_name)
01021 {
01022 char *ext;
01023 mime_map_t *mm;
01024
01025 dbg_goto_if (file_name == NULL, notfound);
01026
01027 if((ext = strrchr(file_name, '.')) != NULL)
01028 {
01029 ++ext;
01030
01031 for(mm = mime_map; mm->ext && mm->mime_type; ++mm)
01032 {
01033 if(strcasecmp(mm->ext, ext) == 0)
01034 return mm;
01035 }
01036 }
01037
01038 notfound:
01039 return mime_map;
01040 }
01041
01052 const char *u_guess_mime_type(const char *file_name)
01053 {
01054 char *ext;
01055 mime_map_t *mm;
01056
01057 dbg_goto_if (file_name == NULL, notfound);
01058
01059 if((ext = strrchr(file_name, '.')) != NULL)
01060 {
01061 ++ext;
01062 for(mm = mime_map; mm->ext && mm->mime_type; ++mm)
01063 if(strcmp(mm->ext, ext) == 0)
01064 return mm->mime_type;
01065 }
01066
01067 notfound:
01068 return "application/octet-stream";
01069 }
01070
01071 #ifdef HAVE_LIBZ
01072
01086 int u_io_unzip_copy(io_t *out, const unsigned char *data, size_t sz)
01087 {
01088 codec_t *zip = NULL;
01089 io_t *ios = NULL;
01090
01091 dbg_return_if (out == NULL, ~0);
01092 dbg_return_if (data == NULL, ~0);
01093
01094
01095 dbg_err_if(io_mem_create(data, sz, 0, &ios));
01096
01097
01098 dbg_err_if(codec_gzip_create(GZIP_UNCOMPRESS, &zip));
01099 dbg_err_if(io_codec_add_tail(ios, zip));
01100 zip = NULL;
01101
01102
01103 dbg_err_if(io_pipe(out, ios) < 0);
01104
01105 io_free(ios);
01106
01107 return 0;
01108 err:
01109 if(zip)
01110 codec_free(zip);
01111 if(ios)
01112 io_free(ios);
01113 return ~0;
01114 }
01115 #endif
01116
01117 #ifdef HAVE_LIBOPENSSL
01118
01139 int u_cipher_encrypt(const EVP_CIPHER *cipher, unsigned char *key,
01140 unsigned char *iv, char *dst, size_t *dcount, const char *src, size_t ssz)
01141 {
01142 EVP_CIPHER_CTX ctx;
01143 ssize_t dlen = 0;
01144 int wr;
01145
01146 dbg_return_if (cipher == NULL, ~0);
01147 dbg_return_if (key == NULL, ~0);
01148 dbg_return_if (iv == NULL, ~0);
01149 dbg_return_if (dcount == NULL, ~0);
01150 dbg_return_if (src == NULL, ~0);
01151 dbg_return_if (dst == NULL, ~0);
01152
01153
01154 EVP_CIPHER_CTX_init(&ctx);
01155
01156
01157 EVP_add_cipher(cipher);
01158
01159 dbg_err_if(!EVP_EncryptInit_ex(&ctx, cipher, NULL, key, iv));
01160
01161 dbg_err_if(!EVP_EncryptUpdate(&ctx, dst, &wr, src, ssz));
01162 dlen += wr;
01163 dst += wr;
01164
01165 dbg_err_if(!EVP_EncryptFinal_ex(&ctx, dst, &wr));
01166 dlen += wr;
01167
01168 *dcount = dlen;
01169
01170 EVP_CIPHER_CTX_cleanup(&ctx);
01171
01172 return 0;
01173 err:
01174 EVP_CIPHER_CTX_cleanup(&ctx);
01175 return ~0;
01176 }
01177
01197 int u_cipher_decrypt(const EVP_CIPHER *cipher, unsigned char *key,
01198 unsigned char *iv, char *dst, size_t *dcount, const char *src, size_t ssz)
01199 {
01200 EVP_CIPHER_CTX ctx;
01201 ssize_t dlen = 0;
01202 int wr;
01203
01204 dbg_return_if (cipher == NULL, ~0);
01205 dbg_return_if (key == NULL, ~0);
01206 dbg_return_if (iv == NULL, ~0);
01207 dbg_return_if (dcount == NULL, ~0);
01208 dbg_return_if (src == NULL, ~0);
01209 dbg_return_if (dst == NULL, ~0);
01210
01211
01212 EVP_CIPHER_CTX_init(&ctx);
01213
01214
01215 EVP_add_cipher(cipher);
01216
01217 dbg_err_if(!EVP_DecryptInit_ex(&ctx, cipher, NULL, key, iv));
01218
01219 dbg_err_if(!EVP_DecryptUpdate(&ctx, dst, &wr, src, ssz));
01220 dlen += wr;
01221 dst += wr;
01222
01223 dbg_err_if(!EVP_DecryptFinal_ex(&ctx, dst, &wr));
01224 dlen += wr;
01225
01226 *dcount = dlen;
01227
01228 EVP_CIPHER_CTX_cleanup(&ctx);
01229
01230 return 0;
01231 err:
01232 EVP_CIPHER_CTX_cleanup(&ctx);
01233 return ~0;
01234 }
01235
01236 #endif
01237