#!/usr/bin/perl
# 
# Author:       James Brister <brister@vix.com> -- berkeley-unix --
# Start Date:   Thu May 16 10:32:02 1996 +0200
# Project:      INN -- innfeed
# File:         procbatch.pl
# RCSId:        $Id: procbatch.pl,v 1.4 1996/08/20 14:01:04 brister Exp $
#
# Copyright:	Copyright (c) 1996 by Internet Software Consortium
#
#               Permission to use, copy, modify, and distribute this
#               software for any purpose with or without fee is hereby
#               granted, provided that the above copyright notice and this
#               permission notice appear in all copies.
#
#               THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE
#               CONSORTIUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
#               SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
#               MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET
#               SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
#               INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
#               WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
#               WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
#               TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
#               USE OR PERFORMANCE OF THIS SOFTWARE.
#
# Description: Take a file of the form generated by innd in the out.going
#	       directory ("Wnm*") and separate it into tape files for inn.
#
# Thanks to Clayton O'Neill <coneill@premier.net> for serious speed
# improvments. 
# 

$spoolTop = "/var/spool/news" ;
$destDir = "/tmp" ;
$tapeDir = "/var/tmp/innfeed/tapes" ;

$0 =~ s!.*/!! ;

require 'getopts.pl' ;

$usage = "$0 [ -q ][ -v ][ -u ][ -e host ][ -d dir ][ -c [ -s dir ]][ -m [-t dir ]] inn-batchfile\n
  -e host\tto process on entries for only that host
  -d dir\tto put the output file(s) in that directory
  -c\t\tto check pathnames of articles before storing them
  -s dir\tto specify the top of the news spool tree ($spoolTop)
  -m\t\tto have $0 move the new files to the tape directory.
  -t dir\tto specify the tape directory ($tapeDir)
  -u\t\tto unlink the input files when finished
  -v\t\tfor verbosity
  -q\t\tquiet mode; only display error messages. Good for cron jobs.

$0 will take inn-batchfile (normally a file in /var/spool/news/out.going),
which is presumed to be of the format:

	pathname message-id peer1 peer2 peer3 ...

and will break it up into files peer1.tmp peer2.tmp peer3.tmp... Each of
these files wil be of the format:

	pathname message-id

that is the same as innfeed's 'tapefile' format. Simply rename these files
to peer1 peer2 peer3 in a running innfeed' tape directory and they will be
picked up automatically and processed by innfeed. Use the '-m' flag and
they'll be moved automatically.
" ;

&Getopts ("he:t:s:d:cvumq") || die $usage ;

die $usage if ( $opt_h ) ;
die "Cannot specify both -q and -v\n\n" . $usage if ($opt_q && $opt_v);

$spoolTop = $opt_s if $opt_s ;
$destDir = $opt_d if $opt_d ;
$tapeDir = $opt_t if $opt_t ;
$inputFile = shift ;

die $usage unless ($inputFile ne "") ;
unless (-f $inputFile) {
       exit if $opt_q;
       die "No such file: $inputFile\n\n" . $usage;
}
die "No such directory: $spoolTop\n\n" . $usage if ( ! -d $spoolTop && $opt_c ) ;
die "No such directory: $destDir\n\n" . $usage if ( ! -d $destDir ) ;
die "No such directory: $tapeDir\n\n" . $usage if ( ! -d $tapeDir && $opt_m ) ;

print "Using $inputFile\n" if $opt_v ;
open (INPUT,"<$inputFile") || die "open ($inputFile): $!\n" ;

while (<INPUT>) {
	chop ;
	@F = split ;

        # Check the format of the line vigorously	
        next unless (m!^\S+/\d+ <.+@.+> \S+!) ;  

	if ( $opt_c ) {
		if ( ! -f "$spoolTop/$F[0]" )  {
			$missing++ ;
			print "Dropping file: $spoolTop/$F[0]\n" if $opt_v ;
			next ;
		}
	}

	for ($i = 2 ; $i <= $#F ; $i++) {
		$host = $F[$i] ;
		next if ($opt_e && $opt_e ne $host) ;

		# Keep out host names with any funny characters (from 
		# corrupted files)
                if ($host !~ /^[-\._0-9A-Za-z]+$/) {
                        warn "$0: bad site name ignored: \"$host\"\n";
                        next;
                }

		if ($hosts{$host}) {
			print {$hosts{$host}} "$F[0] $F[1]\n";
		} else {
			$outputFile = "$destDir/$host.tmp" ;
			$tmpTape = "$tapeDir/$host.tmp" ;
			$tapeFile = "$tapeDir/$host" ;
			print "Starting $host\n" if ($opt_v);
			$hosts{$host}=$host;
			open ($hosts{$host},">$outputFile") || die "open (>$out
putFile): $!\n" ;
			print {$hosts{$host}} "$F[0] $F[1]\n";
		}
	}	
}
close (INPUT) ;

foreach $host (keys %hosts) {
	close($hosts{$host});
	$outputFile = "$destDir/$host.tmp" ;
	$tmpTape = "$tapeDir/$host.tmp" ;
	$tapeFile = "$tapeDir/$host" ;
	if ( $opt_m ) {
		$cmd = "mv $outputFile $tmpTape" ;
		system ($cmd) ;
		die "$cmd: failed\n" unless ($? == 0) ;

		$cmd = "cat $tmpTape |sort>> $tapeFile && rm -f $tmpTape" ;
		system ($cmd) ;
		die "$cmd: failed\n" unless ($? == 0) ;
	}
}

unlink($inputFile) if ($opt_u);

print "$missing articles dropped\n" if ( $opt_v && $missing > 0 ) ;
