=head1 NAME

Mail::IMAPClient - An IMAP Client API

=head1 INHERITANCE

=head1 DESCRIPTION

This module provides methods implementing the IMAP protocol. It allows
perl scripts to interact with IMAP message stores.

The module is used by constructing or instantiating a new IMAPClient
object via the L<new> constructor method. Once the object has been
instantiated, the L<connect> method is either implicitly or explicitly
called. At that point methods are available that implement the IMAP
client commands as specified in I<RFC2060>. When processing is
complete, the I<logoff> object method should be called.

This documentation is not meant to be a replacement for RFC2060, and
the wily programmer will have a copy of that document handy when coding
IMAP clients. 

Note that this documentation uses the term I<folder> in place of
RFC2060's use of I<mailbox>. This documentation reserves the use of the
term I<mailbox> to refer to the set of folders owned by a specific IMAP
id.

RFC2060 defines four possible states for an IMAP connection: not
authenticated, authenticated, selected, and logged out. These
correspond to the B<IMAPClient> constants C<Connected>,
C<Authenticated>, C<Selected>, and C<Unconnected>, respectively. These
constants are implemented as class methods, and can be used in
conjunction with the L<Status> method to determine the status of an
B<IMAPClient> object and its underlying IMAP session. Note that an
B<IMAPClient> object can be in the C<Unconnected> state both before a
server connection is made and after it has ended. This differs slightly
from RFC2060, which does not define a pre-connection status. For a
discussion of the methods available for examining the B<IMAPClient>
object's status, see the section labeled L<"Status Methods">, below.

=head2 Advanced Authentication Mechanisms

RFC2060 defines two commands for authenticating to an IMAP server:
LOGIN for plain text authentication and AUTHENTICATE for more secure
authentication mechanisms. Currently Mail::IMAPClient supports
DIGEST-MD5, CRAM-MD5, LOGIN, PLAIN (SASL), and NTLM authentication.

There are also a number of methods and parameters that you can use to
build your own authentication mechanism. Since this topic is a source of
many questions, I will provide a quick overview here. All of the methods
and parameters discussed here are described in more detail elsewhere in
this document; this section is meant to help you get started.

First of all, if you just want to do plain text authentication and
your server is okay with that idea then you don't even need to read
this section.

Second of all, the intent of this section is to help you implement the
authentication mechanism of your choice, but you will have to understand
how that mechanism works.  There are I<lots> of authentication mechanisms
and most of them are not available to me to test with for one reason or
another. Even if this section does not answer all of your authentication
questions it I<does> contain all the answers that I have, which I admit
are scant.

Third of all, if you manage to get any advanced authentication mechanisms
to work then please consider donating them to this module. I don't quite
have a framework visualized for how different authentication mechanisms
could "plug in" to this module but I would like to eventually see this
module distributed with a number of helper modules to implement various
authentication schemes.

The B<Mail::IMAPClient>'s support for add-on authentication mechanisms is
pretty straight forward and is built upon several assumptions. Basically
you create a callback to be used to provide the response to the server's
challenge. The I<Authcallback> parameter contains a reference to the
callback, which  can be an anonymous subroutine or a named subroutine.
Then, you identify your authentication mechanism, either via the
I<Authmechanism> parameter or as an argument to L<authenticate>.

You may also need to provide a subroutine to encrypt (or whatever) data
before it is sent to the server. The I<Prewritemethod> parameter must
contain a reference to this subroutine.  And, you will need to decrypt
data from the server; a reference to the subroutine that does this must
be stored in the I<Readmethod> parameter.

This framework is based on the assumptions that a) the mechanism you are
using requires a challenge-response exchange, and b) the mechanism does
not fundamentally alter the exchange between client and server but merely
wraps the exchange in a layer of encryption. It particularly assumes
that the line-oriented nature of the IMAP conversation is preserved;
authentication mechanisms that break up messages into blocks of a
predetermined size may still be possible but will certainly be more
difficult to implement.

Alternatively, if you have access to B<imtest>, a utility included in
the Cyrus IMAP distribution, you can use that utility to broker your
communications with the IMAP server.  This is quite easy to implement. An
example, L<examples/imtestExample.pl>, can be found in the C<examples>
subdirectory of the source distribution.

The following list summarizes the methods and parameters that you may
find useful in implementing advanced autentication:

=over 4

=item authenticate method

This method implements the AUTHENTICATE IMAP client command as documented
in RFC2060.  If you have set the I<Authmechanism> parameter then the
L<login> method will call L<authenticate> instead of doing a clear text
login, which is its normal behavior.  If you don't want B<login> to call
B<authenticate> on your behalf then you can call it yourself. Instead
of setting an I<Authmechanism> you can just pass the authmechanism as
the first argument to AUTHENTICATE.

=item Socket and RawSocket Parameters

Both parameters hold a reference to the socket connection.  Normally this
is set for you by the L<connect> method, but if you are implementing
an advanced authentication technique you may choose to set up your own
socket connection and then set this parameter manually, bypassing the
B<connect> method completely.  This is also useful if you want to use
L<IO::Socket::INET> alternatives, like L<IO::Socket::SSL>.

The I<RawSocket> parameter simply records the socket to use for future
operations, without attempting any interaction on it. In this case, you
have to be sure to handle all the preliminar operations and to manually
set the B<Mail::IMAPClient> object in sync with its actual status with
respect to this socket (see below for additional parameters regarding
this, especially the I<State> parameter).

The I<Socket> parameter, instead, also attempts to carry on preliminar
phases if the conditions apply. If both parameters are present, this
takes the precedence over I<RawSocket>. It is primarily used to
provide an alternative socket for communications, e.g. to use
L<IO::Socket::SSL> instead of L<IO::Socket::INET> used by L<connect>
by default.

B<PLEASE NOTE>
As of version 2.99_04 of this module, the I<Socket> parameter has
changed semantics to make it more "DWIM". The I<RawSocket> parameter was
introduced as a replacement for the I<Socket> parameter in older version.

=item State, Server, Proxy, Password, and User Parameters

If you need to make your own connection to the server and perform your
authentication manually, then you can set these parameters to keep your
B<Mail::IMAPClient> object in sync with its actual status. Of these,
only the I<State> parameter is always necessary.  The others need to be
set only if you think your program will need them later.

I<Proxy> is required for PLAIN (SASL) authentication.

=item Authmechanism 

Set this to the value that AUTHENTICATE should send to the server as the
authentication mechanism. If you are brokering your own authentication
then this parameter may be less useful. It is also not needed by the
L<authenticate> method. It exists solely so that you can set it when
you call L<new> to instantiate your object. The B<new> method will
call L<connect>, who will call L<login>. If B<login> sees that you've
set an I<Authmechanism> then it will call B<authenticate>, using your
I<Authmechanism> and I<Authcallback> parameters as arguments.

=item Authuser

Normally you authenticate and log in with the username specified in
the User parameter. When you are using DIGEST-MD5 as I<Authmechanism>,
you can optionally specify a different username for the final log in.
This can be useful to mark messages as seen for the I<Authuser>
if you don't know the password of the user as the seen state
is often a per-user state.

=item Authcallback 

The I<Authcallback> parameter, if set, should contain a pointer
to a subroutine. The L<login> method will use this as the callback
argument to the B<authenticate> method if the I<Authmechanism> and
I<Authcallback> parameters are both set. If you set I<Authmechanism>
but not I<Authcallback> then the default callback for your mechanism will
be used.  All supported authentication mechanisms have a default callback;
in every other case not supplying the callback results in an error.

Most advanced authentication mechanisms require a challenge-response
exchange. After the L<authenticate> method sends "<tag> AUTHENTICATE
<Authmechanism>\r\n"  to the IMAP server, the server replies with
a challenge. The B<authenticate> method then invokes the code whose
reference is stored in the I<Authcallback> parameter as follows:

	$Authcallback->($challenge,$imap)

where C<$Authcallback> is the code reference stored in the I<Authcallback>
parameter, C<$challenge> is the challenge received from the IMAP server,
and C<$imap> is a pointer to the B<Mail::IMAPClient> object. The return
value from the I<Authcallback> routine should be the response to the
challenge, and that return value will be sent by the L<authenticate>
method to the server.

=item Readmethod 

The I<Readmethod> parameter points to a routine that will read data from
the socket connection. This read method will replace the B<sysread> that
would otherwise be performed by B<Mail::IMAPClient>. The replacement
method is called with five arguments. The first is a pointer to the
B<Mail::IMAPClient> object; the rest are the four arguments required by
the B<sysread> function. Note the third argument (which corresponds to
the second argument to B<sysread>) is a buffer to read into; this will
be a pointer to a scalar. So for example if your I<Readmethod> were
just going to replace B<sysread> without any intervening processing
(which would be silly but this is just an example after all) then you
would set your I<Readmethod> like this:

	$imap->Readmethod( 
		sub { 
			my($self) = shift; 
			my($handle,$buffer,$count,$offset) = @_;
			return sysread( $handle, $$buffer, $count, $offset);
		}
	);

Note particularly the double dollar signs in C<$$buffer> in the B<sysread>
call; this is not a typo!

=item Prewritemethod

The I<Prewritemethod>, if defined, should contain a pointer to a
subroutine.  It is called immediately prior to writing to the socket
connection. It is called by B<Mail::IMAPClient> with two arguments:
a reference to the B<Mail::IMAPClient> object and the ASCII text
string to be written.  It should return another string that will be
the actual string sent to the IMAP server.  The idea here is that your
I<Prewritemethod> will do whatever encryption is necessary and then
return the result to the caller so it in turn can be sent to the server.

=item Ignoresizeerrors

Certain (caching) servers, like Exchange 2007, often report the wrong
message size.  Instead of chopping the message into a size that it
fits the specified size, the reported size will be simply ignored
when this parameter is set to C<1>.

=item Supportedflags

Especially when C<migrate()> is used, the receiving peer may need to
be configured explicitly with the list of supported flags; that may
be different from the source IMAP server.

The names are to be specified as an ARRAY.  Black-slashes and casing
will be ignored.

You may also specify a CODE reference, which will be called for each of
the flags seperately.  In this case, the flags are not (yet) normalized.
The returned lists of the CODE calls are shape the resulting flag list.

=back

=head2 Errors

If you attempt an operation that results in an error, then you can
retrieve the text of the error message by using the L<LastError>
method. However, since the L<LastError> method is an object method (and
not a class method) you will only be able to use this method if you've
successfully created your object. Errors in the L<new> method can
prevent your object from ever being created. Additionally, if you
supply the I<Server>, I<User>, and I<Password> parameters to L<new>, it
will attempt to call B<connect> and B<login>, either of which could
fail and cause your L<new> method call to return C<undef> (in which case
your object will have been created but its reference will have been
discarded before ever having been returned to you).

If this happens to you, you can always check C<$@>. B<Mail::IMAPClient>
will populate that variable with something useful if either of the
L<new>, L<connect>, or L<login> methods fail. In fact, as of version 2,
the C<$@> variable will always contain error info from the last error,
so you can print that instead of calling L<LastError> if you wish. 

If you run your script with warnings turned on (which I'm sure you'll
do at some point because it's such a good idea) then any error message
that gets placed into the L<LastError> slot (and/or in C<$@>) will
automatically generate a warning. 

=head2 Transactions

RFC2060 requires that each line in an IMAP conversation be prefixed
with a tag. A typical conversation consists of the client issuing a
tag-prefixed command string, and the server replying with one of more
lines of output. Those lines of output will include a command
completion status code prefixed by the same tag as the original command
string.

The B<IMAPClient> module uses a simple counter to ensure that each
client command is issued with a unique tag value. This tag value is
referred to by the B<IMAPClient> module as the transaction number. A
history is maintained by the B<IMAPClient> object documenting each
transaction. The L<Transaction> method returns the number of the last
transaction, and can be used to retrieve lines of text from the
object's history. 

The L<Clear> parameter is used to control the size of the session
history so that long-running sessions do not eat up unreasonable
amounts of memory. See the discussion of L<Clear> under L<"Parameters">
for more information.

The L<Report> transaction returns the history of the entire IMAP
session since the initial connection or for the last I<Clear>
transactions. This provides a record of the entire conversation,
including client command strings and server responses, and is a
wonderful debugging tool as well as a useful source of raw data for
custom parsing.

=head1 SEE ALSO

This module is part of Mail-IMAPClient distribution version 3.07,
built on April 28, 2008.

=head1 LICENSE

Copyrights 2008. For other contributors see Changes.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
See F<http://www.perl.com/perl/misc/Artistic.html>

