#!/usr/bin/perl
#    Big Sister network monitor
#    Copyright (C) 1998  Thomas Aeby
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#

#=============================================================================
#
$BigSister::common::Usage	  = "[-D level] [-r]";
#
#=============================================================================
@BigSister::common::options = ( "r" );
use lib "$ENV{BIGSISTER_CHROOT}/usr/local/bigsister/bin"; use lib "$ENV{BIGSISTER_CHROOT}/usr/local/bigsister/uxmon"; #inslib
use BigSister::common;
proginit();

use strict;
use Win32::Registry;

my $dl = $BigSister::common::dl;
my $binmode = 1;
my $cwd = `cd`;
$cwd =~ s/[\r\n]//g;
my $cdrive = $cwd;
$cdrive =~ s/^(.*?):.*/$1/;
($cdrive = "C") unless( $cdrive );

$ENV{"PATH"} = $cwd.";".$cwd."\\bin;$BigSister::common::progdir;$BigSister::common::root\\bin;$BigSister::common::root;".$ENV{"PATH"};

print "path is ".$ENV{"PATH"}."\n" if( $dl>3 );

my $have_win32daemon = 0;
eval {
    require Win32::Daemon;
    $have_win32daemon = 1;
    print "You do have Win32::Daemon - good\n";
};

my $perl = find_prog( "perl" );
my $instsrv = find_prog( "instsrv" );
my $srvany = find_prog( "srvany" );
my $cygrunsrv = find_prog( "cygrunsrv" );
my $bbd = find_prog( "bbd" );

unless( $bbd ) {
    unless( -f $BigSister::common::root."/bin/bbd" ) {
	print STDERR "\nIt seems that you haven't installed Big Sister in
the default location $BigSister::common::root. Unfortunately Big Sister will
not work under this circumstances ...
Either use 'make' to install Big Sister at the location you prefer
or get the binary distribution ...\n";
	exit(1);
    }
    $bbd = $BigSister::common::root."/bin/bbd";
    $binmode = 0;
}
my $root_path = $bbd;
$root_path =~ s/.bin.bbd.*//i;
$root_path =~ tr/\//\\/;
$root_path =~ s/^\\/$cdrive:\\/;
print "Big Sister is installed in $root_path\n";

unless( ($instsrv && $srvany) || $cygrunsrv || $have_win32daemon ) {
    print STDERR "
If you would like to run Big Sister as a service you
need the cygrunsrv program, the instsrv/srvany utilities
from Microsoft or the Win32::Daemon perl module.";
}
else {
    my @services = ( [ "BigSuxmon", "Big Sister Agent", "uxmon", "", "Monitors local and remote systems" ],
		  [ "BigSbbd", "Big Sister Server", "bbd", "", "Accepts status messages from Big Sister Agent and forwards them to the Big Sister Monitor" ],
		  [ "BigSmon", "Big Sister Monitor", "bsmon", "", "Reacts on status messages being received by Big Sister Server" ]
		  );
    my $service;
    foreach $service (@services) {
	my $cmd = $service->[2];
	if( -f $root_path."\\bin\\$cmd.exe" ) {
	    $cmd = $root_path."\\bin\\$cmd.exe";
	}
	else {
	    my $dir = "bin";
	    if( $cmd eq "uxmon" ) { $dir = "uxmon"; };
	    $service->[3] = $root_path."\\$dir\\$cmd";
	    $cmd = $perl;
	}
	$service->[2] = $cmd;
    }
    if( $BigSister::common::opt_r ) {
	print "removing Big Sister services\n";
	my $srv;
	foreach $srv (@services, [ "BigSevent", "Big Sister Event Generator" ]) {
	    if( $have_win32daemon ) {
		Win32::Daemon::DeleteService( "", $srv->[0] );
	    }
	    elsif( $cygrunsrv ) {
		system( "$cygrunsrv -R \"$srv->[0]\"" );
	    }
	    else {
		system( "$instsrv \"$srv->[0]\" REMOVE" );
	    }
	}
    }
    else {
	print "registering Big Sister services\n";
	my $srv;
	foreach $srv (@services) {
	    if( $have_win32daemon ) {
	        my $result = Win32::Daemon::CreateService( {
		    "name" => $srv->[0],
		    "display" => $srv->[1],
		    "description" => $srv->[4],
		    "path" => $srv->[2],
		    "parameters" => $srv->[3],
		    "start_type" => ($srv->[0] =~ /uxmon/)
		     		    ? Win32::Daemon::SERVICE_AUTO_START()
				    : Win32::Daemon::SERVICE_DEMAND_START(),
		} );
		unless( $result ) {
		    print STDERR "failed to register ".($srv->[1]).": ".Win32::Daemon::GetLastError()."\n";
		}
	    }	
	    elsif( $cygrunsrv ) {
	        system( $cygrunsrv,
		    "-I", $srv->[0],
		    "-p", cygpath( $srv->[2] ),
		    "-d", $srv->[1],
		    "-t", ($srv->[0] =~ "uxmon") ? "auto" : "manual",
		    "-c", cygpath( $root_path."\\bin" ),
		    "-a", $srv->[3],
		    "-f", $srv->[4]
		    );
	    }
	    else {
		system( "$instsrv \"$srv->[0]\" $srvany" );
		service_reg( $srv->[0], $srv->[1], $srv->[2], $root_path."\\bin", $srv->[3], ($srv->[0] =~ /uxmon/)?"auto":"manual" );
	    }
	}
    }
}

unless( $BigSister::common::opt_r ) {
    print "switching on diskperf monitoring\n";
    system( "diskperf -y" );
    print "registering the Big Sister root directory: $root_path\n";
    my $reg;
    unless( $main::HKEY_LOCAL_MACHINE->Create( "Software\\GraeffComm\\BigSis", $reg ) ) {
	print "  registration failed!!\n";
    }
    else {
	$reg->SetValueEx( "RootDir", undef, REG_SZ(), $root_path );
    }

    print <<END


Your Big Sister should now be installed. Please go to the Control Panel, 
choose Services and set the startup options for the Big sister services 
as you want them to be set.

Do not forget to at least minimally configure your Big Sister - at
least you will have to edit $root_path\\adm\\uxmon-net and let
'bsdisplay' point to your Status Collector.

Note: you can de-install the Big Sister services using 'install32 -r'.

Good luck!
END
    ;
}



sub find_prog {
    my( $prog, $ext ) = @_;

    my $where = Platform::perlpath( $prog, $ext );
    unless( $where ) {
	print "Hmh, you haven't got $prog\n";
    }
    else {
	print "$prog is installed as $where\n";
    }
    return $where;
}


sub service_reg {
    my( $service, $display, $command, $dir, $args, $start ) = @_;
    my $reg;
    my $param;

    unless( $main::HKEY_LOCAL_MACHINE->Open( "System\\CurrentControlSet\\Services\\$service", $reg ) ) {
	print "could not configure service $display: $!\n";
	return;
    }
    unless( $main::HKEY_LOCAL_MACHINE->Create( "System\\CurrentControlSet\\Services\\$service\\Parameters", $param ) ) {
	$reg->Close();
	print "could not configure service $display: $!\n";
	return;
    }
    $reg->SetValueEx( "DisplayName", undef, REG_SZ(), $display );
    $reg->SetValueEx( "Start", undef, REG_DWORD(), ($start eq "auto")?2:3 );
    $param->SetValueEx( "Application", undef, REG_SZ(), $command );
    $param->SetValueEx( "AppDirectory", undef, REG_SZ(), $dir );
    $param->SetValueEx( "AppParameters", undef, REG_SZ(), $args );
    $reg->Close();
    $param->Close();
}


sub cygpath {
    my( $path ) = @_;

    $path =~ s#\\#/#g;
    if( $path =~ /^([a-z]):/i ) {
        $path = "/cygdrive/$1$'";
    }
    return $path;
}
