#!/usr/bin/perl
##############################################################################
#                                                                            #
# BigBen V 0.5                                                               #
#                                                                            #
# $Id: BigBen,v 1.13 1998/01/17 12:31:06 cesare Exp cesare $                 #
##############################################################################

$revision="0.5";
$internal_revision="1.13";

### Signal catch ###
$SIG{"INT"}='trap_signal';
$SIG{"QUIT"}='trap_signal';
$SIG{"TERM"}='trap_signal';

### Port where BigBen is listening ###
$port=4455;

### Log file name ###
$logfile="/tmp/BigBen.log";
$log_event=1;

### Workdir ###
$workdir="./store";

print "BigBen $revision - by Pizzi Cesare\n";
print "Type BigBen -h to see the available options\n";

&parse_options();

&check_Weber();

&accept_connection($port);

if (($child=fork()) == 0) {

	### Unlink the process from the terminal ###
	setpgrp();

	for ($con=1; ; $con++) {
		($addr=accept(NS,S)) || die $!;

		if (($child=fork())==0) {

			($af,$port,$inetaddr)=unpack($sockaddr,$addr);
			@inetaddr=unpack('C4',$inetaddr);
			$inetaddr=$inetaddr[0].".".$inetaddr[1].".".$inetaddr[2].".".$inetaddr[3];

			### Open the data file ###
			if (open(OUTFILE,">$workdir/$inetaddr/data")) {

				### Disable buffering ###
				select(OUTFILE);
				$|=1;

				&log_message("$con: $af $port $inetaddr") if $log_event == 1;

				### Read from the port and save the data ###
				while (<NS>) {

					print OUTFILE "$_";
				}

				### Close all ###
				close(NS);
				close(OUTFILE);

			} else {
				### If we are not able to open the file ###

				&log_message("WARNING: $!") if $log_event == 1;
			}

			exit;
		}
		close(NS);
	}

	exit;
}

exit;

##############################################################################
#                                                                            #
# SUBROUTINES                                                                #
#                                                                            #
##############################################################################

###############################################
### Accept a connection on a specified port ###
###############################################
sub accept_connection {

	### Get parameters ###
	local $port=shift;

	###############################
	### Defines local variables ###
	###############################
	local $AF_INET, $SOCK_STREAM, $sockaddr, $name, $aliases;
	local $proto, $this;

	$AF_INET=2;
	$SOCK_STREAM=1;

	$sockaddr='S n a4 x8';

	($name,$aliases,$proto)=getprotobyname('tcp');
	if ($port !~ /^\d+$/) {
		($name,$aliases,$port)=getservbyport($port,'tcp');
	}

	$this=pack($sockaddr,$AF_INET,$port,"\0\0\0\0");

	select(NS);
	$|=1;

	select(stdout);

	if (socket(S,$AF_INET,$SOCK_STREAM,$proto)) { 
		### Nothing ###
	} else {
		&log_message("ERROR: $!") if $log_event == 1;
		die;
	}

	if (bind(S,$this)) {
		### Nothing ###
	} else {
		&log_message("ERROR: $!") if $log_event == 1;
		die;
	}

	if (listen(S,5)) {
		### Nothing ###
	} else {
		&log_message("ERROR: $!") if $log_event == 1;
		die;
	}
}

#################################################
### Handle the signal received by the program ###
#################################################
sub trap_signal {

	local ($sig)=@_;

	#################################
	### Check the received signal ###
	#################################

	if ($sig eq 'INT' || $sig eq 'QUIT' || $sig eq 'TERM') {

		&log_message("Signal received: $sig. Exit") if $log_event == 1;
		exit(0);

	} else {
		### Unknown signal. Ignore it. ###
	}
}

#######################################################################
### Check if Weber is running, or if the working directory is wrong ###
#######################################################################
sub check_Weber {

	local $err;

	$err="Weber is not running, or the Workdir is not correctly set. Exit.";

	### Check the existance of $workdir/main.html ###
	if (!(-e "$workdir/main.html")) {

		### The Weber is not running ###
		print "\n$err\n";
		&log_message("$err") if $log_event == 1;

		exit(1);
	}
}

######################################
### Parse the command line options ###
######################################
sub parse_options {

        while ($_=$ARGV[0],s/^-( ?)(.+)$/$2/ && shift(@ARGV)) {

		next if $_ eq '';

		### Help screen ###
		if (/^h/) { &usage(); }

		### Set the log file name ###
		if (/^l(.*)$/) {
			if ($1) {
				$logfile=$1;
			} else {
				$logfile=$ARGV[0];
				shift(@ARGV);
			}

			next;
		}

                ### Set the port where BigBen is listening ###
		if (/^p(\d*)$/) {
			if ($1) {
				$port=$1;
			} else {
				$port=$ARGV[0];
				shift(@ARGV);
			}

			next;
		}

		### Disable logging ###
		if (/^nolog$/) {
			$log_event=0;

			next;
		}

		### Set working directory ###
		if (/^d(.*)$/) {
			if ($1) {
				$workdir=$1;
			} else {
				$workdir=$ARGV[0];
				shift(@ARGV);
			}

			next;
		}

		&usage();
	}
}

###################################
### Display the program options ###
###################################
sub usage {

	print "Usage: BigBen [options]\n\n";
	print "\t-d xxx     Working directory (default: $workdir)\n";
	print "\t           WARNING: this MUST be the same set in Weber\n";
	print "\t-p nnn     Port where BigBen is listening (default: $port)\n";
	print "\t-l xxx     Log file (default: $logfile)\n";
	print "\t-nolog     Disable logging\n";
	print "\t-h         This page\n";
	print "\n";

	exit(0);
}

#####################################################
### Log function. Open a log file and write in it ###
#####################################################
sub log_message {

	### Get the parameter ###
	local $message=shift;
	local $date;

	open(LOG,">>$logfile") || warn "Can't open log file: $!";

	chop($date=`/bin/date`);
	print LOG "$date: $message\n";

	close(LOG);
}
