#! /bin/sh
#
# lpsmpc -- Top-level script for managing Print Client objects
#
# @(#)lpsmpc	1.17	LPS_UNX_COM	02/20/95
#
# Copyright 1995   Digital Equipment Corporation, Maynard, MA
#
# DESCRIPTION:
#
# This script is used to perform various management tasks for Print Client
# objects, such as adding, modifying, removing and listing currently
# defined client objects.
#
# This script MUST be executed from the "lpssetup" shell script to ensure
# proper privileges are available, key global variables are set, and the
# current working directory is properly established.
#
# The current working directory is expected to be LPSROOT directory.
#
# AUTHOR:   JK Martin, Underscore, Inc.
#
###

# Set all script-specific initial variables

ABORT="kill -1 $$"
ATTRLIST="Alist.PC"		# Expected to be in our working dir (LPSROOT)
BASEDEVICE="/dev/null"		# Used in generating Print Client device names
RESPONSE=""
SCRIPTNAME="lpsmpc"
TITLE="Manage Print Clients"
VARLIST="Vlist.PC.$PCTYPE"	# Expected to be in our working dir (LPSROOT)

OLDLPSODB="$TMPDIR/oldodb.$$"
OUTFILE="$TMPDIR/${SCRIPTNAME}.$$"

INTROTEXT="
$TITLE   (lpsmpc)

This script performs various management tasks for Print Clients,
allowing you to list all currently defined Clients, add new Clients,
modify existing Clients, remove existing Clients, or control Clients."

#----------------------------------------------------------------------

# Perform the standard top-level management script initialization

. scripts/lpsmxxinit

#----------------------------------------------------------------------

# testpage()
#
# This function is used to print a test page to the specified Print Client
# object according to whether the PC is new or updated.
#
# Return value is 0 if successful, 1 otherwise.

testpage ()
{
    pcname=$1
    operation=$2	# Either "add" or "mod"

    case $2 in
	add ) type=new     ; operation=created ;;
	mod ) type=updated ; operation=updated ;;
	  * ) echo
	      echo "    testpage: unrecognized 2nd parameter: \"$2\""
	      echo
	      type='???'
	      ;;
    esac

    if yesno y "Print a test page to the $type Print Client $pcname"
    then
	:
    else
	return 0	# The user declined
    fi

    # Construct a test page file that shows the PC object configuration

    tpfile=$TMPDIR/tpage.$$

    cat > $tpfile << EOF


                               Test Print Page 

PrintServer Print Client "$pcname" was $operation on host "$LOCALHOST"
on `date`.

EOF
    showobjvars PC $pcname $VARLIST >> $tpfile

    case $PCTYPE in
	AIX ) cmd="lp  -d$pcname -t 'TestPage' $tpfile" ;;
	BSD ) cmd="lpr -P$pcname -J 'TestPage' $tpfile" ;;
	SV3 ) cmd="lp  -d$pcname -t 'TestPage' $tpfile" ;;
	  * ) echo
	      echo "    testpage: unrecognized PCTYPE value: \"$PCTYPE\""
	      echo
	      pause
	      return 1
	      ;;
    esac

    if $cmd
    then
	echo
	echo "Test page job submitted successfully to print queue \"$pcname\""
    else
	cat << EOF

    Submitting the test page job failed for reasons shown above.

    The command used to submit the job was:

	$cmd

    There is no reason to believe the definition of either the Print Client
    or associated print queue is incorrect.  Perhaps the printing system
    has a problem?
EOF
    fi

    return 0
}

#----------------------------------------------------------------------

# addpc()
#
# This function is used to add a new Print Client object.  No arguments
# are expected.
#
# Return value is 0 if successful, 1 otherwise.

addpc ()
{
    clear
    echo
    echo "Add a new Print Client..."

    # Clear all existing PC_* variables

    clearobjvars PC

    # Begin the initialization of this new Client object by getting and
    # validating the object name, and getting the associated printer
    # object name.
    #
    # Note that the object name also serves as the "official" print queue name

    PC_OBJNAME=""

    while true   # Loop until we break
    do
	echo
	$ECHON "What is the name of the new Print Client? "
	read PC_OBJNAME

	if [ -z "$PC_OBJNAME" ]
	then
	    return 0	# NULL response implies go back to the menu
	fi

	# Check the name to ensure it consists of valid characters, and
	# that a local print queue by that name doesn't already exist,
	# and that another PC object by that name doesn't already exist.

	if ckname.$PCTYPE "$PC_OBJNAME"
	then
	    if objectexists PC $PC_OBJNAME
	    then
		echo
		echo "    A Print Client by that name already exists."
		echo "    Please choose another name, or press RETURN to go"
		echo "    back to the \"$TITLE\" menu."
	    else
		break   # Success, name is OK and no PC object exists
	    fi
	fi
    done

    # Initialize all other object variables with "reasonable" values,
    # most often coming from the ENV object.  Note that all "common"
    # variables are initialized, even if they are not necessarily used
    # within a specific $PCTYPE environment.

    PC_ACCTFILE="$ENV_LPSACCT/${PC_OBJNAME}.acct"   # Derived on PC_OBJNAME
    PC_ACCTUNIT="$ENV_ACCTUNIT"
    PC_ASC2PSPRO="$ENV_ASC2PSPRO"
    PC_BANNERFILE="$ENV_BANNERFILE"
    PC_BANNERTRAY="$ENV_BANNERTRAY"
    PC_CONNTIMEOUT="$ENV_CONNTIMEOUT"
    PC_DEBUGLEVEL="$ENV_DEBUGLEVEL"
    PC_DESCRIPTION="`getobjdesc PC`"
    PC_DEVICE="${BASEDEVICE}"
    PC_ENABLEACCT="$ENV_ENABLEACCT"
    PC_ENABLEANSI="$ENV_ENABLEANSI"
    PC_ENABLEBANNERS="$ENV_ENABLEBANNERS"
    PC_ENABLEIMAGES="$ENV_ENABLEIMAGES"
    PC_ENABLELOG="$ENV_ENABLELOG"
    PC_ERRORFILE="$ENV_ERRORFILE"
    PC_IMAGESUFFIX="$ENV_IMAGESUFFIX"
    PC_IOBUFSIZE="$ENV_IOBUFSIZE"
    PC_LASTUPDATED=""
    PC_LOGFILE="$ENV_LPSLOG/${PC_OBJNAME}.log"   # Derived on PC_OBJNAME
    PC_LOGLEVEL="$ENV_LOGLEVEL"
    PC_LPSIMAGES="$ENV_LPSIMAGES"
    PC_MAILADMADDRS="$ENV_MAILADMADDRS"
    PC_NOTIFYSTYLE="$ENV_NOTIFYSTYLE"
    PC_OFFSETSTACK="$ENV_OFFSETSTACK"
    PC_PAGELENGTH="$ENV_PAGELENGTH"
    PC_PAGEWIDTH="$ENV_PAGEWIDTH"
    PC_PCSUPERNAME="$ENV_PCSUPERNAME"
    PC_PSNAME=""
    PC_SPOOLDIR="$ENV_TOPQDIR/$PC_OBJNAME"       # Derived on PC_OBJNAME

    # Do any special $PCTYPE-related processing here that deviates
    # from the standard initialiation above.

    case "$PCTYPE" in
	"AIX" | "BSD" ) PC_DEVICE="${BASEDEVICE}-${PC_OBJNAME}" ;;
    esac

    # Export the complete set of new PC variables and the existing imported
    # ENV variables for general subprocess use.

    expobjvars PC
    expobjvars ENV

    # Ask the user if configuration should be done "step-by-step" or via
    # a variable menu mechanism, then do perform that request.

    if setPCvars "add" $PC_OBJNAME $VARLIST $ATTRLIST $OUTFILE
    then
	if . $OUTFILE
	then
	    :	# The complete set of PC_* variables are now imported
	else
	    echo
	    echo "FAILURE to import variables from file \"$OUTFILE\"!"
	    return 1
	fi
    else
	echo
	echo "FAILURE to set all Print Client variables!"
	return 1
    fi

    # Add this new Print Client to the LPS Object Database, then perform
    # the $PCTYPE-dependent tasks necessary to install and activate the
    # associated print queue.

    ODBDEF="$TMPDIR/odbdef.$$"

    if mkodbdef PC $ATTRLIST $ODBDEF
    then
	if updateLPSODB $LPSODB add PC $PC_OBJNAME "" $ODBDEF $OLDLPSODB
	then
	    rm -f $ODBDEF   # No longer need this file

	    if mkq.$PCTYPE $PC_OBJNAME
	    then
		$PAGER << END_OF_INPUT

The Print Client "$PC_OBJNAME" should now be ready for use with the
local print queue called "$PC_OBJNAME" on $LOCALHOST.  Here is the
current status of the queue:

`listq.$PCTYPE $PC_OBJNAME`

END_OF_INPUT
		rm -f $OLDLPSODB $OUTFILE

		# Print a test page, if the user desires

		testpage $PC_OBJNAME add

		return 0
	    fi
	fi
    fi

    # To get here means that something went wrong in either the modification
    # of the LPSODB file, or in the creation of the associated print queue.

    cat << END_OF_INPUT

    Sorry, but the creation of the new Print Client failed for the
    reasons listed above.  See what you can do to fix the problem,
    then try to recreate the Print Client.
END_OF_INPUT

    return 1
}

#----------------------------------------------------------------------

# modpc()
#
# This function is used to modify an existing Print Client object.
# No arguments are expected.
#
# Return value is 0 if successful, 1 otherwise.

modpc ()
{
    clear
    echo
    echo "Modify an existing Print Client..."

    # Clear all existing PC_* variables

    clearobjvars PC

    # Select the PC object to modify, and confirm modification

    if selectobject PC "Which Print Client is to be modified" $OUTFILE ""
    then
	PC_OBJNAME="`cat $OUTFILE`"
    else
	return 0
    fi

    # Extract the current attributes of the client, and save all those
    # values in corresponding "OLDPC_xxx" variables for potential later
    # referencing.

    getobject true PC $PC_OBJNAME

    mkoldobjvars PC

    # Get the (potentially) new name of the client

    while true   # Loop until we break
    do
	echo
	$ECHON "What is the name of the Print Client [${OLDPC_OBJNAME}]? "
	read PC_OBJNAME
	if [ -z "$PC_OBJNAME" -o "$PC_OBJNAME" = "$OLDPC_OBJNAME" ]
	then
	    PC_OBJNAME=$OLDPC_OBJNAME
	    break
	fi

	# Check the name to ensure it consists of valid characters, and
	# that a local print queue by that name doesn't already exist,
	# and that another PC object by that name doesn't already exist.

	if ckname.$PCTYPE "$PC_OBJNAME"
	then
	    if objectexists PC $PC_OBJNAME
	    then
		echo
		echo "    A Print Client by that name already exists."
		echo "    Please choose another name, or press RETURN to go"
		echo "    back to the \"$TITLE\" menu."
	    else
		# We now have a new name for this Print Client, so perform
		# Do any required special $PCTYPE-related processing here.

		case "$PCTYPE" in
		    "AIX" | "BSD" ) PC_DEVICE="${BASEDEVICE}-${PC_OBJNAME}" ;;
		esac

		break   # Success, name is OK and no PC object exists
	    fi
	fi
    done

    # Export the complete set of new PC variables for general subprocess use

    expobjvars PC

    # Ask the user if modification should be done "step-by-step" or via
    # a variable menu mechanism, then do perform that request.

    if setPCvars "mod" $PC_OBJNAME $VARLIST $ATTRLIST $OUTFILE
    then
	if . $OUTFILE
	then
	    :	# The complete set of PC_* variables are now imported
	else
	    echo
	    echo "FAILURE to import variables from file \"$OUTFILE\"!"
	    return 1
	fi
    else
	echo
	echo "FAILURE to set all Print Client variables!"
	return 1
    fi

    # Shutdown the associated print queue, then update the LPS Object
    # Database, then change the print queue configuration and restart
    # the queue.

    ODBDEF="$TMPDIR/odbdef.$$"

    while true
    do
	echo
	echo "Shutting down the \"$OLDPC_OBJNAME\" print queue..."

	if downq.$PCTYPE $OLDPC_OBJNAME true "Modifying the print queue definition."
	then
	    break   # Exit the while() loop
	else
	    cat << END_OF_INPUT

    If you do not deactivate the queue now, you will lose all of the
    changes you have made to Print Client "$PC_OBJNAME" thus far.
    If you do not want to continue with this procedure, press the
    CTRL/C key when next prompted to deactivate the print queue.

END_OF_INPUT
	    pause
	fi
    done

	if mkodbdef PC $ATTRLIST $ODBDEF
	then
	    if updateLPSODB $LPSODB replace PC $PC_OBJNAME "$OLDPC_OBJNAME" \
			    $ODBDEF $OLDLPSODB
	    then
		rm -f $ODBDEF   # No longer need this file

		if chq.$PCTYPE $OLDPC_OBJNAME $OLDPC_DEVICE $PC_OBJNAME
		then
		    $PAGER << END_OF_INPUT

The Print Client "$PC_OBJNAME" should now be ready for use with the
local print queue called "$PC_OBJNAME" on $LOCALHOST.  Here is the
current status of the queue:

`listq.$PCTYPE $PC_OBJNAME`

END_OF_INPUT
		    rm -f $OLDLPSODB $OUTFILE

		    # Print a test page, if the user desires

		    testpage $PC_OBJNAME mod

		    return 0
		fi
	    fi
	fi

    # To get here means that something went wrong in either the modification
    # of the LPSODB file, or in the modification of the associated print
    # queue.

    cat << END_OF_INPUT

    Sorry, but the modification of the Print Client failed for the
    reasons listed above.  See what you can do to fix the problem,
    then try modifying the Print Client again.
END_OF_INPUT

    return 1
}

#----------------------------------------------------------------------

# delpc()
#
# This function is used to remove an existing Print Client (PC) object.
# No arguments are expected.
#
# Return value is 0 if successful, 1 otherwise.

delpc ()
{
    clear
    echo
    echo "Remove an existing Print Client..."

    # Clear all existing PC_* variables

    clearobjvars PC

    # Get the name of the Client to remove, then force the user to
    # confirm the removal.  When confirmed, extract the attributes
    # of the Client from the LPS Object Database, and export all
    # associated variables.

    if selectobject PC "Which Print Client is to be removed" $OUTFILE ""
    then
	PC_OBJNAME="`cat $OUTFILE`"

	if yesno x "Are you sure you want to remove \"$PC_OBJNAME\""
	then
	    getobject true PC $PC_OBJNAME
	    expobjvars PC
	else
	    return 0
	fi
    else
	return 0
    fi

    # Remove the associated print queue, then update the LPS Object
    # Database.  Note well that we ignore the exit value from rmq.$PCTYPE,
    # leaving those kinds of cleanup problems to the local administrator.

    rmq.$PCTYPE $PC_OBJNAME

    if updateLPSODB $LPSODB delete PC "" "$PC_OBJNAME" "" $OLDLPSODB
    then
	rm -f $OLDLPSODB
    else
	return 1	# Error updating the LPSODB!
    fi

    return 0
}

#----------------------------------------------------------------------

# ctrlpc()
#
# This function is used to start/restart/stop a Print Client object.
# One argument: "start" or "restart" or "stop".
#
# Return value is 0 if successful, 1 otherwise.

ctrlpc ()
{
    ctrl=$1

    case $ctrl in
	start ) Control="Start"
		Controlled="Started"
		cmd='upq.$PCTYPE $PC_OBJNAME'
		;;
      restart ) Control="Restart"
		Controlled="Restarted"
		reason="Restarting the print queue."
   cmd='downq.$PCTYPE $PC_OBJNAME true "$reason" && upq.$PCTYPE $PC_OBJNAME'
		;;
	 stop ) Control="Stop"
		Controlled="Stopped"
		cmd='downq.$PCTYPE $PC_OBJNAME true ""'
		;;
    esac


    clear
    echo
    echo "$Control an existing Print Client..."

    # Get the name of the Client to control, then perform the
    # controlling action.

    if selectobject PC "Which Print Client is to be $Controlled" $OUTFILE ""
    then
	PC_OBJNAME="`cat $OUTFILE`"

	echo

	if eval $cmd
	then
	    :
	else
	    return 1
	fi
    fi

    return 0
}

#----------------------------------------------------------------------

# This is the top-level execution path for this script.  Here we simply
# sit in an infinite loop, requesting a menu number and performing the
# requested procedure.

objdesc=`getobjdesc PC`

while true
do
    echo "
    1) LIST    the names of all defined ${objdesc}s
    2) SHOW    the configuration of a defined $objdesc
    3) EXAMINE the log file of a ${objdesc}

    4) ADD     a new $objdesc definition
    5) MODIFY  an existing $objdesc definition
    6) REMOVE  an existing $objdesc definition

    7) START   an existing $objdesc
    8) RESTART a running $objdesc
    9) STOP    a running $objdesc

   10) Return to Main Menu
"
    while true
    do
	$ECHON "Enter one of the above menu numbers [10]: "
	read item
	if checknumrange 1 10 10 "$item"
	then
	    break 1
	fi
    done

    case $item in
	1) listobjects PC          ;;
	2) showobject  PC $VARLIST ;;
        3) showlogfile PC          ;;

	4) addpc                   ;;
	5) modpc                   ;;
	6) delpc                   ;;

	7) ctrlpc start            ;;
	8) ctrlpc restart          ;;
	9) ctrlpc stop             ;;

	*) break                   ;;
    esac

    echo
    pause "Press RETURN to return to the $TITLE Menu... "
    clear
    echo
    echo $TITLE Menu
done

rm -f $TMPDIR/*.$$
rm -f /tmp/*.$$
rm -f ./*.$$

exit 0

#
# Local Variables:
# page-delimiter:"^#---"
# fill-column:75
# End:
