#!/usr/bin/perl
#
# fido.daily -- resume your ifcico, iftoss, ifmail, and ifnews logs
#
# by Joaquim Baptista, px@fct.unl.pt
#
# Placed on the public domain.  If you make significant improvements on
# this script, please send them to me so that I can mantain a "reference"
# version.  This script works with ifmail28; future versions may break it.
#
# Example usage from cron, before rotating the logs:
#     fido.daily iflog | mail -s 'Daily Fidonet report' sysop
#
# v1.1 -- Ignore "@somenet" in addresses like "2:362/42@fidonet" to avoid
#         multiple entries for the same node.  Add -s option to select
#         nodes.  Avoid dupplicate lines in the table of messages sent.
#         Add report of period covered.
#
# v1.0 -- First release
#
# Modified by kao@linux.it
#

require "getopts.pl";
&Getopts("s:") || die "usage: $0 [-s pattern] [file...]\n";
if ($opt_s ne "") { $opt_s =~ s/([^a-zA-Z0-9\s])/\\$1/g; }

$first="zzz 99";
$last= "      ";
while (<>) {
  if (/^([A-Z][a-z][a-z] [ \d]\d )/) {
    $date= substr($_,0,15);
    if ($date lt $first) { $first=$date; }
    if ($last lt $date ) { $last=$date; }
  }

  if    (/ifcico\[(\d+)\]: calling\s+([^\s@]+)/ ) {
    $call{$1}=$2;
    $attempts{$2}++;
  }
  elsif (/ifcico\[(\d+)\]: chat got "CONNECT"/) {
    $conn{$call{$1}}++;
  }
  elsif (/ifcico\[(\d+)\]: chat got "BUSY"/) {
    $busy{$call{$1}}++;
  }
  elsif (/ifcico\[(\d+)\]: chat got "NO CARRIER"/) {
    $noca{$call{$1}}++;
  }
  elsif (/ifcico\[(\d+)\]: received (\d+) bytes in (\d+)/) {
    $bytes_rcvd{$call{$1}} += $2;
    $seconds_rcvd{$call{$1}} += $3;
  }
  elsif (/ifcico\[(\d+)\]: sent (\d+) bytes in (\d+)/) {
    $bytes_sent{$call{$1}} += $2;
    $seconds_sent{$call{$1}} += $3;
  }
  elsif (/iftoss\[(\d+)\]: packet from node ([^\s@]+)/) {
    $toss{$1}= $2;
  }
  elsif (/iftoss\[(\d+)\]: No newsgroup for area tag (\S+)/) {
    $toss_area{$2}++;
  }
  elsif (/iftoss\[(\d+)\]: end (\d+) echomail, (\d+)/) {
    $tosskeys{$toss{$1}} ++;
    $echomail{$toss{$1}} += $2;
    $netmail{$toss{$1}}  += $3;
  }
  elsif (/ifmail\[(\d+)\]: route: ([^\s@]+)/) {
    $ifmail{$2}++;
  }
  elsif (/ifnews\[(\d+)\]: route: ([^\s@]+)/) {
    $snews{$1}= $2;
  } 
  elsif (/ifnews\[(\d+)\]: end input (\d+)/) {
    $ifnewskeys{$snews{$1}} ++;
    $ifnewscount{$snews{$1}} += $2; 
  }
  elsif (/ifcico\[(\d+)\]: start inbound/) {
    $inb{$1} = $1;
    $inbcount{$1}++;
  }
  elsif (/ifcico\[(\d+)\]: remote operator: ([\S ]*)/) { 
    $inbkeys{$inb{$1}} = $2;
  }
  elsif (/ifcico\[(\d+)\]: remote     time: ([\S ]*)/) { 
    $inbtime{$inb{$1}} = $2;
  }
}

print "Report period:\n  From  $first\n  To    $last\n\n";

print "Call-out systems (ifcico):\n";
print "Attempts Busy NoCa Conn   Time   Received    Sent   System\n";
for $s (sort keys %attempts) {
  next  if  ($opt_s ne "") && ($s !~ /$opt_s/o);
  printf("%7d  %3d  %3d  %3d %s   %6dKb  %4dKb   %s\n",
         $attempts{$s}, $busy{$s}, $noca{$s}, $conn{$s},
         &mmss($seconds_rcvd{$s}+$seconds_sent{$s}),
         $bytes_rcvd{$s}/1024, $bytes_sent{$s}/1024, $s);
}

print "\n\nMessages received by system (iftoss):\nEchomail Netmail  Route\n";
for $s (sort keys %tosskeys) {
  next  if  ($opt_s ne "") && ($s !~ /$opt_s/o);
  printf("%7d %7d   %s\n", $echomail{$s}, $netmail{$s}, $s);
}

print "\n\nMessages sent by system (ifnews+ifmail):\nEchomail Netmail  Route\n";
%aux=(%ifmail, %ifnewskeys);
for $s (sort (keys %aux)) {
  next  if  ($opt_s ne "") && ($s !~ /$opt_s/o);
  printf("%7d %7d   %s\n", $ifnewscount{$s}, $ifmail{$s}, $s);
}

print "\n\nCall-in systems (ifcico):\n";
printf("%-20s%s\n","Time","Operator");
for $s (sort keys %inbcount) {
  next  if  ($opt_s ne "") && ($s !~ /$opt_s/o);
  printf("%-20s%s\n",
         $inbtime{$s}, $inbkeys{$s});
}

if (%toss_area) {
  print "\n\nMessages not tossed for lack of area tag (iftoss):\nNumber  Area tag\n";
  for $a (sort keys %toss_area) {
    printf("%5d    %s\n", $toss_area{$a}, $a);
} }

exit 0;

sub mmss {
  local($s)= @_;
  sprintf("%4d:%2.2d", $s/60, $s-int($s/60)*60);
}
