#!/usr/bin/perl
#
# Generates pointsegment from binkd logfile.
# written by Stas Mishchenkov 2:460/58
#
#@CHRS: CP866

use strict;
use warnings;

use Getopt::Long;
use LWP::Simple;
use Cwd 'abs_path';

my $vers = 'v.0.0.0.4';

my ( $config, $needhelp, $prinver, $whatsnew, $export, $check_updates, $logfile,
	$BinkdConf, $BinkdLogMonth, $pntfiledir, $pntfileflag, $NetMail, %var,
	$RobotFromName, $ErrorSubj, $NPKaddress, $NPKname, $SendFileMethod,
	$newnailflag, %pntlst, $pointnumber, %cfgpntlst, $ExecuteBefore,
	$ExecuteAfter, $err_wrongname, $err_longname, $err_xxsysopname,
	$err_xxlocname, $err_xxsystemname, @abbr, @wdaray, $pntliststr, 
	$bossnode, $pntfilename, $pvt, $cra, $att, $k_s, $loc, $hld, $req, $rrq,
	$rrd, $aud, $Error_Message, $errorsonly, $binkdconflog, $pntfilenamesize,
	$sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst, $SystemName,
	$location, $newmailflag, $domain, $brakeboxes, $outbaund, $PntFileflag,
	$defaultzone, $sysopname, %systemname, %location, %sysopname, $Errormsg
   );

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

sub usage()
{
	printf <<USAGE;

Generates node pointsegment from binkd logfile.
					Written by Stas Mishchenkov 2:460/58.

Usage: lazypoint.pl options
~~~~~~
       Options:

        --config,-c[=]filename  Name of config file. Required.

        --export,-e        Export configuration and exit.

        --ver,-V           Print version and exit.
        --whatsnew,-w      Print whats new in new version and exit. Internet
                           connection requierd.
        --only-errors,-o   Don\'t create poin segment. Cheek errors only.
        --update,-u        How to update the program. Optional.
                                  =a - auto. Check for a new version, download
                                       and update.
                                  =d - download. Check for a new version and
                                       download the update to a new file.
                                  =f - Force download lazypoint.pl end exit
                                       even if no new version is found.
                                  =w - warn. Check for a new version and warn
                                       the sysop. Default.
                                  =n - no. Do nothing. 

         --log,-l[=]filename      The name of log file.
                                  No logging if not defined.

         --help,-h        This text.

USAGE
	exit;
}

sub exportcfg()
{
	printf <<CONFIG;

# lasypoint config file
# Generates pointsegment from binkd logfile.
# written by Stas Mishchenkov 2:460/58
#
#\@CHRS: CP866
#------------------------------------------------------------------------------
#
# Required
BinkdConf /home/fido/etc/binkd.cfg
#
#
# monthly log file name. If defined, will be used insted of filename
# from binkd.conf
# имя лог файла из архива за месяц. Если определен, то будет использован вместо
# лог файла из binkd.conf
BinkdLogMonth /home/fido/logs/tmp/binkd.log
#
#
# ExecuteBefore "command"
# Каманда, которая будет выполнена перед разбором логфайла и построением
# поинтсегмента.
# Можно использовать для создания лог файла за месяц из архива.
# Поддерживаются следующие макро:
# #mon# - Будет подставлен Прошлый месяц в формате mm (01, 02, 03 ... 12)
# #year# - Будет подставлен Год. Если #mon# = 12, то прошлый год. (2018, 2017).
# #binkdlog#  - Будет подставлено то, что BinkdLogMonth в этом конфиге.
#
#ExecuteBefore "/home/fido/bin/pointlog.sh '/home/fido/logs/arc/#year#-#mon#-??.zip'"
#ExecuteBefore "rar p -inul -y d:\\fido\\logs\\arc\\#year#\\binkd.rar #mon#??.log \>#binkdlog#"
#
#ExecuteAfter "echo All done."
# Будет выполнено после разбора лога, создания поинтсегмента и отправки его NPK.
# Поддерживаются следующие макро:
# #mon# - Будет подставлен Прошлый месяц в формате mm (01, 02, 03 ... 12)
# #year# - Будет подставлен Год. Если #mon# = 12, то прошлый год. (2018, 2017).
# #binkdlog#  - Будет подставлено то, что BinkdLogMonth в этом конфиге.
# #pntname# - имя файла поинтсегмента (без пути, тольо имя и расширение).
# #fullpntname# - полное имя файла поинтсегмента (с путём).
# 
#
# where to put your new pointsegment
# куда сложить твой новый поинтсегмент.
PntFileDir  /home/fido/tmp/perl/point
#
#
# flag file created if new pointsegment is
# Флаг, что создан новый поинтсегмент.
PntFileflag home/fido/flags/pnt.new
#
# Netmail MSG base directory
# Директория в которй лежит нетмей (MSG база)
NetMail	/home/fido/mail/NetMail/
#
# От чьего имени будут писаться письма в нетмейл.
# From whom netmail messages will be.
RobotFromName  "Lazy PointList"
#
#
# To whom send pointsegment
# кому отсылать поинтсегмент
NPKaddress  2:460/58
#
NPKname "NPK"
#
#
# Метод отправки поинтсегмента.
# How to send pointsegment.
# attach | uue | box <flavor> | bso <flavor> | no
# (Flavor may be Hold, Direct, Normal, Crush, Immediat)
#
# Netmail attach
SendFileMethod  Attach
#
# Netmail with UUEncoded file inside
#SendFileMethod  UUE
#
# Copy pnt segment to BrakeBox of NPK node
#SendFileMethod  box Direct
#
# Send file by Bink Style Outbound
#SendFileMethod  bso Normal
#
# Send nothing
#SendFileMethod  No
#
# flag created if new mail is.
# флаг создается, если есть неотправленное письмо.
#NewMailFlag /home/fido/flags/scan.NetMail
#
#
# тема письма об ошибках, отправляемого поинту.
# error message subject
ErrorSubj "Error in your config."
#
#
err_wrongname "Starting #037/09 one word sysop names are no longer permitted except the keyword 'UUCP'."
#err_wrongname "Имена сисопов из одного слова, кроме 'UUСP', не разрешены с 037 дня 2009 года."
#
err_longname "SysOp name can not be longer then 35 letters include space. The result is:"
#err_longname "Имя сисопа не может быть длиннее 35 симфволов, влючая пробелы. Исправлено на:"
#
err_xxsysopname "Not permitted letters in SysOp name replaced by '#'. The result is:"
#err_xxsysopname "Недопустимые символы в имени сисопа заменены на '#'. В результате получилось:"
#
err_xxlocname "Not permitted letters in location name replaced by '#'. The result is:"
#err_xxlocname "Недопустимые символы в наименовании местоположения заменены на '#'. В результате получилось:"
#
err_xxsystemname "Not permitted letters in System name replaced by '#'. The result is:"
#err_xxsystemname "Недопустимые символы в наименовании системы (станции) заменены на '#'. В результате получилось:"
#
# owerride binkd.log. may be many.
FixedPoint ,10,Rabbits_Hole,Simferopol_Crimea,Brother_Rabbit,-Unpublished-,300,MO
#
#------------------------------------------------------------------------------
CONFIG
	exit;
}

sub createflagfile($)
{

	my($file) = @_;

	if ( open(FF, ">$file") ) {
		close(FF);
	} else {
		printf( "Can't create $file: $!\r");
	}
}

sub readbinkdcfg()
{

	my($line, $keyword, $rest);
    
	if (open(CFG, "<$BinkdConf")) {
	        while ( $line = <CFG>) {
			$line =~ s/	/ /gs;
			$line =~ s/[ ]+$//s;
			$line =~ s/\r?\n$//s;
			next if $line =~ /^[ ]*\#.*/i;
			$line =~ /^[ ]*([a-zA_Z]+)[ ]+([^ ]+.*)/i;
			($keyword, $rest) = ($1, $2);
			next unless defined $keyword;
			if ($keyword =~ /^domain$/i && !defined($defaultzone)) {
				$rest =~ /([^ ]+)[ ]*([^ ]+)[ ]*(\d+)/i;
				($domain, $outbaund, $defaultzone) = ($1, $2, $3);
				while( $outbaund =~ /([^ ]*)[\\]$/ ) {
					$outbaund = $1;
				}
				while( $outbaund =~ /([^ ]*)[\/]$/ ) {
					$outbaund = $1;
				}
			}
			if ($keyword =~ /^address$/i && !defined($bossnode)) {
				$rest =~ /(\d+\:\d+\/\d+)[^\d]*/i;
				$bossnode = $1;
			}
			if ( $keyword =~ /^sysname$/i ) {
				$rest =~ /\"(.*)\"/;
				$SystemName = $1;
			}
			if ( $keyword =~ /^location$/i ) {
				$rest =~ /\"(.*)\"/;
				$location = $1;
			}
			if ( $keyword =~ /^sysop$/i ) {
				$rest =~ /\"(.*)\"/;
				$sysopname = $1;
			}
			$binkdconflog = $rest if $keyword =~ /^log$/i;
			if ($keyword =~ /^brakebox$/i) {
				$brakeboxes = $rest;
				if ( $brakeboxes =~ /\\/ ) {
					$brakeboxes .= "\\" if $brakeboxes !~ /\\$/;
				} elsif ( $brakeboxes =~ /\// ) {
					$brakeboxes .= "\/" if $brakeboxes !~ /\/$/;
				}
			}
		}
	} else {
		printf("Can't read $BinkdConf ($!)\n");
		writelog("Can't read $BinkdConf ($!)");
		exit();
	}
}


sub readbinkdlog
{
	my ($file) = @_;
	my ($line, $pid, $keyword, $rest);

	unless (open (F, "<$file")) {
		printf( "Can't open $file: $!\r");
		writelog("Can't open $file: $!");
		exit;
	}

  printf("\n\nReading binkd log file: \"$file\".\n");
  writelog( "Reading binkd log file: \"$file\"." );
  while (defined($line = <F>)) {
	$line =~ s/\r?\n$//s;
	$line =~ s/ $//gs;
	next unless $line =~ /^. \d\d [a-z]{3} \d\d:\d\d:\d\d \[(\d+)\] ([^ ]+) ([^ ]*.*)$/i;
	($pid, $keyword, $rest ) = ($1, $2, $3);
        if ( $keyword =~ /done/ && $rest =~ / OK\,/ ) {
           if ($rest =~ /.* $bossnode\.(\d+)\@.*/) {
		$pointnumber = $1;
#		checkstr();
		$pntlst{$pointnumber} = ",$pointnumber,$systemname{$pid},$location{$pid},$sysopname{$pid},-Unpublished-,300,MO" unless defined $cfgpntlst{$pointnumber};
           }
        } elsif ( $keyword =~ /^SYS$/ ) {
		$systemname{$pid} = "$rest";
		$systemname{$pid} =~ s/ /_/g;
		$systemname{$pid} =~ s/,//g;
        } elsif ( $keyword =~ /^ZYZ$/ ) {
		$sysopname{$pid} = "$rest";
		$sysopname{$pid} =~ s/ /_/g;
		$sysopname{$pid} =~ s/,//g;
        } elsif ( $keyword =~ /^LOC$/ ) {
		$location{$pid} = "$rest";
		$location{$pid} =~ s/ /_/g;
		$location{$pid} =~ s/,//g;
        } elsif ( $keyword =~ /^addr:/ ) {
           if ($rest =~ /^$bossnode\.(\d+)\@.*/i) {
		$pointnumber = $1;
#		checkstr();
		$pntlst{$pointnumber} = ",$pointnumber,$systemname{$pid},$location{$pid},$sysopname{$pid},-Unpublished-,300,MO" unless defined $cfgpntlst{$pointnumber};
           }
        }
  }
  close(F);
}


sub BuildPointlist
{
	printf("\nBuilding pointlist...\n");
	writelog('Building pointlist...');
	foreach my $key ( sort { $a <=> $b } keys %pntlst) {
#		checkstr($pntlst{$key});
		$pntliststr .= checkstr($pntlst{$key}) ."\n";
		$pntlst{$key} =~ /^,([^,]+),[^,]+,[^,]+,([^,]+),.*/;
		printf(sprintf("%-23s","$bossnode.$1")." $2\n");
		writelog( "$bossnode.$1 $2" );
	}

	unless (open (PF, ">$pntfilename")) {
		printf( "Can't open $pntfilename: $!\r");
		writelog( "Can't open $pntfilename: $!." );
		exit;
	}
	print(PF $pntliststr);
	close(PF);
}

sub checkstr
{
	my ( $str ) = @_;

	$str =~ /^\,(\d+)\,([^\,]+)\,([^\,]+)\,([^\,]+)\,(.*)/;
	my ( $point, $system, $loc, $sysop, $flags ) = ( $1, $2, $3, $4, $5 );

	undef $Errormsg;

	if ( $sysop !~ /(UUCP)|(_)/i ) {
		$sysop = "John_$sysop";
		$Errormsg .= "\n$err_wrongname\n";
	}
	if ( length($sysop) > 35 ) {
		$sysop = substr($sysop, 0, 35);
		$Errormsg .= "\n$err_longname \"$sysop\"\n";
	}
	if ( $sysop =~ /[^a-zA-Z_0-9\.\'\[\]\>\<\-\#\=\/\&\$\)\(\:\!\*\+\`\\\}\{\|]/i) {
		$sysop =~ s/([^a-zA-Z_0-9\.\'\[\]\>\<\-\#\=\/\&\$\)\(\:\!\*\+\`\\\}\{\|])/\#/g;
		$Errormsg .= "\n$err_xxsysopname \"$sysop\"\n";
	}
	if ( $loc =~ /[^a-zA-Z_0-9\@\.\'\[\]\>\<\-\#\=\/\&\$\)\(\:\!\*\+\`\\\}\{\|]/i) {
		$loc =~ s/([^a-zA-Z_0-9\@\.\'\[\]\>\<\-\#\=\/\&\$\)\(\:\!\*\+\`\\\}\{\|])/\#/g;
		$Errormsg .= "\n$err_xxlocname \"$loc\"\n";
	}
	if ( $system =~ /[^a-zA-Z_0-9\@\.\'\[\]\>\<\-\#\=\/\&\$\)\(\:\!\*\+\`\\\}\{\|]/i) {
		$system =~ s/([^a-zA-Z_0-9\@\.\'\[\]\>\<\-\#\=\/\&\$\)\(\:\!\*\+\`\\\}\{\|])/\#/g;
		$Errormsg .= "\n$err_xxsystemname \"$system\"\n";
	}

	if ( defined $Errormsg ) {
		writemsg($bossnode,"$bossnode\.$point",$sysopname,
			$sysop,$ErrorSubj,$pvt+$loc,"\n$Errormsg\n",
			"$SystemName\. $location");
		createflagfile( $newmailflag ) if defined $newmailflag;
		writelog( $Errormsg );
		return ",$point, $system, $loc, $sysop, $flags";
	} else {
		return $str;
	}
}


sub writemsg($$$$$$$$)
{
	my ($origaddress, $destaddress, $fromUserName, $toUserName, $subject,
		$attr, $msgtext, $origintext) = @_;
	my ($DateTime, $msgheader, $Kludges, $msgnum );

	$origaddress =~ /(\d+)\:(\d+)\/(\d+)\.?(\d*)/;
	my ($origzone, $orignet, $orignode, $origpoint) = ($1, $2, $3, $4);
	if ( !defined( $origpoint ) || $origpoint eq '' ) {
		$origpoint = 0;
	}
	$destaddress =~ /(\d+)\:(\d+)\/(\d+)\.?(\d*)/;
	my ($destzone, $destnet, $destnode, $destpoint) = ($1, $2, $3, $4);
	if ( !defined( $destpoint ) || $destpoint eq ''  ) {
		$destpoint = 0;
	}

	localtime() =~ /[a-z]+ ([a-z]+) (\d+) (\d+):(\d+):(\d+) \d\d(\d\d)/i;
	$DateTime = "$2 $1 $6 $3:$4:$5\000";

	$msgheader = pack("Z36Z36Z72Z20S13",
		$fromUserName,$toUserName,$subject,$DateTime,
		\000,$destnode,$orignode,\000,$orignet,$destnet,$destzone,
		$origzone,$destpoint,$origpoint,\000,$attr,\000);

	$Kludges = "\001INTL $destzone\:$destnet\/$destnode $origzone\:$orignet\/$orignode\n";
	$Kludges .= "\001TOPT $destpoint\n" if $destpoint != 0;
	$Kludges .= "\001FMPT $origpoint\n" if $origpoint != 0;
	$Kludges .= "\001MSGID: $origaddress ". sprintf("%08x", time()) . "\n\001CHRS: CP866 2\n\001PID: Lazy Pointlist\n";

	my $maxorigintextlen = 65 - length($origaddress);
	$origintext = substr($origintext, 0, $maxorigintextlen) if length($origintext) > $maxorigintextlen;

	$msgnum = 1; $msgnum++ while -e $NetMail . $msgnum . "\.msg";

	if (open (MSGHANDLE, ">$NetMail" . $msgnum . "\.msg")) {
		print(MSGHANDLE $msgheader . $Kludges . $msgtext .
		"\n--- Lazy Pointlist" .
		"\n * Origin: $origintext ($origaddress)\000" );
		close(MSGHANDLE);
	} else {
		printf( "Can't open $NetMail" . $msgnum . "\.msg: $!\r");
	}

}


sub tobrakebox
{
	my ( $file, $addr, $dom, $flav, $boxes ) = @_;
	my ( $buff, $bboxf );
	$addr .= ".0" if $addr !~ /\.[\d]+$/;
	$addr =~ s/\:/\./;
	$addr =~ s/\//\./;
	$bboxf = $boxes . ucfirst( lc($dom) ). ".$addr.".ucfirst( lc($flav) ."\\" ) if $boxes =~ /\\/;
	$bboxf = $boxes . ucfirst( lc($dom) ). ".$addr.".ucfirst( lc($flav) ."\/" ) if $boxes =~ /\//;
	mkdir $bboxf unless -e $bboxf;
	$file =~ /([^\\\/]+)$/;
	$bboxf .= $1;
	if ( open(FO, "<$file") ) {
		if ( open(FR, ">$bboxf") ) {
			sysread( FO, $buff, -s $file );
			syswrite( FR, $buff );
			close(FR);
		} else {
			printf( "Can't open $bboxf: $!\r");
		}
		close(FO);
	} else {
		printf( "Can't open $file: $!\r");
	}
}


sub createBSOattach
{
	my ( $file, $flavor, $bso) = @_;
	$flavor = "f" if $flavor =~ /Normal/i;
	my $attach = "$bso." . substr( lc( $flavor ), 0, 1) . "lo";
	my $x = 20; while ( $x != 0 ) {
		if ( -e "$bso.bsy" ) {
			sleep 2;
		}
		$x--;
	}
	return "BUSY" if -e "$bso.bsy" ;

	createflagfile( "$bso.bsy" );

	if ( open( FA, ">>$attach") ) {
		print( FA "$file\n");
		close( FA );
		unlink("$bso.bsy");
		return "Ok";
	} else {
		printf("Can't open file $attach ($!)\n");
		return "error";
	}
}

sub getBSOname($$)
{
	my ( $addr, $out ) = @_;
	$addr =~ /([\d]+)\:([\d]+)\/([\d]+)\.?([\d]*)/;
	my ( $zone, $net, $node, $point ) = ( $1, $2, $3, $4 );
        my ( $bsoname );

	$bsoname  = $out;
	$bsoname .= ".".sprintf("%03x", $zone) if $zone != $defaultzone;
	mkdir $bsoname unless -e $bsoname;

	$bsoname .= "\\" if $bsoname =~ /\\/;
	$bsoname .= "\/" if $bsoname =~ /\//;

	$bsoname .= sprintf("%04x", $net) . sprintf("%04x", $node);
	if ( defined ( $point ) && $point != 0 ) {
		mkdir $bsoname unless -e $bsoname;
		$bsoname .= "\\" if $bsoname =~ /\\/;
		$bsoname .= "\/" if $bsoname =~ /\//;
		$bsoname .= sprintf( "%08x", $point );
	}
	return $bsoname;
}


sub initvar()
{
	my ( $subvar );
	($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
	$year = $year + 1900;
	$yday++;

	@abbr = qw(January February March April May June July August September October November December);
	@wdaray = qw(Sunday Monday Tuesday Wednesday Thursday Friday Saturday);

	$pntliststr = ";\n;A Poinlist of node $bossnode for $wdaray[$wday], $abbr[$mon] ".sprintf("%02d", $mday).", $year -- Day number ".sprintf("%03d", $yday)."\n;\nBoss,$bossnode\n";

	$bossnode =~ /(\d+)\:(\d+)\/(\d+)/;
	my ($origzone, $orignet, $orignode) = ($1, $2, $3);
	$pntfilename = $pntfiledir."PNT".sprintf("%05d", $orignode).".".sprintf("%03d", $yday);

	if ($mon == 0) {
	    $mon = 12;
	    $year--;
	}
#	$mon = sprintf("%02d", $mon);
	$var{"\#mon\#"} = sprintf("%02d", $mon);
	$var{"\#year\#"} = $year;

	$pvt = 0x0001;
	$cra = 0x0002;
	$att = 0x0010;
	$k_s = 0x0080;
	$loc = 0x0100;
	$hld = 0x0200;
	$req = 0x0800;
	$rrq = 0x1000;
	$rrd = 0x2000;
	$aud = 0x4000;

	$var{"\#binkdlog\#"} = $BinkdLogMonth;
	$var{"\#pntname\#"} = "PNT".sprintf("%05d", $orignode).".".sprintf("%03d", $yday);
	$var{"\#fullpntname\#"} = $pntfilename;

	if ( defined( $ExecuteBefore ) ) {
		while( $ExecuteBefore =~/(\#[a-z]+\#)/i ) {
			$subvar = lc($1);
			$ExecuteBefore =~ s/$subvar/$var{$subvar}/sgi;
		}
	}

	if ( defined( $ExecuteAfter ) ) {
		while( $ExecuteAfter =~/(\#[a-z]+\#)/i ) {
			$subvar = lc($1);
			$ExecuteAfter =~ s/$subvar/$var{$subvar}/sgi;
		}
	} 
}



sub readcfg($)
{

	my ($cfgfile) = @_;
	my ($line, $keyword, $rest);
	
	writelog("Reading config file $cfgfile.");
	if (open(CFG, "<$cfgfile")) {
	        while ( $line = <CFG>) {
			$line =~ s/	/ /gs;
			$line =~ s/\r?\n$//s;
			$line =~ s/[ ]+$//s;
			next if $line =~ /^[ ]*\#.*/i;
			$line =~ /^[ ]*([a-zA_Z]+)[ ]+([^ ]+.*)/i;
			($keyword, $rest) = ($1, $2);
			$BinkdConf = $rest if  $keyword =~ /^BinkdConf$/i;
			$BinkdLogMonth = $rest if  $keyword =~ /^BinkdLogMonth$/i;
			if ($keyword =~ /^PntFileDir$/i) {
				$pntfiledir = $rest;
				if ( $pntfiledir =~ /\\/ ) {
					$pntfiledir .= "\\" if $pntfiledir !~ /\\$/;
				} elsif ( $pntfiledir =~ /\// ) {
					$pntfiledir .= "\/" if $pntfiledir !~ /\/$/;
				}
			}
			$pntfileflag = $rest if $keyword =~ /^PntFileflag$/i;
			if ( $keyword =~ /^NetMail$/i) {
				$NetMail = $rest;
				if ( $NetMail =~ /\\/ ) {
					$NetMail .= "\\" if $NetMail !~ /\\$/;
				} elsif ( $NetMail =~ /\// ) {
					$NetMail .= "\/" if $NetMail !~ /\/$/;
				}
			}
			if ( $keyword =~ /^RobotFromName$/i ) {
				$rest =~ /\"([^\"]+)\"/;
				$RobotFromName = $1;
			}
			if ( $keyword =~ /^ErrorSubj$/i ) {
				$rest =~ /\"([^\"]+)\"/;
				$ErrorSubj = $1;
			}
			$NPKaddress = $rest if $keyword =~ /^NPKaddress$/i;
			if ( $keyword =~ /^NPKname$/i ) {
				$rest =~ /\"([^\"]+)\"/;
				$NPKname = $1;
			}
			$SendFileMethod = $rest if $keyword =~ /^SendFileMethod$/i;
			$newnailflag = $rest if $keyword =~ /^NewMailFlag$/i;
			if ( $keyword =~ /^FixedPoint$/i ) {
				$rest =~ /\,(\d+)\,/;
				$pntlst{$1} = $rest;
				$pointnumber = $1;
				$cfgpntlst{$1} = 1;
			}
			if ( $keyword =~ /^ExecuteBefore$/i) {
				$rest =~ /\"([^\"]+)\"/;
				$ExecuteBefore = ($1);
			}
			if ( $keyword =~ /^ExecuteAfter$/i) {
				$rest =~ /\"([^\"]+)\"/;
				$ExecuteAfter = ($1);
			}
			if ( $keyword =~ /^err_wrongname$/i) {
				$rest =~ /\"([^\"]+)\"/;
				$err_wrongname = ($1);
			}
			if ( $keyword =~ /^err_longname$/i) {
				$rest =~ /\"([^\"]+)\"/;
				$err_longname = ($1);
			}
			if ( $keyword =~ /^err_xxsysopname$/i) {
				$rest =~ /\"([^\"]+)\"/;
				$err_xxsysopname = ($1);
			}
			if ( $keyword =~ /^err_xxlocname$/i) {
				$rest =~ /\"([^\"]+)\"/;
				$err_xxlocname = ($1);
			}
			if ( $keyword =~ /^err_xxsystemname$/i) {
				$rest =~ /\"([^\"]+)\"/;
				$err_xxsystemname = ($1);
			}
		}
        close(CFG);
        } else {
		printf("Could not open: $cfgfile ($!)\n");
		writelog("Could not open: $cfgfile ($!).");
		exit(1);
	}
}


sub uuencode($)
{

    my ( $file ) = @_;
    my ( $uuencoded_data, $line );
    
    if (open(ATTCH, $file)) {
        # Process the file
        while (read(ATTCH, $line, 45)) {
            $uuencoded_data .= pack("u", $line);
        } 
        close(ATTCH);

	$file =~ /([^\\|^\/]+)$/;
	$uuencoded_data = "\nbegin 644 $1\n" . $uuencoded_data . "end\n\n";
        return($uuencoded_data);
    }
    else {
        # Return error if file couldn't be opened
        $Error_Message = "Could not open uuencode attachment: $file ($!)";
        writelog( $Error_Message );
        return('');
    }
}

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

    my ( $ver_s, $upd, $of );
#    my $url = 'http://brorabbit.g0x.ru/files/perl/';

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

    $ver_s = get( $url . 'lazypoint.v');
    if (defined ($ver_s) ) {
	if ( $check_updates eq 'f' ) {
		if ( $curpath =~ /^(.*?)\.pl$/ ) {
		    $of = "$1_$ver_s\.pl";
		} elsif ( $curpath =~ /^(.*?[\/\\])[^\/\\]+$/ ) {
		    $of = $1 . "lazypoint_${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 "lazypoint.pl will be updated to $ver_s\!\n";
		writelog(" \*\*\* Updating lazypoint.pl to $ver_s\!\n");
	    } elsif ( $check_updates eq 'd' ) {
		if ( $curpath =~ /^(.*?)\.pl$/ ) {
		    $of = "$1_$ver_s\.pl";
		} elsif ( $curpath =~ /^(.*?[\/\\])[^\/\\]+$/ ) {
		    $of = $1 . "lazypoint_${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 . 'lazypoint.pl' );
	unless( defined $upd ) {
	    print STDERR "Can't get update.\n";
	    writelog("Can't get update. ${url}lazypoint.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 writelog
{
    return unless defined($logfile);
    my ( $str ) = @_;
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
    $str =~ s/([\r\n])$//;
	my $startstr = sprintf("%04d-%02d-%02d %02d:%02d:%02d ",
			       ($year+1900), $mon+1, $mday, $hour, $min, $sec );
    $str =~ s/([\r\n]+)/$1$startstr/g;
	
        if ( open( FLOG, ">>$logfile") ) {
	    syswrite( FLOG, "${startstr}$str\n" );
	    close( FLOG );
        } else {
            printf( STDERR "Can't open $logfile. ($!)\n" );
        }
}


# -----------------------------------------------------------------------------

GetOptions (
            "config=s"    => \$config,
            "help"        => \$needhelp,
            "ver"         => \$prinver,
            "whatsnew"    => \$whatsnew,
            "only-errors"  => \$errorsonly,
            "export"      => \$export,
            "update=s"    => \$check_updates,
            "log=s"       => \$logfile)  # string
or die("Error in command line arguments\n");

$check_updates = 'w' unless defined $check_updates;

if( $prinver ) {
   print "lazypoint.pl $vers\n";
   update();
   exit;
}

update();

if ( $whatsnew ) {
    my $wn = get( $url . 'lazypoint.w');
    if( defined( $wn) ) {
	if ( $wn =~ /^$vers/i ) {
	    print $wn;
	} elsif ( $wn =~ /$vers/i ) {
	    print $`;
	} else { print $wn; }
    } else {
	print "Can't get what's new.\n";
    }
    exit;
}

        exportcfg() if defined $export;
	usage() if $needhelp;
	usage() unless( defined( $config ) );

	readcfg( $config );

	readbinkdcfg();

	initvar();

	if( defined($ExecuteBefore) ) {
	    writelog("Executing \'$ExecuteBefore\'.");
	    system($ExecuteBefore);
	}

	if( defined($errorsonly) ) {
		readbinkdlog( $binkdconflog );
		printf("\nCheck errors only...\n");
		foreach my $key ( sort { $a <=> $b } keys %pntlst) {
			$pntliststr = checkstr($pntlst{$key});
			$pntliststr =~ /^,([^,]+),[^,]+,[^,]+,([^,]+),.*/;
			printf( sprintf("%-23s","$bossnode.$1")." $2\n" );
		}
		exit;
	}
	if ( defined( $BinkdLogMonth ) ) {
		readbinkdlog( $BinkdLogMonth );
#		unlink $BinkdLogMonth;
	} else {
		readbinkdlog( $binkdconflog );
	}

	if ( defined($pointnumber) ) {
		BuildPointlist();
	} else {
		printf("\nNo points found.\n");
		writelog("No points found.");
  		exit(1);
	}

	if ( $SendFileMethod =~ /^attach$/i ) {
		writelog('Sending as netmail attach...');
		$pntfilenamesize = -s $pntfilename;
		$pntfilename =~ /.*[\\|\/]([a-z0-9]{8}\.\d{3})$/i;
		writemsg( $bossnode, $NPKaddress, $RobotFromName,
			$NPKname, $pntfilename, $pvt+$loc+$att,
			"\n$1 $pntfilenamesize bytes.\nPoinlist of node $bossnode for $wdaray[$wday], $abbr[$mon] ".sprintf("%02d", $mday).", $year -- Day number ".sprintf("%03d", $yday)."\n",
			"$SystemName\. $location");
		createflagfile( $newmailflag ) if defined $newmailflag;
	} elsif ( $SendFileMethod =~ /^UUE$/i ) {
		$pntfilename =~ /.*[\\|\/]([a-z0-9]{8}\.\d{3})$/i;
		writemsg( $bossnode, $NPKaddress, $RobotFromName,
			$NPKname,$1,$pvt+$loc, uuencode($pntfilename),
			"$SystemName\. $location");
		createflagfile( $newmailflag ) if defined $newmailflag;
	} elsif ( $SendFileMethod =~ /^box[ ]+([^\s]+)/i ) {
		tobrakebox( $pntfilename, $NPKaddress, $domain, $1, $brakeboxes );
	} elsif ($SendFileMethod =~ /^bso[ ]+([^\s]+)/i) {
		if ( createBSOattach( $pntfilename, $1, getBSOname( $NPKaddress, $outbaund ) ) == "BUSY" ) {
			$pntfilename =~ /.*[\\|\/]([a-z0-9]{8}\.\d{3})$/i;
			writemsg($bossnode,$NPKaddress,$RobotFromName,
				$NPKname,"$1",$pvt+$loc, uuencode($pntfilename),
				"$SystemName\. $location");
			createflagfile( $newmailflag ) if defined $newmailflag;
		}
	}

	createflagfile( $PntFileflag ) if defined $PntFileflag;
	if( defined($ExecuteAfter) ){
	    writelog( "Execute \'$ExecuteAfter\'." );
	    system($ExecuteAfter);
	}

#exit(0);
#------------------------------------------------------------------------------
