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