#!/usr/bin/perl
# Author is Stas Mishchenkov 2:460/58.
# Generates polls in BSO
#
use strict;
use warnings;

use Getopt::Long;

my $defaultzone = 2;
our $outbound = '/home/fido/outbound/fidonet';

my ( $logfile, $pollnodes, $listpollnodes, $config, $fromfile );

#$ENV{TMP} =~ /([\\\/])/;

GetOptions ( "poll-nodes=s"      => \$pollnodes,
             "config=s"          => \$config,
             "from-file=s" =>       \$fromfile,
             "outbound=s"        => \$outbound,     # string
             "zone-default=i"    => \$defaultzone,  # integer
             "log-file=s"        => \$logfile )     # string
or die("Error in command line arguments\n");


sub readconf()
{
	my $line;
	printf( STDERR "Cannot open $config: $!\r") && return '' unless open( CF, "<$config" );

	while (defined($line = <CF>)) {
		$line =~ s/\r//g;
		$line =~ s/\n//g;
		$line =~ s/	/ /g;
		next if $line =~ /^[ ]*\#.*/;

		if ( $line =~ /^[ ]*DefaultZone[ ]+(\d+).*/i ) {
			$defaultzone = $1;
		} elsif( $line =~ /^[ ]*outbound[ ]+([^ ]+).*/i ) {
			$outbound = $1;
		} elsif( $line =~ /^[ ]*logfile[ ]+([^ ]+).*/i ){
			$logfile = $1;
		}  elsif( $line =~ /^[ ]*node[ ]+([^ ]+).*/i ){
			$pollnodes .= " $1";
		}
	}
	close(CF);
}

sub readfromfile()
{
	my $fb;
	if ( open( F, $fromfile) ) {
		read( F, $fb, -s $fromfile );
		close(F);
	}
	$fb =~ s/\r/ /sg;
	$fb =~ s/\n/ /sg;
	$fb =~ s/	/ /sg;
#	$fb =~ s/  / /sg while $fb =~ /  /sg;
#	$fb =~ s/^ //g;
#	$fb =~ s/ $//g;
return $fb;
}

sub dolog($)
{
    my ( $logstr ) = @_;
    return if !defined ( $logfile );
    my @ltime = localtime();
    my $logtime = sprintf( "%04d-%02d-%02d %02d:%02d:%02d", 1900+$ltime[5], 1+$ltime[4], $ltime[3], $ltime[2], $ltime[1], $ltime[0] );

    if( open( LF, ">>$logfile" ) ) {
	print( LF "$logtime $logstr\n" );
	close( LF );
    } else { print STDERR "Cant open \'$logfile\'. ($!)\n"; }
}

$outbound =~ /([\\\/])/;
my $slash = $1;

sub getbsoname($)
{
	my ( $address ) = @_;

	$address =~ /(\d+)\:(\d+)\/(\d+)\.?(\d*)/;
	my ( $destzone, $destnet, $destnode, $destpnt ) = ( $1, $2, $3, $4 );
	$destpnt = 0 if !defined( $destpnt ) || $destpnt eq "";

	$outbound =~ s/[\\\/]+^//s if $outbound =~ /[\\\/]+^/;
	my $bsoname = $outbound;
	$bsoname  = sprintf( "$outbound.%03x", $destzone ) if $destzone != $defaultzone;
	mkdir $bsoname unless -e $bsoname;

	$bsoname .= $slash;

	$bsoname .= sprintf("%04x", $destnet) . sprintf("%04x", $destnode);
	if ( defined ( $destpnt ) && $destpnt != 0 ) {
		$bsoname .= '.pnt';
		mkdir $bsoname unless -e $bsoname;
		$bsoname .= $slash;
		$bsoname .= sprintf( "%08x", $destpnt );
	}

return $bsoname;
}

if (defined($fromfile)){
	if (defined($pollnodes)) {
		$pollnodes .= ' ' . readfromfile();
	} else {
		$pollnodes = readfromfile();
	}
}

if ( defined( $config ) ){
	readconf();
}

if ( !defined( $pollnodes ) ) {
	print(
		"Usage: $0 options\n".
		"~~~~~~\n".
		"were options are:\n".
		"                     -c\n".
		"                    --config=config filename. May be omitted.\n".
		"                     -f\n".
		"                    --from-file=filename with space, tab or carriage return\n".
		"                               separated list of nodes to poll. May be omitted.\n".
		"                     -l\n".
		"                    --log-file=log file name. If omitted no logfile will be\n".
		"                               created.\n".
		"                     -o\n".
		"                    --outbound=path to youre outbound. May be omitted.\n".
		"                               Default \'/home/fido/outbound/fidonet\'.\n".
		"                     -p\n".
		"                    --poll-nodes=\"list of node adress\" if more then one address\n".
		"                               listed it must be in a quters. May be omitted.\n".
		"                     -z\n".
		"                    --zone-default=zone youre zone number. May be omitted.\n".
		"                               Default 2.\n".
		"   You can mix any options. At least one node addres to poll must be specified\n in any way. You can mix ways to specify addresses to poll.\n The configuration file prevails over the command line options, except for the\n list of nodes to be added.\n"

	);
	exit;
}

$pollnodes =~ s/  / /sg while $pollnodes =~ /  /sg;
$pollnodes =~ s/ $//sg;
$pollnodes =~ s/^ //sg;

our @nodes = split( / /, $pollnodes );

my $filename;

for my $addr ( @nodes ) {

	$filename = getbsoname($addr);
	dolog("$addr is busy.") && next if -e "$filename.bsy";
	dolog("Poll for $addr already exists.") && next if -e "$filename.clo";
#	print $filename."\n";
	if( open( F, ">>$filename.clo") ) {
		close(F);
		dolog("Poll for $addr created.")
	} else {
		print STDERR "Can't create $filename.clo ($!)\n";
		dolog("Can't create poll for node $addr. Filename $filename.clo (Error: $!)");
	}
}

