# # This file is best read with ``perldoc advanced.pod'' # ### # Conventions: # plugin names: F, F # constants: I # smtp commands, answers: B, B<250 Queued!> # # Notes: # * due to restrictions of some POD parsers, no C<<$object->method()>> # are allowed, use C<$object-Emethod()> # =head1 Advanced Playground =head2 Discarding messages If you want to make the client think a message has been regularily accepted, but in real you delete it or send it to F, ..., use something like the following plugin and load it before your default queue plugin. sub hook_queue { my ($self, $transaction) = @_; if ($transaction->notes('discard_mail')) { my $msg_id = $transaction->header->get('Message-Id') || ''; $msg_id =~ s/[\r\n].*//s; return(OK, "Queued! $msg_id"); } return(DECLINED); } =head2 Changing return values This is an example how to use the C method. The B plugin wraps the B plugin. The B plugin checks the F and F config files for domains, which we accept mail for. If not found it tells the client that relaying is not allowed. Clients which are marked as C are excluded from this rule. This plugin counts the number of unsuccessfull relaying attempts and drops the connection if too many were made. The optional parameter I configures this plugin to drop the connection after I unsuccessful relaying attempts. Set to C<0> to disable, default is C<5>. Note: Do not load both (B and B). This plugin should be configured to run I, like B. use Qpsmtpd::DSN; sub init { my ($self, $qp, @args) = @_; die "too many arguments" if @args > 1; $self->{_count_relay_max} = defined $args[0] ? $args[0] : 5; $self->isa_plugin("rcpt_ok"); } sub hook_rcpt { my ($self, $transaction, $recipient) = @_; my ($rc, @msg) = $self->SUPER::hook_rcpt($transaction, $recipient); return ($rc, @msg) unless (($rc == DENY) and $self->{_count_relay_max}); my $count = ($self->qp->connection->notes('count_relay_attempts') || 0) + 1; $self->qp->connection->notes('count_relay_attempts', $count); return ($rc, @msg) unless ($count > $self->{_count_relay_max}); return Qpsmtpd::DSN->relaying_denied(DENY_DISCONNECT, "Too many relaying attempts"); } =head2 Results of other hooks B just copied from README.plugins If we're in a transaction, the results of a callback are stored in $self->transaction->notes( $code->{name})->{"hook_$hook"}->{return} If we're in a connection, store things in the connection notes instead. B: does the above (regarding connection notes) work? =cut # vim: ts=2 sw=2 expandtab