2 Copyright (c) 2006 Joey Schulze <joey@infodrom.org>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 * Index_hex and Index_64 imported from Mutt:handler.c
27 * decode_quotedprintable() and decode_base64() as well
29 int Index_hex[128] = {
30 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
31 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
32 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
33 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1, -1,-1,-1,-1,
34 -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
35 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
36 -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
37 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
41 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
42 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
43 -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
44 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
45 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
46 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
47 -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
48 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
50 #define hexval(c) Index_hex[(unsigned int)(c)]
51 #define base64val(c) Index_64[(unsigned int)(c)]
55 * Decode a string from quoted printable
57 char *decode_quotedprintable(char *buf)
62 endp = buf+strlen(buf);
64 for (inp = outp = buf; inp < endp; inp++) {
67 else if (*inp == '=' && inp+2 < endp &&
68 (!(*(inp+1) & ~127) && hexval(*(inp+1)) != -1) &&
69 (!(*(inp+2) & ~127) && hexval(*(inp+2)) != -1)) {
70 *(outp++) = (hexval(*(inp+1)) << 4) | hexval(*(inp+2));
81 * Decode a string from base43
83 char *decode_base64(char *buf)
89 endp = buf+strlen(buf);
91 for (inp = outp = buf; inp < endp; inp++) {
94 if ((*inp & ~127) || (c = base64val(*inp)) == -1)
99 *(outp++) = b | (c >> k);
114 * converts a header line into the current character set if required
116 char *convert_header(char *buf)
120 char *inp, *outp, *encstart, *wordp, *encp, *endp;
126 endp = buf+strlen(buf);
129 outlen = strlen(buf)+1;
130 if ((output = (char *)malloc(outlen)) == NULL) {
135 memset(output, 0, outlen);
138 while ((encstart = strstr (inp, "=?"))) {
139 if (encstart != inp) {
140 // -1 nur falls vorher kein encoded-word
141 memcpy (outp, inp, encstart-inp);
142 outp += encstart-inp;
144 charset = encstart+2;
146 if ((encp = strchr (charset, '?')) == NULL) {
147 memcpy (outp, inp, strlen(inp)+1);
153 if ((encp + 3 >= endp) || !strchr ("BbQq", *encp) || (*(encp+2) != '?')) {
155 memcpy (outp, inp, strlen(inp)+1);
156 outp += strlen(inp)+1;
157 inp += strlen(inp)+1;
161 encoding = toupper(*(encp+1));
165 if ((wordp = strstr (inp, "?=")) == NULL) {
166 memcpy (outp, inp, strlen(inp)+1);
167 outp += strlen(inp)+1;
168 inp += strlen(inp)+1;
175 /* Look for next =?, spaces will be eaten between two encoded-words */
176 if (*wordp && *wordp == ' ' && *(wordp+1) && *(wordp+1) == '=' && *(wordp+2) && *(wordp+2) == '?')
181 decode = decode_base64 (inp);
184 decode = decode_quotedprintable (inp);
191 size = outlen - strlen(output);
192 decode = convert_word (charset, decode, outp, size);
194 outp += strlen(decode);
200 memcpy (outp, inp, strlen(inp)+1);
202 memcpy (buf, output, strlen(output)+1);
210 * Needs to be called with LANG=de_DE.ISO-8859-1
222 qp = strdup ("f=FCr");
223 printf ("\t%s -> ", qp);
224 b64 = decode_quotedprintable (qp);
226 if (!strcmp (qp, "für"))
227 printf ("rfc2047.c: decode_quotedprintable() passed\n");
229 printf ("rfc2047.c: decode_quotedprintable() failed\n");
232 qp = strdup ("f=FCr_Umlaute_=EFm_Sub");
233 printf ("\t%s -> ", qp);
234 b64 = decode_quotedprintable (qp);
236 if (!strcmp (qp, "für Umlaute ïm Sub"))
237 printf ("rfc2047.c: decode_quotedprintable() passed\n");
239 printf ("rfc2047.c: decode_quotedprintable() failed\n");
242 b64 = strdup ("ZvxyINxtbOT8dOs=");
243 printf ("\t%s -> ", b64);
244 b64 = decode_base64 (b64);
245 printf ("%s\n", b64);
246 if (!strcmp (b64, "für Ümläütë"))
247 printf ("rfc2047.c: decode_base64() passed\n");
249 printf ("rfc2047.c: decode_base64() failed\n");
252 subject = strdup ("Vorschlag =?ISO-8859-1?Q?f=FCr?= ein Eintrittskonzept");
253 printf ("\t%s\n", subject);
254 subject = convert_header (subject);
255 printf ("\t%s\n", subject);
256 if (!strcmp (subject, "Vorschlag für ein Eintrittskonzept"))
257 printf ("rfc2047.c: convert_header() passed\n");
259 printf ("rfc2047.c: convert_header() failed\n");
262 subject = strdup ("=?utf-8?q?Google=3A_Chat_f=C3=BCr_die_Ewigkeit?=");
263 printf ("\t%s\n", subject);
264 subject = convert_header (subject);
265 printf ("\t%s\n", subject);
266 if (!strcmp (subject, "Google: Chat für die Ewigkeit"))
267 printf ("rfc2047.c: convert_header() passed\n");
269 printf ("rfc2047.c: convert_header() failed\n");
272 subject = strdup ("=?iso-8859-1?B?ZvxyINxtbOT8dOs=?= testen");
273 printf ("\t%s\n", subject);
274 subject = convert_header (subject);
275 printf ("\t%s\n", subject);
276 if (!strcmp (subject, "für Ümläütë testen"))
277 printf ("rfc2047.c: convert_header() passed\n");
279 printf ("rfc2047.c: convert_header() failed\n");