#! /usr/bin/perl


use strict;

use IO::File;
use IO::Pipe;
use File::Copy;

use Net::hostent;
use Socket;

use gateway_lib;

chdir("/tmp");

my $TMCC = "/usr/local/etc/emulab/tmcc";
my $RC_ROUTE = "/usr/local/etc/emulab/rc/rc.route";
my $tmcc_p = new IO::Pipe() || die "Can't open pipe: $!\n";
my $shared_config_dir;
my $local_config_dir = "/usr/local/federation/etc";
my %services;
my $perl;

my $gateway;
my $smbshare = "USERS";
my $smbuser;
my $smbproject;
my $exp;
my $proj;
chomp (my $uname = `uname`);
my $smbmount = "smbmount.$uname.pl";

# find perl
for my $p ("/usr/bin/perl", "/usr/local/bin/perl") {
    if ( -x $p ) {
	$perl = $p;
	last;
    }
}
$perl = "perl" unless $perl;


$tmcc_p->reader("$TMCC -b status");
while (<$tmcc_p>) {
    /ALLOCATED=([^\/]+)\/(\S+)/ && do {
	($proj, $exp) = ($1, $2);
	$shared_config_dir = "/proj/$proj/exp/$exp/tmp";
	last;
    };
}
$tmcc_p->close();

mkdir($local_config_dir);

foreach my $fn ("seer.conf", "client.conf", "userconf") {
    copy("$shared_config_dir/$fn", $local_config_dir )
	if -e "$shared_config_dir/$fn";
}

my $client = new IO::File("$local_config_dir/client.conf");
while (<$client>) {
    chomp;
    /ControlGateway:\s+(.*)/i && do { $gateway = $1; };
    /SMBShare:\s+(.*)/i && do { $smbshare = $1; };
    /ProjectUser:\s+(.*)/i && do { $smbuser = $1; };
    /ProjectName:\s+(.*)/i && do { $smbproject = $1; };
    /Service:\s+(.*)/i && do { $services{$1}++;};
}
$client->close();
# Create the /etc/hosts file
my $hosts = new IO::File("/etc/hosts") || die "Can't open /etc/hosts:$!\n";
my $new_hosts = new IO::File(">/tmp/hosts") || die "Can't open /tmp/hosts:$!\n";
my $config_hosts = new IO::File("$shared_config_dir/hosts") || 
    die "Can't open $shared_config_dir/hosts: $!\n";
my $has_control = 0;

while (<$hosts>) {
    /^127\.0\.0\.1/ && do { print $new_hosts $_; };
    /control\./ && $has_control++;
}
$hosts->close();
while (<$config_hosts>) {
    print $new_hosts $_;
}
$config_hosts->close();

# If seer is enabled and no local control node in play, alias the gateway to be
# control
if ($services{'seer'} && !$has_control ) {
    if ( my $hent = gethostbyname($gateway) ) {
	my $gwip = inet_ntoa($hent->addr_list->[0]);

	print $new_hosts "\n$gwip\tcontrol.$exp.$proj\n";
    }
}
$new_hosts->close();
copy("/tmp/hosts", "/etc/hosts");

# Ick.  at least one of our images has gated in the wrong place (sigh).  If
# so, fix it and restart routing.  
if (!-x "/usr/sbin/gated" && -x "/sbin/gated" ) {
    print "Linking to /sbin/gated and starting routing\n";
    symlink("/sbin/gated", "/usr/sbin/gated");
    system("$RC_ROUTE boot") if -x $RC_ROUTE;
}

# If there are tunnelip interfaces to bring up, bring 'em
system("$perl -I/usr/local/federation/lib " . 
    "/usr/local/federation/bin/config_from_tunnelip.pl");


if ($services{'userconfig'}) {
    $tmcc_p = new IO::Pipe() || die "Can't open pipe for accounts:$!\n";
    my $old_accounts = new IO::File(">$local_config_dir/old_accts") || 
	die "Can't open $local_config_dir/old_accts: $!\n";

    $tmcc_p->reader("$TMCC -b accounts");
    while (<$tmcc_p>) {
	print $old_accounts $_;
    }
    $tmcc_p->close();
    $old_accounts->close();
    print("Updating accounts");
    system("/usr/local/federation/bin/rc.fedaccounts");
}

if ($services{'SMB'}) {
    if ($uname =~ /FreeBSD/ ) {
	system("umount -A -f -t nfs,smbfs,cifs");
    }
    elsif ($uname =~ /Linux/ ) {
	# Pass individual filestems to Linux umount.  No -A.
	my $mtab = new IO::File("/etc/mtab") || die "Can't open /etc/mtab:$1\n";
	while (<$mtab>) {
	    chomp;
	    my @F = split($_);
	    next unless $F[2] =~ /(nfs|cifs|smbfs)/;
	    system("umount -f $F[1]");
	}
    }

    print "Waiting for SMB server\n";
    gateway_lib::wait_for_port($gateway, 139, 60*60) || 
	die "SMB server never came up\n";
    print "Mounting via SMB\n";
    system("$perl /usr/local/federation/bin/$smbmount $smbshare $gateway " . 
	"$smbuser $smbproject");
}

if ($uname =~ /FreeBSD/ ) {
    # Restart ntp
    system("/etc/rc.d/ntpd stop; /usr/sbin/ntpdate boss; " . 
	"/etc/rc.d/ntpd start;");
					       
}
elsif ($uname =~ /Linux/ ) {
    # restart ntp
    system("/etc/rc.d/init.d/ntpd stop; /usr/sbin/ntpdate boss; ". 
	"/etc/rc.d/init.d/ntpd start");
}

# startcmd
if ($ARGV[0] && $ARGV[1]) {
    if ($uname =~ /FreeBSD/) {
	system("su -l \"$ARGV[0]\" -c \"$ARGV[1]\"");
    }
    elsif ($uname =~ /Linux/) {
	system("su \"$ARGV[0]\" --command \"$ARGV[1]\"");
    }
}
exit(0);
