#!/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.7 1997/02/14 03:21:48 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. 
# 

# If you have inn 1.5 or higher, then set $innshellvars to point at the
# installed innshellvars.pl file. 
$innshellvars = "/var/news/etc/innshellvars.pl" ;

if ( -f $innshellvars ) {
    require $innshellvars ;

    $spoolTop = $inn'spool ; #'

    # if $inn'batch is /var/news/spool/out.going then set tapeDir to 
    # /var/news/spool/innfeed
    $tapeDir = $inn'batch ; #'
    $tapeDir =~ s!(.*)/.*!$1! ;
    $tapeDir .= "/innfeed" ;

    $destDir = $inn'spooltemp ; #'
} else {
    # the top of the article spool. In this directory are alt, comp etc. 
    # Overriden with the ``-s'' option.
    $spoolTop = "/var/news/spool/articles" ;

    # The directory where innfeed stores its backlog files. 
    # Overriden with the ``-t'' option.
    $tapeDir = "/var/news/spool/innfeed" ;

    # Where the files get written to before possibly being moved to the 
    # tape directory. The ``-d'' option overrides
    $destDir = "/var/tmp" ;
}



##
## Everything below here should probably be left alone.
##

$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    to process on entries for only that host
  -d dir     to put the output file(s) in that directory ($destDir)
  -c         to check pathnames of articles before storing them
  -s dir     to specify the top of the news 
             spool tree ($spoolTop)
  -m         to have $0 move the new files to the backlog directory.
  -t dir     to specify the backlog directory ($tapeDir)
  -u         to unlink the input files when finished
  -v         for verbosity
  -q         quiet mode; only display error messages. Good for cron jobs.

$0 will take an inn funnel file (normally a file in
/var/spool/news/out.going), or an innfeed ``dropped'' file, 
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 backlog file format. Simply rename these files
to peer1 peer2 peer3 in a running innfeed's backlog directory and they will be
picked up automatically and processed by innfeed. Use the '-m' flag and
they'll be moved automatically.
" ;

$opt_u = $opt_h = "";  # shut up, perl -w
&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 if !$inputFile ;
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 "$0: 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" ;
			print "Starting $host\n" if ($opt_v);
			$hosts{$host}=$host;
			open ($hosts{$host},">>$outputFile") || 
				die "open >>$outputFile: $!\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 ) {
		if ($outputFile ne $tmpTape) {
			$cmd = "mv $outputFile $tmpTape" ;
			system ($cmd) ;
			die "$0: $cmd: failed\n" unless ($? == 0) ;
		}

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

unlink($inputFile) if ($opt_u);

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