Changes proposed by Sam.
Showing
1 changed file
with
122 additions
and
50 deletions
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 | ... | ... |
-
Please register or sign in to post a comment