#
# NASD.pm
#
# General NASD utilities for writing quick-and-dirty perl scripts.
#
# Author: Nat Lanza
#
#
# Copyright (c) of Carnegie Mellon University, 1998,1999.
#
# Permission to reproduce, use, and prepare derivative works of
# this software for internal use is granted provided the copyright
# and "No Warranty" statements are included with all reproductions
# and derivative works. This software may also be redistributed
# without charge provided that the copyright and "No Warranty"
# statements are included in all redistributions.
#
# NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS.
# CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
# EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED
# TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY
# OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE
# MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT
# TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
#


package NASD;

use Getopt::Std;

use Exporter;
@ISA = ('Exporter');
@EXPORT = ('set_var', 'get_var',
	   'init', 'partition',
	   'create', 'test',
	   'test_verbose', 'test_quiet');

$| = 1;

my %variables;

###########################################################
###########################################################
## General utility infielder things.
##

sub set_var {
  my $var = $_[0];
  my $value = $_[1];
  
  $variables{$var} = $value;
}

sub get_var {
  my $var = $_[0];
  
  if (defined $variables{$var}) {
    return $variables{$var};
  } else {
    return undef;
  }
}

sub program {
  return (get_var("path") . "/$_[0]");
}

BEGIN {
  my $drive;

  getopt('R');
  
  if ($opt_R) {
    NASD::set_var("path", $opt_R);
  } elsif (defined $ENV{"TEST_HOME"}) {
    NASD::set_var("path", $ENV{"TEST_HOME"});
  } else {
    NASD::set_var("path", $ENV{"PWD"});
  }

  if ($opt_v) { set_var("verbose", 1); }
  else { set_var("verbose", 0); }

  $drive = shift(@ARGV) or ($drive = "localhost");
  set_var("drive", $drive);
  set_var("password", "password");
  set_var("partition", 1);
  set_var("security", 0);
}

###########################################################
###########################################################
## Drive commands
##

sub test {
  my $mycommand = shift @_;
  my @args = @_;
  my $result;

  print "command \"$mycommand @args\"";
  if (get_var("verbose")) {
    print ":\n";
  } else {
    print "...... ";
  }

  unshift(@args, program($mycommand));
  $result = `@args 2>&1`;

  if ($?) {
    if (get_var("verbose")) {
      print "Test failed:\n";
    } else {
      print "failed!\n"
    }

    print "$result\n\n";
  } else {
    if (get_var("verbose")) {
      print "Results:\n$result";
      print "Test passed.\n";
    } else {
      print " passed\n";
    }
  }

  return $result;
}

sub test_verbose {
  my $v = get_var("verbose");

  set_var("verbose", 1);
  test(@_);
  set_var("verbose", $v);
}

sub test_quiet {
  my $v = get_var("verbose");

  set_var("verbose", 0);
  test(@_);
  set_var("verbose", $v);
}

sub init {
  my $drive = get_var("drive");
  my $password = get_var("password");
  my $result;

  if (defined $_[0]) { $drive = $_[0]; }
  if (defined $_[1]) { $password = $_[1]; }

  my @pinit_args = (program("pinit"), $drive, $password);

  print "Initializing drive $drive... ";

  $result = `@pinit_args 2>&1`;

  if ($? == 46) {
    print "failed\n";
    print "\tYou cannot initialize a drive that's already been initialized.\n";
    print "\tPlease try again with a freshly-formatted disk.\n";
    exit(1);
  } elsif ($?) {
    print "failed:\n$result\n\n";
    exit(1);
  } 

  sync($drive, $password);

  if (get_var("verbose")) {
    print "\nResult:\n$result\nDrive initialized.\n\n";
  } else {
    print " initialized\n";
  }

}

sub partition {
  my $result;
  my $drive = get_var("drive");
  my $part = get_var("partition");
  my $size = 50000;
  my $security = get_var("security");
  my $password = get_var("password");
  if (defined $_[0]) { $part = $_[0]; }
  if (defined $_[1]) { $size = $_[1]; }
  my @pcrpart_args = (program("pcrpart"), $drive, $part, $size, $security, $password);
  
  print "Creating $size block partition $part on drive $drive... ";

  $result = `@pcrpart_args 2>&1`;

  if ($?) {
    print "failed:\n$result\n\n";
    exit(1);
  }

  sync($drive, $password);

  if (get_var("verbose")) {
    print "succeeded:\n$result\n\n";
  } else {
    print "succeeded\n";
  }
}

sub create {
  my $result;
  my $drive = get_var("drive");
  my $partition = get_var("partition");
  my $password = get_var("password");
  my $object;

  if (defined $_[0]) { $partition = $_[0]; }

  my @pcrobj_args = (program("pcrobj"), "-p", $partition, $drive, $password);

  print "Creating object on partition $partition of drive $drive... ";

  $result = `@pcrobj_args 2>&1`;
    
  if ($?) {
    print "failed:\n\n$result\n\n";
    exit(1);
  } elsif (get_var("verbose")) {
    print "succeeded:\n$result\n";
  } else {
    print "succeded\n";
  }    

  sync($drive, $password);

  chomp($result);
  $result =~ /^Succeeded, id=(0x[^ ]+)/;
  $object = $1;

  print "Object ID: $object\n";

  set_var("last", $object);

  return $object;
}

sub sync {
  my $drive = get_var("drive");
  my $result;

  if (defined $_[0]) { $drive = $_[0]; }

  my @psync_args = (program("psync"), $drive);
  
  if (get_var("verbose")) {
    print "Syncing drive $drive... ";
  }

  $result = `@psync_args 2>&1`;

  if ($?) {
    if (get_var("verbose")) {
      print "failed: sync failed\n\n$result\n\n";
    } else {
      print "sync of drive $drive failed:\n$result\n\n";
    }
    exit(1);
  }

  if (get_var("verbose")) {
    print "succeeded\n";
  }
}

##############################################

1;
