#!/usr/bin/perl

use strict;
use warnings;

use Getopt::Long;
use File::Spec::Functions;
use LWP::Simple;
use Cwd 'abs_path';
use Time::TZOffset qw/tzoffset/;
use File::Path qw( make_path );
use File::Copy;

use constant PVT => 0x0001;
use constant CRA => 0x0002;
use constant ATT => 0x0010;
use constant K_S => 0x0080;
use constant LOC => 0x0100;
use constant HLD => 0x0200;
use constant REQ => 0x0800;
use constant RRQ => 0x1000;
use constant RRD => 0x2000;
use constant AUD => 0x4000;
use constant UPD => 0x8000;


my $vers = 'v.0.4';
my $url = 'http://brorabbit.g0x.ru/files/perl/';

my ( $outdir, $needhelp, $alltbl, $sesstbl, $forday, $check_updates,
     $configfile, $write_text, $export );

GetOptions ("out-dir=s"     => \$outdir,
            "config=s"      => \$configfile,
            "export"        => \$export,
            "text-write"    => \$write_text,
	    "day=s"         => \$forday,
            "update=s"      => \$check_updates,
            "help"          => \$needhelp
	) or die("Error in command line arguments\n");

$check_updates = 'w' unless defined $check_updates;

my $binkdconf = shift @ARGV;

my ( %char, $binkdlog, %addr, %list, %sessFrom, %sessTo, %addrR, %addrS, $nodes,
     %tab, $startperiod, $endperiod, $logfile, $msgfromname, $graphheader,
     $tableheader, $graphfooter, $tablefooter );


sub help
{
	$0 =~ /([^\/\\]+)$/;
	my $src = $1;
	print   "Creates stat files from the binkd.log file.\n".
		"Usage: $src [options] binkd_config_file_name\n".
		"~~~~~~ \n".
#		"  Binkd config MUST be defined!\n".
		"  Options:\n".
		"    --out-dir[|-o]     - directory name where create stat files. Optional.\n".
		"                         Default is current dir.\n".
		"    --day[|-d]         - date to create stat for. Format dd.mm, dd-mm or dd/mm.\n".
		"                         Default is from the start of log file till the end.\n".
                "     -c,--config       - Configuration file name. Command line options\n".
                "                         override it. Optional. Not needed by default.\n".
                "                         Use command 'bls.pl -e > bls.conf' to create a new one.\n".
                "     -e,--export       - export configuration and exit.\n".
	        "     -u,--update       - How to update the program. Optional.\n".
	        "                          =d - download. Check for a new version and\n".
	        "                               download the update to a new file.\n".
	        "                          =f - force download bls.pl end exit even\n".
	        "                               if no new version is found.\n".
	        "                          =w - warn. Check for a new version and warn\n".
	        "                               the sysop. Default.\n".
	        "                          =n - no. Do nothing.\n";
	exit;
}

sub export_conf()
{

	print <<MARK;
##############################################################################
#
#      binkd log stat config file by Stas Mishchenkov 2:460/58
#
##############################################################################
#
# binkd log file name with path
binkdconf D:\\Fido\\binkd\\binkd.cfg
#
#
# where to create stat and pkt files
outdir /home/fido/inbound
#outdir D:\\Fido\\logs
#
#
pktfromaddress 2:460/58.256
#
#
pktpassword 12345678
#
#
pkttoaddress 2:460/58
#
#
msgfromname Stas Mishchenkov
#
#
msgfromaddress 2:460/58
#
#
# echo area tags to post sessions statistic table
#posttable  CRIMEA.ROBOTS LORAPVT.BIGFILES
#
# echo area tags to post sessions statistic graph
#postgraph  CRIMEA.ROBOTS
#
#
#  regular expression and echo area tags to post sessions statistic graph
#             all nodes from R46
#filternodes (^2:46[^.]+\$\)       R46.ALIVE
#
#             all nodes from net 460
#filternodes (^2:460\\/[^.]+\$\)    LORAPVT.BIGFILES
#
#             all points from net 460
#filternodes (^2:460\\/\\d+\\.\\d+\$\) LORAPVT.BIGFILES
#
#             all nodes
#filternodes (^[^.]+\$\)           STATS
#
##############################################################################
MARK
	exit;
}

sub update()
{
#    return if $check_updates eq 'n';
    return unless $check_updates =~ /^[wdf]$/;

    my ( $ver_s, $upd, $of );

    my $curpath = abs_path($0);
    $curpath = Cwd::realpath($0) unless defined $curpath;
    $curpath = Cwd::realpath('./') unless defined $curpath;

    $ver_s = get( $url . 'bls.v');
    if (defined ($ver_s) ) {
	if ( $check_updates eq 'f' ) {
		if ( $curpath =~ /^(.*?)\.pl$/ ) {
		    $of = "$1_$ver_s\.pl";
		} elsif ( $curpath =~ /^(.*?[\/\\])[^\/\\]+$/ ) {
		    $of = $1 . "bls_${ver_s}\.pl";
		} else {
		    $of = "${curpath}_${ver_s}\.pl";
		}
		print "Latest version is $ver_s\!\n";
		writelog("Latest version is $ver_s\! Downloaded filename is \'$of\'.\n");
	} elsif ( $vers lt $ver_s ) {
	    if ( $check_updates eq 'w' ) {
		print " \*\*\* You should update to $ver_s\! \*\*\* \n";
		writelog(" \*\*\* You should update to $ver_s\! \*\*\* \n");
		return;
	    } elsif ( $check_updates eq 'a' ) {
		$of = $curpath;
		print "bls.pl will be updated to $ver_s\!\n";
		writelog(" \*\*\* Updating bls.pl to $ver_s\!\n");
	    } elsif ( $check_updates eq 'd' ) {
		if ( $curpath =~ /^(.*?)\.pl$/ ) {
		    $of = "$1_$ver_s\.pl";
		} elsif ( $curpath =~ /^(.*?[\/\\])[^\/\\]+$/ ) {
		    $of = $1 . "bls_${ver_s}\.pl";
		} else {
		    $of = "${curpath}_${ver_s}\.pl";
		}
		print "You should update to $ver_s\!\n";
		writelog(" \*\*\* You should update to $ver_s\! Update filename is \'$of\'.\n");
	    }

	} else {
	    print "You have actual version.\n";
	    return;
	}
	$upd = get( $url . 'bls.pl' );
	unless( defined $upd ) {
	    print STDERR "Can't get update.\n";
	    writelog("Can't get update. ${url}bls.pl\n");
	    return;
	}
	if ( open ( OF, ">$of") ) {
	    binmode(OF);
	    print( OF $upd );
	    close(OF);
	    chmod 0755, $of if $^O eq 'linux';
	    print "$of saved.\n\n";
	} else {
	    print STDERR "Can't open $of ($!).\n";
	}
    } else {
	print STDERR "Can't connect to $url\n";
	writelog("Can't connect to $url\n");
    }
    exit if $check_updates eq 'f';
}


sub packpkt
{
    my ($pkt_from,$pkt_to,$password, @msgs ) = @_;
    $pkt_from =~ /(\d+)\:(\d+)\/(\d+)\.?(\d*)/;
    my ( $pkt_origzone, $pkt_orignet, $pkt_orignode, $pkt_origpnt ) = ( $1, $2, $3, $4 );
    $pkt_origpnt = 0 if !defined $pkt_origpnt || $pkt_origpnt eq '';
    $pkt_to =~ /(\d+)\:(\d+)\/(\d+)\.?(\d*)/;
    my ( $pkt_destzone,$pkt_destnet,$pkt_destnode,$pkt_destpnt ) = ( $1,$2,$3,$4 );
    $pkt_destpnt = 0 if !defined $pkt_destpnt || $pkt_destpnt eq '';
    $password = '' unless defined $password;
    $password .= "\x00" while length($password) < 8;

    my ($second,$minute,$hour,$day,$month,$year,$wday,$yday,$isdst) = localtime();
    $year = $year + 1900;
    $yday++;

    my $pkthdr = pack("S2S3S3 S2S2 C2A8S2S2 C2SS4I", $pkt_orignode,
    $pkt_destnode,$year,$month,
    $day,$hour,$minute,$second,0,2,$pkt_orignet,$pkt_destnet,3,3,
    $password,$pkt_origzone,$pkt_destzone,0, 0x0100,3,3,0x0001,
    $pkt_origzone,$pkt_destzone,$pkt_origpnt,$pkt_destpnt, 0 );

    return $pkthdr . join('',@msgs) . "\000\000";
}

sub packedmsg($$$$$$$;$$)
{
    my ( $msg_fromname, $msg_toname, $msg_fromaddr, $msg_toaddr, $attr,
         $msg_txt, $msg_subj, $msg_area, $msg_chrs ) = @_;

    my ( $msgheader,$m_txt,$msg_destzone,$msg_destnet,$msg_destnode,
         $msg_destpnt);
         
    $msg_txt =~ s/\n/\r/g;

    if (length($msg_fromname) > 35){
	$msg_fromname = substr($msg_fromname,0,35);
    }
    $msg_fromname .= "\000";
    if (length($msg_toname) > 35){
	$msg_toname = substr($msg_toname,0,35);
    }
    $msg_toname .= "\000";
    if (length($msg_subj) > 71){
	$msg_subj = substr($msg_subj,0,71);
    }
    $msg_subj .= "\000";

    localtime =~ /[a-z]+ ([a-z]+)[ ]+(\d+) (\d+)\:(\d+)\:(\d+) \d\d(\d\d)/i;
    my $DateTime = sprintf("%02s", $2)." $1 $6  $3:$4:$5\000";

    $msg_fromaddr =~ /(\d+)\:(\d+)\/(\d+)\.?(\d*)/;
    
    my ( $msg_origzone, $msg_orignet, $msg_orignode, $msg_origpnt ) = ( $1, $2, $3, $4 );
    $msg_origpnt = 0 if !defined( $msg_origpnt ) || $msg_origpnt eq '';

    if ( defined($msg_toaddr) ) {
       $msg_toaddr =~ /(\d+)\:(\d+)\/(\d+)\.?(\d*)/;
       ($msg_destzone,$msg_destnet,$msg_destnode,$msg_destpnt) = ( $1, $2, $3, $4 );
       $msg_destpnt = 0 if !defined($msg_destpnt) || $msg_destpnt eq '';
    } else {
       ($msg_destzone,$msg_destnet,$msg_destnode,$msg_destpnt) = ( 0, 0, 0, 0 );
    }

    $msgheader = pack( "S7Z20", 2,$msg_orignode,$msg_destnode,
    $msg_orignet,$msg_destnet,$attr,0,$DateTime ) . $msg_toname .
    $msg_fromname . $msg_subj;

    $m_txt = "AREA:$msg_area\r" if defined($msg_area);
    my $TZUTC = sprintf( "%04d", tzoffset( localtime() ) );
    $m_txt .= "\001MSGID: $msg_fromaddr ".sprintf("%08x", time())."\r\001TZUTC: $TZUTC\r";
    
# NO INTL in Echmail permitted
    $m_txt .= "\001INTL $msg_destzone:$msg_destnet/$msg_destnode $msg_origzone:$msg_orignet/$msg_orignode\r" if !defined $msg_area;
    $m_txt .= "\001CHRS: ".uc($msg_chrs)." 2\r" if defined $msg_chrs;
    $m_txt .= "\001FMPT $msg_origpnt\r" if $msg_origpnt != 0;
    $m_txt .= "\001TOPT $msg_destpnt\r" if $msg_destpnt != 0 && !defined $msg_area;
    $msg_fromaddr =~ /(\d+\:\d+\/\d+\.?\d*)/;
    $msg_txt .= "\r--- \r \* Origin: perl packPKT by Stas Mishchenkov [2:460/58] \($1\)\r";

    my ( $g_sec, $g_min, $g_hour, $g_mday,$g_month,$g_year) = (gmtime)[0...5];
    if ( defined( $msg_area ) ) {
       if ( $msg_origpnt == 0 ) {
            $msg_txt .= "SEEN\-BY: $msg_orignet\/$msg_orignode\r".
	    "\x01PATH: $msg_orignet\/$msg_orignode\r";
       }
    } else {
	$msg_txt .= sprintf("\x01Via $msg_fromaddr \@%04d%02d%02d\.%02d%02d%02d\.UTC perl packPKT by Stas Mishchenkov\r",
	$g_year+1900, $g_month+1, $g_mday, $g_hour, $g_min, $g_sec );
    }
return "$msgheader$m_txt$msg_txt\000";
}

sub writepkt($$)
{
   my ( $dir, $pkt ) = @_;

   my $tmppath = catfile( $dir, 'temp.tmp' );
   make_path( $tmppath, { mode => 0755, } );
   my $tmppktname = catfile( $tmppath, sprintf( "%08x", time() ) . '.qqq' );
   $tmppktname = catfile( $tmppath, sprintf( "%08x", time() + 1 ) . '.qqq' ) while -e $tmppktname;
   if ( open( my $fh, ">$tmppktname" ) ) {
      binmode($fh);
      print $fh $pkt;
      close($fh);
   } else {
      print STDERR "Can't open $tmppktname ($!).\n";
      return;
   }
   my $pktname = catfile( $dir, sprintf( "%08x", time() ) . '.pkt' );
   $pktname = catfile( $dir, sprintf( "%08x", time() + 1 ) . '.pkt' ) while -e $pktname;
   print STDERR "Can't rename $tmppktname to $pktname ($!)\n" unless move($tmppktname,$pktname);
}

sub writelog
{
    my ( $str ) = @_;
    if ( defined($logfile) ) {
        my ($sec,$min,$hour,$mday,$month,$year) = (localtime)[0...5];
        if ( open( FLOG, ">>$logfile") ) {
            print( FLOG sprintf("%04d-%02d-%02d %02d:%02d:%02d $str\n",
                                $year+1900, $month+1, $mday, $hour,$min,$sec) );
            close( FLOG );
        } else {
            print(STDERR "Can't open $logfile. ($!)\n");
        }
    }
}


sub setvar
{
	my @monthes = ( undef, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul',
			'Aug', 'Sep', 'Oct', 'Nov', 'Dec' );
	my ($mm,$dd);

	$char{0}=" ";
	$char{1}="°";
	$char{2}="±";
	$char{3}="²";
	$char{4}="Û";

#	$graphheader  = "RealName: Evil Robot\n\n * From $startperiod till $endperiod *\n\n                     0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223\n";
#	$tableheader  = "RealName: Evil Robot\n\n * From $startperiod till $endperiod *\nÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n³     Node address       ³  Sent bytes  ³Received bytes³   In     Out  Sess. ³\nÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n";
        $graphfooter  = "\n\" \" - 0 sessions, ° - 1 session, ± - 2 sessions,\n² - 3 sessions, Û - 4 or more sessions.\n\n";
#        $tablefooter  = "ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n³                Total:  ³" . sprintf("%14s", $totalSent) ."³" . sprintf("%14s", $totalRcvd) ."³" . sprintf("%21s", $totalSess) ."³\n";

	$outdir = Cwd::realpath('.') unless defined( $outdir );
	$alltbl = catfile($outdir, "graph866.txt");
	$sesstbl = catfile($outdir, "sesstbl.txt");

	if ( defined($forday) ) {
		if ( $forday =~ /^(\d{1,2})[\.\-\/](\d{1,2})$/ ) {
			($mm,$dd) = ($2,$1);
			$mm = sprintf("%d ",$mm);
			$forday = sprintf("%02d ",$dd) . $monthes[$mm];
		} else {
			undef $forday;
		}
#		print "$forday\n";
	}
}


sub readbinkdconf
{

    my $point="0";
    my ($zone, $net, $node,$_address, $domain, $password,$z,$n,$f,$p,$aa);

#	print "Reading $binkdconf\n";
	unless (open (F, "<$binkdconf")) {
		printf( "Can not open $binkdconf: $!\r");
		exit(1);
	}
	
	$nodes=0;
	while (defined(my $line = <F>)) {
		$line =~ s/	/ /g;
		$line =~ s/^ //g;
		next if $line =~ /^\#.*/i;
		
		if ( $line =~ /^[ ]*address[ ]+(\d+)\:(\d+)\/(\d+)\.*\d*\@.*/i && !defined ($node)) {
			($zone, $net, $node)=($1, $2, $3);
			next;
		}
		
		if ($line =~ /^[ ]*log[ ]+([^ ]+).*/i) {
			$binkdlog = $1;
			next;
		}

		if ($line =~ /^[ ]*sysop[ ]+\"([^\r\n]+)\".*/i) {
			$msgfromname = $1 unless defined $msgfromname;
			next;
		}

		if ( $line =~ /^[ ]*node[ ]+([^ ]+)[ ]+([^ ]+)[ ]+([^ ]+).*/i ) {
			($_address, $domain, $password) = ($1, $2, $3);

			$nodes++;

			if ($_address =~ /^(\d+)\:\d+.*/) {
				$z=$1;
			} else {
				$z=$zone;
			}
			if ($_address =~ /^\d+\:(\d+)\/.*/ || $_address =~ /^(\d+)\/.*/) {
				$n=$1;
			} else {
				$n=$net;
			}

			if ($_address =~ /.*\/(\d+)\..*/ || $_address =~ /.*\/(\d+)$/ || $_address =~ /^(\d+)\..*/ || $_address =~ /^(\d+)$/) {
				$f=$1;
			} else {
				$f=$node;
			}
			if ($_address =~ /.*\.(\d+)$/) {
				$p=$1;
			} else {
				$p=$point;
			}
			
			if ($p != 0) {
				$aa="$z\:$n\/$f\.$p";
			} else {
				$aa="$z\:$n\/$f";
			}
			
			$addr{$aa}{'def'}=1;
			$list{$nodes}=$aa;
			$sessFrom{$aa}=0;
			$sessTo{$aa}=0;
			$addrR{$aa}=0;
			$addrS{$aa}=0;
		}
	}
	
	close(F);
	print("Binkd log file not found in specified config!\n") && exit unless defined $binkdlog;
}


sub readbinkdlog
{
	my($direction,$day, $hour, $minsec,
		$address, $result, $sent, $rcvd);
#	print "Reading $binkdlog\n";
	unless (open (F, "<$binkdlog")) {
		printf( "Cannot open $binkdlog: $!\r");
		exit();
	}

  while (defined(my $line = <F>)) {
	$line =~ s/\r?\n$//s;

	next unless $line =~ /^. (\d\d [a-z]{3}) (\d\d):(\d\d:\d\d) \[\d+\] done \((from|to) (\d+\:\d+\/\d+\.?\d*)\@[^,]+, ([^,]+), S\/R\: \d+\/\d+ \((\d+)\/(\d+) bytes\)\)$/i;
	($day, $hour, $minsec, $direction, $address, $result, $sent, $rcvd) = ($1, $2, $3, $4, $5, $6, $7, $8);
	if (defined($forday)) {
		next unless $day eq $forday;
	}
	
	if ( !defined($startperiod) ) {
		$startperiod="$day $hour:$minsec";
	}

	if ( $direction eq "from" ) {
		$sessFrom{$address}++;
	}
	if ( $direction eq "to" ) {
		$sessTo{$address}++;
	}
#	print "$address\n";
	if ( !defined( $addr{$address}{'def'} ) ) {
		$nodes++;
		$addr{$address}{'def'} = 1;
		$addrS{$address}=$sent;
		$addrR{$address}=$rcvd;
		$list{$nodes}=$address;
	} else {
		$addrS{$address}+=$sent;
		$addrR{$address}+=$rcvd;
        }
	if ( !defined($addr{$address}{$direction})) {
		$addr{$address}{$direction}=1;
	} else {
		$addr{$address}{$direction}++;
	}
	if ( !defined($tab{$address}{$hour}) ) {
		$tab{$address}{$hour}=1;
	} else {
		if ($tab{$address}{$hour} < 4) {
			$tab{$address}{$hour}++;
		}
	}
  }     
  $endperiod="$day $hour:$minsec";
  close(F);

}


sub qsortp
{
  my $n = 1;
  my $a = '0';
  my ( $nn, $z, $ne, $f, $p, $zn, $nen, $fn, $pn );
  until( $n == $nodes ) {
	$nn=$n+1;
	if ( $nn <= $nodes ) {


	$list{$n} =~ /(\d+)\:(\d+)\/(\d+)\.?(\d*)/;
	($z, $ne, $f, $p) = ($1, $2, $3, $4);
	if ($p !~ /\d+/) { $p = 0; }

	$list{$nn} =~ /(\d+)\:(\d+)\/(\d+)\.?(\d*)/;
	($zn, $nen, $fn, $pn) = ($1, $2, $3, $4);
	if ($pn !~ /\d+/) { $pn = 0; }

		if (($z <=> $zn || $ne <=> $nen || $f <=> $fn || $p <=> $pn) == 1) {
	       		$a = $list{$n};
			$list{$n}=$list{$nn};
			$list{$nn}=$a;
		}
        }
	$n++;
  }
  qsortp() if $a ne 0;
}

my ( $pktfromaddress, $pktpassword, $pkttoaddress, $msgfromaddress, $posttable,
     $postgraph, %filternodes, %filterstr );

sub readconf()
{
#	print "Reading config file $configfile.\n";
	my ( $fh, $line );
	unless ( open( $fh, "<$configfile") ) {
		print STDERR "Can't open $configfile ($!).\n";
		writelog("Can't open $configfile ($!).");
		return;
	}
	while( $line = <$fh> ) {
		$line =~ s/[\r\n]//g;
		$line =~ s/	/ /g;
		next if $line =~ /^[ ]*\#/;
		if ( $line =~ /[ ]*pktfromaddress[ ]+(\d+\:\d+\/\d+\.?\d*)/i) {
			$pktfromaddress = $1;
		} elsif ( $line =~ /[ ]*pktpassword[ ]+([^ ]{1,8})/i ) {
			$pktpassword = $1;
		} elsif ( $line =~ /[ ]*pkttoaddress[ ]+(\d+\:\d+\/\d+\.?\d*)/i ) {
			$pkttoaddress = $1;
		} elsif ( $line =~ /[ ]*msgfromname[ ]+(.{1,35})/i ) {
			$msgfromname = $1;
		} elsif ( $line =~ /[ ]*msgfromaddress[ ]+(\d+\:\d+\/\d+\.?\d*)/i ) {
			$msgfromaddress = $1;
		} elsif ( $line =~ /[ ]*binkdconf[ ]+([^ \r\n]+)/i ) {
			$binkdconf = $1 unless defined $binkdconf;
		} elsif ( $line =~ /[ ]*outdir[ ]+([^ \r\n]+)/i ) {
			$outdir = $1 unless defined $outdir;
		} elsif ( $line =~ /[ ]*posttable[ ]+([^\r\n]+)$/i ) {
			$posttable = uc($1);
		} elsif ( $line =~ /[ ]*postgraph[ ]+([^\r\n]+)$/i ) {
			$postgraph = uc($1);
		} elsif ( $line =~ /[ ]*filternodes[ ]+\(([^\r\n]+?)\)[ ]+([^\r\n]+)/i ) {
			$filternodes{$1} = uc($2);
		}
	}
	close($fh);
}

sub writetxt($$)
{
   my ( $fname, $txt ) = @_;
   my ( $fh, $tmpname ) = ( undef, $fname . time() );
   if ( open( $fh, ">$fname" ) ) {
	binmode( $fh );
        print( $fh $txt );
        close( $fh );
#	print STDERR "Can't rename $tmpname to $fname ($!).\n" unless 
	move( $tmpname, $fname );
   } else {
       print STDERR "Can't open $tmpname ($!).\n";
   }
}

	export_conf() if $export;

        help() if defined $needhelp;

	update();

        readconf() if defined $configfile;

        help() unless defined $binkdconf;

	setvar();

	readbinkdconf();
	readbinkdlog();
	unless( defined $startperiod ) {
		print( "No log entryes for $forday.\n");
		exit ;
	}
	$graphheader  = "RealName: Evil Robot\n\n * From $startperiod till $endperiod *\n\n                     0 1 2 3 4 5 6 7 8 9 1011121314151617181920212223\n";
	$tableheader  = "RealName: Evil Robot\n\n * From $startperiod till $endperiod *\nÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n³     Node address       ³  Sent bytes  ³Received bytes³   In     Out  Sess. ³\nÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n";
	qsortp();

	my ( $allstr, $sessstr ) = ( $graphheader, $tableheader );
     
	foreach my $f ( keys %filternodes ) {
		$filterstr{$f} = $graphheader;
	}

  my $n=1;
  my $totalSent=0;
  my $totalRcvd=0;
  my $totalSess=0;
  my ($h,$hh,$strout,$c);
  until( $n > $nodes ) {
	$h=0;
	$strout="³";

	$strout=$strout . sprintf("%-20s", $list{$n});
	until( $h == 24) {
		$hh=sprintf("%02d", $h);
		$a=$list{$n};
		if ( defined($tab{$a}{$hh})) {
			$c=$tab{$a}{$hh}; 
                } else { $c=0; }
		$strout=$strout . "³$char{$c}";
		$h++;
	}
	$strout=$strout . "³\n";
#	$allstr .= sprintf("%3s", $n) . $strout;
	$allstr .= $strout;

	foreach my $f ( keys %filternodes ) {
		if ( $list{$n} =~ /$f/) {
			$filterstr{$f} .= $strout;
		}

	}

	$sessFrom{$a} = 0 if !defined($sessFrom{$a});
	$sessTo{$a} = 0 if !defined($sessTo{$a});
#	$sessstr .= "³" . sprintf("%3s", $n) . "³" . sprintf("%-20s", $a) . "³" . sprintf("%14s", $addrS{$a}) . "³" . sprintf("%14s", $addrR{$a}) . "³" . sprintf("%6s", $sessFrom{$a})  . "³" . sprintf("%6s", $sessTo{$a})  . "³"  . sprintf("%7s", $sessTo{$a} + $sessFrom{$a})  . "³" ."\n";
	$sessstr .= sprintf("³ %-23s", $a) . "³" . sprintf("%14s", $addrS{$a}) . "³" . sprintf("%14s", $addrR{$a}) . "³" . sprintf("%6s", $sessFrom{$a})  . "³" . sprintf("%6s", $sessTo{$a})  . "³"  . sprintf("%7s", $sessTo{$a} + $sessFrom{$a})  . "³" ."\n";

	$totalSent+=$addrS{$a};
	$totalRcvd+=$addrR{$a};
	$totalSess+=$sessTo{$a} + $sessFrom{$a};

	$n++;
  }

  $allstr .= $graphfooter;
  $sessstr .= "ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n³                Total:  ³" . sprintf("%14s", $totalSent) ."³" . sprintf("%14s", $totalRcvd) ."³" . sprintf("%21s", $totalSess) ."³\n";
  foreach my $f ( keys %filternodes ) {
	$filterstr{$f} .= $graphfooter;
  }

   my ( $i, $m );
#   if ( $ext == 1 ) {
       $m = '';
       if ( defined($posttable) ) {
          foreach $i ( split(  / /, $posttable ) ) {
            $m .= packedmsg( $msgfromname, 'All', $msgfromaddress,
                             $msgfromaddress, LOC, $sessstr,
                             'Sessions statistics table', $i, 'cp866');
          }
       }
       if ( defined($postgraph) ) {
          foreach $i ( split(  / /, $postgraph ) ) {
            $m .= packedmsg( $msgfromname, 'All', $msgfromaddress,
                             $msgfromaddress, LOC, $allstr,
                             'Sessions graph', $i, 'cp866');
          }
       }
       foreach $i ( keys %filternodes ) {
            $m .= packedmsg( $msgfromname, 'All', $msgfromaddress,
                             $msgfromaddress, LOC, $filterstr{$i},
                             'Sessions graph', $filternodes{$i}, 'cp866');
#            $filterstr{$f} .= $strout;
       }
       writepkt( $outdir, 
                 packpkt( $pktfromaddress,$pkttoaddress,$pktpassword, $m )
               ) unless $m eq '';
#   } else { $write_text = 1 }

#   if ( $write_text ) {
       writetxt( $alltbl, $allstr );
       writetxt( $sesstbl, $sessstr );
#   }

#	foreach my $ft ( keys %filternodes ) {
#		print "$filterstr{$ft}\n";
#	}

exit;
#----------------------------------------------------------------------------
