#!/usr/bin/env perl

##------------------------------------------------------------------------------
## History:
## Date      OPR      Who        Reason
## --------  -------- ---------- ------------------------------------------
## 01/24/02  45017    Sherbert   Initial code
## 08/16/02  -        ditto      Check for opus_iors and empty resource.locks
## 09/16/02  -        ditto      Improvements
## 10/23/02  -        ditto      Remove opus_iors and recreate it empty
## 03/24/03  45017    Sherbert   Cleaned up long lines
## 09/08/03  45017    Sherbert   More clean up; less loquacious
## 09/10/03  45017    Sherbert   Attempt to prevent accidents: Prompt user 
## 12/23/03  49783    Sontag     Add code to empty lock dir
##
##------------------------------------------------------------------------------
##
##
## Usage: alter_server_files.pl
##
## Purpose: to rewrite   OPUS_DEFINITIONS_DIR:opus_corba_objs file
##          to recreate  OPUS_HOME_DIR:opus_iors (empty)
##          to recreate  OPUS_HOME_DIR:resource.locks exists (empty) (if nec)
##          to make sure OPUS_HOME_DIR/lock is empty (empty) (if nec)
##
## Prints only the lines from opus_corba_objs file which begin with:
## CONTEXT, EVENT, FILE, OSF, or PSTAT
##
## Can be used by OPUS-server killing script to clean up with -force
##
##------------------------------------------------------------------------------
my $PATH=      $ENV{"PATH"};
my $OPUS_HOME_DIR = $ENV{"OPUS_HOME_DIR"};

@parts = split /:/, $PATH;
while (defined($val = pop(@parts))) {
   if (substr($val,0,1) eq "/") { unshift(@INC, $val)}
}

require 'printmsg.pl';  # PrintMsg routine
require 'resolve.pl';   # PrintMsg routine

use Getopt::Long;
($opt_help, $opt_verbose) = (0) x 3;
GetOptions qw{
    force
    help
    verbose
    };
## apparently "-nodes string" is same as "-n string" 
## whereas   "--nodes string" would be different

if ( $opt_force ) {
	$force = 1;
} else {
	$force = 0;
}
if ( $opt_help ) {
    PrintUsage();
}
if ( $opt_verbose ) {
    $verbose = 1;
} else {
    $verbose = 0;
}

##------------------------------------------------------------------------------
## Have user verify this is what they REALLY want to do
##------------------------------------------------------------------------------
if ( ! $force ) {
    print STDERR "\nThis script will DESTROY and recreate files used by \n";
    print STDERR "the OPUS servers.  DO NOT RUN this script if servers \n";
    print STDERR "are still up.  Do you still want to continue? [y/n] ";
    
    my $answer = <STDIN>;
    chomp($answer);
    print "\n";
    if ( $answer =~ /^[Nn]/ ) {
    	print STDERR "Exiting.\n";
    	exit 1;
    }
}

##------------------------------------------------------------------------------
## Make pretties
##------------------------------------------------------------------------------
print "\n";
my $beg_banner = "*"x10 . "Begin Script alter_server_files.pl" . "*"x10 ;
my $end_banner = "*"x10 . "End   Script alter_server_files.pl" . "*"x10 . "\n";
PrintMsg ("I","$beg_banner");

##------------------------------------------------------------------------------
## Touch and recreate $OPUS_HOME_DIR/opus_iors no matter what
##------------------------------------------------------------------------------
if ( $verbose ) {
    PrintMsg("D","Checking $OPUS_HOME_DIR/opus_iors");    ## loquacious
}
my $oi = "$OPUS_HOME_DIR/opus_iors";
## remove it
if ( !unlink ($oi) ) {
    PrintMsg("E","*** ERROR: Could not unlink $oi: $!\n");
    exit 1;
}
if ( $verbose ) {    ## loquacious
    PrintMsg("D","unlink $oi  -- file removal seems to have been successful");
}
## recreate it empty 
touch_and_recreate ($oi);
my $oi_size = (-s $oi);
PrintMsg("I",
    "$oi exists, size: $oi_size bytes.  Expect 0.");

##------------------------------------------------------------------------------
## Check size of resource.locks file; delete and recreate, if necessary.
##------------------------------------------------------------------------------
if ( $verbose ) {
    PrintMsg("D","Checking $OPUS_HOME_DIR/resource.locks");   ## loquacious
}
my $rl = "$OPUS_HOME_DIR/resource.locks";
## Does the file exist?
if (!-e $rl) {
    if ( $verbose ) {    ## loquacious
        PrintMsg ("I","$rl does NOT exist.  Therefore I must create it.");
    }
    touch_and_recreate ($rl);
}
else
## It does exist  (so check the size)
{
    ## -z: "File has zero size" p. 85 Programming Perl 2nd Ed. 1996
    ## if the file exists but is NOT zero size then delete it
    if ( ! -z $rl ) {
        ## The file still contains something
        my $rl_size = (-s $rl);
        if ( $verbose ) {    ## loquacious
            PrintMsg("I","$rl is $rl_size bytes.  Will remove and recreate.");
        }
        ## remove it
        if ( !unlink ($rl) ) {
            PrintMsg("E","*** ERROR: Could not unlink $rl: $!\n");
            exit 1;
        }
        if ( $verbose ) {   ## loquacious
            PrintMsg("D","unlink $rl  -- file removal successful");
        }
        ## recreate it empty 
        touch_and_recreate ($rl);
    }
}
my $rl_size = (-s $rl);
PrintMsg("I","$rl exists, size: $rl_size bytes.  Expect 0.");

##------------------------------------------------------------------------------
## Make sure $OPUS_HOME_DIR/lock/ is empty; delete contents if necessary.
##------------------------------------------------------------------------------
if ( $verbose ) {
    PrintMsg("D","Checking $OPUS_HOME_DIR/lock directory");    ## loquacious
}

## empty it and check status (we need it to be empty either way)
`/bin/rm $OPUS_HOME_DIR/lock/* 2> /dev/null`;
if ($?) {
    PrintMsg("I","$OPUS_HOME_DIR/lock directory was empty.");
}
else {
    PrintMsg("I","Emptied $OPUS_HOME_DIR/lock directory");
}

##------------------------------------------------------------------------------
## State file intentions and open intended files
##------------------------------------------------------------------------------
my $corba_objs_file = 
    `osfile_stretch_file OPUS_DEFINITIONS_DIR:opus_corba_objs`;
chomp($corba_objs_file);
my $tempo_objs_file = $corba_objs_file . ".tmp";

# print "Your corba_objs_file is $corba_objs_file\n";    ## trace
# print "Your tempo_objs_file is $tempo_objs_file\n";    ## trace

if ( ! open (INFILE, "<$corba_objs_file") ) {
    PrintMsg("E","ERROR: could not open $corba_objs_file: $!\n");
    PrintMsg ("I","$end_banner");
    exit 1;
}
if ( ! open (OUTFILE, ">$tempo_objs_file") ) {
    PrintMsg("E","ERROR: could not open $tempo_objs_file: $!\n");
    PrintMsg ("I","$end_banner");
    close (INFILE);
    exit 1;
}

##------------------------------------------------------------------------------
## Read opus_corba_objs and print to OUTFILE only lines containing
## CONTEXT, EVENT, FILE, OSF, or PSTAT thus removing the STARTING line and others
##------------------------------------------------------------------------------
umask (0000);
while (<INFILE>) {

    if ( /^CONTEXT/ || /^EVENT/ || /^FILE/ || /^OSF/ || /^PSTAT/ ) {
        if ( $verbose ) {
            print STDOUT;   ## loquacious
        }
        print OUTFILE;
    }


}
if ( $verbose ) {
    print STDOUT "\n";    ## loquacious
}
PrintMsg("I","Finished rewriting $corba_objs_file without STARTING line");

##------------------------------------------------------------------------------
## Rename the temporary file, leaving only the expected opus_corba_objs file
##------------------------------------------------------------------------------
my $numerr = 0;
if ( ! rename($tempo_objs_file, $corba_objs_file) ) {
    PrintMsg("E",
        "ERROR: Cannot rename $tempo_objs_file to $corba_objs_file: $! \n");
    $numerr = $numerr + 1;
    if ( ! unlink $tempo_objs_file ) {
        PrintMsg("E","ERROR: Cannot remove $tempo_objs_file: $! \n");
        $numerr = $numerr + 1;
    }
}

##------------------------------------------------------------------------------
## Exit with status, closing files always
##------------------------------------------------------------------------------
close (INFILE);
close (OUTFILE);
PrintMsg ("I","$end_banner");
exit $numerr;

sub touch_and_recreate {

    my ($file) = @_;
    # print "file to be touch_and_recreate-ed is $file\n";  ## loquacious

    my $cmd = "/bin/touch $file";
    # PrintMsg("D",$cmd);   ## loquacious
    `$cmd`;
    if ($?) {
        PrintMsg ("E","*** ERROR: Could not touch $file: $!\n");
        exit 1;
    }

}   ## end sub touch_and_recreate

##############################################################################
## Print Usage statement
##############################################################################
sub PrintUsage
{
    use File::Basename;
    
    my ($name, $unixpath, $ext) = fileparse($0, '.pl' );
    
    print STDERR<<EOF; 

     $name$ext
        [-help] 
        [-verbose] 
     All arguments are optional.  
     
     -h[elp]      
        Print this usage statement.
     -v[erbose] 
        Runs script verbosely.
     
     Examples: 
     $name$ext
            Will rewrite OPUS_DEFINITIONS_DIR:opus_corba_objs 
                with the bare minimum lines necessary to start servers.
            Will recreate an empty OPUS_HOME_DIR:resource.locks, if necessary.
            Will recreate an empty OPUS_HOME_DIR:opus_iors file.

EOF
    exit 1;
}
