NAME
   Mail::Spool - Extensible Perl Mail Spooler

SYNOPSIS
     #!/usr/bin/perl -w
     package MyPackage;

     use Mail::Spool;
     @ISA = qw(Mail::Spool);

     my $spool = Mail::Spool->new();

     $spool->dequeue_dir = '/var/spool/mail';

     $spool->daemon;
     exit;

     # OR

     use Mail::Spool qw(send_mail);
     my $args = {to   => '[email protected]',
                 from => '[email protected]',
                 delivery => 'Interactive', # or Deferred
                 timeout  => 2 * 60, # two minutes
                 filename =>
                 #or# message  => $scalar,
                 #or# message  => \$scalar,
                 #or# message  => $a_mail_internet_object,
                 #or# filehandle => $open_io_handle,
                 };
     my $spool = Mail::Spool->new();
     eval{ $spool->send_mail($args) };

     # OR

     eval{ send_mail($args) };
     if( $@ ){
       die "Something went wrong [$@]";
     }

OBTAINING
   Visit http://seamons.com/ for the latest version.

DESCRIPTION
   Mail::Spool is a "pure perl" implementation of mail spooling, unspooling
   and sending. It is intended to be used with daemons such as
   Net::Server::SMTP (to be released soon), but it also contains its own
   daemon (based off of Net::Server::Fork) that can be used if necessary.

   It is also intended to be used as a quick spooling mechanism for perl
   scripts. As it can write straight to the queue without opening another
   process.

   The send_mail method allows for either Deferred or Interactive sending
   of mail.

   As of this writing, a version Mail::Spool has been in use in production
   for three months spooling and sending about 200MB a day in several
   thousand messages.

   The default setup allows for setup on multiple servers, all sharing a
   common spool directory. NFS capable locking will take place in necessary
   areas.

PROPERTIES
   Properties of Mail::Spool are accessed methods of the same name. They
   may be set by calling the method and passing the new value as an
   argument. For example:

     my $dequeue_dir = $self->dequeue_dir;
     $self->dequeue_dir($new_dequeue_dir);

   The following properties are available:

   dequeue_dir
       Base location for the mail spool. Defaults to
       $Mail::Spool::DEQUEUE_DIR which at load time contains
       "/var/spool/mail".

   dequeue_periods
       An array ref containing the amount of time a message must wait in
       the spool and fallback spools. Defaults to
       $Mail::Spool::DEQUEUE_PERIODS which at load time contains an array
       ref with 0, .5*3600, 4*3600, 8*3600, 16*3600, 24*3600, and 48*3600
       as its values. A directory for each of these times will be created
       (0 will be in dequeue_dir/0, .5*3600 will be dequeue_dir/1, etc).
       For a further discussion of dequeue times and methods, please read
       the extended comment in the source code under the subroutine
       list_spool_handles.

   dequeue_priority
       An array ref containing an equal number of elements as
       dequeue_periods. Elements should be integers. Defaults to
       $Mail::Spool::DEQUEUE_PRIORITY which at load time contains an array
       ref with 1, 3, 9, 25, 50, 100, and 200 as its values. A lower number
       means higher priority. With a 20 second dequeue_timeout, a priority
       of 1 checks the queue every 20 seconds, 3 checks every 60 seconds,
       and 200 checks every 66 minutes. For a further discussion of dequeue
       times and methods, please read the extended comment in the source
       code under the subroutine list_spool_handles.

   dequeue_timeout
       Seconds to wait before before looking through the queues. Defaults
       to $Mail::Spool::DEQUEUE_TIMEOUT which at load time is 20 (seconds).

   max_dequeue_processes
       Maximum number of dequeue processes to start under a daemon.
       Defaults to $Mail::Spool::MAX_DEQUEUE_PROCESSES which at load time
       is 20.

   max_connection_time
       Maximum amount of time to stay connected to a remote host. Defaults
       to $Mail::Spool::MAX_CONNECTION_TIME which at load time is 6*60*60
       (6 hours). Messages not delivered under this time period are queued
       for later delivery.

   usage_log
       Location to store raw spool usage information. Defaults to
       $Mail::Spool::USAGE_LOG which at load time is
       "$Mail::Spool::DEQUEUE_DIR/usage".

METHODS
   new Returns an object blessed into the passed class. A hash, or hashref
       passed to the the method will be set as hash keys of the object.

   daemon
       Starts a mail spool daemon using Net::Server::Fork as the back end.
       Will run continuously until the main process is killed. Log
       information defaults to 'Sys::Syslog'.

   create_dequeue_dirs
       May be called as a method or function. Hook to create the necessary
       directories used by the spool daemon.

   list_spool_handles
       Returns a list of objects blessed into the Mail::Spool::Handle class
       (by default). These handle objects represent the queue (spools) that
       need to be processed at the moment. For an important discussion of
       architecture and waiting times, please read the comments in the
       source code located within this subroutine.

   mail_spool_handle
       Returns an object blessed into the Mail::Spool::Handle class. See
       the Mail::Spool::Handle manpage.

   mail_spool_node
       Returns an object blessed into the Mail::Spool::Node class. See the
       Mail::Spool::Node manpage.

   dequeue
       May be called as a method or function. Run through a dequeue
       process. This consists of listing spool handles, opening the spools,
       reading nodes from the spools, and having the nodes fallback upon
       failed delivery. Dequeue is called periodically based upon
       dequeue_timeout one the daemon process has been started.

   parse_for_address
       Short wrapper around Mail::Address->parse. Should take an email
       address line and return a list of objects that can support
       ->address, ->domain, and ->format methods. See the Mail::Address
       manpage.

   new_message_id
       During the send_mail process if a message is deferred, the spooler
       will attempt to parse a message id from the email. If none can be
       found, this method is called to generate a new id which will be used
       in the spooling process.

   send_mail
       May be called as a method or function. Send mail takes a message and
       either sends it off or places it in the queue. Arguments are a hash
       or a hashref. The possible arguments to send_mail are as follows:

       to  Will be used in the "rcpt to" SMTP header (this will be parsed
           out of message if not given).

       from
           Will be used in the "mail from" header (this will be parsed out
           of message if not given).

       message
           My be either a scalar, a scalar ref, an array ref, or an object
           which supports the following head, print, body, header,
           head->get, head->add, and head->delete. Mail::Internet and
           MIME::Entity objects work. If message is not given, filehandle
           or filename may be given.

       filehandle
           Used if message is not given. Must contain an open IO::Handle
           style object (such as IO::File or IO::Scalar).

       filename
           Used if neither message or filehandle are given. Must contain
           the path to a readable filename.

       delivery
           Type of delivery to be used. Must be one of the following:
           Deferred - put in the spool for later (default), Standard - same
           as Deferred, Interative - block until sent (or timed out) and
           die on failure, Background - block until sent (or timed out) and
           put in spool on failure.

       timeout
           Used with delivery Interactive or delivery Background. Seconds
           to wait while trying to connect to a host.

       id  Message id to be used in the queue filename. Used under deferred
           delivery. If none is given, will be parsed out of the message.
           If none is found, will be generated using new_message_id.

   parse_message
       Based upon the arguments given, returns an object that possesses the
       correct methods for use in the send_mail routine. Arguments may be
       given either as a hash or a hashref. The main arguments are
       "message," "filehandle," or "filename.". Message may be either a
       scalar or scalar ref containing the message, an array ref containing
       the lines of the message, or an object which supports head, body,
       and print methods (such as Mail::Internet, or MIME::Entity)
       (actually the object needs to support head, print, body, header,
       head->get, head->add, and head->delete). If there is no message
       argument, and there is a "filehandle" argument, parse_message will
       create an object from the filehandle (the filehandle should be an
       IO::Handle style object). If no filehandle is given, parse_message
       will look for a "filename" argument. This should be a readable
       filename accessible by the spooler. In all cases, the passed message
       should contain the email headers necessary. If it does not, the
       headers will be added as necessary. This method returns a
       Mail::Internet compatible object.

   _send_mail_deferred
       Called by send_mail. Arguments should a hash or hash ref. Places the
       message contained in the "message" argument into the mail spool and
       returns immediately. Required arguments are "message," "to," "from,"
       "id," and "msh" (a Mail::Spool::Handle object).

   _send_mail_now
       Called by send_mail. Arguments shoud be a hash or hash ref. Required
       arguments are "message," "to," "from," "id," "timeout," and
       "delivery." Looks up the mx records of the domain found in "to"
       using the lookup_mx method, and iterates through each of these
       records and tries to open a connection using open_smtp_connection
       (times out after "timeout" seconds). Once a connection has been
       established, sends the message, testing responses using
       check_sock_status. If delivery is "Background," and a connection
       could not be established, the message will be queued for later
       delivery. Any errors die.

   check_sock_status
       Checks the status of the last smtp command. Arguments are the open
       socket, the mx host, the to address, and the from address. Any
       errors die.

   lookup_mx
       Takes a hostname as an argument. Should return a list of the mx
       records for that hostname, ordered by their priorities. This method
       could also be sub classed to allow for caching of the response.

   lookup_host
       Takes a hostname as an argument. Should return a hostname or an ip
       address. Intended as a means of caching records. Default is to
       simply return the passed host.

   open_smtp_connection
       Takes a hostname as an argument. Returns a IO::Socket style object
       containing an open connection to that host (or undef on failure).
       This could be overridden to allow for holding the connection open
       across several emails to the same domain.

   log_usage
       Takes a number and word as arguments. Writes this information out to
       a very simple log. Intended for gathering basic spool information,
       such as total bytes spooled and total bytes sent, as well as total
       messages spooled and sent.

   AUTOLOAD
       Used to dynamically some of the property methods.

TO DO
   Use It
       The best way to further the status of this project is to use it. A
       less extensible version of this module has been in use for around
       three months as of this writing.

   Extensions
       Explore other extenstions such as optimized read of spool
       directories to order by domain. Possibly add interface to allow
       placing mail in postfix and sendmail compatible queues.

   DNS Add modules to handle DNS caching.

   Interfaces
       Add modules containing interfaces to databases, or other "file
       systems".

BUGS
   The current setup of Mail::Spool does represent a possible denial of
   service if 20 or thirty messages are sent to a host that simply holds a
   connection open and does nothing else during mail delivery. What should
   probably be done instead is to only do one dequeue process at a time
   (ever) and fork off a separate process for each mail. This will probably
   be coming under later releases.

SEE ALSO
   Please see also the Mail::Spool::Handle manpage, the Mail::Spool::Node
   manpage.

COPYRIGHT
     Copyright (C) 2001, Paul T Seamons
                         [email protected]
                         http://seamons.com/

     This package may be distributed under the terms of either the
     GNU General Public License
       or the
     Perl Artistic License

     All rights reserved.