#! /bin/perl --    # -*-Perl-*-
#
# outflow-stat - display outgoing feed statistics (#articles)
#                this works for innfeed only
#
# History: This program is based on some ideas (and source code lines) of
#          Felix Kugler, SWITCH, inflow-package and could be part of it.
#
# 961029 V1.0   released
# 970109 V1.1   change ls to readdir for sitelist
#               fix strip path statement
# 970113 V1.2   aligned some paths, renumbered version (FK)
# 970128 V1.2.1	added config of innfeeds checkpointing
# 970220 V1.2.2	enriched outfile naming (FK)
# 970224 V1.2.3	innfeed.0.10 support added (FK)
# 970305 V1.2.4	read sitelist from conffile instead lockfiles (GW)
# 970310 V1.2.5	minor bug fixes concerning innfeed.conf parsing  
#
$Copy="(c) 1996 Gerhard.Winkler\@univie.ac.at";


$RELDATE = "Mon Mar 10 10:56:47 MET 1997";
$RELEASE = "V1.2.5";
#
#
# local settings ----------------------------------------------------
#
$SPOOLDIR     = "/var/news/innfeed/tapes";
$CONFFILE     = "/home/news/config/innfeed.conf";
$OLDCONFSTYLE = 0;       # pre-0.10 innfeed uses old format for innfeed.conf
$CHKPT_FL     = 0;       # some innfeed versions use .checkpoint files
                         # some use .input for storing checkpoint info (>0.9.3)
$OUTFILE      = "/home/news/status/outflow";  # generic outfile name
$WANTHOSTNAME = 1;       # add hostname to outfile name ( -host) ?
#
$DATE         = "/usr/bin/date";
$WC           = "/usr/bin/wc";
#
# local HTML stuff: you can put custom header & footer information into 
#                   local files; optional...
#
$HTMLHEADER = "/home/news/config/inflowhtmlheader";
$HTMLFOOTER = "/home/news/config/inflowhtmlfooter";
# 
# end local settings ------------------------------------------------

require "getopts.pl";

($path,$0) = ($0 =~ /^(.*)\/([^\/]+)$/);                # strip path...

$Usage="$0    -  $Copy

Release $RELEASE  of $RELDATE

Process information from spoolfiles in $SPOOLDIR
and show how many articles should be sent to the remote site.
Output either in Text or HTML format.

Usage: 	$0 [-dhwF] 

Parameters:

   -d:            turn on verbosity; for debugging only
   -h:            This help.
   -w:            WWW support: show results in HTML table format
   -F:            write to file (defined in script header)

Optional HTML-stuff:

header file: $HTMLHEADER
footer file: $HTMLFOOTER

\n";

#
# initialisation ----------------------------------------------------
#

&Getopts('dhwF');

&gethostandfqdn;
$date = `$DATE`;
if ($WANTHOSTNAME) { $OUTFILE .= "-$hostname"; }

if ($opt_h) { print "$Usage"; exit 0; }

if ($opt_F) {
    if ($opt_w) { $OUTFILE .= ".html"; }
    open(OUT,">$OUTFILE") || die "can't open $OUTFILE\n";
} else {
    open(OUT,">-");
}

#  check for custom header & footer files
if ($opt_w) {
   if (open(IN,$HTMLHEADER)) {  while (<IN>) { $htmlheader .= $_; } close(IN); }
   if (open(IN,$HTMLFOOTER)) {  while (<IN>) { $htmlfooter .= $_; } close(IN); }
}

# main calculation part
# -----------------------------------------------------------------------------


&readconf;
&initpage;

chdir $SPOOLDIR || die "Can't change to $SPOOLDIR directory\n";

foreach $site (sort @sitelist) {
   $file = $site . ".lock";
   unless (-e $file) {
      print "no lock file found: $site\n" if ($opt_d);
      &printsite("no data");
      next;
   }
   print "check site: $site\n" if ($opt_d);

   $scount = $icount = $ocount = $offset = 0;
   $file = $site;
   if (-e $file) {
      $scount = &countfile($file);
      print "found articles in $file: $scount\n" if ($opt_d);
   } else {
      print "no $file\n" if ($opt_d);
   }

   $file = $site . ".input";
   if (-e $file) {
      $icount = &countfile($file);
      print "found articles in $file: $icount\n" if ($opt_d);
      if ($CHKPT_FL) { $check = $site . ".checkpoint"; }
      else { $check = $site . ".input"; }
      $offset = 0;
      if (open(CFL,"<$check")) {
         $offset = <CFL>;
         chop($offset);
         close(CFL);
      }
      print "found offset: $offset\n" if ($opt_d);
      @status = stat($file);
      $size = @status[7];
      $icount = $icount - ($icount * $offset / $size);
      $icount = int($icount);
      print "found articles in $file minus offset: $icount\n" if ($opt_d);
   } else {
      print "no $file\n" if ($opt_d);
   }

   $file = $site . ".output";
   if (-e $file) {
      $ocount = &countfile($file);
      print "found articles in $file: $ocount\n" if ($opt_d);
   } else {
      print "no $file\n" if ($opt_d);
   }

   $count = $scount + $icount + $ocount;
   &printsite($count);

}

&closepage;



# countfile
# -----------------------------------------------------------------------------
# count number of articles (lines) in file
# maybe there will be some size (byte) of articles in it
sub countfile {
   local($f) = @_;
   local($c) = 0;
### as long as we can't count bytes we can use 'wc'
### which is much faster
###   open(F,"<$f") || return $c;
###   while(<F>) {
###   }
###   $c = $. ;
###   close(F);
   $c = `$WC -l $f`;
   return($c);
}



#readconf
# -----------------------------------------------------------------------------
#read innfeed configuration files and extract site names

sub readconf {
    open(F,"<$CONFFILE") || die "can't open innfeeds config\n";
    if ($OLDCONFSTYLE) {       # innfeed 0.9.3 and older
	while(<F>) {
	    next if (/^\#/);
	    next if (/^$/);
            next if (/^default:/);
	    ($peer,$ipname) = split(/:/);
            push(@sitelist,$peer);
	    $conflist{$peer} = $ipname;
	}
    }
    else {                     # innfeed 0.10 and newer
	while(<F>) {
	    next if (/^\#/);
	    next if (/^$/);
#	    if (/^\s*peer\s+([\w\-]+)/) { 
	    if (/^\s*peer\s+([^{}\s]+)/) { 
		$peer = $1; 
                push(@sitelist,$peer);
	    }
	    if (/ip-name:\s+(\S+)/ && $peer) {
		$ipname = $1;
		$conflist{$peer} = $ipname;
		print "conflist{$peer} = $ipname\n" if $opt_d;
		$peer = "";
	    }
	}
    }
    close(F);
}



# printsite
# -----------------------------------------------------------------------------
# print result for one site

sub printsite {
   local($c) = @_;
   if ($opt_w) {
      print OUT "<TR>
                 <TD> $site </TD>
                 <TD> $conflist{$site} </TD>
                 <TD> $c </TD>
                 </TR>\n";
   } else {
      printf(OUT "%15s %35s %10s\n",$site,$conflist{$site},$c);
   }
}




# initpage
# -----------------------------------------------------------------------------
# Print Page Headers 
#
sub initpage {
    if ($opt_w) { 
	print OUT "<html><head><!--Content-type: text/html\nRefresh: 60-->\n\n";
	print OUT "<title>Status of outgoing feeds at $fqdn</title></head>
                   <body>
                   $htmlheader
                   <h1>Status of outgoing feeds at $fqdn</h1>
                   <p><b>calculated at:</b> $date</p>\n";
        print OUT "<center><TABLE BORDER>
                   <TR><TH>Feedname</TH>
                   <TH>Sitename</TH>
                   <TH>Articles to transfer</TH>
                   </TR>\n";

    } else {
        print OUT "Status of outgoing feeds at $fqdn\n\n";
        print OUT "calculated at: $date\n";
	printf(OUT "%15s %35s %10s\n\n","Feedname","Sitename","Articles to transfer");
    }
}


# closepage
# -----------------------------------------------------------------------------
# close page, write footers...
#
sub closepage {
    if ($opt_w) {
        print OUT "</table></center><P><P>\n";
	if ($htmlfooter) { print OUT "$htmlfooter\n"; } 
	print OUT "</body></html>\n";
    } else { print OUT "\n\n"; }
}


# gethostandfqdn
#---------------------------------------------------------------------- 
# construct fully qualified domain name...
sub gethostandfqdn {
    chop($str=`uname -n`);
    if ($str =~ /\./) {             # str is fqdn
	$fqdn = $str;
	($hostname) = ($str =~ /^([^.]+)\./);
    } else {                        # str is simple hostname
	$hostname = $str;
	$str = `/bin/grep domain /etc/resolv.conf`;
	$str =~ /domain\s*(\S+)$/;
	$fqdn = $hostname . "." . $1;
    }
}

