
#  N.B. the previous line should be blank.
#+
#  Name:
#     browse

#  Purpose:
#     Display a document using a WWW browser.

#  Type of Module:
#     Shell script

#  Description:
#     This script displays a document using a WWW browser. If necessary, it
#     starts a new invocation of the browser. Otherwise, it uses an existing
#     one and passes the document to it by "remote control".
#
#     Documents may be specified using URLs or local file names, or temporary
#     documents may be given by supplying their contents (in HTML format)
#     on standard input. These options are controlled by the setting of the
#     HTX_WHERE environment variable.

#  Invocation:
#        browse doc
#     or cat doc | browse

#  Parameters:
#     doc
#        The optional specification of the document to be displayed, given
#        either as a URL or the name of a local file which is accessible to the
#        browser.

#  Environment Variables Used:
#     DISPLAY
#        Normally, this should be set to identify the X display in use. If
#        it is not set, an attempt will be made to run the Starlink "xdisplay"
#        utility to define it, although this may slow down document display.
#        If the DISPLAY variable cannot be set in this way, then an error will
#        result.
#     HTX_BROWSER
#        An optional command which will be used to invoke the WWW browser. This
#        should contain a string corresponding to one of the supported WWW
#        browsers (currently "netscape" or "Mosaic") in order that the browser
#        being used can be recognosed. If this variable is not defined, then
#        "netscape" is used by default. If it is not recognised, then an error
#        will result.
#     HTX_SCRIPT
#        The name of the script originally invoked by the user. This is used
#        in the generation of warning and error messages.
#     HTX_TMP
#        The name of the directory in which to create temporary communication
#        files. If this variable is not set, or is null, $HOME/.htxtmp is used
#        instead.
#     HTX_TTY
#        The name of the controlling terminal. This may be needed on some
#        systems if a document is being read from standard input, because the
#        Starlink "xdisplay" utility may examine standard input to identify
#        the terminal. If given, and not null, HTX_TTY is supplied to
#        "xdisplay" in place of standard input.
#     HTX_WARN
#        If this has the value '1', then any warning messages generated by
#        the browser (e.g. during startup) will be written to standard error.
#        Otherwise, these warnings will be suppressed.
#     HTX_WHERE
#        -  If this has the value "l", then the "doc" parameter is interpreted
#        as the name of a local file.
#        -  If it has the value "i", the document contents (in HTML format)
#        will be read from standard input by this script and stored in a
#        temporary file for access by the browser.
#        -  If it has neither of these values, the "doc" argument is
#        interpreted as a URL.

#  Notes:
#     -  Subject to the limitations imposed by each browser, this script
#     attempts to use the most appropriate current browser invocation for
#     displaying documents.
#     -  It also attempts to manage temporary file space used to store any
#     documents read from standard input.

#  Implementation Deficiencies:
#     -  Management of temporary files is somewhat imperfect due to the
#     difficulty of knowing when the browser has finished with them. The
#     strategy adopted is to leave the last 3 of these around but to remove
#     older ones whenever a new one is created (the configuration files used
#     by Mosaic are handled somewhat more precisely than this, however).
#     -  In the case of Mosaic, temporary files are associated with a specific
#     browser process ID, so it is possible to periodically determine if the
#     associated browser has been stopped and remove all unnecessary files.
#     With Netscape, however, the process ID is not known (it could be running
#     on another machine) so some files will generally be left around. The
#     main objective in this case is simply to prevent the number of files
#     growing without limit.

#  Copyright:
#     Copyright (C) 1998 Central Laboratory of the Research Councils

#  Authors:
#     RFWS: R.F. Warren-Smith (Starlink, RAL)
#     SER: S.E. Rankin (Starlink, RAL)
#     {enter_new_authors_here}

#  History:
#     17-OCT-1995 (RFWS):
#        Original version.
#     5-JAN-1998 (RFWS):
#        Made Netscape the default browser.
#     5-JAN-1998 (RFWS):
#        Fixed problems with openFILE no longer working properly in Netscape.
#     6-JAN-1998 (RFWS):
#        Use HTX_TMP for temporary communication files.
#     6-JAN-1998 (RFWS):
#        Re-define standard input to be ${HTX_TTY} for "xdisplay" if possible.
#     29-OCT-2003 (SER)
#        Added Mozilla. Fixed bug for Solaris when starting 
#        netscape (redirection command for sh).
#     17-MAY-2004 (SER)
#        Added Netscape 7.1 code (same as Mozilla). Made some alterations
#        with "file://". The file:// part of the url is now added in the
#        urlgen and showme scripts.
#     {enter_further_changes_here}

#  Bugs:
#     {note_any_bugs_here}

#-

#  Obtain the document URL.
      url="${1}"

#  Export variables required by related scripts.
      export DISPLAY
      export HTX_BROWSER

#  Include the definition of the "settrap" function which is used to define
#  traps for clearing up scratch files if the script is aborted.
      . ${HTX_DIR}/settrap

#  Determine which directory to use for temporary communication files and
#  ensure that it exists.
      tmpdir="${HTX_TMP:-${HOME}/.htxtmp}"
      if test ! -d "${tmpdir}"; then mkdir "${tmpdir}"; fi

#  Select a WWW browser, providing "netscape" as a default.
      case "${HTX_BROWSER:=netscape}" in

#
#  Netscape.
#  ========
      *[Nn][Ee][Tt][Ss][Cc][Aa][Pp][Ee]*)

#  Manage scratch file space.
#  -------------------------
#  If the document to be viewed is being supplied on standard input, then
#  we must generate a name for a temporary file to store it.
         if test "${HTX_WHERE}" = 'i'; then

#  Use "ls" to list all the temporary file names so far used in reverse order
#  of their creation time.
            tempfiles="`ls -t ${tmpdir}/htx-browse-netscape-${LOGNAME}-*.html \
                        2>/dev/null`"

#  Pass this list of file names through "sed" to extract the sequence number
#  field, quitting once that corresponding to the most recently created file
#  has been obtained.
            n="`echo "${tempfiles}" \
            | sed -n 's%^.*/htx-browse-netscape-'"${LOGNAME}"'-\([1-9][0-9]*\)\.html$%\1%p
                      t done
                      b
                      :done
                      q'`"

#  If no sequence number was found, then use 1. Otherwise increment it.
            if test ! -n "${n}"; then n='1'; else n="`expr "${n}" + 1`"; fi

#  Generate the temporary file name and replace the URL value with it. This
#  name must be unique to the current machine, software, browser, user and
#  temporary document sequence number.
            url="${tmpdir}/htx-browse-netscape-${LOGNAME}-${n}.html"

#  Select the names of all but the most recent few temporary files and remove
#  these older ones if necessary.
            oldfiles="`echo "${tempfiles}" | tail +3`"
            if test -n "${oldfiles}"; then rm -f ${oldfiles}; fi
         fi

#  Ensure DISPLAY is set.
#  ---------------------
#  The DISPLAY variable is always required for netscape, so see if it is
#  defined.
         wasset='1'
         if test ! -n "${DISPLAY}"; then
            wasset=''

#  If it was not defined, then search relative to directories ending in "/bin"
#  that appear in $PATH to see if the Starlink "xdisplay" executable is
#  available.
            xdisplay="`IFS=':'; for dir in ${PATH}; do
               case "${dir}" in */bin)
                  file="${dir}/../etc/xdisplay"
                  test -x "${file}" -a ! -d "${file}" && echo "${file}" \
                                                      && break;;
               esac
            done`"

#  If "xdisplay" was found, then use it to set a DISPLAY value. If possible,
#  redirect standard input to the controlling terminal, since this affects
#  results on some systems.
            if test -n "${xdisplay}"; then
               if test -n ${HTX_TTY}; then
                  DISPLAY="`${xdisplay} <${HTX_TTY}`"
               else
                  DISPLAY="`${xdisplay}`"
               fi

#  If it could not be found, abort with an error message.
            else
               echo >&2 \
               "${HTX_SCRIPT}: please set DISPLAY to identify your X display"
               exit 1
            fi
         fi

#  Prepare to communicate with Netscape.
#  ------------------------------------
#  Generate the Netscape remote command required to make an existing browser
#  read the document.
         if test "${HTX_WHERE}" = 'l' -o "${HTX_WHERE}" = 'i'; then
            url=`echo "${url}" | sed 's#file://#file://localhost/#'`
            remcmd="openURL(${url})"
         else
            remcmd="openURL(${url})"
         fi

#  If necessary, read the document from standard input into its temporary file.
#  Before doing so, set a trap to remove the file if this script is aborted.
         if test "${HTX_WHERE}" = 'i'; then
            settrap 'rm -f "${url}"'
            cat >"${url}" || exit
         fi

#  Try to use an existing invocation of Netscape.
#  ----------------------------------------------
#  Try to run netscape with "-remote" to make an existing browser invocation
#  read the document. Suppress any error messages.
         if ${HTX_BROWSER} -noraise -remote "${remcmd}" > /dev/null 2>&1; then

#  If successful, disable the trap associated with temporary files, if
#  necessary.
            if test "${HTX_WHERE}" = 'i'; then settrap; fi

#  Start a new invocation of Netscape.
#  -----------------------------------
#  If the attempt to use an existing browser failed, then we must start a new
#  one. Before doing so, check if the DISPLAY variable was set before invoking
#  this script. If not, then issue a warning because running "xdisplay" each
#  time will slow down document access.
         else
            if test ! "${wasset}" = '1'; then
               echo >&2 \
"${HTX_SCRIPT}: for faster access, please set DISPLAY to identify your X display"
            fi

#  Start a new browser, supplying the URL generated above. Suppress warning
#  messages if required.
            echo "Starting ${HTX_BROWSER} WWW browser..."
            if test "${HTX_WARN}" = '1'; then
               ${HTX_BROWSER} "${url}" &
            else
               ${HTX_BROWSER} 2>/dev/null "${url}" &
            fi

#  Disable the trap associated with temporary files, if necessary.
            if test "${HTX_WHERE}" = 'i'; then settrap; fi
         fi
         ;;
#
#  Mozilla.
#  ========
      *[Mm][Oo][Zz][Ii][Ll][Ll][Aa]*)

#  Manage scratch file space.
#  -------------------------
#  If the document to be viewed is being supplied on standard input, then
#  we must generate a name for a temporary file to store it.
         if test "${HTX_WHERE}" = 'i'; then

#  Use "ls" to list all the temporary file names so far used in reverse order
#  of their creation time.
            tempfiles="`ls -t ${tmpdir}/htx-browse-mozilla-${LOGNAME}-*.html \
                        2>/dev/null`"

#  Pass this list of file names through "sed" to extract the sequence number
#  field, quitting once that corresponding to the most recently created file
#  has been obtained.
            n="`echo "${tempfiles}" \
            | sed -n 's%^.*/htx-browse-mozilla-'"${LOGNAME}"'-\([1-9][0-9]*\)\.html$%\1%p
                      t done
                      b
                      :done
                      q'`"

#  If no sequence number was found, then use 1. Otherwise increment it.
            if test ! -n "${n}"; then n='1'; else n="`expr "${n}" + 1`"; fi

#  Generate the temporary file name and replace the URL value with it. This
#  name must be unique to the current machine, software, browser, user and
#  temporary document sequence number.
            url="${tmpdir}/htx-browse-mozilla-${LOGNAME}-${n}.html"

#  Select the names of all but the most recent few temporary files and remove
#  these older ones if necessary.
            oldfiles="`echo "${tempfiles}" | tail +3`"
            if test -n "${oldfiles}"; then rm -f ${oldfiles}; fi
         fi

#  Ensure DISPLAY is set.
#  ---------------------
#  The DISPLAY variable is always required for mozilla, so see if it is
#  defined.
         wasset='1'
         if test ! -n "${DISPLAY}"; then
            wasset=''

#  If it was not defined, then search relative to directories ending in "/bin"
#  that appear in $PATH to see if the Starlink "xdisplay" executable is
#  available.
            xdisplay="`IFS=':'; for dir in ${PATH}; do
               case "${dir}" in */bin)
                  file="${dir}/../etc/xdisplay"
                  test -x "${file}" -a ! -d "${file}" && echo "${file}" \
                                                      && break;;
               esac
            done`"

#  If "xdisplay" was found, then use it to set a DISPLAY value. If possible,
#  redirect standard input to the controlling terminal, since this affects
#  results on some systems.
            if test -n "${xdisplay}"; then
               if test -n ${HTX_TTY}; then
                  DISPLAY="`${xdisplay} <${HTX_TTY}`"
               else
                  DISPLAY="`${xdisplay}`"
               fi

#  If it could not be found, abort with an error message.
            else
               echo >&2 \
               "${HTX_SCRIPT}: please set DISPLAY to identify your X display"
               exit 1
            fi
         fi

#  Prepare to communicate with Mozilla.
#  ------------------------------------
#  Generate the Mozilla remote command required to make an existing browser
#  read the document.
         if test "${HTX_WHERE}" = 'l' -o "${HTX_WHERE}" = 'i'; then
            url=`echo "${url}" | sed 's#file://#file://localhost/#'`
            remcmd="openURL(${url})"
         else
            remcmd="openURL(${url})"
         fi

#  If necessary, read the document from standard input into its temporary file.
#  Before doing so, set a trap to remove the file if this script is aborted.
         if test "${HTX_WHERE}" = 'i'; then
            settrap 'rm -f "${url}"'
            cat >"${url}" || exit
         fi

#  Try to use an existing invocation of Mozilla.
#  ----------------------------------------------
#  Try to run Mozilla with "-remote" to make an existing browser invocation
#  read the document. Suppress any error messages.
         if ${HTX_BROWSER} -noraise -remote "${remcmd}" > /dev/null 2>&1; then

#  If successful, disable the trap associated with temporary files, if
#  necessary.
            if test "${HTX_WHERE}" = 'i'; then settrap; fi

#  Start a new invocation of Mozilla.
#  -----------------------------------
#  If the attempt to use an existing browser failed, then we must start a new
#  one. Before doing so, check if the DISPLAY variable was set before invoking
#  this script. If not, then issue a warning because running "xdisplay" each
#  time will slow down document access.
         else
            if test ! "${wasset}" = '1'; then
               echo >&2 \
"${HTX_SCRIPT}: for faster access, please set DISPLAY to identify your X display"
            fi

#  Start a new browser, supplying the URL generated above. Suppress warning
#  messages if required.
            echo "Starting ${HTX_BROWSER} WWW browser..."
            if test "${HTX_WARN}" = '1'; then
               ${HTX_BROWSER} "${url}" &
            else
               ${HTX_BROWSER} 2>/dev/null "${url}" &
            fi

#  Disable the trap associated with temporary files, if necessary.
            if test "${HTX_WHERE}" = 'i'; then settrap; fi
         fi
         ;;

#  Mosaic.
#  ======
      *[Mm][Oo][Ss][Aa][Ii][Cc]*)

#  Define a cleanup function.
#  -------------------------
#  The "mosclean" function will remove all files created in ${tmpdir} by the
#  current user using this script once they are no longer required.
         mosclean() {

#  Check if a readable cleanup file exists.
            if test -f "${clean}" -a -r "${clean}"; then

#  Extract from the cleanup file a list of the browser process IDs for which
#  temporary Mosaic configuration files have been created. Then remove the
#  cleanup file.
               ids="`cat "${clean}"`"
               rm -f "${clean}"

#  For each process ID, send a null signal to see if the browser process still
#  exists. If it does, return the process ID to the cleanup file.
               for id in ${ids}; do
                  if kill 1>/dev/null 2>/dev/null -0 "${id}"; then
                     echo >>"${clean}" "${id}"

#  If the browser process no longer exists, then remove the temporary
#  configuration file created for it in /tmp (note, not in ${tmpdir}).
                  else
                     rm -f "/tmp/Mosaic.${id}"
                  fi
               done
            fi

#  We next clean up any temporary files created to hold documents read from
#  standard input whose browsers are no longer active. Obtain a list of all
#  the files in which these temporary files are listed and loop to process
#  each one.
            for logfile in \
                `ls ${tmpdir}/htx-browse-mosaic-${LOGNAME}-*.htmlfiles \
                   2>/dev/null`; do

#  For each file found, use "expr" to extract the process ID field from the
#  file name.
               pid="`expr "X${logfile}" : \
               'X.*/htx-browse-mosaic-'"${LOGNAME}"'-\([1-9][0-9]*\)\.htmlfiles$'`"

#  If successful, send a null signal to the associated browser process to see
#  if it is still active. Take no action if it is.
               if test -n "${pid}"; then
                  if kill 1>/dev/null 2>/dev/null -0 "${pid}"; then
                     :

#  If the browser is no longer active, then pass the list of temporary files
#  through "sed" as a security measure to eliminate malicious entries.
                  else
                     oldfiles="`sed -n \
                     's%^.*/htx-browse-mosaic-'"${LOGNAME}"'-[1-9][0-9]*\.html$%&%p' "${logfile}"`"

#  Remove the old temporary files and the file that contained their names.
                     rm -f ${oldfiles} "${logfile}"
                  fi
               fi
            done

#  End of "mosclean" function definition.
         }

#  Generate new temporary file names.
#  ---------------------------------
#  If the document to be viewed is being supplied on standard input, then
#  we must generate a name for a temporary file to store it.
         if test "${HTX_WHERE}" = 'i'; then

#  Use "ls" to list all the temporary file names so far used in reverse order
#  of their creation time. Pipe these file names through "sed" to extract the
#  sequence number field and quit after the first one is found.
            n="`ls -t ${tmpdir}/htx-browse-mosaic-${LOGNAME}-*.html \
                   2>/dev/null \
            | sed -n 's%^.*/htx-browse-mosaic-'"${LOGNAME}"'-\([1-9][0-9]*\)\.html$%\1%p
                      t done
                      b
                      :done
                      q'`"

#  If no sequence number was found, use 0. Then increment it.
            n="`expr "${n:-0}" + 1`"

#  Generate the temporary file name and replace the URL value with it. This
#  name must be unique to the current machine, software, browser, user and
#  temporary document sequence number.
            url="${tmpdir}/htx-browse-mosaic-${LOGNAME}-${n}.html"
         fi

#  Define the name of a cleanup file to be used to drive cleanup operations.
#  This will reside in ${tmpdir}. It must be unique to the current machine,
#  software, browser and user (it may already exist from a previous invocation
#  of this script).
         clean="${tmpdir}/htx-browse-mosaic-${LOGNAME}.pids"

#  See if an existing invocation of Mosaic is active.
#  -------------------------------------------------
#  Initially assume we need to start a new invocation of the browser.
         new='1'

#  Test if a readable ".mosaicpid" file exists in the user's home directory.
#  If it does, then the browser has previously been run and may still be
#  active. Extract its process ID from this file.
         if test -f "${HOME}/.mosaicpid" -a -r "${HOME}/.mosaicpid"; then
            pid="`cat "${HOME}/.mosaicpid"`"

#  Send a null signal to the browser process, suppressing all error messages,
#  to see if it it still active. If so, note that we need not start a new
#  browser.
            if kill 1>/dev/null 2>/dev/null -0 "${pid}"; then new=''; fi
         fi

#  Make an existing Mosaic invocation read the document.
#  ----------------------------------------------------
#  If an existing browser can be used, then generate the name of the
#  configuration file to use for communication with it (note this must be
#  in /tmp, not in ${tmpdir}). Also note if we are creating this file for the
#  first time.
         if test ! -n "${new}"; then
            confile="/tmp/Mosaic.${pid}"
            if test -f "${confile}"; then newcon=''; else newcon='1'; fi

#  Write the commands to send to Mosaic into the configuration file. Note that
#  in remote control mode we have to distinguish local files from server
#  references or they may not be found if the browser has previously visited
#  other WWW sites.
            echo  >"${confile}" 'goto'
            if test "${HTX_WHERE}" = 'l' -o "${HTX_WHERE}" = 'i'; then
               url=`echo "${url}" | sed 's#file://#file://localhost/#'`
               echo >>"${confile}" "${url}"
            else
               echo >>"${confile}" "${url}"
            fi

#  If the document is to be read from standard input, then copy it into its
#  temporary file. Before doing so, set a trap to remove the file if this
#  script is aborted.
            if test "${HTX_WHERE}" = 'i'; then
               settrap 'rm -f "${url}"'
               cat >"${url}" || exit
            fi

#  Send the "SIGUSR1" signal to the browser. This is an instruction for it to
#  read the configuration file and act on its contents.
            kill -USR1 "${pid}"

#  Manage scratch file space.
#  -------------------------
#  We must leave the configuration file in place as long as the browser is
#  active, as we don't know when it will actually read it. If this was a new
#  file, append the browser's process ID to the cleanup file so that future
#  cleanup operations will remove the configuration file.
            if test "${newcon}" = '1'; then echo >>"${clean}" "${pid}"; fi

#  If we have created a temporary document by reading standard input, then this
#  must also be left in place. To prevent large numbers of files accumulating,
#  however, we only retain the last few such documents. This is handled here.
            if test "${HTX_WHERE}" = 'i'; then

#  To keep track of the temporary documents that have been created, we store
#  their names in a scratch file. Generate the name of this file, incorporating
#  the browser process ID, so that we can associate the documents with the
#  browser that read them.
               logfile="${tmpdir}/htx-browse-mosaic-${LOGNAME}-${pid}.htmlfiles"

#  If a file containing a document list for this browser already exists, then
#  run "awk" on it to read in its contents, storing each line.
               newlog=''
               if test -r "${logfile}"; then
                   oldfiles="`awk -F"\n" '{
                      l[ ++n ] = $0

#  When the contents have been read, write out all but the last 3 lines. These
#  are the names of old files that can be deleted and are stored in the
#  "oldfiles" variable (see above). Write the final 3 lines back into the
#  input file. Thse are the names of the files being retained.
                   } END {
                      while ( i < n - 2 ) print l[ ++i ]
                      while ( i < n ) print l[ ++i ] >\"'"${logfile}"'\"

#  Pipe the output from "awk" through "sed" to pass only those file names that
#  match the expected form. This is a security measure to prevent malicious
#  entries being added to the list of file names.
                   }' "${logfile}" \
                   | sed -n 's%^.*/htx-browse-mosaic-'"${LOGNAME}"'-[1-9][0-9]*\.html$%&%p'`"

#  If any old files have been identified, then remove them.
                   if test -n "${oldfiles}"; then rm -f ${oldfiles}; fi

#  Note if a new file will be created to hold the list of temporary files.
               else
                  newlog='1'
               fi

#  Append a record of the latest temporary document (the one we have just
#  created). Once it is recorded, disable the trap associated with it.
               echo "${url}" >>"${logfile}"
               settrap
            fi

#  If any new file was created for communicaton with the browser, then perform
#  cleanup operations. This generally occurs when we make initial contact with
#  a browser (perhaps started by other means) and helps prevent debris
#  accumulating from past invocations of it.
            if test "${newcon}" = '1' -o "${newlog}" = '1'; then
               mosclean
            fi

#  Ensure that DISPLAY is set.
#  --------------------------
#  If a new browser invocation is required, check if the DISPLAY variable is
#  defined.
         else
            if test ! -n "${DISPLAY}"; then

#  If it was not defined, then search relative to directories ending in "/bin"
#  that appear in $PATH to see if the Starlink "xdisplay" executable is
#  available.
               xdisplay="`IFS=':'; for dir in ${PATH}; do
                  case "${dir}" in */bin)
                     file="${dir}/../etc/xdisplay"
                     test -x "${file}" -a ! -d "${file}" && echo "${file}" \
                                                         && break;;
                  esac
               done`"

#  If "xdisplay" was found, then use it to set a DISPLAY value. If possible,
#  redirect standard input to the controlling terminal, since this affects
#  results on some systems.
               if test -n "${xdisplay}"; then
                  if test -n ${HTX_TTY}; then
                     DISPLAY="`${xdisplay} <${HTX_TTY}`"
                  else
                     DISPLAY="`${xdisplay}`"
                  fi

#  If it could not be found, abort with an error message.
               else
                  echo >&2 \
                  "${HTX_SCRIPT}: please set DISPLAY to identify your X display"
                  exit 1
               fi
            fi

#  Start a new invocation of Mosaic.
#  --------------------------------
#  Clean up after any previous browsers have finished. This will not be
#  necessary if all browsers are invoked by this script as they will clean up
#  after themselves (see below), but is needed if we have created
#  scratch files to communicate with browsers invoked by other means.
            mosclean

#  If the document is to be read from standard input, then copy it into its
#  temporary file. Before doing so, set a trap to remove the file if this
#  script is aborted.
            if test "${HTX_WHERE}" = 'i'; then
               settrap 'rm -f "${url}"'
               cat >"${url}" || exit
            fi

#  To invoke the browser we now create a background process that runs the
#  browser in a child process of its own, waits for it to complete, and then
#  invokes "mosclean" to tidy up after it.
            echo "Starting ${HTX_BROWSER} WWW browser..."
            {

#  Suppress warning messages when starting the browser if required.
            if test "${HTX_WARN}" = '1'; then
               ${HTX_BROWSER} "${url}" &
            else
               ${HTX_BROWSER} 2>/dev/null "${url}" &
            fi

#  Once we know the process ID of the new browser, check if a temporary file
#  was created to hold a document read from standard input. If so, record its
#  name in a separate scratch file associated with the browser.
               pid="${!}"
               if test "${HTX_WHERE}" = 'i'; then
                  echo "${url}" \
                     >"${tmpdir}/htx-browse-mosaic-${LOGNAME}-${pid}.htmlfiles"
               fi

#  Wait for the browser process to finish and then clean up after it.
               wait
               mosclean
            } &

#  If necessary, disable the trap associated with temporary files.
            if test "${HTX_WHERE}" = 'i'; then settrap; fi
         fi
         ;;

#  Unknown browser.
#  ===============
#  If the browser was not recognised, then abort with an error message.
      *)
         echo >&2 \
         "${HTX_SCRIPT}: the ${HTX_BROWSER} WWW browser is not recognised"
         exit 1
      esac

#  End of script.
