/* Quick and dirty RFC 2047 */ #include "a.h" static int unhex1(char c) { if('0' <= c && c <= '9') return c-'0'; if('a' <= c && c <= 'f') return c-'a'+10; if('A' <= c && c <= 'F') return c-'A'+10; return 15; } static int unhex(char *s) { return unhex1(s[0])*16+unhex1(s[1]); } int _decqp(uchar *out, int lim, char *in, int n, int underscores) { char *p, *ep; uchar *eout, *out0; out0 = out; eout = out+lim; for(p=in, ep=in+n; p ep) break; *out++ = unhex(p+1); p += 3; }else *out++ = *p++; } return out-out0; } int decqp(uchar *out, int lim, char *in, int n) { return _decqp(out, lim, in, n, 0); } char* decode(int kind, char *s, int *len) { char *t; int l; if(s == nil) return s; switch(kind){ case QuotedPrintable: case QuotedPrintableU: l = strlen(s)+1; t = emalloc(l); l = _decqp((uchar*)t, l, s, l-1, kind==QuotedPrintableU); *len = l; t[l] = 0; return t; case Base64: l = strlen(s)+1; t = emalloc(l); l = dec64((uchar*)t, l, s, l-1); *len = l; t[l] = 0; return t; default: *len = strlen(s); return estrdup(s); } } struct { char *mime; char *tcs; } tcstab[] = { "iso-8859-2", "8859-2", "iso-8859-3", "8859-3", "iso-8859-4", "8859-4", "iso-8859-5", "8859-5", "iso-8859-6", "8859-6", "iso-8859-7", "8859-7", "iso-8859-8", "8859-8", "iso-8859-9", "8859-9", "iso-8859-10", "8859-10", "iso-8859-15", "8859-15", "big5", "big5", "iso-2022-jp", "jis-kanji", "windows-1251", "cp1251", "koi8-r", "koi8", }; char* tcs(char *charset, char *s) { static char buf[4096]; int i, n; int fd[3], p[2], pp[2]; uchar *us; char *t, *u; char *argv[4]; Rune r; if(s == nil || charset == nil || *s == 0) return s; if(cistrcmp(charset, "utf-8") == 0) return s; if(cistrcmp(charset, "iso-8859-1") == 0 || cistrcmp(charset, "us-ascii") == 0){ latin1: n = 0; for(us=(uchar*)s; *us; us++) n += runelen(*us); n++; t = emalloc(n); for(us=(uchar*)s, u=t; *us; us++){ r = *us; u += runetochar(u, &r); } *u = 0; free(s); return t; } for(i=0; i