#!/usr/bin/env perl

BEGIN {
    $ENV{PERL_READLINE_NOWARN} = 1;
}

use lib "/home/systest/perl";
use Getopt::Long;
use NFSTool;

our %options = (
		host => undef,
		share => "/",
		cache => undef,
		srcIP => undef,
		device => undef,
	    );
	    
GetOptions (\%options, 'verbose', 'host=s', 'share=s', 'cache', 'help', 'srcIP=s', 'device=s');
Help() if ($options{help});
if (!$options{host}) {
    print "Please specify a host\n";
    Help();
}

our %cmds = (
	     mount => [\&Mnt, "mount a filesystem"],
	     getattr => [\&Getattr, "get attributes of an object"],
	     setattr => [\&Setattr, "set attributes of an object"],
	     lookup => [\&Lookup, "lookup the filehandle for an object"],
	     access => [\&Access, "find the access bits for an object"],
	     readlink => [\&Readlink, "read the symlink path"],
	     read => [\&Read, "read from a file"],
	     write => [\&Write, "write to a file"],
	     create => [\&Create, "create a file"],
	     mkdir => [\&Mkdir, "create a directory"],
	     sln => [\&Symlink, "create a symlink"],
	     mknod => [\&Mknod, "create a special file"],
	     rm => [\&Remove, "remove a file"],
	     rmdir => [\&Rmdir, "remove a directory"],
	     rename => [\&Rename, "rename an object"],
	     link => [\&Link, "create a hard link"],
	     readdir => [\&Readdir, "get a directory listing"],
	     readdirplus => [\&Readdirplus, "get a directory listing plus attributes"],
	     fsstat => [\&Fsstat, "get the fsstat for the filesystem"],
	     fsinfo => [\&Fsinfo, "get the fsinfo for the filesystem"],
	     pathconf => [\&Pathconf, "get the pathconf for the filesystem"],
	     ls => [\&LS, "like the Unix ls command"],
	     cd => [$main::path->ChdirRef, "change directory", $path],
	     pwd => [$main::path->PwdRef, "print the current directory", $path],
	     su => [\&SU, "change the default user and group ID"],
	     whoami => [\&WhoAmI, "print the current user and group ID"],
	     chmod => [\&Chmod, "like the Unix chmod"],
	     chown => [\&Chown, "like the Unix chown"],
	     readfromfile => [\&readfromfile, "read commands from a file"],
	     rfile => [\&readfromfile, "read commands from a file"],
	     exit => [sub { exit; }, "quit the program"],
	     quit => [sub { exit; }, "quit the program"],
	     cacheon => [sub { $options{cache} = 1; 0; }, "turn on filehandle caching"],
	     cacheoff => [sub { $options{cache} = 0; 0; }, "turn off filehandle caching"],
	     verboseon => [sub { $options{verbose} = 1; 0; }, "turn verbosity on"],
	     verboseoff => [sub { $options{verbose} = 0; 0; }, "turn verbosity off"],
	     help => [\&internalhelp, "This command"],
	     );

$| = 1;
Mount($options{host}, $options{share});
my $currenthost = currentHost();

my @cmds;
my $maxcmdlen = 0;
foreach my $cmd (keys %cmds) {
    push(@cmds, $cmd);
    if (length($cmd) > $maxcmdlen) {
	$maxcmdlen = length($cmd);
    }
}
my $columns = int(80/($maxcmdlen+2));


handleinit();
if (@ARGV){
    handlecmd(@ARGV);
    exit;
}

use Term::ReadLine;
my $term = new Term::ReadLine;
 readline::rl_set('TcshCompleteMode', 'On');
 readline::rl_basic_commands(@cmds);
while (defined ($_ = $term->readline("nfstool ($currenthost) => "))){
    chomp;
    my @cmd = split;
    if (handlecmd(@cmd) == -6868){
	if ($cmd[0] =~ /\?/){
	    internalhelp();
	} elsif ($cmd[0] ne "") {
	    print "Unknown command: ". join(' ', @cmd). "\n";
	}
    }
}

sub internalhelp {
    my $long = undef;
    $long = 1 if (@_); # this was the command line help command if any options present
    my $colnum = 0;
    foreach my $cmd (sort @cmds) {
	if ($long) {
	    printf("%-".($maxcmdlen+2)."s", $cmd);
	    print "@{$cmds{$cmd}}[1]\n";
	} else {
	    $colnum++;
	    if ($colnum >= $columns){
		print "$cmd\n";
		$colnum = 0;
	    } else {
		printf("%-".($maxcmdlen+2)."s", $cmd);
	    }
	}
    }
    print "\n" if (!$long && colnum);
}

sub Help {
    print <<"xxENDxx";
Usage $0 -host <hostname> [-share <share name>] 
          [-srcip <IP>] [-device <eth#>]
          [-cache] [-verbose]
          [-help]

     -share <share name> defaults to "/"
     -srcip <IP> will specify a new source IP to use. This should not be active
                 on the network.
     -device <eth#> will specify the ethernet device to use
     -cache will cache filehandles rather than looking them up each time
     -verbose will show the actual commands that are running
xxENDxx
    exit(0);
}



