#!/usr/pkg/bin/perl
#
# $Id: ftninpost.pl,v 4.9 1998/09/23 19:23:14 mj Exp $
#
# Postprocessor for ftnin, feeds output of ftn2rfc to rnews and sendmail.
# Call via ftnin's -x option or run after ftn2rfc. Replaces old fidorun
# script.
#
 
require 5.000;

my $PROGRAM = "ftninpost";
 
use strict;
use vars qw($opt_v $opt_c);
use Getopt::Std;
use FileHandle;

##############################################################################
#
# $Id: config.pl,v 4.4 2001/01/04 20:03:42 mj Exp $
#
# Perl functions to read FIDOGATE config file,
# included by <INCLUDE config.pl> when running subst.pl
#

my %CONFIG;

# specials for DosDrive and Zone
my %CONFIG_dosdrive;
my %CONFIG_zone;



my %CONFIG_default =
    (
##Automatically generated by subst.pl, DO NOT EDIT!!!##
	"outpkt_mail", "%S/outpkt/mail",
	"outrfc_mail", "%S/outrfc/mail",
	"lockdir", "/var/spool/fido/lock",
	"config_main", "%C/fidogate.conf",
	"seq_split", "%V/seq/split",
	"libdir", "/usr/pkg/lib/fidogate",
	"outpkt_news", "%S/outpkt/news",
	"outrfc_news", "%S/outrfc/news",
	"routing", "%C/routing",
	"config_gate", "%C/fidogate.conf",
	"logdir", "/var/log/fido",
	"seq_pkt", "%V/seq/pkt",
	"passwd", "%C/passwd",
	"config_ffx", "%C/fidogate.conf",
	"logfile", "%G/log",
	"tick_hold", "%B/tick",
	"pinbound", "/var/spool/bt/pin",
	"newsetcdir", "/var/news/etc",
	"toss_bad", "%S/toss/bad",
	"newsvardir", "/var/news",
	"bindir", "/usr/pkg/lib/fidogate/bin",
	"seq_news", "%V/seq/news",
	"ftpinbound", "/var/spool/bt/ftpin",
	"seq_ff", "%V/seq/ff",
	"uuinbound", "/var/spool/bt/uuin",
	"newslibdir", "/usr/pkg/inn/lib",
	"vardir", "/var/spool/fido",
	"seq_toss", "%V/seq/toss",
	"areas", "%C/areas",
	"btbasedir", "/var/spool/bt",
	"charsetmap", "%L/charset.bin",
	"seq_tick", "%V/seq/tick",
	"seq_mail", "%V/seq/mail",
	"seq_msgid", "%V/seq/msgid",
	"lock_history", "history",
	"packing", "%C/packing",
	"newsspooldir", "/var/news/spool/articles",
	"toss_route", "%S/toss/route",
	"spooldir", "/var/spool/fido",
	"configdir", "/usr/pkg/etc/fidogate",
	"aliases", "%C/aliases",
	"history", "%V/history",
	"acl", "%C/acl",
	"ifmaildir", "/usr/pkg/sbin",
	"seq_pack", "%V/seq/pack",
	"outpkt", "%S/outpkt",
	"hosts", "%C/hosts",
	"toss_toss", "%S/toss/toss",
	"inbound", "/var/spool/bt/in",
	"toss_pack", "%S/toss/pack",
     );
my %CONFIG_abbrev =
    (
##Automatically generated by subst.pl, DO NOT EDIT!!!##
	"U", "uuinbound",
	"B", "btbasedir",
	"I", "inbound",
	"L", "libdir",
	"N", "bindir",
	"G", "logdir",
	"S", "spooldir",
	"C", "configdir",
	"P", "pinbound",
	"V", "vardir",
	"K", "lockdir",
     );



sub CONFIG_read {
    my($file) = @_;
    my($key, $arg);
    local *C;

    $file = CONFIG_expand($file);

    open(C,"$file") || die "config.pl: can't open config file $file\n";
    while(<C>) {
	chop;
	next if( /^\s*\#/ );	# comments
	next if( /^\s*$/  );	# empty
	s/\s*$//;		# remove trailing white space
	s/^\s*//;		# remove leading white space
	($key,$arg) = split(' ', $_, 2);
	$key =~ tr/A-Z/a-z/;
	if($key eq "include") {
	    CONFIG_read($arg);
	    next;
	}
	if($key eq "dosdrive") {
	    my ($d, $path) = split(' ', $arg);
	    $CONFIG_dosdrive{lc($d)} = $path;
	    next;
	}
	if($key eq "zone") {
	    my ($z, $rest) = split(' ', $arg, 2);
	    $CONFIG_zone{$z} = $rest;
	    next;
	}
	$CONFIG{$key} = $arg if(!$CONFIG{$key});
    }
    close(C);
}


sub CONFIG_get1 {
    my($key) = @_;
    my($ukey);

    $ukey = $key;
    $ukey =~ tr/a-z/A-Z/;
    return $ENV{"FIDOGATE_$ukey"} if($ENV{"FIDOGATE_$ukey"});

    return $CONFIG{$key} if($CONFIG{$key});
    return $CONFIG_default{$key};
}


sub CONFIG_get {
    my($key) = @_;
    my($ret);
    my($exp);

    $key =~ tr/A-Z/a-z/;
    return CONFIG_expand( CONFIG_get1($key) );
}


sub CONFIG_expand {
    my($v) = @_;
    my($exp);

    if($v =~ /^%([A-Z])/) {
	$exp = CONFIG_get1($CONFIG_abbrev{$1});
	$v =~ s/^%./$exp/;
    }

    return $v;
}


sub CONFIG_debug {    
    my($key);

    for $key (keys %CONFIG) {
	print "$key = $CONFIG{$key} -> ", CONFIG_get($key), "\n";
    }
}

##############################################################################

getopts('vc:');

# read config
my $CONFIG = $opt_c ? $opt_c : "%C/fidogate.conf";
CONFIG_read($CONFIG);

# options
my @options;
if($opt_c) {
    push @options, ("-c", $CONFIG);
}
if($opt_v) {
    push @options, "-v";
}


# get gate.conf parameters
my $SENDMAIL    = CONFIG_get("FTNInSendmail");
my $RNEWS       = CONFIG_get("FTNInRnews");
my $RECOMB      = CONFIG_get("FTNInRecombine");

my $OUTRFC_MAIL = CONFIG_get("OUTRFC_MAIL");
my $OUTRFC_NEWS = CONFIG_get("OUTRFC_NEWS");

if(! $SENDMAIL) {
    print STDERR "ftninpost:$CONFIG:FTNInSendmail not specified\n";
    exit 1;
}
if(! $RNEWS) {
    print STDERR "ftninpost:$CONFIG:FTNInRnews not specified\n";
    exit 1;
}

print
    "sendmail  = $SENDMAIL\n",
    "rnews     = $RNEWS\n",
    "recombine = $RECOMB\n",
    "mail      = $OUTRFC_MAIL\n",
    "news      = $OUTRFC_NEWS\n"
    if($opt_v);


# command lists
my @sendmail = split(' ', $SENDMAIL);
my @rnews    = split(' ', $RNEWS);
# remove -f%s option from sendmail command if present
# (compatibility with old configurations)
my $fidx = -1;
my $i;
for($i=0; $i<=$#sendmail; $i++) {
    $fidx = $i if($sendmail[$i] eq "-f%s");
}
if($fidx > -1) {
    splice(@sendmail, $fidx, 1);
    print "sendmail  = @sendmail\n" if($opt_v);
}



# ----- main -----------------------------------------------------------------
my $dir;
my $f;
my @files;

# do recombining of split messages
if($RECOMB) {
    my @cmd = (&CONFIG_expand($RECOMB));
    push(@cmd, @options);
    print "Running @cmd\n" if($opt_v);
    system @cmd;
}

# mail
$dir = $OUTRFC_MAIL;

opendir(DIR, "$dir") || die "ftninpost: can't open $dir\n";
@files = grep(/\.rfc$/, readdir(DIR));
closedir(DIR);

for $f (sort @files) {
    do_file(1, "$dir/$f");
}

# news
$dir = $OUTRFC_NEWS;

opendir(DIR, "$dir") || die "ftninpost: can't open $dir\n";
@files = grep(/\.rfc$/, readdir(DIR));
closedir(DIR);

for $f (sort @files) {
    do_file(0, "$dir/$f");
}



# ----- do_file() - process mail message or news batch -----------------------

sub do_file {
    my($mail, $file) = @_;
    my($ret, $bad, $from, @cmd);
    local(*SAVE);

    if($mail) {
	# Mail
	@cmd = @sendmail;
	$from = &get_sender($file);
	push(@cmd, "-f$from") if($from);
    }
    else {
	# News
	@cmd = @rnews;
    }

    print "CMD: @cmd" if($opt_v);

    # Save STDIN, open $file as new STDIN
    open(SAVE, "<&STDIN") || die "ftninpost: can't save STDIN\n";
    open(STDIN, "$file") || die "ftninpost: can't open STDIN with $file\n";

    # Run
    $ret = system(@cmd) >> 8;

    # Restore STDIN
    close(STDIN);
    open(STDIN, "<&SAVE") || die "ftninpost: can't restore STDIN\n";

    if($ret == 0) {
	print " - SUCCESS\n" if($opt_v);
	unlink($file) || die "ftninpost: can't unlink $file\n";
    }
    else {
	print " - ERROR\n" if($opt_v);
	$bad = $file;
	$bad =~ s/\.rfc$/.bad/;
	rename($file, $bad) || die "ftninpost: can't move $file -> $bad\n";
    }
}



# ----- get_sender() - get envelope sender for mail --------------------------

sub get_sender {
    my($file) = @_;
    local(*FILE);

    open(FILE, "$file") || die "ftninpost: can't open $file\n";
    $_ = <FILE>;
    close(FILE);

    if( /^From ([^ ]+) / ) {
	return $1;
    }
    else {
	return "";
    }
}
