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); | |
139 | time_t rfc822_parsedt(const char *); | |
140 | ||
141 | #define CORESUBJ_RE 1 | |
142 | #define CORESUBJ_FWD 2 | |
143 | ||
144 | char *rfc822_coresubj(const char *, int *); | |
145 | char *rfc822_coresubj_nouc(const char *, int *); | |
146 | char *rfc822_coresubj_keepblobs(const char *s); | |
147 | ||
8d138742 CE |
148 | /* |
149 | ** Display a header. Takes a raw header value, and formats it for display | |
150 | ** in the given character set. | |
151 | ** | |
152 | ** hdrname -- header name. Determines whether the header contains addresses, | |
153 | ** or unstructured data. | |
154 | ** | |
155 | ** hdrvalue -- the actual value to format. | |
156 | ** | |
157 | ** display_func -- output function. | |
158 | ** | |
159 | ** err_func -- if this function returns a negative value, to indicate an error, | |
160 | ** this may be called just prior to the error return to indicate where the | |
161 | ** formatting error is, in the original header. | |
162 | ** | |
163 | ** ptr -- passthrough last argument to display_func or err_func. | |
164 | ** | |
165 | ** repeatedly invokes display_func to pass the formatted contents. | |
166 | ** | |
167 | ** Returns 0 upon success, -1 upon a failure. | |
168 | */ | |
169 | ||
170 | int rfc822_display_hdrvalue(const char *hdrname, | |
171 | const char *hdrvalue, | |
172 | const char *charset, | |
173 | void (*display_func)(const char *, size_t, | |
174 | void *), | |
175 | void (*err_func)(const char *, int, void *), | |
176 | void *ptr); | |
177 | ||
178 | /* | |
179 | ** Like rfc822_display_hdrvalue, except that the converted header is saved in | |
180 | ** a malloc-ed buffer. The pointer to the malloc-ed buffer is returned, the | |
181 | ** caller is responsible for free-ing it. An error condition is indicated | |
182 | ** by a NULL return value. | |
183 | */ | |
184 | ||
185 | char *rfc822_display_hdrvalue_tobuf(const char *hdrname, | |
186 | const char *hdrvalue, | |
187 | const char *charset, | |
188 | void (*err_func)(const char *, int, | |
189 | void *), | |
190 | void *ptr); | |
191 | ||
192 | /* | |
193 | ** Display a recipient's name in a specific character set. | |
194 | ** | |
195 | ** The index-th recipient in the address structure is formatted for the given | |
196 | ** character set. If the index-th entry in the address structure is not | |
197 | ** a recipient address (it represents an obsolete list name indicator), | |
198 | ** this function reproduces it literally. | |
199 | ** | |
200 | ** If the index-th entry in the address structure is a recipient address without | |
201 | ** a name, the address itself is formatted for the given character set. | |
202 | ** | |
203 | ** If 'charset' is NULL, the name is formatted as is, without converting | |
204 | ** it to any character set. | |
205 | ** | |
206 | ** A callback function gets repeatedly invoked to produce the name. | |
207 | ** | |
208 | ** Returns a negative value upon a formatting error. | |
209 | */ | |
210 | ||
211 | int rfc822_display_name(const struct rfc822a *rfcp, int index, | |
212 | const char *chset, | |
213 | void (*print_func)(const char *, size_t, void *), | |
214 | void *ptr); | |
215 | ||
216 | /* | |
217 | ** Display a recipient's name in a specific character set. | |
218 | ** | |
219 | ** Uses rfc822_display_name to place the generated name into a malloc-ed | |
220 | ** buffer. The caller must free it when it is no longer needed. | |
221 | ** | |
222 | ** Returns NULL upon an error. | |
223 | */ | |
224 | ||
225 | char *rfc822_display_name_tobuf(const struct rfc822a *rfcp, int index, | |
226 | const char *chset); | |
227 | ||
228 | /* | |
229 | ** Display names of all addresses. Each name is followed by a newline | |
230 | ** character. | |
231 | ** | |
232 | */ | |
233 | int rfc822_display_namelist(const struct rfc822a *rfcp, | |
234 | const char *chset, | |
235 | void (*print_func)(const char *, size_t, void *), | |
236 | void *ptr); | |
237 | ||
238 | /* | |
239 | ** Display a recipient's address in a specific character set. | |
240 | ** | |
241 | ** The index-th recipient in the address structure is formatted for the given | |
242 | ** character set. If the index-th entry in the address structure is not | |
243 | ** a recipient address (it represents an obsolete list name indicator), | |
244 | ** this function produces an empty string. | |
245 | ** | |
246 | ** If 'charset' is NULL, the address is formatted as is, without converting | |
247 | ** it to any character set. | |
248 | ** | |
249 | ** A callback function gets repeatedly invoked to produce the address. | |
250 | ** | |
251 | ** Returns a negative value upon a formatting error. | |
252 | */ | |
253 | ||
254 | int rfc822_display_addr(const struct rfc822a *rfcp, int index, | |
255 | const char *chset, | |
256 | void (*print_func)(const char *, size_t, void *), | |
257 | void *ptr); | |
258 | ||
259 | /* | |
260 | ** Like rfc822_display_addr, but the resulting displayable string is | |
261 | ** saved in a buffer. Returns a malloc-ed buffer, the caller is responsible | |
262 | ** for free()ing it. A NULL return indicates an error. | |
263 | */ | |
264 | ||
265 | char *rfc822_display_addr_tobuf(const struct rfc822a *rfcp, int index, | |
266 | const char *chset); | |
267 | ||
268 | /* | |
269 | ** Like rfc822_display_addr, but the user@domain gets supplied in a string. | |
270 | */ | |
271 | int rfc822_display_addr_str(const char *tok, | |
272 | const char *chset, | |
273 | void (*print_func)(const char *, size_t, void *), | |
274 | void *ptr); | |
275 | ||
276 | /* | |
277 | ** Like rfc822_display_addr_str, but the resulting displayable string is | |
278 | ** saved in a buffer. Returns a malloc-ed buffer, the caller is responsible | |
279 | ** for free()ing it. A NULL return indicates an error. | |
280 | */ | |
281 | char *rfc822_display_addr_str_tobuf(const char *tok, | |
282 | const char *chset); | |
283 | ||
284 | /* | |
285 | ** address is a hostname, which is IDN-encoded. 'address' may contain an | |
286 | ** optional 'user@', which is preserved. Returns a malloc-ed buffer, the | |
287 | ** caller is responsible for freeing it. | |
288 | */ | |
289 | char *rfc822_encode_domain(const char *address, | |
290 | const char *charset); | |
291 | ||
d9898ee8 | 292 | #ifdef __cplusplus |
293 | } | |
294 | #endif | |
295 | ||
296 | #endif |