Dear qpsmtpd-list,
I try to add the (e)?smtproutes possibility of courier and qmail to
minimize the used servers in my setup.
http://www.courier-mta.org/courier.html
http://www.qmail.org/qmail-manual-html/man8/qmail-remote.html
http://wiki.qmailtoaster.com/index.php/Smtproutes
This is my first plugin for qpsmtpd so I hope we can come together to a
standard plugin.
attached the first hacked version.
Due to the fact that I haven't developed for ~4 Year with perl please
can you help me to fix the both TODO.
The first one is how to handle the 'domain => port' hash without a
while((...) = each ) loop
the second one is a design issue.
I would prefer to move the connection and the main loop
my $smtp = Net::SMTP->new(...)
for ($transaction->recipients) {
}
to a fuction whic will be called from the
for ($transaction->recipients) {
$self->{_smtp_server} = $self->{_smtproutes}->{$_->host()}
$self->{_smtp_server} = $self->{_smtproutes}->{''}
$self->send_or_quequ($trans =
$_,$self->{_smtp_server},$self->{_smtp_port});
}
but as I said I'am new to qpsmtpd and don't know how your policy is ;-)
The nicest step would be the plugins/async/queue/smtp-forward-smtproutes
but this could be the second step.
Your comments are desired.
BR
Aleks
>From 3ab1535ec000dd696a6231b1e87fb90595b903f8 Mon Sep 17 00:00:00 2001
From: root <r...@excalibur.bitrace.net>
Date: Wed, 15 Jul 2009 22:48:16 +0200
Subject: [PATCH] add the possibility to deliver the mail per domain based to
the destionation server
http://wiki.qmailtoaster.com/index.php/Smtproutes or
http://www.courier-mta.org/courier.html
---
plugins/queue/smtp-forward-smtproutes | 98 +++++++++++++++++++++++++++++++++
1 files changed, 98 insertions(+), 0 deletions(-)
create mode 100644 plugins/queue/smtp-forward-smtproutes
diff --git a/plugins/queue/smtp-forward-smtproutes
b/plugins/queue/smtp-forward-smtproutes
new file mode 100644
index 0000000..7f2eb49
--- /dev/null
+++ b/plugins/queue/smtp-forward-smtproutes
@@ -0,0 +1,98 @@
+=head1 NAME
+
+smtp-forward-smtproutes
+
+=head1 DESCRIPTION
+
+This plugin forwards the mail via SMTP to a specified server based on
destination domain, rather than
+delivering the email locally.
+
+=head1 CONFIG
+
+It takes one required parameter, the smtproutes file.
+
+ queue/smtp-forward smtproutes_file=smtproutes
+
+=cut
+
+use Net::SMTP;
+
+sub init {
+ my ($self, $qp, @args) = @_;
+
+ $self->{_smtp_port} = 25;
+
+ if (@args > 0) {
+ if ($args[0] =~ /^smtproutes_file=(\w+)$/) {
+ my $domain='';
+ my $target='';
+ my $target_port='';
+
+ $self->{_smtproutes_file} = $1;
+ $self->log(LOGDEBUG, "will use
smtp_routes_file=$self->{_smtproutes_file}");
+ my @smtproutes = $self->qp->config("smtproutes") or return (DECLINED);
+
+ for ( @smtproutes ){
+ $_ =~ /^([\.\w\-]*):([\.\w\-]*)(?::(\d+))?$/o;
+ ($domain,$target) = ($1,$2);
+
+ # TODO: how to solve a different remote port
+ # $target_port = $3 if defined $3;
+ # $self->{_smtproutes}->{$domain} = $target $target_port if defined
$target_port;
+
+ $self->{_smtproutes}->{$domain} = $target;
+ $self->log(LOGDEBUG, "will use $target for $domain");
+ }
+ pop @args;
+ }
+
+ if (defined $args[0] && ( $args[0] =~ /^([\.\w_-]+)$/)) {
+ $self->{_smtp_server} = $1;
+ }
+ else {
+ die "Bad data in smtp server: $args[0]" if ! exists
$self->{_smtproutes_file};
+ }
+ if (@args > 1 and $args[1] =~ /^(\d+)$/) {
+ $self->{_smtp_port} = $1;
+ }
+ $self->log(LOGWARN, "WARNING: Ignoring additional arguments.") if (@args >
2);
+ } else {
+ die("No SMTP server specified in smtp-forward config");
+ }
+
+}
+
+sub hook_queue {
+ my ($self, $transaction) = @_;
+
+ if ( exists $self->{_smtproutes}) {
+ # TODO: handle this in a real setup! the connect Net::SMTP->new (...) bust
be handled in this loop
+ for ($transaction->recipients) {
+ $self->{_smtp_server} = $self->{_smtproutes}->{$_->host()} if exists
$self->{_smtproutes}->{$_->host()};
+ $self->{_smtp_server} = $self->{_smtproutes}->{''} if ! exists
$self->{_smtproutes}->{$_->host()};
+ $self->log(LOGDEBUG, "forwarding to
$self->{_smtp_server}:$self->{_smtp_port}");
+ }
+ }
+
+ $self->log(LOGINFO, "forwarding to
$self->{_smtp_server}:$self->{_smtp_port}");
+ my $smtp = Net::SMTP->new(
+ $self->{_smtp_server},
+ Port => $self->{_smtp_port},
+ Timeout => 60,
+ Hello => $self->qp->config("me"),
+ ) || die $!;
+ $smtp->mail( $transaction->sender->address || "" ) or return(DECLINED,
"Unable to queue message ($!)");
+ for ($transaction->recipients) {
+ $smtp->to($_->address) or return(DECLINED, "Unable to queue message ($!)");
+ }
+ $smtp->data() or return(DECLINED, "Unable to queue message ($!)");
+ $smtp->datasend($transaction->header->as_string) or return(DECLINED, "Unable
to queue message ($!)");
+ $transaction->body_resetpos;
+ while (my $line = $transaction->body_getline) {
+ $smtp->datasend($line) or return(DECLINED, "Unable to queue message ($!)");
+ }
+ $smtp->dataend() or return(DECLINED, "Unable to queue message ($!)");
+ $smtp->quit() or return(DECLINED, "Unable to queue message ($!)");
+ $self->log(LOGINFO, "finished queueing");
+ return (OK, "Queued!");
+}
--
1.5.4.3