2 20bd3ca2 2006-04-09 devnull * For decoding the files that get passed to validateattachment.
3 20bd3ca2 2006-04-09 devnull * NOT a general mime decoder.
5 20bd3ca2 2006-04-09 devnull #include <u.h>
6 20bd3ca2 2006-04-09 devnull #include <libc.h>
7 20bd3ca2 2006-04-09 devnull #include <bio.h>
9 20bd3ca2 2006-04-09 devnull enum { None, Base64, Quoted };
10 20bd3ca2 2006-04-09 devnull static int decquoted(char *out, char *in, char *e);
13 20bd3ca2 2006-04-09 devnull main(void)
15 20bd3ca2 2006-04-09 devnull Biobuf b, b1;
16 20bd3ca2 2006-04-09 devnull char *p, *encoding;
17 20bd3ca2 2006-04-09 devnull int e, len;
19 20bd3ca2 2006-04-09 devnull Binit(&b, 0, OREAD);
20 20bd3ca2 2006-04-09 devnull Binit(&b1, 1, OWRITE);
22 20bd3ca2 2006-04-09 devnull /* header */
23 20bd3ca2 2006-04-09 devnull encoding = nil;
24 20bd3ca2 2006-04-09 devnull while((p = Brdstr(&b, '\n', 1)) != nil){
25 20bd3ca2 2006-04-09 devnull if(p[0] == 0)
27 83ab7d88 2007-11-27 rsc if(cistrncmp(p, "Content-Transfer-Encoding: ", 27) == 0)
28 20bd3ca2 2006-04-09 devnull encoding = strdup(p+27);
32 20bd3ca2 2006-04-09 devnull e = None;
33 20bd3ca2 2006-04-09 devnull if(encoding == nil)
34 20bd3ca2 2006-04-09 devnull e = None;
35 20bd3ca2 2006-04-09 devnull else if(strcmp(encoding, "base64") == 0)
36 20bd3ca2 2006-04-09 devnull e = Base64;
37 20bd3ca2 2006-04-09 devnull else if(strcmp(encoding, "quoted-printable") == 0)
38 20bd3ca2 2006-04-09 devnull e = Quoted;
40 20bd3ca2 2006-04-09 devnull while((p = Brdstr(&b, '\n', 0)) != nil){
41 20bd3ca2 2006-04-09 devnull if(strncmp(p, "--", 2) == 0 && e != None)
43 20bd3ca2 2006-04-09 devnull len = strlen(p);
44 20bd3ca2 2006-04-09 devnull switch(e){
45 20bd3ca2 2006-04-09 devnull case None:
47 20bd3ca2 2006-04-09 devnull case Base64:
48 20bd3ca2 2006-04-09 devnull len = dec64((uchar*)p, len, p, len);
50 20bd3ca2 2006-04-09 devnull case Quoted:
51 20bd3ca2 2006-04-09 devnull len = decquoted(p, p, p+len);
54 20bd3ca2 2006-04-09 devnull Bwrite(&b1, p, len);
57 20bd3ca2 2006-04-09 devnull exits(0);
61 20bd3ca2 2006-04-09 devnull * decode quoted
68 20bd3ca2 2006-04-09 devnull uchar tableqp[256];
70 20bd3ca2 2006-04-09 devnull static void
71 20bd3ca2 2006-04-09 devnull initquoted(void)
75 20bd3ca2 2006-04-09 devnull memset(tableqp, 0, 256);
76 20bd3ca2 2006-04-09 devnull for(c = ' '; c <= '<'; c++)
77 20bd3ca2 2006-04-09 devnull tableqp[c] = Self;
78 20bd3ca2 2006-04-09 devnull for(c = '>'; c <= '~'; c++)
79 20bd3ca2 2006-04-09 devnull tableqp[c] = Self;
80 20bd3ca2 2006-04-09 devnull tableqp['\t'] = Self;
81 20bd3ca2 2006-04-09 devnull tableqp['='] = Hex;
84 20bd3ca2 2006-04-09 devnull static int
85 20bd3ca2 2006-04-09 devnull hex2int(int x)
87 20bd3ca2 2006-04-09 devnull if(x >= '0' && x <= '9')
88 20bd3ca2 2006-04-09 devnull return x - '0';
89 20bd3ca2 2006-04-09 devnull if(x >= 'A' && x <= 'F')
90 20bd3ca2 2006-04-09 devnull return (x - 'A') + 10;
91 20bd3ca2 2006-04-09 devnull if(x >= 'a' && x <= 'f')
92 20bd3ca2 2006-04-09 devnull return (x - 'a') + 10;
93 20bd3ca2 2006-04-09 devnull return 0;
96 20bd3ca2 2006-04-09 devnull static char*
97 20bd3ca2 2006-04-09 devnull decquotedline(char *out, char *in, char *e)
99 20bd3ca2 2006-04-09 devnull int c, soft;
101 20bd3ca2 2006-04-09 devnull /* dump trailing white space */
102 20bd3ca2 2006-04-09 devnull while(e >= in && (*e == ' ' || *e == '\t' || *e == '\r' || *e == '\n'))
105 20bd3ca2 2006-04-09 devnull /* trailing '=' means no newline */
106 20bd3ca2 2006-04-09 devnull if(*e == '='){
107 20bd3ca2 2006-04-09 devnull soft = 1;
110 20bd3ca2 2006-04-09 devnull soft = 0;
112 20bd3ca2 2006-04-09 devnull while(in <= e){
113 20bd3ca2 2006-04-09 devnull c = (*in++) & 0xff;
114 20bd3ca2 2006-04-09 devnull switch(tableqp[c]){
115 20bd3ca2 2006-04-09 devnull case Self:
116 20bd3ca2 2006-04-09 devnull *out++ = c;
118 20bd3ca2 2006-04-09 devnull case Hex:
119 20bd3ca2 2006-04-09 devnull c = hex2int(*in++)<<4;
120 20bd3ca2 2006-04-09 devnull c |= hex2int(*in++);
121 20bd3ca2 2006-04-09 devnull *out++ = c;
125 20bd3ca2 2006-04-09 devnull if(!soft)
126 20bd3ca2 2006-04-09 devnull *out++ = '\n';
127 20bd3ca2 2006-04-09 devnull *out = 0;
129 20bd3ca2 2006-04-09 devnull return out;
132 20bd3ca2 2006-04-09 devnull static int
133 20bd3ca2 2006-04-09 devnull decquoted(char *out, char *in, char *e)
135 20bd3ca2 2006-04-09 devnull char *p, *nl;
137 20bd3ca2 2006-04-09 devnull if(tableqp[' '] == 0)
138 20bd3ca2 2006-04-09 devnull initquoted();
140 20bd3ca2 2006-04-09 devnull p = out;
141 20bd3ca2 2006-04-09 devnull while((nl = strchr(in, '\n')) != nil && nl < e){
142 20bd3ca2 2006-04-09 devnull p = decquotedline(p, in, nl);
143 20bd3ca2 2006-04-09 devnull in = nl + 1;
145 20bd3ca2 2006-04-09 devnull if(in < e)
146 20bd3ca2 2006-04-09 devnull p = decquotedline(p, in, e-1);
148 20bd3ca2 2006-04-09 devnull /* make sure we end with a new line */
149 20bd3ca2 2006-04-09 devnull if(*(p-1) != '\n'){
150 20bd3ca2 2006-04-09 devnull *p++ = '\n';
154 20bd3ca2 2006-04-09 devnull return p - out;