#!/usr/bin/perl



=pod

  This is the TEST distribution of local routines for the TUSC layer of
  the PST toolkit (www.pstoolkit.org).

GENERAL NOTES FOR THE IMPLEMENTATION OF LOCAL ROUTINES

  Each routine is very simple, and has the following structure.

  1. Argument definition.  This is the line like:
     my($host,$path,$file) = @_
     It's turning the arguments from the caller into the local variables
     that you'll want to use, so don't mess with it.
  2. A check on the hostname.  If you have multiple ASF's you might have to
     have different behavior for some of these functions, here represented
     by the (trivial) if ($host == "local") check.
  3. The body.  Usually a simple local command.
  4. Return values as described in the comments for each subroutine.


NOTES
  This is the only file you need to edit to port the TUSC layer to your
  site.  You should make yourself familiar with every line of this file.

  If you find you need to edit more than these lines to port to your
  site, please share your code with www.pstoolkit.org.


HISTORY
  This history list is no longer maintained.

  6-8-2001: VERSION = 0.01

  6-9-2001: VERSION = 0.02
    1. modify all error messages to include archive.pm:subroutine name
    2. site_get subroutine added
    3. other subroutines modfied according to their history statements
    4. include LOCAL+LOCAL and local-local to identify regions that MUST
       by updated for site-specific implementation

=cut




#============================================== Define TUSC/local module

package TUSC::local;

use Exporter;
@ISA = "Exporter";
@EXPORT = qw(site_env archive_mkdir site_put site_verify_files site_unglob_files site_get archive_stat site_ls directory_exists site_migrate);

$VERSION = "0.02";

# Enhance Perl strictness and verbosity, for aid in development.
use strict;
#use warnings;




sub site_get
{
=pod

NAME
  site_get: (site-specific) get a file from archive file system


ARGUMENTS
  host (in): name of this host, for determining specifically how to do
       the "get" on sites that have more than one archive file system.

  remote_file (in): name of file on archive file system


DESCRIPTION



RETURN VALUES
  site_get returns a list of two scalar elements:  The first element
  is a string containing the output of the "get" command.  The second
  element is the integer exit status value of the command.


=cut

  # Unpack arguments from ARGS array
  my ($host, $remote_file)=@_;

  # Declare local variables
  my ($command_output, $exit_status);

  # Use /bin/cp to copy files.
  $command_output = `/bin/cp -f $remote_file . 2>&1` ;

  # Store exit status of previous backtic command.
  $exit_status    = $?;

  return($command_output, $exit_status);
}




sub site_verify_files
{
=pod

NAME
  site_verify_files: (site-specific) verify sameness of local and remote files


ARGUMENTS
  host (in): name of this host, for determining specifically how to do
       the "get" on sites that have more than one archive file system.

  local_file (in): name of file on local file system

  remote_file (in): name of file on archive file system


DESCRIPTION
  Verify that the given local and remote files are the same.


RETURN VALUES
  Returns zero if files are the same, non-zero otherwise.


=cut

  # Extract arguments from ARGS array
  my ($host, $local_file, $remote_file)=@_;

  # Declare local variables
  my ($local_size, $remote_size);

  # Check file sizes as a rudimentary verification against corruption.
  $local_size    = -s $local_file;
  $remote_size   = -s "$remote_file";  #perl's size checker

  if($local_size == $remote_size)
  {
    return 0;
  }
  else
  {
    return 1;
  }
}




sub site_unglob_files
{
  # Extract arguments from ARGS array
  my ($host, $path, $file)=@_;

  # Declare local variables
  my ($ls_output, @list, @files, $file1, @links);

  # Clear @links array to assure it does not return unintentional garbage.
  undef @links;

  if ($host eq "local")
  {
    # If $file contains wildcards,
    # obtain list of remote directory entries that match.
    #
    #
    $ls_output=`/bin/ls -ld $path$file`;

    # Remove easily-identified directories by removing all lines that
    # start with "d"
    $ls_output=~s/^d.*\n//gm;

    # This did not get rid of ALL directories, because some entries may
    # be symbolic links to directories.  The code below contains two
    # strategies for dealing with symbolic links.  You may have other
    # techniques at your site for dealing with links.  We could also
    # write code to traverse all the links, but that is not implemented
    # here yet.  Please use whatever technique seems best at your site
    # for removing symbolic links which point to directories.

    # ---------------------------------------
    # Technique A:  use Perl's (-d file) test
    # ---------------------------------------

    # 1. Extract directory entries from each line of $ls_output.
    $ls_output=~s/.* ($path[^\s]+).*/$1/mg;

    # 2. Split $ls_output into elements for @files.
    @files=split /\n/,$ls_output;

    # Clear @list array so we can add to a fresh array.
    undef @list;

    # 3. For each element of @files, remove all directories and
    #    symbolic links pointing to directories.
    foreach $file1 (@files)
    {
      if (! -d $file1)
      {
        push @list,$file1
      }
    }

#       --------------------------------------
#       Technique B:  use "/bin/ls -ld" output
#       --------------------------------------
#                                                                      #
#       1. split $ls_output into elements for @files.                  #
####    @files=split /\n/,$ls_output;                                  #
#                                                                      #
#       2. separate out the links (those lines that start with "l")    #
####    @links=grep /^l/,@files;                                       #
#                                                                      #
#       3. if links are found, warn the user.                          #
####    if (@links) {                                                  #
####        warn "\n";                                                 #
####        warn "WARNING: local.pm:site_get currently does not make more\n";
####        warn "  than three attempts to transfer symbolic links because\n";
####        warn "  they may be directories.\n\n";                     #
####     }                                                             #
#                                                                      #
#       4. now remove the links from @files                            #
####    $ls_output=join "\n",@files;                                   #
####    $ls_output=~s/^l.*\n//gm;                                      #
#                                                                      #
#       5. of what remains, save the file name and split into @files   #
####    $ls_output=~s/.* ($path[^\s]+).*/$1/mg;                        #
####    @files=split /\n/,$ls_output;                                  #
#                                                                      #
#       6. do the same for the links                                   #
####    $ls_output=join "\n",@links;                                   #
####    $ls_output=~s/.* ($path[^\s]+).*/$1/mg;                        #
####    @links=split /\n/,$ls_output;                                  #
#                                                                      #
#     now we have two lists @files and @links.  we attempt to get the  #
#     @files $opts{retry} times, but we only try the @links 3 times.   #

  }

  #
  # NOTES:  This might need to return "files" as well, but I am not clear
  # on the distinction between files, list and links as used by the
  # caller.  --MJG
  #

  return (\@list, \@links);
}




#========================================================= ARCHIVE_MKDIR

sub archive_mkdir
{

=pod

Make directories on the archival storage facility.

EXAMPLE
  %out = archive_mkdir(\%opts,\%args,\%errs);

INPUT
  %opts -- command-line options; see set_default_opts()
  %args -- command-line arguments; see define_args_hash()
  %errs -- error-message list; see define_error_table()

OUTPUT
  %opts -- updated command-line options
  %out -- nested hash with KEY's equal to KEY's of %args.  Each KEY
      points to the KEY's VAL and MSG.  The VALUE for VAL is the exit
      code for the "archive mkdir" operation, 0 if successful or
      $errs{MKDIR_FAILED}{VAL} if unsuccessful.  The VALUE for MSG
      is a string equal to the standard output from the unix mkdir
      command.  If the asf host is down, then the VALUE for VAL is
      set to $errs{HOST_DOWN}{VAL} and the VALUE for MSG is set to
      $statout{$host}{MSG}.

OPTIONS
  $opts{mode}*, $opts{parent}, $opts{silent}

  *partially implemented.  we'd like mode to allow ugoa+rwx format.
  currently we can specify octal mode format.

VARIABLES
  HASHES
    %statopts -- copy of %opts with $statopts{silent}=1.  used for input
        to archive_stat().
    %statout -- output from archive_stat(); see archive_stat()
  ARRAYS
    @args -- list of KEY's for input hash %args
  SCALARS
    $args -- reference for input hash %args
    $dir -- set to each element of @args in foreach loop
    $e -- exit status from unix mkdir command
    $errs -- reference for input hash %errs
    $home -- string set to home directory for $host
    $host -- string set to $opts{DEFAULT_HOST}
    $line -- standard output from unix mkdir command
    $opts -- reference for input hash %opts; options for unix mkdir
        command.
    $path -- full path name (begins with "/") for each $dir

NOTES
  Since TEST's archival storage facility is just a unix file system,
  mkdir works in the usual way.

AUTHOR
  Written 6-2001 by Joe Werne

HISTORY
  6-9-2001: Joe Werne
    1. set $out{$dir}{VAL} and $out{$dir}{MSG} correctly
    2. hold archive_stat output in %statout

  7-11-2001: Joe Werne
    1. expanded header comments; scoped all variables as my.

=cut

#------------------------------------------------------- scope variables
  my (%opts,%args,%errs,$host,%out,%statopts,%statout,@args,$dir,$path);
  my ($home,$line,$e);

#------------------------------------------------------------ read input
  my ($opts,$args,$errs)=@_;

#----------------------------------------------------- dereference input
  %opts=%$opts; %args=%$args; %errs=%$errs;

#-------------------------------------------------- obtain list of @args
  @args=keys %args;

#-------------------------------- identify host from $opts{DEFAULT_HOST}
  $host=$opts{DEFAULT_HOST};

#------------------------------------------------- make sure $host is up
# wait for $host to become available (controlled by $opts{retry})
  %statopts=%opts; $statopts{silent}=1;
  %statout = archive_stat(\%statopts,$host,\%errs);

# if host is up ...
  if ($statout{$host}{VAL}==0) {

#LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL
#                                                                      #
#   if $host="local" ... (Just in case you have more than one ASF),    #
#   then set options for mkdir                                         #
#                                                                      #
    if ($host eq "local") {                                            #
      if ($opts{parent}==1) { $opts="-p -m $opts{mode}" }              #
      else { $opts="-m $opts{mode}" }                                  #
#                                                                      #
#local-local-local-local-local-local-local-local-local-local-local-local

#     consider each directory $dir to create
      foreach $dir (@args) {

#       if $dir does not start with "/", prepend with $home.
        $path=$dir; $home=$opts{HOST}{$host}{HOME};
        if ($path!=~/^\//) {$path="$home$path"}

#LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL
#                                                                      #
#       create $path                                                   #
#                                                                      #
        $line = `mkdir $opts $path 2>&1`; $e=$?/256;                   #
#                                                                      #
#local-local-local-local-local-local-local-local-local-local-local-local

#       set message flag
        $out{$dir}{MSG}=$line;

#       print feedback to user
        if ($opts{silent}==0 && $line ne "") {
          warn $line;
        }

#LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL
#                                                                      #
#       if path is not a directory, print message; increment fatal.    #
        if (! -d $path) {                                              #
#                                                                      #
#local-local-local-local-local-local-local-local-local-local-local-local

          $opts{fatal}++;
          $out{$dir}{VAL}=$errs{MKDIR_FAILED}{VAL};
          if ($opts{silent}==0) {
            warn sprintf $errs{MKDIR_FAILED}{MSG},
              ("local.pm:archive_mkdir",$path);
          }
        }
        else {
          $out{$dir}{VAL}=0;
        }
      }
    }
  }

# or, if host is down, set VAL and MSG and write error
  else {
    $opts{fatal}++;
    foreach $dir (@args) {
      $out{$dir}{VAL}=$errs{HOST_DOWN}{VAL};
      $out{$dir}{MSG}=$statout{$host}{MSG};
    }
    if ($opts{silent}==0) {
      sprintf $errs{HOST_DOWN}{MSG},
        ("local.pm::archive_mkdir",$host,$statout{$host}{MSG});
    }
  }

#---------------------------------------------------------------- return
  return (\%opts,\%out);

}




#========================================================== ARCHIVE_STAT

sub archive_stat
{

=pod

Check the status of the archival storage facilities listed in
keys %{$opts{HOST}}.

EXAMPLE
  %out = archive_stat(\%opts,$host,\%errs);

INPUT
  %opts -- command-line options; see set_default_opts()
  $host -- archival storage facility to probe; see archive_ls()
  %errs -- error-message list; see define_error_table()

OUTPUT
  %out -- nested hash with a single KEY set to $host.  When archive_stat
      is complete, additional KEY's will exist for all hosts specified
      by the -asf option, or, if -asf is not present, then KEY's will
      exist for all hosts indicated by the %{$opts{HOST}} hash.  See
      comment statements re $host in archive_ls().  Each KEY (for now
      there is only one) points to KEY's VAL and MSG.  The VALUE for VAL
      is the exit code for the "archive stat" operation, 0 if the system
      is up or $errs{RETRY}{VAL} if the system is down.  The VALUE for
      MSG is the last output prepared for STDOUT (see NOTES below) from
      archive_stat().

VARIABLES
  HASHES
    %report -- hash containing output messages in KEY => VALUE pairs.
        KEY "up" has associated VALUE "on-line"; KEY "down" has VALUE
        "unavailable".
  ARRAYS
    @host -- list of hosts identified by the keys of %{$opts{HOST}}
  SCALARS
    $errs -- reference for input hash %opts
    $fhost -- string of comma-separated list of the elements of @host.
        $fhost is needed for a possible error message.
    $form -- format string for output to STDOUT
    $hour -- 3rd element returned by localtime
    $line -- output prepared using $form for STDOUT
    $mday -- 4th element returned by localtime
    $min -- 2nd element returned by localtime
    $mon -- 5th element returned by localtime + 1
    $opts -- reference for input hash %opts
    $report -- set to $report{up} if the system is up or $report{down}
        if the system is down.
    $s -- optional note for $line; see "archive" man page (also included
        as comments in bin/archive.
    $sec -- 1st element returned by localtime
    $success -- string set to "no" while system is found to be
        unavailable or "yes" if the system is up.
    $try -- counter for retry attempts to check system status;  if
        the system is down, archive_stat() will check its status
        $opts{retry} times until the system is up.
    $year -- 6th element returned by localtime + 1900

NOTES
  archive_stat prints the output string:

  hh:mm:ss mm/dd/yyyy status [note]

  status is either "on-line" or "unavailable" and is printed after the
  date reported by the system from which archive_stat was invoked.

  Currently archive_stat() is conducted the retry attempts (up to
  $opts{retry} times).  This really should be moved out of local.pm,
  so new developers don't have to look at so much Perl.

AUTHOR
  Written 6-7-2001 by Joe Werne

HISTORY
  6-9-2001: Joe Werne
    1. add $out{$host}{MSG} to output
    2. introduce $success so $try-while test is only at bottom of block

  6-11-2001: Joe Werne
    1. prepare message outside of silent-test

  7-11-2001: Joe Werne
    1. expanded header comments

=cut

#------------------------------------------------------- Scope variables
  my (%opts,%out,%errs,$host,@host,$fhost,%report,$report,$s,$try);
  my ($sec,$min,$hour,$mday,$mon,$year,$form,$line,$success);
  my ($day);

#------------------------------------------------------- Read input data
  my ($opts,$host,$errs)=@_;

#------------------------------------------------ Dereference input data
  %opts=%$opts; %errs=%$errs;

#------------------------------------------------------ Define variables
  $report{up}  ="on-line";
  $report{down}="unavailable";
  $form = "%2.2d:%2.2d:%2.2d %2.2d/%2.2d/%4.4d %s %s %s\n";

#----------------------------------------------------------- Check hosts
# get host list from %opts.
  @host = keys %{$opts{HOST}}; $fhost=join ", ",@host;

# Initiate $host flag to RETRY.
  $out{$host}{VAL}=$errs{RETRY}{VAL};

#LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL
#                                                                      #
#  "local" is our pretend archival storage facility for local.pm.TEST. #
#                                                                      #
  if ($host eq "local") {                                              #
#                                                                      #
#local-local-local-local-local-local-local-local-local-local-local-local

#   try up to $opts{retry} times
    $try=0; $success="no";
    while ($success ne "yes") {

#LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL
#                                                                      #
#  since the TEST version of local.pm uses a file system for archival  #
#  storage, just see if the specified home directory is present        #
#                                                                      #
      if (-e $opts{HOST}{$host}{HOME}) {                               #
#                                                                      #
#local-local-local-local-local-local-local-local-local-local-local-local

        $report=$report{up};
        $out{$host}{VAL}=0;
      }
      else {
        $report=$report{down};
      }

#     prepare output message
      ($sec,$min,$hour,$mday,$mon,$year)=(localtime)[0,1,2,3,4,5];
      $year=$year+1900; $mon=$mon+1; $s="";
      $line = sprintf $form,
        ($hour,$min,$sec,$mon,$day,$year,$host,$report,$s);

#
#     print output message to STDOUT
#     for the TEST version of archive_stat, it seems prudent to make
#     stat failures verbose.  print the first attempt only if
#     $opts{silent}==0.  print output for all subsequent attempts,
#     regardless the value of $opts{silent}.
#
      if ($opts{silent}==0 || $try>0) {
        print $line;
        if ($report eq $report{down}) {
          print "Does $opts{HOST}{$host}{HOME} exist?\n";
        }
      }

      $try++;
      if ($out{$host}{VAL}!=0 && $try<$opts{retry}) {sleep 5+2*$try;}
      else {$success="yes"}
    }
    $out{$host}{MSG}=$line;
  }

#---------------------------------------------------------------- Return
  return %out;

}




sub site_env
{

=pod

Specify site-specific variables.

EXAMPLE
  %e = site_env();

INPUT
  none

OUTPUT
  %e -- output hash containing KEY => VALUE pairs relevant to the local
      site.  The KEY's and VALUE's are described below.

    KEYS:

      PSTDIR -- VALUE is the location of the PST root directory.  VALUE
          is set by pstinstall2 during PST installation.

      ARCHIVE_HOST -- comma-separated list (no white space) of the valid
          archival storage facility names for the current site.  The
          first name in the list is the name of the default system.  If
          an environment variable with the name ARCHIVE_HOST exists, it
          is used to set the VALUE; if not, the default value coded into
          site_env() is used.

      ARCHIVE_HOME -- comma-separated list (no white space) of the user
          root directories on the archival storage facility identified
          by ARCHIVE_HOST.  If more than one directory is specified in
          ARCHIVE_HOME, then each directory must identify the user root
          directory for the corresponding archival storage facility
          identified by ARCHIVE_HOST.  That is, in this case there
          should be an equal number of systems and root directories
          specified.  If only one directory is specified by
          ARCHIVE_HOME, then the same directory will be used for all
          of the archival storage facilities specified by ARCHIVE_HOST.
          If an environment variable with the name ARCHIVE_HOME exists,
          it is used to set the VALUE; if not, the default value coded
          into site_env() is used.

      ARCHIVE_PROBE -- comma-separated list (no white space) of flags
          that indicate whether or not we will attempt to check the
          status and type of files on the archival facility before and
          after transfer.  VALUE is "yes" if we will check the status.
          VALUE is "no" if we will not.  A reason for setting
          ARCHIVE_PROBE="no" could be failure in accurate or complete
          reporting of file types by the archival storage facility.  As
          with ARCHIVE_HOME, the number of items in the comma-separated
          list determines the flag for each archival storage facility.
          If an environment variable with the name ARCHIVE_PROBE exists,
          it is used to set the VALUE; if not, the default value coded
          into site_env() is used.

      PST_NOTE -- VALUE is a string variable containing a note that is
          communicated to new users during installation.  PST_NOTE
          should provide useful information about environment variables
          and directories used by the TUSC layer of the toolkit.
          Variables and directories that must be set and those that
          can be set should be clearly identified.  Man pages for the
          toolkit should also be mentioned in PST_NOTE.  Any other basic
          information for the user can also be communicated through the
          PST_NOTE string variable.

      PST_SITE -- VALUE is the name of the SITE; e.g., ERDC, NAVO, ASC,
          ARL, AHPCRC, PST, SDSC, ....

VARIABLES
  SCALARS
    $USER -- set to environment variable of same name

NOTES
  This routine is called by set_default_opts() and pstinstall2.

AUTHOR
  Written 6-2001 by Joe Werne

HISTORY
  7-10-2001: Joe Werne
    1. expanded header comments.

=cut

#-----------------------------------------------------------------------
  my (%e,$USER);
  $USER = $ENV{'USER'};
#---------------------------------------------------- Specify $e{PSTDIR}
#PST BEGIN(1)
  $e{PSTDIR}="/home/bizon/PST";
#PST END(1)
#---------------------------------------------- Specify $e{ARCHIVE_HOME}
  if (exists $ENV{'ARCHIVE_HOME'} && $ENV{'ARCHIVE_HOME'} ne "") {
    $e{ARCHIVE_HOME}=$ENV{'ARCHIVE_HOME'}
  }
  else {

#LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL
#                                                                      #
#   specify default $ARCHIVE_HOME                                      #
#                                                                      #
    $e{ARCHIVE_HOME}="/tmp/$USER/DATA_ARCHIVE";                        #
#                                                                      #
#local-local-local-local-local-local-local-local-local-local-local-local

  }
#---------------------------------------------- Specify $e{ARCHIVE_HOST}
  if (exists $ENV{'ARCHIVE_HOST'} && $ENV{'ARCHIVE_HOST'} ne "") {
    $e{ARCHIVE_HOST}=$ENV{'ARCHIVE_HOST'}
  }
  else {

#LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL
#                                                                      #
#   specify default $ARCHIVE_HOST                                      #
#                                                                      #
    $e{ARCHIVE_HOST}="local";                                          #
#                                                                      #
#local-local-local-local-local-local-local-local-local-local-local-local

  }
#--------------------------------------------- Specify $e{ARCHIVE_PROBE}
  if (exists $ENV{'ARCHIVE_PROBE'} && $ENV{'ARCHIVE_PROBE'} ne "") {
    $e{ARCHIVE_PROBE}=$ENV{'ARCHIVE_PROBE'}
  }
  else {

#LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL
#                                                                      #
#    Specify the local site                                            #
#                                                                      #
  $e{ARCHIVE_PROBE}="yes";                                             #
#                                                                      #
#local-local-local-local-local-local-local-local-local-local-local-local

  }

#LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL
#                                                                      #
#    specify the local site                                            #
#                                                                      #
  $e{PST_SITE}="TEST";                                                 #
#                                                                      #
#local-local-local-local-local-local-local-local-local-local-local-local

#LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL+LOCAL
#                                                                      #
#    offer a note for the user                                         #
#                                                                      #
  $e{PST_NOTE}= <<here_1;
  NOTE: See the man pages for the PST routines that use these environment
  variables.  Man pages are included in the PST distribution and are
  available on-line at pstoolkit.org.

  If you choose not to set these environment variables, then the
  default values specified here will be used.  Please make sure your
  \$ARCHIVE_HOME directory exists.

  There is no actual separate archival storage facility accessed for the
  TEST version of PST.  Unix file-system utilities are used.
here_1
#                                                                      #
#local-local-local-local-local-local-local-local-local-local-local-local
#---------------------------------------------------------------- Return
  return %e;

}




#==============================================================site_put
sub site_put
{

=pod
  site_put: put a local file on the ASF.

  inputs: $host: name of the ASF on which to put the file
          $path: directory on the ASF where the file will go
          $file: local file to be put

  outputs: $line: a string containing the stdout from the local put command
           $status: the status code returned by the local put command
=cut
  my ($host,$path,$file)=@_;
  my ($line,$status);

  if ($host=="local")
  {
    $line=`/bin/cp -f $file $path 2>&1`;
    $status=$?; #Perlese for the status returned by the last `` command.
  }

  return($line,$status);

}




#=======================================================directory_exists
sub directory_exists
{

=pod
  directory_exits: Determine whether a remote directory exists.

  inputs: $host: name of the ASF where the directory may exist
          $path: directory whose existence is in question

  outputs: $line: a string containing the stdout from the local put command
           $direxists: A string that contains "true" if the directory exists,
                       and "false" if it does not.
=cut

  my ($host,$path)=@_;
  my ($direxists);

  if ($host=="local")
  {
    if (-d $path) { $direxists = "true"; }
    else { $direxists = "false"; }
  }

  return($direxists);

}




sub site_get_remote_file_size
{

=pod

NAME
  site_get_remote_file_size: Get the size of a remote file (in bytes).


ARGUMENTS
  $host: name of the ASF where the file lives.
  $path: directory on the ASF where the file lives.
  $file: name of the file to be sized.


RETURN VALUES
  $size: Size of the remote file in bytes.

=cut

  # Extract arguments from ARGS array.
  my ($host,$path,$file)=@_;

  # Local variables
  my ($size);

  if ($host=="local")
  {
    $size = -s "$path$file";  #perl's size checker
  }

  return($size);

}


=pod

NAME
  site_migrate: Migrate a remote file.


ARGUMENTS
  $host: name of the ASF where the file lives.
  $file: full-path name of the file to be sized.


RETURN VALUES
  None.

=cut


sub site_migrate
{

  my ($host,$file)=@_;

  if ($host=="local")
  {
     warn("site_migrate: COMMENT: Doing nothing.\n");
     warn(" If this were a real archival system, this would migrate your file.\n");
  }

}




#===============================================================site_ls

=pod

NAME
  site_ls: perform an ls on remote files.


ARGUMENTS
  $host: name of the ASF where the file lives.
  $options: ls-sytle options.
  $files: full-path names of the files to be ls'ed.


RETURN VALUES
  $message: output generated by the ls command
  $status: status returned by the ls command

=cut
sub site_ls
{

  my ($host,$options,$files)=@_;
  my ($message,$status);

  if ($host=="local")
  {
    $message=`/bin/ls $options $files 2>&1`;
    $status=$?; #perlese for get the status from the last `` command.
  }

  return ($message,$status);

}

#============================================================== Finished

1;

__END__
