#!/usr/bin/perl
until($config_check =~ /^(y|yes)$/i) {
    chomp($uname = `uname`);
    $version = "0.1.1-beta";
    $stb_path = "/var/stb";
    $htdocs_path = "/var/www/htdocs";
    $cnupm_path = "/var/cnupm";
    $localnet = "192.168.0.0/16";
    $httpd_user = "www";

    undef @all_if;
    undef $bridge;
    undef $use_bridge;
    foreach $i (`ifconfig -a`) {
	if($i =~ /^(\w+)(\d): flags=\w+<UP/) {
	    push @all_if, "$1$2";
	}
    }
    unless(@all_if[1]) {
	print "You have only one network interface.\nSTB require two and more interfaces.\nExiting..\n";
	sleep(1);
	exit;
    }
    print "Please, specify the following parameters:\n";
    print "Path to STB statistics [$stb_path]: ";
    undef $str;
    chomp($str = <STDIN>);
    if($str) {
	$str =~ s/\/$//;
	$stb_path = $str;
    }
    print "Path to Apache htdocs [$htdocs_path]: ";
    undef $str;
    chomp($str = <STDIN>);
    if($str) {
	$str =~ s/\/$//;
	$htdocs_path = $str;
    }
    print "Cnupm home directory [$cnupm_path]: ";
    undef $str;
    chomp($str = <STDIN>);
    if($str) {
	$str =~ s/\/$//;
	$cnupm_path = $str;
    }
    undef $str;
    undef $ext_if;
    until($ext_if) {
	undef @last_if;
	print "External interface (@all_if) [@all_if[0]]: ";
	chomp($str = <STDIN>);
	if($str) {
	    foreach(@all_if) {
		if($_ eq $str) {
		    $ext_if = $str if($str);
		} else {
		    push @last_if, $_;
		}
	    }
	    if(!$ext_if) {
		print "$0: ERROR: Invalid interface ($str) for external intarface.\n";
	    }
	} else {
	    $ext_if = @all_if[0];
	    shift @all_if;
	    @last_if = @all_if;
	}
    }
    undef $ans;
#    unless($bridge) {
	print "Use bridge with one ip-adress for all internal interfaces? (yes/no) [no]: ";
	chomp($ans = <STDIN>);
	if($ans =~ /^(y|yes)$/i) {
	    $bridge = 1;
	    $use_bridge = 1;
	}
#    }
    undef $ans;
    undef @int_if;
    until($ans =~ /^(n|no)$/i) {
	undef $str;
	undef $int_if;
	until($int_if) {
	    undef @tmp;
	    if($bridge) {
		print "Internal interface for bridge with one ip-adress (@last_if) [@last_if[0]]: ";
	    } else {
		print "Internal interface (@last_if) [@last_if[0]]: ";
	    }
	    chomp($str = <STDIN>);
	    if($str) {
		foreach(@last_if) {
		    if($_ eq $str) {
			push @int_if, $_;
			$int_if = 1;
		    } else {
			push @tmp, $_;
		    }
		}
		@last_if = @tmp;
		if(!$int_if) {
		    print "$0: ERROR: Invalid interface ($str) for internal intarface.\n";
		} else {
		    undef $bridge;
		}
	    } else {
		push @int_if, @last_if[0];
		shift @last_if;
		$int_if = 1;
		undef $bridge;
	    }
	}
	unless(@last_if) {
	    $ans = "no";
	    last;
	}
	print "Specify one more internal interface? (yes/no) [no]: ";
	chomp($ans = <STDIN>);
	$ans = "no" unless $ans;
    }
    undef $localnet_ok;
    until($localnet_ok) {
	print "Local sub-net [$localnet]: ";
	undef $str;
	chomp($str = <STDIN>);
	if($str) {
	    if($str =~ /\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}\/\d{1,2}/) {
		$localnet = $str;
		$localnet_ok = 1;
	    } else {
	        print "$0: ERROR: Invalid localnet ($str).\n";
	    }
	} else {
	    $localnet_ok = 1;
	}
    }
    print "Apache user [$httpd_user]: ";
    undef $str;
    chomp($str = <STDIN>);
    if($str) {
	$httpd_user = $str;
    }
    print "Please, check your settings:\n";
    print "=========================================================\n";
    print "Path to STB statistics:\t\t\t$stb_path\n";
    print "Cnupm home directory:\t\t\t$cnupm_path\n";
    print "Path to Apache htdocs: \t\t\t$htdocs_path\n";
    print "External interface:\t\t\t$ext_if\n";
    print "Internal interfaces:\t\t\t@int_if\n";
    if($use_bridge) {
	print "Use bridge:\t\t\t\tYes\n";
	print "Internal interface for bridge:\t\t@int_if[0]\n";
    } else {
	print "Use bridge:\t\t\t\tNo\n";
    }
    print "Localnet:\t\t\t\t$localnet\n";
    print "Apache user:\t\t\t\t$httpd_user\n";
    print "=========================================================\n";
    print "Configuration is correct? (yes/no) [no]: ";
    undef $config_check;
    chomp($config_check = <STDIN>);
}
print "Cool! Begining instalation...\n";

open(stb_sample, "<_etc/stb.conf.sample") or die "Open _etc/stb.conf.sample: $!\n";
open(stb, ">_etc/stb.conf") or die "Open _etc/stb.conf: $!\n";
while(<stb_sample>) {
    chomp;
    $_ =~ s/STB_PATH/$stb_path\t\t/;
    $_ =~ s/CNUPM_PATH/$cnupm_path\t\t/;
    $_ =~ s/EXT_IF/$ext_if\t\t\t/;
    if($_ =~ /INT_IF/) {
	@tmp = @int_if;
	$int_ifs = @tmp[0];
	shift @tmp;
	foreach $if (@tmp) {
	    $int_ifs = "$int_ifs, $if";
	}
	$_ =~ s/INT_IF/$int_ifs\t\t\t/;
    }
    $_ =~ s/LOCALNET/$localnet\t\t/;
    $_ =~ s/HTTPD_USER/$httpd_user\t\t\t/;
    printf stb "$_\n";
}
close(stb_sample);
close(stb);

open(pf_sample, "<_etc/pf.conf.sample") or die "Open _etc/stb.conf.sample: $!\n";
open(pf, ">_etc/pf.conf") or die "Open _etc/stb.conf: $!\n";
while(<pf_sample>) {
    chomp;
    $_ =~ s/EXT_IF/$ext_if/;
    if($_ =~ /INT_IF/) {
	unless($use_bridge) {
	    @tmp = @int_if;
	    $int_ifs = @tmp[0];
	    shift @tmp;
	    foreach $if (@tmp) {
		$int_ifs = "$int_ifs, $if";
	    }
	} else {
	    $int_ifs = @int_if[0];
	}
	$_ =~ s/INT_IF/$int_ifs/;
    }
    $_ =~ s/PASSIP/$stb_path\/etc\/pass.ip/;
    printf pf "$_\n";
}
close(pf_sample);
close(pf);
$startup_script = "echo -n \"STB\"; $stb_path/bin/cnupmstart.pl";
if($uname eq "OpenBSD") {
    open(rc, ">>/etc/rc.local");
    printf rc "\n# Simple Traffic Billing (v.$version) [begin]\n";
    printf rc $startup_script;
    printf rc "\n# Simple Traffic Billing (v.$version) [end]\n";
    close(rc);
    open(crontab, ">>/var/cron/tabs/root");
    printf crontab "\n# Simple Traffic Billing (v.$version) [begin]\n*/1\t*\t*\t*\t*\t/usr/bin/perl\t$stb_path/bin/stat.pl\n# Simple Traffic Billing (v.$version) [end]\n";
    close(crontab);
    system("pkill cron");
}
if($uname eq "FreeBSD") {
    open(rc, ">/usr/local/etc/rc.d/stb.sh");
    printf rc "#!/bin/sh\n\n";
    printf rc "# Simple Traffic Billing (v.0.1-beta)\n";
    printf rc $startup_script;
    close(rc);
    system("chmod +x /usr/local/etc/rc.d/stb.sh");
    open(crontab, ">>/etc/crontab");
    printf crontab "\n# Simple Traffic Billing (v.$version) [begin]\n*/1\t*\t*\t*\t*\troot\t/usr/bin/perl\t$stb_path/bin/stat.pl\n# Simple Traffic Billing (v.$version) [end]\n";
    close(crontab);
    system("killall cron");
}
if($uname eq "NetBSD") {
    open(rc, ">/etc/rc.d/stb");
    printf rc "#!/bin/sh\n\n";
    printf rc "# Simple Traffic Billing (v.0.1-beta)\n";
    printf rc $startup_script;
    close(rc);
    system("chmod +x /etc/rc.d/stb");
    open(crontab, ">>/var/cron/tabs/root");
    printf crontab "\n# Simple Traffic Billing (v.$version) [begin]\n*/1\t*\t*\t*\t*\t/usr/bin/perl\t$stb_path/bin/stat.pl\n# Simple Traffic Billing (v.$version) [end]\n";
    close(crontab);
    system("killall cron");
}
system("cron");
system("install -b -c -o $httpd_user -g $httpd_user -m 600 _etc/stb.conf /etc/stb.conf");
system("install -b -c -o root -g wheel -m 600 _etc/pf.conf /etc/pf.conf");
system("mkdir -p $htdocs_path/stb");
system("mkdir -p $stb_path/log $stb_path/reports $stb_path/messages");
system("cp -R www/* $htdocs_path/stb/");
system("cp -R stat/* $stb_path/");
system("chown -R $httpd_user:$httpd_user $stb_path/etc $stb_path/log $stb_path/reports $stb_path/messages");
print "Instalation is complete.\n";
print "Reload rules for PF:\n";
print "\tpfctl -e\n";
print "\tpfctl -f /etc/pf.conf\n";
print "Run $stb_path/bin/cnupmstart.pl for starting cnupm.\n";
print "Go to http://yourdomain/stb/ and use this account:\n\n";
print "\tLogin:\t\tadmin\n";
print "\tPassword:\tadmin\n\n";
