Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals

utils.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005, 2006 by KoanLogic s.r.l. <http://www.koanlogic.com>
00003  * All rights reserved.
00004  *
00005  * This file is part of KLone, and as such it is subject to the license stated
00006  * in the LICENSE file which you have received as part of this distribution.
00007  *
00008  * $Id: utils.c,v 1.39 2006/11/21 22:53:28 tat Exp $
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     { '"',  "&quot;" },
00048     { '\'', "&#39;"  }, 
00049     { '<',  "&lt;"   },
00050     { '>',  "&gt;"   },
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 /* OS_UNIX */
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     /* open the given directory */
00149     dir = opendir(path);
00150     dbg_err_if(dir == NULL);
00151 
00152     while((de = readdir(dir)) != NULL)
00153     {
00154         /* skip . and .. dirs */
00155         if(!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
00156             continue;
00157 
00158         /* build fully qualified name of this item */
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         /* skip if its type is not in the requested mask */
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 /* hex char to int */
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             ; /* skip */
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             //dbg_err_if(c == 0);
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; /* zero-term the string */
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; /* error */
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     /* slen must be multiple of 2 */
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; /* zero-term */
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; /* zero-term */
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; /* zero-term the string */
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     /* build the map table (could be static but it wouldn't be thread-safe) */
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;   /* this char doesn't need encoding */
00534             wr++;
00535             --slen;
00536         } else {
00537             elen = strlen(map[c]);
00538             if(slen < elen)
00539                 break; /* there's not enough space to fit the entity */
00540             strncpy(d, map[c], slen); /* append the entity */
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; /* zero-term */
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: /* fall through */
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; /* found */
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; /* flags modifier */
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     /* name the stream */
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; /* line's longer the bufsz (or eof);get next line chunk */
00772         else
00773             break;
00774     }
00775 
00776     dbg_if(rc < 0); /* io_gets error */
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; /* line's longer the bufsz, get next line chunk */
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) // first line char
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; /* zero-term */
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]; /* binary digest */
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]; /* binary digest */
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     /* disable child shell jobs notification */
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; /* skip '.' */
01030         /* FIXME binary search here */
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; /* the first item is the default */
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; /* skip '.' */
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     /* create an io_t around the HTML block */
01095     dbg_err_if(io_mem_create(data, sz, 0, &ios));
01096 
01097     /* apply a gzip codec */
01098     dbg_err_if(codec_gzip_create(GZIP_UNCOMPRESS, &zip));
01099     dbg_err_if(io_codec_add_tail(ios, zip));
01100     zip = NULL; /* io_free() will free the codec */
01101 
01102     /* pipe ios to out */
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;  /* dst buffer length */
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     /* init the context */
01154     EVP_CIPHER_CTX_init(&ctx);
01155 
01156     /* be sure that the cipher has been loaded */
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; /* # of bytes written to dst */
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;  /* dst buffer length */
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     /* init the context */
01212     EVP_CIPHER_CTX_init(&ctx);
01213 
01214     /* be sure that the cipher has been loaded */
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; /* # of bytes written to dst */
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 

←Products
© 2005-2006 - KoanLogic S.r.l. - All rights reserved