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.
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.
new |
$mailer = new Mail::Mailer [type, command]
Constructor. Creates a new Mailer object representing the message to be sent. If the optional arguments are specified, the value of commanddepends on type, which can be one of:
If no arguments are specified, the Mailer object searches for executables in the above order and uses the first one found as the default mailer.
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.
new |
$msg = new Mail::Send [header=>'value'[, ...]]
Constructor. Creates a new Mail::Send object that is the mail message you want to send. You can include values for headers when you create the object, or include them later by calling the appropriate methods.
add |
$msg->add(header, values)
Adds a header to the message. header is the header to be added, and values is a list of values to be appended to that header.
bcc |
$msg->bcc(values)
Adds a Bcc header containing the mail addresses specified in the list of values to the message. If there already is a Bcc, the new values replace any old values.
cc |
$msg->cc(values)
Adds a Cc header containing the mail addresses in the list of values to the message. If there already is a Cc, the new values replace any old values.
open |
$fh = $msg->open
Opens a filehandle for the message object. The filehandle is a Mail::Mailer object.
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:
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.
new |
$folder = new(ftype[, foldername][, options])
Creates a new Mail::Folder object of the specified type. Arguments are:
add_label |
$folder->add_label(msg_num, label)
Associates the label label with the message msg_num. Returns 1 on success or 0 if the label has a length of 0. Possible values of label are:
append_message |
$folder->append_message(\$mi_ref)
Adds message to a folder. Argument is a reference to a Mail::Internet object.
clear_label |
$folder->clear_label(label)
Deletes the association with label for all messages in the folder. Returns the number of messages for which there was an association.
current_message |
$folder->current_message([msg_num])
With no argument, returns the message number of the current message in the folder. With an argument, sets the current message number for the folder to msg_num.
debug |
$folder->debug([value])
Sets the level of debugging information for the object to value. With no argument, returns the current debugging level.
delete_label |
$folder->delete_label(msg_num, label)
Deletes the association of label with msg_num. Returns 1 on success and 0 if there was no association.
delete_message |
$folder->delete_message(msgs)
Takes a list of messages, msgs, to be marked for deletion. The messages aren't actually deleted until sync is called.
dup |
$folder->dup(msg_num, \$folder_ref)
Copies the message specified by msg_num to the folder referenced by \$folder_ref. Like refile, but doesn't delete the original message. Generates a fatal error if no folder is currently open or if the folder doesn't contain message msg_num.
first_labeled_message |
$folder->first_labeled_message(label)
Returns the message number of the first message in the folder that has label associated with it, or 0 if there are none.
get_fields |
$folder->get_fields(msg_num, fields)
Retrieves the fields specified in the list fields for message msg_num. If called in list context, returns a list; in scalar context, returns a reference to a list of the fields. Returns the fields in the same order as they were specified.
get_header |
$folder->get_header(msg_num)
Extracts a message header; takes one argument: the message number. Returns a reference to a Mail::Header object.
get_message |
$folder->get_message(msg_num)
Takes a message number as argument and returns a Mail::Internet object reference to that message, or 0 on failure.
get_message_file |
$folder->get_message_file(msg_num)
Like get_message, but returns a filename instead of a Mail::Internet object reference.
get_mime_header |
$folder->get_mime_header(msg_num)
Works much like get_header, but returns a reference to a MIME::Head object instead. Takes one argument, the message number.
get_mime_message |
$folder->get_mime_message (msg_num[, parserobject][, options])
Returns a MIME::Entity object for the specified message. Calls get_message_file to get a message to parse, creates a MIME::Parser object, and uses that to create the MIME::Entity object. The arguments are:
get_option |
$folder->get_option(option)
Returns the setting for the specified option, or undef if the option doesn't exist.
inverse_select |
$folder->inverse_select(\$func_ref)
Returns a list, in no specific order, of message numbers that do not match a set of criteria. The argument, \$func_ref, is a reference to a function used to determine the criteria. The function is passed a reference to a Mail::Internet object containing only a header.
is_readonly |
$folder->is_readonly
Returns 1 if the folder has the readonly attribute set; otherwise, returns 0.
label_exists |
$folder->label_exists(msg_num, label)
Returns 1 if label is associated with message msg_num; otherwise, returns 0.
last_labeled_message |
$folder->last_labeled_message(label)
Returns the message number of the last message in the folder with the label label associated with it, or 0 if there is no such message number.
list_all_labels |
$folder->list_all_labels
Returns a list, in no specific order, of all labels associated with messages in the folder. If called in scalar context, returns the number of labels associated with the messages.
list_labels |
$folder->list_labels(msg_num)
Returns a list, in no specific order, of all labels associated with msg_num. If called in scalar context, returns the number of labels associated with the message.
message_exists |
$folder->message_exists(msg_num)
Returns 1 if a message with the number msg_num exists in the folder; otherwise, returns 0.
message_list |
$folder->message_list
Returns a list of the message numbers in the folder, in no specific order. The syntax is:
print $folder->message_list."\n"
next_labeled_message |
$folder->next_labeled_message(msg_num, label)
Returns the message number of the next message in the folder relative to msg_number that has the label label associated with it, or 0 if there is no such message.
next_message |
$folder->next_message([msg_num])
Returns the number of the next message in the folder relative to msg_numif it is specified; otherwise, relative to the current message. Returns 0 if at end of folder.
open |
$folder->open(foldername)
If you didn't specify a folder name in the constructor, you need to call the open method, which takes the folder name as an argument and opens the folder. Also sets readonly if the folder is determined to be read-only.
pack |
$folder->pack
For formats that allow message number sequences to have gaps, renames the files in the folders to eliminate any such gaps. May result in renumbering some messages.
prev_labeled_message |
$folder->prev_labeled_message(msg_num, label)
Returns the message number of the previous message in the folder relative to msg_num that has the label label associated with it, or 0 if there is no such message.
prev_message |
$folder->prev_message([msg_num])
Returns the number of the previous message in the folder relative to msg_num if it is specified; otherwise, relative to the current message. Returns 0 if at the beginning of the folder.
qty |
$folder->qty
Returns the number of messages in the folder. The syntax is:
print "There are ".$folder->qty." messages in your folder\n";
refile |
$folder->refile(msg_num, \$fldr_ref)
Moves messages between folders. Takes a message number and folder reference as arguments.
select |
$folder->select(\$func_ref)
Returns a list of messages that meet a set of criteria. The argument, \$func_ref, is a reference to a function used to determine the criteria. The function is passed a reference to a Mail::Internet object containing only a header. The list is returned in no specific order.
select_label |
$folder->select_label(label)
Returns a list of messages with the label label. If called in scalar context, returns the number of messages that have the label.
set_readonly |
$folder->set_readonly
Sets the readonly attribute for the folder. Once readonly has been set, sync won't perform any updates to the actual folder.
sort |
$folder->sort(\$func_ref)
Returns a sorted list of messages. \$func_ref is a reference to a function that is passed two Mail::Header message references and returns an integer less than, equal to, or greater than 0 to indicate the sort order.
sync |
$folder->sync
Synchronizes the folder with internal data structures and reads in any new messages since the last open or sync. Does not perform any updates if the readonly attribute has been set.
undelete_message |
$folder->undelete_message(msgs)
Unmarks a list of messages, msgs, that have been marked for deletion.
Mail::Internet implements a number of helpful functions for manipulating a mail message. These include body, print_header, and head. Mail::Internet is built on top of Mail::Header, which parses the header of an email message, and it inherits the Mail::Header constructor style that requires that a file descriptor or reference to an array be used. For example:
@lines = <STDIN>; $mi_obj = new Mail::Internet([@lines]);
reads a mail message from STDIN (using a reference to an array). The following example reads a mail message from a filehandle, FILE:
open(FILE, "/home/nvp/Mail/nvp"); $mi_obj = new Mail::Internet(\*FILE); close(FILE);
The print_header function outputs the header of a message to a file descriptor; the default is STDOUT:
open(FILE, "/home/nvp/Mail/nvp"); $mi_obj = new Mail::Internet(\*FILE); close(FILE); $mi_obj->print_header(\*STDOUT);
The above example might output:
From nvp Mon Jun 9 00:11:10 1997 Received: (from nvp@localhost) by mail.somename.com (8.8/8.8) id AAA03248 for nvp; Mon, 9 Jun 1997 00:11:09 -0500 (EST) Date: Mon, 9 Jun 1997 00:11:09 -0500 (EST) From: "Nathan V. Patwardhan" <nvp> Message-Id: <199706090511.AAA03248@mail.somename.com> To: nvp Subject: pop test X-Status: X-Uid: 1 Status: RO
in which print_body also takes a file descriptor as an argument, but outputs only the body of the message, whereas the print function outputs an entire message.
new |
$mail = new Mail::Internet ([arg], [options])
Creates a new Mail::Internet object. arg is optional and may be either a file descriptor (a reference to a glob) or a reference to an array. If present, the new object is initialized with headers either from the array or read from the file descriptor. options is a list of options in the form of key/value pairs. Possible options are:
add_signature |
$mail->add_signature([file])
Appends a signature to the message. file is a file that contains the signature; if not specified, the file $ENV{HOME}/.signature is checked for a signature.
body |
$mail->body( )
Returns the body of the message as a reference to an array. Each entry in the array represents one line of the message.
escape_from |
$mail->escape_from( )
Inserts a leading > on any line that starts with "From " to avoid the problems that some applications have if a message contains a line starting with "From ".
head |
$headobj = $mail->head( )
Returns the Mail::Header object that holds the headers for the current message.
nntppost |
$mail->nntppost([options])
Posts an article via NNTP; requires Net::NNTP. Options are passed as key/value pairs. Available options are:
print_header |
$mail->print_header([\*fd]) $mail->print_body([\*fd]) $mail->print([\*fd]) |
Prints the header, body, or whole message to file descriptor \*fd, which should be a reference to a glob. If the file descriptor is not given, the output is sent to STDOUT:
$mail->print(\*STDOUT); # Print message to STDOUT
remove_sig |
$mail->remove_sig([nlines])
Removes a user's signature from the body of a message. Looks for a line equal to "-- " within the last nlines lines of the message and removes that line and all lines after it. nlinesdefaults to 10.
reply |
$reply = $mail->reply( )
Creates a new object with headers initialized for a reply to the current object and with a body that is an indented copy of the current message.
smtpsend |
$mail->smtpsend( )
Sends the Mail::Internet message via SMTP to all addresses on the To, Cc, and Bcc lines. Finds the SMTP host by trying to connect first to hosts specified in $ENV{SMTPHOSTS}, then to mailhost, and then to localhost.
In a future release of Mail::Internet, smtpsend will be able to take the hostname as a parameter, as nntppost does.
tidy_body |
$mail->tidy_body( )
Removes all leading and trailing lines that contain only whitespace from the message body.
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
new |
$addr = Mail::Address->new(phrase, address[, comment])
Constructor. Creates new Mail::Address object representing an address with the specified elements. In a message, these three elements show up as:
phrase <address> (comment) address (comment)
parse |
Mail::Address->parse(line)
Constructor. Parses the specified line, usually a To, Cc, or Bcc line, and returns a list of extracted Mail::Address objects.
format |
$addr->format( )
Returns a string representing the address in a form suitable for the To, Cc, or Bcc line of a message
name |
$addr->name( )
Takes information contained in the object and uses various heuristics to try to identify the name of the person or group.
Mail::RBL eases the task of checking if a given host is in the real-time blackhole list. Mail::RBL does this by speaking directly to the RBL server and searching for a specified host. Ordinarily, you build this functionality into your MTA (sendmail, qmail, Exim, etc.), but if your system administrator hasn't built RBL support into your MTA, you might consider integrating Mail::RBL into your own mail filter.
For example:
use Mail::RBL; my $host = q[some-spammer.domain.here]; my $rbl = Mail::RBL->new('list.org'); if($rbl->check($host)) { print "$host is in the RBL, and I won't deliver the mail." } else { # Do something to deliver the email }
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:
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.
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.
Copyright © 2002 O'Reilly & Associates. All rights reserved.