Blame


1 20bd3ca2 2006-04-09 devnull /*
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.
4 20bd3ca2 2006-04-09 devnull */
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>
8 20bd3ca2 2006-04-09 devnull
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);
11 20bd3ca2 2006-04-09 devnull
12 20bd3ca2 2006-04-09 devnull void
13 20bd3ca2 2006-04-09 devnull main(void)
14 20bd3ca2 2006-04-09 devnull {
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;
18 20bd3ca2 2006-04-09 devnull
19 20bd3ca2 2006-04-09 devnull Binit(&b, 0, OREAD);
20 20bd3ca2 2006-04-09 devnull Binit(&b1, 1, OWRITE);
21 20bd3ca2 2006-04-09 devnull
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)
26 20bd3ca2 2006-04-09 devnull break;
27 83ab7d88 2007-11-27 rsc if(cistrncmp(p, "Content-Transfer-Encoding: ", 27) == 0)
28 20bd3ca2 2006-04-09 devnull encoding = strdup(p+27);
29 20bd3ca2 2006-04-09 devnull free(p);
30 20bd3ca2 2006-04-09 devnull }
31 20bd3ca2 2006-04-09 devnull
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;
39 20bd3ca2 2006-04-09 devnull
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)
42 20bd3ca2 2006-04-09 devnull break;
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:
46 20bd3ca2 2006-04-09 devnull break;
47 20bd3ca2 2006-04-09 devnull case Base64:
48 20bd3ca2 2006-04-09 devnull len = dec64((uchar*)p, len, p, len);
49 20bd3ca2 2006-04-09 devnull break;
50 20bd3ca2 2006-04-09 devnull case Quoted:
51 20bd3ca2 2006-04-09 devnull len = decquoted(p, p, p+len);
52 20bd3ca2 2006-04-09 devnull break;
53 20bd3ca2 2006-04-09 devnull }
54 20bd3ca2 2006-04-09 devnull Bwrite(&b1, p, len);
55 20bd3ca2 2006-04-09 devnull free(p);
56 20bd3ca2 2006-04-09 devnull }
57 20bd3ca2 2006-04-09 devnull exits(0);
58 20bd3ca2 2006-04-09 devnull }
59 20bd3ca2 2006-04-09 devnull
60 20bd3ca2 2006-04-09 devnull /*
61 20bd3ca2 2006-04-09 devnull * decode quoted
62 20bd3ca2 2006-04-09 devnull */
63 20bd3ca2 2006-04-09 devnull enum
64 20bd3ca2 2006-04-09 devnull {
65 20bd3ca2 2006-04-09 devnull Self= 1,
66 20bd3ca2 2006-04-09 devnull Hex= 2
67 20bd3ca2 2006-04-09 devnull };
68 20bd3ca2 2006-04-09 devnull uchar tableqp[256];
69 20bd3ca2 2006-04-09 devnull
70 20bd3ca2 2006-04-09 devnull static void
71 20bd3ca2 2006-04-09 devnull initquoted(void)
72 20bd3ca2 2006-04-09 devnull {
73 20bd3ca2 2006-04-09 devnull int c;
74 20bd3ca2 2006-04-09 devnull
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;
82 20bd3ca2 2006-04-09 devnull }
83 20bd3ca2 2006-04-09 devnull
84 20bd3ca2 2006-04-09 devnull static int
85 20bd3ca2 2006-04-09 devnull hex2int(int x)
86 20bd3ca2 2006-04-09 devnull {
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;
94 20bd3ca2 2006-04-09 devnull }
95 20bd3ca2 2006-04-09 devnull
96 20bd3ca2 2006-04-09 devnull static char*
97 20bd3ca2 2006-04-09 devnull decquotedline(char *out, char *in, char *e)
98 20bd3ca2 2006-04-09 devnull {
99 20bd3ca2 2006-04-09 devnull int c, soft;
100 20bd3ca2 2006-04-09 devnull
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'))
103 20bd3ca2 2006-04-09 devnull e--;
104 20bd3ca2 2006-04-09 devnull
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;
108 20bd3ca2 2006-04-09 devnull e--;
109 20bd3ca2 2006-04-09 devnull } else
110 20bd3ca2 2006-04-09 devnull soft = 0;
111 20bd3ca2 2006-04-09 devnull
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;
117 20bd3ca2 2006-04-09 devnull break;
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;
122 20bd3ca2 2006-04-09 devnull break;
123 20bd3ca2 2006-04-09 devnull }
124 20bd3ca2 2006-04-09 devnull }
125 20bd3ca2 2006-04-09 devnull if(!soft)
126 20bd3ca2 2006-04-09 devnull *out++ = '\n';
127 20bd3ca2 2006-04-09 devnull *out = 0;
128 20bd3ca2 2006-04-09 devnull
129 20bd3ca2 2006-04-09 devnull return out;
130 20bd3ca2 2006-04-09 devnull }
131 20bd3ca2 2006-04-09 devnull
132 20bd3ca2 2006-04-09 devnull static int
133 20bd3ca2 2006-04-09 devnull decquoted(char *out, char *in, char *e)
134 20bd3ca2 2006-04-09 devnull {
135 20bd3ca2 2006-04-09 devnull char *p, *nl;
136 20bd3ca2 2006-04-09 devnull
137 20bd3ca2 2006-04-09 devnull if(tableqp[' '] == 0)
138 20bd3ca2 2006-04-09 devnull initquoted();
139 20bd3ca2 2006-04-09 devnull
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;
144 20bd3ca2 2006-04-09 devnull }
145 20bd3ca2 2006-04-09 devnull if(in < e)
146 20bd3ca2 2006-04-09 devnull p = decquotedline(p, in, e-1);
147 20bd3ca2 2006-04-09 devnull
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';
151 20bd3ca2 2006-04-09 devnull *p = 0;
152 20bd3ca2 2006-04-09 devnull }
153 20bd3ca2 2006-04-09 devnull
154 20bd3ca2 2006-04-09 devnull return p - out;
155 20bd3ca2 2006-04-09 devnull }
156 20bd3ca2 2006-04-09 devnull