#! /usr/bin/perl
require '/usr/local/news/lib/innshellvars.pl';

# 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.in 6648 2004-01-25 20:07:11Z rra $
#
# 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. 
# 

#
#	Hmm, perhaps we should try to read "backlog-directory"
#	from innfeed.conf. Oh well.
#
$tapeDir = $inn'pathspool . "/innfeed"; #'
$destDir = $inn'spooltemp ; #'
$spoolArts = $inn'patharticles ; #'
$outGoing = $inn'pathoutgoing; #'

##
## 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 where the news articles are
             ($spoolArts)
  -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
$outGoing), 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);

$spoolArts = $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: $spoolArts\n\n" . $usage if ( ! -d $spoolArts && $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+! || m!^@[0-9A-F]+@ <.+@.+> \S+!) ;  

	if ( $opt_c ) {
		if ( ! -f "$spoolArts/$F[0]" )  {
			$missing++ ;
			print "Dropping file: $spoolArts/$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 ) ;
