move the queue code to a plugin; document the queue plugin hook.
git-svn-id: https://svn.perl.org/qpsmtpd/trunk@80 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
parent
9c38313d06
commit
253eeee879
@ -84,6 +84,17 @@ Hook after receiving all data; just before the message is queued.
|
|||||||
|
|
||||||
All other codes and the message will be queued normally
|
All other codes and the message will be queued normally
|
||||||
|
|
||||||
|
=head2 queue
|
||||||
|
|
||||||
|
Called on completion of the DATA command.
|
||||||
|
|
||||||
|
DONE - skip further processing (plugin gave response code)
|
||||||
|
OK - Return success message
|
||||||
|
DENY - Return hard failure code
|
||||||
|
DENYSOFT - Return soft failure code
|
||||||
|
|
||||||
|
Any other code will return a soft failure code.
|
||||||
|
|
||||||
|
|
||||||
=head2 connect
|
=head2 connect
|
||||||
|
|
||||||
@ -93,6 +104,7 @@ Allowed return codes:
|
|||||||
DECLINED - Process the next plugin
|
DECLINED - Process the next plugin
|
||||||
DONE - Stop processing plugins and don't give the default response
|
DONE - Stop processing plugins and don't give the default response
|
||||||
|
|
||||||
|
|
||||||
=head2 quit
|
=head2 quit
|
||||||
|
|
||||||
Called on the "quit" command.
|
Called on the "quit" command.
|
||||||
|
@ -8,7 +8,9 @@ check_badrcptto
|
|||||||
# this plugin needs to run after all other "rcpt" plugins
|
# this plugin needs to run after all other "rcpt" plugins
|
||||||
check_relay
|
check_relay
|
||||||
|
|
||||||
|
# content filters
|
||||||
klez_filter
|
klez_filter
|
||||||
|
spamassassin
|
||||||
|
|
||||||
|
queue/qmail-queue
|
||||||
|
|
||||||
spamassassin
|
|
@ -300,6 +300,8 @@ sub data {
|
|||||||
# way a Received: line that is already in the header.
|
# way a Received: line that is already in the header.
|
||||||
|
|
||||||
$header->extract(\@header);
|
$header->extract(\@header);
|
||||||
|
$header->add("X-SMTPD", "qpsmtpd/".$self->version.", http://develooper.com/code/qpsmtpd/");
|
||||||
|
|
||||||
$buffer = "";
|
$buffer = "";
|
||||||
|
|
||||||
# FIXME - call plugins to work on just the header here; can
|
# FIXME - call plugins to work on just the header here; can
|
||||||
@ -360,55 +362,23 @@ sub data {
|
|||||||
sub queue {
|
sub queue {
|
||||||
my ($self, $transaction) = @_;
|
my ($self, $transaction) = @_;
|
||||||
|
|
||||||
# these bits inspired by Peter Samuels "qmail-queue wrapper"
|
my ($rc, $msg) = $self->run_hooks("queue");
|
||||||
pipe(MESSAGE_READER, MESSAGE_WRITER) or fault("Could not create message pipe"), exit;
|
if ($rc == DONE) {
|
||||||
pipe(ENVELOPE_READER, ENVELOPE_WRITER) or fault("Could not create envelope pipe"), exit;
|
return 1;
|
||||||
|
|
||||||
my $child = fork();
|
|
||||||
|
|
||||||
not defined $child and fault(451, "Could not fork"), exit;
|
|
||||||
|
|
||||||
if ($child) {
|
|
||||||
# Parent
|
|
||||||
my $oldfh = select(MESSAGE_WRITER); $| = 1;
|
|
||||||
select(ENVELOPE_WRITER); $| = 1;
|
|
||||||
select($oldfh);
|
|
||||||
|
|
||||||
close MESSAGE_READER or fault("close msg reader fault"),exit;
|
|
||||||
close ENVELOPE_READER or fault("close envelope reader fault"), exit;
|
|
||||||
|
|
||||||
$transaction->header->add("X-SMTPD", "qpsmtpd/".$self->version.", http://develooper.com/code/qpsmtpd/");
|
|
||||||
|
|
||||||
$transaction->header->print(\*MESSAGE_WRITER);
|
|
||||||
$transaction->body_resetpos;
|
|
||||||
while (my $line = $transaction->body_getline) {
|
|
||||||
print MESSAGE_WRITER $line;
|
|
||||||
}
|
|
||||||
close MESSAGE_WRITER;
|
|
||||||
|
|
||||||
my @rcpt = map { "T" . $_->address } $transaction->recipients;
|
|
||||||
my $from = "F".($transaction->sender->address|| "" );
|
|
||||||
print ENVELOPE_WRITER "$from\0", join("\0",@rcpt), "\0\0"
|
|
||||||
or respond(451,"Could not print addresses to queue"),exit;
|
|
||||||
|
|
||||||
close ENVELOPE_WRITER;
|
|
||||||
waitpid($child, 0);
|
|
||||||
my $exit_code = $? >> 8;
|
|
||||||
$exit_code and respond(451, "Unable to queue message ($exit_code)"), exit;
|
|
||||||
$self->respond(250, "Queued.");
|
|
||||||
}
|
}
|
||||||
elsif (defined $child) {
|
elsif ($rc == OK) {
|
||||||
# Child
|
$self->respond(250, ($msg || 'Queued'));
|
||||||
close MESSAGE_WRITER or die "could not close message writer in parent";
|
|
||||||
close ENVELOPE_WRITER or die "could not close envelope writer in parent";
|
|
||||||
|
|
||||||
open(STDIN, "<&MESSAGE_READER") or die "b1";
|
|
||||||
open(STDOUT, "<&ENVELOPE_READER") or die "b2";
|
|
||||||
|
|
||||||
unless (exec '/var/qmail/bin/qmail-queue') {
|
|
||||||
die "should never be here!";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
elsif ($rc == DENY) {
|
||||||
|
$self->respond(552, $msg || "Message denied");
|
||||||
|
}
|
||||||
|
elsif ($rc == DENYSOFT) {
|
||||||
|
$self->respond(452, $msg || "Message denied temporarily");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->respond(451, $msg || "Queuing declined or disabled; try again later" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
57
plugins/queue/qmail-queue
Normal file
57
plugins/queue/qmail-queue
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
|
||||||
|
sub register {
|
||||||
|
my ($self, $qp) = @_;
|
||||||
|
$self->register_hook("queue", "queue_handler");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub queue_handler {
|
||||||
|
my ($self, $transaction) = @_;
|
||||||
|
|
||||||
|
# these bits inspired by Peter Samuels "qmail-queue wrapper"
|
||||||
|
pipe(MESSAGE_READER, MESSAGE_WRITER) or fault("Could not create message pipe"), exit;
|
||||||
|
pipe(ENVELOPE_READER, ENVELOPE_WRITER) or fault("Could not create envelope pipe"), exit;
|
||||||
|
|
||||||
|
my $child = fork();
|
||||||
|
|
||||||
|
not defined $child and fault(451, "Could not fork"), exit;
|
||||||
|
|
||||||
|
if ($child) {
|
||||||
|
# Parent
|
||||||
|
my $oldfh = select(MESSAGE_WRITER); $| = 1;
|
||||||
|
select(ENVELOPE_WRITER); $| = 1;
|
||||||
|
select($oldfh);
|
||||||
|
|
||||||
|
close MESSAGE_READER or fault("close msg reader fault"),exit;
|
||||||
|
close ENVELOPE_READER or fault("close envelope reader fault"), exit;
|
||||||
|
|
||||||
|
$transaction->header->print(\*MESSAGE_WRITER);
|
||||||
|
$transaction->body_resetpos;
|
||||||
|
while (my $line = $transaction->body_getline) {
|
||||||
|
print MESSAGE_WRITER $line;
|
||||||
|
}
|
||||||
|
close MESSAGE_WRITER;
|
||||||
|
|
||||||
|
my @rcpt = map { "T" . $_->address } $transaction->recipients;
|
||||||
|
my $from = "F".($transaction->sender->address|| "" );
|
||||||
|
print ENVELOPE_WRITER "$from\0", join("\0",@rcpt), "\0\0"
|
||||||
|
or return(DECLINED,"Could not print addresses to queue");
|
||||||
|
|
||||||
|
close ENVELOPE_WRITER;
|
||||||
|
waitpid($child, 0);
|
||||||
|
my $exit_code = $? >> 8;
|
||||||
|
$exit_code and return(DECLINED, "Unable to queue message ($exit_code)");
|
||||||
|
return (OK, "Queued!");
|
||||||
|
}
|
||||||
|
elsif (defined $child) {
|
||||||
|
# Child
|
||||||
|
close MESSAGE_WRITER or die "could not close message writer in parent";
|
||||||
|
close ENVELOPE_WRITER or die "could not close envelope writer in parent";
|
||||||
|
|
||||||
|
open(STDIN, "<&MESSAGE_READER") or die "b1";
|
||||||
|
open(STDOUT, "<&ENVELOPE_READER") or die "b2";
|
||||||
|
|
||||||
|
unless (exec '/var/qmail/bin/qmail-queue') {
|
||||||
|
return (DECLINED, "fatal error spawning qmail-queue");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user