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()
{
}
|