#! /bin/sh
#
# @(#)updateLPSODB	1.8	LPS_UNX_COM	04/18/95
#
# Copyright 1995   Digital Equipment Corporation, Maynard, MA
#
# updateLPSODB
#
# Common script to update an LPS Object Database for a given class
# and object name.
#
# This script handles the generation of the required object header
# information for additions and replacements to the database.
#
# The user is asked if the existing database should first be preserved
# before updating.
#
# When the database has been successfully updated, write a copy into
# the $LPSROOT directory as "lpsodb.BAK" so as to serve as an emergency
# copy for the user.  If writing this copy fails, warn the user, but do
# not consider the overall operation to have failed; instead, display a
# message and return success.
#
# Parameters:
#    $1 - Path to the LPS Object Database file
#    $2 - Operation, one of {"add", "replace", "delete"}
#    $3 - Class identifier, one of {PC, MC, PS, ENV}
#    $4 - New object name if adding or replacing, should be null if deleting
#    $5 - Old object name if replacing or deleting, should be null for adding
#    $6 - Path of the object definition file, typically created by the
#	  mkodbdef script; this can be null if deleting an object
#    $7 - Path of the file used to store the pre-modified version of LPSODB,
#	  to be used by the caller to "roll back" the database in case of
#	  failure within this script.
#
# NOTE:	The $7 parameter (old LPSODB file copy) is zeroed *before* the
#	pre-modified LPSODB file is copied to it.  If the copying of the
#	pre-modified database fails, then the caller should first check to
#	see if the file referenced by $7 exists or has a zero length; if
#	the file does NOT EXIST or has a ZERO LENGTH, then that file
#	should obviously NOT BE USED to roll back the database.  In this
#	rare case, the caller should give up and notify the user in some
#	fashion.  No matter what, though, in this case, the current LPSODB
#	database has not been modified, so life should be as before the
#	update request, only that the user has just lost the new/modified
#	configuration information and will have to start all over again.
#	This should be very rare indeed...
#
# Global variables:
#    ENV_LPSROOT
#    ECHON
#    PRESERVE
#    TMPDIR
#
# Exit values:
#    0 - Success, the database was successfully updated.
#    1 - Failure of some sort; the state of the database is probably
#	 intact...

LPSODB=$1
OP=$2
CLASS=$3
NEWNAME=$4
OLDNAME=$5
ODBDEF=$6
OLDODB=$7

LPSODB_BACKUP="lpsodb.BAK"

DESC="`getobjdesc $CLASS`"
NEWODB=$TMPDIR/newodb.$$
NEWDEF=$TMPDIR/newdef.$$

: ${PRESERVE:=true}
: ${SILENT:=false}

Msg ()
{
    if $SILENT
    then
	:
    else
	echo "$*"
    fi

    return 0
}

# Display our intended actions to the user

Msg
case $OP in
       "add" ) Msg "Adding the definition for $DESC $NEWNAME in $LPSODB ..."
	       remdef=false
	       newdef=true
	       ;;
   "replace" ) Msg "Replacing the definition for $DESC $OLDNAME in $LPSODB ..."
	       remdef=true
	       newdef=true
	       ;;
    "delete" ) Msg "Deleting the definition for $DESC $OLDNAME in $LPSODB ..."
	       remdef=true
	       newdef=false
	       ;;
esac

# First clear the target old LPSODB copy file, then copy the current
# database file to that old file.  Then ensure that we can create a
# working copy of the new database file.

if cp /dev/null $OLDODB && cp $LPSODB $OLDODB
then
    Msg "    [Current database copied to $OLDODB]"

    rm -f $NEWODB
    if touch $NEWODB
    then
	Msg "    [Working copy of database created in $NEWODB]"
    else
	echo
	echo '    FAILURE to create a working copy of the database!!!'
	exit 1
    fi
else
    echo
    echo '    FAILURE to create a copy of the current database!!!'
    exit 1    
fi

# Set two important state variables that control the rest of this
# script.  We need to keep track of whether we are A-OK thus far,
# and whether the new version of the database (wherever it is) is
# actually usable, even if it does not reside as $LPSODB.

oksofar=true      # Controls subsequent activities
newcopyok=false   # Set true when the working database copy is usable

# If adding or replacing, generate the complete object definition now

if $oksofar && $newdef
then
    # Be CAREFUL editing the following definition for "ENTRY" !!!
    # The "\\" string must be part of the echo command, not the
    # shell variable (in order to get around a bug in Pyramid OSX,
    # see mkodbdef for more details on this bug).

    ENTRY="$NEWNAME|$DESC:\\
	:class=$CLASS:"

    if echo "${ENTRY}\\" > $NEWDEF  &&  cat $ODBDEF >> $NEWDEF
    then
	Msg "    [Formal definition created]"
    else
	oksofar=false
	echo
	echo '    FAILURE while trying to create the formal definition!'
    fi
fi

# If replacing or deleting, then rip out the old definition now;
# otherwise, if adding, then simply copy the current LPSODB file.

if $oksofar
then
    if $remdef
    then
	if sed -e '/^'$OLDNAME'|'"$DESC"'[:|]/,/[^\\]$/d' < $LPSODB > $NEWODB
	then
	    Msg "    [New copy of the database created]"
	    if [ $OP = delete ]
	    then
		newcopyok=true   # Can now use the new copy if necessary
	    fi
	else
	    oksofar=false
	    echo
	    echo '    FAILURE to extract the current object definition!!!'
	fi
    else
	if cp $LPSODB $NEWODB
	then
	    Msg "    [New copy of the database created]"
	else
	    oksofar=false
	    echo
	    echo '    FAILURE to copy the current database file!!!'
	fi
    fi
fi

# If adding or replacing, then append the definition file to the
# new database copy.

if $oksofar && $newdef
then
    if cat $NEWDEF >> $NEWODB
    then
	newcopyok=true   # Can now use the new copy if necessary
	rm -f $NEWDEF
	Msg "    [New object definition appended to database copy]"
    else
	oksofar=false
	echo
	echo '    FAILURE to append new definition to database copy file!!!'
    fi
fi

# The working database copy has been updated, so preserve the current
# database file (if the user desires), then write the database copy
# file over the real database file.

if $oksofar && $PRESERVE
then
    if savefile $LPSODB
    then
	Msg
    else
	oksofar=false
	echo
	echo '    FAILURE to preserve the current database file!!!'
    fi
fi

if $oksofar
then
    if cp $NEWODB $LPSODB
    then				# Success!
	chmod 644 $LPSODB		# Ensure the world can read it!
	rm -f     $NEWODB		# No longer need this copy
	Msg "    [New copy of database written over current copy]"
    else
	oksofar=false
	echo
	echo '    FAILURE to copy the new database file!!!'
    fi
fi

if $oksofar
then
    case $OP in
	   "add" ) NAME=$NEWNAME
		   ACTION="added to"
		   ;;
       "replace" ) NAME=$OLDNAME
		   ACTION="updated in"
		   ;;
	"delete" ) NAME=$OLDNAME
		   ACTION="removed from"
		   ;;
    esac

    Msg
    Msg "Definition of $DESC $NAME has been $ACTION $LPSODB"

    # Make a copy of the database in the $LPSROOT directory

    backup_ok=false

    if [ "$ENV_LPSROOT" ]	# We do have a definition, right??
    then
	LPSODB_BACKUP="$ENV_LPSROOT/$LPSODB_BACKUP"  # Prepend $LPSROOT path

	if cp $LPSODB $LPSODB_BACKUP
	then
	    backup_ok=true	# Successful backup copy has been made
	else
	    failmsg="file copy failed (see preceding error message)"
	fi
    else
	failmsg="ENV_LPSROOT variable not defined (script error!)"
    fi

    if $backup_ok
    then
	echo
	echo "[Emergency backup of $LPSODB created in $LPSODB_BACKUP]"
	echo
    else
	echo
	echo "  Warning: emergency backup of $LPSODB not performed."
	echo "  Reason:  $failmsg"
	echo
	echo "  Note that this prolem should not affect the operation of"
	echo "  the software in anyway."
	echo
	pause
    fi

    exit 0
fi

# If we get here, then we're in trouble...

if $newcopyok
then
    USENEWCOPY="
    A complete copy of the new, updated version of the database
    file may be found in:  $NEWODB

    This copy contains all the edits necessary to effect the changes
    for the $DESC $NAME as you have instructed.  Once this file has
    been copied to the $LPSODB file, all PrintServer Software components
    should operate properly."
else
    USENEWCOPY="
    Please try to correct this situation, then re-run this script."
fi

cat << END_OF_INPUT

    The current LPS Object Database file ($LPSODB) could not be
    properly and completely updated.  As a result, it is possible
    that one or more PrintServer Software components may not operate
    with complete integrity.
$USENEWCOPY

END_OF_INPUT

pause "Press RETURN to continue..."

exit 1
