The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Sendmail::Queue - Manipulate Sendmail queues directly

SYNOPSIS

    use Sendmail::Queue;

    # The high-level interface:
    #
    # Create a new queue object.  Throws exception on error.
    my $q = Sendmail::Queue->new({
        queue_directory => '/var/spool/mqueue'
    });

    # Queue one copy of a message (one qf, one df)
    my $id = $q->queue_message({
        sender     => 'user@example.com',
        recipients => [
                'first@example.net',
                'second@example.org',
        ],
        data       => $string_or_object,
    });

    # Queue multiple copies of a message using multiple envelopes, but
    # the same body.  Results contain the envelope name as key,
    # and the queue ID as the value.
    my %results = $q->queue_multiple({
        sender         => 'user@example.com',
        envelopes => {
                'envelope one' => {
                        sender     => 'differentuser@example.com',
                        recipients => [
                                'first@example.net',
                                'second@example.org',
                        ],
                },
                'envelope two' => {
                        recipients => [
                                'third@example.net',
                                'fourth@example.org',
                        ],
                }
        },
        data           => $string_or_object,
    });

    # The low-level interface:

    # Create a new qf file object
    my $qf = Sendmail::Queue::Qf->new();

    # Generate a Sendmail 8.12-compatible queue ID
    $qf->create_and_lock();

    my $df = Sendmail::Queue::Df->new();

    # Need to give it the same queue ID as your $qf
    $df->set_queue_id( $qf->get_queue_id );
    $df->set_data( $some_body );

    # Or....
    $df->set_data_from( $some_fh );

    # Or, if you already have a file...
    my $second_df = Sendmail::Queue::Df->new();
    $second_df->set_queue_id( $qf->get_queue_id );
    $second_df->hardlink_to( $df ); # Need better name

    $qf->set_sender('me@example.com');
    $qf->add_recipient('you@example.org');

    $q->enqueue( $qf, $df );

DESCRIPTION

Sendmail::Queue provides a mechanism for directly manipulating Sendmail queue files.

METHODS

new ( \%args )

Create a new Sendmail::Queue object.

Required arguments are:

queue_directory

The queue directory to use. Should (usually) be the same as your Sendmail QueueDirectory variable for the client submission queue.

queue_message ( $args )

High-level interface for queueing a message. Creates qf and df files in the object's queue directory using the arguments provided.

Returns the queue ID for the queued message.

Required arguments:

sender

Envelope sender for message.

recipients

Array ref containing one or more recipients for this message.

data

Scalar containing message headers and body, in RFC-2822 format (ASCII text, headers separated from body by \n\n).

Data should use local line-ending conventions (as used by Sendmail) and not the \r\n used on the wire for SMTP.

Optional arguments may be specified as well. These will be handed off directly to the underlying Sendmail::Queue::Qf object:

product_name

Name to use for this product in the generated Recieved: header. May be set to blank or undef to disable. Defaults to 'Sendmail::Queue'.

helo

The HELO or EHLO name provided by the host that sent us this message, or undef if none. Defaults to undef.

relay_address

The IP address of the host that sent us this message, or undef if none. Defaults to undef.

relay_hostname

The name of the host that sent us this message, or undef if none. Defaults to undef.

local_hostname

The name of the host that received this message. Defaults to 'localhost'

protocol

Protocol over which this message was received. Valid values are blank, SMTP, and ESMTP. Default is blank.

timestamp

A UNIX seconds-since-epoch timestamp. If omitted, defaults to current time.

macros

A hash reference containing Sendmail macros that should be set in the resulting queue file.

The names of macros should be the bare name, as the module will add the leading $ and any surrounding {} necessary for multi-character macro names.

If omitted, the '$r' macro will be set to the 'protocol' value. Other macros will not be set by default.

On error, this method may die() with a number of different runtime errors.

enqueue ( $qf, $df )

Enqueue a message, given a Sendmail::Queue::Qf object and a Sendmail::Queue::Df object.

This method is mostly for internal use. You should probably use queue_message() or queue_multiple() instead.

Returns true if queuing was successful. Otherwise, cleans up any qf and df data that may have been written to disk, and rethrows any exception that may have occurred.

Here are the file ops (from inotify) on a /usr/sbin/sendmail enqueuing:

/var/spool/mqueue-client/ CREATE dfo2JEQb7J002161 /var/spool/mqueue-client/ OPEN dfo2JEQb7J002161 /var/spool/mqueue-client/ MODIFY dfo2JEQb7J002161 /var/spool/mqueue-client/ CLOSE_WRITE,CLOSE dfo2JEQb7J002161 /var/spool/mqueue-client/ OPEN dfo2JEQb7J002161 /var/spool/mqueue-client/ CREATE qfo2JEQb7J002161 /var/spool/mqueue-client/ OPEN qfo2JEQb7J002161 /var/spool/mqueue-client/ MODIFY qfo2JEQb7J002161 /var/spool/mqueue-client/ CREATE tfo2JEQb7J002161 /var/spool/mqueue-client/ OPEN tfo2JEQb7J002161 /var/spool/mqueue-client/ MODIFY tfo2JEQb7J002161 /var/spool/mqueue-client/ MOVED_FROM tfo2JEQb7J002161 /var/spool/mqueue-client/ MOVED_TO qfo2JEQb7J002161 /var/spool/mqueue-client/ OPEN,ISDIR /var/spool/mqueue-client/ CLOSE_NOWRITE,CLOSE,ISDIR /var/spool/mqueue-client/ CLOSE_WRITE,CLOSE qfo2JEQb7J002161 /var/spool/mqueue-client/ CLOSE_NOWRITE,CLOSE dfo2JEQb7J002161

queue_multiple ( $args )

Queue multiple copies of a message using multiple envelopes, but the same body.

Returns a results hash containing the recipient set name as key, and the queue ID as the value.

    my %results = $q->queue_multiple({
        envelopes => {
                'envelope one' => {
                        sender     => 'user@example.com',
                        recipients => [
                                'first@example.net',
                                'second@example.org',
                        ],
                }
                'envelope two' => {
                        sender     => 'user@example.com',
                        recipients => [
                                'third@example.net',
                                'fourth@example.org',
                        ],
                }
        },
        data           => $string_or_object,
    });

In the event that we cannot create a queue file for ANY of the envelopes, we die() with an appropriate error after unlinking all created queue files -- either all succeed, or none succeed.

sync ( )

Ensure that the queue directories have been synced.

DEPENDENCIES

Core Perl Modules

Carp, File::Spec, IO::Handle, Fcntl

Other Modules

Sendmail::Queue::Qf, Sendmail::Queue::Df

INCOMPATIBILITIES

There are no known incompatibilities with this module.

BUGS AND LIMITATIONS

There are no known bugs in this module. However, it messes with undocumented bits of Sendmail. YMMV.

Please report problems to the author. Patches are welcome.

AUTHOR

Dave O'Neill, <support at roaringpenguin.com>

LICENCE AND COPYRIGHT

Copyright (c) 2007 Roaring Penguin Software, Inc. All rights reserved.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.