#!/bin/sh
#      ******************************************************************
#      *                                                                *
#      *  Start up Terminals in a Reasonable Way, Only works under ksh  *
#      *                                                                *
#      ******************************************************************
# File: utils/misc/sigterm
#
#         COPYRIGHT (c) 1994, 1999, 2000, 2003, 2008, 2009 BY
#             VAISALA INC., WESTFORD MASSACHUSETTS, U.S.A.
# 
# THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
# ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
# INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
# COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
# OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
# TRANSFERED.

# Choose default style of terminal, and the directory in which the
# executable file can be found.
#

STYLE="xterm"
REMSH="rsh"
EXEDIR="/usr/bin"

EXPSTYLE=""  # No string to export if default is taken

# Remove extensions from the possibly fully qualified node name
#
LOCALNODE="`hostname`" ; LOCALNODE="${LOCALNODE%%.*}"

# Set our display, taking care of the case where the current setting
# of DISPLAY does not explicitely mention the display name.  Also
# check whether we have a numeric IP address, in which case we leave
# it alone.  Otherwise, strip off the domain name if there is one.
#
OURDISPLAY="${DISPLAY%%:*}"		# Start with text up to the colon
if [ "${OURDISPLAY}" = "${DISPLAY}" ] ; then
  echo "Bad display name: ${DISPLAY}" 1>&2 ; exit 1  
fi
if [ "${OURDISPLAY##[0-9]*.[0-9]*.[0-9]*.[0-9]*}" != "" ] ; then
  OURDISPLAY="${OURDISPLAY%%.*}"	# Strip possible full domain name
fi

# Causes error.  It's fine if there is no host in $DISPLAY
# if [ "${OURDISPLAY}" = "" ] ; then OURDISPLAY="${LOCALNODE}" ; fi

OURADDRESS="${DISPLAY##*:}"
if [ "${OURADDRESS}" = "" ] ; then OURADDRESS="0.0" ; fi

# Override the original definition of DISPLAY, so that it is always
# defined with the (unqualified) node name.
#
DISPLAY="${OURDISPLAY}:${OURADDRESS}"

# Figure out who we are.  These variables are initialized inconsistently
# on different platforms, so get the name from whatever variable seems
# to have it.
#
if   [ "${LOGNAME}" != "" ] ; then SIGUSER="${LOGNAME}" ;
elif [ "${USER}"    != "" ] ; then SIGUSER="${USER}"    ;
else                               SIGUSER="???"        ;
fi

# ----------------------------------------
# Process the argument list
#
FONT=""
GEOM=""
NEWUSER="${SIGUSER}"
COUNT="1" ; EXPCOUNT=""
HELP="false"
VERBOSE="false"
XRMARGS="null"
RLOGIN="false"
TELNET="false"
PROGRAM=""

# If the first argument is not NULL, and does not begin with "-", then
# take it as the node name.
#
NODE="${LOCALNODE}"

if [ "${1}" != "" ] ; then
  if [ "${1#-}" = "${1}" ] ; then
    NODE="${1}" ; shift
  fi
fi

while [ "${1}" != "" ] ; do
  OPT="${1}" ; shift

  if [  "${OPT}" = "-display" ] ; then
    if [ "${1}" = "" ] ; then
      echo "Missing display spec" 1>&2 ; exit 1
    else
      DISPLAY="${1}" ; shift
    fi

  elif [  "${OPT}" = "-font" ] ; then
    if [ "${1}" = "" ] ; then
      echo "Missing font spec" 1>&2 ; exit 1
    else
      FONT="${1}" ; shift
    fi

  elif [  "${OPT}" = "-geom" ] ; then
    if [ "${1}" = "" ] ; then
      echo "Missing geometry spec" 1>&2 ; exit 1
    else
      GEOM="${1}" ; shift
    fi

  elif [ "${OPT}" = "-help" ] ; then
    HELP="true"

  elif [  "${OPT}" = "-l" ] ; then
    if [ "${1}" = "" ] ; then
      echo "Missing user name" 1>&2 ; exit 1
    else
      NEWUSER="${1}" ; shift
    fi

  elif [  "${OPT}" = "-n" ] ; then
    if [ "${1}" = "" ] ; then
      echo "Missing replication count" 1>&2 ; exit 1
    else
      COUNT="${1}" ; shift
      if [ "$((COUNT > 8))" = "1" ] ; then COUNT="8" ; fi
      if [ "$((COUNT < 1))" = "1" ] ; then exit 0    ; fi
      if [ "${COUNT}" = "1" ] ; then EXPCOUNT=""
                                else EXPCOUNT="-n ${COUNT}" ; fi
    fi

  elif [  "${OPT}" = "-rsh" ] ; then
      REMSH="rsh"  ;

  elif [  "${OPT}" = "-ssh" ] ; then
      REMSH="ssh"  ;

  elif [  "${OPT}" = "-style" ] ; then
    if [ "${1}" = "" ] ; then
      echo "Missing style spec" 1>&2 ; exit 1
    else
      STYLE="${1}" ; EXPSTYLE="-style '${STYLE}'" ; shift
    fi

  elif [ "${OPT}" = "-v" ] ; then
    VERBOSE="true"

  elif [ "${OPT}" = "-rlogin" ] ; then
    RLOGIN="true"
  elif [ "${OPT}" = "-telnet" ] ; then
    TELNET="true"

  elif [  "${OPT}" = "-xrm" ] ; then
    if [ "${1}" = "" ] ; then
      echo "Missing arg to -xrm" 1>&2 ; exit 1
    else
      XRMARGS="${1}" ; shift
    fi

  elif [  "${OPT}" = "-e" ] ; then
    while [ "${1}" != "" ] ; do
      PROGRAM="${PROGRAM} ${1}" ; shift ;
    done

  else
    echo "Unknown option: '${OPT}'" 1>&2 ; HELP="true"
  fi
done

if [ "${HELP}" = "true" ] ; then
  echo "sigterm <node> <options>"
  echo " -display <name> : Override the default display"
  echo "    -font <font> : Use a particular font, or S,M,L defaults"
  echo " -geom <WxH+X+Y> : Start up with a particular width/height X/Y"
  echo "       -l <user> : Login as named user"
  echo "       -n <N>    : Create N sigterms all at once"
  echo "      -rsh       : Use 'rsh' rather than 'ssh' (default)"
  echo "      -ssh       : Use 'ssh' rather than 'rsh'"
  echo "   -style <term> : Choose 'hpterm', 'xterm', or 'dtterm'"
  echo "    -help        : Display this list"
  echo "       -v        : Verbose debugging"
  echo " -rlogin/-telnet : Remote connection via local window"
  echo " -e prog args... : Execute arbitrary program + args"
  exit 0
fi

if [ "${VERBOSE}" = "true" ]; then DUMP=""; else DUMP="1>/dev/null 2>/dev/null"; fi

# ----------------------------------------
# Do some additional error checking on the inputs
#
II=0
if [ "${TELNET}"   = "true" ] ; then ((II=II+1)) ; fi
if [ "${RLOGIN}"   = "true" ] ; then ((II=II+1)) ; fi
if [ "${PROGRAM}" != ""     ] ; then ((II=II+1)) ; fi
if [ "$((II > 1))" = "1" ] ; then
  echo "Can not mix 'telnet', 'rlogin', and '-e'" 1>&2 ; exit 1
fi

if [ "${TELNET}" = "true" -a "${NEWUSER}" != "${SIGUSER}" ] ; then
  echo "Can not 'telnet' as a different user" 1>&2 ; exit 1
fi

# ----------------------------------------
# Customize default fonts and XTerm preferences for the displays that need
# special attention. Then set the actual font according to what was (or was
# not) typed in.
#
LFONT="-*-terminal-medium-r-normal--25-*-iso8859-*"
MFONT="-*-terminal-medium-r-normal--18-*-iso8859-*"
SFONT="-*-terminal-medium-r-normal--14-*-iso8859-*"

TITLE="${NEWUSER} on ${NODE}"
FG="-fg black"
BG="-bg grey92"
SCROLL="-sb -sl 800"
NOPCMD="-sb" # Wont hurt anything if spuriously added

if [ "${OURDISPLAY#wes-}" = "skunk" ] ; then
  if [ "${FONT}" = "s" -o "${FONT}" = "S" ] ; then
    if [ "${GEOM}" = "" ] ; then GEOM="110x40" ; fi
  fi
  SFONT="-dt-interface user-medium-r-normal-m serif-13-130-72-72-m-90-iso8859-*"
  # SFONT="-misc-fixed-medium-r-normal--13-100-100-100-c-80-iso8859-*"

elif [ "${OURDISPLAY}"  = "hail" ] ; then
  LFONT="-*-courier-bold-r-normal--17-*-iso8859-*"
  MFONT="-*-courier-bold-r-normal--14-*-iso8859-*"
  SFONT="-*-courier-medium-r-normal--12-*-iso8859-*"

elif [ "${OURDISPLAY}"  = "w-acton" ] ; then
  if [ "${GEOM}" = "" ] ; then
    if [ "${FONT}" = "s" -o "${FONT}" = "S" ] ; then GEOM="110x40"
                                                else GEOM="80x30"
    fi
  fi
fi

if   [ "${FONT}" = "" ]                     ; then FONT="${MFONT}"
elif [ "${FONT}" = "s" -o "${FONT}" = "S" ] ; then FONT="${SFONT}"
elif [ "${FONT}" = "m" -o "${FONT}" = "M" ] ; then FONT="${MFONT}"
elif [ "${FONT}" = "l" -o "${FONT}" = "L" ] ; then FONT="${LFONT}"
fi

if [ "${GEOM}" = "" ] ; then GEOM="80x24" ; fi

# ----------------------------------------
# If we are creating a terminal on a remote machine or for someone
# other than ourself, then execute a remote shell to start it up.  The
# most important thing happening here is the exporting of the DISPLAY
# variable and other command line arguments to the next xterm.
#
if [ "${RLOGIN}" = "false" -a "${TELNET}" = "false" -a \
     \( "${NODE}" != "${LOCALNODE}" -o "${NEWUSER}" != "${SIGUSER}" \) ] ; then

  # Pass program to execute, if any, and override stdout and stderr so
  # parent process will not block.
  #
  EXESHELL=""
  if [ "${PROGRAM}" != "" ] ; then EXESHELL="-e ${PROGRAM}" ; fi

  FORKS="1>/dev/null 2>/dev/null &" 

  # Set up the environment on the remote machine, and execute both the
  # system and private the profile scripts.  This will set the PATH
  # for finding the executable sigterm.  Finally, pass any args that
  # were supplied to us directly over to the new sigterm.
  #
  ${REMSH} ${NODE} -l ${NEWUSER} -n \
    "DISPLAY=${DISPLAY}           ; export DISPLAY      ;
     cd ;
     if [ -r /etc/profile ] ; then . /etc/profile ${DUMP}; fi ;
     if [ -r ./.profile ]   ; then . ./.profile ${DUMP}; fi ;
     sigterm -font '${FONT}' -geom '${GEOM}' ${EXPSTYLE} \
       ${EXPCOUNT} -xrm '${XRMARGS}' ${EXESHELL} ${FORKS} " ${DUMP}

# ----------------------------------------
# Start up a terminal on the local machine.
#
else
  # If this is supposed to be a remote login to another machine, then
  # use a remote login shell instead of the default shell, and change
  # the title bar to remind us that this is what is happening.  Also
  # handle executing arbitrary commands in a nicely titled window.
  #
  EXESHELL="" ; EXEARGS="${NOPCMD}"
  if [ "${RLOGIN}" = "true" ] ; then
    EXESHELL="-e rlogin ${NODE} -l ${NEWUSER}"
    TITLE="${TITLE} (from ${LOCALNODE})"
  elif [ "${TELNET}" = "true" ] ; then
    EXESHELL="-e telnet ${NODE}"
    TITLE="${TITLE} (from ${LOCALNODE})"
  elif [ "${PROGRAM}" != "" ] ; then
    EXESHELL="-e sh -c" ;
    EXEARGS="${PROGRAM} ; stty -echo ; \
      echo '' ; \
      echo '--------------------------------------'; \
      echo '  Program exited:${PROGRAM}' ; \
      echo '  Type ^C or ^D to close this window' ; \
      echo '--------------------------------------'; \
      cat > /dev/null"
    TITLE="${NODE} : ${PROGRAM}"
  fi

  # Decide whether we will create multiple windows cascaded uniformly.
  # Only do this if if more than one window is being created, and no
  # positions were specified in their original geometry.
  #
  CASCADE="false" ; GEOMSIZE="${GEOM%%[-+]*}" ;
  if [ "${GEOMSIZE}" = "${GEOM}" -a "$((COUNT > 1))" = "1" ] ; then
    CASCADE="true" ; XPOS="0" ; YPOS="0" ;
  fi

  # Startup as many terminals as were requested.  Initialize the
  # COLUMNS variable to match the width of the terminal window
  # that we are creating.
  #
  cd ${HOME} ; export COLUMNS="${GEOM%%x*}"

  while [ "${COUNT}" != "0" ] ; do

    # If cascading, then update the position portion of the geometry
    # spec each time.
    #
    if [ "${CASCADE}" = "true" ] ; then
      GEOM="${GEOMSIZE}-${XPOS}-${YPOS}" ; ((XPOS=XPOS+102)) ; ((YPOS=YPOS+108))
    fi
    # Now startup one of the selected types of terminals...
    #
    if [ "${STYLE}" = "hpterm" ] ; then
      if [ ! -x ${EXEDIR}/hpterm ] ; then
        echo "Can't find ${EXEDIR}/hpterm" 1>&2 ; exit 1
      else
        ${EXEDIR}/hpterm \
          -font "${FONT}" ${FG} ${BG} -geom ${GEOM} ${SCROLL} \
	  -title "${TITLE}" -n ${NODE} -display ${DISPLAY} \
          -mb -mc shadow -sbbg grey55 \
          -xrm "*hpterm*pointerShape: left_ptr" \
          -xrm "*hpterm*scrollBar*width: 20" \
          -xrm "${XRMARGS}" \
          ${EXESHELL} "${EXEARGS}" &
      fi

    elif [ "${STYLE}" = "xterm" ] ; then
      if [ ! -x ${EXEDIR}/xterm ] ; then
        echo "Can't find ${EXEDIR}/xterm" 1>&2 ; exit 1
      else
        XRMWHEEL="*XTerm*VT100*Translations:#override\n \
                    Shift<Btn4Down>:scroll-back(1,halfpage)\n \
                    Shift<Btn5Down>:scroll-forw(1,halfpage)\n \
                     Ctrl<Btn4Down>:scroll-back(1,line)\n \
                     Ctrl<Btn5Down>:scroll-forw(1,line)\n \
                         <Btn4Down>:scroll-back(1,line) scroll-back(1,line) \
                                    scroll-back(1,line) scroll-back(1,line) \
                                    scroll-back(1,line)\n \
                         <Btn5Down>:scroll-forw(1,line) scroll-forw(1,line) \
                                    scroll-forw(1,line) scroll-forw(1,line) \
                                    scroll-forw(1,line)"
        ${EXEDIR}/xterm \
          -font "${FONT}" ${FG} ${BG} -geom ${GEOM} ${SCROLL} \
	  -title "${TITLE}" -n ${NODE} -display ${DISPLAY} \
          -mb -si -cr black -ms black \
          -xrm "${XRMWHEEL}" -xrm "${XRMARGS}" \
          ${EXESHELL} "${EXEARGS}" &
      fi

    elif [ "${STYLE}" = "dtterm" ] ; then
      if [ ! -x ${EXEDIR}/dtterm ] ; then
        echo "Can't find ${EXEDIR}/dtterm" 1>&2 ; exit 1
      else
        ${EXEDIR}/dtterm \
          -fn "${FONT}" ${FG} ${BG} -geom ${GEOM} ${SCROLL} \
	  -title "${TITLE}" -n ${NODE} -display ${DISPLAY} \
          -mb -ms black -bw 0 \
          -xrm "*dtterm*menuBar: False" \
          -xrm "${XRMARGS}" \
          ${EXESHELL} "${EXEARGS}" &
      fi

    else
      echo "Unknown terminal style: ${STYLE}" 1>&2 ; exit 1
    fi

    ((COUNT=COUNT-1))
  done
fi
