cdesktopenv/cde/programs/dtcreate/dtcreate.sh

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