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

Reply via email to