File: rfc2646.c

package info (click to toggle)
cone 0.75-1
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 31,040 kB
  • ctags: 13,930
  • sloc: ansic: 90,648; cpp: 79,781; sh: 18,355; perl: 3,218; makefile: 1,611; yacc: 289; sed: 16
file content (99 lines) | stat: -rw-r--r-- 1,697 bytes parent folder | download | duplicates (11)
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
/*
** Copyright 2000 Double Precision, Inc.  See COPYING for
** distribution information.
*/

#include "rfc2045_config.h"
#include	"rfc2646.h"
#include	<stdlib.h>
#include	<string.h>

static const char rcsid[]="$Id: rfc2646.c,v 1.2 2003/03/07 00:47:31 mrsam Exp $";

struct rfc2646parser *rfc2646_alloc( int (*f)(struct rfc2646parser *, int,
					     void *),
				     void *a)
{
	struct rfc2646parser *p=(struct rfc2646parser *)
		calloc(1, sizeof(struct rfc2646parser));

	if (!p)
		return (0);

	p->handler=f;
	p->voidarg=a;
	return (p);
}

#define PARSER_QUOTECNT	1
#define PARSER_LINE	2

int rfc2646_parse_cb(const char *s, size_t c, void *vp)
{
	return (rfc2646_parse( (struct rfc2646parser *)vp, s, c));
}

int rfc2646_parse(struct rfc2646parser *p, const char *s, size_t c)
{
	for ( ; c; --c, ++s)
	{
		if (*s == '\r')
			continue;

		if (!p->parse_mode)
		{
			p->parse_mode=PARSER_QUOTECNT;
			p->quote_depth=0;
			p->linelen=0;
		}

		if (*s == '\n')
		{
			int rc;
			int isflowed=0;

			if (p->linelen && p->line[p->linelen-1] == ' ' &&
			    (p->linelen != 3 || strncmp(p->line, "-- ", 3)))
			{
				--p->linelen;
				isflowed=1;
			}

			p->line[p->linelen]=0;

			p->parse_mode=0;
			rc=(*p->handler)(p, isflowed, p->voidarg);
			if (rc)
				return (rc);
			continue;
		}

		if (p->parse_mode == PARSER_QUOTECNT)
		{
			if (*s == '>')
			{
				++p->quote_depth;
				continue;
			}

			p->parse_mode=PARSER_LINE;
			if (*s == ' ')
			{
				continue;
			}
		}
		if (p->linelen < sizeof(p->line)-1)
			p->line[p->linelen++]= *s;
	}
	return (0);
}

int rfc2646_free(struct rfc2646parser *p)
{
	int rc=0;

	if (p->parse_mode)
		rc=rfc2646_parse(p, "\n", 1);
	free(p);
	return (rc);
}