#!/usr/local/bin/perl
#
# accept_l_mail - accept Listserv mail
#
# this script is invoked by Sendmail via the setuid wrapper to 
# deliver mail to a list.  It does some checks to make sure
# this is not a subscribe or unsubscribe command, then invokes
# catmail to append to appropriate mail file.  (We use catmail
# because it knows how to lock the mail file.)
#
# usage: accept_l_mail list_directory
#
# Author: "Michael H. Morse" <mmorse@z.nsf.gov>

$ENV{'PATH'} = '/bin:/usr/bin';
$ENV{'IFS'} = '' if $ENV{'IFS'} ne '';  # from Camel book

umask(022);
$tmpdir = "/tmp";
$tmpfile = "$tmpdir/accept$$";
$list = $ARGV[0];
if (!$list){
   die("Invokation error.\n");
}
$catmail = "/usr/server/catmail";

# copy file to tmp file, looking for suspicious lines, and picking
# up the "from:" field, just in case.

$in_msg = 0;
$from = "";
$got_command = 0;
$got_other_stuff = 0;
open(TMP,">$tmpfile") || die("Can't open $tmpfile\n");
while (<STDIN>){
   chop;
   if ($_ =~ /^\s*$/){
      $in_msg++;
   }
   elsif (! $in_msg){
      # look for from:
      if ($_ =~ /^From:/){
         $from = $_;
         $from =~ s/From:\s*//;
      }
   }
   else {              # in the message
      if ($_ =~ /^\s*subscribe(\s|$)/i ||
          $_ =~ /^\s*unsubscribe(\s|$)/i ){
          $got_command++;
      }
      else {
          $got_other_stuff++;
      }
   }
   print(TMP "$_\n");
}
close(TMP);
# analyze what we got
if ($from && $got_command && ($got_other_stuff < 5)){
   &kill_message;
}
else {
   &post_message;
}
unlink($tmpfile);
exit 0;

sub post_message{
   open(TMP,"$tmpfile") || die("Can't open $tmpfile\n");
   # need to untaint $list:
   $list =~ tr/a-zA-Z-//cd;  # get rid of nasty shell meta characters
   $list =~ /.*/;
   $utlist = $&;
   open(OUT,"| $catmail -L $utlist -f") || die ("Can't run $catmail:$!\n");
   while (<TMP>){
      print(OUT $_);
   }
   close(OUT);
}

sub kill_message {
   open(MAIL, "|/usr/lib/sendmail -t") 
                       || die ("Can't run sendmail: $!\n");
   
   print MAIL <<EOF;
From: NSF Listserv <stisop@nsf.gov>
To: $from
bcc: mmorse@nsf.gov
Subject: Suspicious posting to list

Hello,
   You just sent a message to "$list@nsf.gov".  Since your message
included a "subscribe" or "unsubscribe" command, we've taken a chance
and assumed that you meant to send it to "listserv@nsf.gov" (Internet)
or "listserv@NSF" (BITNET).  All messages to subscribe or unsubscribe
should go to one of those addresses.

   If we were correct, please re-send your message to Listserv instead
of the list itself.  If we erred, and you really meant for your message
to be re-distributed to all the list subscribers, please re-format 
your message so that the Listserv command is not the first word on 
the line, and re-send it (and accept our apologies).
   
   This message is automatically generated.

   Your message to us is included below.

EOF
   open(TMP,"$tmpfile") || die("Can't open $tmpfile\n");
   while (<TMP>){
      print(MAIL "> $_");
   }

   close MAIL;
}
