Commit | Line | Data |
---|---|---|
d9898ee8 | 1 | /* |
d9898ee8 | 2 | */ |
3 | #ifndef rfc822_h | |
4 | #define rfc822_h | |
5 | ||
6 | /* | |
8d138742 | 7 | ** Copyright 1998 - 2009 Double Precision, Inc. |
d9898ee8 | 8 | ** See COPYING for distribution information. |
9 | */ | |
10 | ||
11 | #if HAVE_CONFIG_H | |
b0322a85 | 12 | #include "rfc822/config.h" |
d9898ee8 | 13 | #endif |
14 | ||
15 | #include <time.h> | |
16 | ||
17 | #ifdef __cplusplus | |
18 | extern "C" { | |
19 | #endif | |
20 | ||
8d138742 CE |
21 | #define RFC822_SPECIALS "()<>[]:;@\\,.\"" |
22 | ||
d9898ee8 | 23 | /* |
24 | ** The text string we want to parse is first tokenized into an array of | |
25 | ** struct rfc822token records. 'ptr' points into the original text | |
26 | ** string, and 'len' has how many characters from 'ptr' belongs to this | |
27 | ** token. | |
28 | */ | |
29 | ||
30 | struct rfc822token { | |
31 | struct rfc822token *next; /* Unused by librfc822, for use by | |
32 | ** clients */ | |
33 | int token; | |
34 | /* | |
35 | Values for token: | |
36 | ||
37 | '(' - comment | |
38 | '"' - quoted string | |
39 | '<', '>', '@', ',', ';', ':', '.', '[', ']', '%', '!', '=', '?', '/' - RFC atoms. | |
40 | 0 - atom | |
41 | */ | |
42 | ||
43 | #define rfc822_is_atom(p) ( (p) == 0 || (p) == '"' || (p) == '(' ) | |
44 | ||
45 | const char *ptr; /* Pointer to value for the token. */ | |
46 | int len; /* Length of token value */ | |
47 | } ; | |
48 | ||
49 | /* | |
50 | ** After the struct rfc822token array is built, it is used to create | |
51 | ** the rfc822addr array, which is the array of addresses (plus | |
52 | ** syntactical fluff) extracted from those text strings. Each rfc822addr | |
53 | ** record has several possible interpretation: | |
54 | ** | |
55 | ** tokens is NULL - syntactical fluff, look in name/nname for tokens | |
56 | ** representing the syntactical fluff ( which is semicolons | |
57 | ** and list name: | |
58 | ** | |
59 | ** tokens is not NULL - actual address. The tokens representing the actual | |
60 | ** address is in tokens/ntokens. If there are comments in | |
61 | ** the address that are possible "real name" for the address | |
62 | ** they are saved in name/nname (name may be null if there | |
63 | ** is none). | |
64 | ** If nname is 1, and name points to a comment token, | |
65 | ** the address was specified in old-style format. Otherwise | |
66 | ** the address was specified in new-style route-addr format. | |
67 | ** | |
68 | ** The tokens and name pointers are set to point to the original rfc822token | |
69 | ** array. | |
70 | */ | |
71 | ||
72 | struct rfc822addr { | |
73 | struct rfc822token *tokens; | |
74 | struct rfc822token *name; | |
75 | } ; | |
76 | ||
77 | /*************************************************************************** | |
78 | ** | |
79 | ** rfc822 tokens | |
80 | ** | |
81 | ***************************************************************************/ | |
82 | ||
83 | struct rfc822t { | |
84 | struct rfc822token *tokens; | |
85 | int ntokens; | |
86 | } ; | |
87 | ||
d9898ee8 | 88 | struct rfc822t *rfc822t_alloc_new(const char *p, |
89 | void (*err_func)(const char *, int, void *), void *); | |
90 | /* Parse addresses */ | |
91 | ||
92 | void rfc822t_free(struct rfc822t *); /* Free rfc822 structure */ | |
93 | ||
94 | void rfc822tok_print(const struct rfc822token *, void (*)(char, void *), void *); | |
95 | /* Print the tokens */ | |
96 | ||
97 | /*************************************************************************** | |
98 | ** | |
99 | ** rfc822 addresses | |
100 | ** | |
101 | ***************************************************************************/ | |
102 | ||
103 | struct rfc822a { | |
104 | struct rfc822addr *addrs; | |
105 | int naddrs; | |
106 | } ; | |
107 | ||
108 | struct rfc822a *rfc822a_alloc(struct rfc822t *); | |
109 | void rfc822a_free(struct rfc822a *); /* Free rfc822 structure */ | |
110 | ||
111 | void rfc822_deladdr(struct rfc822a *, int); | |
112 | ||
113 | /* rfc822_print "unparses" the rfc822 structure. Each rfc822addr is "printed" | |
114 | (via the attached function). NOTE: instead of separating addresses by | |
115 | commas, the print_separator function is called. | |
116 | */ | |
117 | ||
8d138742 | 118 | int rfc822_print(const struct rfc822a *a, |
d9898ee8 | 119 | void (*print_func)(char, void *), |
120 | void (*print_separator)(const char *, void *), void *); | |
121 | ||
122 | /* rfc822_print_common is an internal function */ | |
123 | ||
8d138742 CE |
124 | int rfc822_print_common(const struct rfc822a *a, |
125 | char *(*decode_func)(const char *, const char *, int), | |
126 | const char *chset, | |
127 | void (*print_func)(char, void *), | |
128 | void (*print_separator)(const char *, void *), void *); | |
d9898ee8 | 129 | |
130 | /* Extra functions */ | |
131 | ||
132 | char *rfc822_gettok(const struct rfc822token *); | |
133 | char *rfc822_getaddr(const struct rfc822a *, int); | |
d9898ee8 | 134 | char *rfc822_getaddrs(const struct rfc822a *); |
135 | char *rfc822_getaddrs_wrap(const struct rfc822a *, int); | |
136 | ||
137 | void rfc822_mkdate_buf(time_t, char *); | |
138 | const char *rfc822_mkdate(time_t); | |
d50284c4 CE |
139 | |
140 | int rfc822_parsedate_chk(const char *, time_t *); | |
d9898ee8 | 141 | |
142 | #define CORESUBJ_RE 1 | |
143 | #define CORESUBJ_FWD 2 | |
144 | ||
145 | char *rfc822_coresubj(const char *, int *); | |
146 | char *rfc822_coresubj_nouc(const char *, int *); | |
147 | char *rfc822_coresubj_keepblobs(const char *s); | |
148 | ||
8d138742 CE |
149 | /* |
150 | ** Display a header. Takes a raw header value, and formats it for display | |
151 | ** in the given character set. | |
152 | ** | |
153 | ** hdrname -- header name. Determines whether the header contains addresses, | |
154 | ** or unstructured data. | |
155 | ** | |
156 | ** hdrvalue -- the actual value to format. | |
157 | ** | |
158 | ** display_func -- output function. | |
159 | ** | |
160 | ** err_func -- if this function returns a negative value, to indicate an error, | |
161 | ** this may be called just prior to the error return to indicate where the | |
162 | ** formatting error is, in the original header. | |
163 | ** | |
164 | ** ptr -- passthrough last argument to display_func or err_func. | |
165 | ** | |
166 | ** repeatedly invokes display_func to pass the formatted contents. | |
167 | ** | |
168 | ** Returns 0 upon success, -1 upon a failure. | |
169 | */ | |
170 | ||
171 | int rfc822_display_hdrvalue(const char *hdrname, | |
172 | const char *hdrvalue, | |
173 | const char *charset, | |
174 | void (*display_func)(const char *, size_t, | |
175 | void *), | |
176 | void (*err_func)(const char *, int, void *), | |
177 | void *ptr); | |
178 | ||
179 | /* | |
180 | ** Like rfc822_display_hdrvalue, except that the converted header is saved in | |
181 | ** a malloc-ed buffer. The pointer to the malloc-ed buffer is returned, the | |
182 | ** caller is responsible for free-ing it. An error condition is indicated | |
183 | ** by a NULL return value. | |
184 | */ | |
185 | ||
186 | char *rfc822_display_hdrvalue_tobuf(const char *hdrname, | |
187 | const char *hdrvalue, | |
188 | const char *charset, | |
189 | void (*err_func)(const char *, int, | |
190 | void *), | |
191 | void *ptr); | |
192 | ||
193 | /* | |
194 | ** Display a recipient's name in a specific character set. | |
195 | ** | |
196 | ** The index-th recipient in the address structure is formatted for the given | |
197 | ** character set. If the index-th entry in the address structure is not | |
198 | ** a recipient address (it represents an obsolete list name indicator), | |
199 | ** this function reproduces it literally. | |
200 | ** | |
201 | ** If the index-th entry in the address structure is a recipient address without | |
202 | ** a name, the address itself is formatted for the given character set. | |
203 | ** | |
204 | ** If 'charset' is NULL, the name is formatted as is, without converting | |
205 | ** it to any character set. | |
206 | ** | |
207 | ** A callback function gets repeatedly invoked to produce the name. | |
208 | ** | |
209 | ** Returns a negative value upon a formatting error. | |
210 | */ | |
211 | ||
212 | int rfc822_display_name(const struct rfc822a *rfcp, int index, | |
213 | const char *chset, | |
214 | void (*print_func)(const char *, size_t, void *), | |
215 | void *ptr); | |
216 | ||
217 | /* | |
218 | ** Display a recipient's name in a specific character set. | |
219 | ** | |
220 | ** Uses rfc822_display_name to place the generated name into a malloc-ed | |
221 | ** buffer. The caller must free it when it is no longer needed. | |
222 | ** | |
223 | ** Returns NULL upon an error. | |
224 | */ | |
225 | ||
226 | char *rfc822_display_name_tobuf(const struct rfc822a *rfcp, int index, | |
227 | const char *chset); | |
228 | ||
229 | /* | |
230 | ** Display names of all addresses. Each name is followed by a newline | |
231 | ** character. | |
232 | ** | |
233 | */ | |
234 | int rfc822_display_namelist(const struct rfc822a *rfcp, | |
235 | const char *chset, | |
236 | void (*print_func)(const char *, size_t, void *), | |
237 | void *ptr); | |
238 | ||
239 | /* | |
240 | ** Display a recipient's address in a specific character set. | |
241 | ** | |
242 | ** The index-th recipient in the address structure is formatted for the given | |
243 | ** character set. If the index-th entry in the address structure is not | |
244 | ** a recipient address (it represents an obsolete list name indicator), | |
245 | ** this function produces an empty string. | |
246 | ** | |
247 | ** If 'charset' is NULL, the address is formatted as is, without converting | |
248 | ** it to any character set. | |
249 | ** | |
250 | ** A callback function gets repeatedly invoked to produce the address. | |
251 | ** | |
252 | ** Returns a negative value upon a formatting error. | |
253 | */ | |
254 | ||
255 | int rfc822_display_addr(const struct rfc822a *rfcp, int index, | |
256 | const char *chset, | |
257 | void (*print_func)(const char *, size_t, void *), | |
258 | void *ptr); | |
259 | ||
260 | /* | |
261 | ** Like rfc822_display_addr, but the resulting displayable string is | |
262 | ** saved in a buffer. Returns a malloc-ed buffer, the caller is responsible | |
263 | ** for free()ing it. A NULL return indicates an error. | |
264 | */ | |
265 | ||
266 | char *rfc822_display_addr_tobuf(const struct rfc822a *rfcp, int index, | |
267 | const char *chset); | |
268 | ||
269 | /* | |
270 | ** Like rfc822_display_addr, but the user@domain gets supplied in a string. | |
271 | */ | |
272 | int rfc822_display_addr_str(const char *tok, | |
273 | const char *chset, | |
274 | void (*print_func)(const char *, size_t, void *), | |
275 | void *ptr); | |
276 | ||
277 | /* | |
278 | ** Like rfc822_display_addr_str, but the resulting displayable string is | |
279 | ** saved in a buffer. Returns a malloc-ed buffer, the caller is responsible | |
280 | ** for free()ing it. A NULL return indicates an error. | |
281 | */ | |
282 | char *rfc822_display_addr_str_tobuf(const char *tok, | |
283 | const char *chset); | |
284 | ||
285 | /* | |
286 | ** address is a hostname, which is IDN-encoded. 'address' may contain an | |
287 | ** optional 'user@', which is preserved. Returns a malloc-ed buffer, the | |
288 | ** caller is responsible for freeing it. | |
289 | */ | |
290 | char *rfc822_encode_domain(const char *address, | |
291 | const char *charset); | |
292 | ||
d9898ee8 | 293 | #ifdef __cplusplus |
294 | } | |
295 | #endif | |
296 | ||
297 | #endif |