@c =================================================================== @c
@c    serrano/prgm/project/bigloo/manuals/mail.texi                    @c
@c    ------------------------------------------------------------     @c
@c    Author      :  Manuel Serrano                                    @c
@c    Creation    :  Wed Dec 17 16:39:34 2008                          @c
@c    Last change :                                                    @c
@c    Copyright   :  2008 Manuel Serrano                               @c
@c    ------------------------------------------------------------     @c
@c    Mail programming                                                 @c
@c =================================================================== @c

@c ------------------------------------------------------------------- @c
@c    Mail ...                                                         @c
@c ------------------------------------------------------------------- @c
@node Mail, Text, Multimedia, Top
@comment  node-name,  next,  previous,  up
@chapter Mail
@cindex mail
@cindex mime

Bigloo provides various facilities for handling mails. It provides
facilities for parsing many formats commonly used in composing mails
(quoted printable, vcard, mime types). It also provides facilities for
dealing with mail servers. For that it proposes an abstracted view of
mail servers with two implementations: @code{imap} and @code{maildir}.

@menu
* RFC 2045:: MIME Part one.
* RFC 2047:: MIME, Part three.
* RFC 2426:: vcard.
* RFC 2822:: Internet Message Format
* Mail servers:: @code{imap} and @code{maildir}
@end menu

@c ------------------------------------------------------------------- @c
@c    RFC 2045 ...                                                     @c
@c ------------------------------------------------------------------- @c
@node RFC 2045, RFC 2047, , Mail
@comment  node-name,  next,  previous, up
@section RFC 2045 -- MIME, Part one
@cindex RFC 2045
@cindex quoted-printable
@cindex mime-multipart
@cindex mime-content-type
@cindex mime-content-disposition

This section described the functions offered by Bigloo to encode
and decode some of the formats specified in the RFC 2045
@url{http://tools.ietf.org/html/rfc2045}.

@deffn {bigloo mail procedure} quoted-printable-encode string
@deffnx {bigloo mail procedure} quoted-printable-decode string
These functions encode/decode a string into and from the 
@code{quoted-printable} format.

Examples:

@smalllisp
(quoted-printable-encode "foo bar") @result{} "foobar=20"
(quoted-printable-decode "foobar=20") @result{} "foo bar"
@end smalllisp
@end deffn


@deffn {bigloo mail procedure} quoted-printable-encode-port ip op
@deffnx {bigloo mail procedure} quoted-printable-decode-port ip op [rfc2047]
These functions are similar to @code{quoted-printable-encode} and 
@code{quoted-printable-decode} except that they operate on
@code{input-port}s and @code{output-port}s. 

The function @code{quoted-printable-decode-port} accepts an optional
argument: @var{rfc2047}. If this argument is @code{#t}, then the parsing
stops on the prefix @code{?=}, which is a marker in the mail subject
as specified by the RFC 2047, (see @url{http://tools.ietf.org/html/rfc2047})
is found.
@end deffn

@deffn {bigloo mail procedure} mime-content-decode string 
@deffnx {bigloo mail procedure} mime-content-decode-port input-port
These two functions parse respectively a @code{string} and an 
@code{input-port} and return a list of three elements:

@itemize @bullet
@item a content type,
@item a content subtype,
@item options.
@end itemize

Example:

@smalllisp
(mime-content-type-decode "text/plain; boundary=Apple-Mail-11") 
  @result{} (text plain ((boundary . Apple-Mail-11)))
@end smalllisp

@end deffn

@deffn {bigloo mail procedure} mime-content-disposition-decode string
@deffnx {bigloo mail procedure} mime-content-disposition-decode-port input-port
These two functions parse respectively a @code{string} and an 
@code{input-port} and return a list describing the content disposition.

Example:

@smalllisp
(mime-content-disposition-decode "attachment; filename=\"smine.p7s\"")
  @result{} (attachment ((filename . smine.p7s)))
@end smalllisp
@end deffn

@deffn {bigloo mail procedure} mime-multipart-decode string boundary [recursive]
@deffnx {bigloo mail procedure} mime-multipart-decode-port input-port boundary [recursive]
These two functions parse respectively a @code{string} and an 
@code{input-port} and return a list of mime sections.

If the optional argument @var{recursive} controls whether subparts of
a multipart section must be decoded are not. If the @var{recursive} is 
@code{#t} then all subparts of the multipart content are decoded. The result
is a fully decoded multipart section. If @var{recursive} is @code{#f} subparts
are not decoded and included in the result as plain strings.
@end deffn

@c ------------------------------------------------------------------- @c
@c    RFC 2047 ...                                                     @c
@c ------------------------------------------------------------------- @c
@node RFC 2047, RFC 2426, RFC 2045, Mail
@comment  node-name,  next,  previous, up
@section RFC 2047 -- MIME, Part three
@cindex RFC 2426

This section described the function offered by Bigloo to decode
the RFC 2047 encoding used in mail headers 
(see @url{http://tools.ietf.org/html/rfc2047}).

@deffn {bigloo mail procedure} rfc2047-decode-port ip op [:charset iso-latin-1]
@deffnx {bigloo mail procedure} rfc2047-decode string [:charset iso-latin-1]

These functions decode mail header fields encoded using the RFC 2047 
specification. The optional argument @var{charset} specified in which charset
the result should be encoded. The allowed values are:

@itemize @bullet
@item @code{utf-8}
@item @code{iso-latin-1}
@item @code{cp-1252}
@end itemize

Example:

@smalllisp
(map char->integer
  (string->list (rfc2047-decode "Poste =?ISO-8859-1?Q?t=E9l=E9phonique?=")))
  @result{} (80 111 115 116 101 32 116 233 108 233 112 104 111 110 105 113 117 101)
(string-for-read (rfc2047-decode "Poste =?ISO-8859-1?Q?t=E9l=E9phonique?=" :charset 'utf8))
  @result{} "Poste t\303\251l\303\251phonique"
@end smalllisp
@end deffn

@c ------------------------------------------------------------------- @c
@c    RFC 2426 ...                                                     @c
@c ------------------------------------------------------------------- @c
@node RFC 2426, RFC 2822, RFC 2047, Mail
@comment  node-name,  next,  previous, up
@section RFC 2426 -- MIME, Part three
@cindex RFC 2426
@cindex VCARD

This section presents the facilities supported by Bigloo for dealing
with @code{vcard}s.

@deffn {bigloo mail class} vcard
@smalllisp
(class vcard
  (version::bstring (default "2.1"))
  (uid (default #f))
  (fn (default #f))
  (familyname (default #f))
  (firstname (default #f))
  (nickname (default #f))
  (photo (default #f))
  (sound (default #f))
  (url (default #f))
  (org (default #f))
  (emails::pair-nil (default '()))
  (phones::pair-nil (default '()))
  (birthday (default #f))
  (addresses::pair-nil (default '()))
  (lang (default #f))
  (related (default #f))
  (key (default #f))
  (notes::pair-nil (default '()))
  (x-thumbnail (default #f))
  (x-color (default #f))
  (xx-extras::pair-nil (default '())))
@end smalllisp

The class @code{vard} is used to reify in memory a vcard as parsed by
the functions @code{port->vcard}, @code{read-vcard}, and @code{string->vcard}.

Except @code{emails}, @code{phones}, and @code{addresses}, all fields
are optional. They should be either @code{#f} or a string. Field meanings
are given by the RFC 2426 specification, apart the @code{x-thumbnail},
@code{x-color}, and @code{xx-extras} that are Bigloo specific.

@itemize @bullet
@item @code{photo} is a flat list of strings.
@item @code{x-thumbnail} an optional thumbnail image.
@item @code{x-color} an optional color.
@item @code{xx-extras} a list of non standard properties.
@item @code{phones} is an alist whose elements are pairs of two strings.
@item @code{addresses} is a list composed of:
  @itemize @bullet
  @item the postoffice, a string, 
  @item a list of strings denoting the street address,
  @item a string denoting the city,
  @item a string denoting the region,
  @item a string denoting the zip code,
  @item a string denoting the zip country.
@end itemize

All street values are required and must be provided. The empty string
should be used to denote empty values.
@end itemize
@end deffn

@deffn {bigloo mail function} read-vcard::vcard ip [:charset-encoder]
@deffnx {bigloo mail function} port->vcard::vcard ip [:charset-encoder]
@deffnx {bigloo mail function} string->vcard::vcard str [:charset-encoder]
These three functions parse a @emph{vcard} to produce a @code{vcard}
instance.  The optional argument @var{charset-encoder}, when provided,
must be a function of argument: a string to be decoded. Vcard strings
are UTF-8 encoded. The @var{charset-encoder} can be used to encode
on-the-fly the strings found in the vcard in a difference encoding.

@code{port->vcard} is similar to @code{read-vcard} but it returns
@code{#f} on end-of-file, while @code{read-vcard} returns the
eof-object.
@end deffn


@c ------------------------------------------------------------------- @c
@c    RFC 2822 ...                                                     @c
@c ------------------------------------------------------------------- @c
@node RFC 2822, Mail servers, RFC 2426, Mail
@comment  node-name,  next,  previous, up
@section RFC 2822 -- Internet Message Format
@cindex RFC 2822

This section described the functions offered by Bigloo to encode
and decode some of the formats specified in the RFC 2822
(@url{http://tools.ietf.org/html/rfc2045}). It mainly supports functions
for parsing email headers and for decoding email addresses.

@deffn {bigloo mail procedure} mail-header->list obj
The function @code{mail-header->list} parses a mail header that can either
be implemented as a string or an input port. It returns a list of fields.

Example:

@smalllisp
(mail-header->list "Return-Path: <foo.bar@@inria.fr>
Received: from eurus.inria.fr ([unix socket])")
  @result{}
  ((return-path . "<foo.bar@@inria.fr>") (received . "from eurus.inria.fr ([unix socket])"))
@end smalllisp
@end deffn

@deffn {bigloo mail procedure} email-normalize string

The function @code{email-normalize} extracts the actual email address
from an email representation.

Example:
@smalllisp
(email-normalize "foo bar <foo.bar@@inria.fr>") @result{} "foo.bar@@inria.fr"
@end smalllisp

@end deffn

@deffn {bigloo mail procedure} rfc2822-address-display-name string
Extract the name component of an email.

Example:
@smalllisp
(rfc2822-address-display-name "Foo Bar <foo.bar@@inria.fr>") @result{} "Foo Bar"
(rfc2822-address-display-name "<foo.bar@@inria.fr>") @result{} "foo bar"
@end smalllisp

@end deffn

@c ------------------------------------------------------------------- @c
@c    Mail servers ...                                                 @c
@c ------------------------------------------------------------------- @c
@node Mail servers, , RFC 2822, Mail
@comment  node-name,  next,  previous, up
@section Mail servers -- imap and maildir
@cindex imap 
@cindex maildir
@cindex RFC 3501

Bigloo implements the @code{imap} protocol
(@url{http://tools.ietf.org/html/rfc3501}) and the @code{maildir}
format. This section presents the API for manipulating them both.

@menu
* mailbox:: main API for dealing with messages and folders.
* imap:: implementation of the RFC 3501 protocol.
* maildir:: implementation of the mail file system format.
@end menu

@c -- mailbox -------------------------------------------------------- @c
@node mailbox, , imap, Mail servers
@subsection Mailboxes

@deffn {bigloo mail class} mailbox
@smalllisp
(abstract-class mailbox
  (label::bstring (default "")))
@end smalllisp

The abstract class @code{mailbox} is the common ancestors to all the
mailbox implementations. It allows the definitions of various generic
functions that deal with mail messages and mail folders.
@end deffn

@deffn {bigloo mail class} &mailbox-error
@smalllisp
(abstract-class &mailbox-error::&error)
@end smalllisp

The @code{&mailbox-error} is the super class of all the errors that
can be raised when accessing mail servers, except the parsing errors
that inherit from the @code{&parse-error} super class.
@end deffn


@deffn {bigloo mail procedure} mailbox-close mailbox
Close the mailbox connection.

Example:
@smalllisp
(let ((mbox (if (network-up?)
                (instantiate::imap (socket ...))
                (instantiate::maildir (path my-local-cache)))))
   (mailbox-close mbox))
@end smalllisp

@end deffn

@deffn {bigloo mail procedure} mailbox-separator mailbox
Returns a string denoting the separator (commonly @code{"} or @code{.})
used by the @var{mailbox}.
@end deffn

@deffn {bigloo mail procedure} mailbox-prefix mailbox
Returns the prefix of the @var{mailbox}, a string or @code{#f}.
@end deffn

@deffn {bigloo mail procedure} mailbox-hostname mailbox
Returns the hostname of the @var{mailbox}, a string or @code{#f}.
@end deffn

@deffn {bigloo mail procedure} mailbox-folders mailbox
Returns a list of strings denoting the folder names of the @var{mailbox}.
@end deffn

@deffn {bigloo mail procedure} mailbox-folder-select! mailbox string
Selects one folder of the @var{mailbox}. This function is central to 
mailboxes because all messages are referenced relatively to the 
folder selection. All the functions that operates on @code{uid} 
implicitly access the current folder selection.
@end deffn

@deffn {bigloo mail procedure} mailbox-folder-unselect! mailbox
Unselects the @var{mailbox} current selected folder.
@end deffn

@deffn {bigloo mail procedure} mailbox-folder-create! mailbox folder
Creates a new @var{folder} denotes by a fully qualified name.

Example
@smalllisp
(mailbox-create! mbox "INBOX.scheme.bigloo")
@end smalllisp
@end deffn

@deffn {bigloo mail procedure} mailbox-folder-delete! mailbox folder
Deletes an empty @var{folder}.
@end deffn

@deffn {bigloo mail procedure} mailbox-folder-rename! mailbox old new
Renames a folder.
@end deffn

@deffn {bigloo mail procedure} mailbox-folder-move! mailbox folder dest
Moves the @var{folder} into the destination folder @var{dest}.
@end deffn

@deffn {bigloo mail procedure} mailbox-subscribe! mailbox folder
@deffnx {bigloo mail procedure} mailbox-unsubscribe! mailbox folder
Subscribe/unsubscribe to a folder. This allows @code{imap} servers not
to present the entire list of folders. Only subscribed folders are returned
by @code{mailbox-folders}. These functions have no effect on @code{maildir}
servers.
@end deffn

@deffn {bigloo mail procedure} mailbox-folder-exists? mailbox folder
Returns @code{#t} if and only if @var{folder} exists in @var{mailbox}. Returns
@code{#f} otherwise.
@end deffn

@deffn {bigloo mail procedure} mailbox-folder-status mailbox folder
Returns the status of the @var{folder}. A status is an alist made of
the number of unseen mail, the uid validity information, the uid next
value, the number of recent messages, and the overall number of messages.
@end deffn

@deffn {bigloo mail procedure} mailbox-folder-uids mailbox
Returns the list of UIDs (a list of integers) of the messages contained
in the currently selected folder.
@end deffn

@deffn {bigloo mail procedure} mailbox-folder-dates mailbox
Returns the list of dates of the messages contained
in the currently selected folder.
@end deffn

@deffn {bigloo mail procedure} mailbox-folder-delete-messages! mailbox
Deletes the messages marked as @emph{deleted} of the currently selected
folder.
@end deffn

@deffn {bigloo mail procedure} mailbox-folder-header-fields mailbox field
Returns the list of headers @var{fields} of the message of the current
folder.
@end deffn

@deffn {bigloo mail procedure} mailbox-message mailbox uid
Returns the message @var{uid} in the current folder.
@end deffn

@deffn {bigloo mail procedure} mailbox-message-path mailbox uid
Returns the full path name of the message @var{uid}.
@end deffn

@deffn {bigloo mail procedure} mailbox-message-body mailbox uid [len]
Returns the body of the message @var{uid}. If @var{len} is provided, only
returns the first @var{len} characters of the body.
@end deffn

@deffn {bigloo mail procedure} mailbox-message-header mailbox uid
Returns the header as a string of the message @var{uid}.
@end deffn

@deffn {bigloo mail procedure} mailbox-message-header-list mailbox uid
Returns the header as an alist of the message @var{uid}.
@end deffn

@deffn {bigloo mail procedure} mailbox-message-header-field mailbox uid field
Extracts one field from the message header.
@end deffn

@deffn {bigloo mail procedure} mailbox-message-size mailbox uid
Returns the size of the message.
@end deffn

@deffn {bigloo mail procedure} mailbox-message-info mailbox uid
Returns the information relative to the message @var{uid}. This a list
containing the message identifier, its uid, the message date, the message
size, and the message flags.
@end deffn

@deffn {bigloo mail procedure} mailbox-message-flags mailbox uid
@deffnx {bigloo mail procedure} mailbox-message-flags-set! mailbox uid lst
Sets/Gets the flags of the message @var{uid}. This is a list of strings.
Typical flags are: 

@itemize @bullet
@item @code{\Flagged}
@item @code{\Answered}
@item @code{\Deleted}
@item @code{\Seen}
@end itemize
@end deffn

@deffn {bigloo mail procedure} mailbox-message-delete! mailbox uid
Deletes the message @var{uid}.
@end deffn

@deffn {bigloo mail procedure} mailbox-message-move! mailbox uid folder
Moves the message @var{uid} into the new @var{folder} (denoted by 
a string).
@end deffn

@deffn {bigloo mail procedure} mailbox-message-create! mailbox folder content
Creates a new message in the @var{folder} whose content is given the
string @var{content}.
@end deffn


@c -- imap ----------------------------------------------------------- @c
@node imap, mailbox, maildir, Mail servers
@subsection IMAP (RFC 3501)

@deffn {bigloo mail class} imap
@smalllisp
(class imap::mailbox
  (socket::socket read-only))

(define mbox
  (instantiate::maildir
    (label "My Remote Mailbox")
    (socket (imap-login (make-client-socket "imap.inria.fr" 993)
                        "serrano" "XXX"))))
@end smalllisp
@end deffn

@deffn {bigloo mail class} &imap-parse-error
@smalllisp
(class &imap-parse-error::&io-parse-error)
@end smalllisp
@end deffn

@deffn {bigloo mail class} &imap-error
@smalllisp
(class &imap-error::&mailbox-error)
@end smalllisp
@end deffn

@deffn {bigloo mail procedure} imap-login socket user password
Log a user into an imap server. The @var{socket} must have been created
first. The argument @var{user} is a string and denotes the user name.
The argument @var{password} is a string too and it contains the user
password. This function returns as value the @var{socket} it has received.
If the operation fails the function raises a @code{&imap-error}
exception.

Example:

@smalllisp
(define mbox
   (imap-login (make-client-socket "imap.inria.fr" 993 :timeout 200000) 
               "serrano" "XXX"))

(print (mailbox-folders mbox))
@end smalllisp
@end deffn

@deffn {bigloo mail procedure} imap-logout socket
Closes an @code{imap} connection.
@end deffn

@deffn {bigloo mail procedure} imap-capability socket
Returns the list of capabilities supported the @code{imap} server.
@end deffn



@c -- maildir -------------------------------------------------------- @c
@node maildir, imap,  , Mail servers
@subsection Maildir

@deffn {bigloo mail class} maildir
@smalllisp
(class maildir::mailbox
  (prefix::bstring read-only (default "INBOX"))
  (path::bstring read-only))
@end smalllisp

Example:

@smalllisp
(define mbox
  (instantiate::maildir
    (label "My Mailbox")
    (path (make-file-name (getenv "HOME") ".maildir"))))

(tprint (mailbox-folders mbox))
@end smalllisp
@end deffn

@deffn {bigloo mail class} &maildir-error
@smalllisp
(class &maildir-error::&mailbox-error)
@end smalllisp
@end deffn


