#!/bin/sh
# shell script 'db'
DB_VERSION='0.9.17 of 2001-01-05'
# Retrieve, enter or change data using MySQL.
# db was tested with GNU bash, version 2.01.1
# and version 3.23.29a-gamma of MySQL
#
##  --------------------------------------------------------------
##  This program is free software; you can redistribute it and/or
##  modify it under the terms of the GNU General Public License
##  as published by the Free Software Foundation; either version 2
##  of the License, or (at your option) any later version.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License
##  along with this program; if not, write to the Free Software
##  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##  --------------------------------------------------------------
#
# MySQL is a very fast, multi-threaded, multi-user and robust SQL
# (Structured Query Language) database server.
#
# Basically MySQL is subject to the GNU GPL licence with a few
# exceptions. For details please refer to the manual (see chapter
# "MySQL Licensing and Support").
#
# The MySQL home page (http://www.mysql.com/) provides the latest
# information about MySQL.
#
# usage: db [ database [ table ] ]
#        db [ serverhost [ username [ password ] ] ]
#
# This is an interactive tool, but still database and tablename 
# or hostname, username and password may be given on the 
# command line.
#
# db needs: dialog (patched), 
#           mysqld, mysql, mysqladmin, mysqlshow,
#           lynx, pinfo,
#           less  |  more  (or eqivalent)
#           joe   |  vi    (or eqivalent)
#           gzip  |  bzip2 (or eqivalent)

#################################################################
# setting some defaults
# users may change values in this section
#       (as long as they know what they are doing  :-)
#
# values set on a 'per user' basis in ~/.db.rc will
# override system defaults from this script or user
# defaults in ~/.my.cnf. The order of precedence is:
# ~/.db.rc ---> db ---> ~/.my.cnf ---> environment variable

# Which host is the database server?
# Set to 'localhost' or server name like 'myserver.mydom.net'
# The preferred location to change this is in ~/.db.rc
# The host may also be set in environment variable MYSQL_HOST.
MYSQLHOST=localhost

# Username to access mysqld on server $MYSQLHOST.
# This is not necessarily your login name and
# mysqld has its own password for this user.
# If MYSQLUSR remains unset MySQL will use the current
# login name. To use the default from ~/.my.cnf set
# to "<none>" (recommended).
MYSQLUSR="<none>"

# The password can be set in ~/.db.rc or in ~/.my.cnf (good!)
# or in the environment variable MYSQL_PWD (very insecure!).
# Please leave it empty here! (except for testing)
PASSWORD=

UPDCMD="UPDATE LOW_PRIORITY"
INSCMD="INSERT LOW_PRIORITY"
LAST_RULES=yes
DEFAULT_DB=
DEFAULTTABLE=
PAGERPROG=/usr/bin/less
HTMLVIEWER=/usr/bin/lynx

# (Przemek Borys's info viewer pinfo-0-6-0.tar.gz is available at
#  http://zeus.polsl.gliwice.pl/~pborys/stable-version/ )
INFOVIEWER="/usr/bin/pinfo -r"

MAILER=/usr/bin/mail

# db makes use of Savio Lam's (lam836@cs.cuhk.hk)
# program 'dialog' Ver. 0.6z to draw nice boxes. However,
# a patched version is preferred. Due to a bug the original
# dialog will not allow to input the %-sign (often needed for
# SQL queries) and lacks input editing. I added the
# capability to move the cursor, doing backspace or delete
# and inserting text and call it differently. This way the
# user may still have the original dialog program in his search path.
DLGPRG=dialog-0.7/dialog

# ifold is provided with the dbtool package
FLDPRG=bin/ifold

TCAP=/etc/termcap

#
MYSQLHELP=mysql.stpd.info
MYSQLHELPDIR=./docu
#
# note: when installing the dbtool package MYSQLHELPDIR will be moved
# to /usr/share/info (or whatever is set in Makefile)
#
DBMANHELP=dbtool.info
DBMANHELPDIR=./docu

#
# enable these if you have the html-manual
# or set HTMLMAN to empty
HTMLMANDIR=/usr/doc/selfhtml
#HTMLMAN=selfhtml.htm
HTMLMAN=
HTMLMANVIEW=/usr/bin/w3m
#
# display help for PHP
#PHPHLP=/usr/doc/packages/php/bigmanual.html
PHPHLP=
#

# must be writable for all users!
TMPDIR=/tmp

# how to print
PRINTER='-Php'

# A directory where the floppy drive may be mounted
# sysadmin must create an entry in client host's /etc/fstab 
# allowing users to mount. Example:
# /dev/fd0  /floppy  auto  noauto,user  0  0
FLOPPYDRIVE=/floppy

# options for mysqldump
DUMPOPTS="--add-locks --add-drop-table"

# program to compress dumped databases
# leave empty for no compression or choose 'gzip' or 'bzip2'
# bzip2 gives better compression, gzip is faster
PACKER="bzip2 -f9"

# option for $PACKER to unpack to stdout
UNPACKOPT="-dc"

# select users preferred editor
DEFAULTEDITOR=/usr/bin/joe
#DEFAULTEDITOR=/usr/local/bin/nano

# options to start the editor
#
# The option EDOPTS makes sure that the last line of the
#      file has a line-feed which is saved.
EDOPTS="-force"     # for joe
#EDOPTS="-w"         # for nano

# Force the file to read only mode.
EDRDO="-rdonly"     # for joe
#EDRDO="-v"          # for nano

# This ending will convince joe to accept long lines (no word wrap)
ENDING=".c"

# Does your editor write a backup~ file (tilde at the end)
# when something has been changed?
ED_WRITES_BKUP=yes  # for joe, vi
#ED_WRITES_BKUP=no   # for nano, ee

# screen width
SCREEN=80

# A location to store global link information for tables
# and for error logging. Manuals are here too.
# It must be writable for users but must be at a common place
# for all users.
LINK_DIR=/var/tmp/db

# a place to store SQL scripts for each user
# This could be a hidden directory in users /home/user
# or some common public place reachable for all users
#SCRIPT_DIR=$LINK_DIR/scripts
SCRIPT_DIR=~/.dbtool/scripts

# a place to store printer output files for each user
# This should be a (hidden?) directory in users /home/user
PRINT_DIR=~/.dbtool/print

VERBHDR=$PRINT_DIR/verbatim.hdr.tex
VERBEND=$PRINT_DIR/verbatim.end.tex
TEXPROG=tex       # could be 'latex'

# a place to store template letters for mass mail
# (and styles too... )
MASSM_DIR=~/.dbtool/massmail

# db can create logfiles for tables to keep a history
# of changes.
# The logfiles have the same name as the table with added suffix.
# Four additional fields are created and may be named.
TBL_SUFFIX="_log"
LOG_REC=log_rnumber
LOG_OPS=log_opscode
LOG_CHG=log_chgtime
LOG_USR=log_usrname

# the opscodes:
    NEW='n'
CHANGED='c'
DELETED='d'

# how many seconds to show a warning
WARNTIME=3
INFOTIME=2
SHORTIME=1

# should we strip the 'AUTO_INCREMENT' column when exporting
# to *.csv formats? This format will normally be used to export
# tables for import to 'excel' and we need no numbering
# there. Set to yes or no
STRIP_AUTO_INC=yes

# when exporting into outfile, is it ok to overwrite an
# existing destination file?
# <danger>! Filename is entered by user and might overwrite
#           something we want to keep.
MAY_OVERWRITE=yes

# when adding new data: should this stay in a loop until
# no data is entered? This is fine if you usually enter
# many entries at a time but impractical otherwise.
# Set to 'yes' or 'no'
ADD_LOOP=no


# when printing massmail letters this could fill up your
# printer buffer. If the handshake is buggy print errors
# will occur. Set a delay time in seconds here to slow
# down output and allow the printer to catch up
# (this is an ugly hack but solves the problem)
WAITTIME=


#echo "still living" && exit


#################################################################
# end of user configuration
# do not fiddle around with stuff below this line
# unless you are dbugging errors :-((
#################################################################

# basic name for temporary files
if test -d "$TMPDIR" -a -w "$TMPDIR" ; then
   TMPFILE="$TMPDIR/dbtmp$$$ENDING"
else
   echo -e "\nSorry, tmp dir $TMPDIR is not writable, giving up"; exit 1
fi

if ! test -x "$DLGPRG" ; then
   echo "Executable $DLGPRG not found!"
   echo "Did you forget to 'make db' ???"
   exit 1
fi

# display help if requested and quit
if test "$1" = -h -o "$1" = --help -o "$1" = "?" \
   -o "$1" = -V -o "$1" = -v -o "$1" = --version ; then
   $DLGPRG --title "Help / Version" \
   --msgbox "               shell script 'db'\n\
       (Version $DB_VERSION)\n\
              needs MySQL to run\n\n\
usage:  'db [database [table]]'\n\
   or:  'db mysqlhost username [password]'\n\
   or:  'db -h | --help | -V | --version'" 11 50
   echo ; clear ; exit
fi

# the following information goes into ~/.my.cnf
MYSQLPORT=3306
MYSQLSOCK=/tmp/mysql.sock

USERNAME="$USER"
if test -z "$USERNAME" ; then
   USERNAME="$LOGNAME"
fi

if test -z "$MYSQLUSR" ; then
   MYSQLUSR="$USERNAME"
elif test "$MYSQLUSR" = "<none>" ; then
   MYSQLUSR=""
fi

MYPAGER=$PAGER
if test -z "$MYPAGER" ; then
   MYPAGER=$PAGERPROG
fi

# What is your favorite editor ?
#   if variable $EDITOR is defined then use this editor
#   else use the default editor as set here:
if test -n "$DEFAULTEDITOR" ; then
   EDITOR="$DEFAULTEDITOR"
fi

# we assume that the user may read/write this in his
# own home directory
UCNF=~/.db.rc

# if there is a configuration file get it else install it
if test -r $UCNF ; then
   . $UCNF
elif test "$EUID" != "0" ; then
   /usr/bin/install -m 600 $LINK_DIR/db.rc $UCNF
fi

# create the scripts directory if required
if test -n "$SCRIPT_DIR" ; then
   if ! test -d "$SCRIPT_DIR" -a -w "$SCRIPT_DIR" ; then
      mkdir -p -m ug+rwx "$SCRIPT_DIR"
   fi
fi

# create the print directory if required
if test -n "$PRINT_DIR" ; then
   if ! test -d "$PRINT_DIR" -a -w "$PRINT_DIR" ; then
      mkdir -p -m ug+rwx "$PRINT_DIR"
   fi
fi

# copy the print styles if not already present
# templates are in ./print or --after installation-- in $LINK_DIR/
if ! test -f $PRINT_DIR/verbatim.hdr.tex ; then
   if test -r ./print/verbatim.hdr.tex ; then
      cp ./print/verbatim.hdr.tex $PRINT_DIR/verbatim.hdr.tex
   else
      cp $LINK_DIR/verbatim.hdr.tex $PRINT_DIR/verbatim.hdr.tex
   fi
fi
if ! test -f $PRINT_DIR/verbatim.end.tex ; then
   if test -r ./print/verbatim.end.tex ; then
      cp ./print/verbatim.end.tex $PRINT_DIR/verbatim.end.tex
   else
      cp $LINK_DIR/verbatim.end.tex $PRINT_DIR/verbatim.end.tex
   fi
fi

# create users mass mail templates directory if required
if test -n "$MASSM_DIR" ; then
   if ! test -d "$MASSM_DIR" -a -w "$MASSM_DIR" ; then
      mkdir -p -m ug+rwx "$MASSM_DIR"
   fi
fi

# copy the massmail style and friends if not already present
for STYLE in massmail.sty german.sty ngerman.sty umlaut.tex ; do
   if ! test -f $MASSM_DIR/$STYLE ; then
      if test -r ./print/$STYLE ; then
         cp ./print/$STYLE $MASSM_DIR/$STYLE
      else
         # this has been installed
         cp $LINK_DIR/$STYLE $MASSM_DIR/$STYLE
      fi
   fi
done

# start with a clean massmail directory
rm -f $MASSM_DIR/*.log $MASSM_DIR/*~

# if a hostname is given as an argument set MYSQLHOST accordingly
# overriding the built in default and .db.rc.
# note: white space in the following 3 brackets is <space><tab>
LOC_HOSTS=$(cat /etc/hosts | sed -e "/^#.*/d" -e "/^[ 	]*$/d" \
   -e "s/[0-9. 	]*//" -e "s/[ 	]*/ /")

for LH in $LOC_HOSTS ; do
   if test $LH = "$1" ; then
      MYSQLHOST=$1
      shift 1
      if test -n "$1" ; then
         MYSQLUSR=$1
         shift 1
         if test -n "$1" ; then
            PASSWORD="$1"
            shift 1
         else
            # get the password in a window
            touch ${TMPFILE}.dia
            chmod 600 ${TMPFILE}.dia
            $DLGPRG --title "Enter your MySQL password" \
             --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
             --passwd "\n This is my password for server $MYSQLHOST:\n" 10 55 2>>${TMPFILE}.dia
            if test $? != 0 ; then
               exit 1
            fi
            PASSWORD=$(cat ${TMPFILE}.dia)
            rm -f ${TMPFILE}.dia
         fi
      else
         # taking MYSQLUSR from ~/.my.cnf or fallback to $USERNAME
         MYSQLUSR=$(cat ~/.my.cnf | sed \
         -e "/^#/ d" -e "/^user/ !d" -e "s/^user[	 =]*//")
         if test -z "$MYSQLUSR" ; then
            MYSQLUSR=$USERNAME
         fi
      fi
      break
   fi
done

# fallback for (still) empty MySQL username
if test -z "$MYSQLUSR" ; then
   MYSQLUSRDISP=$USERNAME
else
   MYSQLUSRDISP=$MYSQLUSR
fi

# message for the top line; tells what the connection is
HOSTINFO="     $USERNAME@$HOSTNAME ---> MySQL/$MYSQLUSRDISP @ $MYSQLHOST"

# we need a file to keep track of links (dependencies) between tables
# it must be writable by users but should be at a general
# place because it's not user-specific. That's where we keep
# the error log too.
LINK_LIST=$LINK_DIR/db.linklist
LOG_FILE=db.log

if ! test -w $LINK_LIST ; then
   if test -d $LINK_DIR -a -w $LINK_DIR -a -x $LINK_DIR ; then
      touch $LINK_LIST
      chmod ug=rw,o=r $LINK_LIST
   elif test "$EUID" = "0" ; then
      mkdir -p $LINK_DIR
      chown root.users $LINK_DIR
      chmod ug=rwx $LINK_DIR
      touch $LINK_LIST
      chown root.users $LINK_LIST
      chmod ug=rw,o=r $LINK_LIST
      touch $LINK_DIR/$LOG_FILE
      chown root.users $LINK_DIR/$LOG_FILE
      chmod ug=rw,o=r $LINK_DIR/$LOG_FILE
      $DLGPRG --title "Success:" \
       --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
       --msgbox "created $LINK_LIST;\n\
exiting now, restart as user" 7 40
      echo ; exit
   else
      $DLGPRG --title "Information:" \
       --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
       --msgbox "Please run this script just once as user 'root'; \
this will create a file named $LINK_LIST with read/write permission \
for all users and then exit." 10 40
      echo ; exit
   fi
else
   if test "$EUID" = "0" ; then
      $DLGPRG --title "Information:" \
       --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
       --msgbox "For safety reasons 'db' will not run as user 'root'" \
         7 40
      echo ; exit 1
   fi
fi

if ! test -w $LINK_DIR/$LOG_FILE ; then
   # this should not happen
   echo "ERROR: cannot write to log file $LINK_LIST/$LOG_FILE"
   echo "please check permissions / 'ls -l' gives:"
   ls -l $LINK_DIR/$LOG_FILE
   exit 1
fi

# compose all parameters for the given host
if test -n "$PASSWORD" ; then
   PWPARM="--password=$PASSWORD"
else
   PWPARM=""
fi

if test -n "$MYSQLHOST" ; then
   HOSTOPT=-h
else
   HOSTOPT=""
fi

if test -n "$MYSQLUSR" ; then
   USROPT="-u"
else
   USROPT=""
fi

HOSTPRMS="$HOSTOPT $MYSQLHOST $USROPT $MYSQLUSR $PWPARM"

# compose the directory for helpfiles
# as soon as info files are installed in a proper directory
# no path is given.
if test -n "$MYSQLHELPDIR" ; then
   MYHLP=$MYSQLHELPDIR/$MYSQLHELP
else
   MYHLP=$MYSQLHELP
fi
if test -n "$DBMANHELPDIR" ; then
   DBHLP=$DBMANHELPDIR/$DBMANHELP
else
   DBHLP=$DBMANHELP
fi

HTHLP=$HTMLMANDIR/$HTMLMAN

# some more configuration stuff
if ! test -e ~/.my.cnf ; then
   $DLGPRG --title "Information:" \
    --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
    --yesno "Creating file ~/.my.cnf in your $HOME directory. \
             It contains user specific settings for MySQL \
             and should be edited to set your personal password. \
             Do you want to see ~/.my.cnf now? \
             (ESC to abort)" 11 40
# a 'yesno' box returns the result as the status 
# of the most recently executed foreground pipeline
# 0 = yes / 1 = no / 255 = ESC
RETVAL=$?

if test $RETVAL = 255 ; then
   echo ; exit
fi

cat > ~/.my.cnf <<-XXX
	# ~/.my.cnf
	# Uncomment and edit what you need.
	#
	# The following password will be used
	# by all standard MySQL clients.
	# (quotes only needed when password is NULL)

	[client]
	#password        = ''
	#host            = $MYSQLHOST
	#user            = $MYSQLUSR
	#port            = $MYSQLPORT
	#socket          = $MYSQLSOCK

	[mysql]
	no-auto-rehash
XXX

chmod 600 ~/.my.cnf

if test $RETVAL = 0 ; then
   $DLGPRG --title 'Your ~/.my.cnf file' \
    --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
    --textbox ~/.my.cnf 16 60
fi
fi

if test -z "$PACKER" ; then
   UNPACKER=cat
else
   UNPACKER=$(echo "$PACKER" | sed -e "s/ .*/ $UNPACKOPT/")
fi

case $(echo "$UNPACKER" | sed -e "s/ .*//") in
   cat) PACK_SUFFIX="sql"
        ;;
  gzip) PACK_SUFFIX="gz"
        ;;
 bzip2) PACK_SUFFIX="bz2"
        ;;
     *) PACK_SUFFIX="sql"
        ;;
esac

# number of lines per screen
MAX_LINES=25

# how many lines maximum for display in the inputbox?
IBOXLINES=$(($MAX_LINES - 9))

#################################################################
# 
# check for a running mysqld and if we have access at all

MYDEAMON=$(ps ax | grep 'mysqld' - | grep -v 'grep' - | head -n 1)
if test -z "$MYDEAMON" -a "$MYSQLHOST" = "localhost" ; then
   $DLGPRG --title "Startup ERROR:" \
      --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
      --msgbox "As it seems there is no 'mysqld' deamon running. \
dbtool is a user frontend to MySQL and will not run without it." \
      8 40
   echo ; exit 1
fi
unset MYDEAMON

if ! mysqlshow $HOSTPRMS >/dev/null 2>&1 ; then
   $DLGPRG --title "Error:" \
      --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
      --msgbox "unable to contact mysqld with option \"$HOSTPRMS\". \
Check settings in ~/.db.rc and ~/.my.cnf" \
      8 40
   echo ; exit 1
fi

MYSQLDVER=$(mysql --version $HOSTPRMS)

$DLGPRG --title "Info" \
   --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
   --infobox "\ndbtool is under the GNU General Public License.\n\
There is absolutely no warranty.\n\n\
Connecting to mysqld on server $MYSQLHOST using\n\
$MYSQLDVER" 10 70
sleep $INFOTIME
unset MYSQLDVER

# If there is a database from the command line, then there is 
# no need to ask for a name.
# Assume the first parameter is the name of the database
# check it; use this one if it's valid
if test -n "$1" ; then
   if mysqlshow $HOSTPRMS "$1" >/dev/null 2>&1 ; then
      DBASE=$1
      shift 1
   else
      DBASE=""
   fi
fi

# get the default database for this user
if test -r $UCNF ; then
   LAST_DB=$(cat $UCNF | sed -e "/# default_database /!d" \
                             -e "s/# default_database //")
fi

if test "$LAST_RULES" = yes -a -n "$LAST_DB" ; then
   DEFAULT_DB="$LAST_DB"
fi

if test -z "$DBASE" ; then

   AVDB=$(mysqlshow $HOSTPRMS | sed \
      -e "/^+--*/d" -e "/^| Databases  *|/d" \
      -e "s/^|  *//" -e "s/  *|/ off/" | sed \
      -e "/^${DEFAULT_DB} off$/s/ off$/ on/" | cat -b - )

   DIALEN=$(echo "$AVDB" | wc --lines)
   if test $(($DIALEN)) -gt $((12)) ; then
      DIALEN=12
   fi
   DIABOX=$(($DIALEN + 7))
   $DLGPRG --title "Select database" \
          --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
          --radiolist "available databases are:" \
          $DIABOX 40 $DIALEN $AVDB 2>${TMPFILE}.dia
   RETVAL=$?
   DIA=$(cat ${TMPFILE}.dia)
   DBASE=$(echo "$AVDB" | sed -e "/^ *$DIA	/!d" \
         -e "s/^ *$DIA	//" -e "s/  *o[nf]f*$//")

   if test "$RETVAL" = 255 -o "$RETVAL" = 1 ; then
      echo ; exit 1
   fi

   if test -z "$DBASE" ; then
      if test -n "$DEFAULT_DB" ; then
         DBASE="$DEFAULT_DB"
      else
         echo ; exit 1
      fi
   else
      if test "$DBASE" != "$DEFAULT_DB" ; then
         DEFAULTTABLE=""
      fi
      if test "$DBASE" != "$LAST_DB" -a -w $UCNF ; then
         cat $UCNF | sed \
           -e "/^# default_database .*$/d" >${TMPFILE}.db
         cp ${TMPFILE}.db $UCNF ; rm -f ${TMPFILE}.db
         echo "# default_database $DBASE" >> $UCNF
      fi
   fi

   if ! mysqlshow $HOSTPRMS $DBASE >/dev/null 2>&1 ; then
      $DLGPRG --title "Error:" \
         --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
         --msgbox "could not access database \"$DBASE\"" 6 40
      echo ; exit 1
   fi
fi

# Now we have a database to use;
# get a table name

if test -n "$1" ; then
   if mysqlshow $HOSTPRMS $DBASE "$1" >/dev/null 2>&1 ; then
      DBTBL=$1
      shift 1
   else
      DBTBL=""
   fi
fi

# what was the last table used with the selected database?
if test -r $UCNF ; then
   LAST_TB=$(cat $UCNF | sed -e "/# default_table $DBASE /!d" \
                             -e "s/# default_table $DBASE //")
fi

if test "$LAST_RULES" = yes -a -n "$LAST_TB" ; then
   DEFAULTTABLE="$LAST_TB"
fi

if test -z "$DBTBL" ; then

   if test -z "$TBL_SUFFIX" ; then
      TSSU="zzzYYYxxx"  # dummy, not likely to occur in your data
   else
      TSSU=$TBL_SUFFIX
   fi

   AVDB=$(mysqlshow $HOSTPRMS $DBASE | sed -e "1 d" \
      -e "/$TSSU /d" -e "/^+--*/d" -e "/^| *Tables  *|/d" \
      -e "s/^|  *//" -e "s/  *|/ off/" | sed \
      -e "/^${DEFAULTTABLE} off$/s/ off$/ on/" | cat -b - )
   unset TSSU

   if test -n "$AVDB" ; then
      DIALEN=$(echo "$AVDB" | wc --lines)
      if test $(($DIALEN)) -gt $((12)) ; then
         DIALEN=12
      fi
      DIABOX=$(($DIALEN + 7))
      $DLGPRG --title "Select table" \
             --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
             --radiolist "available tables are" \
             $DIABOX 40 $DIALEN $AVDB 2>${TMPFILE}.dia
      RETVAL=$?
      if test "$RETVAL" = 255 -o "$RETVAL" = 1 ; then
         echo ; exit 1
      fi
      DIA=$(cat ${TMPFILE}.dia)

      DBTBL=$(echo "$AVDB" | sed -e "/^ *$DIA	/!d" \
            -e "s/^ *$DIA	//" -e "s/  *o[nf]f*$//")

      if test -n "$DBTBL" -a "$DBTBL" != "$LAST_TB" -a -w $UCNF ; then
         cat $UCNF | sed \
            -e "/^# default_table $DBASE .*$/d" > ${TMPFILE}.db
         cp ${TMPFILE}.db $UCNF ; rm -f ${TMPFILE}.db
         echo "# default_table $DBASE $DBTBL" >> $UCNF
      fi

      if ! mysqlshow $HOSTPRMS $DBASE $DBTBL >/dev/null 2>&1 ; then
         $DLGPRG --title "Error:" \
         --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
         --msgbox "could not access table \"$DBTBL\" \
                   using database \"$DBASE\"" \
         6 40
         echo ; exit 1
      fi
   else
      DBTBL='<none>'
   fi
fi


#################################################################
# define some functions to make life easier

errlog() {
   # check for a lockfile; someone else might be writing to the log
   while test -e $LINK_DIR/db-log.lock ; do
      sleep 1
   done
   # create the lockfile
   echo $$ >$LINK_DIR/db-log.lock
   NOW=$(date)
   if test -z "$MYSQLUSR" ; then
      ERRUSR=\'\'
   else
      ERRUSR=$MYSQLUSR
   fi
   echo "$NOW pid=$$ $USERNAME@$HOSTNAME-->$ERRUSR@$MYSQLHOST" \
         >>$LINK_DIR/$LOG_FILE
   echo -e "> $1\n" >>$LINK_DIR/$LOG_FILE
   rm -f $LINK_DIR/db-log.lock
}


getquery() {
   # help typing in: make clever assumptions for the template:
   # bug: (to do:) should allow for EXPLAIN SELECT syntax
   if test -r $UCNF ; then
      LAST_SE=$(cat $UCNF \
         | sed -e  "/^# default_selct $DBASE $DBTBL /!d" \
               -e "s/^# default_selct $DBASE $DBTBL //")
   fi
   if test -z "$LAST_SE" ; then
      LAST_SE='*'
   fi

   if test -r $UCNF ; then
      LAST_WF=$(cat $UCNF \
         | sed -e  "/^# default_whfld $DBASE $DBTBL /!d" \
               -e "s/^# default_whfld $DBASE $DBTBL //")
   fi
   if test -z "$LAST_WF" ; then
      LAST_WF='<fieldname>'
   fi

   if test -r $UCNF ; then
      LAST_WH=$(cat $UCNF \
         | sed -e  "/^# default_where $DBASE $DBTBL /!d" \
               -e "s/^# default_where $DBASE $DBTBL //")
   fi
   if test -z "$LAST_WH" ; then
      LAST_WH="$LAST_WF like '%'"
   fi

   # get FROM table_references
   if test -r $UCNF ; then
      LAST_FR=$(cat $UCNF \
         | sed -e  "/^# default_from $DBASE $DBTBL /!d" \
               -e "s/^# default_from $DBASE $DBTBL //")
   fi
   if test -z "$LAST_FR" ; then
      LAST_FR=$DBTBL
   fi


   LAST_QY="SELECT $LAST_SE FROM $LAST_FR WHERE $LAST_WH"

   showlabels "$LAST_QY;"
   QUERY=$(cat ${TMPFILE}.dia)
   rm -f ${TMPFILE}.dia

   if test "$QUERY" = q -o "$QUERY" = Q ; then
      QUERY=""
   fi

   # revise assumptions according this query if not empty
   if test -n "$QUERY" ; then
   QUERY=$(echo "$QUERY" | sed -e "$ s/ *;* *$/;/")
   # made sure that there is one `;' at the end

   # arguments to the SELECT statement (select_expression)
   # up to FROM
   SELFIELDS=$(echo "$QUERY" | sed \
      -e "s/^ *[Ss][Ee][Ll][Ee][Cc][Tt]  *//" \
      -e "s/  *[Ff][Rr][Oo][Mm] .*//")
   if test "$LAST_SE" != "$SELFIELDS" -a -w $UCNF ; then
      cat $UCNF | sed \
        -e "/^# default_selct $DBASE $DBTBL .*$/d" > ${TMPFILE}.db
      cp ${TMPFILE}.db $UCNF ; rm -f ${TMPFILE}.db
      echo "# default_selct $DBASE $DBTBL $SELFIELDS" >> $UCNF
      #echo "updating SELFIELDS as $SELFIELDS"
   fi

   # the table references
   FRMFIELDS=$(echo "$QUERY" | sed \
      -e "s/^.* [Ff][Rr][Oo][Mm]  *//" \
      -e "s/ *[Ss][Ee][Ll][Ee][Cc][Tt] .*//" \
      -e "s/  *[Ww][Hh][Ee][Rr][Ee] .*$//" \
      -e "s/ *; *$//")
   if test "$LAST_FR" != "$FRMFIELDS" -a -w $UCNF ; then
      cat $UCNF | sed \
        -e "/^# default_from $DBASE $DBTBL .*$/d" > ${TMPFILE}.db
      cp ${TMPFILE}.db $UCNF ; rm -f ${TMPFILE}.db
      echo "# default_from $DBASE $DBTBL $FRMFIELDS" >> $UCNF
   fi

   # the complete WHERE clause with everything after it
   CONFIELDS=$(echo "$QUERY" | sed \
      -e "s/^.* [Ww][Hh][Ee][Rr][Ee]  *//" \
      -e "s/ *[Ss][Ee][Ll][Ee][Cc][Tt] .*//" \
      -e "s/ *; *$//")
   if test "$LAST_WH" != "$CONFIELDS" -a -w $UCNF ; then
      cat $UCNF | sed \
        -e "/^# default_where $DBASE $DBTBL .*$/d" > ${TMPFILE}.db
      cp ${TMPFILE}.db $UCNF ; rm -f ${TMPFILE}.db
      echo "# default_where $DBASE $DBTBL $CONFIELDS" >> $UCNF
   fi

   # a valid fieldname from $DBTBL
   WHEREFIELD=$(echo "$QUERY" | sed \
      -e "s/^.* [Ww][Hh][Ee][Rr][Ee]  *//" \
      -e "s/ *[Ss][Ee][Ll][Ee][Cc][Tt] .*//" \
      -e "s/[ =><].*//" )
   LBLS=$(echo "show columns from $DBTBL ;" \
       | mysql --batch $HOSTPRMS $DBASE \
       | sed -e "1 d" -e "s/	.*$//") # there is a <TAB> !
   WF=""
   for FN in $LBLS ; do
      if test "$WHEREFIELD" = $FN ; then
         WF="$FN"
         break 1
      fi
   done
   if test "$LAST_WF" != "$WF" -a -n "$WF" -a -w $UCNF ; then
      cat $UCNF | sed \
         -e "/^# default_whfld $DBASE $DBTBL .*$/d" > ${TMPFILE}.db
      cp ${TMPFILE}.db $UCNF ; rm -f ${TMPFILE}.db
      echo "# default_whfld $DBASE $DBTBL $WF" >> $UCNF
   fi

   fi # QUERY was not empty
}


preplbls() {
   LBLS=$(echo "show columns from $DBTBL ;" \
          | mysql --batch $HOSTPRMS $DBASE \
          | sed -e "1 d" -e "s/	.*$//")
   # want them nicely in columns; trim to the same length
   # pick the longest one, make a blank template
   # add blanks and trim to length
   LT=$(echo "$LBLS" | sed -e "s/././g" | sort | tail -n 1)
   LBLS=$(echo "$LBLS" | sed -e "s/$/#.$LT /")
   LBLS=$(echo "$LBLS" | sed -e "s/^\\($LT..\\).*/\\1/")
   echo $LBLS | fold -s -w 73 | sed -e "s/ $//" -e "s/#/ /g"
   }


showlabels() {
   SLBLS=$(preplbls)
   # if there are too many lines we have to cut
   LBLPROMPT=$(echo "$SLBLS" | head -n $IBOXLINES - )
   LBLCNT=$(echo "$LBLPROMPT" | wc --lines | sed "s/^ *//")
   LBLCNT=$(($LBLCNT + 7))
   $DLGPRG --title "Enter / edit SQL SELECT-Query for table $DBTBL" \
    --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
    --inputbox "$LBLPROMPT" $LBLCNT 75 "$1" 2>${TMPFILE}.dia
   }


search() { echo "$QUERY" \
           | mysql $HOSTPRMS --vertical $DBASE \
           1>$TMPFILE 2>${TMPFILE}.err
           RST=$(cat ${TMPFILE}.err | fold -s -w 72)
           rm -f ${TMPFILE}.err ; }


chgtable() {
   AVDB=$(mysqlshow $HOSTPRMS $DBASE | sed -e "1 d" \
      -e "/^+--*/d"   -e "/^| *Tables  *|/d" \
      -e "s/^|  *//"  -e "s/  *|/ off/" | sed \
      -e "/^${LAST_TB} off$/s/ off$/ on/" | cat -b - )

   if test -n "$AVDB" ; then
      DIALEN=$(echo "$AVDB" | wc --lines)
      if test $(($DIALEN)) -gt $((12)) ; then
         DIALEN=12
      fi
      DIABOX=$(($DIALEN + 7))

      $DLGPRG --title "Select table" \
             --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
             --radiolist "available tables are" \
             $DIABOX 40 $DIALEN $AVDB 2>${TMPFILE}.dia
      DIA=$(cat ${TMPFILE}.dia)
      DBTBL=$(echo "$AVDB" | sed -e "/^ *$DIA	/!d" \
            -e "s/^ *$DIA	//" -e "s/  *o[nf]f*$//")

      if test -n "$DBTBL" -a "$DBTBL" != "$LAST_TB" -a -w $UCNF ; then
         cat $UCNF | sed \
            -e "/^# default_table $DBASE .*$/d" > ${TMPFILE}.db
         cp ${TMPFILE}.db $UCNF ; rm -f ${TMPFILE}.db
         echo "# default_table $DBASE $DBTBL" >> $UCNF
      fi

      if test -z "$DBTBL" ; then
         DBTBL='<none>'
      elif ! mysqlshow $HOSTPRMS $DBASE $DBTBL >/dev/null 2>&1 ; then
         $DLGPRG --title "Error:" \
         --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
         --msgbox "could not access table \"$DBTBL\" \
                   using database \"$DBASE\"" \
         6 40
         echo ; exit 1
      fi
   else
      DBTBL='<none>'
      $DLGPRG --title "Information:" \
         --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
         --infobox "Database $DBASE is empty. Use \"create table\" \
command. For the time table is set to <none>" 7 40
      sleep $INFOTIME
      sleep $INFOTIME
   fi
}


# check for a log file containing all changes for this table
# this db script uses the following conventions:
#    every table may have a shadow table named <table_$TBL_SUFFIX>
#    where $TBL_SUFFIX is a default value.
#    This shadow table will be used to log all changes to the
#    main table giving a complete history.

chklogtbl() {
#   bullshit! Does not work with mysqlshow; it will give
#   a return code for success even if there is no such table
#   when it contains a joker like the underscore;
#   if mysqlshow $HOSTPRMS $DBASE ${DBTBL}$TBL_SUFFIX >/dev/null 2>&1
#
   if echo "show columns from ${DBTBL}$TBL_SUFFIX;" \
      | mysql $HOSTPRMS $DBASE >/dev/null 2>&1
   then
      TBL_LOG="${DBTBL}$TBL_SUFFIX"
   else
      TBL_LOG=""
   fi ; }


# make a label template to add new data
# get a list of all column names first
# replace every character with a dot, sort lengths, take longest
# append a row of blanks to every label
# cut the length adding a colon ':' into the blanks
# cat away : and trailing blanks
# swap blanks and label name and add a colon again
# sets variable TSTMP as well containing column names of TIMESTAMP columns

lbltmpl() { TD=$(echo "show columns from $DBTBL ;" \
               | mysql --batch $HOSTPRMS $DBASE \
               | sed -e "1 d")
            LB=$(echo "$TD" | sed -e "s/	.*$//")
            TSTMP=$(echo "$TD" | sed -e '/timestamp([0-9][0-9]*)/!d' \
               -e "s/	.*$//")
            LBCUT=$(echo "$LB" | sed -e "s/././g" | sort | tail -n 1)
            LBFIL=$(echo "$LBCUT" | sed -e "s/./ /g")
            LB=$(echo "$LB" | sed -e "/^./s/$/$LBFIL/" \
               -e "/^./s/^$LBCUT/&:/" -e "/^./s/: *$//" \
               -e "/^./s/\\(^[^ ][^ ]*\\)\\( *\\)/>\\2\\1: /")
          }


# Convert one file with labels and data into an SQL statement.
# Put the data into the current table and get the unique
# number used for the auto_increment field;
#
# detects timestamp() columns using $TSTMP as set by lbltmpl()

toins() { # preprocess for timestamp() columns
          # timestamp() columns are set to NOW() irrespective of what
          # they were to make it foolproof (is this useful?)
          DATA=$(cat $1)
          for TSTLBL in "$TSTMP" ; do
             DATA=$(echo "$DATA" | sed -e "/^> *$TSTLBL:/s/:.*/: NOW()/")
          done
          # convert to VALUES format
          # the last line allows to enter some simple formulae 
          # like WEEKDAY('1997-11-05') or even DAYNAME(CURDATE())
          # but functions MUST be in ALL_CAPS
          DATA=$(echo "$DATA" | sed \
          -e "/^ *$/d" -e "s/^>[^:]*:  *//" \
          -e "s/'/\\\\'/g" -e "s/^.*$/'&',/" \
          -e "s/'NOW()'/NOW()/" \
          -e "s/\\('\\)\\([A-Z_][A-Z_]*([\" _,:A-Z0-9(-]*))*\\)\\(',\\)$/\\2,/")
          # reduce to one line and yank the last comma
          DATA=$(echo $DATA | sed -e "s/,$//")
          QUERY="$INSCMD INTO $DBTBL VALUES ($DATA); SELECT LAST_INSERT_ID();"
          # if there's an error we write a folded version of QUERY
          # to the $LOG_FILE file. This may fold within data strings
          # and may not be applied to the real query.
          DATA_LOG=$(echo $DATA | sed -e "s/,$//" | fold -s -w 72)
          QUERY_LOG="$INSCMD INTO $DBTBL VALUES
($DATA_LOG);
SELECT LAST_INSERT_ID();"
          if ! INSID=$(echo "$QUERY" \
             | mysql $HOSTPRMS $DBASE 2>&1) ; then
             QUERY=$(echo "$QUERY" | sed -e "s/\\\\/\\\\\\\\/g")
             errlog "toins(): error inserting data with query:\n\
>$QUERY_LOG\nresulted in message:\n$INSID"
             $DLGPRG --title "Insert into table $DBTBL" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --msgbox "ERROR inserting data. Nothing has been \
                        inserted into table $DBTBL." 7 40
          elif test -n "$TBL_LOG" ; then
             # get result of SELECT LAST_INSERT_ID()
             LAST_ID=$(echo "$INSID" | tail -n 1)
             INC_LBL=$(echo "show columns from $DBTBL ;" \
                | mysql --batch $HOSTPRMS $DBASE \
                | sed -e "/auto_increment/!d" \
                      -e "s/	.*$//") # the blank is a tab
             DIFF=$(echo "SELECT * FROM $DBTBL WHERE $INC_LBL=$LAST_ID" \
                | mysql --vertical $HOSTPRMS $DBASE \
                | sed -e "1 d" -e "s/^ *//" -e "s/'/\\\\'/g" \
                  -e "s/: */='/" -e "s/^..*$/&',/" -e "$ s/,$//")
             ADDIFF="$LOG_OPS='$NEW', $LOG_USR='$USERNAME', $DIFF"
             QUERY="$INSCMD INTO $TBL_LOG SET $ADDIFF ;"
             if ! RST=$(echo "$QUERY" \
                | mysql $HOSTPRMS $DBASE 2>&1) ; then
                errlog "toins(): error inserting $TBL_SUFFIX \
data with query:\n\>$QUERY\n>resulted in message:\n>$RST"
             fi
          fi
        }


unique() { PKLINE=$(echo "show columns from $DBTBL ;" \
           | mysql --batch $HOSTPRMS $DBASE | sed -e "/	PRI	/!d")
           PRIKEY=$(echo "$PKLINE"  | sed -e "s/	.*$//")
            #echo "Primary key = $PRIKEY" ; sleep 20
           PKTYPE=$(echo "$PKLINE" | sed \
             -e "s/[^	]*	//" -e "s/(.*//" )
            #echo "Type of primary key = $PKTYPE"
           case $PKTYPE in
              char|varchar|text)
                   CPCLAUSE="like '"
                   CPTERMIN="' ;"
                   ;;
              *)   CPCLAUSE="= "
                   CPTERMIN=" ;"
                   ;;
           esac
         }


# update works on two files: $TMPFILE and ${TMPFILE}.bak
#        ${TMPFILE}.bak is the result of a SELECT command and
#        $TMPFILE is a partly edited version of it.
# the task is to update the database with the changed records.
# update has to extract rows from the files to compare them.
# it checks how many records there are.
#
# for every record do
#     extract the record data from original and changed files
#     list the differences and clean them up
#     compile and execute the query
# done
# (sorry, this is SLOW)

update() { NREC=$(cat $TMPFILE | sed -e "/^\\*\\** [0-9]/!d" \
              | wc --lines | sed -e "s/^ *//")
              # echo -n "handling $NREC records: "
   # paste two files together joining 2 corresponding
   #    lines on one line;
   # mask all quote characters (these are delimiters for SQL);
   #    two backslashes are needed because one is lost when
   #    reading in for $INLINE later;
   # change record separator lines deleting the first one
   #    and adding another separator at the end;
   # clean up blanks around the field separator and at the beginning
   #    and the end of each line;
   paste -d\| $TMPFILE ${TMPFILE}.bak | sed \
      -e "1 d" -e "s/'/\\\\\\\\'/g" \
      -e "/^\\*\\** [1-9][0-9]*\\. row \\*/s/^.*$/---/" \
      -e "s/^ *//" -e "s/ *| */|/" -e "s/ *$//" > ${TMPFILE}.join
   echo "---" >> ${TMPFILE}.join
   unique
   cat /dev/null > ${TMPFILE}.1
   cat /dev/null > ${TMPFILE}.2
   COUNT=0
   rm -f ${TMPFILE}.err

   ( while read INLINE ; do
      # if this is not a record separator line then
      #    just temporarily save the data 
      # else split lines into two parts; compare;
      #    write changed records to table.

      if test "$INLINE" != "---" ; then
         echo "$INLINE" >> ${TMPFILE}.1
      else
         COUNT=$(($COUNT + 1)); PCENT=$(($COUNT * 100 / $NREC))
         cat ${TMPFILE}.1 | cut -f 1 -d '|' > ${TMPFILE}.2
         if ! cat ${TMPFILE}.1 | cut -f 2 -d '|' \
               | diff --ignore-space-change --brief \
               ${TMPFILE}.2 - >/dev/null 2>&1 ; then
            # files differ
            DIFF=$(cat ${TMPFILE}.2 | sed -e "/^$/d" | sed \
               -e "s/: */='/" -e "s/^..*$/&',/" -e "$ s/,$//" )
            KEYDAT=$(cat ${TMPFILE}.2 | sed \
               -e "/^$PRIKEY/!d" -e "s/^[^:]*: *//")
            QUERY="$UPDCMD $DBTBL SET $DIFF \
               WHERE ${PRIKEY} ${CPCLAUSE}${KEYDAT}${CPTERMIN}"
            if ! RST=$(echo "$QUERY" | mysql $HOSTPRMS $DBASE 2>&1) ; then
               errlog "update(): error inserting data with query:\n\
>$QUERY\n>resulted in message:\n>$RST"
               touch ${TMPFILE}.err
            fi
            if test -n "$TBL_LOG" ; then
               ADDIFF="$LOG_OPS='$CHANGED', $LOG_USR='$USERNAME', "
               QUERY="$INSCMD INTO $TBL_LOG SET ${ADDIFF}${DIFF} ;"
               if ! RST=$(echo "$QUERY" | mysql $HOSTPRMS $DBASE 2>&1 ); then
                  errlog "update(): error inserting $TBL_SUFFIX data \
with query:\n>$QUERY\nresulted in message:\n>$RST"
                  touch ${TMPFILE}.err
               fi
            fi
            echo "XXX"
            echo "$PCENT"
            echo "\n              updating $COUNT"
            echo "XXX"
         else
            echo "XXX"
            echo "$PCENT"
            echo "\n              scanning unmodified records"
            echo "XXX"
         fi
         cat /dev/null > ${TMPFILE}.1
         cat /dev/null > ${TMPFILE}.2
      fi
   done < ${TMPFILE}.join ) | \
      $DLGPRG --title "Update table $DBTBL $NREC records" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --guage "updating ..." 8 58 0

   rm -f ${TMPFILE}.1 ${TMPFILE}.2 ${TMPFILE}.bak \
         $TMPFILE ${TMPFILE}.join

   if test -e ${TMPFILE}.err ; then
      rm -f ${TMPFILE}.err
      $DLGPRG --title "Update table $DBTBL $NREC records" \
        --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
        --msgbox "An ERROR occurred while updating. \
                  Please check the logfile $LINK_DIR/$LOG_FILE \
                  for details." 8 58
   fi
}


# delete() reads $TMPFILE and deletes every record contained
# in it provided there is a primary key column available.
# Deleted records are added to the log-file

delete() { NREC=$(cat $TMPFILE | sed -e "/^\\*\\** [0-9]/!d" \
                | wc --lines | sed -e "s/^ *//")
   errlog "delete operation on $NREC records"
   unique
   cat /dev/null > ${TMPFILE}.1
   cat /dev/null > ${TMPFILE}.2
   cat $TMPFILE | sed \
      -e "1 d" -e "s/'/\\\\\\\\'/g" \
      -e "/^\\*\\** [0-9]/s/^.*$/---/" \
      -e "s/^ *//" > ${TMPFILE}.1
   echo "---" >> ${TMPFILE}.1
   COUNT=0
   rm -f ${TMPFILE}.err

   ( while read INLINE ; do
      if test "$INLINE" != "---" ; then
         echo "$INLINE" >> ${TMPFILE}.2
      else
         COUNT=$(($COUNT + 1)); PCENT=$(($COUNT * 100 / $NREC))
         KEYDAT=$(cat ${TMPFILE}.2 | sed \
            -e "/^$PRIKEY/!d" -e "s/^[^:]*: *//")
         if test -n "$KEYDAT" ; then
            # something to delete; but first get it (if there's a log)
            if test -n "$TBL_LOG" ; then
               # get all columns of previous record from table
               QUERY="SELECT * FROM $DBTBL \
                      WHERE $PRIKEY $CPCLAUSE$KEYDAT$CPTERMIN"
               DDAT=$(echo "$QUERY" \
                      | mysql --vertical $HOSTPRMS $DBASE 2>/dev/null)
            fi

            # do the delete operation
            QUERY="DELETE FROM $DBTBL WHERE $PRIKEY $CPCLAUSE$KEYDAT$CPTERMIN"
            if ! RST=$(echo "$QUERY" | mysql $HOSTPRMS $DBASE 2>&1) ; then
               errlog "update(): error deleting data with query:\n\
>$QUERY\n>resulted in message:\n>$RST"
               touch ${TMPFILE}.err
            elif test -n "$TBL_LOG" -a -n "$DDAT" ; then
               # write previous record into _log table
               DIFF=$(echo "$DDAT" | sed -e "/^\\*\\** [0-9]/d" \
                  -e "s/'/\\\\\\\\'/g" -e "s/^ *//" \
                  -e "s/: */='/" -e "/='$/d" \
                  -e "s/^..*$/&',/" | sed -e "$ s/,$//" )
               ADDIFF="$LOG_OPS='$DELETED', $LOG_USR='$USERNAME', "
               QUERY="$INSCMD INTO $TBL_LOG SET ${ADDIFF}${DIFF} ;"
               if ! RST=$(echo "$QUERY" | mysql $HOSTPRMS $DBASE 2>&1 ); then
                  errlog "delete(): error inserting $TBL_SUFFIX data \
with query:\n>$QUERY\nresulted in message:\n>$RST"
                  touch ${TMPFILE}.err
               fi
            fi
            echo "XXX"
            echo "$PCENT"
            echo "\n              deleting $COUNT ... "
            echo "XXX"
         else
            echo "XXX"
            echo "$PCENT"
            echo "\n              skipping modified records"
            echo "XXX"
         fi
         cat /dev/null > ${TMPFILE}.2
      fi
   done < ${TMPFILE}.1 ) | \
      $DLGPRG --title "Delete $NREC records from table $DBTBL" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --guage "updating ..." 8 58 0


   rm -f ${TMPFILE}.1 ${TMPFILE}.2 ${TMPFILE}.bak $TMPFILE

   if test -e ${TMPFILE}.err ; then
      rm -f ${TMPFILE}.err
      $DLGPRG --title "Update $NREC records from table $DBTBL" \
        --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
        --msgbox "An ERROR occurred while deleting. \
                  Please check the logfile $LINK_DIR/$LOG_FILE \
                  for details." 8 58
   fi
}


isalog() { 
        # do not allow to add directly to log tables
        # or to edit them
        LMASK=$(echo "$TBL_SUFFIX" | sed 's/././g')
        TBSUF=$(echo $DBTBL | sed -e "s/\\(.*\\)\\($LMASK$\\)/\\2/")
        # if someone undef'd the suffix
        if test -z "$TBL_SUFFIX" ; then
           $DLGPRG --title "Error:" \
                  --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                  --msgbox '$TBL_SUFFIX is undefined' 5 40
           ADDFLG=quit
        # lets see if we are trying to add directly to
        # a logfile. This is not permitted.
        elif test "$TBSUF" = "$TBL_SUFFIX" ; then
           errlog "attempt to add to logfile $DBTBL"
           $DLGPRG --title "Add new records to $DBTBL" \
                  --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                  --msgbox "ERROR: Can't add to a log table" 6 40
           ADDFLG=quit
        fi
}


#################################################################
# Menu of special commands
specials () {
SC=""

ACTIVE="$DBASE.$DBTBL is active"

$DLGPRG --title "Special commands" \
       --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
       --menu "$ACTIVE" 20 60 13 \
c "create a logfile for table $DBTBL" \
d "drop the logfile for table $DBTBL" \
i "import from data file" \
k "backup database $DBASE" \
l "define link dependencies for table $DBTBL" \
m "make a new database" \
n "create a new table" \
o "drop (=delete) table $DBTBL" \
p "drop (=delete) database $DBASE" \
r "restore database $DBASE from backup" \
s "show status for $DBTBL" \
w "write mass mail letters" \
q "quit special commands"  2>${TMPFILE}.dia


SC=$(cat ${TMPFILE}.dia)

if test -z "$SC" ; then
   SC=q
fi

# handle the special case with no table
case $SC in
c|d|l|o|s|w)
   if test $DBTBL = '<none>' ; then
      $DLGPRG --title "Warning:" \
             --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
             --infobox "No table is selected. Use 'create a new table' \
                        from the special commands \
                        or select a table" 6 40
      SC=noop
      sleep $WARNTIME
   fi
esac

case "$SC" in
        #
        # create a logfile
   c|C) LMASK=$(echo "$TBL_SUFFIX" | sed 's/././g')
        TBSUF=$(echo $DBTBL | sed -e "s/\\(.*\\)\\($LMASK$\\)/\\2/")

        # if someone undef'd the suffix
        if test -z "$TBL_SUFFIX" ; then
           $DLGPRG --title "Error:" \
                  --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                  --msgbox '$TBL_SUFFIX is undefined' 5 40

        # lets see if we are trying to make a logfile for
        # a logfile. This is not permitted.
        elif test "$TBSUF" = "$TBL_SUFFIX" ; then
           $DLGPRG --title "Error:" \
                  --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                  --msgbox "$DBTBL is a logfile itself;\n\
cannot make a logfile for it!" 6 40

        # if a logfile exists then we are not going to make one
        elif test -n "$TBL_LOG" ; then
           $DLGPRG --title "Warning:" \
                  --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                  --msgbox "$TBL_LOG exists; can not create" 6 40

        # lets go ahead
        # make a description for the log table
        else
        mysqldump $HOSTPRMS --add-drop-table --no-data \
           $DBASE $DBTBL | sed \
           -e "/# Table structure/s/$DBTBL/$DBTBL$TBL_SUFFIX/" \
           -e "/DROP TABLE/s/$DBTBL/$DBTBL$TBL_SUFFIX/" \
           -e "/CREATE TABLE/s/$DBTBL/$DBTBL$TBL_SUFFIX/" \
           -e "s/ auto_increment//" \
           -e "/^  PRIMARY KEY /s/(.*)/($LOG_REC)/" \
           -e "/CREATE TABLE /a\\
  $LOG_REC int(6) DEFAULT '0' NOT NULL auto_increment,\\
  $LOG_OPS char(1) DEFAULT '' NOT NULL,\\
  $LOG_USR varchar(255) DEFAULT '' NOT NULL,\\
  $LOG_CHG TIMESTAMP(14)," > ${TMPFILE}.tbl
           if cat ${TMPFILE}.tbl | mysql $HOSTPRMS $DBASE ; then
              TBL_LOG="${DBTBL}$TBL_SUFFIX"
              errlog "created log table $DBASE.$TBL_LOG"
              $DLGPRG --title "Information:" \
                  --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                  --infobox "Creating table $TBL_LOG" 5 40
              sleep $INFOTIME
           else
              $DLGPRG --title "Error:" \
                  --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                  --msgbox "Could not create table $TBL_LOG;\
                             some error occurred." 6 40
           fi
           rm -f ${TMPFILE}.tbl
        fi
        ;;


        #
        # drop log table
   d|D) if test -n "$TBL_LOG" -a -n "$TBL_SUFFIX" ; then
           $DLGPRG --title "Drop table $TBL_LOG" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --inputbox "Are you nuts?\n\
Warning: All data from $TBL_LOG\n\
         will be lost.\n\n\
Enter your username:" 12 40  2>${TMPFILE}.dia
           FC=$(cat ${TMPFILE}.dia)
           if test "$FC" = "$USERNAME" ; then
              if echo "DROP TABLE IF EXISTS ${DBTBL}$TBL_SUFFIX ;" \
                 | mysql $HOSTPRMS $DBASE 2>&1 ; then
                 $DLGPRG --title "Drop table $TBL_LOG" \
                    --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                    --infobox "ok, dropping table $TBL_LOG" 5 40
                 errlog "dropped table $DBASE.$TBL_LOG"
                 sleep $INFOTIME
                 TBL_LOG=""
              else
                 $DLGPRG --title "Drop table $TBL_LOG" \
                    --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                    --msgbox "ERROR dropping table $TBL_LOG" 5 40
              fi
           else
              $DLGPRG --title "Drop table $TBL_LOG" \
                 --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                 --infobox "keeping table $TBL_LOG" 5 40
              sleep $INFOTIME
           fi
        else
           $DLGPRG --title "Drop table $TBL_LOG" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --msgbox "ERROR: there is no log table for $DBTBL \
                        or \$TBL_SUFFIX is unset" 7 40
        fi
        ;;


	# import from data file
	#
   i|I) $DLGPRG --title "Import from data file" \
          --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
          --msgbox "\n\n           This function is not yet supported" 10 60
	;;


        # make a backup of the current database
        #
   k|K) CURDIR=$(pwd)
        $DLGPRG --title "Backup database $DBASE" \
          --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
          --inputbox "A backup copy of the $DBASE database will be \
written to the current directory of your local host. \
The user may enter any other target directory \
but must have write permission." 13 60 "$CURDIR/" \
        2>${TMPFILE}.dia
        RETVAL=$?
        if test $RETVAL = 0 ; then
           CURDIR=$(cat ${TMPFILE}.dia | sed -e "s/\\/$//")
           FLOPPY=true  # false for mount failure, otherwise always true
           #
           # may be a floppy; mount it if we can; needs /etc/fstab entry
           # like: /dev/fd0  /floppy  auto  noauto,user  0  0
           # if some other user currently accesses /floppy both
           # umount and mount will fail (as it should)
           if test $CURDIR = $FLOPPYDRIVE ; then
              umount $FLOPPYDRIVE >/dev/null 2>&1
              mount $FLOPPYDRIVE >/dev/null 2>&1 || FLOPPY=false
           fi

           if ! test -d "$CURDIR" -a -w "$CURDIR" -a $FLOPPY = true ; then
              $DLGPRG --title "Backup database $DBASE" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --msgbox "ERROR: Directory $CURDIR does not exist \
on host $HOSTNAME or $CURDIR is not writable for user $USERNAME \
or failure to mount floppy drive." 9 50
           else
              # make a backup of the backup if it exists
              OLDBKUP=$(2>/dev/null ls -Bmt $CURDIR/$DBASE.${PACK_SUFFIX}* \
                 | head -n 1 | sed -e "s/, .*//" )
              if test -n "$OLDBKUP" ; then
                 mv -f $OLDBKUP ${OLDBKUP}~ 2>/dev/null
              fi
              errlog "dumped $DBASE to $CURDIR/${DBASE}.${PACK_SUFFIX}"
              if test -n "$PACKER" ; then
                 mysqldump $DUMPOPTS $HOSTPRMS $DBASE \
                 | $PACKER > $CURDIR/${DBASE}.${PACK_SUFFIX} 2>${TMPFILE}.err
                 sync
              else
                 mysqldump $DUMPOPTS $HOSTPRMS $DBASE \
                 > $CURDIR/${DBASE}.${PACK_SUFFIX} 2>${TMPFILE}.err
                 sync
              fi
              sleep 1
              umount $FLOPPYDRIVE >/dev/null 2>&1
              if test -s ${TMPFILE}.err ; then
                 RETMSG=$(cat ${TMPFILE}.err | fold -s -w 60)
                 $DLGPRG --title "Backup database $DBASE" \
                 --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                 --msgbox "ERROR: Could not create backup file\n\
       $CURDIR/${DBASE}.${PACK_SUFFIX}.\n\
Returned message was:\n\n\
$RETMSG" 15 65
              fi
           fi
        fi
        ;;


        #
        # define link dependencies
        #
   l|L) LINK_STATUS=$(cat $LINK_LIST | sed \
           -e "/link_information $DBASE $DBTBL/!d" \
           -e "s/link_information $DBASE $DBTBL */$DBTBL./" \
           -e "s/  */ <is preset from table> /")
        if test -z "$LINK_STATUS" ; then
           LINK_STATUS="No links from table $DBTBL to another table."
        fi
        FIELDS=$(preplbls)
        LSMSG=$(echo -e "${LINK_STATUS}\n${FIELDS}" | head -n 12)

        $DLGPRG --title "Define link dependencies for $DBTBL" \
        --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
        --inputbox "Enter name of field from table $DBTBL to be initialized with data from\n\
another table. Present status is:\n$LSMSG" 21 76 \
        2>${TMPFILE}.dia
        RETVAL=$?
        unset FIELDS LSMSG
        LK_LOC_FN=$(cat ${TMPFILE}.dia)

        if test -n "$LK_LOC_FN" ; then
           OTHTBL=$(mysqlshow $HOSTPRMS $DBASE | sed \
              -e "1 d" -e "/^+--*+/d" -e "/^|  *Tables .*/d" \
              -e "/$TBL_SUFFIX  *|/d" -e "s/^|  *//" \
              -e "s/  *|$//" -e "/$DBTBL/d")
           LSMSG=$(echo $OTHTBL | fold -s -w 60)

           $DLGPRG --title "Define link dependencies for $DBTBL" \
           --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
           --inputbox "These links are defined:\n$LINK_STATUS\n\n\
Defining import of data to $DBTBL.$LK_LOC_FN\n\n\
Tables in $DBASE:\n\
$LSMSG\n\n\
Enter name of other table [<enter> to delete entry]..: " 21 76 \
           2>${TMPFILE}.dia
           RETVAL=$?
           LK_OTH_TB=$(cat ${TMPFILE}.dia)

           if test -z "$LK_OTH_TB" -a $RETVAL = 0 ; then
              # delete entry for this field
              cat $LINK_LIST | sed \
               -e "/link_information $DBASE $DBTBL $LK_LOC_FN/d" >$TMPFILE
               cp $TMPFILE $LINK_LIST
           else
              DBTBL_TMP=$DBTBL
              DBTBL=$LK_OTH_TB
              FIELDS=$(preplbls)
              DBTBL=$DBTBL_TMP
              $DLGPRG --title "Define link dependencies for $DBTBL" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --inputbox "Field names in $LK_OTH_TB:\n$FIELDS\n\
Name of the field the data comes from: " 21 76 \
              2>${TMPFILE}.dia
              RETVAL=$?
              LK_OTH_FN=$(cat ${TMPFILE}.dia)
              if test -n "$LK_LOC_FN" -a $RETVAL = 0 \
                 -a -n "$LK_OTH_TB" -a -n "$LK_OTH_FN" ; then
                 # delete whatever there was for this $LK_LOC_FN
                 cat $LINK_LIST | sed \
                    -e "/link_information $DBASE $DBTBL $LK_LOC_FN/d" \
                    >$TMPFILE
                 cp $TMPFILE $LINK_LIST
                 # and add new entry
                 echo "link_information $DBASE $DBTBL \
$LK_LOC_FN $LK_OTH_TB $LK_OTH_FN" >> $LINK_LIST
              fi
           fi
        fi
        ;;


        # make a new database
        #
   m|M) $DLGPRG --title "Make a new Database" \
          --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
          --inputbox "Enter the name for a new database." 8 60 "" \
        2>${TMPFILE}.dia
        RETVAL=$?
        NEWDBASE=$(cat ${TMPFILE}.dia)
        
        if test "$RETVAL" = 0 -a -n "$NEWDBASE" ; then
           if RV=$(mysqladmin $HOSTPRMS create $NEWDBASE 2>&1) ; then
              $DLGPRG --title "Make a new Database" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --infobox "new database $NEWDBASE created" \
              7 40
              sleep $INFOTIME
           else
              RV=$(echo $RV | sed -e "s///" | fold -s -w 36)
              $DLGPRG --title "Make a new Database" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --msgbox "ERROR creating database $NEWDBASE.\n\
Result was:\n$RV" 10 40
           fi
        fi
        ;;


        #
        # create new table
        #
   n|N) QUIT=no
        # 
TYPECHOICE=" 1 tinyint(3) off
 2 smallint(5) off
 3 mediumint(7) off
 4 int(9) off
 5 bigint(19) off
 6 float(4) off
 7 float(10,9) off
 8 double(17,16) off
 9 decimal(17,16) off
10 char(255) off
11 varchar(255) on
12 date off
13 time off
14 timestamp(14) off
15 datetime off
16 tinyblob off
17 blob off
18 mediumblob off
19 longblob off
20 tinytext off
21 text off
22 mediumtext off
23 longtext off
24 enum('value1','value2','value3') off
25 set('value1','value2','value3') off"

        #
        # get table name
        #
        $DLGPRG --title "Create a new table in database $DBASE" \
          --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
          --inputbox "Enter a name for the new table:" 8 60 "" \
        2>${TMPFILE}.dia
        RETVAL=$?
        NTB_NAME=$(cat ${TMPFILE}.dia)
        if test "$RETVAL" != "0" -o -z "$NTB_NAME" ; then
           QUIT=yes
        fi

        if test $QUIT = no ; then
        # writing the header for the new table
        echo '#' > $TMPFILE
        echo "# Database: $DBASE" >>$TMPFILE
        echo '#' >>$TMPFILE
        echo >>$TMPFILE
        echo '#' >>$TMPFILE
        echo "# Table structure for table '$NTB_NAME'" >>$TMPFILE
        echo '#' >>$TMPFILE
        echo "DROP TABLE IF EXISTS $NTB_NAME;" >>$TMPFILE
        echo "CREATE TABLE $NTB_NAME (" >>$TMPFILE

        #
        # get column names
        #
        $DLGPRG --title "Create a new table in database $DBASE" \
          --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
          --inputbox "Enter the names for all columns in desired order,\n\
all on one line and separated by one blank.\n\n\
Include one column to be used for an automatically numbered\n\
primary key.\n\n\
Column names are:" 14 75 "" \
        2>${TMPFILE}.dia
        RETVAL=$?
        NTB_FIELDS=$(cat ${TMPFILE}.dia)
        if test "$RETVAL" != "0" -o -z "$NTB_FIELDS" ; then
           QUIT=yes
        fi
        ALNUM='A-Za-z0-9_$ '
        COLON=$(echo $NTB_FIELDS | sed -e "s/[$ALNUM]//g")
        if test -n "$COLON" ; then
           $DLGPRG --title "Create a new table in database $DBASE" \
            --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
            --msgbox "ERROR: found non alphanumeric characters \n\
       '$COLON' in column names.\n\
This is not allowed for internal reasons.\n\n\
Press <enter> and select 'create table' function again." 10 60
           QUIT=yes
        fi
        unset COLON
        fi # testing for QUIT=yes

        #
        # select the primary key
        #
        if test $QUIT = no ; then
        RADIO=$(echo $NTB_FIELDS | sed -e "s/  */ /" \
        -e "s/ /\\
/g" | sed -e 's/$/ off/' \
        | sed -e "1 s/off$/on/" | cat -b -)

        $DLGPRG --title "Create a new table in database $DBASE" \
          --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
          --radiolist "One of the columns must be selected as a\n\
primary key for table $NTB_NAME\n\n\
Which one of these columns is the primary key?" 19 60 9 $RADIO \
          2>${TMPFILE}.dia
        RETVAL=$?
        if test "$RETVAL" != "0" ; then
           QUIT=yes
        else
           DIA=$(cat ${TMPFILE}.dia)
           NTB_PRI=$(echo "$RADIO" | sed -e "/^ *$DIA	/!d" \
              -e "s/^ *$DIA	//" -e "s/  *o[nf]f*$//")
        fi
        fi # testing for QUIT=yes


        #
        # pre-fill table column definitions
        #
        if test $QUIT = no ; then
        for NTB_F in $NTB_FIELDS ; do
          if test $NTB_F = $NTB_PRI ; then
             echo "  $NTB_F int(6) DEFAULT '0' NOT NULL auto_increment," \
             >>$TMPFILE
          else
             echo "  $NTB_F varchar(255) DEFAULT '' NOT NULL," >>$TMPFILE
          fi
        done
        echo "  PRIMARY KEY ($NTB_PRI)," >>$TMPFILE
        echo ");" >>$TMPFILE
        fi # testing for QUIT=yes


        #
        # change column types
        #
        if test $QUIT = no ; then
          CHGTYP=yes
          while test $CHGTYP = yes ; do
            # create a template
            RADIO=$(cat $TMPFILE | sed \
            -e "/^  PRIMARY KEY/d" \
            -e "/^#/d" \
            -e "/^$/d" \
            -e "/^DROP TABLE /d" \
            -e "/^CREATE TABLE /d" \
            -e "/);/d" \
            -e "s/^ *//" \
            -e 's/,$/	off/' \
               | sed -e "1 s/	off$/	on/" | cat -b -)

(IFS='	
' # this was a <tab> and a <newline>
            $DLGPRG --title "Create a new table in database $DBASE" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --radiolist "The type of each column may now be changed.\n\
Pick one column to be changed from the list. As a next step,\n\
you will be offered a choice of alternate column types to\n\
select from.\n\n\
This is repeated until you're done and <cancel>." 21 75 9 \
            $RADIO 2>${TMPFILE}.dia
            echo $? >${TMPFILE}.ret
)
            RETVAL=$(cat ${TMPFILE}.ret)
            rm -f ${TMPFILE}.ret

            if test "$RETVAL" = "255" ; then
              QUIT=yes ; CHGTYP=done
            elif test "$RETVAL" = "1" ; then
              CHGTYP=done
            else
              DIA=$(cat ${TMPFILE}.dia)
              NTB_RTC=$(echo "$RADIO" | sed -e "/^ *$DIA	/!d" \
              -e "s/^ *$DIA	//" -e "s/	o[nf]f*$//")
            fi

          if test $QUIT = no -a $CHGTYP = yes ; then
            $DLGPRG --title "Create a new table in database $DBASE" \
            --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
            --radiolist "This column is selected to change the type:\n\n\
  $NTB_RTC\n\n\
Pick the new type from the list:" 19 60 9 \
$TYPECHOICE 2>${TMPFILE}.dia
            RETVAL=$?
            NTB_NTY=$(cat ${TMPFILE}.dia)
            if test "$RETVAL" = "255" ; then
              QUIT=yes ; CHGTYP=done
            elif test "$RETVAL" = "1" ; then
              CHGTYP=done
            else
              # get the desired column type
              NTB_FNP=$(echo "$TYPECHOICE" | sed \
               -e "/^ *$NTB_NTY /!d" \
               -e "s/^ *$NTB_NTY //" -e "s/ .*//")

              # cut off parameters
              NTB_FUNC=$(echo $NTB_FNP | sed -e "s/(..*//")

              # get the current column type
              NTB_OLD=$(echo "$NTB_RTC" | sed -e "s/^[^ ]*//" \
               -e "s/^ *//" -e "s/ ..*//")

              # get the name of current column
              NTB_FOP=$(echo "$NTB_RTC" | sed -e "s/^ *//" \
               -e "s/ ..*//")

              case $NTB_FUNC in
                 char|varchar|tinyblob|blob|mediumblob|longblob|\
tinytext|mediumtext|text|longtext) DEFLT="DEFAULT ''"
                 ;;
                 tinyint|smallint|mediumint|int|bigint) DEFLT="DEFAULT '0'"
                 ;;
                 float|double|decimal) DEFLT="DEFAULT '0.0'"
                 ;;
                 *) DEFLT=" "
              esac

              cat $TMPFILE | sed \
               -e "/^  $NTB_FOP /s/$NTB_OLD/$NTB_FNP/" \
               -e "/^  $NTB_FOP /s/DEFAULT '[.0-9]*'/$DEFLT/" \
               -e "/^  $NTB_FOP /s/   / $DEFLT /" \
               > ${TMPFILE}.bak
              cp ${TMPFILE}.bak $TMPFILE
            fi
          fi
        done
        fi # testing for QUIT=yes


        #
        # indexing columns
        #
        if test $QUIT = no ; then
          CHGTYP=yes
          while test $CHGTYP = yes ; do
            # create a template
            RADIO=$(cat $TMPFILE | sed \
            -e "/^  PRIMARY KEY/d" \
            -e "/^#/d" \
            -e "/^$/d" \
            -e "/^DROP TABLE /d" \
            -e "/^CREATE TABLE /d" \
            -e "/);/d" \
            -e "s/^ *//" \
            -e 's/,$/	off/' \
               | sed -e "1 s/	off$/	on/" | cat -b -)

(IFS='	
'
            $DLGPRG --title "Create a new table in database $DBASE" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --radiolist "\
Columns may be indexed. A table may have up to 16 indexes.\n\
Remember: indexed columns must be declared NOT NULL.\n\
Indexes from multiple columns are not supported by this script\n\
but may be created manually.\n\n\
Select a column to be indexed.\n\
This is repeated until you're done and <cancel>." 21 75 8 \
            $RADIO 2>${TMPFILE}.dia
            echo $? >${TMPFILE}.ret
)

            RETVAL=$(cat ${TMPFILE}.ret)
            rm -f ${TMPFILE}.ret

            if test "$RETVAL" = "255" ; then
              QUIT=yes ; CHGTYP=done
            elif test "$RETVAL" = "1" ; then
              CHGTYP=done
            else
              DIA=$(cat ${TMPFILE}.dia)
              NTB_RTC=$(echo "$RADIO" | sed -e "/^ *$DIA	/!d" \
              -e "s/^ *$DIA	//" -e "s/	o[nf]f*$//")
            fi

            if test $QUIT = no -a $CHGTYP = yes ; then
              N_KEYS=$(cat $TMPFILE | sed -e "/^ *KEY /!d" \
                | wc --lines | sed -e "s/^ *//")
              if test $(($N_KEYS)) -le $((16)) ; then
                # are we on a key line or a column definition?
                NTB_TYP=$(echo "$NTB_RTC" | sed -e "/^ *KEY /!d")
                if test -n "$NTB_TYP" ; then
                  # delete this KEY
                  NTB_FOP=$(echo "$NTB_RTC" | sed -e "s/^ *KEY //" \
                    -e "s/ .*$//")
                  cat $TMPFILE | sed -e "/^ *KEY $NTB_FOP/d" \
                    > ${TMPFILE}.bak
                  cp ${TMPFILE}.bak $TMPFILE
                else
                  # add a new KEY
                  # get the name of current column
                  NTB_FOP=$(echo "$NTB_RTC" | sed -e "s/^ *//" \
                    -e "s/ ..*//")

                  # get the current column type
                  NTB_OLD=$(echo "$NTB_RTC" | sed -e "s/^[^ ]*//" \
                   -e "s/^ *//" -e "s/ ..*//")

                  # cut off parameters
                  NTB_FUNC=$(echo $NTB_OLD | sed -e "s/(..*//")

                  SKIP=no
                  case $NTB_FUNC in
                  tinyblob|blob|mediumblob|longblob|\
tinytext|mediumtext|text|longtext) 
                  $DLGPRG --title "Create a new table in database $DBASE" \
                   --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                   --infobox "\n\
      Cannot create index for text or blob types" 6 58
                  sleep $INFOTIME
                  SKIP=yes
                  ;;
                  char|varchar)
                  # get the parameters
                  IDX_PRM=$(echo "$NTB_OLD" | sed -e "s/^.*(//" \
                    -e "s/).*$//" -e "s/^.*$/(&)/")
                  ;;
                  *) IDX_PRM=""
                  ;;
                  esac

                  if test $SKIP = no ; then
                    cat $TMPFILE | sed \
                    -e "/^);/s/^/  KEY (${NTB_FOP}$IDX_PRM),\\
/" > ${TMPFILE}.bak
                    cp ${TMPFILE}.bak $TMPFILE
                  fi
                fi
              else
                $DLGPRG --title "Create a new table in database $DBASE" \
                 --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                 --msgbox "ERROR: maximum number of keys reached" 8 58
              fi # end of add a new KEY
            fi
          done
        fi # testing for QUIT=yes


        #
        # change column parameters
        #
        if test $QUIT = no ; then
          CHGTYP=yes
          while test $CHGTYP = yes ; do
            # create a template
            RADIO=$(cat $TMPFILE | sed \
            -e "/^  PRIMARY KEY/d" \
            -e "/^#/d" \
            -e "/^$/d" \
            -e "/^DROP TABLE /d" \
            -e "/^CREATE TABLE /d" \
            -e "/);/d" \
            -e "/([0-9,]*)/!d" \
            -e "s/^ *//" \
            -e 's/,$/	off/' \
               | sed -e "1 s/	off$/	on/" | cat -b -)

(IFS='	
'
            $DLGPRG --title "Create a new table in database $DBASE" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --radiolist "The display style or size parameters of each column\n\
may now be changed.\n\
Pick one column to be changed from the list. As a next step,\n\
you will be asked to type in different values.\n\n\
This is repeated until you're done and <cancel>." 21 75 9 \
            $RADIO 2>${TMPFILE}.dia
            echo $? >${TMPFILE}.ret
)

            RETVAL=$(cat ${TMPFILE}.ret)
            rm -f ${TMPFILE}.ret

            if test "$RETVAL" = "255" ; then
              QUIT=yes ; CHGTYP=done
            elif test "$RETVAL" = "1" ; then
              CHGTYP=done
            else
              DIA=$(cat ${TMPFILE}.dia)
              NTB_RTC=$(echo "$RADIO" | sed -e "/^ *$DIA	/!d" \
              -e "s/^ *$DIA	//" -e "s/	o[nf]f*$//")
            fi

            if test $QUIT = no -a $CHGTYP = yes ; then
              OLD_PRM=$(echo "$NTB_RTC" | sed \
                -e "s/^.*(//" -e "s/).*$//")
              $DLGPRG --title "Create a new table in database $DBASE" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --inputbox "This column is selected to change the parameter:\n\n\
  $NTB_RTC\n\n\
Defaults are maximum values. Enter the new parameter:" 19 75 "$OLD_PRM" \
              2>${TMPFILE}.dia
              RETVAL=$?
              NTB_NTY=$(cat ${TMPFILE}.dia)
              if test "$RETVAL" = "255" ; then
                QUIT=yes ; CHGTYP=done
              elif test "$RETVAL" = "1" ; then
                CHGTYP=done
              else
                # get the name of current column
                NTB_FOP=$(echo "$NTB_RTC" | sed -e "s/^ *//" \
                 -e "s/KEY *//" -e "s/ ..*//")
                cat $TMPFILE | sed \
                 -e "/^  $NTB_FOP /s/([0-9,]*)/($NTB_NTY)/" \
                 -e "/^  KEY (*$NTB_FOP/s/([0-9]*))/($NTB_NTY))/" \
                 > ${TMPFILE}.bak
                cp ${TMPFILE}.bak $TMPFILE
              fi
            fi
          done
        fi # testing for QUIT=yes


        #
        # toggle NULL  |  NOT NULL property
        #
        if test $QUIT = no ; then
          CHGTYP=yes
          while test $CHGTYP = yes ; do
            # create a template
            RADIO=$(cat $TMPFILE | sed \
            -e "/^  PRIMARY KEY/d" \
            -e "/^#/d" \
            -e "/^$/d" \
            -e "/^DROP TABLE /d" \
            -e "/^CREATE TABLE /d" \
            -e "/);/d" \
            -e "/NULL/!d" \
            -e "s/^ *//" \
            -e 's/,$/	off/' \
               | sed -e "1 s/	off$/	on/" | cat -b -)

(IFS='	
'
            $DLGPRG --title "Create a new table in database $DBASE" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --radiolist "Toggle the NOT NULL or NULL property\n\n\
Mark one column to be changed from the list.\n\n\
This is repeated until you're done and <cancel>." 20 75 9 \
            $RADIO 2>${TMPFILE}.dia
            echo $? >${TMPFILE}.ret
)

            RETVAL=$(cat ${TMPFILE}.ret)
            rm -f ${TMPFILE}.ret

            if test "$RETVAL" = "255" ; then
              QUIT=yes ; CHGTYP=done
            elif test "$RETVAL" = "1" ; then
              CHGTYP=done
            else
              DIA=$(cat ${TMPFILE}.dia)
              NTB_RTC=$(echo "$RADIO" | sed -e "/^ *$DIA	/!d" \
              -e "s/^ *$DIA	//" -e "s/	o[nf]f*$//")
            fi

            if test $QUIT = no -a $CHGTYP = yes ; then
              OLD_PRM=$(echo "$NTB_RTC" | sed \
                -e "/NOT NULL/!d")
              if test -n "$OLD_PRM" ; then
                NTB_OLD="NOT NULL" ; NTB_NTY="NULL"
              else
                NTB_OLD="NULL" ; NTB_NTY="NOT NULL"
              fi

              NTB_FOP=$(echo "$NTB_RTC" | sed -e "s/^ *//" -e "s/ ..*//")
              OLD_PRM=$(cat $TMPFILE | sed -e "/^  KEY ($NTB_FOP(/!d")
              if test -z "$OLD_PRM" ; then
                # toggle NULL / NOT NULL
                cat $TMPFILE | sed -e "/^  $NTB_FOP/s/$NTB_OLD/$NTB_NTY/" \
                  > ${TMPFILE}.bak
                cp ${TMPFILE}.bak $TMPFILE
              else
                $DLGPRG --title "Create a new table in database $DBASE" \
                 --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                 --msgbox "\n\
        ERROR: indexed columns may not be NULL" 8 58
              fi
            fi
          done
        fi # testing for QUIT=yes


        #
        # creating the new table
        #
        if test $QUIT = no ; then
        # get rid of this last comma
        cat $TMPFILE | sed -n -e "1,$ H" -e "$ g" \
           -e "$ s/,\\n);/\\
);/" -e "$ p" > ${TMPFILE}.bak
        cp ${TMPFILE}.bak $TMPFILE


        if RST=$(cat $TMPFILE | mysql $HOSTPRMS $DBASE 2>&1) ; then
           $DLGPRG --title "Create a new table in database $DBASE" \
            --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
            --infobox "\n\
           Table $NTB_NAME successfully created" 6 58
           sleep $INFOTIME
           errlog "created table $DBASE.$NTB_NAME"
        else
           $DLGPRG --title "Create a new table in database $DBASE" \
            --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
            --msgbox "ERROR creating table $NTB_NAME. \
                  Please check the logfile $LINK_DIR/$LOG_FILE \
                  for details." 8 58
           ERRQRY=$(cat $TMPFILE)
           errlog "ERROR creating table $DBASE.$NTB_NAME with query:\n\
$ERRQRY\n> resulted in message:\n$RST"
        fi
        fi # testing for QUIT=yes
        ;;


   o|O) echo -e "Drop the current table $DBTBL ???" >${TMPFILE}.dia
        echo -e "All data will be lost!" >>${TMPFILE}.dia
        # check for references from other tables in $LINK_LIST
        OTH_LNK=$(cat $LINK_LIST | sed \
           -e "/link_information $DBASE $DBTBL/d" \
           -e "/ $DBTBL /!d")
        if test -n "$OTH_LNK" ; then
           echo "Beware: other tables have links" >>${TMPFILE}.dia
           echo "        to $DBTBL" >>${TMPFILE}.dia
        fi

        echo "If you really want to drop" >>${TMPFILE}.dia
        echo "enter 'drop $DBTBL':" >>${TMPFILE}.dia
        IPBTXT=$(cat ${TMPFILE}.dia)
        $DLGPRG --title "Drop table $DBTBL" \
               --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
               --inputbox "$IPBTXT" 15 40  2>${TMPFILE}.dia
        unset IPBTXT
        RESP="$(cat ${TMPFILE}.dia)"

        if test "$RESP" = "drop $DBTBL" ; then
           errlog "dropped table $DBASE.$DBTBL"
           if ! RV=$(echo "DROP TABLE $DBTBL" \
              | mysql $HOSTPRMS $DBASE 2>&1); then
              $DLGPRG --title "Drop table $DBTBL" \
               --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
               --msgbox "ERROR dropping table $DBTBL. \
                         mysql reported: $RV" 10 40
           fi
           # delete all entries for table or referencing
           # this table from LINK_LIST
           cat $LINK_LIST | sed \
              -e "/link_information $DBASE $DBTBL/d" \
              -e "/ $DBTBL /d" >$TMPFILE
              # ooops, this one was dangerous!
           cp $TMPFILE $LINK_LIST
           # delete all entries for table from users hitlist
           # (sorry; zombies will remain for other users)
           cat $UCNF | sed \
              -e "/^# .* $DBASE $DBTBL/d" > ${TMPFILE}.db
           cp ${TMPFILE}.db $UCNF ; rm -f ${TMPFILE}.db
           #
           # get a new table; user's default or ask
           # what was the last table used?
           if test -r $UCNF ; then
              NEWDBTBL=$(cat $UCNF | sed \
                 -e "/# default_table $DBASE /!d" \
                 -e "s/# default_table $DBASE //")
           else
              NEWDBTBL=""
           fi

           if test -z "$NEWDBTBL" ; then
              chgtable
           else
              DBTBL=$NEWDBTBL
           fi
        fi
        ;;


        #
        # drop database
        #
   p|P) $DLGPRG --title "Drop Database $DBASE" \
          --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
          --inputbox "Beware: dropping a database will delete \
all data and all tables. \
To confirm this action enter 'drop $DBASE':" 10 60 "" \
        2>${TMPFILE}.dia
        RETVAL=$?
        DROPDB=$(cat ${TMPFILE}.dia)

        if test "$RETVAL" = 0 -a "$DROPDB" = "drop $DBASE" ; then
           if RV=$(echo y | \
              (mysqladmin $HOSTPRMS drop $DBASE 2>&1)) ; then
              errlog "dropped database $DBASE"
              $DLGPRG --title "Drop Database $DBASE" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --infobox "dropped database $DBASE." 7 40
              sleep $INFOTIME
              if test -w $UCNF ; then
                 cat $UCNF | sed \
                 -e "/^# default_database $DBASE/d" >${TMPFILE}.db
                 cp ${TMPFILE}.db $UCNF ; rm -f ${TMPFILE}.db
              fi
              DBASE='<none>'
              DBTBL='<none>'
           else
              RV=$(echo $RV | sed -e "s///" | fold -s -w 36)
              $DLGPRG --title "Drop Database $DBASE" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --msgbox "ERROR dropping database $DBASE.\n\
Result was:\n$RV" 10 40
           fi
        fi
        ;;


        #
        # restore a database from backup file
        #
   r|R) $DLGPRG --title "Restore database $DBASE from backup" \
          --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
          --inputbox "Beware: this is a dangerous operation! All data \
in your current database will be lost and overwritten with data \
from the backup. Do you really want this? \
Enter 'restore from [/path/]$DBASE': "\
        12 60 "" 2>${TMPFILE}.dia
        RETVAL=$?
        CURDIR=$(pwd)
        RESPONSE=$(cat ${TMPFILE}.dia)
        DBPATH=$(echo "$RESPONSE" | sed -e "s/^restore from  *//" \
        -e "s/$DBASE.*//" -e "s/\\/$//")
        if test -n "$DBPATH" ; then
           CURDIR=$DBPATH
        fi
        RESPTPL=$(echo "$RESPONSE" | sed -e "s|$DBPATH/*||")
 
        # may be a floppy; mount it if we can; needs /etc/fstab entry
        # like: /dev/fd0  /floppy  auto  noauto,user  0  0
        FLOPPY=true
        if test $CURDIR = $FLOPPYDRIVE ; then
           umount $FLOPPYDRIVE >/dev/null 2>&1
           mount $FLOPPYDRIVE >/dev/null 2>&1 || FLOPPY=false
        fi

        if test $RETVAL = 0 -a "$RESPTPL" = "restore from $DBASE" \
                            -a $FLOPPY = true ; then
           if ! test -r "$CURDIR/$DBASE.$PACK_SUFFIX" ; then
              $DLGPRG --title "Restore database $DBASE from backup" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --msgbox "ERROR: backup file $CURDIR/$DBASE.$PACK_SUFFIX \
not found." 12 60
           else
              errlog "restored $DBASE from $CURDIR/$DBASE.$PACK_SUFFIX"
              $UNPACKER $CURDIR/$DBASE.$PACK_SUFFIX \
              | mysql $HOSTPRMS $DBASE
           fi
           if test $CURDIR = $FLOPPYDRIVE ; then
              umount $FLOPPYDRIVE >/dev/null 2>&1
           fi
        fi
        ;;


        #
        # show the status of the active table
        #
   s|S) TWIDTH=70
        BWIDTH=$(($TWIDTH - 4))
        FLC="fold -s -w $BWIDTH"
        echo -e "\nStatus of table $DBTBL:\n" \
           | $FLC >${TMPFILE}.dia

        if test -z "$TBL_LOG" ; then
           echo "table $DBTBL has no logfile" | $FLC >>${TMPFILE}.dia
        else
           echo "table $DBTBL has a logfile $TBL_LOG" | $FLC >>${TMPFILE}.dia
        fi

        if test -r $UCNF ; then
           echo -e "\nuser $USERNAME has these default settings for $DBTBL:" \
              | $FLC >>${TMPFILE}.dia
           cat $UCNF | sed -e "/# default_/!d" \
                           -e "/# .*$DBASE $DBTBL /!d" \
                           -e "s/^# //" | $FLC >>${TMPFILE}.dia
        fi

        echo -e "\ntable $DBTBL contains links to following tables:" \
           | $FLC >>${TMPFILE}.dia
        cat $LINK_LIST | sed \
           -e "/^link_information $DBASE $DBTBL /!d" \
           | $FLC >>${TMPFILE}.dia

        echo -e "\ntable $DBTBL is referenced by these tables:" \
           >>${TMPFILE}.dia
        cat $LINK_LIST | sed \
           -e "/^link_information $DBASE $DBTBL/d" \
           -e "/$DBTBL/!d" | $FLC >>${TMPFILE}.dia

        $DLGPRG --title "Table Status:" \
               --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
               --textbox ${TMPFILE}.dia 19 $TWIDTH
        ;;

        #
        # massmail: write mass letters
        #
   w|W) QUIT=no
        RMK='%'           # the letter to start a remark
        #
        # create the letter template file
        cat > $MASSM_DIR/template.tex <<-XXX
	% file $MASSM_DIR/template.tex
	% Uncomment and edit what you need.
	\\input massmail.sty
	%
	% Database = $DBASE
	% Table    = $DBTBL
	% Where    = 1=0
	% Printer  = -Plp
	% Printing = yes
	%% Options for mass email
	%% give column_name containing E-Mail address
	% E-Mail   =
	% Subject  =
	% Mailing  = no
	%
	XXX

        QHDR="You have these column_names at your disposition:"
        QHDR="${QHDR}
$(preplbls)"
        echo "$QHDR" | sed -e "s/^/% /" >>$MASSM_DIR/template.tex

        cat >>$MASSM_DIR/template.tex <<-XXX
	%
	%% Program lines to define local variables:
	%% (remove one % to uncomment program lines)
	%% if column_name == Value then localvar = constant data
	%% if column_name == DEFAULT then localvar = ''
	%
	%% Begin every addressblock line with \\relax and end it with \\par
	%% Put your column_names and local variables in between.
	%% Column names are given as:      %!column_name!%
	%% Local variables are given as:   !!localvar!!
	\\addressblock{%
	\\relax %!column_name!%\\par
	\\smallskip\\addressfontbold
	\\relax %!!% %!!%\\par}

	\\dateline{\\location\ \heute}
	\\vskip 0.2in
	\\baselineskip 15pt
	\\subjectline{}
	% start your text here:

	\\signed
	% specify things to be printed at the bottom of the page
	\\endofdocument{}
	XXX

        SCRIPTS=$(2>/dev/null ls --color=no -t -1 $MASSM_DIR/*.tex \
                  | sed -e "s|^.*/||" | cat -n - | sed -e "s/^ *//")

        if test -z "$SCRIPTS" ; then
           SCRIPTS="x	(no template available)"
        fi

(IFS='	
'
        $DLGPRG --title "Print massmail letter using data from $DBTBL" \
         --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
         --menu "Pick one of the existing letters or 'template.tex'\n\
and edit as required. The letter will be printed \n\
upon exiting the editor. To keep a new letter it \n\
must be saved under a different new name with \n\
extension '*.tex'. With joe use ^KD to do this." 21 68 10 \
        $SCRIPTS 2>${TMPFILE}.dia
        echo $? >${TMPFILE}.ret
)

        RETVAL=$(cat ${TMPFILE}.ret)
        rm -f ${TMPFILE}.ret

        if test "$RETVAL" = "255" -o "$RETVAL" = "1" ; then
           QUIT=yes
        else
           DIA=$(cat ${TMPFILE}.dia)
           EDFILE=$(echo "$SCRIPTS" | sed -e "/^ *$DIA	/!d" \
           -e "s/^ *$DIA	//")
        fi

        if test $QUIT = no ; then

           # start the editor from the script directory
           ( cd $MASSM_DIR && $EDITOR $EDOPTS $EDFILE )

           SFNAME="$MASSM_DIR/$EDFILE"
           SFNAME=$(echo "$SFNAME" | sed s/.tex$//)
           FNAME=$SFNAME.tex
           TNAME=$SFNAME$$

           # Look for printer specification in the template file
           # An empty value may be assigned, like '% Printer = '
           TFPRI=$(sed '/^% *Printer *=/!d' <$FNAME)
           if test -n "$TFPRI" ; then
              PRINTER=$(echo "$TFPRI" | sed 's/^% *Printer *= *//')
           fi

           # Is this a printing template file?
           # Printing = 'yes' or 'no' overrides everything else
           PTING=$(sed '/^% *Printing *=/!d' <$FNAME)
           if test -n "$PTING" ; then
              PTANS=$(echo "$PTING" | sed 's/^% *Printing *= *//')
              if test "$PTANS" = yes ; then
                 PRINTING=yes
              else
                 PRINTING=no
              fi
           fi

           # Get e-Mail related data (if any) from the template file
           EMAIL=$(sed -e "/^${RMK} *E-Mail *=/!d" \
                       -e "s/^${RMK} *E-Mail *= *//" <$FNAME)
           if test -n "$EMAIL" ; then
              EM=$(echo -e "\n$EMAIL")
           fi
           ESUBJ=$(sed -e "/^${RMK} *Subject *=/!d" \
                       -e "s/^${RMK} *Subject *= *//" <$FNAME)
           MLING=$(sed -e "/^${RMK} *Mailing *=/!d" \
                       -e "s/^${RMK} *Mailing *= *//" <$FNAME)

           # Database to use
           # check for a valid database name in the template file first
           # if there is more than one database line then the last one rules
           MMDB="$(sed -e '/^% *Database *= */!d' \
                       -e 's/^% *Database *= *//' <$FNAME)"
           if test -n "$MMDB" ; then
              MMDB=$(echo "$MMDB" | tail -n 1)
           fi
           #echo "using database $MMDB"

           # name of the table to use:
           # take it from the template file
           MMTBL=$(sed -e "/^% *Table *= */!d" \
                       -e "s/^% *Table *= *//" <$FNAME)
           #echo "using table $MMTBL"

           # Check the template file for a SQL-WHERE clause
           #
           SCLAUSE=$(sed -e "/^% *Where *= */!d" \
                         -e "s/^% *Where *= *//" \
                         -e "s/; *$//" <$FNAME )

           # Programmable Variables
           PROG=$(cat $FNAME | sed -e '/^%[ 	]*if[ 	]/!d' \
                        -e 's/[ 	][ 	]*/_/g' \
                        -e 's/^%_*if_//')
           # (space in the brackets is one blank and one tab)

           # From the template text file isolate all variables;
           #      add commas;
           #      looks for variables in if-statements too.
           VVARS=$(cat $FNAME | sed -e "/^%%/d" -e '/%!.*!%/!d' \
           | sed -e 's/^[^%]*%!/%!/' \
                 -e 's/!%[^%]*%!/!%%!/g' \
                 -e 's/!%[^%]*$/!%/' \
                 -e 's/!%%!/!%\
%!/g' | sed -e 's/^%!//' -e 's/!%$//')

           IFVRS=$(echo "$PROG" | sed -e 's/_==_.*$//')
           if test -n "$IFVRS" ; then
              IFVRS=$(echo -e "\n$IFVRS")
           fi

           VARS=$(echo "${VVARS}${IFVRS}${EM}" \
              | sed -e 's/$/,/' | sort -u \
              | sed -e '$ s/,$//')
           #echo "variables = $VARS"

           ERRORFLAG=false
           for VV in $VARS ; do
              V=$(echo $VV | sed "s/,$//")
              if ! echo "select $V from $MMTBL where 1=0;" \
                 | mysql $HOSTPRMS $MMDB >/dev/null 2>&1 ; then
                 ERRMSG="$ERRMSG
unknown variable '$V' in table '$MMTBL'"
                 ERRORFLAG=true
              fi
           done

           #echo "accumulated errors are: $ERRMSG"

           if test $ERRORFLAG = true ; then
              $DLGPRG --title "Writing mass mail letters using $DBTBL" \
               --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
               --msgbox "Scanning of your template file resulted in:\n\
$ERRMSG" 18 75
           else
              QUERY="select $VARS from $MMTBL where $SCLAUSE ;"
              RST=$(echo "$QUERY" | mysql $HOSTPRMS $MMDB \
                 2>&1 1>$TNAME.tmp)

              if test -n "$RST" ; then
                 QUERY=$(echo $QUERY)
                 $DLGPRG --title "Writing mass mail letters using $DBTBL" \
                  --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                  --msgbox "Error: Fetching data with query '$QUERY' \
                            resulted in message: $RST" 18 75
                 ERRORFLAG=true
              fi
           fi

           if test $ERRORFLAG = false ; then
              # get the list of field names from the first line:
              # separate fields with linefeeds and add line numbers
              FIELDS=$(head --lines 1 $TNAME.tmp | tr '\011' '\012' \
                 | cat -n - | sed -e "s/^ *//" | tr '\011' '_')

              # get rid of the first line:
              sed -e "1 d" <$TNAME.tmp >$TNAME.dta
              rm -f $TNAME.tmp

              # let's see how many rows have been retrieved
              LASTLINE=$(wc -l $TNAME.dta | cut -c 1-7 | sed -e "s/^ *//")

              $DLGPRG --title "Print massmail letter using data from $MMTBL" \
               --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
               --yesno "\n            Selected $LASTLINE entries\n\
           Print these letters?" 8 50
           fi

           if test $? = 0 -a $ERRORFLAG = false ; then
              CTR=1
              TIMEFORMAT='%3R'
              OLDIFS="$IFS" # save to restore later on
              #TAB is no longer an internal field separator
              IFS=' 
'
              # while reads from standard input
              # file $TNAME.dta is fed as input to the 'done' command
              time while read DTALINE
                 do
                 # we want one item per line
                 DTATBL=$(echo "$DTALINE" | tr '\011' '\012')
                 # make a local copy of the letter template
                 cp $FNAME $FNAME.loc
                 # prepare a letter for this data row
                 # 1st step:
                 # adapt the template according to any program
                 # lines in the original
                 for PL in $PROG ; do
                    # name of the variable in the database
                    DBVAR=$(echo $PL | sed -e 's/_==_.*$//')
                    # get value to compare with
                    CMPVL=$(echo $PL | sed -e 's/^.*_==_//' \
                                           -e 's/_*then_.*//')
                    if test "$CMPVL" = "''" ; then CMPVL="EMPTY" ; fi
                    CMPLEN=$(echo "$CMPVL" | sed -e "s/././g")
                    # name of the variable in the template file
                    TPVAR=$(echo $PL | sed -e 's/^.*_*then_//' \
                                           -e 's/_=_.*//')
                    # constant to be assigned if the condition is met
                    TPVAL=$(echo $PL | sed -e 's/^.*_=_//' -e 's/_/ /g')
                    if test "$TPVAL" = "''" ; then TPVAL="" ; fi
                    # Mask special characters in the dataline for TeX
                    if test "$MLING" != yes ; then
                       TPVAL=$(echo "$TPVAL" | sed \
                          -e "s/#/\\\\\\\\#/g" \
                          -e "s/%/\\\\\\\\%/g" \
                          -e "s/\\$/\\\\\\\\$/g" \
                          -e "s/&/\\\\\\\\\\\\&/g")
                    fi
                    #
                    # now: get the value for the database variable $DBVAR:
                    # result is returned in $DBVARVAL 
                    # and truncated to len($CMPVL)
                    FC=$(echo "$FIELDS" | sed -e "/$DBVAR/!d" -e "s/_.*//")
                    DBVARVAL=$(echo "$DTATBL" | sed -e "$FC !d" \
                       -e "s/\\($CMPLEN\\)\\(.*\\)/\\1/")
                    if test -z "$DBVARVAL" ; then DBVARVAL="EMPTY" ; fi
                    #
                    if test "$DBVARVAL" = "$CMPVL" ; then
                       sed -e "s|!!$TPVAR!!|$TPVAL|g" <$FNAME.loc >$FNAME.tmp
                       rm $FNAME.loc ; mv $FNAME.tmp $FNAME.loc
                    else
                       if test "$CMPVL" = DEFAULT ; then
                          sed -e "s|!!$TPVAR!!|$TPVAL|g" \
                             <$FNAME.loc >$FNAME.tmp
                          rm $FNAME.loc ; mv $FNAME.tmp $FNAME.loc
                       fi
                    fi
                 done
                 #
                 # 2nd: Substitution of ordinary variables:
                 # Mask special characters in the datalines for TeX
                 # (all double quotes are converted to closing
                 #  double quotes)
                 if test "$MLING" != yes ; then
                    DTATBL=$(echo "$DTATBL" | sed \
                       -e "s/\\\\/|\\\\\\\\backslash|/g" \
                       -e "s/#/\\\\\\\\#/g" \
                       -e "s/%/\\\\\\\\%/g" \
                       -e "s/\\$/\\\\\\\\$/g" \
                       -e "s/&/\\\\\\\\\\\\&/g" \
                       -e "s/\"/''/g" \
                       -e "s/|/$/g")
                 fi
                 #
                 for FN in $FIELDS ; do
                    FC=$(echo $FN | sed "s/_.*//")
                    FF=$(echo $FN | sed "s/[0-9]*_//")
                    FD=$(echo "$DTATBL" | sed -e "$FC !d" -e "s|/|\\\\/|g")
                    sed "s/%!$FF!%/$FD/g" <$FNAME.loc >$FNAME.tmp
                    rm $FNAME.loc ; mv $FNAME.tmp $FNAME.loc
                    if test "$FF" = "$EMAIL" ; then EADDR="$FD" ; fi
                 done
                 #
                 FSUFF=$(echo "0000$((CTR))" \
                    | sed "s/\\(0*\\)\\([0-9][0-9][0-9][0-9]\\)/\\2/")
                 # write the result to a unique file and remove remarks
                 sed "/^${RMK}.*/d" >$TNAME-$FSUFF.tex <$FNAME.loc
                 #
                 if test "$PRINTING" = yes ; then
                    (cd $MASSM_DIR && $TEXPROG $TNAME-$FSUFF.tex \
                      >/dev/null 2>&1)
                    if test -r $MASSM_DIR/$TNAME-$FSUFF.dvi ; then
                       (cd $MASSM_DIR && \
                           dvips -q -o $TNAME-$FSUFF.ps $TNAME-$FSUFF.dvi)
                       lpr $PRINTER $TNAME-$FSUFF.ps
                       rm -f $TNAME-$FSUFF.tex
                       rm -f $TNAME-$FSUFF.log
                       TEXERROR=false
                    else
                       # dialog gets no input within this loop
                       # so we have to use infobox (not msgbox)
                       ERRMSG=$(fold -s -w 70 $TNAME-$FSUFF.log | tail -n 17)
                       $DLGPRG --title "Writing mass mail letters" \
                        --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                        --infobox "Problems with your TeX syntax; please check:\n\
$TNAME-$FSUFF.log\n$ERRMSG" 21 75
                       sleep $WARNTIME
                       sleep $WARNTIME
                       rm -f $TNAME-$FSUFF.tex
                       TEXERROR=true
                       break 1
                    fi
                    if test -n "$WAITTIME" ; then sleep $WAITTIME ; fi
                    rm -f $TNAME-$FSUFF.ps
                    rm -f $TNAME-$FSUFF.dvi
                 fi
                 CTR=$((CTR+1))
                 #
                 if test "$MLING" = yes ; then
                    sed -e "s/\\\\%/<!percent!>/g" \
                        -e "s/%.*//" -e "s/<!percent!>/%/g" \
                        <$TNAME-$FSUFF.tex >$TNAME-$FSUFF.mail
                    $MAILER -s "$ESUBJ" "$EADDR" <$TNAME-$FSUFF.mail
                    rm -f $TNAME-$FSUFF.tex
                    rm -f $TNAME-$FSUFF.mail
                 fi
              done <$TNAME.dta >/dev/null
           IFS="$OLDIFS" # set back to default
           fi
           rm -f $TNAME-*.tmp
           rm -f $TNAME.dta
           if test $TEXERROR != true ; then
              rm -f $TNAME-$FSUFF.log
           fi
           rm -f $FNAME.loc
        fi
        #read dummy
        ;;

        #
   q|Q|noop) # quit
        ;;

   *)   $DLGPRG --title "Warning:" \
         --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
         --infobox "Unknown command $SC" 6 40
        sleep $WARNTIME
        ;;
esac
}


#################################################################
# Help menu
showhelp () {
$DLGPRG --title "List of Help commands" \
       --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
       --menu "$ACTIVE" 19 60 12 \
d "help about db" \
m "help about MySQL and SQL syntax" \
p "help about PHP" \
s "selfhtml Tutorial" \
q "quit"   2>${TMPFILE}.dia

RETVAL=$?

SC=$(cat ${TMPFILE}.dia)

if test -z "$SC" ; then
   SC=q
fi

case "$SC" in

        #
   d|D) if ! $INFOVIEWER $DBHLP; then
           echo -e "\nFailed to call viewer;\n\
did: $INFOVIEWER $DBHLP\n"
           exit 1
        fi
        ;;

        #
   m|M) if ! $INFOVIEWER $MYHLP; then
           echo -e "\nFailed to call viewer;\n\
did: $INFOVIEWER $MYHLP\n"
           exit 1
        fi
        ;;

        #
   p|P) if test -r "$PHPHLP" ; then
           if ! $HTMLMANVIEW $PHPHLP; then
              echo -e "\nFailed to call viewer;\n\
did: $HTMLMANVIEW $PHPHLP\n"
              exit 1
           fi
        else
           $DLGPRG --title "PHP Help" \
            --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
            --msgbox "Help for PHP not implemented" 6 40
        fi
        ;;

        #
   s|S) if test -n "$HTMLMAN" ; then
           if ! $HTMLMANVIEW $HTHLP; then
              echo -e "\nFailed to call viewer;\n\
did: $HTMLMANVIEW $HTHLP\n"
              exit 1
           fi
        else
           $DLGPRG --title "HTML Tutorial" \
            --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
            --msgbox "Selfhtml tutorial not implemented" 6 40
        fi
        ;;

        #
   q|Q) # leaving help menu
        ;;

   *)   echo ; echo "unknown command $SC"
        ;;

esac

}


#################################################################
# Yippee, we have a database and a table
# Main: Go to the (main) menu

errlog "db started with $DBASE.$DBTBL"
chklogtbl
FC=""
LASTCHOICE=""

while ! test "$FC" = q ; do
ACTIVE="$DBASE.$DBTBL is active"

$DLGPRG --title "List of commands" \
       --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
       --menu "$ACTIVE" 20 60 13 \
"add" "add new records of data" \
"bind" "bind new records into a linked table" \
"change" "edit and change records" \
"delete" "delete records" \
"edit" "edit / compose SQL query" \
"find" "find and retrieve data" \
"help" "go to the help menu" \
"output" "export data into outfile" \
"print" "print results from a select query" \
"special" "go to the SPECIAL commands menu" \
"table" "select a table" \
"use" "use another database" \
"quit" "terminate program / QUIT"  2>${TMPFILE}.dia

RETVAL=$?

FC=$(cat ${TMPFILE}.dia | cut -b 1)

case $RETVAL in
   0) # normal data returned
      ;;

   1) # cancel
      FC="q"
      ;;

 255) # ESC
      FC=q
      ;;
esac

if test -z "$FC" ; then
   FC="$LASTCHOICE"
fi

LASTCHOICE="$FC"

# handle the special case with no database
case $FC in
a|b|c|d|e|f|o|t)
   if test $DBASE = '<none>' ; then
      $DLGPRG --title "Warning:" \
             --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
             --infobox "No database is selected. Use 'make a new database' \
                        from the special commands menu \
                        or 'use another database'" 6 40
      FC=noop
      sleep $WARNTIME
   fi
   ;;
esac

# handle the special case with no table
case $FC in
a|b|c|d|e|f|o)
   if test $DBTBL = '<none>' -o $DBTBL = '' -a $DBASE != '<none>' ; then
      $DLGPRG --title "Warning:" \
             --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
             --infobox "No table is selected. Use 'create a new table' \
                        from the special commands \
                        or select a table" 6 40
      FC=noop
      sleep $WARNTIME
   fi
   ;;
esac


case "$FC" in
        #
        # add new records to the database
   a|A) ADDFLG=add
        isalog  # set ADDFLG=quit if this is a log table
        while test $ADDFLG = add ; do
           lbltmpl
           echo "$LB" > $TMPFILE

           if test $ED_WRITES_BKUP = yes ; then
              rm -f ${TMPFILE}~
           else
              FILE_TIMESTAMP=$(ls -lG --full-time $TMPFILE)
           fi

           $EDITOR $EDOPTS $TMPFILE

           # call insert module if something was changed
           if test $ED_WRITES_BKUP = yes ; then
              if test -f ${TMPFILE}~ ; then
                 toins $TMPFILE
              else
                 ADDFLG=quit
              fi
           else # we have to look at the modification time
              FILE_MODTIME=$(ls -lG --full-time $TMPFILE)
              if test "$FILE_TIMESTAMP" != "$FILE_MODTIME" ; then
                 toins $TMPFILE
              else
                 ADDFLG=quit
              fi
           fi
           if test $ADD_LOOP != "yes" ; then
              ADDFLG=quit
           fi
        done
        # No backup file exists
        $DLGPRG --title "Insert into table $DBTBL" \
         --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
         --infobox "No further changes have been made. \
Leaving insertion mode for table $DBTBL" 7 40
        sleep $INFOTIME
        ;;

        #
        # bind new rows to another table
        # like "add new" but makes a link (or many links)
        # and imports data from other table(s)
        #
        # input goes to the current table
        # for each table the following information is kept:
        #    for every field to be filled with linked data from another
        #    table there is one line containing:
        #    <localfieldname> <othertable> <othertablefield> [<other...]
        # and having a header of:
        #    link_information <database> <table>
        # the user has to find the desired record(s) with much
        #    default help from the system before the template
        #    mask is created.
        #
   b|B) ADDFLG=add
        # refuse to add to log tables
        isalog

        # extract link information pertaining to the current
        # database and table and delete the headers;
        # new field separator is '|';
        # sort neglecting case and dropping duplicates
        LINK_INF=$(cat $LINK_LIST | sed \
           -e "/^link_information $DBASE $DBTBL/!d" \
           -e "s/^link_information $DBASE $DBTBL  *//" \
           -e "s/  */|/g" \
           | sort -t \| -k 2,2 -k 1,1 -u)
           # sort on other table and local column / no duplicates

        if test -z "$LINK_INF" ; then
           $DLGPRG --title "Add to (linked?) table $TBL_LOG" \
           --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
           --msgbox "ERROR: No link dependencies \
                     for table $DBASE.$DBTBL found" 6 40
           ADDFLG=quit
        fi

        ########################################
        # WHILE user does not quit entering data
        while test $ADDFLG = add ; do

        lbltmpl # make label template in $LB
        LAST_TB_WAS=''

        for LWORD in $LINK_INF ; do

           # for every link dependency look up data in another
           # table and insert into current template
           LK_LOC_FN=$(echo $LWORD | sed -e "s/|.*//")
           LK_OTH_TB=$(echo $LWORD | sed -e "s/[^|]*|//" -e "s/|.*//")
           LK_OTH_FN=$(echo $LWORD | sed -e "s/.*|//")

           if test "$LAST_TB_WAS" = "$LK_OTH_TB" ; then
              SAME_AS_LAST=yes
           else
              SAME_AS_LAST=no
           fi
           LAST_TB_WAS=$LK_OTH_TB

           # Substitution is like:
           # LK_LOC_FN=LK_OTH_TB.LK_OTH_FN

           # get user's defaults for this dependency
           if test -r $UCNF ; then
              LINK_QRY=$(cat $UCNF \
              | sed -e "/^# default_link_qry $DBASE $DBTBL $LK_LOC_FN/!d" \
              -e "s/^# default_link_qry $DBASE $DBTBL $LK_LOC_FN *//")
           fi

           # ******* here starts a while loop  ********
           #     try until the desired link record is found
           if test $SAME_AS_LAST = no ; then
              ALL_OK=n
           else
              ALL_OK=y
           fi

           while test "$ALL_OK" = 'n' -a $ADDFLG = add ; do

              # set DBTBL temporarily to the referenced table
              # and get the field names
              DBTBL_TMP=$DBTBL
              DBTBL=$LK_OTH_TB
              LBLS=$(preplbls)
              DBTBL=$DBTBL_TMP
              unset DBTBL_TMP

              DIALEN=$(echo "$LBLS" | wc --lines)
              if test $(($DIALEN)) -gt $((13)) ; then
                 DIALEN=13
              fi
              DIABOX=$(($DIALEN + 10))
              # with too many labels only 13 lines are shown
              LBLS=$(echo "$LBLS" | head -n 13)

              if test -z "$LINK_QRY" ; then
                 DEFLK_QRY="SELECT * FROM $LK_OTH_TB WHERE $LK_OTH_FN LIKE '%???%';"
              else
                 DEFLK_QRY="$LINK_QRY"
              fi


              # inner loop; compose a valid query
              VDAT="x"
              while test "$VDAT" = 'x' -a $ADDFLG = add ; do

                 # cut the query for display on one line
                 DSPWIDTH=75
                 DISPQL=$(echo "$DEFLK_QRY" | wc -c | sed "s/^ *//")
                 DISPCUT=$(($DISPQL - $DSPWIDTH + 6))
                 if test $(($DISPCUT)) -le $((0)) ; then
                    DISPCUT=1
                 fi
                 DISPQ="~$(echo "$DEFLK_QRY" | cut -c ${DISPCUT}- )"


                 $DLGPRG --title "Enter data into linked table $DBTBL" \
                 --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                 --inputbox "Importing linked data from $LK_OTH_TB.$LK_OTH_FN\n\
$LBLS\n$DISPQ\n\
Enter data replacing ???  (enter 'x' to edit query):" \
$DIABOX $DSPWIDTH 2>${TMPFILE}.dia
                 RETVAL=$? ; VDAT=""

                 case $RETVAL in
                   1)  ADDFLG=quit
                       ;;
                 255)  ADDFLG=quit
                       ;;
                   0)  VDAT="$(cat ${TMPFILE}.dia)"
                       ;;
                 esac


                 if test "$VDAT" = 'x' -a $ADDFLG = add ; then
                    # change the query
                    $DLGPRG --title "Enter data into linked table $DBTBL" \
                    --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                    --inputbox "Importing data from $LK_OTH_TB.$LK_OTH_FN \n\
                 to $DBTBL.$LK_LOC_FN\n\
$LBLS\nEdit default query; (use ??? for variable part):" \
$DIABOX 75 "$DEFLK_QRY" 2>${TMPFILE}.dia
                    RETVAL=$?
                    READ_QRY=$(cat ${TMPFILE}.dia)

                    case $RETVAL in
                      1)  READ_QRY="$DEFLK_QRY"
                          ;;
                    255)  ADDFLG=quit
                          ;;
                      0)  ;;
                    esac

                    # if something was changed then write back as new default
                    if test "$DEFLK_QRY" != "$READ_QRY" \
                    -a $RETVAL = 0 -a -w $UCNF ; then
                       cat $UCNF | sed \
                       -e "/^# default_link_qry $DBASE $DBTBL $LK_LOC_FN.*$/d" \
                       > ${TMPFILE}.db
                       cp ${TMPFILE}.db $UCNF ; rm -f ${TMPFILE}.db
                       echo "# default_link_qry $DBASE $DBTBL \
$LK_LOC_FN $READ_QRY" >> $UCNF
                    fi
                    DEFLK_QRY="$READ_QRY"
                 fi

              done
              # end of while '$VDAT=x' loop
              # we should have a query by now



              if test $ADDFLG = add ; then
                 # mask &-chars in the data for the next sed
                 VDAT=$(echo "$VDAT" | sed -e "s/\\\\/\\\\\\\\\\\\\\\\/g" \
                    -e "s/&/\\\\&/g")
                 LQR=$(echo "$DEFLK_QRY" | sed -e "s/[?][?][?]/$VDAT/" \
                    -e "s/ *;* *$/;/")

                 echo "$LQR" | mysql --vertical $HOSTPRMS $DBASE \
                    >$TMPFILE 2>&1

                 NHITS=$(cat $TMPFILE | sed -e "/^\\*\\** [0-9]/!d" \
                    | wc --lines | sed -e "s/^ *//")
                 XX=""; if test $(($NHITS)) -ne $((1)) ; then XX=s; fi
                 if test $(($NHITS)) -eq $((0)) ; then
                    OKMSG=$(echo "Nothing has been found for this query: $LQR"\
                    | fold -s -w 70)
                 else
                    OKMSG="first record shown is ok?"
                 fi

                 # let's see how to display this ...
                 TPFLEN=$(cat $TMPFILE | wc --lines | sed -e "s/^ *//")
                 if test $(($TPFLEN)) -le $((200)) ; then
                    $DLGPRG \
                    --title "Your query has resulted in $NHITS record$XX:"\
                    --backtitle " db (Ver. $DB_VERSION) $HOSTINFO"\
                    --yesno "$(echo "$OKMSG")
$(cat $TMPFILE | cut -b -70 | head -n 16)" \
                    21 75

                    RETVAL=$?
                    if test $(($NHITS)) -eq $((0)) ; then RETVAL=1 ; fi
                    case $RETVAL in
                    0)   ALL_OK=y
                         ;;
                    1)   ALL_OK=n
                         ;;
                    255) ALL_OK=q
                         ADDFLG=quit
                         ;;
                    esac
                 else
                    $MYPAGER $TMPFILE
                    read -e -p "first entry ok? [y/n/q] " ALL_OK
                 fi
              fi

           done # --- end of the while 'ALL_OK' loop
           # Query results in the right data


           # ready to get data to be entered into template
           if test $ADDFLG = add ; then

              LQR=$(echo "$LQR" | sed \
                -e "s/.* [Ww][Hh][Ee][Rr][Ee]  *//")

              QUERY="SELECT $LK_OTH_FN FROM $LK_OTH_TB WHERE $LQR"

              LK_RESULT=$(echo "$QUERY" \
                 | mysql --batch --skip-column-names \
                 $HOSTPRMS $DBASE | head -n 1)

              LB=$(echo "$LB" | sed \
                 -e "/> *$LK_LOC_FN: /s/$/$LK_RESULT/")
           fi

        done # end of FOR loop; template is ready

        if test $ADDFLG = add ; then
           echo "$LB" > $TMPFILE

           if test $ED_WRITES_BKUP = yes ; then
              rm -f ${TMPFILE}~
           else
              FILE_TIMESTAMP=$(ls -lG --full-time $TMPFILE)
           fi

           $EDITOR $EDOPTS $TMPFILE

           # call insert module if something was changed
           if test $ED_WRITES_BKUP = yes ; then
              if test -f ${TMPFILE}~ ; then
                 toins $TMPFILE
              else
                 ADDFLG=quit
              fi
           else # we have to look at the modification time
              FILE_MODTIME=$(ls -lG --full-time $TMPFILE)
              if test "$FILE_TIMESTAMP" != "$FILE_MODTIME" ; then
                 toins $TMPFILE
              else
                 ADDFLG=quit
              fi
           fi
        fi

        done  # end of while 'ADDFLG'

        # No backup file exists; leaving
        $DLGPRG --title "Insert into table $DBTBL" \
         --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
         --infobox "No further changes have been made. \
Leaving insertion mode for table $DBTBL" 7 40
        sleep $INFOTIME
        ;;

        #
   c|C) ADDFLG=add
        unique
        if test -z "$PRIKEY" ; then
           $DLGPRG --title "Change data from table $DBTBL" \
               --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
               --msgbox "\n           cannot update table with\n\
           no primary key!\n" 8 52
           QUERY=""
        else
           getquery
        fi

        if test -n "$QUERY" ; then
        # make sure we selected PRIKEY too
        PKA=$(echo "$QUERY" | sed \
           -e "s/ [Ff][Rr][Oo][Mm]  *.*//" \
           -e "/$PRIKEY/!d")
        PKB=$(echo "$QUERY" | sed \
           -e "s/ [Ff][Rr][Oo][Mm]  *.*//" \
           -e "/[Ss][Ee][Ll][Ee][Cc][Tt]  *\\*/!d")
        PKF="${PKA}${PKB}"
        if test -z "$PKF" ; then
           QUERY=$(echo "$QUERY" | sed \
           -e "s/\\(.*[Ss][Ee][Ll][Ee][Cc][Tt]  *\\)\\(.*\\)/\\1$PRIKEY,\\2/")
        fi

        search

        TFL=$(wc -l $TMPFILE | cut -c 1-7 | sed -e "s/^ *//")
        if test $(($TFL)) -gt $((0)) ; then
           if test $ED_WRITES_BKUP = yes ; then
              rm -f ${TMPFILE}~
           else
              FILE_TIMESTAMP=$(ls -lG --full-time $TMPFILE)
           fi

           cp ${TMPFILE} ${TMPFILE}.bak
           $EDITOR $EDOPTS $TMPFILE

           # do not allow to change log tables
           LMASK=$(echo "$TBL_SUFFIX" | sed 's/././g')
           TBSUF=$(echo $DBTBL | sed -e "s/\\(.*\\)\\($LMASK$\\)/\\2/")
           # if someone undef'd the suffix
           if test "$TBSUF" = "$TBL_SUFFIX" -a -n "$TBSUF" ; then
              ADDFLG=quit
           fi

           # call insert module if something has been changed
           if test $ED_WRITES_BKUP = yes ; then
              if test -f ${TMPFILE}~ -a $ADDFLG = add ; then
                 update
              elif test $ADDFLG = quit ; then
                 $DLGPRG --title "Change records in $DBTBL" \
                   --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                   --msgbox "ERROR: Can't change a log table" 6 40
              fi
           else # we have to look at the modification time
              FILE_MODTIME=$(ls -lG --full-time $TMPFILE)
              if test "$FILE_TIMESTAMP" != "$FILE_MODTIME" \
                 -a $ADDFLG = add ; then
                 update
              elif test $ADDFLG = quit ; then
                 $DLGPRG --title "Change records in $DBTBL" \
                   --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                   --msgbox "ERROR: Can't change a log table" 6 40
              fi
           fi
        else
           $DLGPRG --title "Result of the SELECT query:" \
                  --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                  --msgbox "\n           nothing found\n" 7 40
        fi
        fi
        ;;

   d|D) getquery
        if test -n "$QUERY" ; then
        # make sure we selected PRIKEY too
        unique
        # (bug: should account for ambigous column names
        #       like ' ... FROM table AS t1, table AS t2')
        PKA=$(echo "$QUERY" | sed \
           -e "s/ [Ff][Rr][Oo][Mm]  *.*//" \
           -e "/$PRIKEY/!d")
        PKB=$(echo "$QUERY" | sed \
           -e "s/ [Ff][Rr][Oo][Mm]  *.*//" \
           -e "/^ *[Ss][Ee][Ll][Ee][Cc][Tt]  *\\*/!d")
        PKF="${PKA}${PKB}"
        if test -z "$PKF" ; then
           QUERY=$(echo "$QUERY" | sed \
           -e "s/\\(.*[Ss][Ee][Ll][Ee][Cc][Tt]  *\\)\\(.*\\)/\\1$PRIKEY,\\2/")
        fi
        search
        TFL=$(wc -l $TMPFILE | cut -c 1-7 | sed -e "s/^ *//")
        if test $(($TFL)) -gt $((0)) ; then
           $EDITOR $EDOPTS $TMPFILE
           $DLGPRG --title "Delete from table $DBTBL" \
                  --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                  --yesno "Do you really want to DELETE all \
                           the records you have seen?" 7 40
           if test $? = "0" ; then
              delete
           fi
        else
           $DLGPRG --title "Result of the SELECT query:" \
                  --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                  --msgbox "\n           nothing found\n" 7 40
        fi
        fi
        ;;

        #
        # edit a query
        #
   e|E) QUIT=no
        QHDR="Columns from table $DBASE.$DBTBL:"
        QHDR="${QHDR}
$(preplbls)"
        QHDR="${QHDR}$(echo -e '\n\nedit SQL query here:\n')"
        echo "$QHDR" | sed -e "s/^/# /" \
           >$SCRIPT_DIR/newquery.sql

        SCRIPTS=$(ls --color=no -t -1 $SCRIPT_DIR/*.sql \
                  | sed -e "s|^.*/||" | cat -n - | sed -e "s/^ *//")

(IFS='	
'
        $DLGPRG --title "Edit and execute an SQL script" \
         --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
         --menu "Pick one of the existing scripts or 'newquery.sql'\n\
and edit as required. The script will be executed \n\
upon exiting the editor. To keep a new script it \n\
must be saved under a different new name with \n\
extension '*.sql'. With joe use ^KD for this." 21 60 10 \
        $SCRIPTS 2>${TMPFILE}.dia
        echo $? >${TMPFILE}.ret
)

        RETVAL=$(cat ${TMPFILE}.ret)
        rm -f ${TMPFILE}.ret

        if test "$RETVAL" = "255" -o "$RETVAL" = "1" ; then
           QUIT=yes
        else
           DIA=$(cat ${TMPFILE}.dia)
           EDFILE=$(echo "$SCRIPTS" | sed -e "/^ *$DIA	/!d" \
           -e "s/^ *$DIA	//")
        fi

        if test $QUIT = no ; then
        rm -f $SCRIPT_DIR/${EDFILE}~
        FILE_TIMESTAMP=$(ls -lG --full-time $SCRIPT_DIR/$EDFILE)

        # start the editor from the script directory
	( cd $SCRIPT_DIR && $EDITOR $EDOPTS $EDFILE )

        FILE_MODTIME=$(ls -lG --full-time $SCRIPT_DIR/$EDFILE)
        if test -f $SCRIPT_DIR/${EDFILE}~ -o \
           "$FILE_TIMESTAMP" != "$FILE_MODTIME" ; then
           if RST=$(cat $SCRIPT_DIR/${EDFILE} \
              | mysql -E $HOSTPRMS $DBASE \
              1>$TMPFILE 2>${TMPFILE}.err) ; then
              if test -s $TMPFILE ; then
                 # result file is greater than zero
                 ALNUM='A-Za-z0-9_$ '
                 SPACER=$(head -n 2 $TMPFILE | sed -e "1 d" \
                    -e "2 s/\\([$ALNUM][$ALNUM]*: \\)\\(.*\\)/\\1/" \
                    -e "2 s/./ /g")
                 # line folding hack; must be reworked later
                 INDENT=$(echo "$SPACER" | wc -c | sed 's/ *//')
                 # subtract 1 for the newline
                 INDENT=$(($INDENT - 1))
                 $FLDPRG $INDENT $SCREEN <$TMPFILE >$TMPFILE.tmp
                 rm $TMPFILE
                 mv $TMPFILE.tmp $TMPFILE
                 $EDITOR $EDOPTS $EDRDO $TMPFILE
              fi
           else
              QUERY=$(cat $SCRIPT_DIR/${EDFILE} | sed -e "/^#.*/d" \
                      | fold -s -w 55 | tail -n 10)
              ERRMSG=$(cat ${TMPFILE}.err | fold -s -w 55 )
              $DLGPRG --title "Edit and execute an SQL script" \
                     --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                     --msgbox "ERROR: the following query\n$QUERY\n\
resulted in message:\n$ERRMSG" 18 60
              rm -f ${TMPFILE}.err
           fi
        fi
        fi
        ;;

        # find data
   f|F) getquery
        if test -n "$QUERY" ; then
           rm -f $TMPFILE
           search   # puts results in $RST and in $TMPFILE
           # check length of resulting file
           if test -s $TMPFILE ; then
              ALNUM='A-Za-z0-9_$ '
              SPACER=$(head -n 2 $TMPFILE | sed -e "1 d" \
                 -e "2 s/\\([$ALNUM][$ALNUM]*: \\)\\(.*\\)/\\1/" \
                 -e "2 s/./ /g")
              # line folding hack; must be reworked later
              INDENT=$(echo "$SPACER" | wc -c | sed 's/ *//')
              # subtract 1 for the newline
              INDENT=$(($INDENT - 1))
              $FLDPRG $INDENT $SCREEN <$TMPFILE >$TMPFILE.tmp
              rm $TMPFILE
              mv $TMPFILE.tmp $TMPFILE
              $EDITOR $EDOPTS $EDRDO $TMPFILE
           else
              QUERY=$(echo "$QUERY" | fold -s -w 72)
              $DLGPRG --title "Result of the SELECT query:" \
                      --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                      --msgbox "\n\
                           Nothing found!\n\
Query:\n$QUERY\nresulted in message:\n$RST" 19 75
              errlog "find data: the following query\n\
$QUERY\n>returned:\n$RST"
           fi
        fi
        ;;

   h|H) showhelp
        ;;


        # output data to a file
        # we can't use the SELECT ... INTO OUTFILE 'file_name' form of SELECT
        # because this would write on the server host, but we want data
        # locally on the client host
   o|O) if test "$STRIP_AUTO_INC" = yes ; then
           STRIPMSG="(STRIP_AUTO_INC is ON)"
        else
           STRIPMSG=""
        fi
        $DLGPRG --title "Select and output data into outfile" \
         --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
         --menu "\nData to be selected with a SELECT query will be written\n\
to a file in a user supplied directory on the client host.\n\n\
The first step is to pick an output file format:" 15 75 4 \
"plain"  "standard <TAB> separated fields" \
"csv"    "comma separated value $STRIPMSG" \
"doscsv" "comma separated value with CR-LF $STRIPMSG" \
"screen" "display as csv on screen" 2>${TMPFILE}.dia
        RETVAL=$?
        QUIT=no

        if test $(($RETVAL)) -eq $((0)) ; then
           FORMAT=$(cat ${TMPFILE}.dia)
        else
           QUIT=yes
        fi

        if test $QUIT = no ; then
           # get a valid destination filename
           if test "$FORMAT" != screen ; then
              EXITLOOP=no
           else
              EXITLOOP=yes
           fi
           while test $EXITLOOP = no ; do
           $DLGPRG --title "Select and output data into outfile" \
            --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
            --inputbox "\nEnter the directory and a filename. Of course\n\
you must have write permission and existing files may not be\n\
overwritten" 12 65 "$(pwd)/" 2>${TMPFILE}.dia
           RETVAL=$?
           DESTFILE=$(cat ${TMPFILE}.dia)

           CURDIR=$(cat ${TMPFILE}.dia | sed -e "s/\\/[^/]*$//")
           FLOPPY=true  # false for mount failure, otherwise always true
           #
           # may be a floppy; mount it if we can; needs /etc/fstab entry
           # like: /dev/fd0  /floppy  auto  noauto,user  0  0
           # if some other user currently accesses /floppy both
           # umount and mount will fail (as it should)
           if test $CURDIR = $FLOPPYDRIVE ; then
              umount $FLOPPYDRIVE >/dev/null 2>&1
              mount $FLOPPYDRIVE >/dev/null 2>&1 || FLOPPY=false
           fi

           if ! test -d "$CURDIR" -a -w "$CURDIR" -a $FLOPPY = true ; then
              $DLGPRG --title "Select and output data into outfile" \
              --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
              --msgbox "ERROR: Directory $CURDIR does not exist \
on host $HOSTNAME or $CURDIR is not writable for user $USERNAME \
or failure to mount floppy drive." 9 50
              QUIT=yes
              EXITLOOP=no
           else
              if test $(($RETVAL)) -eq $((0)) ; then
                 if test -z "$DESTFILE" ; then
                    QUIT=yes
                    EXITLOOP=yes
                 elif test -e "$DESTFILE" -a "$MAY_OVERWRITE" = no ; then
                    QUIT=yes
                    EXITLOOP=no # ask again
                    $DLGPRG --title "Select and output data into outfile" \
                     --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                     --infobox "\n\
                       ERROR: File exists" 5 65
                    sleep $INFOTIME
                 else
                    EXITLOOP=yes
                 fi
              else
                 QUIT=yes
                 EXITLOOP=yes
              fi
           fi
           done # END OF THE LOOP
        fi

        if test $QUIT = no ; then
           getquery
           echo "$QUERY" | mysql --batch $HOSTPRMS $DBASE \
              1>$TMPFILE 2>${TMPFILE}.err
           RST=$(cat ${TMPFILE}.err | fold -s -w 61 )
           rm -f ${TMPFILE}.err
           if test -n "$RST" ; then
                $DLGPRG --title "Select and output data into outfile" \
                --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                --msgbox "ERROR selecting data. Your query has \
resulted in this message:\n\n$RST" 12 66
           else

             if test "$STRIP_AUTO_INC" = yes ; then
                CSVCOL=$(echo "show columns from $DBTBL;" \
                | mysql --batch $HOSTPRMS $DBASE | sed -e "1 d" \
                | cat -n - )

                CSVMSK=$(echo "$CSVCOL" \
                | sed -e "/	auto_increment/!d" \
                      -e "s/^ *//" -e "s/	.*$//" )

                # what is the last column?
                CSVLST=$(echo "$CSVCOL" \
                | sed -e "$ !d" -e "s/^ *//" -e "s/	.*$//" )

                if test -z "$CSVMSK" ; then
                   CUTFLD="1-"
                elif test $(($CSVMSK)) -eq $((1)) ; then
                   CUTFLD="2-"
                elif test $(($CSVMSK)) -eq $(($CSVLST)) ; then
                   CUTFLD="-$(($CSVLST-1))"
                else
                   CUTFLD="-$(($CSVMSK-1)),$(($CSVMSK+1))-"
                fi
             else
                CUTFLD="1-"
             fi

             case $FORMAT in

             plain)  cp $TMPFILE $DESTFILE
                     ;;

             csv)    cat $TMPFILE | cut -f $CUTFLD | sed -e 's/;/|$|/g' \
                     -e 's/"/|$$|/g' -e 's/	/;/g' \
                     -e 's/[^;|]*|$$*|[^;]*/"&"/g' \
                     -e 's/|$$|/""/g' -e 's/|$|/;/g' \
                     -e 's/\\t/	/g' >$DESTFILE
                     ;;

             doscsv) cat $TMPFILE | cut -f $CUTFLD | sed -e 's/;/|$|/g' \
                     -e 's/"/|$$|/g' -e 's/	/;/g' \
                     -e 's/[^;|]*|$$*|[^;]*/"&"/g' \
                     -e 's/|$$|/""/g' -e 's/|$|/;/g' \
                     -e 's/\\t/	/g' -e 's/$/
/' >$DESTFILE
                     ;;

             screen) cat $TMPFILE | cut -f $CUTFLD | sed -e 's/;/|$|/g' \
                     -e 's/"/|$$|/g' -e 's/	/;/g' \
                     -e 's/[^;|]*|$$*|[^;]*/"&"/g' \
                     -e 's/|$$|/""/g' -e 's/|$|/;/g' \
                     -e 's/\\t/	/g' > ${TMPFILE}.dia
                     rm $TMPFILE ; mv ${TMPFILE}.dia $TMPFILE
                     $DEFAULTEDITOR $EDRDO $TMPFILE
                     ;;

             esac
           fi
        fi
        ;;

        # print data
   p|P) getquery
        if test -n "$QUERY" ; then
           rm -f $TMPFILE
           search   # puts results in $RST and in $TMPFILE
           # check length of resulting file
           if test -s $TMPFILE ; then
              ALNUM='A-Za-z0-9_$ '
              SPACER=$(head -n 2 $TMPFILE | sed -e "1 d" \
                 -e "2 s/\\([$ALNUM][$ALNUM]*: \\)\\(.*\\)/\\1/" \
                 -e "2 s/./ /g")
              # line folding hack; must be reworked later
              INDENT=$(echo "$SPACER" | wc -c | sed 's/ *//')
              # subtract 1 for the newline
              INDENT=$(($INDENT - 1))
              # fold and replace question marks
              $FLDPRG $INDENT $SCREEN <$TMPFILE \
                 | sed -e "s/?/?quest/g" >$TMPFILE.tmp
              # make something printable out of this data
              # create a filename
              PRINT_FILE=$(date "+$DBTBL-%Y.%m.%d-")$$
              #echo "using filename $PRINT_FILE"; sleep 20
              cat $VERBHDR $TMPFILE.tmp $VERBEND >$PRINT_DIR/$PRINT_FILE.tex
              rm -f $TMPFILE.tmp
              (cd $PRINT_DIR && $TEXPROG $PRINT_FILE.tex >/dev/null 2>&1)
              sync
              if test -e $PRINT_DIR/$PRINT_FILE.dvi ; then
                 rm -f $PRINT_DIR/$PRINT_FILE.log
                 # extract name of printer / check status
                 PR_NAME=$(echo "$PRINTER" | sed -e "s/-P//")
                 #echo "Printer is: $PR_NAME"; sleep 1
                 PRINTER_STATUS=$(lpc status $PR_NAME \
                  | sed -e "/queuing/ !d" -e "s/	queuing is //")
                 #echo "Printer status = $PRINTER_STATUS";
                 if test "$PRINTER_STATUS" = "enabled" ; then
                    (cd $PRINT_DIR && dvips -q $PRINTER -o $PRINT_FILE.ps \
                     $PRINT_FILE.dvi)
                    #echo "doing lpr"; sleep 1
                    lpr $PRINTER $PRINT_DIR/$PRINT_FILE.ps
                    rm -f $PRINT_DIR/$PRINT_FILE.ps
                 fi
              fi
           else
              QUERY=$(echo "$QUERY" | fold -s -w 72)
              $DLGPRG --title "Result of the SELECT query:" \
                      --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                      --msgbox "\n\
                           Nothing found!\n\
Query:\n$QUERY\nresulted in message:\n$RST" 19 75
              errlog "find data: the following query\n\
$QUERY\n>returned:\n$RST"
           fi
        fi
        ;;

   s|S) specials
        ;;

   t|T) LAST_TB="$DBTBL"
        chgtable # on row 807
        chklogtbl
        rm -f ${TMPFILE}.qry
        ;;

        # use another database (affects the current table too)
   u|U) AVDB=$(mysqlshow $HOSTPRMS | sed \
         -e "/^+--*/d" -e "/^| Databases  *|/d" \
         -e "s/^|  *//" -e "s/  *|/ off/" | sed \
         -e "/^${DEFAULT_DB} off$/s/ off$/ on/" | cat -b - )

        DIALEN=$(echo "$AVDB" | wc --lines)
        if test $(($DIALEN)) -gt $((12)) ; then
           DIALEN=12
        fi
        DIABOX=$(($DIALEN + 7))
        $DLGPRG --title "Select database" \
          --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
          --radiolist "available databases are:" \
          $DIABOX 40 $DIALEN $AVDB 2>${TMPFILE}.dia
        RETVAL=$?
        DIA=$(cat ${TMPFILE}.dia)

        NEWDBASE=$(echo "$AVDB" | sed -e "/^ *$DIA	/!d" \
         -e "s/^ *$DIA	//" -e "s/  *o[nf]f*$//")

        if test "$RETVAL" = 255 -o "$RETVAL" = 1 ; then
           NEWDBASE=""
        fi

        if test -n "$NEWDBASE" ; then
           # try to open this database
           if ! mysqlshow $HOSTPRMS "$NEWDBASE" >/dev/null 2>&1 ; then
              $DLGPRG --title "Select database" \
               --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
               --msgbox "ERROR: can't connect to database $NEWDBASE" \
               6 40
           else
              LAST_DB="$DBASE"
              DBASE="$NEWDBASE"
              errlog "using new database $DBASE"
              if test "$DBASE" != "$LAST_DB" \
                 -a "$LAST_RULES" = yes -a -w $UCNF ; then
                 cat $UCNF | sed \
                    -e "/^# default_database .*$/d" > ${TMPFILE}.db
                 cp ${TMPFILE}.db $UCNF ; rm -f ${TMPFILE}.db
                 echo "# default_database $DBASE" >> $UCNF
              fi

              # get a new table; user's default or ask
              # what was the last table used?
              LAST_TB="$DBTBL"
              DBTBL=""
              if test -r $UCNF ; then
                 # try to get a default
                 DBTBL=$(cat $UCNF | sed \
                    -e "/# default_table $DBASE /!d" \
                    -e "s/# default_table $DBASE //")
              fi

              if test -z "$DBTBL" ; then
                 chgtable
              fi

              # now there's a new table; verify that it's useable
              # (or <none>)
              if test $DBTBL != '<none>' ; then
                 if ! mysqlshow $HOSTPRMS $DBASE $DBTBL >/dev/null \
                    2>&1 ; then
                    $DLGPRG --title "Select database" \
                    --backtitle " db (Ver. $DB_VERSION) $HOSTINFO" \
                    --msgbox "ERROR: could not access new database \
\"$DBASE\" table \"$NEWDBTBL\"; using old values database = $LAST_DB \
and table = $LAST_TB" 10 40
                    DBASE="$LAST_DB"
                    DBTBL="$LAST_TB"
                 else
                    # we have a useable new table
                    chklogtbl
                    if test "$DBTBL" != "$LAST_TB" \
                       -a "$LAST_RULES" = yes -a -w $UCNF ; then
                       cat $UCNF | sed \
                       -e "/^# default_table $DBASE .*$/d" > ${TMPFILE}.db
                       cp ${TMPFILE}.db $UCNF ; rm -f ${TMPFILE}.db
                       echo "# default_table $DBASE $DBTBL" >> $UCNF
                    fi
                 fi
              fi
           fi
        fi
        ;;

   q|Q) echo ; echo "Bye"
        rm -f ${TMPFILE}*
        FC=q
        ;;

    ls) echo ; ls
        ;;

  noop) # do nothing
        ;;

     *) if test -z "$FC" ; then
           echo "Bye"
           rm -f ${TMPFILE}*
           FC=q
        else
           echo "unknown command $FC"
        fi
        ;;
esac
done

exit
