/*- * Copyright (c) 1999, 2000, 2001, 2002, 2003 Lev Walkin . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: mimeword.c,v 1.7 2006/05/26 19:12:01 vlm Exp $ */ #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include extern int _sf_in_mime_words; char *(*_sf_convert_to_utf8)(const char *charset, char *body); static char * _sf_handler(svect *sl) { char *p; if(sl->count < 4) { sclear(sl); return NULL; } p = sl->list[3]; if(ecq(sl->list[2], "Q")) { _sf_in_mime_words++; p = quoted_printable_decode(p, NULL); _sf_in_mime_words--; } else if(ecq(sl->list[2], "B")) { p = (char *)base64_decode(p, NULL); } if(_sf_convert_to_utf8) { static char *_np; char *np = _sf_convert_to_utf8(sl->list[1], p); if(np != p) { if(_np) free(_np); _np = np; p = np; } } sclear(sl); return p; } char * mime_word_decode(const char *str, size_t *size) { #ifndef HAVE_REGCOMP #warning "mime_word_decode() will not function without regex." errno = EINVAL; return NULL; #else static sed_t *se; static sbuf *sbs; sbuf *sb; if(se == NULL) { se = sed_compile( "s/=\\?([a-z0-9._-]+)\\?(.)\\?" "([^[:space:]\n\r\t?]+)" "\\?=[ \n\r\t]*/\\@/gei"); if(se == NULL) { errno = EINVAL; return NULL; } sed_handler(se, _sf_handler); } if(sbs == NULL) { sbs = sbuf_init(); if(sbs == NULL) /* ENOMEM? */ return NULL; } /* Dynamic allocation */ sb = sbuf_init(); if(sb == NULL) /* ENOMEM? */ return NULL; if(str == NULL) { if(sbuf_add(sb, "") == -1) { sbuf_free(sb); /* ENOMEM? */ return NULL; } goto mwde; } if(countchar2(str, "=?") < 4) { sbuf_add(sb, str); goto mwde; } if(sbuf_add(sb, sed_exec(se, str)) == -1) { sbuf_free(sb); /* ENOMEM? */ return NULL; } mwde: if(sbs) sbuf_free(sbs); sbs = sb; if(size) *size = sbs->len; return sbs->buf; #endif /* HAVE_REGCOMP */ }