Go to the first, previous, next, last section, table of contents.
/* Prefix address_ is reserved */
#include <mailutils/address.h>
The Internet address format is defined in RFC 822. RFC 822 has been updated, and is now superceeded by RFC 2822, which makes some corrections and clarifications. References to RFC 822 here apply equally to RFC 2822.
The RFC 822 format is more flexible than many people realize, here is a quick summary of the syntax this parser implements, see RFC 822 for the details. "[]" pairs mean "optional", "/" means "one or the other", and double-quoted characters are literals.
addr-spec = local-part "@" domain mailbox = addr-spec ["(" display-name ")"] / [display-name] "<" [route] addr-spec ">" mailbox-list = mailbox ["," mailbox-list] group = display-name ":" [mailbox-list] ";" address = mailbox / group / unix-mbox address-list = address ["," address-list]
unix-mbox is a non-standard extension meant to deal with the common practice of using user names as addresses in mail utilities. It allows addresses such as "root" to be parsed correctly. These are NOT valid internet email addresses, they must be qualified before use.
Several address functions have a set of common arguments with consistent semantics, these are described here to avoid repetition.
Since an address-list may contain multiple addresses, they are accessed by a one-based index number, 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 len is greater than 0
it is the length of the buffer
buf, and as much of the component as possible will be copied
into the buffer. The buffer will be null terminated.
The size of a particular component may be queried by providing 0
for the len of the buffer, in which case the buffer is optional.
In this case, if n is provided *n is assigned the length of
the component string.
@macro ADDRESSENOMEM
null
.
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 an address in the address list.
0
on success and a code number on error conditions:
0
on success and a code number on error conditions:
0
on success and a code number on error conditions:
0
on success and a code number on error conditions:
0
length for a unix-mbox.
The return value is 0
on success and a code number on error conditions:
0
on success and a code number on error conditions:
0
length for a unix-mbox.
The return value is 0
on success and a code number on error conditions:
0
on success and a code number on error conditions:
1
if this address is just the name of a group,
0
otherwise. This is faster than checking if the address has
a non-zero length personal, and a zero-length local_part and domain.
yes can be null
, though that doesn't serve much purpose other
than determining that no refers to an address.
Currently, there is no way to determine the end of the group.
The return value is 0
on success and a code number on error conditions:
0
on success and a code number on error conditions:
null
, the count is 0
. If count is
not null
, the count will be written to *count.
The return value is 0
.
#include <stdio.h> #include <errno.h> #include <mailutils/address.h> #define EPARSE ENOENT static const char* err_name(int e) { struct { int e; const char* s; } map[] = { #define E(e) { e, #e }, E(ENOENT) E(EINVAL) E(ENOMEM) #undef E { 0, NULL } }; static char s[sizeof(int) * 8 + 3]; int i; for(i = 0; map[i].s; i++) { if(map[i].e == e) return map[i].s; } sprintf(s, "[%d]", e); return s; } static int parse(const char* str) { size_t no = 0; size_t pcount = 0; int status; char buf[BUFSIZ]; address_t address = NULL; status = address_create(&address, str); address_get_count(address, &pcount); if(status) { printf("%s=> error %s\n\n", str, err_name(status)); return 0; } else { printf("%s=> pcount %d\n", str, pcount); } for(no = 1; no <= pcount; no++) { size_t got = 0; int isgroup; address_is_group(address, no, &isgroup); printf("%d ", no); if(isgroup) { address_get_personal(address, no, buf, sizeof(buf), &got); printf("group <%s>\n", buf); } else { address_get_email(address, no, buf, sizeof(buf), 0); printf("email <%s>\n", buf); } address_get_personal(address, no, buf, sizeof(buf), &got); if(got && !isgroup) printf(" personal <%s>\n", buf); address_get_comments(address, no, buf, sizeof(buf), &got); if(got) printf(" comments <%s>\n", buf); address_get_local_part(address, no, buf, sizeof(buf), &got); if(got) { printf(" local-part <%s>", buf); address_get_domain(address, no, buf, sizeof(buf), &got); if(got) printf(" domain <%s>", buf); printf("\n"); } address_get_route(address, no, buf, sizeof(buf), &got); if(got) printf(" route <%s>\n", buf); } address_destroy(&address); printf("\n"); return 0; } static int parseinput(void) { char buf[BUFSIZ]; while(fgets(buf, sizeof(buf), stdin) != 0) { buf[strlen(buf) - 1] = 0; parse(buf); } return 0; } int main(int argc, const char *argv[]) { argc = 1; if(!argv[argc]) { return parseinput(); } for(; argv[argc]; argc++) { if(strcmp(argv[argc], "-") == 0) { parseinput(); } else { parse(argv[argc]); } } return 0; }
Go to the first, previous, next, last section, table of contents.