#!/bin/sh
VERSION="Version 2.2.1 / June 28, 2003"
################################################################################
# Script to create and maintain the system wide savealls in a pre-configured
# directory on the local harddrive of an AP or AW.
# (see variable list for current location)
#
# A creative conception by:    M. de Waal(MdW) & R. Deen (RD)
# Special guest appearance by: R. de Groot (RdG) & C. van Diepen (CvD)
# Thanks to B. Marsman (BM) for his valuable testing, input and bug fixes
#
# Additional functionality added by Stan Brown (SBD)
#
################################################################################
#  Copyright (c)2000-2003 Invensys Process Systems/The Cassandra Project
#  All Rights Reserved.                                               
#                                                                     
#  This is free software; you can redistribute it and/or modify it    
#  under the terms of the GNU General Public License as published by  
#  the Free Software Foundation; either version 2 of the License, or  
#  (at your option) any later version.                                
#                                                                     
#  This software is distributed in the hope that it will be useful,   
#  but WITHOUT ANY WARRANTY; without even the implied warranty of     
#  merchantability or fitness for a particular purpose. See the GNU   
#  General Public License (http://www.fsf.org/copyleft/gpl.htm)for    
#  more details.                                                      
#                                                                     
#  To obtain the GNU General Public License, write to:                
#                                                                     
#      Free Software Foundation, Inc.                                 
#      59 Temple Place - Suite 330                                    
#      Boston, MA  02111-1307                                         
#      USA                                                            
################################################################################
# Revision history:
# Feb 23, 2000 - Initial release.
# Feb 24, 2000 + Added usage information.
#              + Added backup procedure for older save_all's.
#              - A lot of testing, seems OK.
#              + Added log-file: saveall.log.
#              - Major clean-up of original script.
# Feb 25, 2000 - A lot of problems solved, it seems to work now!
#              - Compressing the backup tar files to save space.
#              - All tests pas%&&*!@~~!@#$!____!!@$$#%%$^&^^&
#                core dumped.
# Feb 28, 2000 - Let's call it Version 1.0 (Amsterdam)!
#              + Fixed: Scripts did not work in crontab, added ./
#              + Added check for control station and remote hosts.
# Feb 29,2000  - Version 1.1 (Breda)!
#              + Added 20 Series host support
#              + Cleaned up the script. Tested remote stations handling.
#              + Improved reporting to screen and log file.
# Mar 01,2000  - Version 1.2 (Coevorden)!
#              + Added Windows NT Support, Added archive management.
#              + Added free space check.
# Mar 02,2000  - Version 1.3 (Deventer)!
# (RD)         + Enhanced NT Support. Improved reporting.
#              + Bug fix: script would fail with no SAVEALL directory 
#                (UNIX only).
# Mar 10,2000  - Version 1.3.2 (Deventer Noord-Oost)
# (BM)         + Bug fixed: Deletion of old backups was done BEFORE making
#                new backup, causing one backup more then specified.
#              + Timestamp for backups now saveall-time instead of backup-
#                time, including hour:minutes, so more then 1 backup per day
#                is possible.
# Aug 22,2000  - Version 2.0 
# (MDW/SDB/RD) + Added -u option to include upload before save_all (SBD)
#              + Added the -h HOST option to make save_all's for HOST (RD)
#              + Fixed: restore the "before last" save_all when
#                last save_all failed (RD)
#              + Added recursive search for include files in sequences (MDW)
#                Include files are stored in "$SA_DIR/include"
# Nov 09, 2000 + Time of backup fixed (only occurred on NT-platform)
# Feb,Mar 2001 + Remote host includes added
# (MDW/RD)     + Includes saved with "relative" paths
#              + Cleaned up script and tested on NT platform
#              + Added external config file support (filename: save_all.cfg)
# Dec 12, 2001 - Version 2.1  
# (MDW/RD)     + Bug fix. Timeout was set to 0 after first CP with surplus
#                backups, resulting in no prompt/timeout for all others.
#              + Bug fix. No validation done on user CPFILE file. 
#              + Enhancement: show if external "save_all.cfg" used at startup.
#              + Enlarged STATKB from 2000 to 5000 kb.(estimated reqd diskspace
#                per station)
#              + Bug fix. Remote locked stations would not be 
#                identified as such.
#              + Bug fix. Diskspace check always counts all controlstations,
#                even if only a few where selected.
#              + Renamed all tmp files, added "sa_" prefix
#              + Removed "schrink" command from "upload" function, reason was
#                possible workfile corruption.
#              + Added include search for SFC files
# May 2002     - Verson 2.2
# (RD)         + Version  new variable "PF" for temp files (prefix).
#              + Added save_all of volumes in this version. (by request)
#              + Modified create save_all dir using mkdir -p command.
#              + Entering bogus -b option, no longer stops save_all,instead
#                continues with default value in script or config file.
#              + Added few cleanup statements when script would exit.
#              + Logfiles are now saved with save_all date and old logs are
#                in "log" directory.
#              + Some minor fixes to logfile.
# Jan 2003     - Version 2.2.1
# (MDW/RD)     + Bug fix. Sequence include search could not 
#                handle #include <filename> syntax
#                Usually the syntax is #include "filename"
#              + Modified: Include files were always searched on "remote 
#                station", even if the host was the local station
#              + Bug fix. Temp files where not cleared after exit. Could result
#                in multiple save_all's.
#              + Added feature. Script is now IACC aware. Will not start if 
#                system is prepared for the new IACC platform.
#              + Bug fix. Changed the crontab example because the cfg file 
#                would not be found the script home directory
# Apr 2003     + Also search for include files relative to the ciocfg directory
# (MDW)          Many people still use this form of defining include files, or
#                it was 'already' like that in the sequencecode. So we 
#                implemented this searchpath at your desire.
# May 2003     + Added rudimentary interrupt handling. At least cleanup tmp
# (RD)           files after CTRL_C and CTRL_D.
#              + Added "local" command line switch to save_all all stations
#                hosted by local host only.
#              + Added -tst parameter for debugging purpose. Keeps tmp files.
#              + Added support for LOG variable in CFG file.
################################################################################
# BUGS/CONSIDERATIONS/WISHES:
#
# - To run from cron, redirect output to /dev/null 2>&1 for instance:
#   30 2 * * 6   cd /opt/tools ; ./save_all.sh -h AW5101 -s MG3 -b 25 > /dev/null 2>&1
#
# - When forcing 25 backup's with a line in crontab, executing a commandline
#   save_all with -b is less than 25 will remove the surplus backups!! User is
#   warned when this happens and gets $TIMEOUT seconds to abort per station.
#
#  -Including files in sequences must be done with absolute paths
#   Correct:   #include "../include/thefile.inc"
#   Incorrect: #include "/opt/fox/ciocfg/include/thefile.inc"
#   Incorrect: #include "thefile.inc" (this will locate the include file in
#                              /usr/fox/ciocfg/sequeninclude
#                         or   /opt/fox/ciocfg/sequeninclude)
#                         depending on the host platform.
#
# - No fix yet for config files for Profibus stored in 
#   /usr/fox/sp/files/devices
#
# - Pointing to an illegal LOG file will exit the script without usage info
#
################################################################################
# Example save_all.cfg file
################################################################################
# # START of file
# # Here make you own choices for the standard parameters
# # DO NOT use the "root" directory for anything at all!!
# # This file will not be overwritten by new version save_all.sh script
# # Format:
# # VARIABLE=VALUE
# #************************************************************************
# # This file name MUST be save_all.cfg to work with save_all.sh version 2.x
# # and MUST be located in the same directory as save_all.sh
# #************************************************************************
#  
# SA_DIR=/opt/SAVEALLS
# CPFILE=/etc/cplns
# LBFILE=/etc/lblns
# APFILE=/etc/aplns
# UPLOAD=FALSE
# ARCHNR=15
# STATKB=2000
# # END of file
################################################################################
################################################################################
# Variable definition starts here
################################################################################
PF="sa221_tmp"                         # Prefix for tmp files.
PLATFORM=`uname -s`                    # define platform
SN_NAME=`uname -n`                     # this station's name
TIMESTAMP=`date '+D%m%dT%H%M'`         # The date and time now
CURDIR=`pwd`                           # the current directory.
LOG=$CURDIR/save_all.log               # use this for logfile
PROG=`basename $0`                     # Returns this script's name without
                                       # the path
SA_DIR="/opt/SAVEALLS"                 # Location of save_alls.
CPFILE="/etc/cplns"                    # List for selected stations (all).
APFILE="/etc/aplns"                    # List for selected hosts (all).
LBFILE="/etc/lblns"                    # List for selected volumes (all).
LBCPFILE=`cat "$CPFILE" "$LBFILE"`     # System file with all control station,
                                       # (not just CP's), DO NOT EDIT.
TRUE_APFILE="/etc/aplns"               # System file with all application 
                                       # processors, DO NOT EDIT.
SLDB="/usr/fox/sp/sldb"                # Control Station / host relation
USRCP="FALSE"                          # No user CPFILE by default
USRAP="FALSE"                          # No user APFILE by default
USRLB="FALSE"                          # No user LBFILE by default
HLDB="/usr/fox/sp/hldb"                # Station ID file for configured stations
UPLOAD="FALSE"                         # No upload by default. Thanks Stan Brown
HOST_SLCT="no"                         # No host filter, All hosts selected
PATH=$PATH:/usr/local                  # Add /usr/local to PATH
EXEC_DIR="/opt/fox/ciocfg/api"         # the location of the api utils.
LOCK_DIR="/usr/fox/sp/locks"           # the lock files
CIO_DIR="/opt/fox/ciocfg"              # CIOCFG directory
SEQINCL="/opt/fox/ciocfg/sequeninclude/"  # Sequence include directory
ICC="/usr/fox/config/Control_Cfg"      # Where is the ICC located
STATKB=2000                            # minimum of free kbytes needed per 
                                       # station (estimate!!!)
ARCHNR=10                              # default number of backup archives in 
                                       # backup dir
BIDLIST="|207|C002|"                   # Stations without remote host support. 
                                       # Syntax is |HLDB_Value_for_bad_station
                                       # Note pipe symbol. Currently applies to
                                       # NT only (ID's are from $HLDB file)
TIMEOUT=10                             # General time-out time 
CFG=$CURDIR/save_all.cfg               # External configuration file
TESTRUN="FALSE"                        # a test run parameter
if [ "$PLATFORM" = "Windows_NT" ]      # Define executable Names
then
   SA_EXEC="save_all.ksh"
   SORT="/nutc/mksnt/sort"
   UNIQ="/nutc/mksnt/uniq"
   FIND="/nutc/mksnt/find"
else
   SA_EXEC="save_all"             
   SORT="/usr/bin/sort"
   UNIQ="/usr/bin/uniq"
   FIND="/usr/bin/find"
fi
# Remove all the temp-files
rm $CURDIR/"$PF"* >/dev/null 2>&1
################################################################################
# Handle interrupts
################################################################################
trap "echo 
      echo Interrupt received! aborting save_all... ;\
      echo Removing temp-files
      rm $CURDIR/"$PF"* >/dev/null 2>&1
      echo If save_all was in progress, station may be locked!
      exit 5  " 1 2 15
################################################################################
# Show version and determine if external configuration is in order
################################################################################
echo "$VERSION"
echo
################################################################################
# External config file will override the script defaults
################################################################################
# look for external config file ($CFG)
if [ -f $CFG ]
then
   echo "Processing \"$CFG\" file."
#
   USRSA_DIR=`cat $CFG | grep SA_DIR | cut -d"=" -f2 | sed s/\"//g`
   if [ "$USRSA_DIR" != "" ] && [ "$USRSA_DIR" != "/" ]
   then
      SA_DIR=$USRSA_DIR
   fi
   USRCPFILE=`cat $CFG | grep CPFILE | cut -d"=" -f2 | sed s/\"//g`
   if [ "$USRCPFILE" != "" ] && [ -f "$USRCPFILE" ]
   then
      CPFILE=$USRCPFILE
      USRCP="TRUE"
   fi
   USRAPFILE=`cat $CFG | grep APFILE | cut -d"=" -f2 | sed s/\"//g`
   if [ "$USRAPFILE" != "" ] && [ -f "$USRAPFILE" ]
   then
      APFILE=$USRAPFILE
      USRAP="TRUE"
   fi
   USRLBFILE=`cat $CFG | grep LBFILE | cut -d"=" -f2 | sed s/\"//g`
   if [ "$USRLBFILE" != "" ] && [ -f "$USRLBFILE" ]
   then
      LBFILE=$USRLBFILE
      USRLB="TRUE"
   fi
   USRARCHNR=`cat $CFG | grep ARCHNR | cut -d"=" -f2 | sed s/\"//g`
   if [ "$USRARCHNR" != "" ]
   then
      ARCHNR=$USRARCHNR
   fi
   USRUPLOAD=`cat $CFG | grep UPLOAD | cut -d"=" -f2 | sed s/\"//g`
   if [ "$USRUPLOAD" = "TRUE" ]
   then
      UPLOAD=$USRUPLOAD
   fi
   USRSTATKB=`cat $CFG | grep STATKB | cut -d"=" -f2 | sed s/\"//g`
   if [ "$USRSTATKB" != "" ]
   then
      STATKB=$USRSTATKB
   fi
   USRLOG=`cat $CFG | grep LOG | cut -d"=" -f2 | sed s/\"//g`
   if [ "$USRLOG" != "" ]
   then
      LOG=$USRLOG
      USRLOG="TRUE"
   fi
fi
# Define the "supporting" directories here
BU_DIR=$SA_DIR/backup             # Location of backup save_alls.
PB_DIR=$SA_DIR/profibus           # Location of Profibus config files.
LOG_DIR=$SA_DIR/log               # Location of old log files.
INC_DIR=$SA_DIR/include           # sequence include files directory
touch $LOG > /dev/null 2>&1
if [ ! -f "$LOG" ]
then
   echo "Cannot create log file with this name: $LOG"
   exit
fi

################################################################################
# Cleanup and manage old log files
################################################################################
# Manage ARCHNR log files
LOGFILE=`basename $LOG`
mv $LOG $LOG_DIR/$LOGFILE$TIMESTAMP > /dev/null 2>&1
# No need to keep more than ARCHNR logfiles I think?
LOGLVL=`ls -l $LOG_DIR/$LOGFILE*|wc -l` > /dev/null 2>&1
DELLVL=`expr $LOGLVL - $ARCHNR`
if [ $DELLVL -gt 0 ]
then 
   for OLDLOG in `ls -lt $LOG_DIR/$LOGFILE* | tail -$DELLVL | awk '{print $9}'`
   do
     ls $OLDLOG
     rm $OLDLOG
   done
fi
################################################################################
# If IACC is used, skip the save_all script
################################################################################
if [ ! -d $ICC ]
then
   echo "This system appears to be configured for IACC." | tee -a $LOG
   echo "Check for Control_Cfg entry under /usr/fox/config when in doubt." | tee -a $LOG
   echo "Save_all script can't continue, exiting..." | tee -a $LOG
   # Remove all the temp-files
   rm $CURDIR/"$PF"* >/dev/null 2>&1
   exit 1
fi
################################################################################
# Define some functions first
################################################################################
# Function to display command usage and exit
################################################################################
usage_exit ()
{
   echo "Usage: $PROG  -s string [[string] [...]] [-h string [[string] [...]] [-u][-b backups]"
   echo "  $PROG all/local [-b backups] [-h string1 string2] [-u]"
   echo "  Use regular expression similar to grep ( no * ):"
   echo "  Where: -u        = force upload first"
   echo "         -s string = [part of] station or volume letterbug"
   echo "         -b digit  = number of backup's to be maintained"
   echo "         -h string = [part of] host letterbug"
   echo "Example:  $PROG all"
   echo "   Make a save_all for ALL stations by ALL hosts in"
   echo "   "$SA_DIR", maintaining "$ARCHNR" backups."
   echo "Example:  $PROG local"
   echo "   Make a save_all for ALL stations by this hosts in"
   echo "   "$SA_DIR", maintaining "$ARCHNR" backups."
   echo "Example:  $PROG -s P30 -b 4 -u"
   echo "   Do an upload and make a save_all for stations:"
   echo "   CP3011, MGCP30, ACP30A, ..., in "$SA_DIR", maintaining 4 backups:"
   echo "Example:  $PROG -h `uname -n` all"
   echo "   will make a save_all for all stations hosted by `uname -n`"
   echo "   in "$SA_DIR" maintain "$ARCHNR" backups. (the \"all\" parameter is optional)"
   echo
   exit 1
}
################################################################################
# Function to do the upload/checkpoint
################################################################################
upload ()   # this function first builds the upload command file for
            # the upload then performs the actual uploading of parameters
            # of the specified CP to the workfile
            #
            # parameter:  $1  letterbug ID of CP to be uploaded
{
    CMD=$CURDIR/$1.upload
    ULOG=$CURDIR/$1.log
    echo OPEN $1 MODIFY byDuc > $CMD
    echo UPLOAD              >> $CMD
    echo CHECKPOINT 300      >> $CMD
    echo CLOSE               >> $CMD
    echo EXIT                >> $CMD
    echo "  `date` " >> $LOG
    echo "  Upload and checkpoint $1" >> $LOG
    ./iccdrvr.tsk -i $CMD -o $ULOG -n ECHO
    cat $ULOG >> $LOG
    rm $ULOG $CMD 2> /dev/null
}
################################################################################
# If no options, show usage info and exit.
################################################################################
if [ ! $# -gt 0 ]
then 
   usage_exit
fi
################################################################################
# For the 70 Series platform: Verify that script is installed/executed 
# from drive D:.
################################################################################
if [ "$PLATFORM" = "Windows_NT" ]
then
   DRIVE=`pwd|cut -c1`
   if [ "$DRIVE" != "D" ] && [ "$DRIVE" != "d" ]
   then
     echo "Script must be executed from D-drive" | tee -a $LOG
     echo
     exit
   fi
fi
################################################################################
# Because Control configurator API is not available on WP's or Venix,
# check for executable presence, no use to go on if it's not there...
################################################################################
if [ ! -f $EXEC_DIR/$SA_EXEC ]
then
   echo "No "$SA_EXEC" program found." | tee -a $LOG
   echo "This program must be run from 50/70 Series AP or AW." | tee -a $LOG
   echo "aborting..."| tee -a $LOG
   exit 2
fi
################################################################################
# Set some defaults first: select all stations on all hosts (unless user
# overrides are in place)
################################################################################
for NAME in `echo $LBCPFILE`
do
   echo $NAME >> "$CURDIR"/"$PF"lbcplns
done
TRUE_CPFILE="$CURDIR"/"$PF"lbcplns     # System file with stations and vols
                                       # DO NOT EDIT.
cp $TRUE_CPFILE $CURDIR/"$PF"cplns
cp $APFILE $CURDIR/"$PF"aplns
CPFILE=$TRUE_CPFILE
################################################################################
# Start command-line evaluation
################################################################################
while [ $# -gt 0 ]
do
   case $1 in
      all)
         # This selection indicates all stations in the variable CPFILE 
         echo "Save-all for all stations in $CPFILE." | tee -a $LOG
         if [ "$USRCPFILE" = "$CPFILE" ]
         then
            for STA in `cat $CPFILE`
            do
              # Check if the stations are valid for this system
              grep $STA $TRUE_CPFILE >> "$CURDIR"/"$PF"cpln
            done
            # Remove possible duplicate letterbugs due to selection criteria
            $SORT "$CURDIR"/"$PF"cpln|$UNIQ > "$CURDIR"/"$PF"cplns
            CPFILE="$CURDIR"/"$PF"cplns
            if [ ! -s $CPFILE ]
            then
               echo "No stations matching selection criteria" | tee -a $LOG
               echo
               # Remove all the temp-files
               rm $CURDIR/"$PF"* >/dev/null 2>&1
               exit 1
            fi
         else
            cat "$TRUE_CPFILE"
            cp "$TRUE_CPFILE" "$CURDIR"/"$PF"cplns
            CPFILE="$TRUE_CPFILE"
         fi
         shift
      ;;
      local)
         HOST_SLCT="yes"
         # This selection indicates selection of local host only
         while [ $# -gt 0 ] && [ `echo $1|cut -c1` != "-" ]
         do
            HOST_NAMES=`grep "$SN_NAME" "$APFILE"`
            echo "$HOST_NAMES" > "$CURDIR"/"$PF"aplns
            shift
         done
            HOSTFILE="$CURDIR"/"$PF"aplns
            echo "Matching hosts:" | tee -a $LOG
            cat $HOSTFILE | tee -a $LOG
            echo
      ;;
      -b)
         # Determine number of backups.
         # move the -b parameter out of the way
         shift
         if [ $# -gt 0 ]
         then
            USRARCHNR=`expr $1 + 0 2>/dev/null`
            if [ "$?" != "0" ] || [ "$ARCHNR" -lt 1 ]
            then
               echo "-b option is not a number value, revert to default of ""$ARCHNR" | tee -a $LOG
            ARCHNR="$ARCHNR"
            fi
         else
            echo "-b option is not a valid value, revert to default of ""$ARCHNR" | tee -a $LOG
            ARCHNR="$ARCHNR"
         fi
         shift
      ;;
      -u)
         # Do upload before a save_all
         shift
         UPLOAD="TRUE"
         # export UPLOAD
      ;;
      -s)
         # Only save_all some stations.
         # move the -s parameter out of the way and see what we have
         shift
         # the next parameter should be (part of) a Control station lbug
         # and the number of params should be 1 or greater
         if [ ! $# -gt 0 ]
         then
   	    echo "No station(s) specified after -s" | tee -a $LOG
   	    echo
	    usage_exit
         fi
         echo "Creating station letterbug file..." | tee -a $LOG;echo
         while [ $# -gt 0 ] && [ `echo $1|cut -c1` != "-" ]
         do
   	    # Check if the stations are valid for this system.
	    grep $1 $TRUE_CPFILE >> "$CURDIR"/"$PF"cpln
	    shift
         done
         # Remove possible duplicate letterbugs due to selection criteria
         $SORT "$CURDIR"/"$PF"cpln|$UNIQ > "$CURDIR"/"$PF"cplns
         # When we have a user CPFILE do something more.
         if [ "$USRCP" = "TRUE" ]
         then
            for CP in `cat $CURDIR/"$PF"cplns`
            do
              grep $CP $USRCPFILE >> $CURDIR/"$PF"usrcplns
            done
            CPFILE="$CURDIR"/"$PF"usrcplns
         else
            CPFILE="$CURDIR"/"$PF"cplns
         fi
         if [ ! -s $CPFILE ]
         then
	    echo "No stations matching selection criteria" | tee -a $LOG
	    echo 
            # Remove all the temp-files
            rm $CURDIR/"$PF"* >/dev/null 2>&1
	    exit 1
         fi
      ;;
      -h)
         HOST_SLCT="yes"
         # This selection indicates selection of hosts
         # move the -h parameter out of the way to see which hosts
         shift
         # the next parameter should be (part of) a Host lbug
         # and the number of params should be 1 or greater
         if [ ! $# -gt 0 ]
         then
   	    echo "No host(s) specified after -h" | tee -a $LOG
   	    echo
	    usage_exit
         fi
         while [ $# -gt 0 ] && [ `echo $1|cut -c1` != "-" ]
         do
            HOST_NAMES=`grep $1 $APFILE`
            echo $HOST_NAMES >> $CURDIR/"$PF"apln
            shift
         done
            for T in `cat $CURDIR/"$PF"apln`
            do
              echo $T >> $CURDIR/"$PF"hostfile
            done
            if [ ! -s $CURDIR/"$PF"hostfile ] 
            then
	       echo "No hosts matching selection criteria" | tee -a $LOG
               echo
               rm $CURDIR/"$PF"* > /dev/null 2>&1
               usage_exit
            fi
            # Remove possible duplicate hosts due to selection criteria
            $SORT "$CURDIR"/"$PF"hostfile|$UNIQ > "$CURDIR"/"$PF"aplns
            HOSTFILE="$CURDIR"/"$PF"aplns
            echo "Matching hosts:" | tee -a $LOG
            cat $HOSTFILE | tee -a $LOG
            echo
      ;;
      -tst)
         # if set do not make savealls but exit after running init.
         TESTRUN="TRUE"
         shift
      ;;
      *)
         echo "Unknown argument or syntax error." | tee -a $LOG
         usage_exit
      ;;
   esac
done
if [ ! -f $CURDIR/"$PF"cplns ]
then
  echo "No stations specified!" | tee -a $LOG
  echo
  usage_exit
fi
################################################################################
# printing a list of all the stations / hosts to be processed
################################################################################
echo;echo "Stations selected for save_all:" | tee -a $LOG
echo "Station      Host name" | tee -a $LOG
for CP in `cat $CPFILE`
do
   HOST=`awk '{if ($1==cp) {print $2} }' cp=$CP < $SLDB`
   if [ $HOST_SLCT != "yes" ] 
   then 
      echo "$CP       $HOST" | tee -a $LOG $CURDIR/"$PF"cpap
   else 
      echo "$CP       $HOST" >> $CURDIR/"$PF"cpap
   fi
done
# When there was a selection of hosts the HOST_SLCT variable is yes
if [ $HOST_SLCT = "yes" ]
then
   rm "$CURDIR"/"$PF"scratch > /dev/null 2>&1
   for AP in `cat "$HOSTFILE"`
   do
      cat "$CURDIR"/"$PF"cpap | grep $AP >> "$CURDIR"/"$PF"scratch
   done
   # let's see what we have
   cat "$CURDIR"/"$PF"scratch | tee -a $LOG
   cat "$CURDIR"/"$PF"scratch | awk ' {print $1}' > $CUR_DIR/"$PF"cplns
   CPFILE=$CUR_DIR/"$PF"cplns
fi
################################################################################
# Setting up the basic administration.
################################################################################
#
# Check for all required directories and create if needed
echo "Checking directory administration, please wait..."
if [ ! -d $SA_DIR ]
then
   mkdir -p $SA_DIR
fi
if [ ! -d $BU_DIR ]
then
   mkdir $BU_DIR
fi
if [ ! -d $INC_DIR ]
then
   mkdir $INC_DIR
fi
if [ ! -d $LOG_DIR ]
then
   mkdir $LOG_DIR
fi
if [ ! -d $PB_DIR ]
then
   mkdir $PB_DIR
fi
echo "Done"
# Create a directory for all the configured control stations
#
echo "Creating station directory if required..."
for CP in `cat $CPFILE`
do
if [ ! -d $SA_DIR/$CP ]
then 
   mkdir $SA_DIR/$CP
fi
done
echo "Done"
################################################################################
# Check for diskspace
################################################################################
STATNR=`cat "$CPFILE"|wc -l`
NEEDED=`echo "$STATNR * $STATKB" |bc`
if [ "$PLATFORM" = "Windows_NT" ] 
then
   AVAILABLE=`df -k D: |tail -1|awk '{print $3}'|awk -F"/" '{print $1}'`
else
   AVAILABLE=`df -k $SA_DIR|tail -1 | awk '{print $4}'`
fi
echo "Available space on system:          ""$AVAILABLE"" kb" | tee -a $LOG
echo "Estimated space required on system: ""$NEEDED"" kb" | tee -a $LOG
if [ $NEEDED -gt $AVAILABLE ]
then
  echo "Not enough space available for selected stations" | tee -a $LOG
  # Remove all the temp-files
  rm $CURDIR/"$PF"* >/dev/null 2>&1
  exit 1
fi
################################################################################
# The actual save_all part starts here
################################################################################
echo
echo "#####################################################"| tee -a $LOG
echo "# Automatic save-all procedure started"| tee -a $LOG
echo "# $VERSION" | tee -a $LOG
if [ $UPLOAD = "TRUE" ]
then
   echo "#  -> Performing upload before save-all"| tee -a $LOG
fi
echo "# Date:                  "`date` | tee -a $LOG
echo "# Started on:            "$SN_NAME | tee -a $LOG
echo "# Save-all Location:     "`uname -n`"  "$SA_DIR | tee -a $LOG
echo "# Backup location:       "$BU_DIR | tee -a $LOG
echo "# Include file location: "$INC_DIR | tee -a $LOG
echo "# Writing logfile in:    "$LOG
   if [ -f $CFG ]
   then
echo "# External config file:  "$CFG | tee -a $LOG
   fi
echo "#####################################################"| tee -a $LOG
#
################################################################################
# If only a testrun exit here
################################################################################
if [ $TESTRUN = "TRUE" ] 
then
   echo "Only a test run, no save_alls done."
   exit 4
fi
################################################################################
# Start with routine to make the save_alls
#

for CP in `cat $CPFILE` 
do 
   HOST=`awk '{if ($1==cp) {print $2} }' cp=$CP < $SLDB`
  if [ "$HOST" = "" ]
  then
    echo "#####################################################"| tee -a $LOG
    echo "# $CP is not a valid station         " | tee -a $LOG
    echo "#####################################################"| tee -a $LOG
    LOCK="unknown"
  else
    cd $EXEC_DIR
    echo "#####################################################"| tee -a $LOG
    echo " Save_all starting for: $CP hosted by $HOST" | tee -a $LOG
    echo "-----------------------------------------------------"| tee -a $LOG
    # Station may be in use by another ICC session
    # So, check if station is locked (also remote hosts)
    if [ "$HOST" = "$SN_NAME" ]
    then
      #echo "Station is hosted locally." | tee -a $LOG
      if [ -f $LOCK_DIR/*"$CP"+ ]
      then
         LOCK="yes"
	    echo "Database locked, skipping $CP" | tee -a $LOG
	 else
	    LOCK="no"
	 fi
      else
	 # Check platform to see how to connect to remote host
	 # Remote connection is not supported on NT!!!!
         STATID=`grep $HOST $HLDB|awk '{print $2}'`
         IDCHECK=`echo "$BIDLIST"|grep "|"$STATID`
	 if [ "$PLATFORM" = "Windows_NT" ] || [ "$IDCHECK" != "" ] 
	 then
	    echo "Remote host-access not supported on 70 Series" | tee -a $LOG
            rmdir "$SA_DIR/$CP" # Saveall dir not needed
	    LOCK="unknown"
	 else
	    echo "Contacting $HOST..." | tee -a $LOG
	    # Check if remote station is rmounted and where
	    MOUNTPOINT=`rmount | grep $HOST | awk '{print $4}'`
	    if [ "$MOUNTPOINT" = "" ]
	    then
	       if [ ! -d /rem/$HOST ]
	       then
		  mkdir /rem/$HOST
	       fi
	       rmount $HOST /rem/$HOST 2>/dev/null
               if [ "$?" -ne "0" ]
               then
                   echo "$HOST is not responding or unavailable" | tee -a $LOG
                   LOCK="unknown" 
	       elif [ -f /rem/"$HOST"/"$LOCK_DIR"/*"$CP"+ ]
	       then
		  LOCK="yes"
		  echo "Database locked, unable to perform the save_all." | tee -a $LOG
	       else
		  LOCK="no"
	       fi
               MOUNTPOINT=`rmount | grep $HOST | awk '{print $4}'`
	       rumount $HOST 2>/dev/null
	    else
	       if [ -f "$MOUNTPOINT""$LOCK_DIR"/"$CP"+ ]
	       then
		  LOCK="yes"
	       else
		  LOCK="no"
	       fi
	    fi
	 fi
      fi
      # Lock check complete
  fi
      
      if [ -d $SA_DIR/$CP/*STA ] && [ $LOCK = "no" ]
      then
	 echo "Found a previously stored save_all for this station." | tee -a $LOG
	 echo "Making back-up first" >> $LOG
	 echo "Making back-up first\r\c" 
	 NAME=`ls -ld $SA_DIR/$CP/*STA"" | awk '{print $7 $6 $8}' | sed s/\://`
	 cd $SA_DIR
	 echo "...backing-up $CP" >> $LOG
	 echo "...backing-up $CP \r\c" 
	 tar cf $BU_DIR/$NAME"_"$CP.tar $SA_DIR/$CP > /dev/null 2>&1
         if [ -f $SA_DIR/include/$CP.tar ]
         then
           tar rf $BU_DIR/$NAME"_"$CP.tar $SA_DIR/include/$CP.tar >/dev/null
           rm $SA_DIR/include/$CP.tar
         fi
	 compress -f $BU_DIR/$NAME"_"$CP.tar >/dev/null
	 echo "Back-up is: ""$BU_DIR""/""$NAME""_""$CP.tar.Z" | tee -a $LOG
         # determine level of backups until now
         LVL=`ls -l $BU_DIR/*"$CP"*|wc -l` 2>/dev/null
         DEL=`echo "$LVL - $ARCHNR" |bc`
         if [ $DEL -gt 0 ]
         then
            if [ $DEL -gt 1 ] 
            then
              echo
              echo ""$DEL" archived save_all(s) will be deleted"
              echo "Press CTRL-C to abort"
              TIMELEFT=$TIMEOUT
              while [ $TIMELEFT -gt -1 ] 
              do
                echo "Continuing in $TIMELEFT  \r\c";sleep 1;
                TIMELEFT=`echo $TIMELEFT - 1|bc` 
              done
              echo "Removing surplus archives" | tee -a $LOG
            fi
            for DELFILE in `ls -lt $BU_DIR/*"$CP"*|tail -$DEL|awk '{print $9}'`
            do
              rm $DELFILE
            done
         fi
	 rm -r $SA_DIR/$CP/*
         BACKUP="TRUE"
      elif [ $LOCK = "no" ]
      then   
	 echo "No previously stored save-all found to backup." | tee -a $LOG
         BACKUP="FALSE" 
      fi
      if [ $LOCK = "no" ]
      then cd $EXEC_DIR
         if [ $UPLOAD = "TRUE" ]
         then 
            echo "Starting upload/checkpoint....\r\c" | tee -a $LOG
            echo "Starting upload/checkpoint...." >> $LOG
            upload $CP
            echo "Upload & checkpoint ready         " | tee -a $LOG
         fi
	 echo "Save_all for $CP started" | tee -a $LOG
	 # Insert ./ to ensure the scripts runs OK from cron!
	 ./$SA_EXEC $CP $SA_DIR/$CP > /dev/null & 
	 PID=`echo $!`
	 #echo "PID= $PID"
	 VAR=0 
	 while [ $VAR -ne 1 ]
	 do
	   ps -p $PID > /dev/null  2>&1
	   VAR=$?
	   echo "|\r\c";sleep 1;echo "/\r\c";sleep 1
	   echo "-\r\c";sleep 1;echo "\\ \r\c";sleep 1
	 done
	 if [ ! -f /tmp/output* ]
	 then
         #
         # Start with routine to search include files
         #
            if [ "$HOST" != "$SN_NAME" ]
            then
               MOUNTPOINT=`rmount | grep $HOST | awk '{print $4}'`
               if [ "$MOUNTPOINT" = "" ]
               then
                 rmount $HOST /rem/$HOST 2>/dev/null
               fi
            fi
            HOST_HLDB=`grep $HOST $HLDB | awk ' {print $2} '`
            if [ $HOST_HLDB != "303" ]
            then
              SEQINCL="/opt/fox/ciocfg/sequeninclude/"
            else
              SEQINCL="/usr/fox/ciocfg/sequeninclude/" 
            fi
            echo "Searching for sequence include files..." | tee -a $LOG
            # First search for main sequencefiles
            $FIND $SA_DIR/$CP -name "*.s" -print > $CURDIR/"$PF"2search
            ###################################################################
            #ADDED FOR SFC SUPPORT
            $FIND $SA_DIR/$CP -name "*.k" -print >> $CURDIR/"$PF"2search
            ###################################################################
            touch $CURDIR/"$PF"inc_lines
            touch $CURDIR/"$PF"found
            # Begin search of nested include files
            while [ -s $CURDIR/"$PF"2search ]
            do
              for FILE in `cat $CURDIR/"$PF"2search|$UNIQ`
              do 
                grep "#include" $FILE >> $CURDIR/"$PF"inc_lines
                REL=`grep "\.\.\/" $FILE`
                if [ -n "$REL" ]
                then
                  echo "File $FILE contains relative paths:" | tee -a $LOG
                  echo "$REL \n" | tee -a $LOG
                fi
              done
              #################################################################
              # MODIFIED FOR SFC SUPPORT
              # Replace < and > by quotes 
              sed -e 's/[<,>]/\"/g' $CURDIR/"$PF"inc_lines|cut -f2 -d "\"" > $CURDIR/"$PF"presearch
              # ADDED FOR SFC SUPPORT
              # Replace backslashes with forward slashes and remove drive-letters
              sed "s/\\\/\//g" $CURDIR/"$PF"presearch > $CURDIR/"$PF"presearch2
              sed "s/\\D://g" $CURDIR/"$PF"presearch2 > $CURDIR/"$PF"search
              #################################################################
              rm $CURDIR/"$PF"2search $CURDIR/"$PF"inc_lines >/dev/null 2>&1
              ERROR="FALSE"
              # Preventing script-looping by include loops
              for NAME in `cat $CURDIR/"$PF"search`
              do
                INCGREP=`grep $NAME $CURDIR/"$PF"found`
                if [ -z "$INCGREP" ]
                then 
                   CHAR1=`echo "$NAME"|cut -c1` 
                   CHAR2=`echo "$NAME"|cut -c1,2` 
                   if [ "$CHAR1" = "/" ] # Absolute path of sequence include file
                   then 
                     if [ ! -f "$MOUNTPOINT$NAME" ]
                     then
                       echo "WARNING: Include file \"$MOUNTPOINT$NAME\" does not exist!!" >> $LOG
                       ERROR="TRUE"
                     else 
                       echo "$MOUNTPOINT$NAME" >> $CURDIR/"$PF"2search
                       echo ".$NAME" >> $CURDIR/"$PF"found
                     fi
###############################################################################
                   elif [ "$CHAR2" = ".." ] # Relative path of sequence include file
		   then
                     # Remove the 2 dots before the file/dir name
		     NAME_REL=`echo $NAME|cut -c3-200` 
		     # Only look for includes relative to the CIOCFG dir.
		     # If relative path's are otherwise defined in sequences 
		     # that's just bad and sloppy programming!!
		     echo "Looking for relative include file:\n $NAME"  >> $LOG
		     echo " in\n $MOUNTPOINT$CIO_DIR$NAME_REL"  >> $LOG
                     if [ -f "$MOUNTPOINT$CIO_DIR$NAME_REL" ]
                     then
                       echo "$MOUNTPOINT$CIO_DIR$NAME_REL" >> $CURDIR/"$PF"2search
                       echo ".$CIO_DIR$NAME_REL" >> $CURDIR/"$PF"found
		       echo "Found: $MOUNTPOINT$CIO_DIR$NAME_REL" >> $LOG
                     else 
                       echo "WARNING: Include file \"$MOUNTPOINT$CIO_DIR$NAME_REL\" does not exist!!" >> $LOG
                       ERROR="TRUE"
		     fi
                   else # No pathname = default path to include directory
                     if [ -f "$MOUNTPOINT$SEQINCL$NAME" ]
                     then
                       echo "$MOUNTPOINT$SEQINCL$NAME" >> $CURDIR/"$PF"2search
                       echo ".$SEQINCL$NAME" >> $CURDIR/"$PF"found
                     else 
                       echo "WARNING: Include file \"$MOUNTPOINT$SEQINCL$NAME\" does not exist!!" >> $LOG
                       ERROR="TRUE"
                     fi
                   fi
###############################################################################
                fi  
              done
            done
	    # If ERROR is true, this means one of the include files in this 
	    # save-all wasn't found
            if [ "$ERROR" = "TRUE" ]
            then
              echo "There were errors with include files!!!"
	      echo "Check $LOG for more details."
            fi 
            # Creating a nice sorted list
            $SORT $CURDIR/"$PF"found|$UNIQ > $CURDIR/"$PF"uniq
            rm $CURDIR/"$PF"found
            # Store include files if there are any
            if [ -s $CURDIR/"$PF"uniq ]
            then
               #tar cf $INC_DIR/$CP.tar -I $CURDIR/"$PF"uniq >/dev/null 2>&1
               if [ -n "$MOUNTPOINT" ]
               then 
                 cd $MOUNTPOINT
               else
                 cd /
               fi
               tar cf $INC_DIR/$CP.tar  `cat $CURDIR/"$PF"uniq` >/dev/null 2>&1
               cd $CURDIR
            fi
            # The Quest of The Lost Includes completed 
	    echo "Save-all for $CP successfully completed." | tee -a $LOG
	 else
	    echo "There were errors for $CP." | tee -a $LOG
	    echo "Check $LOG for more details."
	    cat /tmp/output* >> $LOG
            # Checking presence of SA_DIR and CP to prevent an rm -r "root dir"
            if [ $BACKUP = "TRUE" ] && [ -n "$SA_DIR" ] && [ -n "$CP" ]
            then
               echo "Restoring most recent save_all for $CP" | tee -a $LOG
               uncompress $BU_DIR/$NAME"_"$CP.tar.Z
               rm -r $SA_DIR/$CP >/dev/null 2>&1
               tar xf $BU_DIR/$NAME"_"$CP.tar
               rm $BU_DIR/$NAME"_"$CP.tar
               echo "Most recent save_all restored"
            fi
	 fi
      fi
done
echo "#####################################################" | tee -a $LOG
echo "# Automatic save-all procedure finished" | tee -a $LOG
echo "# Date:"`date` | tee -a $LOG
echo "#####################################################" | tee -a $LOG
# Cleanup after work is done (don't try this at home)
# Remove all the temp-files
####################################################################
rm $CURDIR/"$PF"* >/dev/null 2>&1 # Security issue!!!!???????
####################################################################
