This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: Mail/Internet,  Next: Mail/IspMailGate/Filter,  Prev: Mail/IMAPClient,  Up: Module List

manipulate Internet format (RFC 822) mail messages
**************************************************

NAME
====

   Mail::Internet - manipulate Internet format (RFC 822) mail messages

SYNOPSIS
========

     use Mail::Internet;

DESCRIPTION
===========

   This package provides a class object which can be used for reading,
creating, manipulating and writing a message with RFC822 compliant headers.

CONSTRUCTOR
===========

new ( [ ARG ], [ OPTIONS ] )
     ARG is optiona and may be either a file descriptor (reference to a
     GLOB) or a reference to an array. If given the new object will be
     initialized with headers and body either from the array of read from
     the file descriptor.

     OPTIONS is a list of options given in the form of key-value pairs,
     just like a hash table. Valid options are

    Header
          The value of this option should be a `Mail::Header' object. If
          given then Mail::Internet will not attempt to read a mail header
          from ARG, if it was specified.

    Body
          The value of this option should be a reference to an array which
          contains the lines for the body of the message. Each line should
          be terminated with \n (LF). If Body is given then Mail::Internet
          will not attempt to read the body from ARG (even if it is
          specified).

     The Mail::Header options Modify, MailFrom and FoldLength may also be
     given.

METHODS
=======

body ()
     Returns the body of the message. This is a reference to an array.
     Each entry in the array represents a single line in the message.

print_header ( [ FILEHANDLE ] )
print_body ( [ FILEHANDLE ] )
print ( [ FILEHANDLE ] )
     Print the header, body or whole message to file descriptor
     *FILEHANDLE*.  *$fd* should be a reference to a GLOB. If *FILEHANDLE*
     is not given the output will be sent to STDOUT.

          $mail->print( \*STDOUT );  # Print message to STDOUT

as_string ()
     Returns the message as a single string.

as_mbox_string ( [ ALREADY_ESCAPED ] )
     Returns the message as a string in mbox format.  `ALREADY_ESCAPED', if
     given and true, indicates that ->escape_from has already been called
     on this object.

head ()
     Returns the `Mail::Header' object which holds the headers for the
     current message

UTILITY METHODS
===============

   The following methods are more a utility type than a manipulation type
of method.

remove_sig ( [ NLINES ] )
     Attempts to remove a users signature from the body of a message. It
     does this by looking for a line equal to `'-- '' within the last
     `NLINES' of the message. If found then that line and all lines after
     it will be removed. If `NLINES' is not given a default value of 10
     will be used. This would be of most use in auto-reply scripts.

tidy_body ()
     Removes all leading and trailing lines from the body that only contain
     white spaces.

reply ()
     Create a new object with header initialised for a reply to the current
     object. And the body will be a copy of the current message indented.

add_signature ( [ FILE ] )
     Append a signature to the message. FILE is a file which contains the
     signature, if not given then the file "$ENV{HOME}/.signature" will be
     checked for.

send ( [ type [ args.. ]] )
     Send a Mail::Internet message using Mail::Mailer.  Type and args are
     passed on to `Mail::Mailer'

smtpsend ( [ OPTIONS ] )
     Send a Mail::Internet message via SMTP, requires Net::SMTP

     The return value will be a list of email addresses that the message
     was sent to. If the message was not sent the list will be empty.

     Options are passed as key-value pairs. Current options are

    Host
          Name of the SMTP server to connect to, or a Net::SMTP object to
          use

          If Host is not given then the SMTP host is found by attempting
          connections first to hosts specified in `$ENV{SMTPHOSTS}', a
          colon separated list, then mailhost and `localhost'.

    To
    Cc
    Bcc
          Send the email to the given addresses, each can be either a
          string or a reference to a list of email addresses. If none of
          To, <Cc> or Bcc are given then the addresses are extracted from
          the message being sent.

    Hello
          Send a HELO (or EHLO) command to the server with the given name.

    Port
          Port number to connect to on remote host

    Debug
          Debug value to pass to Net::SMPT, see <Net::SMTP>

nntppost ( [ OPTIONS ] )
     Post an article via NNTP, requires Net::NNTP.

     Options are passed as key-value pairs. Current options are

    Host
          Name of NNTP server to connect to, or a Net::NNTP object to use.

    Port
          Port number to connect to on remote host

    Debug
          Debug value to pass to Net::NNTP, see <Net::NNTP>

escape_from ()
     It can cause problems with some applications if a message contains a
     line starting with ``From '', in particular when attempting to split
     a folder.  This method inserts a leading ``''> on anyline that
     matches the regular expression `/^'*From/>

unescape_from ()
     This method will remove the escaping added by escape_from

SEE ALSO
========

   *Note Mail/Header: Mail/Header, *Note Mail/Address: Mail/Address,

AUTHOR
======

   Graham Barr <gbarr@pobox.com>

COPYRIGHT
=========

   Copyright (c) 1995-7 Graham Barr. All rights reserved. This program is
free software; you can redistribute it and/or modify it under the same
terms as Perl itself.


File: pm.info,  Node: Mail/IspMailGate/Filter,  Next: Mail/IspMailGate/Filter/Banner,  Prev: Mail/Internet,  Up: Module List

An abstract base class of mail filters
**************************************

NAME
====

   Mail::IspMailGate::Filter - An abstract base class of mail filters

SYNOPSIS
========

     # Create a filter
     my($filter) = Mail::IspMailGate::Filter->new({});

     # Call him for filtering a given mail (aka MIME::Entity)
     my ($attr) = {
         'entity' => $entity,    # a MIME::Entity object
         'parser' => $parser     # a MIME::Parser object
     };
     my($res) = $filter->doFilter($attr);

VERSION AND VOLATILITY
======================

     $Revision 1.0 $
     $Date 1998/04/05 18:19:45 $

DESCRIPTION
===========

   This class is the abstract base class of email filters. It implements
the main functionality every email filter should have, such as recursive
filtering on multipart MIME-message. You create a new filter by deriving a
subclass from Mail::IspMailGate::Filter. Usually you only need to
implement your own versions of the getSign, filterFile and IsEq methods.

   Most filters are in/out filters. For example the packer module can do
compression or decompression and the PGP module can do encryption and
decryption. These filters are derived from
Mail::IspMailGate::Filter::InOut, which is itself derived from
Mail::IspMailGate::Filter. The main idea of these filters is that they
have two directions, a 'positive' direction (or 'in' mode) and a negative
direction (or 'out' mode).

PUBLIC INTERFACE
================

*new $ATTR*
     *Class method.* Create a new filter instance; by passing the hash ref
     ATTR you configure the filters behaviour. For example, the PGP filter
     typically needs a user ID, the virus scanner needs a path to the
     external virus scanning binary and so on.

     The method returns an object for success or an error message
     otherwise.

getSign
     *Instance method.* Returns a header name, that will be inserted into
     the MIME entities head. For example, the base class inserts a header
     field "X-ispMailGateFilter". Note that more than one header line will
     be inserted if you apply multiple filters.

     You should override this method.

*filterFile $ATTR*
     *Instance method.* This method is called for modifying a given, single
     part of the MIME entity. You can rely on the following attributes
     being set in the hash ref ATTR:

    body
          The MIME::Body object representing the part. The true data is
          stored as a file on disk. (It's a MIME::Body::File object, to be
          precise.) In particular this means that you can create a handle
          referring to the object with

               $fh = $ATTR->{'body'}->open("r") or die $!;

          If you need to work with external binaries you might use

               $path = $ATTR->{'body'}->path();

          If the external binaries create a new file and you want to
          replace the old file, use

               $ATTR->{'body'}->path($newPath);

          See `MIME::Body(3)' in this node for detailed information.

    head
          The MIME::Head object representing this parts head. See
          `MIME::Head(3)' in this node for detailed information.

    globHead
          The MIME::Head object of the top level MIME entity. If you are
          working on a single part entity, this is just the same as the
          'head' attribute.

    parser
          The Mail::IspMailGate::Parser object used for parsing the entity.
          This is mostly usefull for using the logging methods

               $ATTR->{'parser'}->Debug("A debugging message");
               $ATTR->{'parser'}->Error("An error message");
               $ATTR->{'parser'}->Fatal("A fatal error message");

          Note that the latter will abort the currently running thread,
          use is discouraged. Instead you should throw a Perl exception by
          calling die.

     The filterFile method returns an empty string for success or an error
     message otherwise. You should override this function, but calling

          $self->SUPER::filterFile($ATTR)

     at the beginning is strongly encouraged.

*mustFilter $ENTITY*
     *Instance method.* This method determines, whether the doFilter method
     ought to be executed. Usually it looks at the headers of the MIME
     entity $ENTITY, for example the InOut class supresses filtering
     twice. The method returns FALSE to supress filtering, TRUE otherwise.

*hookFilter $ENTITY*
     *Instance method.* If filtering was needed (see doFilter) and done,
     this method is called, mainly for modifying the headers of the MIME
     entity $ENTITY. When overriding this method, you should usually start
     with calling

          $self->SUPER::hookFilter($ENTITY);

*doFilter $ATTR*
     *Instance method.* This method builds the frame of the filtering
     process.  It calls mustFilter. If this method returns TRUE, the
     recdoFilter and hookFilter methods are executed.

     The hash ref $ATTR contains attributes 'entity', 'parser' correspond
     to the same attributes of the filterFile method.

*recdoFilter $ATTR*
     *Instance method.* Called by doFilter for filtering a MIME entity.
     It calls the filterFile method for singlepart entities. For multipart
     entities, it calls itself recursively for any part.

     The hash ref $ATTR corresponds to the arguments of doFilter.

*IsEq $CMP*
     *Instance method.* The IspMailGate program can handle multiple
     recipients at the same time, which is obviously important for
     performance reasons.  For any recipient, a list of filters is built
     that the mail is fed into.  In most cases these filter lists or at
     least parts of them are equivalent, so there's no need to pass the
     mail into both filter lists.

     This method is called for determining whether two filter objects
     ($self and $CMP) are equivalent. In other words: If I feed a mail
     into both objects, the method tells me whether I can expect the same
     result. For example, a simple implementation of IsEq would just look
     at the filter object classes and return TRUE, if both objects are of
     the same classes, but FALSE otherwise:

          sub IsEq ($$) {
              my($self, $CMP) = @_;
              ref($self) eq ref($CMP);
          }

     The above is the default implementation, so it's quite likely that
     you need to override this method.


File: pm.info,  Node: Mail/IspMailGate/Filter/Banner,  Next: Mail/IspMailGate/Filter/PGP,  Prev: Mail/IspMailGate/Filter,  Up: Module List

Add a banner message to outgoing mails
**************************************

NAME
====

   Mail::IspMailGate::Filter::Banner - Add a banner message to outgoing
mails

SYNOPSIS
========

     # Create a filter
     my($filter) = Mail::IspMailGate::Filter::Banner->new({
         'plain' => '/etc/mail/banner.plain',
         'html' => '/etc/mail/banner.html'
     });

     # Call him for filtering a given mail (aka MIME::Entity)
     my ($attr) = {
         'entity' => $entity,    # a MIME::Entity object
         'parser' => $parser     # a MIME::Parser object
     };
     my($res) = $filter->doFilter($attr);

DESCRIPTION
===========

   This class can be used for adding a banner message to the top of
outgoing E-Mails. It knows about MIME types and can deal with plain text
or HTML messages.

PUBLIC INTERFACE
================

*new $ATTR*
     *Class method.* Create a new filter instance; you may supply two
     attributes: `plain' is the name of a banner file to attach to plain
     text mails and html is similar for HTML mails. The difference is,
     that the latter may contain HTML tags.


File: pm.info,  Node: Mail/IspMailGate/Filter/PGP,  Next: Mail/IspMailGate/Filter/Packer,  Prev: Mail/IspMailGate/Filter/Banner,  Up: Module List

Encrypt and decrypt mails with PGP
**********************************

NAME
====

   Mail::IspMailGate::Filter::PGP - Encrypt and decrypt mails with PGP

SYNOPSIS
========

     # Create a filter object
     my($scanner) = Mail::IspMailGate::Filter::VirScan->new({
         'uid' => 'Jochen Wiedmann <joe@ispsoft.de>'
     });

     # Call it for filtering the MIME entity $entity and pass it a
     # Mail::IspMailGate::Parser object $parser
     my($result) = $scanner->doFilter({
         'entity' => $entity,
         'parser' => $parser
         });
     if ($result) { die "Error: $result"; }

VERSION AND VOLATILITY
======================

     $Revision 1.0 $
     $Date 1998/04/05 18:46:12 $

DESCRIPTION
===========

   This class implements an encrypting and decrypting filter based on PGP.
It is derived from the abstract base class Mail::IspMailGate::Filter.  For
details of an abstract filter see *Note Mail/IspMailGate/Filter:
Mail/IspMailGate/Filter,.

   The PGP module is based on the MIME::Decoder::PGP module which is using
an external PGP binary. The filter module is designed for installation on
two servers: When sending mail from one server to the other mails get
automatically encrypted on the sending server and decrypted on the
receiving server. Of course both servers need the IspMailGate package and
PGP installed. Installation typically includes creating an own secret and
public key ring which is specifically dedicated to IspMailGate.

INSTALLATION AND CUSTOMIZATION
==============================

Patching the MIME-tools
-----------------------

   Unfortunately the current version of the MIME-tools (4.116, as of this
writing) has a minor bug that make the MIME::Decoder::PGP module unusable.
This bug was reported to Eryq, the MIME-tools author and will be fixed in
the next release. The patch is quite easy:

     *** /usr/lib/perl5/site_perl/MIME/ParserBase.pm Thu Feb 12 04:11:27 1998
     --- lib/MIME/ParserBase.pm      Thu Apr  9 12:22:44 1998
     ***************
     *** 518,523 ****
     --- 518,524 ----
                 $ent->effective_type('application/octet-stream');
                 $decoder = new MIME::Decoder 'binary';
             }
     +       $decoder->head($head);
     
             # Obtain a filehandle for reading the encoded information:
             #    We have two different approaches, based on whether or not we

   In other words, just use your favourite text editor to edit the file
lib/MIME/ParserBase.pm of the MIME-tools distribution and add the line
marked with a plus sign as line 521. Then reinstall the MIME modules.

Creating a key ring
-------------------

   Before starting to use the PGP module, you have to create a public and
private keyring of the ispmailgate user. If you already have an appropriate
keyring, this is done by copying the files `pubring.pgp', `secring.pgp'
and `randseed.bin' to the `.pgp' subdirectory of the ispmailgate users
home directory. Note that your personal keyring is not appropriate.  An
anonymous user representing your information (an "info" user, for example)
might be more appropriate.

   Do not forget to set the file permissions the right way. For example you
might do the following:

     su
     mkdir ~ispmailgate/.pgp
     cp ~info/.pgp/pubring.pgp ~ispmailgate/.pgp
     cp ~info/.pgp/secring.pgp ~ispmailgate/.pgp
     cp ~info/.pgp/randseed.bin ~ispmailgate/.pgp
     chown -R ispmailgate ~ispmailgate/.pgp
     chgrp -R ispmailgate ~ispmailgate/.pgp
     chmod 755 ~ispmailgate/.pgp
     chmod 600 ~ispmailgate/.pgp/*

   If you don't have an appropriate keyring, you can instead create a new
one. This is done with the following command:

     su - ispmailgate -c "pgp -kg"

   PGP will ask you some questions, for example:

RSA key size
     I recommend using a value of 1024 bit; IspMailGate is not an
     interactive application and it doesn't hurt, if encryption and
     decryption take a little bit longer.

user ID
     Choose an appropriate user ID for representing your organization, for
     example

          FooBar Inc. <info@foobar.com>

     Do not choose the same user ID's and or keyrings on both ends. For
     example another user ID might be

          FooBar Inc., Department Stuttgart <info@stuttgart.foobar.com>

pass phrase
     Enter a random word (you'll be asked to repeat it), note that what you
     enter is usually not visible on the terminal. Remember this pass
     phrase for later use!

Configuring the PGP module
--------------------------

   Next step is editing the Mail::IspMailGate::Config module. In particular
you have to enter values for the following variables:

$cfg->{'pgp'}->{'uid'}
     This is the default user ID for encrypting emails. (You might override
     it with the uid attribute of the Mail::IspMailGate::Filter::PGP
     objects, see below.) Example:

          $PGP_UID = 'FooBar Inc. <info@foobar.com>';

$cfg->{'pgp'}->{'uids'}
     This is a hash ref of user ID's that you want to encrypt
     automatically.  The hash keys are the user ID's, the hash values are
     the respective pass phrases. Example:

          $PGP_UIDS = {
              'FooBar Inc. <info@foobar.com>' => 'foobar'
          };

$cfg->{'pgp'}->{'encrypt_command'}
     A command template for encrypting messages. Example:

          $cfg->{'pgp'}->{'encrypt_command'} =
              '/usr/bin/pgp -fea $uid +verbose=0';

     Note the use of single quotes to prevent expansion of the variable
     $uid. This variable will be expanded my the MIME::Decoder module.

$cfg->{'pgp'}->{'decrypt_command'}
     Likewise for decryption. Example:

          $cfg->{'pgp'}->{'decrypt_command'} =
              '/usr/bin/pgp -f +verbose=0';

     You might miss a variable $pass or something sililar here, as
     decryption requires a pass phrase. Pgp has no command line option for
     setting the pass phrase (Security reasons, might be visible in ps
     output), but it accepts an environment variable PGPPASS.  This
     variable gets set automatically.

Creating filter rules
---------------------

   Recall the situation from above. We have the FooBar headquarters and
the department in Stuttgart. The headquarter might use the following rule
for encrypting mails to the department:

     { 'recipients' => '\\@stuttgart.foobar.com^',
       'filters' => [ Mail::IspMailGate::Filter::PGP->new({
     	'uid' => 'FooBar Inc., Department Stuttgart'
     	    . ' <info@stuttgart.foobar.com>',
           'direction' => 'pos'
     	}) ]
     },
     { 'recipients' => '\\@stuttgart.foobar.com^',
       'filters' => [ Mail::IspMailGate::Filter::PGP->new({
           'direction' => 'neg'
     	}) ]
     }

   Likewise the following might be used at the department of Stuttgart:

     { 'recipients' => '\\@hq.foobar.com^',
       'filters' => [ Mail::IspMailGate::Filter::PGP->new({
     	'uid' => 'FooBar Inc. <info@foobar.com>',
           'direction' => 'pos'
     	}) ]
     },
     { 'recipients' => '\\@hq.foobar.com^',
       'filters' => [ Mail::IspMailGate::Filter::PGP->new({
           'direction' => 'neg'
     	}) ]
     }

   If you use multiple filters (for example the PGP filter might well be
used together with a compressing filter), note the following:

   When encrypting a mail, the PGP filter *must* always be the last
filter, because what the filter does is mainly choosing a certain type for
the content-transfer-encoding. On the other hand, the PGP filter must be
the first one, when decrypting a mail. Thus the headquarters setup for
both compressing and decrypting mails from the headquarter to the
department in Stuttgart and vice versa might look like this:

     { 'recipients' => '\\@stuttgart.foobar.com^',
       'filters' => [
           Mail::IspMailGate::Filter::Packer->new({
     	    'packer' => 'gzip',
     	    'direction' => 'pos'
               }),
           Mail::IspMailGate::Filter::PGP->new({
     	    'uid' => 'FooBar Inc., Department Stuttgart'
     	         . ' <info@stuttgart.foobar.com>',
               'direction' => 'pos'
     	    })
           ]
     },
     { 'recipients' => '\\@stuttgart.foobar.com^',
       'filters' => [
           Mail::IspMailGate::Filter::PGP->new({
     	    'uid' => 'FooBar Inc., Department Stuttgart'
     	         . ' <info@stuttgart.foobar.com>',
               'direction' => 'neg'
     	    })
           Mail::IspMailGate::Filter::Packer->new({
     	    'packer' => 'gzip',
     	    'direction' => 'neg'
               })
           ]
     }

SEE ALSO
========

   `ispMailGate' in this node, *Note Mail/IspMailGate/Filter:
Mail/IspMailGate/Filter,


File: pm.info,  Node: Mail/IspMailGate/Filter/Packer,  Next: Mail/IspMailGate/Filter/VirScan,  Prev: Mail/IspMailGate/Filter/PGP,  Up: Module List

Compressing emails
******************

NAME
====

   Mail::IspMailGate::Filter::Packer  - Compressing emails

SYNOPSIS
========

     # Create a Packer object for compression
     my($packer) = Mail::IspMailGate::Filter::Packer->new({
         'packer' => 'gzip',
         'direction' => 'pos'
     });

     # Create a Packer object for decompression
     my($packer) = Mail::IspMailGate::Filter::Packer->new({
         'packer' => 'gzip',
         'direction' => 'neg'
     });

     # Create a Packer object for automatic compression/decompression
     my($packer) = Mail::IspMailGate::Filter::Packer->new({
         'packer' => 'gzip'
     });

     # Call the filter
     my($res) = $packer->doFilter({
         'entity' => $entity,  # the MIME::Entity which is to be filtered
         'parser' => $parser
     });

VERSION AND VOLATILITY
======================

     $Revision 1.0 $
     $Date 1998/04/05 18:46:12 $

DESCRIPTION
===========

   This class is the Packer (compressing emails) derived from *Note
Mail/IspMailGate/Filter: Mail/IspMailGate/Filter, (refer to the manpage).
You can specify the attribute 'direction' with the constructor, so you can
force to act only in one direction: 'pos' only compressing and 'neg' only
for decompressing. If you specify no direction it will be guessed in the
function mustFilter. If the message has never been Filter by Packer it
chooses 'pos', else it checks in which direction this has happened and
chooses the opposite. You can also specify the attribute 'packer' in the
constructor to set the comressor type for direction 'pos'.  The supported
packer are configured in *$cfg-*{'packer'}> in each direction with a
template for the *system()* command.  It overrides the function
filterFile, mustFilter, *hookFile* and getSign.

PUBLIC INTERFACE
================

*mustFilter ENTITY*
     It determines the direction as described in DESCRIPTION and stores it
     in $self->{'recDirection'}. If the direction is 'neg' it also tries to
     determine the packer which was used for the compressing to guarantee
     a correct decompressing. If this failes it returns 0 and the email
     will not be decompressed.  The same happens if this obejct has the
     attribute 'direction' and this attribute equals the sign in the
     MIME-header which is set in hookFilter. The packer which is to use
     (if possible) is stored in $self->{'recPacker'}.

*filterFile FILENAME*
     Does the (de)compressing of a part of the MIME-message depending on
     $self->{'recDirection'} and $self->{'recPacker'}.

*hookFilter ENTITY*
     This function sets the direction in the header of the message as well
     which packer was used.

   Additionaly we have the function:

*sub setEncoding ATTR*
     Where the attribute 'direction' specifies in which direction Packer
     acts at the moment and 'head' is the head of a subpart of the whole
     entity. This function sets in 'head' the
     'Content-Transfer-Encoding'. It is set to base64 if the direction is
     'pos' else it restores the old one which is stored in
     'X-ispMailGate-Packer-PEncoding'. If this cannot be determined we
     assume base64.  It is called by the overriden filterFile to guarantee
     a correct encoding of the email.


File: pm.info,  Node: Mail/IspMailGate/Filter/VirScan,  Next: Mail/ListDetector,  Prev: Mail/IspMailGate/Filter/Packer,  Up: Module List

Scanning emails for Viruses
***************************

NAME
====

   Mail::IspMailGate::Filter::VirScan  - Scanning emails for Viruses

SYNOPSIS
========

     # Create a filter object
     my($scanner) = Mail::IspMailGate::Filter::VirScan->new({});

     # Call it for filtering the MIME entity $entity and pass it a
     # Mail::IspMailGate::Parser object $parser
     my($result) = $scanner->doFilter({
         'entity' => $entity,
         'parser' => $parser
         });
     if ($result) { die "Error: $result"; }

DESCRIPTION
===========

   This class implements a Virus scanning email filter. It is derived from
the abstract base class Mail::IspMailGate::Filter. For details of an
abstract filter see *Note Mail/IspMailGate/Filter:
Mail/IspMailGate/Filter,.

   The virus scanner class needs an external binary which has the ability
to detect viruses in given files, like VirusX from http://www.antivir.com.
What the module does is extracting files from the email and passing them
to the scanner. Extracting includes dearchiving .zip files, .tar.gz files
and other known archive types by using external dearchiving utilities like
unzip, *tar* and *gzip*. Known extensions and dearchivers are
configurable, so you can customize them for your own needs.

CUSTOMIZATION
=============

   The virus scanner module depends on some items in the
Mail::IspMailGate::Config module:

$cfg->{'antivir_path'}
     Path of the AntiVir binary, for example

          $cfg->{'antivir_path'} = '/usr/bin/antivir';

$cfg->{virscan}->{scanner}
     A template for calling the external virus scanner; example:

          $cfg->{'virscan'}->{'scanner'} =
          	'$antivir_path -rs -nolnk -noboot $ipaths';

     The template must include either of the variable names $ipath or
     $ipaths; the former must be used, if the virus scanner cannot accept
     more than one file name with one call. Note the use of single quotes
     which prevent expanding the variable name!

     Additionally the pattern $antivir_path may be used for the path to
     the antivir binary.

$cfg->{virscan}->{deflater}
     This is an array ref of known archive deflaters. Each element of the
     array is a hash ref with the attributes cmd, a template for calling
     the dearchiver and pattern, a Perl regular expression for detecting
     file names which refer to archives that this program might extract.
     An example which configures the use of unzip, `tar' and `gzip':

          $cfg->{'virscan'}->{'deflater'} =
              [ { pattern => '\\.(tgz|tar\\.gz|tar\\.[zZ])$',
                  cmd => '$gzip_path -cd $ipath | /bin/tar -xf -C $odir'
                },
                { pattern => '\\.tar$',
                  cmd => '$tar_path -xf -C $odir'
          	  },
          	  { pattern => '\\.(gz|[zZ])$',
                  cmd => '$gzip_path -cd $ipath >$opath'
                },
                { pattern => '\\.zip$',
                  cmd => '$unzip_path $ifile -d $odir'
                }
              ];

     Again, note the use of single quotes to prevent variable expansion and
     double backslashes for passing a single backslash in the Perl regular
     expressions. See *Note Perlre: (perl.info)perlre, for details of
     regular expressions.

     The command template can use the following variables:

    $ipath
          Full filename of the archive being deflated

    $idir
    $ifile
          Directory and file name portion of the archive

    $odir
          Directory where the archive must be extracted to; if your
          dearchiver doesn't support an option -directory or something
          similar, you need to create a subshell. For example the
          following might be used for an LhA deflater:

               { 'pattern' => '\\.(lha|lzx)',
                  'cmd' => '(cd $odir; lha x $ipath)'
               }

    $ofile
    $opath
          Same as $ifile and $odir/$ofile; for example gzip needs this,
          when it runs as a standalone deflater and not as a backend of
          tar.

    $gzip_path
    $tar_path
    $unzip_path
    $lha_path
    $unarj_path
          These are the paths of the corresponding binaries and read from
          $cfg->{'gzip_path'}, $cfg->{'tar_path'} and so on.

PUBLIC INTERFACE
================

*checkFile $ATTR, $FILE*
     This function is called for every part of a MIME-message from within
     the filterFile method. It receives the arguments $ATTR (same as the
     $ATTR argument of filterFile) and $FILE, the filename where the MIME
     part is stored. If it detects $FILE to be an archive, it calls
     checkArchive for deflating it and building a list of files contained
     in the archive. If another archive is found, it calls checkArchive
     again.

     Finally, after building a list of files, it calls the virus scanner.
     If the scanner can handle multiple files, a single call occurs,
     otherwise the scanner will be called for any file. See
     `CONFIGURATION' in this node above.

*checkArchive $ATTR, $IPATH, $DEFLATER*
     This function is called from within checkFile to extract the archive
     $IPATH by using the $DEFLATER->{'cmd'} ($DEFLATER is an element from
     the deflater list). The $ATTR argument is the same as in checkFile.

     The function creates a new temporary directory and extracts the
     archive contents into that directory. Finally it returns a list of
     files that have been extracted.

HasVirus
          $hasVirus = $self->HasVirus($OUTPUT)

     (Instance method) This method takes the string $OUTPUT, which is a
     message emitted by the virus scanner and parses it for possible virus
     warnings.  The method returns TRUE, if such warnings are detected or
     FALSE otherwise.

     The default implementation knows about the output of the *AntiVir*
     virus scanner. To use the filter with other virus scanners, you
     typically dervice a subclass from it which overrides this method.

SEE ALSO
========

   `ispMailGate' in this node, *Note Mail/IspMailGate/Filter:
Mail/IspMailGate/Filter,


File: pm.info,  Node: Mail/ListDetector,  Next: Mail/ListDetector/Detector/Base,  Prev: Mail/IspMailGate/Filter/VirScan,  Up: Module List

Perl extension for detecting mailing list messages
**************************************************

NAME
====

   Mail::ListDetector - Perl extension for detecting mailing list messages

SYNOPSIS
========

     use Mail::ListDetector;

DESCRIPTION
===========

   This module analyzses `Mail:;Internet' in this node objects. It returns
a *Note Mail/ListDetector/List: Mail/ListDetector/List, object
representing the mailing list.

   The RFC2369 mailing list detector is also capable of matching some
Mailman and Ezmlm messages. It is deliberately checked last to allow the
more specific Mailman and Ezmlm parsing to happen first, and more
accurately identify the type of mailing list involved.

METHODS
=======

new()
=====

   This method is the core of the module. Pass it a *Note Mail/Internet:
Mail/Internet, object, it will either return a *Note
Mail/ListDetector/List: Mail/ListDetector/List, object that describes the
mailing list that the message was posted to, or undef if it appears not to
have been a mailing list post.

EMAILS USED
===========

   This module includes a number of sample emails from various mailing
lists. In all cases, mails are used with permission of the author, and
must not be distributed separately from this archive. If you believe I may
have accidentally used your email or content without permission, contact
me, and if this turns out to be the case I will immediately remove it from
the latest version of the archive.

BUGS
====

   * A lot of the code applies fairly simple regular expressions to email
     address to extract information. This may fall over for really weird
     email addresses, but I'm hoping no-one will use those for names of
     mailing lists.

   * The majordomo and smartlist recognisers don't have much to go on, and
     therefore are probably not as reliable as the other detectors.  This
     is liable to be hard to fix.

AUTHOR
======

   Michael Stevens - michael@etla.org.

SEE ALSO
========

   perl(1).


File: pm.info,  Node: Mail/ListDetector/Detector/Base,  Next: Mail/ListDetector/Detector/Ezmlm,  Prev: Mail/ListDetector,  Up: Module List

base class for mailing list detectors
*************************************

NAME
====

     Mail::ListDetector::Detector::Base - base class for mailing list detectors

SYNOPSIS
========

     use Mail::ListDetector::Detector::Base;

DESCRIPTION
===========

   Abstract base class for mailing list detectors, should not be
instantiated directly.

METHODS
=======

new()
-----

   Provides a simple constructor for the class. Accepts an optional data
argument and stores that argument in the object if it is supplied.

match()
-------

   This just dies, and should be implemented in any subclass.

BUGS
====

   No known bugs.

AUTHOR
======

   Michael Stevens - michael@etla.org.


File: pm.info,  Node: Mail/ListDetector/Detector/Ezmlm,  Next: Mail/ListDetector/Detector/Listar,  Prev: Mail/ListDetector/Detector/Base,  Up: Module List

Ezmlm message detector
**********************

NAME
====

   Mail::ListDetector::Detector::Ezmlm - Ezmlm message detector

SYNOPSIS
========

     use Mail::ListDetector::Detector::Ezmlm;

DESCRIPTION
===========

   An implementation of a mailing list detector, for ezmlm.

METHODS
=======

new()
-----

   Inherited from *Note Mail/ListDetector/Detector/Base:
Mail/ListDetector/Detector/Base,.

match()
-------

   Accepts a *Note Mail/Internet: Mail/Internet, object and returns either
a *Note Mail/ListDetector/List: Mail/ListDetector/List, object if it is a
post to an ezmlm mailing list, or undef.

BUGS
====

   No known bugs.

AUTHOR
======

   Michael Stevens - michael@etla.org.


File: pm.info,  Node: Mail/ListDetector/Detector/Listar,  Next: Mail/ListDetector/Detector/Mailman,  Prev: Mail/ListDetector/Detector/Ezmlm,  Up: Module List

Listar message detector
***********************

NAME
====

   Mail::ListDetector::Detector::Listar - Listar message detector

SYNOPSIS
========

     use Mail::ListDetector::Detector::Listar;

DESCRIPTION
===========

   An implementation of a mailing list detector, for Listar.

   This seems to only match older Listar list versions - newer ones appear
to be rfc2369 compliant, and are recognised as that instead.

METHODS
=======

new()
-----

   Inherited from *Note Mail/ListDetector/Detector/Base:
Mail/ListDetector/Detector/Base,.

match()
-------

   Accepts a *Note Mail/Internet: Mail/Internet, object and returns either
a *Note Mail/ListDetector/List: Mail/ListDetector/List, object if it is a
post to a listar mailing list, or undef.

BUGS
====

   None known.

AUTHOR
======

   Michael Stevens - michael@etla.org.


File: pm.info,  Node: Mail/ListDetector/Detector/Mailman,  Next: Mail/ListDetector/Detector/Majordomo,  Prev: Mail/ListDetector/Detector/Listar,  Up: Module List

Mailman message detector
************************

NAME
====

   Mail::ListDetector::Detector::Mailman - Mailman message detector

SYNOPSIS
========

     use Mail::ListDetector::Detector::Mailman;

DESCRIPTION
===========

   An implementation of a mailing list detector, for GNU Mailman.

METHODS
=======

new()
-----

   Inherited from *Note Mail/ListDetector/Detector/Base:
Mail/ListDetector/Detector/Base,.

match()
-------

   Accepts a *Note Mail/Internet: Mail/Internet, object and returns either
a *Note Mail/ListDetector/List: Mail/ListDetector/List, object if it is a
post to a Mailman mailing list, or undef.

BUGS
====

   No known bugs.

AUTHOR
======

   Michael Stevens - michael@etla.org.


File: pm.info,  Node: Mail/ListDetector/Detector/Majordomo,  Next: Mail/ListDetector/Detector/RFC2369,  Prev: Mail/ListDetector/Detector/Mailman,  Up: Module List

Majordomo message detector
**************************

NAME
====

   Mail::ListDetector::Detector::Majordomo - Majordomo message detector

SYNOPSIS
========

     use Mail::ListDetector::Detector::Majordomo;

DESCRIPTION
===========

   An implementation of a mailing list detector, for majordomo.

METHODS
=======

new()
-----

   Inherited from *Note Mail/ListDetector/Detector/Base:
Mail/ListDetector/Detector/Base,.

match()
-------

   Accepts a *Note Mail/Internet: Mail/Internet, object and returns either
a *Note Mail/ListDetector/List: Mail/ListDetector/List, object if it is a
post to a majordomo mailing list, or undef.

BUGS
====

   * This module needs to guess a little about whether a message is a post
     to a majordomo mailing list, as majordomo puts so little information
     in the message headers.

AUTHOR
======

   Michael Stevens - michael@etla.org.


File: pm.info,  Node: Mail/ListDetector/Detector/RFC2369,  Next: Mail/ListDetector/Detector/Smartlist,  Prev: Mail/ListDetector/Detector/Majordomo,  Up: Module List

RFC2369 message detector
************************

NAME
====

   Mail::ListDetector::Detector::RFC2369 - RFC2369 message detector

SYNOPSIS
========

     use Mail::ListDetector::Detector::RFC2369;

DESCRIPTION
===========

   An implementation of a mailing list detector, for RFC2369 compliant
mailing lists.

METHODS
=======

new()
-----

   Inherited from *Note Mail/ListDetector/Detector/Base:
Mail/ListDetector/Detector/Base,.

match()
-------

   Accepts a *Note Mail/Internet: Mail/Internet, object and returns either
a *Note Mail/ListDetector/List: Mail/ListDetector/List, object if it is a
post to a RFC2369 compliant mailing list, or undef.

   The RFC2369 standard does not REQUIRE all the information we wish to
extract to be present - therefore this module may not be able to return
full information for all RFC2369 compliant lists.

BUGS
====

   No known bugs.

AUTHOR
======

   Michael Stevens - michael@etla.org.


File: pm.info,  Node: Mail/ListDetector/Detector/Smartlist,  Next: Mail/ListDetector/List,  Prev: Mail/ListDetector/Detector/RFC2369,  Up: Module List

Smartlist message detector
**************************

NAME
====

   Mail::ListDetector::Detector::Smartlist - Smartlist message detector

SYNOPSIS
========

     use Mail::ListDetector::Detector::Smartlist;

DESCRIPTION
===========

   An implementation of a mailing list detector, for smartlist.

METHODS
=======

new()
-----

   Inherited from *Note Mail/ListDetector/Detector/Base:
Mail/ListDetector/Detector/Base,.

match()
-------

   Accepts a *Note Mail/Internet: Mail/Internet, object and returns either
a *Note Mail/ListDetector/List: Mail/ListDetector/List, object if it is a
post to a smartlist mailing list, or undef.

BUGS
====

   No known bugs.

AUTHOR
======

   Michael Stevens - michael@etla.org.


File: pm.info,  Node: Mail/ListDetector/List,  Next: Mail/Mailer,  Prev: Mail/ListDetector/Detector/Smartlist,  Up: Module List

an object representing a mailing list
*************************************

NAME
====

   Mail::ListDetector::List - an object representing a mailing list

SYNOPSIS
========

     use Mail::ListDetector::List;

DESCRIPTION
===========

   This object provides a representation of the information extracted
about a mailing list. It should not be instantiated directly by anything
outside the *Note Mail/ListDetector: Mail/ListDetector, package.

METHODS
=======

new()
=====

listname()
==========

   This method gets or sets the name of the mailing list. The name to set
is an optional argument.

posting_address()
=================

   This method gets or sets the posting address of the mailing list.  The
posting address to set is an optional argument.

listsoftware()
==============

   This method gets or sets the mailing list software name. The name to
set is an optional argument.

BUGS
====

   No known bugs.

AUTHOR
======

   Michael Stevens - michael@etla.org.


File: pm.info,  Node: Mail/Mailer,  Next: Mail/MsgStore,  Prev: Mail/ListDetector/List,  Up: Module List

Simple interface to electronic mailing mechanisms
*************************************************

NAME
====

   Mail::Mailer - Simple interface to electronic mailing mechanisms

SYNOPSIS
========

     use Mail::Mailer;
     use Mail::Mailer qw(mail);

     $mailer = new Mail::Mailer;

     $mailer = new Mail::Mailer $type, @args;

     $mailer->open(\%headers);

     print $mailer $body;

     $mailer->close;

DESCRIPTION
===========

   Sends mail using any of the built-in methods.  You can alter the
behaviour of a method by passing $command to the new method.

mail
     Use the Unix system mail program to deliver the mail.  $command is
     the path to mail.  Mail::Mailer will search for `mailx', Mail and
     mail (in this order).

sendmail
     Use the sendmail program to deliver the mail.  $command is the path
     to sendmail.

smtp
     Use the smtp protocol via Net::SMTP to deliver the mail. The server
     to use can be specified in `@args' with

          $mailer = new Mail::Mailer 'smtp', Server => $server;

test
     Used for debugging, this calls `/bin/echo' to display the data.  No
     mail is ever sent.  $command is ignored.

   `Mail::Mailer' will search for executables in the above order. The
default mailer will be the first one found.

ARGUMENTS
---------

   new can optionally be given a $command and $type.  $type is one
sendmail, mail, ... given above.  The meaning of $command depends on $type.

   open is given a reference to a hash.  The hash consists of key and
value pairs, the key being the name of the header field (eg, To), and the
value being the corresponding contents of the header field.  The value can
either be a scalar (eg, `gnat@frii.com') or a reference to an array of
scalars (`eg, ['gnat@frii.com', 'Tim.Bunce@ig.co.uk']').

TO DO
=====

   Assist formatting of fields in ...::rfc822:send_headers to ensure valid
in the face of newlines and longlines etc.

   Secure all forms of send_headers() against hacker attack and invalid
contents. Especially "\n~..." in ...::mail::send_headers.

ENVIRONMENT VARIABLES
=====================

PERL_MAILERS
     Augments/override the build in choice for binary used to send out our
     mail messages.

     Format:

          "type1:mailbinary1;mailbinary2;...:type2:mailbinaryX;...:..."

     Example: assume you want you use private sendmail binary instead of
     mailx, one could set PERL_MAILERS to:

          "mail:/does/not/exists:sendmail:$HOME/test/bin/sendmail"

SEE ALSO
========

   Mail::Send

AUTHORS
=======

   Maintained by Graham Barr <`gbarr@pobox.com'>

   Original code written by Tim Bunce <`Tim.Bunce@ig.co.uk'>, with a kick
start from Graham Barr <`gbarr@pobox.com'>. With contributions by Gerard
Hickey <`hickey@ctron.com'> Small fix and documentation by Nathan
Torkington <`gnat@frii.com'>.

   For support please contact comp.lang.perl.misc or Graham Barr
<`gbarr@pobox.com'>


File: pm.info,  Node: Mail/MsgStore,  Next: Mail/POP3Client,  Prev: Mail/Mailer,  Up: Module List

Complete mail client back end.
******************************

NAME
====

   Mail::MsgStore - Complete mail client back end.

SYNOPSIS
========

     use Mail::MsgStore;

     # set mailroot
     Mail::MsgStore::mailroot($ENV{MAILROOT});
     # get new messages from server
     $count= Mail::MsgStore::getmail(\&prompt);
     # send a Mail::Internet message
     Mail::MsgStore::send($msg);

     # add an account
     Mail::MsgStore::acct_set('Joe User <user@server.com> (work)',$password);
     # delete an account
     Mail::MsgStore::acct_del('Joe User <user@server.com> (work)');
     # change mailroot
     Mail::MsgStore::mailroot('c:/mail');
     # change from address
     Mail::MsgStore::from('Brian Lalonde <brianl@sd81.k12.wa.us>');
     # get SMTP server address
     $smtp= Mail::MsgStore::smtp;
     
     # add message
     $MsgStore{'/'}= $msg;                # auto-filter
     $MsgStore{'path/to/folder/'}= $msg;  # add to specific folder
     # delete message
     delete $MsgStore{'path/to/folder/msgid'};
     # delete folder
     delete $MsgStore{'path/to/folder/'};

     # get message
     $msg= $MsgStore{'path/to/folder/msgid'};
     # mark message as read, unmark 'general' flag
     $MsgStore{'path/to/folder/msgid'}= 'read, -general';
     # get folder's message id list
     @msgids= $MsgStore{'path/to/folder/'};
     # get list of folders
     @folders= keys %MsgStore;

     # move message
     $MsgStore{'newfolder/'}= delete $MsgStore{'path/to/folder/msgid'};
     # copy message
     $MsgStore{'path/to/newfolder/'}= $MsgStore{'path/to/folder/msgid'};

DESCRIPTION
===========

   The primary goal of this module is ease of use.  The Mail::Folder
module, on top of not quite being complete yet, is a pretty low-level API.
I was very impressed with how Win32::TieRegistry simplified an otherwise
complex task, and decided to adopt a similar interface for handling a mail
store.

   Another, equally important, reason for creating this module was
user-configurability.  I was unhappy with existing mail clients' filtering
capabilities- I wanted to pass every new message through some arbitrary
Perl code that was smart enough to forward, reply, send pages, activate
emergency-type alerts, etc. based on properties of the message.  What I
didn't want was more bloatware-Exchange, Outlook and Groupwise have
already been written, and despite being huge, still don't do enough.

Storage Format
--------------

   MsgStore uses a modified form of qmail's maildir format.  Here's how it
works: new messages are downloaded into a file guaranteed to have a
unique, but incomplete, name.  The filename is completed once the entire
message has been successfully downloaded (the finishing of the filename
replaces maildir's state subdirectories).

   The unique filename is generated as a dot-separated list of (uppercase)
hexadecimal numbers:  seconds past epoch (12 digits), IP address (8
digits), process id (4 digits), and download number (2 digits).  The IP
should guarantee uniqueness to a machine, the time and pid narrows it down
to a specific process, and a simple incremental number ensures that 256
messages can be downloaded per second and still retain uniqueness.  The
filename also begins and ends with 'mail', also separated by dots.

   Message flags are part of the message id (although requesting a message
by an id with the wrong flags still works).  The flags are five characters
delimited by parens.  Each position is either a dash (off) or a letter
(on).  Order is significant, but since the letters spell the word FLAGS,
that shouldn't be a problem.  Here are what the letters stand for:

     F  flame
     L  list/group
     A  answered/replied
     G  general/flag
     S  seen/opened/read

Warning
-------

   The storage format used for this module quickly becomes unusable for
large message stores; hundreds or thousands of tiny files are rarely
stored efficiently on the disk.

   Although the module is completely usable, I hope it will inspire better
storage formats to use the same simple tied-hash interface.

EVENTS
======

   The message store allows definition of the following subroutines in the
`events.pl' file located in the *mailroot* directory:

`filter($msg)'
     Accepts the Mail::Internet message object.  The message's recipient
     account is available as `X-Recipient-Account' in the message header.

     Returns the name of the folder that the Mail::Internet $msg belongs
     in.  Returning undef implies the `Inbox'.  Also, all message flags
     should be stored in the `X-Msg-Info' header, either as the native
     `(FLOR!)' format of the message ID, or the english equivalents:
     `flame, mailing-list, opened, replied, flagged'.

`keep($msg)'
     Accepts the Mail::Internet message object.  The message's recipient
     account is available as `X-Recipient-Account' in the message header.

     Returns a boolean value that determines whether the message should be
     kept on the server.

`sign($msg)'
     Signs a message before it is sent.

FUNCTIONS
=========

Sending and Receiving
---------------------

`getmail(\&prompt[,\&status])'
     Logs on to each mail account, checking for new messages, which are
     downloaded, passed to `filter()' and added.

     Returns number of messages downloaded.  Requires a callback that will
     be used if there is a problem logging in:

    `prompt($acct)'
          Parameters: `$acct' ISA Mail::Address: user is the POP3 username,
          host is the POP3 server.

          The function must return a password, or undef to cancel.  The
          password will be updated if it was initially set, or left blank
          otherwise.

    `status($status_message[,$percent_done])'
          Parameters: `$status_message' is a string describing what is
          going on suitable for GUI statusbars, etc.  `$percent_done' is
          an integer between 0 and 100 (when included, else undef)
          suitable for feeding to progress bars, etc.

`signmsg($msg)'
     Signs a Mail::Internet message, using the sign() function from the
     user-defined `events.pl'.

`sendmsg($msg)'
     Sends a Mail::Internet message, and stores a copy in `Sent/'.

Settings
--------

`mailroot([$mailroot])'
     Gets/sets the root directory of the mailstore.  The user's login is
     appended to this directory.  If the directory doesn't exist, it is
     created.  If the directory doesn't contain an `events.pl' file, one
     (fully commented) is created.

     Defaults to `$ENV{MAILROOT}' or current dir unless set.

`load_events()'
     Reloads the `events.pl' file.  Useful if you provide an editing
     facility for that file, or otherwise know that it has changed.

`smtp([$smtp])'
     Gets/sets the address of the outgoing mail server.

`from([$from])'
     Gets/sets the email `From:' address.

`accounts()'
     Returns a list of account strings.

`acct_set($acct,$pwd)'
     Adds/sets an POP3 account to the list handled by `getmail()'.
     Parameters: account and optional password.

     Accounts strings are parsed by Mail::Address; the server portion is
     used to connect, and the user portion is used to log in.  Everything
     else is mnemonic.

`acct_del($acct)'
     Deletes an account.

The Address Book
----------------

`addresses()'
     Returns a list of (references to) hashes for the entire address book.

`address( field => $value, ... )'
     Add an entry to the address book.  The key for the new entry is
     returned.  The full list of fields is available in `@addr_field',
     pretty names for the fields are in `%addr_field' (neither exported by
     default).

     Some fields of note:

    key
          A guaranteed unique identifier for the address entry.
          Auto-generated on insert.

    notes
          The *only* field allowed to contain tabs and newlines.

    firstname, lastname, nickname, email
          Standard mail-client stuff.

    tons more...
          (and in no guaranteed order)

`address($key)'
     Retrive the hash for an address.

`address($key, field => $value, ...)'
     Update fields on an existing address.  Boolean success is returned.

`address($key, DELETE => 1 )'
     Delete an entry from the address book.

`ldaps([$ldaps])'
     Gets/sets a comma or space-delimited list of LDAP servers.

`whosearch(qr/regex/, [ @fields ] )'
     Searches the address book fields specified by fields, looking for
     records that match the regex, the `firstname' and `lastname' fields
     by default.  (Actually, matches with `"@addr{@fields}"=~ /regex/'.)
     The special field nickname is also checked to match.  A list of
     (references to) hashes of matching records are returned, plus a
     `MATCHED' field in each hash that contains the value of either
     `$field[0]' or nickname, depending on which field matched.

     The result set is sorted by matching field.

     This function is probably unneccessarily complex for most mail
     clients.

`addrsearch( -starts => $namestart,  [ -number => $hitnum, ] [ -fields => \@fields, ] )'
     This is a simpler version of `"whosearch"' in this node that just
     returns address strings (rather than entire hashrefs for each record).
     (Actually, matches with `"@addr{@fields}"=~ /regex/'.)  By default,
     the `firstname' and `lastname' fields are used, just as in
     `"whosearch"' in this node.  The special field nickname is also
     checked to match.  In list context, the list of matching address
     strings is returned, but in a scalar context, the `$hitnum'-th
     element is returned (this allows passing of a kind of "Nope, next
     one." request).

     Each address is formatted this way:   `firstname' `lastname' <email>
     unless the match was via nickname, in which case the nickname and a
     tab character are prepended to the address string.

`ldapsearch($startswith)'
     Searches the server(s) specified by `ldaps()' for an entry that
     starts with `$startswith', and returns a list similar to
     `"addrsearch"' in this node.  Ignores queries shorter than 3 letters.

     This function is called by `"addrsearch"' in this node, and probably
     needn't be called directly.

Utility
-------

`msgsearch($folder,\&match)'
     Searches messages in `$folder' (and all subfolders) for messages that
     produce a true value when passed to `&match'.  Returns a list of
     fully-qualified message IDs.

`simplifymsg($msg)'
     Returns a text-only body of $msg.  If the actual $msg is a
     `multipart/mixed' or `multipart/alternative', for example, this just
     gives you the text portion of the message for display purposes.

`msgpath($fullqid)'
     Given a fully-qualified messsage ID (one that begins with the folder
     path), breaks the string into folder path and message ID.  (Similar
     in spirit to the *Note File/Basename: File/Basename, module.)

`msgid($msgid)'
     Given a message ID whose flags may have changed (the message ID
     contains the message flags), returns the new message ID.

`flags($string)'
     Returns a valid flagstring for the Mail::MsgStore message ID, given
     either a msgid or english string (`'+read -list !flame'') to parse.
     Mostly for internal use.

AUTHOR
======

   v, <v@rant.scriptmania.com>

SEE ALSO
========

   perl(1), Sys::UniqueId, Mail::Internet, Mail::Folder,
Win32::TieRegistry, Net::LDAP, Net::POP3, Time::ParseDate


