/*- * 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: qprint.c,v 1.5 2005/12/11 01:53:35 vlm Exp $ */ #include #include #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include int _sf_in_mime_words; /* Externally visible */ static char *_sf_qp_buf = NULL; char * quoted_printable_decode(const char *str, size_t *size) { char *buf; char *s; register int n; if(str == NULL) { /* * Return an empty string. */ if(_sf_qp_buf) free(_sf_qp_buf); _sf_qp_buf=sf_strdup(""); if(size) *size = 0; return _sf_qp_buf; } /* * Allocate sufficient space to hold decoded string. */ s=buf=(char *)sf_malloc((size?*size:strlen(str)) + 1); if(buf == NULL) /* ENOMEM? */ return NULL; for(; *str; str++) { if(_sf_in_mime_words && (*str == '_')) { *s++ = ' '; continue; } if(*str == '=') { *s = '\0'; n = *++str; if(n == '\0') { str--; break; } if(str[1] == '\0') break; switch(n) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': *s = n - '0'; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': *s=n - 'A' + 10; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': *s=n - 'a' + 10; break; case '\r': case '\n': continue; default: *s++ = '='; *s++ = n; continue; } *s *= 16; n = *++str; switch(n) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': *s += n - '0'; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': *s += n - 'A' + 10; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': *s += n - 'a' + 10; break; case '\r': case '\n': *s++ = n; continue; default: *s = ' '; continue; } s++; continue; } *s++ = *str; } *s = '\0'; if(_sf_qp_buf) free(_sf_qp_buf); if(size) *size = (s - buf); return (_sf_qp_buf=buf); }