1 /*
2 ** Copyright 1998 - 1999 Double Precision, Inc. See COPYING for
3 ** distribution information.
4 */
5
6 #include "rfc2045.h"
7 #include <ctype.h>
8 #include <string.h>
9
10 /* $Id$ */
11
12 static void start_rwprep(struct rfc2045 *);
13 static void do_rwprep(const char *, size_t);
14 static void end_rwprep();
15
16 static struct rfc2045ac rfc2045acprep={
17 &start_rwprep,
18 &do_rwprep,
19 &end_rwprep};
20
21 static struct rfc2045 *currwp;
22 static int curlinepos=0;
23
24 typedef enum {
25 raw,
26 quotedprint,
27 qpseeneq,
28 qpseeneqh,
29 base64} state_t;
30
31 static state_t curstate;
32 static int statechar;
33
34 #define h2nyb(c) ( (c) >= 'a' && (c) <= 'f' ? (c)-('a'-10): \
35 (c) >= 'A' && (c) <= 'F' ? (c)-('A'-10): (c)-'0')
36
rfc2045_alloc_ac()37 struct rfc2045 *rfc2045_alloc_ac()
38 {
39 struct rfc2045 *p=rfc2045_alloc();
40
41 if (p) p->rfc2045acptr= &rfc2045acprep;
42 currwp=0;
43 return (p);
44 }
45
46
start_rwprep(struct rfc2045 * p)47 static void start_rwprep(struct rfc2045 *p)
48 {
49 currwp=p;
50 curlinepos=0;
51 curstate=raw;
52 if (p->content_transfer_encoding)
53 {
54 if (strcmp(p->content_transfer_encoding,
55 "quoted-printable") == 0)
56 curstate=quotedprint;
57 else if (strcmp(p->content_transfer_encoding, "base64") == 0)
58 curstate=base64;
59 }
60 }
61
do_rwprep(const char * p,size_t n)62 static void do_rwprep(const char * p, size_t n)
63 {
64 if (!currwp) return;
65 for ( ; n; --n, ++p)
66 switch (curstate) {
67 case quotedprint:
68 if (*p == '=')
69 {
70 curstate=qpseeneq;
71 continue;
72 }
73 /* FALLTHRU */
74 case raw:
75 if (*p == '\r' || *p == '\n')
76 curlinepos=0;
77 else if (++curlinepos > 500)
78 currwp->haslongline=1;
79 if ((unsigned char)*p >= 127)
80 currwp->has8bitchars=1;
81 break;
82 case qpseeneq:
83 if (*p == '\n')
84 {
85 curstate=quotedprint;
86 continue;
87 }
88 if (isspace((int)(unsigned char)*p)) continue; /* Ignore WSP */
89 statechar=*p;
90 curstate=qpseeneqh;
91 continue;
92 case qpseeneqh:
93 curstate=quotedprint;
94 if ( (unsigned char)
95 ( (h2nyb(statechar) << 4) + h2nyb(*p) ) >= 127
96 ) currwp->has8bitchars=1;
97 if (++curlinepos > 500)
98 currwp->haslongline=1;
99 continue;
100 case base64:
101 break;
102 }
103 }
104
end_rwprep()105 static void end_rwprep()
106 {
107 }
108