Commit b8975450 b89754507e2bdc1e147741d748f468e745c26bcf by Sergey Poznyakoff

Reorganized directory structure

1 parent 5d3b3b4f
@example
@code{/* Prefix @emph{address_} is reserved */}
@code{#include <mailutils/address.h>}
@end example
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.
@example
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]
@end example
unix-mbox is a non-standard extention 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 @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
@var{buf}, 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 *@var{n} is assigned the length of
the component string.
@macro ADDRESSENOMEM
@item ENOMEM
Not enough memory to allocate resources.
@end macro
@macro ADDRESSEPARSE
@item ENOENT
Invalid RFC822 syntax, parsing failed.
@end macro
@macro ADDRESSENOENT
@item ENOENT
The index @var{no} is outside of the range of available addresses.
@end macro
@macro ADDRESSEINVAL
@item EINVAL
Invalid usage, usually a required argument was @code{nul}.
@end macro
@deftp {Data Type} address_t
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 an address in the address list.
@end deftp
@deftypefun int address_create (address_t *@var{addr}, const char *@var{string})
This function allocates and initializes @var{addr} by parsing the
RFC822 address-list @var{string}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@ADDRESSEINVAL
@ADDRESSENOMEM
@ADDRESSEPARSE
@end table
@end deftypefun
@deftypefun void address_destroy (address_t *@var{addr})
The @var{addr} is destroyed.
@end deftypefun
@deftypefun int address_get_email (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
Accesses 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:
@table @code
@ADDRESSEINVAL
@ADDRESSENOENT
@end table
@end deftypefun
@deftypefun int address_get_personal (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
Accesses the display-name describing the @var{no}th email address. This
display-name is optional, so may not be present. If it is not present, but
there is an RFC822 comment after the address, that comment will be
returned as the personal phrase, as this is a common usage of the comment
even though it is not defined in the internet mail standard.
A group is a kind of a special case. It has a display-name, followed
by an optional mailbox-list. The display-name will be allocated an address
all it's own, but all the other elements (local-part, domain, etc.) will
be zero-length. So "a group: ;" is valid, will have a count of 1, but
address_get_email(), and all the rest, will return zero-length output.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@ADDRESSEINVAL
@ADDRESSENOENT
@end table
@end deftypefun
@deftypefun int address_get_comments (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
Accesses the comments extracted while parsing the @var{no}th email address.
These comments have no defined meaning, and are not currently collected.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@ADDRESSEINVAL
@ADDRESSENOENT
@end table
@end deftypefun
@deftypefun int address_get_email (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
Accesses the email addr-spec extracted while
parsing the @var{no}th email address. This will be @code{0}
length for a unix-mbox.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@ADDRESSEINVAL
@ADDRESSENOENT
@end table
@end deftypefun
@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})
Accesses the local-part of an email addr-spec extracted while
parsing the @var{no}th email address.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@ADDRESSEINVAL
@ADDRESSENOENT
@end table
@end deftypefun
@deftypefun int address_get_domain (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
Accesses the domain of an email addr-spec extracted while
parsing the @var{no}th email address. This will be @code{0}
length for a unix-mbox.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@ADDRESSEINVAL
@ADDRESSENOENT
@end table
@end deftypefun
@deftypefun int address_get_route (address_t *@var{addr}, size_t @var{no}, char* @var{buf}, size_t @var{len}, size_t* @var{n})
Accesses the route of an email addr-spec extracted while
parsing the @var{no}th email address. This is a rarely used RFC822 address
syntax, but is legal in SMTP as well. The entire route is returned as
a string, those wishing to parse it should look at <mailutils/parse822.h>.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@ADDRESSEINVAL
@ADDRESSENOENT
@end table
@end deftypefun
@deftypefun int address_is_group (address_t *@var{addr}, size_t @var{no}, size_t @var{len}, int* @var{yes})
Sets *@var{yes} to @code{1} if this address is just the name of a group,
@code{0} otherwise. This is faster than checking if the address has
a non-zero length personal, and a zero-length local_part and domain.
@var{yes} can be @code{nul}, though that doesn't serve much purpose other
than determining that @var{no} refers to an address.
Currently, there is no way to determine the end of the group.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@ADDRESSEINVAL
@ADDRESSENOENT
@end table
@end deftypefun
@deftypefun int address_to_string (address_t *@var{addr}, 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:
@table @code
@ADDRESSEINVAL
@ADDRESSENOMEM
@end table
@end deftypefun
@deftypefun int address_get_count (address_t @var{addr}, size_t* @var{count})
Returns a count of the addresses in the address list.
If @var{addr} is @code{nul}, the count is @code{0}. If @var{count} is
not @code{nul}, the count will be written to *@var{count}.
The return value is @code{0}.
@end deftypefun
@section Example
@example
@include ex-address.texi
@end example
@example
@code{/* Prefix @emph{attribute_} is reserved */}
@code{#include <mailutils/attribute.h>}
@end example
@deftypefun int attribute_create (attribute_t *@var{pattribute})
@end deftypefun
@deftypefun void attribute_destroy (attribute_t *@var{pattribute})
@end deftypefun
@deftypefun int attribute_is_seen (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_is_answered (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_is_flagged (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_is_deleted (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_is_draft (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_is_recent (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_is_read (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_set_seen (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_set_answered (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_set_flagged (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_set_deleted (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_set_draft (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_set_recent (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_set_read (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_unset_seen (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_unset_answered (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_unset_flagged (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_unset_deleted (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_unset_draft (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_unset_recent (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_unset_read (attribute_t @var{attribute})
@end deftypefun
@deftypefun int attribute_is_equal (attribute_t @var{att1}, attribute_t @var{att2})
@end deftypefun
@deftypefun int attribute_copy (attribute_t @var{dst}, attribute_t @var{src})
@end deftypefun
@deftypefun int string_to_attribute (const char *@var{buf}, attribute_t *@var{pattr})
@end deftypefun
@deftypefun int attribute_to_string (attribute_t @var{attr}, char *@var{buf}, size_t @var{len}, size_t *@var{pwriten})
@end deftypefun
@example
@code{/* Prefix @emph{auth_} is reserved */}
@code{#include <mailutils/auth.h>}
@end example
There are many ways to authenticate to a server. To be flexible the
authentication process is provided by two objects @code{auth_t} and
@code{ticket_t}. The @code{auth_t} can implement different protocol like
APOP, MD5-AUTH, One Time Passwd etc .. By default if a mailbox
does not understand or know how to authenticate it falls back to
user/passwd authentication. The @code{ticket_t} is a way for
Mailboxes and Mailers provide a way to authenticate when the URL does not
contain enough information. The default action is to call the function
@code{auth_authenticate} which will get the @emph{user} and @emph{passwd}
if not set, this function can be overriden by a custom method.
@deftypefun int auth_create (auth_t *@var{pauth}, void *@var{owner})
@end deftypefun
@deftypefun void auth_destroy (auth_t *@var{pauth}, void *@var{owner})
@end deftypefun
@deftypefun int auth_prologue (auth_t @var{auth})
@end deftypefun
@deftypefun int auth_authenticate (auth_t @var{auth}, char **@var{user}, char **@var{passwd})
@end deftypefun
@deftypefun int auth_epilogue (auth_t @var{auth})
@end deftypefun
A simple example of an authenticate function:
@example
#include <mailutils/auth.h>
#include <stdio.h>
#include <string.h>
int
my_authenticate (auth_t auth, char **user, char **passwd)
@{
char u[128] = "";
char p[128] = "";
/* prompt the user name */
printf ("User: ");
fflush (stdout);
fgets (u, sizeof (u), stdin);
u[strlen (u) - 1] = '\0'; /* nuke the trailing NL */
/* prompt the passwd */
printf ("Passwd: "); fflush (stdout);
echo_off ();
fgets (p, sizeof(p), stdin);
echo_on ();
p[strlen (p) - 1] = '\0';
/* duplicate */
*user = strdup (u);
*passwd = strdup (p);
return 0;
@}
@end example
@example
@code{/* Prefix @emph{body_} is reserved */}
@code{#include <mailutils/body.h>}
@end example
@deftypefun int body_create (body_t *@var{body}, void *@var{owner})
Initialize an object @var{bdy}.
@end deftypefun
@deftypefun void body_destroy (body_t *@var{pbody})
The resources allocate are release.
@end deftypefun
@deftypefun int body_get_stream (body_t @var{body}, stream_t *@var{pstream})
@end deftypefun
@deftypefun int body_set_stream (body_t @var{body}, stream_t @var{stream}, void *@var{owner})
@end deftypefun
@deftypefun int body_get_filename __P ((body_t @var{body}, char *@var{buffer}, size_t@var{buflen}, size_t *@var{pwriten})
@end deftypefun
@deftypefun int body_set_filename (body_t @var{body}, const char*@var{buffer})
@end deftypefun
@deftypefun int body_size (body_t @var{body}, size_t*@var{psize})
@end deftypefun
@deftypefun int body_lines (body_t @var{body}, size_t *@var{plines})
@end deftypefun
@menu
* POP3:: POP3
* IMAP4:: IMAP4
* Mbox:: Mbox
* Mh:: Mh
* Maildir:: Maildir
* SMTP:: SMTP
* Sendmail:: Sendmail
* NNTP:: NNTP
* Parse822:: Parse822
@end menu
@node POP3
@comment node-name, next, previous, up
@section POP3
@cindex POP3
@include pop3.texi
@node IMAP4
@comment node-name, next, previous, up
@section IMAP4
@cindex IMAP4
@include imap4.texi
@node Mbox
@comment node-name, next, previous, up
@section Mbox
@cindex Mbox
@include mbox.texi
@node Mh
@comment node-name, next, previous, up
@section Mh
@cindex Mh
@include mh.texi
@node Maildir
@comment node-name, next, previous, up
@section Maildir
@cindex Maildir
@include maildir.texi
@node SMTP
@comment node-name, next, previous, up
@section SMTP
@cindex SMTP
@include smtp.texi
@node Sendmail
@comment node-name, next, previous, up
@section Sendmail
@cindex Sendmail
@include sendmail.texi
@node NNTP
@comment node-name, next, previous, up
@section NNTP
@cindex NNTP
@include nntp.texi
@node Parse822
@comment node-name, next, previous, up
@section Parse822
@cindex Parse822
@include parse822.texi
@section RFC1522
@cindex RFC1522
@section Quoted Printable
@cindex Quoted Printable
@section Base64
@cindex Base64
@example
@code{/* Prefix @emph{envelope_} is reserved */}
@code{#include <mailutils/envelope.h>}
@end example
@deftypefun int envelope_date (envelope_t, char *, size_t, size_t *);
Get the date that the message was delivered to the mailbox, in
something close to ANSI ctime() format: Mon Jul 05 13:08:27 1999.
@end deftypefun
@deftypefun int envelope_sender (envelope_t, char *, size_t, size_t *);
Get the address that this message was reportedly received from. This
would be the "mail from" argument if the message was delivered
or received via SMTP, for example.
@end deftypefun
@deftypefun int envelope_get_message (envelope_t, message_t *);
@end deftypefun
@deftypefun int envelope_create (envelope_t *, void *);
Primarily for internal use.
@end deftypefun
@deftypefun void envelope_destroy (envelope_t *, void *);
Primarily for internal use.
@end deftypefun
@deftypefun int envelope_set_sender (envelope_t, int (*_sender) __P ((envelope_t, char *, size_t, size_t*)), void *);
Primarily for internal use. The implementation of envelope_t depends
on the mailbox type, this allows the function which actually gets
the sender to be set by the creator of an envelope_t.
@end deftypefun
@deftypefun int envelope_set_date (envelope_t, int (*_date) __P ((envelope_t, char *, size_t, size_t *)), void *);
Primarily for internal use. The implementation of envelope_t depends
on the mailbox type, this allows the function which actually gets
the date to be set by the creator of an envelope_t.
@end deftypefun
#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;
@}
#include <mailutils/url.h>
#include <stdio.h>
#include <string.h>
int
main ()
@{
char str[1024];
char buffer[1024];
long port = 0;
int len = sizeof (buffer);
url_t u = NULL;
while (fgets (str, sizeof (str), stdin) != NULL)
@{
int rc;
str[strlen (str) - 1] = '\0'; /* chop newline */
if(strspn(str, " \t") == strlen(str))
continue; /* skip empty lines */
if ((rc = url_create(&u, str)) != 0)
@{
printf(stderr, "url_create %s ERROR: [%d] %s",
str, rc, strerror(rc));
exit (1);
@}
if ((rc = url_parse (u)) != 0)
@{
printf ("%s --> FAILED: [%d] %s\n",
str, rc, strerror(rc));
continue;
@}
printf ("%s --> SUCCESS\n", str);
url_get_scheme (u, buffer, len, NULL);
printf (" scheme <%s>\n", buffer);
url_get_user (u, buffer, len, NULL);
printf (" user <%s>\n", buffer);
url_get_passwd (u, buffer, len, NULL);
printf (" passwd <%s>\n", buffer);
url_get_auth (u, buffer, len, NULL);
printf (" auth <%s>\n", buffer);
url_get_host (u, buffer, len, NULL);
printf (" host <%s>\n", buffer);
url_get_port (u, &port);
printf (" port %ld\n", port);
url_get_path (u, buffer, len, NULL);
printf (" path <%s>\n", buffer);
url_get_query (u, buffer, len, NULL);
printf (" query <%s>\n", buffer);
url_destroy (&u);
@}
return 0;
@}
@example
@code{/* Prefix @emph{folder_} is reserve */}
@code{#include <mailutils/folder.h>}
@end example
@example
@group
folder_t url_t
-/var/mail- +---//---->/-----------------\ +-->/-----------\
( alain *-)-+ | | url_t *-|----+ | port |
----------- | | |-----------------+ | hostname |
( jakob *-)-+--+ | observer_t *-| | file |
----------- | |-----------------+ | ... |
( jeff *-)-+ | stream_t | \-----------/
----------- | |-----------------|
( sean *-)-+ | auth_t |
---------- |-----------------|
| mailbox_t(1) |
|-----------------|
| mailbox_t(2) |
| ...... |
| mailbox_t(n) |
\-----------------/
@end group
@end example
@deftypefun int folder_create (folder_t *, const char *@var{url})
@end deftypefun
@deftypefun void folder_destroy (folder_t *)
@end deftypefun
@deftypefun int folder_open (folder_t, int @var{flag})
@end deftypefun
@deftypefun int folder_close (folder_t)
@end deftypefun
@deftypefun int folder_delete (folder_t, const char *@var{mailbox})
@end deftypefun
@deftypefun int folder_rename (folder_t, const char *, const char *@var{mailbox})
@end deftypefun
@deftypefun int folder_subscribe (folder_t, const char *@var{mailbox})
@end deftypefun
@deftypefun int folder_unsubscribe (folder_t, const char *@var{mailbox})
@end deftypefun
@deftypefun int folder_list (folder_t, const char *@var{ref}, const char *@var{wcard}, iterator_t *)
@end deftypefun
@deftypefun int folder_lsub (folder_t, const char *@var{ref}, const char *@var{wcar}, iterator_t *)
@end deftypefun
@deftypefun int folder_get_stream (folder_t, stream_t *)
@end deftypefun
@deftypefun int folder_set_stream (folder_t, stream_t)
@end deftypefun
@deftypefun int folder_get_observable (folder_t, observable_t *)
@end deftypefun
@deftypefun int folder_get_debug (folder_t, debug_t *)
@end deftypefun
@deftypefun int folder_set_debug (folder_t, debug_t)
@end deftypefun
@deftypefun int folder_get_authority (folder_t, authority_t *)
@end deftypefun
@deftypefun int folder_set_authority (folder_t, authority_t)
@end deftypefun
@deftypefun int folder_get_url (folder_t, url_t *)
@end deftypefun
@deftypefun int folder_set_url (folder_t, url_t)
@end deftypefun
@menu
* Folder:: Folder.
* Mailbox:: Mailbox.
* Mailer:: Protocol Used to Send Mail.
* Message:: Message.
* Envelope:: Envelope.
* Headers:: Headers.
* Body:: Body.
* Attribute:: Attribute.
* Stream:: Stream.
* Iterator:: Iterator.
* Authenticator:: Authenticator.
* Address:: Address.
* Locker:: Locker.
* URL:: Uniform Resource Locators.
@end menu
Whereever the mail is and whatever format it is stored in, the same operations
to manipulate emails are common. To unified the C API, GNU mailutils offers
a heteroclite set of objects that work in aggregation to do operations on
emails. Each object do a specific task and delegates non related tasks to
others. The object comes alive by specifying a @emph{URL} parameter when
created, it will indicate the storage format or protocol
(POP3, IMAP4, MH, MAILDIR, etc ..).
@example
@group
folder_t url_t
-/var/mail- +- .. ->+-----------------+ +-->+------------+
( alain *-)-+ | | url_t *-|---+ | port |
----------- | | |-----------------| | hostname |
( jakob *-)-+--+ | auth_t *-|---+ | file |
----------- | |-----------------| | | ... |
( jeff *-)-+ | stream_t | | +------------+
----------- | |-----------------| |
( shaleh*-)-+ | ..... | | auth_t
---------- |-----------------| +-->+------------+
+---|-* mailbox_t[] | | ticket_t |
mailbox_t | +-----------------+ +------------+
+----------------+<-+
| locker_t *--|-------------+
|----------------| |
| url_t | | locker_t
|----------------| +-------->+---------+
| stream_t | | lock |
|----------------| | unlock |
| message_t[] *-|-------+ +---------+
+----------------+ | envelope_t
| +-------->+-----------+
message_t | | | date |
+----------------+<------+ | | from |
| envelope_t *-|------------------+ | to |
|----------------| header_t +-----------+
| header_t *-|------------>+--------------+
|----------------| | stream_t |
| body_t *-|----+ +--------------+
+----------------+ | body_t
+-->+--------------+
| stream_t |
+--------------+
@end group
@end example
For example writing a simple @code{from} command that will list the
@emph{From} and @emph{Subject} headers of every mail in a mailbox.
@example
@include sfrom.c.texi
@end example
@example
@cartouche
% MAIL=pop://alain@@localhost ./sfrom
Passwd: xxxx
Jim Meyering <meyering@@foo.org> fetish(shellutils) beta
Fran@,{c}ois Pinard <pinard@@bar.org> recode new alpha
@dots{}
@end cartouche
@end example
@node Folder
@comment node-name, next, previous, up
@section Folder
@cindex Folder
@include folder.texi
@node Mailbox
@comment node-name, next, previous, up
@section Mailbox
@cindex Mailbox
@include mailbox.texi
@node Mailer
@comment node-name, next, previous, up
@section Mailer
@cindex Mailer
@include mailer.texi
@node Message
@comment node-name, next, previous, up
@section Message
@cindex Message
@include message.texi
@node Envelope
@comment node-name, next, previous, up
@section Envelope
@cindex Envelope
@include envelope.texi
@node Headers
@comment node-name, next, previous, up
@section Headers
@cindex Headers
@include headers.texi
@node Body
@comment node-name, next, previous, up
@section Body
@cindex Body
@include body.texi
@node Attribute
@comment node-name, next, previous, up
@section Attribute
@cindex Attribute
@include attribute.texi
@node Stream
@comment node-name, next, previous, up
@section Stream
@cindex Stream
@include stream.texi
@node Iterator
@comment node-name, next, previous, up
@section Iterator
@cindex Iterator
@include iterator.texi
@node Authenticator
@comment node-name, next, previous, up
@section Authenticator
@cindex Authenticator
@include auth.texi
@node Address
@comment node-name, next, previous, up
@section Address
@cindex Address
@include address.texi
@node Locker
@comment node-name, next, previous, up
@section Locker
@cindex Locker
@include locker.texi
@node URL
@comment node-name, next, previous, up
@section URL
@cindex URL
@include url.texi
@example
@code{/* Prefix @emph{header_} is reserved */}
@code{#include <mailutils/header.h>}
@end example
So far we plan support for RFC822 and plan for RFC1522. with RFC1522 non ASCII
characters will be encoded.
@deftypefun int header_create (header_t *@var{hdr}, const char *@var{blurb}, size_t @var{len}, void *@var{owner})
Initialize a @var{hdr} to a supported type. If @var{blurb} is not NULL, it is
parsed.
@end deftypefun
@deftypefun void header_destroy (header_t *@var{hdr}, void *@var{owner})
The resources allocated for @var{hdr} are freed.
@end deftypefun
@deftypefun int header_set_value (header_t @var{hdr}, const char *@var{fn}, const char *@var{fv}, size_t n, int @var{replace})
Set the field-name @var{fn} to field-value @var{fv} of size @var{n} in
@var{hdr}. If @var{replace} is non-zero the initial value is replaced, if zero
it is appended.
Some basic macros are already provided for rfc822.
@table @code
@item MU_HDR_RETURN_PATH
Return-Path
@item MU_HDR_RECEIVED
Received
@item MU_HDR_DATE
Date
@item MU_HDR_FROM
From
@item MU_HDR_RESENT_FROM
Resent-From
@item MU_HDR_SUBJECT
Subject
@item MU_HDR_SENDER
Sender
@item MU_HDR_RESENT_SENDER
Resent-SENDER
@item MU_HDR_TO
To
@item MU_HDR_RESENT_TO
Resent-To
@item MU_HDR_CC
Cc
@item MU_HDR_RESENT_CC
Resent-Cc
@item MU_HDR_BCC
Bcc
@item MU_HDR_RESENT_BCC
Resent-Bcc
@item MU_HDR_REPLY_TO
Reply-To
@item MU_HDR_RESENT_REPLY_TO
Resent-Reply-To
@item MU_HDR_MESSAGE_ID
Message-ID
@item MU_HDR_RESENT_MESSAGE_ID
Resent-Message-ID
@item MU_HDR_IN_REPLY_TO
In-Reply-To
@item MU_HDR_ENCRYPTED
Encrypted
@item MU_HDR_PRECEDENCE
Precedence
@item MU_HDR_STATUS
Status
@item MU_HDR_CONTENT_LENGTH
Content-Length
@item MU_HDR_CONTENT_TYPE
Content-Type
@item MU_HDR_MIME_VERSION
MIME-Version
@end table
@end deftypefun
@deftypefun int header_get_value (header_t @var{hdr}, const char *@var{fn}, char *@var{fv}, size_t @var{len}, size_t *@var{n})
Value of field-name @var{fn} is returned in buffer @var{fv} of size @var{len}.
The number of bytes written is put in @var{n}.
@end deftypefun
@deftypefun int header_aget_value (header_t @var{hdr}, const char *@var{fn}, char **@var{fv})
The value is allocated.
@end deftypefun
@deftypefun int header_get_stream (header_t @var{hdr}, stream_t *@var{pstream})
@end deftypefun
@deftypefun int header_set_size (header_t @var{hdr}, size_t *@var{size})
@end deftypefun
@deftypefun int header_set_lines (header_t @var{hdr}, size_t *@var{lpines})
@end deftypefun
@example
@code{/* Prefix @emph{imap4_} is reserved */}
@code{#include <mailutils/imap4.h>}
@end example
Internet Message Access Protocol - Version (4rev1). Not implemented.
@subsection Commands
@subsubsection Initialisation
@cindex IMAP4 Inintialisation
@deftypefun int imap4_create (imap4_t *)
@end deftypefun
@deftypefun int imap4_open (imap4_t, const char *@var{hostname}, unsigned int @var{port}, int @var{flags})
@end deftypefun
@deftypefun int imap4d_set_timeout (imap4_t, unsigned int @var{seconds})
@end deftypefun
@subsubsection Append
@cindex IMAP4 Append
@deftypefun int imap4_append (imap4_t)
@end deftypefun
@subsubsection Capability
@cindex IMAP4 Capability
@deftypefun int imap4_capability (imap4_t)
@end deftypefun
@subsubsection Create
@cindex IMAP4 Create
@deftypefun int imap4_create_mailbox (imap4_t, const char *@var{mbox})
@end deftypefun
@subsubsection Check
@cindex IMAP4 Check
@deftypefun int imap4_check (imap4_t)
@end deftypefun
@subsubsection Close
@cindex IMAP4 Close
@deftypefun int imap4_close (imap4_t)
@end deftypefun
@subsubsection Copy
@cindex IMAP4 Copy
@deftypefun int imap4_copy (imap4_t)
@end deftypefun
@subsubsection UID Copy
@cindex IMAP4 UID Copy
@deftypefun int imap4_uid_copy (imap4_t)
@end deftypefun
@subsubsection Delete
@cindex IMAP4 Delete
@deftypefun int imap4_delete (imap4_t)
@end deftypefun
@subsubsection Fetch
@cindex IMAP4 Fetch
@deftypefun int imap4_fetch (imap4_t)
@end deftypefun
@subsubsection UID Fetch
@cindex IMAP4 UID Fetch
@deftypefun int imap4_uid_fetch (imap4_t)
@end deftypefun
@subsubsection Examine
@cindex IMAP4 Examine
@deftypefun int imap4_examine (imap4_t)
@end deftypefun
@subsubsection Expunge
@cindex IMAP4 Expunge
@deftypefun int imap4_expunge (imap4_t)
@end deftypefun
@subsubsection List
@cindex IMAP4 List
@deftypefun int imap4_list (imap4_t)
@end deftypefun
@subsubsection Lsub
@cindex IMAP4 Lsub
@deftypefun int imap4_lsub (imap4_t)
@end deftypefun
@subsubsection Namespace
@cindex IMAP4 Namespace
@deftypefun int imap4_namespace (imap4_t)
@end deftypefun
@subsubsection Rename
@cindex IMAP4 Rename
@deftypefun int imap4_rename (imap4_t)
@end deftypefun
@subsubsection Search
@cindex IMAP4 Search
@deftypefun int imap4_search (imap4_t)
@end deftypefun
@subsubsection UID Search
@cindex IMAP4 UID Search
@deftypefun int imap4_uid_search (imap4_t)
@end deftypefun
@subsubsection Select
@cindex IMAP4 Select
@deftypefun int imap4_select (imap4_t)
@end deftypefun
@subsubsection Status
@cindex IMAP4 Status
@deftypefun int imap4_status (imap4_t)
@end deftypefun
@subsubsection Store
@cindex IMAP4 Store
@deftypefun int imap4_store (imap4_t)
@end deftypefun
@subsubsection UID Store
@cindex IMAP4 UID Store
@deftypefun int imap4_uid_store (imap4_t)
@end deftypefun
@subsubsection Subscribe
@cindex IMAP4 Subscribe
@deftypefun int imap4_subscribe (imap4_t)
@end deftypefun
@subsubsection Unsubscribe
@cindex IMAP4 Unsubscribe
@deftypefun int imap4_unsubscribe (imap4_t)
@end deftypefun
@example
@code{/* Prefix @emph{iterator_} is reserved */}
@code{#include <mailutils/iterator.h>}
@end example
@deftypefun int iterator_create (iterator_t *)
@end deftypefun
@deftypefun void iterator_destroy (iterator_t *)
@end deftypefun
@deftypefun int iterator_first (iterator_t)
@end deftypefun
@deftypefun int iterator_next (iterator_t)
@end deftypefun
@deftypefun int iterator_current (iterator_t, void **pitem)
@end deftypefun
@deftypefun int iterator_is_done (iterator_t)
@end deftypefun
@example
@code{/* Prefix @emph{locker_} is reserved */}
@code{#include <mailutils/locker.h>}
@end example
@deftypefun int locker_create (locker_t * @var{plocker}, char *@var{filename}, size_t @var{len}, int @var{flags})
@end deftypefun
@deftypefun void locker_destroy (locker_t * @var{plocker})
@end deftypefun
@deftypefun int locker_lock (locker_t @var{locker}, int @var{flag})
@table @code
@item MU_LOCKER_RDLOCK
@item MU_LOCKER_WRLOCK
@item MU_LOCKER_PID
@item MU_LOCKER_FCNTL
@item MU_LOCKER_TIME
@end table
@end deftypefun
@deftypefun int locker_touchlock (locker_t @var{locker})
@end deftypefun
@deftypefun int locker_unlock (locker_t @var{locker})
@end deftypefun
@example
@code{/* Prefix @emph{mailbox_} is reserved */}
@code{#include <mailutils/mailbox.h>}
@end example
@deftp {Data Type} mailbox_t
The @code{mailbox_t} object is used to hold information and it is an opaque
data structure to the user. Functions are provided to retrieve information
from the data structure.
@end deftp
@example
@group
mailbox_t url_t
-/var/mail- +---//---->/-----------------\ +-->/-----------\
( alain ) | | url_t *-|----+ | port |
----------- | |-----------------+ | hostname |
( jakob *-)----+ | observer_t *-| | file |
----------- |-----------------+ | ... |
( jeff ) | stream_t | \-----------/
----------- |-----------------|
( sean ) | locker_t |
---------- |-----------------|
| message_t(1) |
|-----------------|
| message_t(2) |
| ...... |
| message_t(n) |
\-----------------/
@end group
@end example
@deftypefun int mailbox_append_message (mailbox_t @var{mbox}, message_t @var{message})
The @var{message} is appended to the mailbox @var{mbox}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null or @var{message} is invalid.
@end table
@end deftypefun
@deftypefun int mailbox_close (mailbox_t @var{mbox})
The stream attach to @var{mbox} is closed.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_create (mailbox_t *@var{pmbox}, const char *@var{name})
The function @code{mailbox_create} allocates and initializes @var{pmbox}.
The concrete mailbox type instanciate is based on the scheme of the url @var{name}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
The url @var{name} supplied is invalid or not supported.
@var{pmbox} is NULL.
@item ENOMEM
Not enough memory to allocate resources.
@end table
@end deftypefun
@deftypefun int mailbox_create_default (mailbox_t *@var{pmbox}, const char *@var{name})
Create a mailbox with @code{mailbox_create ()} based on the environment
variable @emph{$MAIL} or the string formed by
@emph{_PATH_MAILDIR}/@var{user}" or @emph{$LOGNAME} if @var{user} is null,
@end deftypefun
@deftypefun void mailbox_destroy (mailbox_t *@var{pmbox})
Destroys and releases resources held by @var{pmbox}.
@end deftypefun
@deftypefun int mailbox_expunge (mailbox_t @var{mbox})
All messages marked for deletion are removed.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_get_folder (mailbox_t @var{mbox}, folder_t *@var{folder})
Get the @var{folder}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_get_debug (mailbox_t @var{mbox}, debug_t *@var{debug})
Get a debug object.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@item ENOMEM
@end table
@end deftypefun
@deftypefun int mailbox_get_locker (mailbox_t @var{mbox}, locker_t *@var{plocker})
Return the @var{locker} object.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_get_message (mailbox_t @var{mbox}, size_t @var{msgno}, message_t *@var{pmessage})
Retreive message number @var{msgno}, @var{pmessage} is allocated and
initialized.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null or @var{msgno} is invalid.
@item ENOMEM
Not enough memory.
@end table
@end deftypefun
@deftypefun int mailbox_get_observable (mailbox_t mbox @var{mbox}, observable_t*@var{observable})
Get the observable object.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@item ENOMEM
Not enough memory.
@end table
@end deftypefun
@deftypefun int mailbox_get_property (mailbox_t @var{mbox}, property_t *@var{property})
Get the property object.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@item ENOMEM
@end table
@end deftypefun
@deftypefun int mailbox_get_size (mailbox_t @var{mbox}, off_t *@var{psize})
Gives the @var{mbox} size.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_get_stream (mailbox_t @var{mbox}, stream_t *@var{pstream})
The mailbox stream is put in @var{pstream}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is invalid or @var{pstream} is NULL.
@end table
@end deftypefun
@deftypefun int mailbox_get_ticket (mailbox_t @var{mbox}, ticket_t @var{ticket})
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_get_url (mailbox_t @var{mbox}, url_t *@var{purl})
Gives the constructed @var{url}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_is_modified (mailbox_t @var{mbox})
Check if the mailbox been modified by an external source.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_message_unseen (mailbox_t @var{mbox}, size_t *@var{pnumber});
Give the number of first unseen message in @var{mbox}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_messages_count (mailbox_t @var{mbox}, size_t *@var{pnumber});
Give the number of messages in @var{mbox}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_messages_recent (mailbox_t @var{mbox}, size_t *@var{pnumber});
Give the number of recent messages in @var{mbox}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_open (mailbox_t @var{mbox}, int @var{flag})
A connection is open, if no stream was provided, a stream
is created based on the @var{mbox} type. The @var{flag} can be OR'ed.
See @code{stream_create} for @var{flag}'s description.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item EAGAIN
@itemx EINPROGRESS
Operation in progress.
@item EBUSY
Resource busy.
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null or flag is invalid.
@item ENOMEM
Not enough memory.
@end table
@end deftypefun
@deftypefun int mailbox_scan (mailbox_t @var{mbox}, size_t @var{msgno}, size_t *@var{pcount});
Scan the mailbox for new messages starting at message @var{msgno}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@item ENOMEM
Not enough memory.
@end table
@end deftypefun
@deftypefun int mailbox_set_locker (mailbox_t @var{mbox}, locker_t @var{locker})
Set the type of locking done by the @var{mbox}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_set_stream (mailbox_t @var{mbox}, stream_t @var{stream})
Set the @var{stream} connection to use for the mailbox.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} or @var{stream} is NULL.
@end table
@end deftypefun
@deftypefun int mailbox_set_ticket (mailbox_t @var{mbox}, ticket_t @var{ticket})
The @var{ticket} will be set on the @code{auth_t} object on creation.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_uidnext (mailbox_t @var{mbox}, size_t *@var{pnumber});
Give the next predicted uid for @var{mbox}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@deftypefun int mailbox_uidvalidity (mailbox_t @var{mbox}, size_t *@var{pnumber});
Give the uid validity of @var{mbox}.
The return value is @code{0} on success and a code number on error conditions:
@table @code
@item MU_ERROR_INVALID_PARAMETER
@var{mbox} is null.
@end table
@end deftypefun
@example
@code{/* Prefix @emph{maildir_} is reserved */}
@code{#include <mailutils/maildir.h>}
@end example
QMail mailbox format. Not implemented.
@example
@code{/* Prefix @emph{mailer_} is reserved */}
@code{#include <mailutils/mailer.h>}
@end example
The API is still shaky and undefined.
@deftypefun int mailer_create (mailer_t *, const char *)
@end deftypefun
@deftypefun void mailer_destroy (mailer_t *)
@end deftypefun
@deftypefun int mailer_open (mailer_t, int flags)
@end deftypefun
@deftypefun int mailer_close (mailer_t)
@end deftypefun
@deftypefun int mailer_send_message (mailer_t, message_t)
@end deftypefun
@deftypefun int mailer_get_property (mailer_t, property_t *)
@end deftypefun
@deftypefun int mailer_get_stream (mailer_t, stream_t *)
@end deftypefun
@deftypefun int mailer_set_stream (mailer_t, stream_t)
@end deftypefun
@deftypefun int mailer_get_debug (mailer_t, debug_t *)
@end deftypefun
@deftypefun int mailer_set_debug (mailer_t, debug_t)
@end deftypefun
@deftypefun int mailer_get_observable (mailer_t, observable_t *)
@end deftypefun
@deftypefun int mailer_get_url (mailer_t, url_t *)
@end deftypefun
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename mailutils.info
@settitle mailutils, Programming Manual
@c %**end of header
@c This file has the new style title page commands.
@c Run `makeinfo' rather than `texinfo-format-buffer'.
@c smallbook
@c tex
@c \overfullrule=0pt
@c end tex
@include version.texi
@c Combine indices.
@syncodeindex ky cp
@syncodeindex pg cp
@syncodeindex tp cp
@defcodeindex op
@syncodeindex op fn
@syncodeindex vr fn
@ifinfo
@direntry
* mailutils: (libmailutils). The GNU mailutils library API.
@end direntry
This file documents @sc{mailutils}, library API.
Published by the Free Software Foundation,
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
Copyright 1999, 2000 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Foundation.
@end ifinfo
@setchapternewpage off
@titlepage
@title mailutils, SDK.
@subtitle version @value{VERSION}, @value{UPDATED}
@author Alain Magloire et al.
@page
@vskip 0pt plus 1filll
Copyright @copyright{} 1999, 2000, 2001 Free Software Foundation, Inc.
@sp 2
Published by the Free Software Foundation, @*
59 Temple Place - Suite 330, @*
Boston, MA 02111-1307, USA
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation approved
by the Foundation.
@end titlepage
@page
@summarycontents
@page
@node Top, Introduction, (dir), (dir)
@comment node-name, next, previous, up
@ifinfo
This document was produced for version @value{VERSION} of @sc{gnu}
@sc{mailutils}.
@end ifinfo
@menu
* Introduction:: GNU @sc{mailutils}
* Concrete API:: Concrete API.
* Framework:: Framework.
* Programs:: Programs.
* Reporting Bugs:: Reporting Bugs.
* Acknowledgement:: Thanks and Credits.
* Concept Index:: All @sc{Mailutils} Functions.
* Index::
@end menu
@node Introduction, Concrete API, Top, Top
@comment node-name, next, previous, up
@chapter Introduction
@cindex Introduction
@sc{gnu} @sc{Mailutils} offers a general purpose library whose aim is to
provide a rich set of functions for accessing different mailbox formats and
mailers.
@section References
For more information on,
@itemize @bullet
@item
SMTP
@itemize @minus
@item
@cite{RFC 2821: Simple Mail Transfer Protocol}
@item
@cite{RFC 2368: The mailto URL scheme}
@end itemize
@item
POP3
@itemize @minus
@item
@cite{RFC 1939: Post Office Protocol - Version 3}
@item
@cite{RFC 1734: POP3 AUTHentication command}
@item
@cite{RFC 1957: Some Observations on Implementations of the Post Office
Protocol (POP3)}
@item
@cite{RFC 2449: POP3 Extension Mechanism}
@item
@cite{RFC 2384: POP URL Scheme}
@end itemize
@item
IMAP4
@itemize @minus
@item
@cite{RFC 2060: INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1}
@item
@cite{RFC 2088: IMAP4 non-synchronizing literals}
@item
@cite{RFC 2193: IMAP4 Mailbox Referrals}
@item
@cite{RFC 2221: IMAP4 Login Referrals}
@item
@cite{RFC 2342: IMAP4 Namespace}
@item
@cite{RFC 2192: IMAP URL Scheme}
@item
@cite{RFC 1731: IMAP4 Authentication Mechanisms}
@item
@cite{RFC 2245: Anonymous SASL Mechanism}
@end itemize
@item
message formats
@itemize @minus
@item
@cite{RFC 2822: Internet Message Format}
@item
@cite{RFC 2045: Multipurpose Internet Mail Extensions (MIME) Part One:
Format of Internet Message Bodies}
@item
@cite{RFC 2046: Multipurpose Internet Mail Extensions (MIME) Part Two:
Media Types}
@item
@cite{RFC 2047: Multipurpose Internet Mail Extensions (MIME) Part Three:
Message Header Extensions for Non-ASCII Text}
@item
@cite{RFC 2049: Multipurpose Internet Mail Extensions (MIME) Part Five:
Conformance Criteria and Examples}
@item
@cite{RFC 2111: Content-ID and Message-ID Uniform Resource Locators}
@end itemize
@item
miscellaneous related topics
@itemize @minus
@item
@cite{RFC 3028: Sieve: A Mail Filtering Language}
@item
@cite{RFC 2298: An Extensible Message Format for Message Disposition
Notifications}
@item
@cite{RFC 1738: Uniform Resource Locators (URL)}
@item
@cite{Internet Email Protocols: A Developer's Guide, by Kevin Johnson}
@end itemize
@end itemize
@node Concrete API, Framework, Introduction, Top
@comment node-name, next, previous, up
@chapter Concrete API
@cindex Concrete API
@include c-api.texi
@node Framework, Programs, Concrete API, Top
@comment node-name, next, previous, up
@chapter Framework
@cindex Framework
@include framework.texi
@node Programs, Reporting Bugs, Framework, Top
@comment node-name, next, previous, up
@chapter Programs
@cindex Programs
@include programs.texi
@node Reporting Bugs, Acknowledgement, Programs, Top
@comment node-name, next, previous, up
@chapter Reporting Bugs
@cindex Reporting Bugs
Email bug reports to @email{bug-mailutils@@gnu.org}.
Be sure to include the word ``mailutils'' somewhere in the ``Subject:'' field.
@node Acknowledgement, Concept Index , Reporting Bugs, Top
@comment node-name, next, previous, up
@chapter Acknowledgement
@cindex Acknowledgement
In no particular order,
Jakob Kaivo @email{jkaivo@@ndn.net},
Jeff Bailey @email{jbailey@@gnu.org},
Sean Perry @email{shaleh@@debian.org},
Thomas Fletcher @email{thomasf@@qnx.com},
Dave Inglis @email{dinglis@@qnx.com},
Brian Edmond @email{briane@@qnx.com},
Sam Roberts @email{sroberts@@uniserve.com},
Sergey Poznyakoff @email{gray@@Mirddin.farlep.net},
Fran@,{c}ois Pinard @email{pinard@@IRO.UMontreal.CA}.
@page
@node Concept Index, Index, Acknowledgement, Top
@comment node-name, next, previous, up
@unnumbered Concept Index
This is a general index of all issues discussed in this manual
@printindex cp
@page
@node Index, , Concept Index, Top
@comment node-name, next, previous, up
@unnumbered Index
This is an alphabetical list of all @sc{mailutils} functions.
@printindex fn
@contents
@bye
@example
@code{/* Prefix @emph{mbox_} is reserved */}
@code{#include <mailutils/mbox.h>}
@end example
The most common mailbox format on UNIX platform is @emph{mbox}. Mbox file
is messages separated by the special format string.
@example
From SP envelope-sender SP date [SP moreinfo]
@end example
@table @code
@item "From "
is sometimes call the @emph{From_}.
@item evelope-sender
is a word with no space.
@item date
has the same format as @code{asctime ()}
@item moreinfo
are optional values that are seldom used.
@end table
A @var{mbox_t} is created, initialised and destroyed by @code{mbox_create ()}
and @code{mbox_destroy ()}. When opening, @code{mbox_open ()} will do a quick
check to see if the format is a valid format or an empty file. The scanning
of the mailbox is done by @code{mbox_scan ()}.
The function, @code{mbox_scan ()}, takes callback functions called during the
scanning to provide information. The scanning will cache some of the headers
fields for speed. Closing the mailbox, @code{mbox_close ()} will free
any ressources like, headers cache, locks etc ... All the messages with
attributes marked deleted will only be removed on @code{mbox_expunge ()}.
If only the attributes need to be save but the messages not removed, this
can be done by @code{mbox_save_attributes ()}. New messages are added with
@code{mbox_append ()}. Attributes are saved in the @emph{Status:} header
field, Read is 'R', Seen is 'O', Deleted is 'd' and Reply is 'r'.
@subsubsection Initialisation
@cindex Mbox Initialisation
@deftypefun int mbox_create (mbox_t *@var{mbox})
Allocate and initialize a @var{mbox} handle.
@table @code
@item MU_ERROR_NO_MEMORY
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun void mbox_destroy (mbox_t @var{mbox})
When a POP3 session is finished, the structure must be @code{free ()}'ed to
reclaim memory.
@end deftypefun
@subsubsection Carrier
@cindex Mbox channel
@deftypefun int mbox_set_carrier (mbox_t, stream_t @var{carrier});
Another type of stream can be provided to work on, the @var{carrier}
is set in the @var{mbox_t} handle. Any previous @var{carrier} stream in
the handle, will be close and release. Since the parsing code
maintain only the offsets off the message the @var{carrier} stream must be
seekable.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_get_carrier (mbox_t, stream_t *@var{carrier});
Return the @var{mbox_t} carrier. If none was set, a new file stream will be
created.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item MU_ERROR_NO_MEMORY
@end table
@end deftypefun
@deftypefun int mbox_open (mbox_t, const char *@var{filename}, int @var{flags})
Open carrier stream with @var{filename} and @var{flags}. The stream will be
quickly examine to see if it is a mbox format.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item MU_ERROR_NO_MEMORY
@item MU_ERROR_NO_ENTRY
@item MU_ERROR_NO_ACCESS
@item MU_ERROR_NOT_SUPPORTED
@end table
@end deftypefun
@deftypefun int mbox_close (mbox_t)
Close the carrier stream and ressources particular to the mailbox.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item MU_ERROR_NO_MEMORY
@end table
@end deftypefun
@deftypefun int mbox_uidnext (mbox_t, unsigned long *@var{uidnext})
Return the uidnext, if the @var{mbox_t} was not scan @code{mbox_scan ()}
is called first.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item same as @code{mbox_scan ()}
@end table
@end deftypefun
@deftypefun int mbox_uidvalidity (mbox_t, unsigned long *@var{uidvalidity})
Return the uidvalidity, if the @var{mbox_t} was not scan @code{mbox_scan ()}
is called first.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item same as @code{mbox_scan ()}
@end table
@end deftypefun
@deftypefun int mbox_get_attribute (mbox_t, unsigned int @var{msgno}, attribute_t *@var{attribute})
Return an @var{attribute} to indicate the status of message number @var{msgno}.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item MU_ERROR_NO_MEMORY
@end table
@end deftypefun
@deftypefun int mbox_get_separator (mbox_t, unsigned int @var{msgno}, char **@var{sep})
Return an allocated string in @var{sep} containing the value "From " separating
each message in Unix mbox format. The string should be @code{free ()}ed by
the caller.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item MU_ERROR_NO_MEMORY
@end table
@end deftypefun
@deftypefun int mbox_set_separator (mbox_t, unsigned int @var{msgno}, const char *@var{sep})
The variable @var{sep} should contain a valid "From " separtor that will be use
when the expunging.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item MU_ERROR_NO_MEMORY
@end table
@end deftypefun
@deftypefun int mbox_get_hstream (mbox_t, unsigned int @var{msgno}, stream_t *@var{stream})
Return a @var{stream} to read the header of message @var{msgno}. The
@var{stream} should be destroy after usage.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item MU_ERROR_NO_MEMORY
@end table
@end deftypefun
@deftypefun int mbox_set_hstream (mbox_t, unsigned int @var{msgno}, stream_t @var{stream})
Use @var{stream} when expunging for message @var{msgno}.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_set_hsize (mbox_t, unsigned int @var{msgno}, unsigned int *@var{size})
Return the @var{size} of message @var{msgno}.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_set_hlines (mbox_t, unsigned int @var{msgno}, unsigned int *@var{size})
Return the number of @var{lines} of message @var{msgno}.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_get_bstream (mbox_t, unsigned int @var{msgno}, stream_t *@var{stream})
Return a @var{stream} to read the body of message @var{msgno}. The
@var{stream} should be destroy after usage.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item MU_ERROR_NO_MEMORY
@end table
@end deftypefun
@deftypefun int mbox_set_bstream (mbox_t, unsigned int @var{msgno}, stream_t @var{stream})
Use @var{stream} when expunging for message @var{msgno}.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_set_bsize (mbox_t, unsigned int @var{msgno}, unsigned int *@var{size})
Return the @var{size} of message @var{msgno}.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_set_blines (mbox_t, unsigned int @var{msgno}, unsigned int *@var{size})
Return the number of @var{lines} of message @var{msgno}.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_get_size (mbox_t, unsigned int *@var{size})
Return the @var{size} of mailbox.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_save (mbox_t)
Save the changes to the messages back to the mailbox, but do not
remove messages mark for deletion in the process.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_mak_deleted (mbox_t, unsigned int @var{msgno})
Mark @var{msgno} for deletion.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_unmak_deleted (mbox_t, unsigned int @var{msgno})
Unmark @var{msgno} if it was marked for deletion.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_expunge (mbox_t)
Save the changes to the mailbox and in the process remove all messages
marked for deletion.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_append (mbox_t, const char *@var{sep}, stream_t @var{stream})
Append to the mailbox an rfc822 message represented by @var{stream}.
The variable @var{sep} should contain a valid "From " separator or
NULL to get the default.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_append_hb (mbox_t, const char *@var{sep}, stream_t @var{hstream}, stream_t @var{bstream})
Append to the mailbox an rfc822 message represented by a header, @var{hstream},
and a body, @var{bstream}. The variable @var{sep} should contain a valid
"From " separator or NULL to get the default.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_scan (mbox_t, unsigned int start, unsigned int *@var{count})
Start scanning the mailbox for new messages. The variable @var{start} can be
a message number starting point. The result of the scanning will be in
@var{count}. The scanning will trigger the @code{mbox_newmsg_cb()} callback
for each new message and @code{mbox_progress_cb ()} at different interval
to notify progression. The return values of the those callback should be
0 is different then 0 the scanning will be stop an the function returns
MU_ERROR_INTERRUPTED.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@item MU_ERROR_INTERRUPTED
@item MU_ERROR_NO_MEMORY
@end table
@end deftypefun
@deftypefun int mbox_set_progress_cb (mbox_t, int (*@var{callback}) (int, void *)), void *@var{arg})
Set the callback function for progress. The variable @var{arg} will be pass
back in the callback as the second argument.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@deftypefun int mbox_set_newmsg_cb (mbox_t, int (*@var{callback}) (int, void *)), void *@var{arg})
Set the callback function for new messages. The variable @var{arg} will be
pass back in the callback as the second argument.
@table @code
@item MU_ERROR_INVALID_PARAMETER
@end table
@end deftypefun
@example
@code{#include <mailutils/message.h>}
@code{/* Prefix @emph{message_} is reserve */}
@end example
The @code{message_t} object is a convenient way to manipulate messages. It
encapsulates the @code{envelope_t}, the @code{header_t} and the @code{body_t}.
@example
@group
mailbox_t
__________ message_t
(message[1]) +------>+-----------------------+
---------- | | envelope_t |
(message[2]) | |-----------------------|
---------- | | header_t |
(message[3])--------+ |-----------------------|
---------- | body_t |
(message[n]) |-----------------------|
---------- | attribute_t |
|-----------------------|
| stream_t |
+-----------------------+
@end group
@end example
@deftypefun void message_create (message_t *@var{msg}, void *@var{owner})
@end deftypefun
@deftypefun void message_destroy (message_t *@var{msg}, void *@var{owner})
The resources allocate for @var{msg} are freed.
@end deftypefun
@deftypefun int message_get_header (message_t @var{msg}, header_t *@var{pheader})
Retrieve @var{msg} header.
@end deftypefun
@deftypefun int message_set_header (message_t @var{msg}, header_t @var{header}, void *@var{owner})
@end deftypefun
@deftypefun int message_get_body (message_t @var{msg}, body_t *@var{pbody})
@end deftypefun
@deftypefun int message_set_body (message_t @var{msg}, body_t @var{body}, void *@var{owner})
@end deftypefun
@deftypefun int message_is_multipart (message_t @var{msg})
Return non-zero value if message is multi-part.
@end deftypefun
@deftypefun int message_get_num_parts (message_t @var{msg}, size_t *nparts)
@end deftypefun
@deftypefun int message_get_part (message_t @var{msg}, size_t part, message_t *msg)
@end deftypefun
@deftypefun int message_get_stream (message_t @var{msg}, stream_t *@var{pstream})
@end deftypefun
@deftypefun int message_set_stream (message_t @var{msg}, stream_t @var{stream},void *@var{owner} )
@end deftypefun
@deftypefun int message_get_attribute (message_t @var{msg}, attribute_t *@var{pattribute})
@end deftypefun
@deftypefun int message_set_attribute (message_t @var{msg}, attribute_t @var{attribute}, void *owner)
@end deftypefun
@deftypefun int message_get_envelope (message_t @var{msg}, envelope_t *penvelope)
@end deftypefun
@deftypefun int message_set_envelope (message_t @var{msg}, envelope_t envelope, void *@var{owner})
@end deftypefun
@deftypefun int message_get_uid (message_t @var{msg}, size_t *@var{uid})
@end deftypefun
@deftypefun int message_get_uidl (message_t @var{msg}, char *@var{buffer}, size_t @var{buflen}, size_t *@var{pwriten})
@end deftypefun
@deftypefun int message_set_uidl (message_t @var{msg}, int (*@var{_get_uidl})(message_t, char *, size_t, size_t *), void *@var{owner})
@end deftypefun
@deftypefun int message_get_observable (message_t @var{msg}, observable_t *@var{observable})
@end deftypefun
@deftypefun int message_create_attachment (const char *@var{content_type}, const char *@var{encoding}, const char *@var{filename}, message_t *@var{newmsg})
@end deftypefun
@deftypefun int message_save_attachment (message_t @var{msg}, const char *@var{filename}, void **@var{data})
@end deftypefun
@deftypefun int message_encapsulate (message_t @var{msg}, message_t *@var{newmsg}, void **@var{data})
@end deftypefun
@deftypefun int message_unencapsulate (message_t @var{msg}, message_t *@var{newmsg}, void **@var{data});
@end deftypefun
@example
@code{/* Prefix @emph{mh_} is reserved */}
@code{#include <mailutils/mh.h>}
@end example
Mail Handler mailbox format. Not implemented.
@example
@code{/* Prefix @emph{pop3_} is reserve */}
@code{#include <mailutils/pop3.h>}
@end example
Multipurpose Internet Mail Extensions (MIME).
@deftypefun int mime_create (mime_t *pmime, message_t msg, int flags)
@end deftypefun
@deftypefun void mime_destroy (mime_t *pmime)
@end deftypefun
@deftypefun int mime_is_multipart (mime_t mime)
@end deftypefun
@deftypefun int mime_get_num_parts (mime_t mime, size_t *nparts)
@end deftypefun
@deftypefun int mime_get_part (mime_t mime, size_t part, message_t *msg)
@end deftypefun
@deftypefun int mime_add_part (mime_t mime, message_t msg)
@end deftypefun
@deftypefun int mime_get_message (mime_t mime, message_t *msg)
@end deftypefun
@example
@code{/* Prefix @emph{nntp_} is reserved */}
@code{#include <mailutils/nntp.h>}
@end example
Network News Transfer Protocol. Not implemented.
@subsection Commands
@subsubsection Initialisation
@cindex NNTP Initialisation
@deftypefun int nntp_create (nnpt_t *)
@end deftypefun
@deftypefun int nntp_destroy (nnpt_t *)
@end deftypefun
@deftypefun int nntp_open (nnpt_t)
@end deftypefun
@subsubsection Article
@cindex NNTP Article
@deftypefun int nntp_article (nnpt_t)
@end deftypefun
@subsubsection Body
@cindex NNTP Body
@deftypefun int nntp_body (nntp_t)
@end deftypefun
@subsubsection Group
@cindex NNTP Group
@deftypefun int nntp_group (nntp_t)
@end deftypefun
@subsubsection Head
@cindex NNTP Head
@deftypefun int nntp_head (nntp_t)
@end deftypefun
@subsubsection Help
@cindex NNTP Help
@deftypefun int nntp_help (nntp_t)
@end deftypefun
@subsubsection IHave
@cindex NNTP IHave
@deftypefun int nntp_ihave (nntp_t)
@end deftypefun
@subsubsection Last
@cindex NNTP Last
@deftypefun int nntp_last (nntp_t)
@end deftypefun
@subsubsection List
@cindex NNTP List
@deftypefun int nntp_list (nntp_t)
@end deftypefun
@subsubsection NewGroups
@cindex NNTP NewGroups
@deftypefun int nntp_newgroups (nntp_t)
@end deftypefun
@subsubsection NewNews
@cindex NNTP NewNews
@deftypefun int nntp_newnews (nntp_t)
@end deftypefun
@subsubsection Next
@cindex NNTP Next
@deftypefun int nntp_next (nntp_t)
@end deftypefun
@subsubsection Post
@cindex NNTP Post
@deftypefun int nntp_post (nntp_t)
@end deftypefun
@subsubsection Quit
@cindex NNTP Quit
@deftypefun int nntp_quit (nntp_t)
@end deftypefun
@subsubsection Slave
@cindex NNTP Slave
@deftypefun int nntp_slave (nntp_t)
@end deftypefun
@subsubsection Stat
@cindex NNTP Stat
@deftypefun int nntp_stat (nntp_t)
@end deftypefun
@example
@code{/* Prefix @emph{parse822_} is reserved */}
@code{#include <mailutils/parse822.h>}
@end example
Internet Message Format, see Address node for the discusion.
@deftypefun int parse822_address_list (address_t* a, const char* s)
@end deftypefun
@deftypefun int parse822_mail_box (const char** p, const char* e, address_t* a)
@end deftypefun
@deftypefun int parse822_group (const char** p, const char* e, address_t* a)
@end deftypefun
@deftypefun int parse822_address (const char** p, const char* e, address_t* a)
@end deftypefun
@deftypefun int parse822_route_addr (const char** p, const char* e, address_t* a)
@end deftypefun
@deftypefun int parse822_route (const char** p, const char* e, char** route)
@end deftypefun
@deftypefun int parse822_addr_spec (const char** p, const char* e, address_t* a)
@end deftypefun
@deftypefun int parse822_unix_mbox (const char** p, const char* e, address_t* a)
@end deftypefun
@deftypefun int parse822_local_part (const char** p, const char* e, char** local_part)
@end deftypefun
@deftypefun int parse822_domain (const char** p, const char* e, char** domain)
@end deftypefun
@deftypefun int parse822_sub_domain (const char** p, const char* e, char** sub_domain)
@end deftypefun
@deftypefun int parse822_domain_ref (const char** p, const char* e, char** domain_ref)
@end deftypefun
@deftypefun int parse822_domain_literal (const char** p, const char* e, char** domain_literal)
@end deftypefun
@deftypefun int parse822_quote_string (char** quoted, const char* raw)
@end deftypefun
@deftypefun int parse822_quote_local_part (char** quoted, const char* raw)
@end deftypefun
@deftypefun int parse822_field_body (const char** p, const char *e, char** fieldbody)
@end deftypefun
@deftypefun int parse822_field_name (const char** p, const char *e, char** fieldname)
@end deftypefun
@section frm
List header from a mailbox.
@section imap4d
Imap4 daemon.
@section mail
Send and receive mail.
@section parse822
Parse RFC 822 fields.
@section pop3d
POP3 daemon.
@section readmsg
Extract messages from a folder.
@section sendmsg
Send a message.
@section sieve
Filter a mailbox.
Network Working Group J. Myers
Request for Comments: 1734 Carnegie Mellon
Category: Standards Track December 1994
POP3 AUTHentication command
Status of this Memo
This document specifies an Internet standards track protocol for the
Internet community, and requests discussion and suggestions for
improvements. Please refer to the current edition of the "Internet
Official Protocol Standards" (STD 1) for the standardization state
and status of this protocol. Distribution of this memo is unlimited.
1. Introduction
This document describes the optional AUTH command, for indicating an
authentication mechanism to the server, performing an authentication
protocol exchange, and optionally negotiating a protection mechanism
for subsequent protocol interactions. The authentication and
protection mechanisms used by the POP3 AUTH command are those used by
IMAP4.
2. The AUTH command
AUTH mechanism
Arguments:
a string identifying an IMAP4 authentication mechanism,
such as defined by [IMAP4-AUTH]. Any use of the string
"imap" used in a server authentication identity in the
definition of an authentication mechanism is replaced with
the string "pop".
Restrictions:
may only be given in the AUTHORIZATION state
Discussion:
The AUTH command indicates an authentication mechanism to
the server. If the server supports the requested
authentication mechanism, it performs an authentication
protocol exchange to authenticate and identify the user.
Optionally, it also negotiates a protection mechanism for
subsequent protocol interactions. If the requested
authentication mechanism is not supported, the server
Myers [Page 1]
RFC 1734 POP3 AUTH December 1994
should reject the AUTH command by sending a negative
response.
The authentication protocol exchange consists of a series
of server challenges and client answers that are specific
to the authentication mechanism. A server challenge,
otherwise known as a ready response, is a line consisting
of a "+" character followed by a single space and a BASE64
encoded string. The client answer consists of a line
containing a BASE64 encoded string. If the client wishes
to cancel an authentication exchange, it should issue a
line with a single "*". If the server receives such an
answer, it must reject the AUTH command by sending a
negative response.
A protection mechanism provides integrity and privacy
protection to the protocol session. If a protection
mechanism is negotiated, it is applied to all subsequent
data sent over the connection. The protection mechanism
takes effect immediately following the CRLF that concludes
the authentication exchange for the client, and the CRLF of
the positive response for the server. Once the protection
mechanism is in effect, the stream of command and response
octets is processed into buffers of ciphertext. Each
buffer is transferred over the connection as a stream of
octets prepended with a four octet field in network byte
order that represents the length of the following data.
The maximum ciphertext buffer length is defined by the
protection mechanism.
The server is not required to support any particular
authentication mechanism, nor are authentication mechanisms
required to support any protection mechanisms. If an AUTH
command fails with a negative response, the session remains
in the AUTHORIZATION state and client may try another
authentication mechanism by issuing another AUTH command,
or may attempt to authenticate by using the USER/PASS or
APOP commands. In other words, the client may request
authentication types in decreasing order of preference,
with the USER/PASS or APOP command as a last resort.
Should the client successfully complete the authentication
exchange, the POP3 server issues a positive response and
the POP3 session enters the TRANSACTION state.
Possible Responses:
+OK maildrop locked and ready
-ERR authentication exchange failed
Myers [Page 2]
RFC 1734 POP3 AUTH December 1994
Examples:
S: +OK POP3 server ready
C: AUTH KERBEROS_V4
S: + AmFYig==
C: BAcAQU5EUkVXLkNNVS5FRFUAOCAsho84kLN3/IJmrMG+25a4DT
+nZImJjnTNHJUtxAA+o0KPKfHEcAFs9a3CL5Oebe/ydHJUwYFd
WwuQ1MWiy6IesKvjL5rL9WjXUb9MwT9bpObYLGOKi1Qh
S: + or//EoAADZI=
C: DiAF5A4gA+oOIALuBkAAmw==
S: +OK Kerberos V4 authentication successful
...
C: AUTH FOOBAR
S: -ERR Unrecognized authentication type
Note: the line breaks in the first client answer are
for editorial clarity and are not in real authentica-
tors.
Myers [Page 3]
RFC 1734 POP3 AUTH December 1994
3. Formal Syntax
The following syntax specification uses the augmented Backus-Naur
Form (BNF) notation as specified in RFC 822.
Except as noted otherwise, all alphabetic characters are case-
insensitive. The use of upper or lower case characters to define
token strings is for editorial clarity only. Implementations MUST
accept these strings in a case-insensitive fashion.
ATOM_CHAR ::= <any CHAR except atom_specials>
atom_specials ::= "(" / ")" / "{" / SPACE / CTLs / "%" / "*" /
<"> / "\"
auth ::= "AUTH" 1*(SPACE / TAB) auth_type *(CRLF base64)
CRLF
auth_type ::= 1*ATOM_CHAR
base64 ::= *(4base64_CHAR) [base64_terminal]
base64_char ::= "A" / "B" / "C" / "D" / "E" / "F" / "G" / "H" /
"I" / "J" / "K" / "L" / "M" / "N" / "O" / "P" /
"Q" / "R" / "S" / "T" / "U" / "V" / "W" / "X" /
"Y" / "Z" /
"a" / "b" / "c" / "d" / "e" / "f" / "g" / "h" /
"i" / "j" / "k" / "l" / "m" / "n" / "o" / "p" /
"q" / "r" / "s" / "t" / "u" / "v" / "w" / "x" /
"y" / "z" /
"0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" /
"8" / "9" / "+" / "/"
;; Case-sensitive
base64_terminal ::= (2base64_char "==") / (3base64_char "=")
CHAR ::= <any 7-bit US-ASCII character except NUL,
0x01 - 0x7f>
continue_req ::= "+" SPACE base64 CRLF
CR ::= <ASCII CR, carriage return, 0x0C>
CRLF ::= CR LF
CTL ::= <any ASCII control character and DEL,
0x00 - 0x1f, 0x7f>
Myers [Page 4]
RFC 1734 POP3 AUTH December 1994
LF ::= <ASCII LF, line feed, 0x0A>
SPACE ::= <ASCII SP, space, 0x20>
TAB ::= <ASCII HT, tab, 0x09>
4. References
[IMAP4-AUTH] Myers, J., "IMAP4 Authentication Mechanisms", RFC 1731,
Carnegie Mellon, December 1994.
5. Security Considerations
Security issues are discussed throughout this memo.
6. Author's Address
John G. Myers
Carnegie-Mellon University
5000 Forbes Ave
Pittsburgh, PA 15213
EMail: jgm+@cmu.edu
Myers [Page 5]
Network Working Group R. Nelson
Request for Comments: 1957 Crynwr Software
Updates: 1939 June 1996
Category: Informational
Some Observations on Implementations
of the Post Office Protocol (POP3)
Status of this Memo
This memo provides information for the Internet community. This memo
does not specify an Internet standard of any kind. Distribution of
this memo is unlimited.
Observations
Sometimes an implementation is mistaken for a standard. POP3 servers
and clients are no exception. The widely-used UCB POP3 server,
popper, which has been further developed by Qualcomm, always has
additional information following the status indicator. So, the
status indicator always has a space following it. Two POP3 clients
have been observed to expect that space, and fail when it has not
been found. The RFC does not require the space, hence this memo.
These clients are the freely copyable Unix "popclient" and the
proprietary "netApp Systems Internet Series". The authors of both of
these have been contacted, and new releases will not expect the
space, but old versions should be supported.
In addition, two popular clients require optional parts of the RFC.
Netscape requires UIDL, and Eudora requires TOP.
The optional APOP authentication command has not achieved wide
penetration yet. Newer versions of the Qualcomm POP server implement
it. Known client implementations of APOP include GNU Emacs VM client
and Eudora Lite and Eudora Pro.
Security Considerations
Security issues are not discussed in this memo.
References
[1] Myers, J., and M. Rose, "Post Office Protocol - Version 3",
STD 53, RFC 1939, May 1996.
Nelson Informational [Page 1]
RFC 1957 Notes on POP3 Implementations June 1996
Author's Address
Russell Nelson
Crynwr Software
521 Pleasant Valley Rd.
Potsdam, NY 13676
Phone: +1.315.268.1925
FAX: +1.315.268.9201
EMail: nelson@crynwr.com
Nelson Informational [Page 2]
This diff could not be displayed because it is too large.
Known errors in RFC 2060 as of 13 September 1998:
1) The SELECT and EXAMINE response list does not mention UIDVALIDITY.
2) In the definition of store_att_flags, #flag should be 1#flag; in other
words, at least one flag must be given. To do an empty list of flags,
you must use the parenthesized form: "()".
3) The example in 6.4.6 is missing parenthesis around the FETCH attributes.
It should read:
Example: C: A003 STORE 2:4 +FLAGS (\Deleted)
S: * 2 FETCH (FLAGS (\Deleted \Seen))
S: * 3 FETCH (FLAGS (\Deleted))
S: * 4 FETCH (FLAGS (\Deleted \Flagged \Seen))
S: A003 OK STORE completed
4) Section 7.4.2 has an example of "a two part message consisting of a
text and a BASE645-encoded text attachment". "BASE645" should be
BASE64.
5) In the example in 7.4.2 discussed above, there is a spurious close
parenthesis at the end of the example.
6) Spurious obsolete response "MAILBOX" is listed in mailbox_data and
should be removed.
7) There is a spurious "<" in the mailbox_data rule that should be removed.
8) CRLF is missing from the continue_req rule.
9) The atom in resp_text_code should specifically exclude "]".
10) The example in 6.3.11 does not show the command continuation request.
11) NEWNAME is missing from resp_text_code.
12) There is a missing open parenthesis in the media_basic grammar rule.
13) Status attributes are incorrectly defined in mailbox_data rule.
14) The UID FETCH example is missing an "OK" in the response.
15) Multipart extension data incorrectly specifies that language must be
given along with disposition.
This diff could not be displayed because it is too large.
Network Working Group J. Myers
Request for Comments: 2088 Carnegie Mellon
Cateogry: Standards Track January 1997
IMAP4 non-synchronizing literals
Status of this Memo
This document specifies an Internet standards track protocol for the
Internet community, and requests discussion and suggestions for
improvements. Please refer to the current edition of the "Internet
Official Protocol Standards" (STD 1) for the standardization state
and status of this protocol. Distribution of this memo is unlimited.
1. Abstract
The Internet Message Access Protocol [IMAP4] contains the "literal"
syntactic construct for communicating strings. When sending a
literal from client to server, IMAP4 requires the client to wait for
the server to send a command continuation request between sending the
octet count and the string data. This document specifies an
alternate form of literal which does not require this network round
trip.
2. Conventions Used in this Document
In examples, "C:" and "S:" indicate lines sent by the client and
server respectively.
3. Specification
The non-synchronizing literal is added an alternate form of literal,
and may appear in communication from client to server instead of the
IMAP4 form of literal. The IMAP4 form of literal, used in
communication from client to server, is referred to as a
synchronizing literal.
Non-synchronizing literals may be used with any IMAP4 server
implementation which returns "LITERAL+" as one of the supported
capabilities to the CAPABILITY command. If the server does not
advertise the LITERAL+ capability, the client must use synchronizing
literals instead.
The non-synchronizing literal is distinguished from the original
synchronizing literal by having a plus ('+') between the octet count
and the closing brace ('}'). The server does not generate a command
continuation request in response to a non-synchronizing literal, and
Myers Standards Track [Page 1]
RFC 2088 LITERAL January 1997
clients are not required to wait before sending the octets of a non-
synchronizing literal.
The protocol receiver of an IMAP4 server must check the end of every
received line for an open brace ('{') followed by an octet count, a
plus ('+'), and a close brace ('}') immediately preceeding the CRLF.
If it finds this sequence, it is the octet count of a non-
synchronizing literal and the server MUST treat the specified number
of following octets and the following line as part of the same
command. A server MAY still process commands and reject errors on a
line-by-line basis, as long as it checks for non-synchronizing
literals at the end of each line.
Example: C: A001 LOGIN {11+}
C: FRED FOOBAR {7+}
C: fat man
S: A001 OK LOGIN completed
4. Formal Syntax
The following syntax specification uses the augmented Backus-Naur
Form (BNF) notation as specified in [RFC-822] as modified by [IMAP4].
Non-terminals referenced but not defined below are as defined by
[IMAP4].
literal ::= "{" number ["+"] "}" CRLF *CHAR8
;; Number represents the number of CHAR8 octets
6. References
[IMAP4] Crispin, M., "Internet Message Access Protocol - Version 4",
draft-crispin-imap-base-XX.txt, University of Washington, April 1996.
[RFC-822] Crocker, D., "Standard for the Format of ARPA Internet Text
Messages", STD 11, RFC 822.
7. Security Considerations
There are no known security issues with this extension.
8. Author's Address
John G. Myers
Carnegie-Mellon University
5000 Forbes Ave.
Pittsburgh PA, 15213-3890
Email: jgm+@cmu.edu
Myers Standards Track [Page 2]
Network Working Group E. Levinson
Request for Comments: 2111 XIson, Inc.
Category: Standards Track March 1997
Content-ID and Message-ID Uniform Resource Locators
Status of this Memo
This document specifies an Internet standards track protocol for the
Internet community, and requests discussion and suggestions for
improvements. Please refer to the current edition of the "Internet
Official Protocol Standards" (STD 1) for the standardization state
and status of this protocol. Distribution of this memo is unlimited.
Abstract
The Uniform Resource Locator (URL) schemes, "cid:" and "mid:" allow
references to messages and the body parts of messages. For example,
within a single multipart message, one HTML body part might include
embedded references to other parts of the same message.
1. Introduction
The use of [MIME] within email to convey Web pages and their
associated images requires a URL scheme to permit the HTML to refer
to the images or other data included in the message. The Content-ID
Uniform Resource Locator, "cid:", serves that purpose.
Similarly Net News readers use Message-IDs to link related messages
together. The Message-ID URL provides a scheme, "mid:", to refer to
such messages as a "resource".
The "mid" (Message-ID) and "cid" (Content-ID) URL schemes provide
identifiers for messages and their body parts. The "mid" scheme uses
(a part of) the message-id of an email message to refer to a specific
message. The "cid" scheme refers to a specific body part of a
message; its use is generally limited to references to other body
parts in the same message as the referring body part. The "mid"
scheme may also refer to a specific body part within a designated
message, by including the content-ID's address.
A note on terminology. The terms "body part" and "MIME entity" are
used interchangeably. They refer to the headers and body of a MIME
message, either the message itself or one of the body parts contained
in a Multipart message.
Levinson Standards Track [Page 1]
RFC 2111 CID and MID URLs March 1997
2. The MID and CID URL Schemes
RFC1738 [URL] reserves the "mid" and "cid" schemes for Message-ID and
Content-ID respectively. This memorandum defines the syntax for
those URLs. Because they use the same syntactic elements they are
presented together.
The URLs take the form
content-id = url-addr-spec
message-id = url-addr-spec
url-addr-spec = addr-spec ; URL encoding of RFC 822 addr-spec
cid-url = "cid" ":" content-id
mid-url = "mid" ":" message-id [ "/" content-id ]
Note: in Internet mail messages, the addr-spec in a Content-ID
[MIME] or Message-ID [822] header are enclosed in angle brackets
(<>). Since addr-spec in a Message-ID or Content-ID might contain
characters not allowed within a URL; any such character (including
"/", which is reserved within the "mid" scheme) must be hex-
encoded using the %hh escape mechanism in [URL].
A "mid" URL with only a "message-id" refers to an entire message.
With the appended "content-id", it refers to a body part within a
message, as does a "cid" URL. The Content-ID of a MIME body part is
required to be globally unique. However, in many systems that store
messages, body parts are not indexed independently their context
(message). The "mid" URL long form was designed to supply the
context needed to support interoperability with such systems.
A implementation conforming to this specification is required to
support the "mid" URL long form (message-id/content-id). Conforming
implementations can choose to, but are not required to, take
advantage of the content-id's uniqueness and interpret a "cid" URL to
refer to any body part within the message store.
In limited circumstances (e.g., within multipart/alternate), a single
message may contain several body parts that have the same Content-ID.
That occurs, for example, when identical data can be accessed through
different methods [MIME, sect. 7.2.3]. In those cases, conforming
implementations are required to use the rules of the containing MIME
entity (e.g., multi-part/alternate) to select the body part to which
the Content-ID refers.
Levinson Standards Track [Page 2]
RFC 2111 CID and MID URLs March 1997
A "cid" URL is converted to the corresponding Content-ID message
header [MIME] by removing the "cid:" prefix, converting %hh hex-
escaped characters to their ASCII equivalents and enclosing the
remaining parts with an angle bracket pair, "<" and ">". For
example, "mid:foo4%25foo1@bar.net" corresponds to
Message-ID: <foo4%foo1@bar.net>
A "mid" URL is converted to a Message-ID or Message-ID/Content-ID
pair in a similar fashion.
Both message-id and content-id are required to be globally unique.
That is, no two different messages will ever have the same Message-ID
addr-spec; no different body parts will ever have the same Content-ID
addr-spec. A common technique used by many message systems is to use
a time and date stamp along with the local host's domain name, e.g.,
950124.162336@XIson.com.
Some Examples
The following message contains an HTML body part that refers to an
image contained in another body part. Both body parts are contained
in a Multipart/Related MIME entity. The HTML IMG tag contains a
cidurl which points to the image.
From: foo1@bar.net
To: foo2@bar.net
Subject: A simple example
Mime-Version: 1.0
Content-Type: multipart/related; boundary="boundary-example-1";
type=Text/HTML
--boundary-example 1
Content-Type: Text/HTML; charset=US-ASCII
... text of the HTML document, which might contain a hyperlink
to the other body part, for example through a statement such as:
<IMG SRC="cid:foo4*foo1@bar.net" ALT="IETF logo">
--boundary-example-1
Content-ID: foo4*foo1@bar.net
Content-Type: IMAGE/GIF
Content-Transfer-Encoding: BASE64
Levinson Standards Track [Page 3]
RFC 2111 CID and MID URLs March 1997
R0lGODlhGAGgAPEAAP/////ZRaCgoAAAACH+PUNvcHlyaWdodCAoQykgMTk5
NSBJRVRGLiBVbmF1dGhvcml6ZWQgZHVwbGljYXRpb24gcHJvaGliaXRlZC4A
etc...
--boundary-example-1--
The following message points to another message (hopefully still in
the recipient's message store).
From: bar@none.com
To: phooey@all.com
Subject: Here's how to do it
Content-type: text/html; charset=usascii
... The items in my
<A HREF= "mid:960830.1639@XIson.com/partA.960830.1639@XIson.com">
previous message</A>, shows how the approach you propose can be
used to accomplish ...
3. Security Considerations
The URLs defined here provide an addressing or referencing mechanism.
The values of these URLs disclose no more about the originators
environment than the corresponding Message-ID and Content-ID values.
Where concern exists about such disclosures the originator of a
message using mid and cid URLs must take precautions to insure that
confidential information is not disclosed. Those precautions should
already be in place to handle existing mail use of the Message-ID and
Content-ID.
4. References
[822] Crocker, D., "Standard for the Format of ARPA Internet Text
Messages," August 1982, University of Delaware, STD 11, RFC
822.
[MIME] N. Borenstein, N. Freed, "MIME (Multipurpose Internet Mail
Extensions) Part One: Mechanisms for Specifying and
Describing the Format of Internet Message Bodies,"
September 1993, RFC 1521.
[URL] Berners-Lee, T., Masinter, L., and McCahill, M., "Uniform
Resource Locators (URL)," December 1994.
[MULREL] E. Levinson, "The MIME Multipart/Related Content-type,"
December 1995, RFC 1874.
Levinson Standards Track [Page 4]
RFC 2111 CID and MID URLs March 1997
5. Acknowledgments
The original concept of "mid" and "cid" URLs were part of the Tim
Berners-Lee's original vision of the World Wide Web. The ideas and
design have benefited greatly by discussions with Harald Alvestrand,
Dan Connolly, Roy Fielding, Larry Masinter, Jacob Palme, and others
in the MHTML working group.
6. Author's Address
Edward Levinson
47 Clive Street
Metuchen, NJ 08840-1060
USA
+1 908 549 3716
<XIson@cnj.digex.net>
Levinson Standards Track [Page 5]
Network Working Group M. Gahrns
Request for Comments: 2221 Microsoft
Category: Standards Track October 1997
IMAP4 Login Referrals
Status of this Memo
This document specifies an Internet standards track protocol for the
Internet community, and requests discussion and suggestions for
improvements. Please refer to the current edition of the "Internet
Official Protocol Standards" (STD 1) for the standardization state
and status of this protocol. Distribution of this memo is unlimited.
Copyright Notice
Copyright (C) The Internet Society (1997). All Rights Reserved.
1. Abstract
When dealing with large amounts of users and many IMAP4 [RFC-2060]
servers, it is often necessary to move users from one IMAP4 server to
another. For example, hardware failures or organizational changes
may dictate such a move.
Login referrals allow clients to transparently connect to an
alternate IMAP4 server, if their home IMAP4 server has changed.
A referral mechanism can provide efficiencies over the alternative
'proxy method', in which the local IMAP4 server contacts the remote
server on behalf of the client, and then transfers the data from the
remote server to itself, and then on to the client. The referral
mechanism's direct client connection to the remote server is often a
more efficient use of bandwidth, and does not require the local
server to impersonate the client when authenticating to the remote
server.
2. Conventions used in this document
In examples, "C:" and "S:" indicate lines sent by the client and
server respectively.
A home server, is an IMAP4 server that contains the user's inbox.
A remote server is a server that contains remote mailboxes.
Gahrns Standards Track [Page 1]
RFC 2221 IMAP4 Login Referrals October 1997
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC-2119].
3. Introduction and Overview
IMAP4 servers that support this extension MUST list the keyword
LOGIN-REFERRALS in their CAPABILITY response. No client action is
needed to invoke the LOGIN-REFERRALS capability in a server.
A LOGIN-REFERRALS capable IMAP4 server SHOULD NOT return a referral
to a server that will return a referral. A client MUST NOT follow
more than 10 levels of referral without consulting the user.
A LOGIN-REFERRALS response code MUST contain as an argument a valid
IMAP server URL as defined in [IMAP-URL].
A home server referral consists of either a tagged NO or OK, or an
untagged BYE response that contains a LOGIN-REFERRALS response code.
Example: A001 NO [REFERRAL IMAP://user;AUTH=*@SERVER2/] Remote Server
NOTE: user;AUTH=* is specified as required by [IMAP-URL] to avoid a
client falling back to anonymous login.
4. Home Server Referrals
A home server referral may be returned in response to an AUTHENTICATE
or LOGIN command, or it may appear in the connection startup banner.
If a server returns a home server referral in a tagged NO response,
that server does not contain any mailboxes that are accessible to the
user. If a server returns a home server referral in a tagged OK
response, it indicates that the user's personal mailboxes are
elsewhere, but the server contains public mailboxes which are
readable by the user. After receiving a home server referral, the
client can not make any assumptions as to whether this was a
permanent or temporary move of the user.
4.1. LOGIN and AUTHENTICATE Referrals
An IMAP4 server MAY respond to a LOGIN or AUTHENTICATE command with a
home server referral if it wishes to direct the user to another IMAP4
server.
Example: C: A001 LOGIN MIKE PASSWORD
S: A001 NO [REFERRAL IMAP://MIKE@SERVER2/] Specified user
is invalid on this server. Try SERVER2.
Gahrns Standards Track [Page 2]
RFC 2221 IMAP4 Login Referrals October 1997
Example: C: A001 LOGIN MATTHEW PASSWORD
S: A001 OK [REFERRAL IMAP://MATTHEW@SERVER2/] Specified
user's personal mailboxes located on Server2, but
public mailboxes are available.
Example: C: A001 AUTHENTICATE GSSAPI
<authentication exchange>
S: A001 NO [REFERRAL IMAP://user;AUTH=GSSAPI@SERVER2/]
Specified user is invalid on this server. Try
SERVER2.
4.2. BYE at connection startup referral
An IMAP4 server MAY respond with an untagged BYE and a REFERRAL
response code that contains an IMAP URL to a home server if it is not
willing to accept connections and wishes to direct the client to
another IMAP4 server.
Example: S: * BYE [REFERRAL IMAP://user;AUTH=*@SERVER2/] Server not
accepting connections. Try SERVER2
5. Formal Syntax
The following syntax specification uses the augmented Backus-Naur
Form (BNF) as described in [ABNF].
This amends the "resp_text_code" element of the IMAP4 grammar
described in [RFC-2060]
resp_text_code =/ "REFERRAL" SPACE <imapurl>
; See [IMAP-URL] for definition of <imapurl>
; See [RFC-2060] for base definition of resp_text_code
6. Security Considerations
The IMAP4 login referral mechanism makes use of IMAP URLs, and as
such, have the same security considerations as general internet URLs
[RFC-1738], and in particular IMAP URLs [IMAP-URL].
A server MUST NOT give a login referral if authentication for that
user fails. This is to avoid revealing information about the user's
account to an unauthorized user.
With the LOGIN-REFERRALS capability, it is potentially easier to
write a rogue 'password catching' server that collects login data and
then refers the client to their actual IMAP4 server. Although
referrals reduce the effort to write such a server, the referral
response makes detection of the intrusion easier.
Gahrns Standards Track [Page 3]
RFC 2221 IMAP4 Login Referrals October 1997
7. References
[RFC-2060], Crispin, M., "Internet Message Access Protocol - Version
4rev1", RFC 2060, December 1996.
[IMAP-URL], Newman, C., "IMAP URL Scheme", RFC 2192, Innosoft,
September 1997.
[RFC-1738], Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform
Resource Locators (URL)", RFC 1738, December 1994.
[RFC-2119], Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", RFC 2119, March 1997.
[ABNF], DRUMS working group, Dave Crocker Editor, "Augmented BNF for
Syntax Specifications: ABNF", Work in Progress.
8. Acknowledgments
Many valuable suggestions were received from private discussions and
the IMAP4 mailing list. In particular, Raymond Cheng, Mark Crispin,
Mark Keasling Chris Newman and Larry Osterman made significant
contributions to this document.
9. Author's Address
Mike Gahrns
Microsoft
One Microsoft Way
Redmond, WA, 98072
Phone: (206) 936-9833
EMail: mikega@microsoft.com
Gahrns Standards Track [Page 4]
RFC 2221 IMAP4 Login Referrals October 1997
10. Full Copyright Statement
Copyright (C) The Internet Society (1997). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implmentation may be prepared, copied, published
andand distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE."
Gahrns Standards Track [Page 5]
Network Working Group C. Newman
Request for Comments: 2245 Innosoft
Category: Standards Track November 1997
Anonymous SASL Mechanism
Status of this Memo
This document specifies an Internet standards track protocol for the
Internet community, and requests discussion and suggestions for
improvements. Please refer to the current edition of the "Internet
Official Protocol Standards" (STD 1) for the standardization state
and status of this protocol. Distribution of this memo is unlimited.
Copyright Notice
Copyright (C) The Internet Society (1997). All Rights Reserved.
Abstract
It is common practice on the Internet to permit anonymous access to
various services. Traditionally, this has been done with a plain
text password mechanism using "anonymous" as the user name and
optional trace information, such as an email address, as the
password. As plaintext login commands are not permitted in new IETF
protocols, a new way to provide anonymous login is needed within the
context of the SASL [SASL] framework.
1. Conventions Used in this Document
The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
in this document are to be interpreted as defined in "Key words for
use in RFCs to Indicate Requirement Levels" [KEYWORDS].
2. Anonymous SASL mechanism
The mechanism name associated with anonymous access is "ANONYMOUS".
The mechanism consists of a single message from the client to the
server. The client sends optional trace information in the form of a
human readable string. The trace information should take one of
three forms: an Internet email address, an opaque string which does
not contain the '@' character and can be interpreted by the system
administrator of the client's domain, or nothing. For privacy
reasons, an Internet email address should only be used with
permission from the user.
Newman Standards Track [Page 1]
RFC 2245 Anonymous SASL Mechanism November 1997
A server which permits anonymous access will announce support for the
ANONYMOUS mechanism, and allow anyone to log in using that mechanism,
usually with restricted access.
The formal grammar for the client message using Augmented BNF [ABNF]
follows.
message = [email / token]
TCHAR = %x20-3F / %x41-7E
;; any printable US-ASCII character except '@'
email = addr-spec
;; as defined in [IMAIL], except with no free
;; insertion of linear-white-space, and the
;; local-part MUST either be entirely enclosed in
;; quotes or entirely unquoted
token = 1*255TCHAR
3. Example
Here is a sample anonymous login between an IMAP client and server.
In this example, "C:" and "S:" indicate lines sent by the client and
server respectively. If such lines are wrapped without a new "C:" or
"S:" label, then the wrapping is for editorial clarity and is not
part of the command.
Note that this example uses the IMAP profile [IMAP4] of SASL. The
base64 encoding of challenges and responses, as well as the "+ "
preceding the responses are part of the IMAP4 profile, not part of
SASL itself. Newer profiles of SASL will include the client message
with the AUTHENTICATE command itself so the extra round trip below
(the server response with an empty "+ ") can be eliminated.
In this example, the user's opaque identification token is "sirhc".
S: * OK IMAP4 server ready
C: A001 CAPABILITY
S: * CAPABILITY IMAP4 IMAP4rev1 AUTH=CRAM-MD5 AUTH=ANONYMOUS
S: A001 OK done
C: A002 AUTHENTICATE ANONYMOUS
S: +
C: c2lyaGM=
S: A003 OK Welcome, trace information has been logged.
Newman Standards Track [Page 2]
RFC 2245 Anonymous SASL Mechanism November 1997
4. Security Considerations
The anonymous mechanism grants access to information by anyone. For
this reason it should be disabled by default so the administrator can
make an explicit decision to enable it.
If the anonymous user has any write privileges, a denial of service
attack is possible by filling up all available space. This can be
prevented by disabling all write access by anonymous users.
If anonymous users have read and write access to the same area, the
server can be used as a communication mechanism to anonymously
exchange information. Servers which accept anonymous submissions
should implement the common "drop box" model which forbids anonymous
read access to the area where anonymous submissions are accepted.
If the anonymous user can run many expensive operations (e.g., an
IMAP SEARCH BODY command), this could enable a denial of service
attack. Servers are encouraged to limit the number of anonymous
users and reduce their priority or limit their resource usage.
If there is no idle timeout for the anonymous user and there is a
limit on the number of anonymous users, a denial of service attack is
enabled. Servers should implement an idle timeout for anonymous
users.
The trace information is not authenticated so it can be falsified.
This can be used as an attempt to get someone else in trouble for
access to questionable information. Administrators trying to trace
abuse need to realize this information may be falsified.
A client which uses the user's correct email address as trace
information without explicit permission may violate that user's
privacy. Information about who accesses an anonymous archive on a
sensitive subject (e.g., sexual abuse) has strong privacy needs.
Clients should not send the email address without explicit permission
of the user and should offer the option of supplying no trace token
-- thus only exposing the source IP address and time. Anonymous
proxy servers could enhance this privacy, but would have to consider
the resulting potential denial of service attacks.
Anonymous connections are susceptible to man in the middle attacks
which view or alter the data transferred. Clients and servers are
encouraged to support external integrity and encryption mechanisms.
Protocols which fail to require an explicit anonymous login are more
susceptible to break-ins given certain common implementation
techniques. Specifically, Unix servers which offer user login may
Newman Standards Track [Page 3]
RFC 2245 Anonymous SASL Mechanism November 1997
initially start up as root and switch to the appropriate user id
after an explicit login command. Normally such servers refuse all
data access commands prior to explicit login and may enter a
restricted security environment (e.g., the Unix chroot function) for
anonymous users. If anonymous access is not explicitly requested,
the entire data access machinery is exposed to external security
attacks without the chance for explicit protective measures.
Protocols which offer restricted data access should not allow
anonymous data access without an explicit login step.
5. References
[ABNF] Crocker, D. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", RFC 2234, November 1997.
[IMAIL] Crocker, D., "Standard for the Format of Arpa Internet Text
Messages", STD 11, RFC 822, August 1982.
[IMAP4] Crispin, M., "Internet Message Access Protocol - Version
4rev1", RFC 2060, December 1996.
[KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", RFC 2119, March 1997.
[SASL] Myers, J., "Simple Authentication and Security Layer (SASL)",
RFC 2222, October 1997.
6. Author's Address
Chris Newman
Innosoft International, Inc.
1050 Lakes Drive
West Covina, CA 91790 USA
Email: chris.newman@innosoft.com
Newman Standards Track [Page 4]
RFC 2245 Anonymous SASL Mechanism November 1997
7. Full Copyright Statement
Copyright (C) The Internet Society (1997). All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works. However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.
The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assigns.
This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Newman Standards Track [Page 5]
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
@example
@code{/* Prefix @emph{sendmail_} is reserved */}
@code{#include <mailutils/sendmail.h>}
@end example
Spawning Sendmail daemon to deliver mail. Not implemented.
/* sfrom, Simple From */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <mailutils/registrar.h>
#include <mailutils/list.h>
#include <mailutils/mailbox.h>
#define BUFFER_SIZE 64
int
main (int argc, const char **argv)
@{
char from[BUFFER_SIZE];
char subject[BUFFER_SIZE];
char *mail;
mailbox_t mbox;
int status
size_t msgno, total = 0;
mail = (argc == 2) ? argv[1] : getenv ("MAIL");
/* Register the type of mailbox. IMAP4, POP3 and local format */
@{
list_t registrar;
registrar_get_list (&registrar);
list_append (registrar, imap_record);
list_append (registrar, path_record);
list_append (registrar, pop_record);
@}
status = mailbox_create (&mbox, mail);
if (status != 0)
@{
fprintf (stderr, "mailbox_create: %s\n", strerror (status));
exit (EXIT_FAILURE);
@}
status = mailbox_open (mbox, MU_STREAM_READ);
if (status != 0)
@{
fprintf (stderr, "mailbox_open: %s\n", strerror (status));
exit (EXIT_FAILURE);
@}
mailbox_messages_count (mbox, &total);
for (msgno = 1; msgno <= total; msgno++)
@{
message_t msg;
header_t hdr;
if ((status = mailbox_get_message (mbox, msgno, &msg)) != 0
|| (status = message_get_header (msg, &hdr)) != 0)
@{
fprintf (stderr, "Error message:%s\n",
strerror (status));
exit (EXIT_FAILURE);
@}
status = header_get_value (hdr, MU_HEADER_FROM, from,
sizeof (from), NULL);
if (status != 0)
strcpy (from, "(NO FROM)");
status = header_get_value (hdr, MU_HEADER_SUBJECT, subject,
sizeof (subject), NULL);
if (status != 0)
strcpy (subject, "(NO SUBJECT)");
printf ("%s\t%s\n", from, subject);
@}
mailbox_close (mbox);
mailbox_destroy (&mbox);
return 0;
@}
@example
@code{/* Prefix @emph{smtp_} is reserved */}
@code{#include <mailutils/smtp.h>}
@end example
Simple Mail Transfer Protocol. Not implemented.
@subsection Commands
@cindex smtp_t
@subsubsection Initialisation
@cindex SMTP Initialisation
@deftypefun int smtp_create (smtp_t *)
@end deftypefun
@deftypefun void smtp_destroy (smtp_t *)
@end deftypefun
@deftypefun int smtp_open (smtp_t, const char *@var{host}, unsigned int @var{port}, int @var{flags})
@end deftypefun
@subsubsection Data
@cindex SMTP Data
@deftypefun int smtp_data (smtp_t, stream_t @var{stream})
@end deftypefun
@subsubsection Helo
@cindex SMTP Helo
@deftypefun int smtp_helo (smtp_t, const char *@var{domain})
@end deftypefun
@deftypefun int smtp_ehlo (smtp_t, const char *@var{domain})
@end deftypefun
@subsubsection Expn
@cindex SMTP Expn
@deftypefun int smtp_expn (smtp_t, const char *@var{list}, iterator_t *)
@end deftypefun
@subsubsection Help
@cindex SMTP Help
@deftypefun int smtp_help (smtp_t, const char *@var{help}, iterator_t *)
@end deftypefun
@subsubsection Mail From
@cindex SMTP Mail From
@deftypefun int smtp_mail_from (smtp_t, const char *@var{address}, const char *@var{param})
@end deftypefun
@subsubsection Noop
@cindex SMTP Noop
@deftypefun int smtp_noop (smtp_t)
@end deftypefun
@subsubsection Quit
@cindex SMTP Quit
@deftypefun int smtp_quit (smtp_t)
@end deftypefun
@subsubsection Recpt To
@cindex SMTP Recpt To
@deftypefun int smtp_rcpt_to (smtp_t, const char *@var{address}, const char *@var{param})
@end deftypefun
@subsubsection Reset
@cindex SMTP Reset
@deftypefun int smtp_reset (smtp_t)
@end deftypefun
@subsubsection Verify
@cindex SMTP Verify
@deftypefun int smtp_verify (smtp_t, const char *@var{user})
@end deftypefun
@subsubsection Help functions
@cindex SMTP Help functions
@deftypefun extern int smtp_readline (smtp_t, char *@var{buffer}, size_t @var{len}, size_t *@var{len})
@end deftypefun
@deftypefun extern int smtp_response (smtp_t, char *@var{buffer}, size_t @var{len}, size_t *@var{len})
@end deftypefun
@deftypefun extern int smtp_writeline (smtp_t, const char *@var{format}, @var{...})
@end deftypefun
@deftypefun extern int smtp_sendline (smtp_t, const char *@var{line})
@end deftypefun
@deftypefun extern int smtp_send (smtp_t
@end deftypefun
@code{#include <mailutils/stream.h>}
@deftypefun int stream_create (stream_t *@var{pstream}, int @var{flags}, void *@var{owner})
@table @code
@item MU_STREAM_READ
@findex MU_STREAM_READ
The stream is open read only.
@item MU_STREAM_WRITE
@findex MU_STREAM_WRITE
The stream is open write only.
@item MU_STREAM_RDWR
@findex MU_STREAM_RDWR
The stream is open read and write.
@item MU_STREAM_APPEND
@findex MU_STREAM_APPEND
The stream is open in append mode for writing.
@item MU_STREAM_CREAT
@findex MU_STREAM_CREAT
The stream is created.
@item MU_STREAM_NONBLOCK
@findex MU_STREAM_NONBLOCK
The stream is set non blocking.
@item MU_STREAM_NO_CHECK
@findex MU_STREAM_NO_CHECK
Stream is destroyed without checking for the owner.
@end table
@end deftypefun
@deftypefun void stream_destroy (stream_t *@var{pstream}, void *@var{owner})
@end deftypefun
@deftypefun int stream_open (stream_t @var{stream}, const char *@var{name}, int@var{port}, int @var{flag})
@end deftypefun
@deftypefun int stream_close (stream_t @var{stream})
@end deftypefun
@deftypefun int stream_get_fd (stream_t @var{stream}, int *@var{pfd})
@end deftypefun
@deftypefun int stream_read (stream_t @var{stream}, char *@var{buffer}, size_t @var{buflen}, off_t @var{offset}, size_t *@var{pwriten})
@end deftypefun
@deftypefun int stream_readline (stream_t @var{stream}, char *@var{buffer}, size_t @var{buflen}, off_t @var{offset}, size_t *@var{pwriten})
@end deftypefun
@deftypefun int stream_size (stream_t @var{stream}, off_t *@var{psize})
@end deftypefun
@deftypefun int stream_truncate (stream_t @var{stream}, off_t @var{size})
@end deftypefun
@deftypefun int stream_write (stream_t @var{stream}, const char *@var{buffer}, size_t @var{buflen}, off_t @var{offset}, size_t *@var{pwriten})
@end deftypefun
@deftypefun int stream_flush (stream_t @var{stream})
@end deftypefun
@deftypefun int stream_get_flags (stream_t @var{stream}, int *@var{pflags})
@end deftypefun
@deftypefun int stream_get_state (stream_t @var{stream}, int *@var{pstate})
@table @code
@item MU_STREAM_STATE_OPEN
Last action was @code{stream_open}.
@item MU_STREAM_STATE_READ
Last action was @code{stream_read} or @code{stream_readline}.
@item MU_STREAM_STATE_WRITE
Last action was @code{stream_write}.
@item MU_STREAM_STATE_CLOSE
Last action was @code{stream_close}.
@end table
@end deftypefun
@deftypefun int file_stream_create (stream_t *@var{pstream})
@end deftypefun
@deftypefun int mapfile_stream_create (stream_t *@var{pstream})
@end deftypefun
@deftypefun int encoder_stream_create (stream_t *@var{pstream}, stream_t @var{iostream}, const char *@var{encoding})
@end deftypefun
@deftypefun int decoder_stream_create (stream_t *@var{pstream}, stream_t @var{iostream}, const char *@var{encoding})
@end deftypefun
@deftypefun int tcp_stream_create (stream_t *@var{pstream})
@end deftypefun
An example using @code{tcp_stream_create} to make a simple web client:
@example
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <mailutils/io.h>
const char *wbuf = "GET / HTTP/1.0\r\n\r\n";
char rbuf[1024];
int
main(int argc, char **argv)
@{
int ret, off = 0, fd;
stream_t stream;
size_t nb;
fd_set fds;
argc = argc, argv = argv;
ret = tcp_stream_create (&stream);
if (ret != 0)
@{
fprintf (stderr, "tcp_stream_create: %s\n",
mailutils_error(ret));
exit (EXIT_FAILURE);
@}
connect_again:
ret = stream_open (stream, "www.netscape.com", 80,
MU_STREAM_NONBLOCK);
if (ret != 0)
@{
if (ret == MU_ERROR_EAGAIN)
@{
ret = stream_get_fd(stream, &fd);
if (ret != 0)
@{
fprintf (stderr, "stream_get_fd: %s\n",
mailutils_error(ret));
exit (EXIT_FAILURE);
@}
FD_ZERO (&fds);
FD_SET (fd, &fds);
select (fd+1, NULL, &fds, NULL, NULL);
goto connect_again;
@}
fprintf (stderr, "stream_open: %s\n", mailutils_error (ret));
exit (EXIT_FAILURE);
@}
ret = stream_get_fd (stream, &fd);
if (ret != 0)
@{
fprintf(stderr, "stream_get_fd: %s\n", strerror(ret));
exit (EXIT_FAILURE);
@}
write_again:
ret = stream_write (stream, wbuf + off, strlen (wbuf), 0, &nb);
if (ret != 0 )
@{
if (ret == EAGAIN)
@{
FD_ZERO (&fds);
FD_SET (fd, &fds);
select (fd + 1, NULL, &fds, NULL, NULL);
off += nb;
goto write_again;
@}
fprintf (stderr, "stream_write: %s\n", strerror(ret));
exit (EXIT_FAILURE)
@}
if (nb != strlen (wbuf))
@{
fprintf(stderr, "stream_write: %s\n", "nb != wbuf length");
exit (EXIT_FAILURE);
@}
do
@{
read_again:
ret = stream_read (stream, rbuf, sizeof (rbuf), 0, &nb);
if (ret != 0)
@{
if (ret == EAGAIN)
@{
FD_ZERO (&fds);
FD_SET (fd, &fds);
select (fd + 1, &fds, NULL, NULL, NULL);
goto read_again;
@}
fprintf (stderr, "stream_read: %s\n", strerror(ret));
exit(EXIT_FAILURE);
@}
write (2, rbuf, nb);
@} while (nb);
ret = stream_close (stream);
if (ret!= 0)
@{
fprintf (stderr, "stream_close: %s\n", strerror(ret));
exit (EXIT_FAILURE);
@}
stream_destroy (&stream, NULL);
exit (EXIT_SUCCESS);
@}
@end example
@comment See rfc2368, rfc2369, rfc2384
A mailbox or a mailer can be described in a URL, the string will contain the
necessary information to initialize @code{mailbox_t}, or @code{mailer_t}
properly.
@subsection POP3
The POP URL scheme contains a POP server, optional port number
and the authentication mechanism. The general form is
@example
@url{pop://[<user>[;AUTH=<auth>]@@]<host>[:<port>]}
or
@url{pop://[<user>[:<passwd>]@@]<host>[:<port>]}
@end example
If @emph{:port} is omitted the default value is 110. Different forms of
authentication can be specified with @emph{;AUTH=type}.
The special string @emph{;AUTH=*} indicates that the client will use
a default scheme base on the capability of the server.
@example
@url{pop://obelix@@gaulois.org}
@url{pop://asterix;AUTH=*@@france.com}
@url{pop://falbala;AUTH=+APOP@@france.com}
@url{pop://obelix;AUTH=+APOP@@village.gaulois.org:2000}
@url{pop://obelix:menhir@@village.gaulois.org:2000}
@end example
For more complete information see @cite{rfc2368}.
@subsection IMAP
The IMAP URL scheme contains an IMAP server, optional port number
and the authentication mechanism. The general form is
@example
@url{imap://[<user>[;AUTH=<type>]]@@<host>[:port][/<mailbox>]}
or
@url{imap://[<user>[:<passwd>]]@@<host>[:port][/<mailbox>]}
@end example
If @emph{:port} is omitted the default value is 220. Different forms of
authentication can be specified with @emph{;AUTH=type}.
The special string @emph{;AUTH=*} indicates that the client will use
a default scheme base on the capability of the server.
@example
@url{imap://obelix@@imap.gaulois.org}
@url{imap://asterix;AUTH=*@@imap.france.com}
@url{imap://asterix:potion@@imap.france.com}
@end example
For more complete information see @cite{rfc2192}.
@subsection File
Local folder should be handle by this URL. It is preferable to let
the mailbox recognize the type of mailbox and take the appropriate
action.
@example
@url{file://path}
@url{file://var/mail/user}
@url{file://home/obelix/Mail}
@end example
For MMDF, MH local mailboxes URLs are provided, but it is preferable to
use @url{file://path} and let the library figure out which one.
@example
@url{mmdf://path}
@url{mh://path}
@end example
@subsection Mailto
After setting a mailer, @url{mailto:} is used to tell the mailer where
and to whom the message is for.
@example
@url{mailto://hostname}
@end example
Mailto can be used to generate short messages, for example to subscribe
to mailing lists.
@example
@url{mailto://bug-mailutils@@gnu.org?body=subscribe}
@url{mailto://bug-mailutils@@gnu.org?Subject=hello&body=subscribe}
@end example
For more complete information see @cite{rfc2368}.
@subsection URL functions
Helper functions are provided to retrieve and set the @emph{URL} fields.
@deftypefun int url_create (url_t *@var{url}, const char *@var{name})
Create and the @var{url} data structure, but do not parse it.
@end deftypefun
@deftypefun void url_destroy (url_t *)
Destroy the url and free it's resources.
@end deftypefun
@deftypefun int url_parse (url_t @var{url})
Parses the url, after calling this the get functions can be called.
The syntax, condensed from RFC 1738, and extended with the ;auth=
of RFC 2384 (for POP) and RFC 2192 (for IMAP) is:
@example
url =
scheme ":" = "//"
[ user [ ( ":" password ) | ( ";auth=" auth ) ] "@" ]
host [ ":" port ]
[ ( "/" urlpath ) | ( "?" query ) ]
@end example
This is a generalized URL syntax, and may not be exactly appropriate
for any particular scheme.
@end deftypefun
@deftypefun const char* url_to_string (const url_t @var{url})
@end deftypefun
@deftypefun int url_get_scheme (const url_t @var{url}, char *@var{schem}, size_t @var{len}, size_t *@var{n})
@end deftypefun
@deftypefun int url_get_user (const url_t @var{url}, char *@var{usr}, size_t @var{len}, size_t *@var{n})
@end deftypefun
@deftypefun int url_get_passwd (const url_t @var{url}, char *@var{passwd}, size_t @var{len}, size_t *@var{n})
@end deftypefun
@deftypefun int url_get_host (const url_t @var{url}, char *@var{host}, size_t @var{len}, size_t *@var{n})
@end deftypefun
@deftypefun int url_get_port (const url_t @var{url}, long *@var{port})
@end deftypefun
@deftypefun int url_get_path (const url_t @var{url}, char *@var{path}, size_t @var{len}, size_t *@var{n})
@end deftypefun
@deftypefun int url_get_query (const url_t @var{url}, char *@var{query}, size_t{len}, size_t *@var{n})
@end deftypefun
@deftypefun char* url_decode (const char* s)
Decodes an RFC 1738 % encoded string, returning the decoded string in
allocated memory. If the string is not encoded, this degenerates to
a strdup().
@end deftypefun
@section Example
@example
@include ex-url.texi
@end example