home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


Book HomeJava and XSLTSearch this book

16.2. The Mail Modules

The Mail modules operate at a higher level than the Net modules, interacting with external mail packages such as mail, mailx, sendmail, or a POP3 server in the case of Net::POP3. This section describes some of the MailTools modules, Mail::Folder, and the other mail-related modules that were mentioned at the beginning of this chapter.

16.2.1. Send Email with Mail::Mailer

The Mail::Mailer module interacts with external mail programs. When you use Mail::Mailer or create a new Mail::Mailer object, you can specify which mail program you want your program to talk to:

use Mail::Mailer qw(mail);

Another way to specify the mailer is:

use Mail::Mailer;
$type = 'sendmail';
$mailprog = Mail::Mailer->new($type);

in which $type is the mail program. Once you've created a new object, use the open function to send the message headers to the mail program as a hash of key/value pairs, in which each key represents a header type, and the value is the value of that header:

# Mail headers to use in the message
%headers = (
    'To' => 'you@mail.somename.com',
    'From' => 'me@mail.somename.com',
    'Subject' => 'working?'
);

This code represents headers in which the recipient of the mail message is you@mail.somename.com, the mail was sent from me@mail.somename.com, and the subject of the mail message is working?.

Once %headers has been defined, it is passed to open:

$mailprog->open(\%headers);

You then send the body of the message to the mail program:

print $mailprog "This is the message body.\n";

Close the program when the message is finished:

$mailprog->close;

A practical example of using Mail::Mailer might be a command line-driven application that works much like the Unix mail program, either reading STDIN until end-of-file or mailing a file specified on the command line.

Mail::Mailer uses the environment variable PERL_MAILERS to augment or modify the built-in mailer selection. PERL_MAILERS is specified in the following format:

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

The possible types are listed for the new method below.

The following methods are defined in Mail::Mailer.

16.2.2. Better Header Control with Mail::Send

Mail::Send is built on top of Mail::Mailer, which means that you can also choose the mail program that sends the mail. Mail::Send has implemented the methods to, cc, bcc, and subject to replace the %headers hash used in Mail::Mailer.

Mail::Send uses the open method to open the mail program for output; it is built on Mail::Mailer's new method, so that:

# Start mailer and output headers
$fh = $msg->open('sendmail');

serves the same purpose as:

# Use sendmail for mailing
$mailer = Mail::Mailer->new('sendmail)';

This code tells Mail::Send to use sendmail as the mail program.

Mail::Send also provides the set and add functions, which assign a value to a header tag and append a value to a header tag, respectively. The set function takes two arguments—a header tag and a value—and is used like this:

$msg->set($scalar, @array);

Therefore, to address a message to you@mail.somename.com:

$msg->set('To', 'you@mail.somename.com');

The above sets the To header to you@mail.somename.com; however, the following sets the To header to postmaster@mail.somename.com and you@mail.somename.com because they represent an array of values:

$msg->set('To', ('you@mail.somename.com', 'postmaster@mail.somename.com'));

You might think that you could use the set function as follows to add multiple values to a header value:

$msg->set('To', 'you@mail.somename.com');
$msg->set('To', 'someone@their.mailaddress.com');

However, set doesn't append information from one call to another, and the above example would send the mail only to someone@their.mailaddress.com. To append a name to the To header, use the add method. For example:

$msg->add('To', 'you@mail.somename.com');
$msg->add('To', 'someone@their.mailaddress.com');

The following methods are defined for Mail::Send.

16.2.3. Handle Folders with Mail::Folder

Once you've begun downloading and reading your mail from a POP server, you might want to save or categorize your messages into folders, which allow you to add, delete, save, and move messages easily. You can do this with Mail::Folder, which was written by Kevin Johnson as an object-oriented, folder-independent interface to mail folders. Mail::Folder supports a number of mailbox formats with the following interfaces:

Mail::Folder::Emaul
A folder interface somewhat similar to MH.

Mail::Folder::Maildir
An interface to maildir folders.

Mail::Folder::Mbox
Standard Unix mailbox format.

Mail::Folder::NNTP
The beginnings of an interface to NNTP. Not all the methods are implemented yet.

If you are interested in writing a folder interface, see the documentation for the module. The documentation explains the concepts and issues involved and describes some of the methods you may need to override.

The following methods are defined for Mail::Folder.

16.2.5. Mail::Internet Reference

16.2.6. Parse Email Addresses with Mail::Address

Mail::Address parses RFC 822-compliant mail addresses of the form:

"Full Name or Phrase" <username@host> (Comment Area)

For example, under RFC 822, an address might be represented as:

"Nathan V. Patwardhan" <nvp@mail.somename.com> (No Comment)

or:

"Nathan V. Patwardhan" <nvp@mail.somename.com>

The Mail::Address constructor parses an email address into three parts based on the categories shown above:

$addr = Mail::Address->new("Full Name or Phrase",
                           "username@host",
                           "(Comment Area)");

Mail::Address also outputs portions of the mail address with the functions phrase, address, comment, format, name, host, and user. The phrase, address, and comment functions represent the first, second, and third entities that were passed to the Mail::Address constructor, in which the phrase function:

print $addr->phrase( );

outputs:

Nathan V. Patwardhan

the address function:

print $addr->address( );

outputs:

nvp@mail.somename.com

and the comment function:

print $addr->comment( );

outputs:

No Comment

A real mail address can be "unmangled," or parsed from its user@somehost.com format, with the user and host functions. The user function removes everything starting with the @ to the end of the address, and host removes everything up to and including the @. Using the previous example of nvp@mail.somename.com, the following line:

print $addr->user;

outputs:

nvp

And the following line using the host function:

print $addr->host;

outputs:

nvp@mail.somename.com

16.2.9. Mail Filtering with Mail::Audit

Mail::Audit is a mail-filtering system for those who want to write good filter rules but choose not to use procmail. It was written to provide flexibility while realizing the strengths of Perl's regular expression engine. Inspired by Tom Christiansen's audit_mail and deliverdb programs, Mail::Audit allows an email message to be logged, examined, routed to another folder or INBOX, resent, or rejected. You should be able to write a simple ruleset or rulesets and put references to it in your .forward file. For example:

use Mail::Audit;

my $m_au = Mail::Audit->new( );

$m_au->reject("Let me call YOU at home!")
    if $m_au =~ /(spammer\@spammer.com|spammer2\@spammer2.com|spammer3\@spammer3.com)/;

$m_au->accept("Majordomo") if $mail->from =~ /Majordomo\@/;

$m_au->accept( );

Mail::Audit implements the following methods.

new

new(%options)

Constructor. Reads a mail message from STDIN (or, if the data option is set, from an array reference) and creates a Mail::Audit object from it. Options include:

log=>logfile
Writes a debugging log.

loglevel=>n
Sets verbosity of the log on a scale of 1 to 4.

noexit=>1
Do not exit after delivering mail.

If you specify a log level without a log file, logging will be written to /tmp/username-audit.log, where username is replaced by your username.

body

body(  )

Returns a reference to an array of lines in the body of the email.

get

get(header)

Retrieves the named header from the mail message.

header

header(  )

Returns the header as a single string.

ignore

ignore(  )

Ignores an email message completely, dumping it into the bit bucket.

pipe

pipe(program)

Opens a pipe to an external program and feeds the message to it.

put

put(header, value)

Inserts a new header into the mail message with the given value.

reject

reject(message)

Rejects an email message, then notifies the sender that the message is undeliverable with message as the reason given.

resend

resend(address)

Bounces the email in its entirety to another address.

tidy

tidy(  )

Tidies up the email as per the Mail::Internet manpage.

xaccept

xaccept(filename)

Writes the incoming (and filtered) mail into a mailbox at filename. If filename is undefined, mail is written to /var/spool/mail/$USER. If you use Maildir instead of mbox-formatted mail, it will deliver the mail in Maildir style.

16.2.10. Alias Manipulation with Unix::AliasFile

While not a member of the Mail umbrella, Unix::AliasFile is an important module since it implements a complete interface to the Unix aliases text file that allows you to query, add, update, and delete aliases. In addition, it has a cleaner interface than Mail::Alias. Unix::AliasFile automatically handles file locking, comma and colon placement, and any other detail that's related to manipulating your Unix mail alias file. For example:

use Unix::AliasFile;

my $aliasfile = '/etc/mail/aliases';
my $uaf = Unix::AliasFile->new($aliasfile);

foreach my $alias $uaf->aliases( ) {
    chomp($alias);
    
    if($uaf->alias($alias) ne "$alias\@yourpopserver.your.domain") {
        # Doesn't exist, so add alias of the form:
        # alias: alias@yourpopserver.your.domain
        
        $uaf->alias($alias, ("$alias\@yourpopserver.your.domain"));
    } else {
        print "I already have $alias that way.\n";
    }
}

$uaf->commit( );
undef $uaf;

Unix::AliasFile implements the following methods.

new

new(filename)

Constructor. Creates a new Unix::AliasFile object.

add_user

add_user(alias, @users)

Adds @users to alias. If a user in @users already exists in alias, duplicates will be ignored. If alias is set to *, @users will be added to every alias.

alias

alias(alias, @users)

Adds, modifies, or returns information about an alias. When only alias is suppled, alias( ) returns a list of all members of an alias, or undef if alias does not exist. If you supply @users, alias will be modified or created if it doesn't already exist.

aliases

aliases(  )

Returns an alphabetized list of all existing aliases. In scalar context, this method returns the total number of aliases.

comment

comment(alias, comment)

Inserts a comment line before alias. comment must begin with #, but a newline will be appended to it. Returns 1 on success and 0 on failure.

commit

commit(  )

Writes the alias file.

delempty

delempty(  )

Deletes all existing aliases that have no members, returning a count of the number of aliases deleted.

delete

delete(alias)

Deletes alias.

remove_user

remove_user(alias, @users)

Removes the list of users from an existing alias. If a user in @usersisn't a member of alias, the removal attempt will be silently ignored. remove_user( ) returns 1 on success and 0 on failure.

rename_user

rename_user(oldname, newname)

Changes one username to another in every alias. Returns the number of aliases affected.

uncomment

uncomment(comment)

Removes the comment from the file that is exactly matched to the supplied text. Returns 1 on success and 0 on failure.



Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.