#!/usr/bin/perl

# Statistics gathering program for ifmail.
# Created by Serg Oskin (2:5020/20 [.10], serg@oskin.msk.ru)
#
# Modified by me (P.Saratxaga srtxg@f2219.n293.z2.fidonet.org)
# on Thu Mar  5 21:05:59 CET 1998 to make it handle only one logfile,
# so to include it in ifmail rpm package; also changed the semi-graphical
# chars to plain ascii.
#
# you only need to configure the following line to tell where reports
# are to be poted. and what to put in From line.

@PostNewsGroup = ( "local.test" );
$From = ( "Spy <Spy>" );

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

@LogFiles = (	"/var/log/ifmail/messages" );
#@LogFiles = (
#		"/var/log/ifmail/OLD/inb.1.iflog",
#		"/var/log/ifmail/OLD/inb.2.iflog.0",
#		"/var/log/ifmail/OLD/inb.tcp.iflog.0",
#		"/var/log/ifmail/OLD/out.iflog.0",
#		"/var/log/ifmail/OLD/out.tcp.iflog.0" );
#@LogFiles = (
#		"/var/log/ifmail/inb.1.iflog",
#		"/var/log/ifmail/inb.2.iflog",
#		"/var/log/ifmail/inb.tcp.iflog",
#		"/var/log/ifmail/out.iflog",
#		"/var/log/ifmail/out.tcp.iflog" );

#@PostNewsGroup = (
#		"fido7.20.ROBOTS",
#		"fido7.20.ROBOTS",
#		"fido7.20.ROBOTS",
#		"fido7.20.ROBOTS",
#		"fido7.20.ROBOTS" );
		
@Subjects = ( "Ifmail traffic" );
#@Subjects = (
#		"Inbound, line 1",
#		"Inbound, line 2",
#		"Inbound, TCP/IP",
#		"Outbound, lines 1,2",
#		"Outbound, TCP/IP" );
#@InOuts = (
#		1,
#		1,
#		1,
#		2,
#		2 );

@RepFiles = (	"| /usr/lib/news/inews -h" );
#@RepFiles = (
#		"| /usr/lib/news/inews -h",
#		"| /usr/lib/news/inews -h",
#		"| /usr/lib/news/inews -h",
#		"| /usr/lib/news/inews -h",
#		"| /usr/lib/news/inews -h" );
#@RepFiles = (
#		">t/inb.1.news",
#		">t/inb.2.news",
#		">t/inb.tcp.news",
#		">t/out.news",
#		">t/out.tcp.news" );

#main {
	for( $i = 0; $i <= $#LogFiles; $i++ ) {
		$LogFile = $LogFiles[$i];
		$PostGroup = $PostNewsGroup[$i] if( defined( $PostNewsGroup[$i] ));
		$Subject = $Subjects[$i] if( defined( $Subjects[$i] ));
#		$InOut = $InOuts[$i];
		$RepFile = $RepFiles[$i];
		&ProcessLog();
	}
#}

sub ProcessLog {
	local( $start, $first, $sys );
	local( $Mon, $Day, $Time, $Host, $Pid, $Text );
	local( %Systems, %Times, %Sessions );
	local( %InBytes, %OutBytes, %InFiles, %OutFiles, %InCPS, %OutCPS, %Speed );
	local( $sTime, $eTime );
	local( @Syst, $i, $CurSpeed, @Speeds, @SortSpeeds );

	undef( %Systems );
	undef( %Times );
	undef( %Sessions );
	undef( %InBytes );
	undef( %OutBytes );
	undef( %InFiles );
	undef( %OutFiles );
	undef( %InCPS );
	undef( %OutCPS );
	undef( %Speed );
	undef( @Speeds );
	undef( @SortSpeeds );

	return 1 if( ! -r $LogFile );
	if( !open( flog, $LogFile )) {
		print "Cannot open $LogFile. $!\n";
		return 0;
	}

	$start = 0;
	$TimeFirst = "";
	$TimeLast = "";
	$CurSpeed = "unknown";
	while( <flog> ) {
		chop;
		( $Mon, $Day, $Time, $Host, $Pid, $Text ) = split( /[ \t]+/, $_, 6 );
		if( $TimeFirst eq "" ) {
			$TimeFirst = "$Mon $Day $Time";
		}
		if( $start == 0 ) {
			if( $Text =~ /^connect/ ) {
				$Text =~ /^connect "CONNECT ([0-9]+).*$/;
				$CurSpeed = $1;
				next;
			}
#			if((( $InOut == 1 ) && ( $Text =~ /^start inbound/ )) ||
#			   (( $InOut == 2 ) && ( $Text =~ /^start outbound/ ))) {
			if(( $Text =~ /^start inbound/ ) ||
			   ( $Text =~ /^start outbound/ )) {
				$start = 1;
				$sys = "";
				$Time =~ /^(..):(..):(..)$/;
				$sTime = ( $1 * 60 + $2 ) * 60 + $3;
			}
			next;
		}
		if( $start != 0 ) {
			if( $Text =~ /^remote[ \t]+address:/ ) {
				next if( $sys ne "" );
				$Text =~ /^.+:[ \t]+([0-9:.\/]+).*$/;
				$sys = $1;
				if( !defined( $Systems{$sys} )) {
					$Systems{$sys} = 0;
					$Times{$sys} = 0;
					$Sessions{$sys} = 0;
					$InBytes{$sys} = 0;
					$OutBytes{$sys} = 0;
					$InFiles{$sys} = 0;
					$OutFiles{$sys} = 0;
					$InCPS{$sys} = 0;
					$OutCPS{$sys} = 0;
				}
				$Sessions{$sys}++;
				next;
			} elsif( $Text =~ /listed system$/ ) {
				$Systems{$sys} = 1;
				next;
			} elsif( $Text =~ /protected EMSI/ ) {
				$Systems{$sys} = 2;
				next;
			} elsif( $Text =~ /^received [0-9]+ bytes in/ ) {
				$Text =~ /^received ([0-9]+).*\(([0-9]+).*$/;
				$InBytes{$sys} += $1;
				$InCPS{$sys} += $2;
				$InFiles{$sys} ++;
				next;
			} elsif( $Text =~ /\+Rcvd-H[ \t]+CPS/ ) {
				$Text =~ /^.*CPS:[ \t]+([0-9]+)[ \t]+.*\(([0-9]+).*$/;
				$InBytes{$sys} += $2;
				$InCPS{$sys} += $1;
				$InFiles{$sys} ++;
				next;
			} elsif( $Text =~ /^sent [0-9]+ bytes in/ ) {
				$Text =~ /^sent ([0-9]+).*\(([0-9]+).*$/;
				$OutBytes{$sys} += $1;
				$OutCPS{$sys} += $2;
				$OutFiles{$sys} ++;
				next;
			} elsif( $Text =~ /\+Sent-H[ \t]+CPS/ ) {
				$Text =~ /^.*CPS:[ \t]+([0-9]+)[ \t]+.*\(([0-9]+).*$/;
				$OutBytes{$sys} += $2;
				$OutCPS{$sys} += $1;
				$OutFiles{$sys} ++;
				next;
			} elsif(( $Text =~ /calls\, maxrc=/ ) ||
				( $Text =~ /got SIGHUP/ ) ||
				( $Text =~ /tcsetattr.+save/ )) {
				$Time =~ /^(..):(..):(..)$/;
				$eTime = ( $1 * 60 + $2 ) * 60 + $3;
				$Times{$sys} += $eTime - $sTime;
				$Times{$sys} += 86400 if(( $eTime - $sTime ) < 0 );
				$sys = "";
				$start = 0;
				$Speed{$CurSpeed} = 0 if( !defined( $Speed{$CurSpeed} ));
				$Speed{$CurSpeed}++;
				$CurSpeed = "unknown";
				next;
			}
		}
	}
	$TimeLast = "$Mon $Day $Time";

	@Syst = sort( keys( %Systems ));
	return 1 if( $#Syst < 0 );

	if( !open( rep, $RepFile )) {
		print "Cannot open $RepFile. $!\n";
		return 0;
	}
	print rep "From: ".$From."\n";
	print rep "Newsgroups: ".$PostGroup."\n";
	print rep "Subject: ".$Subject."\n";
	print rep "MIME-Version: 1.0\n";
	print rep "Content-Type: text/plain; charset=koi8-r\n";
	print rep "Content-Transfer-Encoding: 8bit\n";
	print rep "\n";
	select( rep );
#	$~ = NULLS;
#	write( rep );
	$~ = BEGIN;
	write;

	local( $ses, $tim, $ibyte, $obyte, $icps, $ocps );
	local( $ases, $atim, $aibyte, $aobyte, $aicps, $aocps, $aises, $aoses );
	$ases = 0;
	$atim = 0;
	$aibyte = 0;
	$aobyte = 0;
	$aicps = 0;
	$aocps = 0;
	$aises = 0;
	$aoses = 0;

	$~ = EACH;
	for( $i = 0; $i <= $#Syst; $i++ ) {
		$sys = $Syst[$i];
		$ses = $Sessions{$sys};
		$ases += $ses;
		$tim = sprintf( "%d.%02d", int( $Times{$sys} / 60 ), $Times{$sys} % 60 );
		$atim += $Times{$sys};
		$ibyte = $InBytes{$sys};
		$aibyte += $ibyte;
		$obyte = $OutBytes{$sys};
		$aobyte += $obyte;
		if( $InFiles{$sys} > 0 ) {
			$icps = int( $InCPS{$sys} / $InFiles{$sys} );
			$aicps += $icps;
			$aises++;
		} else {
			$icps = 0;
		}
		if( $OutFiles{$sys} > 0 ) {
			$ocps = int( $OutCPS{$sys} / $OutFiles{$sys} );
			$aocps += $ocps;
			$aoses++;
		} else {
			$ocps = 0;
		}
		write;
	}
	$atim = sprintf( "%d.%02d", int( $atim / 60 ), $atim % 60 );
	if( $aises > 0 ) {
		$aicps = int( $aicps / $aises );
	} else {
		$aicps = 0;
	}
	if( $aoses > 0 ) {
		$aocps = int( $aocps / $aoses );
	} else {
		$aocps = 0;
	}
	$~ = END;
	write;
#
#	$sk = "unknown";
#	if( defined( $Speed{$sk} )) {
#		$sc = $Speed{$sk};
#		write;
#		undef( $Speed{$sk} );
#	}
	@Speeds = sort srtspeed keys( %Speed );
#	@Speeds = sort { $a <=> $b } keys( %Speed );
#	@Speeds = sort( keys( %Speed ));
#	@Speeds = keys( %Speed );
	$~ = EACH_CONN;
	for( $i = 0; $i <= $#Speeds; $i++ ) {
		$sk = $Speeds[$i];
		$sc = $Speed{$sk};
		write;
	}
	close( rep );

	return 1;
}

sub srtspeed {
	if(( $a !~ /[0-9]+/ ) || ( $b !~ /[0-9]+/ )) {
		$a cmp $b;
	} else {
		$a <=> $b;
	}
}

format NULLS =
.

format BEGIN =
+------------------+----------------------------------+------------------+
|  @<<<<<<<<<<<<<< |    Session Calls & Transfers     | @>>>>>>>>>>>>>>  |
   $TimeFirst,                                          $TimeLast
+--------------+---+-----+---------+------------------+------+-----------+
|Zone:Net/Node |Telephone|  Tran   |          Bytes          |  CPS Avg  |
|    Number    |  Calls  |   Min   |  Incoming  |  Outgoing  | In  | Out |
+--------------+---------+---------+------------+------------+-----+-----+
.

format EACH =
|@<<<<<<<<<<<<<   @>>>    @>>>>>>>>  @>>>>>>>>>>  @>>>>>>>>>> @>>>> @>>>>|
$sys,             $ses,   $tim,     $ibyte,      $obyte,     $icps,$ocps
.

format END =
+------------------------------------------------------------------------+
| TOTAL           @>>>    @>>>>>>>>  @>>>>>>>>>>  @>>>>>>>>>> @>>>> @>>>>|
                  $ases,  $atim,     $aibyte,     $aobyte,    $aicps,$aocps
+------------------------------------------------------------------------+
**
  Tran -- время на линии.
  CPS  -- "чистый" CPS при передаче/приеме (не (Incoming+Outgoing)/Tran ).

  Connects
.

format EACH_CONN =
@>>>>>>>      @>>>
$sk,          $sc
.
