440 lines
15 KiB
Bash
440 lines
15 KiB
Bash
#!/bin/ksh
|
|
|
|
#######################################################################
|
|
#
|
|
# dtcreate
|
|
#
|
|
# The shell-script which implements dtcreate (a.k.a. CreateAction).
|
|
#
|
|
# Hewlett-Packard Visual User Environment
|
|
#
|
|
# Copyright (c) 1990 Hewlett-Packard Company
|
|
#
|
|
# @(#) $XConsortium: dtcreate.sh /main/3 1995/11/01 16:13:20 rswiston $
|
|
#
|
|
######################################################################
|
|
|
|
#####################################################################
|
|
#
|
|
# determine_system - determines the system name and then sets
|
|
# the global variables _SIGUSR1 and _SIGUSR2 accordingly.
|
|
#
|
|
determine_system ()
|
|
{
|
|
sys_name=`uname`
|
|
|
|
case ${sys_name} in
|
|
HP-UX)
|
|
_SIGUSR1=16
|
|
_SIGUSR2=17
|
|
;;
|
|
AIX)
|
|
_SIGUSR1=30
|
|
_SIGUSR2=31
|
|
;;
|
|
*)
|
|
_SIGUSR1=16
|
|
_SIGUSR2=17
|
|
;;
|
|
esac
|
|
}
|
|
|
|
#####################################################################
|
|
#
|
|
# getvalue accepts two arguments, the name of the resource whose
|
|
# value is desired and the name of the file where it is contained.
|
|
# The value of the resource is returned in $VALUE.
|
|
#
|
|
getvalue ()
|
|
{
|
|
VALUE=`grep $1 $2 | sed -e "s/[^:]*: *//"`
|
|
}
|
|
|
|
enabledialog ()
|
|
{
|
|
# Sending SIGUSR1 to the dtdialog process tells it to reenable
|
|
# the dialog.
|
|
kill -${_SIGUSR1} $1
|
|
}
|
|
|
|
toggleinvaliddialog ()
|
|
{
|
|
# Sending SIGIUSR2 to the dtdialog process tells it to either
|
|
# go to the invalid state (put up the invalid cursor) or go
|
|
# back to its previous state (either active or busy).
|
|
kill -${_SIGUSR2} $1
|
|
}
|
|
|
|
dismissdialog ()
|
|
{
|
|
# Sending SIGINT to the dtdialog process tells it to remove the
|
|
# dialog and die.
|
|
kill -2 $1
|
|
}
|
|
|
|
##############################################################
|
|
#
|
|
# checkprocess accepts a single argument with is a process-id.
|
|
# If the specified process is running (as reported by ps -ef),
|
|
# checkprocess returns 1. If it isn't running, checkprocess
|
|
# returns 0.
|
|
#
|
|
checkprocess ()
|
|
{
|
|
RUNNING=`ps -ef | cut -c 9-14 | grep -c $1`
|
|
|
|
if [ "$RUNNING" = "0" ] ; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# This is the main callback that is called whenever the user presses
|
|
# one of the buttons on the CreateAction dialog.
|
|
actioncallback ()
|
|
{
|
|
# Check which button on the dialog was invoked. The Help button
|
|
# is automatically handled by dtdialog, so it is only the apply
|
|
# and close buttons that we care about.
|
|
getvalue selectedButton $DIALOG_OUTPUT
|
|
|
|
if [ "$VALUE" = "apply" ] ; then
|
|
checkactionvalues
|
|
else
|
|
cleanupandexit
|
|
fi
|
|
}
|
|
|
|
checkactionvalues ()
|
|
{
|
|
# Read all the values in from the dialog.
|
|
getvalue windowId $DIALOG_OUTPUT
|
|
CREATEACTION_WID=$VALUE
|
|
|
|
getvalue name.text $DIALOG_OUTPUT
|
|
ACTION=$VALUE
|
|
|
|
getvalue largeIcon.text $DIALOG_OUTPUT
|
|
LICON=$VALUE
|
|
|
|
getvalue smallIcon.text $DIALOG_OUTPUT
|
|
SICON=$VALUE
|
|
|
|
getvalue description.text $DIALOG_OUTPUT
|
|
DESCRIPTION=`echo $VALUE | tr -s "\012" " "`
|
|
|
|
getvalue commandLine.text $DIALOG_OUTPUT
|
|
EXECSTRING=$VALUE
|
|
|
|
getvalue prompt.text $DIALOG_OUTPUT
|
|
PROMPT=$VALUE
|
|
|
|
getvalue commandType.active $DIALOG_OUTPUT
|
|
if [ "$VALUE" = "xWin" -o "$VALUE" = "noOut" ] ; then
|
|
WINDOWTYPE="NO_STDIO"
|
|
elif [ "$VALUE" = "term" ] ; then
|
|
WINDOWTYPE="PERM_TERMINAL"
|
|
else
|
|
WINDOWTYPE="TERMINAL"
|
|
fi
|
|
|
|
BAIL_OUT=""
|
|
# Make sure that an action name and an exec-string were provided.
|
|
if [ ! "$BAIL_OUT" -a ! "$ACTION" -a ! "$EXECSTRING" ] ; then
|
|
dtdialog -descFile dtcreate.ddf -dialogName noNameOrExec \
|
|
-transientFor $CREATEACTION_WID &
|
|
SECONDARY_DIALOG_PIDS[${NUM_SECONDARY_DIALOGS}]=$!
|
|
let NUM_SECONDARY_DIALOGS=${NUM_SECONDARY_DIALOGS}+1
|
|
enabledialog $CREATEACTION_PID
|
|
BAIL_OUT="yes"
|
|
fi
|
|
|
|
if [ ! "$BAIL_OUT" -a ! "$ACTION" ] ; then
|
|
dtdialog -descFile dtcreate.ddf -dialogName noName \
|
|
-transientFor $CREATEACTION_WID &
|
|
SECONDARY_DIALOG_PIDS[${NUM_SECONDARY_DIALOGS}]=$!
|
|
let NUM_SECONDARY_DIALOGS=${NUM_SECONDARY_DIALOGS}+1
|
|
enabledialog $CREATEACTION_PID
|
|
BAIL_OUT="yes"
|
|
fi
|
|
|
|
if [ ! "$BAIL_OUT" -a ! "$EXECSTRING" ] ; then
|
|
dtdialog -descFile dtcreate.ddf -dialogName noExecString \
|
|
-transientFor $CREATEACTION_WID &
|
|
SECONDARY_DIALOG_PIDS[${NUM_SECONDARY_DIALOGS}]=$!
|
|
let NUM_SECONDARY_DIALOGS=${NUM_SECONDARY_DIALOGS}+1
|
|
enabledialog $CREATEACTION_PID
|
|
BAIL_OUT="yes"
|
|
fi
|
|
|
|
# Make sure the action name does not contain any blanks.
|
|
if [ ! "$BAIL_OUT" -a `echo $ACTION | grep -c ' '` -eq 1 ] ; then
|
|
dtdialog -descFile dtcreate.ddf -dialogName foundBlank \
|
|
-transientFor $CREATEACTION_WID &
|
|
SECONDARY_DIALOG_PIDS[${NUM_SECONDARY_DIALOGS}]=$!
|
|
let NUM_SECONDARY_DIALOGS=${NUM_SECONDARY_DIALOGS}+1
|
|
enabledialog $CREATEACTION_PID
|
|
BAIL_OUT="yes"
|
|
fi
|
|
|
|
if [ ! "$BAIL_OUT" ] ; then
|
|
# Check the vf file we want to write to. If it exists and
|
|
# isn't writable, complain.
|
|
VF_DIR=$HOME/.dt/types
|
|
# Hack warning! Do temporary dt stuff.
|
|
if [[ $doDT = 1 ]] then
|
|
VF_FILE=$VF_DIR/$ACTION.dt
|
|
else
|
|
VF_FILE=$VF_DIR/$ACTION.vf
|
|
fi
|
|
if [ -f $VF_FILE -a ! -w $VF_FILE ] ; then
|
|
dtdialog -descFile dtcreate.ddf \
|
|
-dialogName notWritable \
|
|
-transientFor $CREATEACTION_WID \
|
|
$VF_FILE &
|
|
SECONDARY_DIALOG_PIDS[${NUM_SECONDARY_DIALOGS}]=$!
|
|
let NUM_SECONDARY_DIALOGS=${NUM_SECONDARY_DIALOGS}+1
|
|
enabledialog $CREATEACTION_PID
|
|
BAIL_OUT="yes"
|
|
fi
|
|
fi
|
|
|
|
# Check if the action name is longer than 11 characters.
|
|
# If so, warn about the problems with short filename
|
|
# systems and give the user a chance to change it. This is a
|
|
# modal dialog (not run in background) because the user has to
|
|
# make a choice.
|
|
if [ ! "$BAIL_OUT" -a `echo $ACTION | wc -c` -gt 11 ] ; then
|
|
toggleinvaliddialog $CREATEACTION_PID
|
|
dtdialog -descFile dtcreate.ddf \
|
|
-dialogName longName \
|
|
-transientFor $CREATEACTION_WID $ACTION
|
|
|
|
if [ $? -eq 2 ] ; then
|
|
enabledialog $CREATEACTION_PID
|
|
BAIL_OUT="yes"
|
|
else
|
|
toggleinvaliddialog $CREATEACTION_PID
|
|
fi
|
|
fi
|
|
|
|
# Check that if the exec-string uses any shell features (e.g. pipes),
|
|
# that a shell is explicitly specified.
|
|
if [ ! "$BAIL_OUT" -a `echo $EXECSTRING | grep -c '[|&;<>]'` -eq 1 -a\
|
|
! `echo $EXECSTRING | grep -c 'sh '` -eq 1 ] ; \
|
|
then
|
|
dtdialog -descFile dtcreate.ddf -dialogName needShell \
|
|
-transientFor $CREATEACTION_WID &
|
|
SECONDARY_DIALOG_PIDS[${NUM_SECONDARY_DIALOGS}]=$!
|
|
let NUM_SECONDARY_DIALOGS=${NUM_SECONDARY_DIALOGS}+1
|
|
enabledialog $CREATEACTION_PID
|
|
BAIL_OUT="yes"
|
|
fi
|
|
|
|
# Check that the prompt string does not contain quotes. I
|
|
# think there is a bug here that a single backquote (`) is not
|
|
# detected. I need to figure out the correct grep expression
|
|
# to catch it.
|
|
QUOTES=`echo \'$PROMPT\' | tr '!$%&(-\\\/"' '%%%%%%%%%' | fgrep -c %`
|
|
if [ ! "$BAIL_OUT" -a $QUOTES -eq 1 ] ; then
|
|
dtdialog -descFile dtcreate.ddf \
|
|
-transientFor $CREATEACTION_WID \
|
|
-dialogName promptQuote &
|
|
SECONDARY_DIALOG_PIDS[${NUM_SECONDARY_DIALOGS}]=$!
|
|
let NUM_SECONDARY_DIALOGS=${NUM_SECONDARY_DIALOGS}+1
|
|
enabledialog $CREATEACTION_PID
|
|
BAIL_OUT="yes"
|
|
fi
|
|
|
|
# Check that if a prompt is supplied, that the action calls for
|
|
# arguments.
|
|
if [ ! "$BAIL_OUT" ] ; then
|
|
if [ "$PROMPT" -a \
|
|
`echo $EXECSTRING | grep -c "\$[*0-9]"` -eq 0 ] ; then
|
|
dtdialog -descFile dtcreate.ddf \
|
|
-transientFor $CREATEACTION_WID \
|
|
-dialogName unusedPrompt &
|
|
SECONDARY_DIALOG_PIDS[${NUM_SECONDARY_DIALOGS}]=$!
|
|
let NUM_SECONDARY_DIALOGS=${NUM_SECONDARY_DIALOGS}+1
|
|
enabledialog $CREATEACTION_PID
|
|
BAIL_OUT="yes"
|
|
fi
|
|
fi
|
|
|
|
# If no errors were caught, create the action and reenable the
|
|
# dialog.
|
|
if [ ! "$BAIL_OUT" ] ; then
|
|
createaction
|
|
enabledialog $CREATEACTION_PID
|
|
fi
|
|
}
|
|
|
|
createaction ()
|
|
{
|
|
# If the vf file already exists, we are going to copy it to a temp
|
|
# file and comment out the definition for the current action.
|
|
# Make sure that this temp file doesn't already exist so that an old
|
|
# one doesn't get used by mistake.
|
|
OLD_FILE=/tmp/`basename $0`2_$$
|
|
rm -f ${OLD_FILE}
|
|
if [ -w $VF_FILE ] ; then
|
|
sed -e "/^ACTION ${ACTION}[ ]*$/,/^[END|}]/s/^/\# /" \
|
|
${VF_FILE} > ${OLD_FILE}
|
|
fi
|
|
|
|
# Write out the new action definition.
|
|
echo "\n#\n# Action created by dtcreate\n#" > $VF_FILE
|
|
echo "ACTION $ACTION" > $VF_FILE
|
|
echo "{" >> $VF_FILE
|
|
|
|
if [ "${LICON}" ] ; then
|
|
echo "\tLARGE_ICON\t\t$LICON" >> $VF_FILE
|
|
fi
|
|
|
|
if [ "${SICON}" ] ; then
|
|
echo "\tSMALL_ICON\t\t$SICON" >> $VF_FILE
|
|
fi
|
|
|
|
if [ "${DESCRIPTION}" ] ; then
|
|
echo "\tDESCRIPTION\t$DESCRIPTION" >> $VF_FILE
|
|
fi
|
|
|
|
echo "\tTYPE\t\tCOMMAND" >>$VF_FILE
|
|
|
|
if [ "${EXECSTRING}" ] ; then
|
|
# Process the exec-string and look for $*, $1, $2, etc.
|
|
# These must be translated into DT's syntax of
|
|
# %(File)Arg_n%. Also insert the prompt string if one
|
|
# was supplied.
|
|
echo "\tEXEC_STRING\t\c" >>$VF_FILE
|
|
if [ "$PROMPT" ] ; then
|
|
echo $EXECSTRING | sed \
|
|
-e "s/\$\*/%(File)Arg_1\"$PROMPT\"% %(File)Args%/" \
|
|
-e "s/\$\([1-9]\)/%(File)Arg_\1\"$PROMPT\"%/" \
|
|
-e "s/\$\([1-9]\)/%(File)Arg_\1%/g" \
|
|
>> $VF_FILE
|
|
else
|
|
echo $EXECSTRING | sed \
|
|
-e "s/\$\*/%(File)Args%/g" \
|
|
-e "s/\$\([1-9]\)/%(File)Arg_\1%/g" >> $VF_FILE
|
|
fi
|
|
fi
|
|
|
|
if [ "${WINDOWTYPE}" ] ; then
|
|
echo "\tWINDOW_TYPE\t$WINDOWTYPE" >> $VF_FILE
|
|
fi
|
|
|
|
echo "}" >>$VF_FILE
|
|
|
|
# If the temp file with the old contents of the vf file exists,
|
|
# stick it on the end of the file we just created.
|
|
if [ -r ${OLD_FILE} ] ; then
|
|
echo "\n#\n# Commented out by dtcreate\n#" >> $VF_FILE
|
|
cat ${OLD_FILE} >> ${VF_FILE}
|
|
rm ${OLD_FILE}
|
|
fi
|
|
|
|
#
|
|
# Invoke ReloadActions so that the new action
|
|
# will be read.
|
|
dtaction -timeout 1 ReloadActions
|
|
|
|
#
|
|
# Create the action copy file in the home directory.
|
|
if [ -w ${TOOLBOX} -a ! -f ${TOOLBOX}/${ACTION} ] ; then
|
|
touch ${TOOLBOX}/${ACTION}
|
|
chmod 755 ${TOOLBOX}/${ACTION}
|
|
fi
|
|
|
|
# Check whether the action exists in the Home directory. (Either we
|
|
# just created it or it may have already existed.)
|
|
if [ -x ${TOOLBOX}/${ACTION} ] ; then
|
|
dtdialog -descFile dtcreate.ddf -dialogName actionExists \
|
|
-transientFor $CREATEACTION_WID \
|
|
$ACTION $VF_FILE &
|
|
SECONDARY_DIALOG_PIDS[${NUM_SECONDARY_DIALOGS}]=$!
|
|
let NUM_SECONDARY_DIALOGS=${NUM_SECONDARY_DIALOGS}+1
|
|
else
|
|
dtdialog -descFile dtcreate.ddf \
|
|
-dialogName actionDoesntExist \
|
|
-transientFor $CREATEACTION_WID \
|
|
$ACTION $VF_FILE &
|
|
SECONDARY_DIALOG_PIDS[${NUM_SECONDARY_DIALOGS}]=$!
|
|
let NUM_SECONDARY_DIALOGS=${NUM_SECONDARY_DIALOGS}+1
|
|
fi
|
|
}
|
|
|
|
cleanupandexit()
|
|
{
|
|
# Dismiss any secondary dialogs (e.g. Help, warnings, errors)
|
|
# that have been created.
|
|
if [ NUM_SECONDARY_DIALOGS -gt 0 ]; then
|
|
for PID in ${SECONDARY_DIALOG_PIDS[*]}
|
|
do
|
|
checkprocess $PID
|
|
if [ $? -eq 1 ] ; then
|
|
dismissdialog $PID
|
|
fi
|
|
done
|
|
fi
|
|
|
|
dismissdialog $CREATEACTION_PID
|
|
|
|
rm -f ${DIALOG_OUTPUT}
|
|
}
|
|
|
|
|
|
#####################################################################
|
|
# Main
|
|
#
|
|
#set -xv
|
|
DIALOG_OUTPUT=/tmp/`basename $0`$$
|
|
#TOOLBOX=$HOME/.dt/types/tools
|
|
TOOLBOX=$HOME
|
|
NUM_SECONDARY_DIALOGS=0
|
|
|
|
determine_system
|
|
|
|
# Hack warning: This is to determine if should create .dt file or .vf file.
|
|
if [[ -f /opt/dt/types/useFT ]] then
|
|
doDT=0
|
|
else
|
|
doDT=1
|
|
fi
|
|
|
|
# Set up the callback function that is invoked when the user
|
|
# presses any of the dialog buttons.
|
|
trap "actioncallback" ${_SIGUSR1}
|
|
|
|
# Invoke dtdialog and pass in the process-ID of this script.
|
|
# When the user presses any of the dialog buttons, dtdialog
|
|
# will send us a signal which will cause the callback function
|
|
# to be called.
|
|
PARENT_PID=$$
|
|
dtdialog -descFile dtcreate.ddf -dialogName createAction -returnWinId \
|
|
-signal SIGUSR1 -ppid $PARENT_PID -outFile $DIALOG_OUTPUT &
|
|
|
|
# Keep track of the process-ID of the dtdialog process that is
|
|
# managing the main CreateAction dialog. We need this process-ID so
|
|
# that we can send it signals to do things such as reenable it.
|
|
CREATEACTION_PID=$!
|
|
|
|
# Sit in a loop as long as the main CreateAction dialog is up. The
|
|
# signals cause the 'wait' call to exit and I don't know of any way to
|
|
# determine whether the wait existed due to a signal or because the
|
|
# process died. Therefore we have to explicitly check if the process
|
|
# is alive.
|
|
EXIT=0
|
|
while [ $EXIT -eq 0 ] ; do
|
|
wait $CREATEACTION_PID
|
|
checkprocess $CREATEACTION_PID
|
|
if [ $? -eq 0 ] ; then
|
|
EXIT=1
|
|
fi
|
|
done
|
|
|
|
exit 0
|
|
|
|
|