#!/usr/local/bin/perl4

# BSMTP for qmail by Olaf Titz <olaf@bigred.inka.de>, Feb.97, public domain
# $Id: maildir2bsmtp,v 1.2 1997/02/09 00:47:21 olaf Exp $

# maildir2bsmtp [-h holdtime] [-s maxsize] dir prefix [command]
# take messages from maildir "dir", make BSMTP out of them
# Remove "prefix" prefix from every recipient address
# keep delivered messages in 'cur' subdir for "holdtime" seconds (0: forever)
# if "command" is given, pipe into this command
# if "maxsize" is given, start a new command when this size was exceeded

require "getopts.pl";
$opt_h=86400; # one day
&Getopts("h:s:");
umask(0077);
$ctl="/var/qmail/control";

$maildir=shift || &fatal('required "dir" parameter missing');
chdir $maildir || &fatal("cannot chdir to `$maildir'");
$prefix=shift  || &fatal('required "prefix" parameter missing');
$comm=shift;

opendir(D, "new") || &fatal("cannot read `new' subdir");
while ($_=readdir(D)) {
    /^[0-9]/ && push(@f, $_);
}
closedir(D);
if ($#f<0) {
    &cleanup(0);
}
@files=sort {$a<=>$b} @f; # this puts oldest message first

if (open(H, "$ctl/helohost") || open(H, "$ctl/me")) {
    $helo=<H>; close H;
}
$helo=~s/[^\040-\177].*$//;
$helo="UNKNOWN" unless $helo;

while ($#files>=0) {
    if ($comm) {
       open(STDOUT, "|$comm") || &fatal("cannot invoke `$comm'");
    }
    select STDOUT; $|=1;
    print "HELO $helo\n";
    $bsiz=0;
  File: while ($f=shift(@files)) {
      if (open(F, "new/$f")) {
         $_=<F>;
         if (!/^Return-Path:\s*\<([^>]*)\>/i) {
             &badmsg($f, "no/bad Return-Path line"); next;
         }
         $fr=$1;
         $_=<F>; chop;
         if (!/^Delivered-To:\s*(.*)$/i) {
             &badmsg($f, "no/bad Delivered-To line"); next;
         }
         $_=$1; s/^$prefix//o;
         print "MAIL FROM:<$fr>\nRCPT TO:<$_>\nDATA\n";
         while (<F>) {
             s/^\./../;
             print;
         };
         print ".\n";
         $bsiz+=(-s F);
         close F;
         if (!rename("new/$f", "cur/$f:batched")) {
             print STDERR "cannot move `$f', will re-deliver\n";
         }
         last File if ($opt_s && ($bsiz>$opt_s));
      } else {
         print STDERR "message `$f' vanished\n";
      }
  }
    print "QUIT\n";
}
&cleanup(0);
exit 0;

sub badmsg # filename, explanation
{
    local($f,$m)=@_;
    print STDERR "message `$f': $m\n";
    if (!rename("new/$f", "cur/$f:BAD")) {
       print STDERR "cannot move `$f' - something is wrong\n";
    }
}

sub cleandir # dirname, suffix, time
{
    local($d,$s,$t)=@_;
    if (!opendir(D, $d)) {
       print STDERR "cannot read `$d' subdir\n";
       return;
    }
    while ($_=readdir(D)) {
       next unless /^[0-9].*$s$/;
       if (@S=stat("$d/$_")) {
           unlink("$d/$_") if ($S[9]+$t<$^T);
       } else {
           print STDERR "cannot stat `$f'\n";
       }
    }
    closedir(D);
}

sub cleanup # exitstatus
{
    local($e)=@_;
    &cleandir("tmp", "", 129600); # 36h - maildir spec
    &cleandir("cur", ":batched", $opt_h) if ($opt_h);
    exit $e;
}

sub fatal # message
{
    local($_)=@_;
    print STDERR "$_\n";
    exit 111;
}
