Merge branch 'debian'
[hcoop/debian/courier-authlib.git] / libs / rfc822 / rfc822hdr.c
CommitLineData
d9898ee8 1/*
b0322a85 2** Copyright 2001-2011 Double Precision, Inc.
d9898ee8 3** See COPYING for distribution information.
4*/
5
b0322a85 6#include "config.h"
d9898ee8 7#include <stdio.h>
8#include <ctype.h>
9#include <stdlib.h>
10#include <string.h>
11#include "rfc822hdr.h"
12
d9898ee8 13
14/*
15** Read the next mail header.
16*/
17
18int rfc822hdr_read(struct rfc822hdr *h, FILE *f, off_t *pos, off_t epos)
19{
20 size_t n=0;
21 int c;
22
23 for (;;)
24 {
25 if ( n >= h->hdrsize)
26 {
27 size_t hn=h->hdrsize + 1024;
28 char *p= h->header ? realloc(h->header, hn):
29 malloc(hn);
30
31 if (!p)
32 return (-1);
33
34 h->header=p;
35 h->hdrsize=hn;
36 }
37
38 if (pos && *pos >= epos)
39 {
40 h->header[n]=0;
41 break;
42 }
43
44 c=getc(f);
45 if (c == EOF)
46 {
47 if (pos)
48 *pos=epos;
49 h->header[n]=0;
50 break;
51 }
52 if (pos)
53 ++*pos;
54
55 h->header[n]=c;
56 if (c == '\n')
57 {
58 if (n == 0)
59 {
60 if (pos)
61 *pos=epos;
62 h->header[n]=0;
63 break;
64 }
65
66 c=getc(f);
67 if (c != EOF)
68 ungetc(c, f);
69 if (c == '\n' || c == '\r' ||
70 !isspace((int)(unsigned char)c))
71 {
72 h->header[n]=0;
73 break;
74 }
75 }
76 n++;
77 if (h->maxsize && n + 2 > h->maxsize)
78 --n;
79 }
80
81 if (n == 0)
82 {
83 if (pos)
84 *pos=epos;
85 h->value=h->header;
86 return (1);
87 }
88
89 for (h->value=h->header; *h->value; ++h->value)
90 {
91 if (*h->value == ':')
92 {
93 *h->value++=0;
94 while (*h->value &&
95 isspace((int)(unsigned char)*h->value))
96 ++h->value;
97 break;
98 }
99 }
100 return (0);
101}
102
103void rfc822hdr_fixname(struct rfc822hdr *h)
104{
105 char *p;
106
107 for (p=h->header; *p; p++)
108 {
109 *p=tolower((int)(unsigned char)*p);
110 }
111}
112
113void rfc822hdr_collapse(struct rfc822hdr *h)
114{
115 char *p, *q;
116
117 for (p=q=h->value; *p; )
118 {
119 if (*p == '\n')
120 {
121 while (*p && isspace((int)(unsigned char)*p))
122 ++p;
123 *q++=' ';
124 continue;
125 }
126 *q++ = *p++;
127 }
128 *q=0;
129}
8d138742 130
b0322a85
CE
131/* This is, basically, a case-insensitive US-ASCII comparison function */
132
133#define lc(x) ((x) >= 'A' && (x) <= 'Z' ? (x) + ('a'-'A'):(x))
134
135int rfc822hdr_namecmp(const char *a, const char *b)
136{
137 int rc;
138
139 while ((rc=(int)(unsigned char)lc(*a) - (int)(unsigned char)lc(*b))==0)
140 {
141 if (!*a)
142 return 0;
143 ++a;
144 ++b;
145 }
146
147 return rc;
148}
149
8d138742
CE
150int rfc822hdr_is_addr(const char *hdr)
151{
b0322a85
CE
152 return rfc822hdr_namecmp(hdr, "from") == 0 ||
153 rfc822hdr_namecmp(hdr, "to") == 0 ||
154 rfc822hdr_namecmp(hdr, "cc") == 0 ||
155 rfc822hdr_namecmp(hdr, "bcc") == 0 ||
156 rfc822hdr_namecmp(hdr, "resent-from") == 0 ||
157 rfc822hdr_namecmp(hdr, "resent-to") == 0 ||
158 rfc822hdr_namecmp(hdr, "resent-cc") == 0 ||
159 rfc822hdr_namecmp(hdr, "resent-bcc") == 0;
8d138742 160}