Commit 78f7eeb6 78f7eeb606e1c1b9134170d448c7d3349180b572 by Alain Magloire

Changes proposed by Sam.

1 parent a63a8ee5
1 @code{#include <mailutils/mailbox.h>} 1 @code{#include <mailutils/mailbox.h>}
2 @deftp {Data Type} address_t
3 The @code{address_t} object is used to hold information about a parsed
4 RFC822 address list, and is an opaque
5 data structure to the user. Functions are provided to retrieve information
6 about a address in the address list.
7 2
8 Several address functions have a set of common arguments, which are described 3 The internet address format is defined in RFC 822. RFC 822 is in the
9 here to avoid repetition. 4 process of being updated, and will soon be superceeded by a new RFC
5 that makes some corrections and clarifications. References to RFC 822
6 here apply equally to the new RFC.
7
8 The RFC 822 format is more flexible than many people realize, here
9 is a quick summary of the syntax this parser implements, see
10 RFC 822 for the details. "[]" pairs mean "optional", "/" means "one or
11 the other", and double-quoted characters are literals.
12
13 @example
14 address-list = address ["," address-list]
15 address = mailbox / group
16 mailbox = addr-spec ["(" personal ")"] /
17 [personal] "<" [route] addr-spec ">"
18 addr-spec = local-part "@" domain
19 group = phrase ":" mailbox-list ";"
20
21 mailbox-list = mailbox ["," mailbox-list]
22 @end example
23
24 Several address functions have a set of common arguments with consistent
25 semantics, these are described here to avoid repetition.
10 26
11 Since an address-list may contain multiple addresses, they are accessed 27 Since an address-list may contain multiple addresses, they are accessed
12 by a @strong{one-based} index number, @var{no}. The index is one-based 28 by a @strong{one-based} index number, @var{no}. The index is one-based
...@@ -22,37 +38,43 @@ for the @var{len} of the buffer, in which case the buffer is optional. ...@@ -22,37 +38,43 @@ for the @var{len} of the buffer, in which case the buffer is optional.
22 In this case, if @var{n} is provided *@var{n} is assigned the length of 38 In this case, if @var{n} is provided *@var{n} is assigned the length of
23 the component string. 39 the component string.
24 40
25 Comments: 41 @macro ADDRESSENOMEM
42 @item ENOMEM
43 Not enough memory to allocate resources.
44 @end macro
26 45
27 What happens if @var{no} is past the end of the list? I think you 46 @macro ADDRESSEPARSE
28 just get zero-length output, but it should be an error, maybe EINVAL. 47 @item ENOENT
48 Invalid RFC822 syntax, parsing failed.
49 @end macro
29 50
30 Musings: 51 @macro ADDRESSENOENT
52 @item ENOENT
53 The index @var{no} is outside of the range of available addresses.
54 @end macro
31 55
32 Two problems are domain literals, and non-ascii characters. I 56 @macro ADDRESSEINVAL
33 think domain literals should be parsed from [127.0.0.1] into 57 @item EINVAL
34 the more commonly groked 127.0.0.1 when somebody does a get_domain() 58 Invalid usage, usually a required argument was @code{nul}.
35 on one, and that if somebody wants to provide one as a domain, they 59 @end macro
36 can.
37 60
38 Non ascii chars are uglier, perhaps a warning? Perhaps a non-strict 61 @deftp {Data Type} address_t
39 switch that makes it an error, and otherwise if they want umlauts 62 The @code{address_t} object is used to hold information about a parsed
40 and utf-8 in the strings, just allow it? The machinery to encode 63 RFC822 address list, and is an opaque
41 and decode header fields according to the MIME spec doesn't really 64 data structure to the user. Functions are provided to retrieve information
42 belong here, it's a layer on top of rfc822. 65 about an address in the address list.
43 66
44 @end deftp 67 @end deftp
45 68
46 @deftypefun int address_create (address_t *@var{addr}, const char *@var{string}) 69 @deftypefun int address_create (address_t *@var{addr}, const char *@var{string})
47 This function allocates and initializes @var{addr} by parsing the 70 This function allocates and initializes @var{addr} by parsing the
48 RFC822 address-list @var{string}. Parsing is best effort, if the 71 RFC822 address-list @var{string}.
49 @var{string} isn't a valid RFC822 syntax list of addresses, then
50 the results are undefined.
51 72
52 The return value is @code{0} on success and a code number on error conditions: 73 The return value is @code{0} on success and a code number on error conditions:
53 @table @code 74 @table @code
54 @item ENOMEM 75 @ADDRESSEINVAL
55 Not enough memory to allocate resources. 76 @ADDRESSENOMEM
77 @ADDRESSEPARSE
56 @end table 78 @end table
57 @end deftypefun 79 @end deftypefun
58 80
...@@ -69,20 +91,23 @@ a contact book entry. ...@@ -69,20 +91,23 @@ a contact book entry.
69 91
70 The return value is @code{0} on success and a code number on error conditions: 92 The return value is @code{0} on success and a code number on error conditions:
71 @table @code 93 @table @code
72 @item EINVAL 94 @ADDRESSEINVAL
73 @var{addr} is NULL. 95 @ADDRESSENOENT
74 @end table 96 @end table
75 @end deftypefun 97 @end deftypefun
76 98
77 @deftypefun int address_get_personal (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n}) 99 @deftypefun int address_get_personal (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
78 100
79 Acesses the personal phrase describing the @var{no}th email address. This 101 Acesses the personal phrase describing the @var{no}th email address. This
80 phrase is optional, so may not be present. 102 personal is optional, so may not be present. If it is not present, but
103 there is an RFC822 comment after the address, that comment will be
104 returned as the personal phrase, as this is a common usage of the comment
105 even though it is not defined in the internet mail standard.
81 106
82 The return value is @code{0} on success and a code number on error conditions: 107 The return value is @code{0} on success and a code number on error conditions:
83 @table @code 108 @table @code
84 @item EINVAL 109 @ADDRESSEINVAL
85 @var{addr} is NULL. 110 @ADDRESSENOENT
86 @end table 111 @end table
87 @end deftypefun 112 @end deftypefun
88 113
...@@ -90,41 +115,88 @@ The return value is @code{0} on success and a code number on error conditions: ...@@ -90,41 +115,88 @@ The return value is @code{0} on success and a code number on error conditions:
90 @deftypefun int address_get_comments (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n}) 115 @deftypefun int address_get_comments (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
91 116
92 Acesses the comments extracted while parsing the @var{no}th email address. 117 Acesses the comments extracted while parsing the @var{no}th email address.
93 These comments have no defined meaning, but in the absence of the personal 118 These comments have no defined meaning, and are not currently collected.
94 descriptive phrase, may describe the email address.
95 119
96 The return value is @code{0} on success and a code number on error conditions: 120 The return value is @code{0} on success and a code number on error conditions:
97 @table @code 121 @table @code
98 @item EINVAL 122 @ADDRESSEINVAL
99 @var{addr} is NULL. 123 @ADDRESSENOENT
100 @end table 124 @end table
101 @end deftypefun 125 @end deftypefun
102 126
103 127
104 @deftypefun int address_to_string (address_t *@var{addr}, char* @var{buf}, size_t @var{len}, size_t* @var{n}) 128 @deftypefun int address_get_email (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
105 129
106 Returns the entire address list as a single RFC822 formatted address 130 Acesses the email addr-spec extracted while
107 list. 131 parsing the @var{no}th email address.
108 132
109 The return value is @code{0} on success and a code number on error conditions: 133 The return value is @code{0} on success and a code number on error conditions:
110 @table @code 134 @table @code
111 @item EINVAL 135 @ADDRESSEINVAL
112 @var{addr} is NULL. 136 @ADDRESSENOENT
113 @end table 137 @end table
114 @end deftypefun 138 @end deftypefun
115 139
140 @deftypefun int address_get_local_part (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
116 141
117 @deftypefun int address_get_count (address_t *@var{addr}, size_t* @var{no}) 142 Acesses the local-part of an email addr-spec extracted while
143 parsing the @var{no}th email address.
118 144
119 Returns the number of addresses in the address list. 145 The return value is @code{0} on success and a code number on error conditions:
146 @table @code
147 @ADDRESSEINVAL
148 @ADDRESSENOENT
149 @end table
150 @end deftypefun
151
152 @deftypefun int address_get_domain (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
153
154 Acesses the domain of an email addr-spec extracted while
155 parsing the @var{no}th email address.
120 156
121 The return value is @code{0} on success and a code number on error conditions: 157 The return value is @code{0} on success and a code number on error conditions:
122 @table @code 158 @table @code
123 @item EINVAL 159 @ADDRESSEINVAL
124 @var{addr} is NULL. 160 @ADDRESSENOENT
125 @end table 161 @end table
126 @end deftypefun 162 @end deftypefun
127 163
164 @deftypefun int address_get_route (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
165
166 Acesses the route of an email addr-spec extracted while
167 parsing the @var{no}th email address. This is a rarely used RFC822 address
168 syntax, but is legal in SMTP as well. The entire route is returned as
169 a string, those wishing to parse it should look at <mailutils/parse822.h>.
170
171 The return value is @code{0} on success and a code number on error conditions:
172 @table @code
173 @ADDRESSEINVAL
174 @ADDRESSENOENT
175 @end table
176 @end deftypefun
177
178 @deftypefun int address_to_string (address_t *@var{addr}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
179
180 Returns the entire address list as a single RFC822 formatted address
181 list.
182
183 The return value is @code{0} on success and a code number on error conditions:
184 @table @code
185 @ADDRESSEINVAL
186 @ADDRESSENOMEM
187 @end table
188 @end deftypefun
189
190
191 @deftypefun int address_get_count (address_t @var{addr}, size_t* @var{count})
192
193 Returns a count of the addresses in the address list.
194
195 If @var{addr} is @code{nul}, the count is @code{0}. If @var{count} is
196 not @code{nul}, the count will be written to *@var{count}.
197
198 The return value is @code{0}.
199 @end deftypefun
128 200
129 @section Example 201 @section Example
130 @example 202 @example
...@@ -158,17 +230,17 @@ main(int argc, const char *argv[]) ...@@ -158,17 +230,17 @@ main(int argc, const char *argv[])
158 230
159 printf(" personal '%s'\n", buf); 231 printf(" personal '%s'\n", buf);
160 232
161 address_get_comments(address, no, buf, sizeof(buf), 0); 233 address_get_local_part(address, no, buf, sizeof(buf), 0);
162 234
163 printf(" comments '%s'\n", buf); 235 printf(" local_part '%s'\n", buf);
164 236
165 address_get_email(address, no, buf, sizeof(buf), 0); 237 address_get_domain(address, no, buf, sizeof(buf), 0);
166 238
167 printf(" email '%s'\n", buf); 239 printf(" domain '%s'\n", buf);
168 240
169 address_to_string(address, buf, sizeof(buf), 0); 241 address_get_email(address, no, buf, sizeof(buf), 0);
170 242
171 printf(" to_string '%s'\n", buf); 243 printf(" email '%s'\n", buf);
172 @} 244 @}
173 @} 245 @}
174 246
......