Index: address.texi =================================================================== RCS file: /cvs/mailutils/doc/address.texi,v retrieving revision 1.1 diff -u -r1.1 address.texi --- address.texi 2001/03/08 04:50:07 1.1 +++ address.texi 2001/03/09 05:04:49 @@ -3,92 +3,32 @@ The @code{address_t} object is used to hold information about a parsed RFC822 address list, and is an opaque data structure to the user. Functions are provided to retrieve information -about the address list. An address list is a sequence of addresses, each -of which has four components: an optional phrase describing the address, the -local-part of the address, the domain of the address, and an optional -comment field. - -If the phrase is present it is probably the personal name -associated with the the address, if not, the comment may contain some -identifying information. - -Since the address-list may contain multiple addresses, they are accessed -by a @strong{one-based index number}, @var{no}. - -Comment: Why is this one-based? nobody -familiar with C would ever expect that! - -The size of a particular component -may be queried by providing @code{0} for the @var{len} of the buffer, -in which case the buffer is optional and if @var{n} is provided address@hidden is assigned the length of the component string. - -If @var{len} -is greater than @code{0} it is the length of the buffer @var{buf}, and -as much of the component as possible will be copied into the buffer. +about a address in the address list. -Comments: - -The API isn't complete, there are useful things you can't do. - -There needs to be a way of accessing the local-part and the -domain of an email address seperately, the syntax of local-part is too complex -to expect somebody to parse it, in particular strchring for '@@' -will fail if there is an '@@' in the local-part, which is valid if -its quoted or escaped. - -You can't create an address or an address list. - -Creating one should apropriately quote unsafe characters in the local -part and phrase/personal name, not allow a comment (its deprecated), etc. - -What about groups? They are easy to parse, but a pain from an api point -of view. _address, instead of being a pure linked list, could -be more tree-like, so each _address also contained and _address* group -member. If there was a group, then email would be the name of the group, -something like "my special group: ;", and group would be the (possibly -empty) list of addresses in the group, and each of those addresses -could in turn be a group, etc. - -This data structure reflects the structure of an address ok, but doesn't -address (;-)) what happens if you had a program that just wanted to print -out all the recipients email addresses. The @var{no} could still be -a linear index into the tree, so those not wanting to know could not -know, and the group nodes could silently dissappear. - -But what if you wanted to iterate the whole tree? - address_is_group(addr, no)? address_get_group_name(addr, no)? - address_get_group(addr, &addr)? - -For creating, maybe the easy way is to splice an address list. - -address_create(&addr, NULL) +Several address functions have a set of common arguments, which are described +here to avoid repetition. -address_insert(addr, -1, "Big John", "bluesman", "yahoo.com"); +Since an address-list may contain multiple addresses, they are accessed +by a @strong{one-based} index number, @var{no}. The index is one-based +because pop, imap, and other message stores commonly use one-based +counts to access messages and attributes of messages. + +If @var{len} is greater than @code{0} it is the length of the buffer address@hidden, and as much of the component as possible will be copied +into the buffer. The buffer will be nul terminated. + +The size of a particular component may be queried by providing @code{0} +for the @var{len} of the buffer, in which case the buffer is optional. +In this case, if @var{n} is provided address@hidden is assigned the length of +the component string. -// -1 is the end, anything else is position to be inserted at, for ex. - -address_create(&group, NULL) - -address_insert(group, -1, "Sam", "sroberts", "uniserve.com"); +Comments: -address_insert(group, -1, "Joe @ \"home\"", "joe", "uniserve.com"); +What happens if @var{no} is past the end of the list? I think you +just get zero-length output, but it should be an error, maybe EINVAL. -address_insert_group(addr, group, "the uniserve boys"); +Musings: -This would be: address@hidden - Big John , the uniserve boys: Sam - , "Joe @@ \"home\"" ; address@hidden example - -This is just a sketch of what I think should be conceptually possible -in a complete address parser class. Basically the goals are to be -able to see the structure of an RFC822 address exactly (except for -comments... they get munged together if present, but what the hell, -they're comments!) and to build as complex an address as is -possible. Simple things should still be simple. - Two problems are domain literals, and non-ascii characters. I think domain literals should be parsed from [127.0.0.1] into the more commonly groked 127.0.0.1 when somebody does a get_domain() @@ -105,7 +45,9 @@ @deftypefun int address_create (address_t address@hidden, const char address@hidden) This function allocates and initializes @var{addr} by parsing the -RFC822 address-list @var{string}. +RFC822 address-list @var{string}. Parsing is best effort, if the address@hidden isn't a valid RFC822 syntax list of addresses, then +the results are undefined. The return value is @code{0} on success and a code number on error conditions: @table @code @@ -117,10 +59,64 @@ @deftypefun void address_destroy (address_t address@hidden) The @var{addr} is destroyed. @end deftypefun + address@hidden int address_get_email (address_t address@hidden, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n}) + +Acesses the @var{no}th email address component of the address list. This +address is the plain email address, correctly quoted, suitable for +using in an smtp dialog, for example, or as the address part of +a contact book entry. + +The return value is @code{0} on success and a code number on error conditions: address@hidden @code address@hidden EINVAL address@hidden is NULL. address@hidden table address@hidden deftypefun + address@hidden int address_get_personal (address_t address@hidden, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n}) + +Acesses the personal phrase describing the @var{no}th email address. This +phrase is optional, so may not be present. + +The return value is @code{0} on success and a code number on error conditions: address@hidden @code address@hidden EINVAL address@hidden is NULL. address@hidden table address@hidden deftypefun + + address@hidden int address_get_comments (address_t address@hidden, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n}) + +Acesses the comments extracted while parsing the @var{no}th email address. +These comments have no defined meaning, but in the absence of the personal +descriptive phrase, may describe the email address. + +The return value is @code{0} on success and a code number on error conditions: address@hidden @code address@hidden EINVAL address@hidden is NULL. address@hidden table address@hidden deftypefun + + address@hidden int address_to_string (address_t address@hidden, char* @var{buf}, size_t @var{len}, size_t* @var{n}) + +Returns the entire address list as a single RFC822 formatted address +list. + +The return value is @code{0} on success and a code number on error conditions: address@hidden @code address@hidden EINVAL address@hidden is NULL. address@hidden table address@hidden deftypefun + + address@hidden int address_get_count (address_t address@hidden, size_t* @var{no}) address@hidden int address_get_email (address_t address@hidden, - size_t no, char* buf, size_t len, size_t* n) -Acesses the @var{no}th email address component. +Returns the number of addresses in the address list. The return value is @code{0} on success and a code number on error conditions: @table @code @@ -128,4 +124,58 @@ @var{addr} is NULL. @end table @end deftypefun + + address@hidden Example address@hidden +#include +#include + +int +main(int argc, const char *argv[]) address@hidden + for(argc = 1; argv[argc]; argc++) + @{ + const char* str = argv[argc]; + address_t address = NULL; + + address_create(&address, str); + + printf("'%s' ->\n", str); + @{ + size_t no = 0; + size_t pcount; + + address_get_count(address, &pcount); + + printf(" pcount %d\n", pcount); + + for(no = 1; no <= pcount; no++) + @{ + char buf[BUFSIZ]; + + address_get_personal(address, no, buf, sizeof(buf), 0); + + printf(" personal '%s'\n", buf); + + address_get_comments(address, no, buf, sizeof(buf), 0); + + printf(" comments '%s'\n", buf); + + address_get_email(address, no, buf, sizeof(buf), 0); + + printf(" email '%s'\n", buf); + + address_to_string(address, buf, sizeof(buf), 0); + + printf(" to_string '%s'\n", buf); + @} + @} + + address_destroy(&address); + @} + + return 0; address@hidden address@hidden example