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