#!/usr/local/bin/perl
#
# Copyright (C) 2000 Serge N. Pokhodyaev
#
# E-mail: snp@ru.ru
# FIDO:   2:5020/1838
#
# Distributed under GNU GPL
#
# Updated by Dmitry Fedotov
#
# FIDO:	  2:5030/1229
#
#

require 5.000;

use strict;

my $VERSION = '$Revision: 5.2 $ ';
my $PROGRAM = "report_traffic";

use POSIX qw(strftime);

use locale;
use POSIX qw(locale_h);
setlocale(LC_TIME, 'C');

##############################################################################
#
#
# Perl functions to read FIDOGATE config file,
# included by <INCLUDE config.pl> when running subst.pl
#

my %CONFIG;

# specials for DosDrive and Zone
my %CONFIG_dosdrive;
my %CONFIG_zone;



my %CONFIG_default =
    (
##Automatically generated by subst.pl, DO NOT EDIT!!!##
	"libexecdir", "/usr/local/libexec/fidogate",
	"newsvardir", "/usr/local/news/db",
	"lock_dbc", "dbc",
	"tick_hold", "%B/tick",
	"seq_msgid", "%V/seq/msgid",
	"spyes", "%C/spyes",
	"seq_tick", "%V/seq/tick",
	"outrfc_mail", "%S/outrfc/mail",
	"toss_toss", "%S/toss/toss",
	"pinbound", "/var/spool/fido/bt/pin",
	"logfile", "%G/log",
	"toss_pack", "%S/toss/pack",
	"newsetcdir", "/usr/local/news/etc",
	"seq_pack", "%V/seq/pack",
	"logdir", "/var/log/fido/gate",
	"vardir", "/var/db/fidogate",
	"lock_tic_hist", "tic_hist",
	"newsbindir", "/usr/local/news/bin",
	"outrfc_news", "%S/outrfc/news",
	"seq_split", "%V/seq/split",
	"config_gate", "%C/fidogate.conf",
	"seq_news", "%V/seq/news",
	"routing", "%C/routing",
	"seq_mail", "%V/seq/mail",
	"aliases", "%C/aliases",
	"config_main", "%C/fidogate.conf",
	"charsetmap", "%L/charset.bin",
	"history", "%V/history",
	"outpkt", "%S/outpkt",
	"netmaildir", "/var/spool/fido/bt/netmail",
	"ftnacl", "%C/ftnacl",
	"inbound", "/var/spool/fido/bt/in",
	"toss_route", "%S/toss/route",
	"newslibdir", "/usr/local/news",
	"configdir", "/usr/local/etc/fido/gate",
	"hosts", "%C/hosts",
	"ftpinbound", "/var/spool/fido/bt/ftpin",
	"lock_history", "history",
	"hubroutedb", "%V/route",
	"passwd", "%C/passwd",
	"lockdir", "/var/run/fidogate",
	"spooldir", "/var/spool/fido/gate",
	"outpkt_mail", "%S/outpkt/mail",
	"tic_history", "%V/tic_hist",
	"areas", "%C/areas",
	"packing", "%C/packing",
	"acl", "%C/acl",
	"inn_batchdir", "/usr/local/news/spool/outgoing",
	"outpkt_news", "%S/outpkt/news",
	"uplinks", "%C/uplinks",
	"seq_pkt", "%V/seq/pkt",
	"seq_toss", "%V/seq/toss",
	"btbasedir", "/var/spool/fido/bt",
	"newsspooldir", "/usr/local/news/spool/articles",
	"seq_ff", "%V/seq/ff",
	"uuinbound", "/var/spool/fido/bt/uuin",
	"toss_bad", "%S/toss/bad",
	"bindir", "/usr/local/bin",
	"dbc_history", "%V/bdc",
     );
my %CONFIG_abbrev =
    (
##Automatically generated by subst.pl, DO NOT EDIT!!!##
	"B", "btbasedir",
	"S", "spooldir",
	"P", "pinbound",
	"L", "libexecdir",
	"G", "logdir",
	"V", "vardir",
	"I", "inbound",
	"K", "lockdir",
	"C", "configdir",
	"N", "bindir",
     );



sub CONFIG_read {
    my($file) = @_;
    my($key, $arg);
    local *C;

    $file = CONFIG_expand($file);

    open(C,"$file") || die "config.pl: can't open config file $file\n";
    while(<C>) {
	chop;
	next if( /^\s*\#/ );	# comments
	next if( /^\s*$/  );	# empty
	s/\s*$//;		# remove trailing white space
	s/^\s*//;		# remove leading white space
	($key,$arg) = split(' ', $_, 2);
	$key =~ tr/A-Z/a-z/;
	if($key eq "include") {
	    CONFIG_read($arg);
	    next;
	}
	if($key eq "dosdrive") {
	    my ($d, $path) = split(' ', $arg);
	    $CONFIG_dosdrive{lc($d)} = $path;
	    next;
	}
	if($key eq "zone") {
	    my ($z, $rest) = split(' ', $arg, 2);
	    $CONFIG_zone{$z} = $rest;
	    next;
	}
	$CONFIG{$key} = $arg if(!$CONFIG{$key});
    }
    close(C);
}


sub CONFIG_get1 {
    my($key) = @_;
    my($ukey);

    $ukey = $key;
    $ukey =~ tr/a-z/A-Z/;
    return $ENV{"FIDOGATE_$ukey"} if($ENV{"FIDOGATE_$ukey"});

    return $CONFIG{$key} if($CONFIG{$key});
    return $CONFIG_default{$key};
}


sub CONFIG_get {
    my($key) = @_;
    my($ret);
    my($exp);

    $key =~ tr/A-Z/a-z/;
    return CONFIG_expand( CONFIG_get1($key) );
}


sub CONFIG_expand {
    my($v) = @_;
    my($exp);

    if($v =~ /^%([A-Z])/) {
	$exp = CONFIG_get1($CONFIG_abbrev{$1});
	$v =~ s/^%./$exp/;
    }

    return $v;
}


sub CONFIG_debug {    
    my($key);

    for $key (keys %CONFIG) {
	print "$key = $CONFIG{$key} -> ", CONFIG_get($key), "\n";
    }
}

##############################################################################

# read config
my $CONFIG = "%C/fidogate.conf";
CONFIG_read($CONFIG);


# Configurable part ##########################################################

my $msgfrom = "\"Stat daemon\" <news\@thor.dragonflybsd.org>";
my $msgnewsgroup = "junk";
my $msgnode = "2:5030/1229.0";

##############################################################################

# Common configuration for perl scripts
#<INCLUDE config.pl>

my $logdir = CONFIG_get("LOGDIR");
my $log;
my $logtime = time;
# - 86400;
my $logdate1 = strftime("%b %e", localtime($logtime));
my $logdate2 = strftime("%b %d", localtime($logtime));
my $repdate = strftime("%a, %e %b %Y", localtime($logtime));

my %traffic;
my @areas;
my $area;

my $total;
my $total_size;
my $flag;

my %f;

my $i;
my $p;



format HEADER =
^||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$f{msg}
.


format HEADER_summary =
               
                            Area name              Messages     Size   
               
.

format LINE_summary =
                ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  ^>>>>>>>  ^>>>> ^>> 
                 $f{area},                           $f{traf},  $f{size} $f{l}
.

format FOOTER_summary =
               
                              TOTAL                ^>>>>>>>  ^>>>>> Kb 
                                                     $f{traf}, $f{size}
               
.


format HEADER_killed =
    
                 Area name                         Messages          
                                          r    i    d    c   r/o 
    
.

format LINE_killed =
     ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  ^>>  ^>>  ^>>  ^>>  ^>> 
      $f{area}, $f{traf_r}, $f{traf_i}, $f{traf_d}, $f{traf_c}, $f{traf_ro}
.

format FOOTER_killed =
    
                   TOTAL                 ^>>  ^>>  ^>>  ^>>  ^>> 
    $f{traf_r}, $f{traf_i}, $f{traf_d}, $f{traf_c}, $f{traf_ro}
    
    r   == routed
    i   == insecure
    d   == dupes
    c   == circular path
    r/o == from read only links
.



  foreach $log ("$logdir/log-in.1.gz","$logdir/log-in.1","$logdir/log",
                "$logdir/log-news.1.gz","$logdir/log-news.1","$logdir/log-news")
  {

    # Check if logfile is readable
    #
    if (!(-r $log))
      {
	next;
      }

    # Try to open logfile
    #
    if ($log =~ /\.gz$/)
      {
	open(LOG, "gunzip -c $log |") || next;
      }
    else
      {
	open(LOG, "< $log") || next;
      }


    # Read logfile
    #
    while (<LOG>)
      {
	if (!($_ =~ ("^" . $logdate1)) && !($_ =~ ("^" . $logdate2)))
	  {
#	    next;
	  }

	if ($_ =~ m( ftntoss area ([^ ]+) *: msgs in: ([0-9]+) *out: ([0-9]+) *size: ([0-9]+) *killed: ([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)))
	  {
	    $area = uc($1);
	    $traffic{$area}{'in'}       += $2;
	    $traffic{$area}{'out'}      += $3;
	    $traffic{$area}{'size'}     += $4;
	    $traffic{$area}{'routed'}   += $5;
	    $traffic{$area}{'insecure'} += $6;
	    $traffic{$area}{'dupes'}    += $7;
	    $traffic{$area}{'circular'} += $8;
	    $traffic{$area}{'ro'}       += $9;
	  }
	elsif ($_ =~ m( ftntoss area ([^ ]+) *: msgs in: ([0-9]+) *out: ([0-9]+) *size: ([0-9]+) *killed: ([0-9]+)/([0-9]+)/([0-9]+)/([0-9]+)))
	  {
	    $area = uc($1);
	    $traffic{$area}{'in'}       += $2;
	    $traffic{$area}{'out'}      += $3;
	    $traffic{$area}{'size'}     += $4;
	    $traffic{$area}{'routed'}   += $5;
	    $traffic{$area}{'insecure'} += $6;
	    $traffic{$area}{'dupes'}    += $7;
	    $traffic{$area}{'circular'} += $8;
	  }
	elsif ($_ =~ m( ftntoss area ([^ ]+) *: msgs in: ([0-9]+) *out: ([0-9]+) *size: ([0-9]+)))
	  {
	    $area = uc($1);
	    $traffic{$area}{'in'}      += $2;
	    $traffic{$area}{'out'}     += $3;
	    $traffic{$area}{'size'}    += $4;
	  }
      }
    
    close(LOG);
  }

@areas = sort(keys(%traffic));

open(STDOUT, "| inews -h -O -S -R") || die("can't pipe report to inews");
#open(STDOUT, "| cat") || die("can't pipe report to cat");

# Print RFC headers
#
print "From: ", $msgfrom, "\n";
print "Newsgroups: ", $msgnewsgroup, "\n";
print "Subject: Traffic statistics for ", $repdate, "\n";
print "\n";

# Print date info
#
$~ = "HEADER";
$f{msg} = "Traffic statistics at node " . $msgnode . " for yesterday (" . $repdate . ")";
write;
print "\n";

# Print total message statistics #############################################
#
$~ = "HEADER_summary";
write;

$~ = "LINE_summary";

$total = 0;
$total_size = 0;
foreach $i (@areas)
  {
    $f{area} = $i;
    $f{traf} = $traffic{$i}{'in'};
    $p = $traffic{$i}{'size'};
    if ($p < 10240)
    {
	$f{size} = "$p";
    }
    else
    {$f{size} = $p/1024;
     $f{l} = "Kb";  }
    write;
#    write;
#    print STDOUT "$f{size}\n";
    $total += $traffic{$i}{'in'};
    $total_size += $traffic{$i}{'size'};
  }

$~ = "FOOTER_summary";
$f{traf} = $total;
$f{size} = $total_size/1024;
write;


# Print detailed message statistics ##########################################
#
$flag = 0;
$total = 0;
$f{traf_r} = 0;
$f{traf_i} = 0;
$f{traf_d} = 0;
$f{traf_c} = 0;
$f{traf_ro} = 0;
foreach $i (@areas)
  {
    if ($traffic{$i}{'routed'}   != 0 ||
	$traffic{$i}{'insecure'} != 0 ||
	$traffic{$i}{'dupes'}    != 0 ||
	$traffic{$i}{'circular'} != 0 ||
	$traffic{$i}{'ro'}       != 0)
      {
	if ($flag == 0)
	  {
	    print "\n";
	    $~ = "HEADER_killed";
	    write;
	    $~ = "LINE_killed";
	    $flag = 1;
	  }
	$f{area} = $i;
	$f{r}  = $traffic{$i}{'routed'};   $f{traf_r}  += $traffic{$i}{'routed'};
	$f{i}  = $traffic{$i}{'insecure'}; $f{traf_i}  += $traffic{$i}{'insecure'};
	$f{d}  = $traffic{$i}{'dupes'};    $f{traf_d}  += $traffic{$i}{'dupes'};
	$f{c}  = $traffic{$i}{'circular'}; $f{traf_c}  += $traffic{$i}{'circular'};
	$f{ro} = $traffic{$i}{'ro'};       $f{traf_ro} += $traffic{$i}{'ro'};
	write;
      }
  }

if ($flag == 1)
  {
    $~ = "FOOTER_killed";
    $f{r}  = $f{traf_r};
    $f{i}  = $f{traf_i};
    $f{d}  = $f{traf_d};
    $f{c}  = $f{traf_c};
    $f{ro} = $f{traf_ro};
    write;
  }

##############################################################################

close(STDOUT);

exit(0);
