Thanks for your response,

So I should develop a script that read headers and then deliver to the correct mailbox. Then I should place a line like :

email-address : "| script-to-deliver-to-the-correct-mailbox.sh"

in /etc/aliases ? Should I add some header when I deliver to a maildir ? Can I just copy the content to a file in Maildir/tmp/ and then invoke a move to new ?

I'm agree with your remarks, but I still have some question about my plugin :

I have implemented the plugin I want, could somebody make some remarks about my ugly code (It's my first qpsmtpd plug and the beginning of my perl experience).

I have tested the plug it works great and fast. We have about 10000 mails in the mailbox and the plugin does not search more than 1 sec when I look at the log. We have (for the moment) a average of 1 mail by hour. I like the way qpsmtpd handle error in my plug (it just deliver with next queue plugin) the mail is still deliver to another mailbox.

Here is the code of my plugin, it is based on queue/maildir :


use File::Path qw(mkpath);
use Sys::Hostname qw(hostname);
use Time::HiRes qw(gettimeofday);
use File::Find;

sub register {
  my ($self, $qp, @args) = @_;

  my $hostname = (hostname =~ m/([\w\._\-]+)/)[0];
  $self->{_hostname} = $hostname;

}

my $maildir_counter = 0;

sub hook_queue {
  my ($self, $transaction) = @_;


  # search the message id in In-Reply-To header or References header
  # if there is no In-Reply-To header $message_id get the value of
  # References header
my $message_id = $transaction->header->get('In-Reply-To') || $transaction->header->get('References');

  my $maildir;

  my @array;

  # "/home/nicoMaildir" should be passed as argument to the plug ...
find({ wanted => sub { push @array, $File::Find::name }, untaint => 1 }, ("/home/nico/Maildir"));

  $self->log(LOGWARN,"searching message id : $message_id");

  for (@array) {

      my $cur = $_;

      #$self->log(LOGWARN,"$cur");

      if (-f){
          open (INPUT, $_) || die "can't open $_: $!";
          while (<INPUT>) {
              if(m/^(m|M)(essage|ESSAGE)-(id|Id|ID): $message_id/){
                  # Email found
                  $self->log(LOGWARN,"Mail trouvé : $cur");
                  $maildir = $cur;
                  goto outside;
              } else {
# stop searching if we are at the end of headers (empty line)
                  if(m/^$/){
                      goto break;
                  }
              }
          }
        break:
          close INPUT;
      }


  }

$self->log(LOGWARN,"Cannot find a mail correspopnding to $message_id") and return(DECLINED,"Not for a paricular user, new discussion ?");

 outside:

  $maildir =~ /(\/home\/(\w*)\/Maildir).*/;
  $maildir = $1;

  $self->log(LOGWARN,"maildir found : $maildir");

  # after this point, this is the initial code of maildir

  my ($time, $microseconds) = gettimeofday;

  $time = ($time =~ m/(\d+)/)[0];
  $microseconds =~ s/\D//g;

  my $unique  = "P$$" . "M$microseconds" . "Q" . $maildir_counter++;
  my $file    = join ".", $time, $unique, $self->{_hostname};

  # TODO: deliver the mail once per recipient instead
  $transaction->header->add('Delivered-To', $_->address, 0)
    for $transaction->recipients;

  open (MF, ">$maildir/tmp/$file") or
    $self->log(LOGWARN, "could not open $maildir/tmp/$file: $!"),
    return(DECLINED, "queue error (open)");

  $transaction->header->print(\*MF);
  $transaction->body_resetpos;
  while (my $line = $transaction->body_getline) {
    print MF $line;
  }

  close MF or
    $self->log(LOGWARN, "could not close $maildir/tmp/$file: $!")
    and return(DECLINED, "queue error (close)");

  link "$maildir/tmp/$file", "$maildir/new/$file" or
$self->log(LOGWARN, "could not link $maildir/tmp/$file to $maildir/new/$file: $!")
    and return(DECLINED, "queue error (link)");

  unlink "$maildir/tmp/$file";

  my $msg_id = $transaction->header->get('Message-Id') || '';
  $msg_id =~ s/[\r\n].*//s;

  return (OK, "Queued! $msg_id");
}

Thanks again to all !

PS : Is there a date for new stable version of qpsmtpd ?

Julien.


Quoting John Peacock <[EMAIL PROTECTED]>:

[EMAIL PROTECTED] wrote:
I have multiple maildir mailbox, I want to deliver new mail in the mailbox containing the previous message (reply, thread, ...).

I strongly recommend against implementing this in a qpsmtpd delivery
plugin.  Normally, you want delivery to do as little work as possible
so that you can return success to the sending MTA.  If you spend a lot
of time groveling through the folders looking for possible matches, you
may take too long and the remote MTA will time out, and retry, and time
out, and retry...

I am certain that there are procmail recipes that would do something
like this.  You are much better off doing this asynchronous with the
SMTP session...

John


Reply via email to