#!/bin/ksh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License, Version 1.0 only
# (the "License").  You may not use this file except in compliance
# with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2006 Bernd Schemmer  All rights reserved.
# Use is subject to license terms.
#
# use "start_xen.sh -H 2 >start_xen.sh.doc" to get the documentation
##
# -----------------------------------------------------------------------------
##
## start_xen.sh - start a xen DomU domain
##
## Author: Bernd Schemmer (Bernd.Schemmer@gmx.de)
##
## Version: see variable ${__SCRIPT_VERSION} below
##          (see variable ${__SCRIPT_TEMPLATE_VERSION} for the template 
##           version used)
##
## Supported OS: Solaris 
##
##      Solaris 10 and above with Xen support
##
##      Tested with Xen for Solaris 07/2006 drop and the 08/2006 drop
##
## Description
## 
##  This script is used to start Xen DomU domains.
##
## Configuration file
##
## This script supports a configuration file called start_xen.conf.
## The configuration file is searched in the working directory,
## the home directory of the user execting this script and /etc
## (in this order).
##
## The configuration file is read before the parameter are read.
##
## See the variable __CONFIG_PARAMETER below for the possible entries in 
## the config file.
## 
## Predefined parameter
##
## see the subroutines ShowShortUsage and ShowUsage 
##
##
## History:
##   14.09.2006 v0.0.1 /bs
##     initial release
##
##
##
## Predefined return codes:
##
##    1 - show usage and exit
##    2 - invalid parameter found
##
##  246 - error writing the config file
##  247 - include script not found
##  248 - unsupported OS version
##  249 - Script not executed by root
##  250 - Script is already running
##
##  252 - User break
##  251 - QUIT signal received
##  253 - TERM signal received
##  254 - unknown external signal received
##   

# -----------------------------------------------------------------------------

##
## ##### general hints
##
## Do not use variable names beginning with __ (these are reserved for
## internal use)
##

## -----------------------------------------------------------------------------
## constants
##
## __TRUE - true (0)
## __FALSE - false (1)
##
typeset -r __TRUE=0
typeset -r __FALSE=1

typeset -r __INVALID_USAGE=-1

# -----------------------------------------------------------------------------
# undocumented features : use --tee to automatically call the script and pipe 
# all output to tee
#
#
if [[ $* == *--tee*  ]] ; then
  T=$( which tee )
  if [ "${T}"x != ""x -a "${T}"x != "no"x ] ; then
    F="/var/log/$( basename $0 ).tee.log"
    echo "Saving STDOUT and STDERR to \"${F}\" ..."
    P="$*"
    $0 ${P%%--tee*} ${P##*--tee} 2>&1 | ${T} -a "${F}"
    exit $?
  fi
fi


# set LANG to a known value
#
export LANG=C


## -----------------------------------------------------------------------------
##
## Uncomment the next if block if you want the script running with RBAC control
## (Solaris 10 and newer only!)
##
## Allow the use of RBAC to control who can access this script. Useful for
## administrators without root permissions
##

##if [ "$_" != "/usr/bin/pfexec" -a -x /usr/bin/pfexec ]; then
##        /usr/bin/pfexec $0 $*
##        exit $?
##fi


## -----------------------------------------------------------------------------
## 
## ##### defined variables that may be changed
##

## __DEBUG_CODE - code executed at start of every predefined sub routine
##
__DEBUG_CODE=""


TESTED_XEN_VERSION="11.11,REV=2006.08.16.05.19"

## __CONFIG_PARAMETER
##   The variable __CONFIG_PARAMETER contains the configuraton variables
##
# The defaults for these variables are defined here. You 
# can use a config file to overwrite the defaults. 
#
# Use the parameter -C to create a default configuration file
#
# Note: The config file is read and interpreted via ". configfile"  -> you can add 
##      also some code her!
#
__CONFIG_PARAMETER='

# extension for backup files

  DEFAULT_BACKUP_EXTENSION=".$$.backup"

  
# action and parameter
# (use the parameter -G/+G to change this variable)
#
  DEFAULT_STARTED_VIA_GUI=${__TRUE}

  DEFAULT_ACTION="start"
  DEFAULT_ACTION_PARAMETER=""
  DEFAULT_ACTION_PARAMETER2=""

# output file
# (use the parameter -o to change this variable)
#
  DEFAULT_OUTPUT_FILE=""

# xen SMF FRMI
#
# Note: The FRMI was different in the 07_2006 Xen drop and it may be again
#       different in the next Xen drop
#
  DEFAULT_XEN_FRMI="svc:/system/xen/xend:default"
  
# xm binary
#
  DEFAULT_XM_BINARY="/usr/sbin/xm"
  
# directory with the xen config files
#
  DEFAULT_XEN_CONFIGDIR="/export/xen-images"

# default parameter for xm
#
  DEFAULT_XM_PARAMETER=""

# default terminal program to use for the console of the domain
# (may be overwritten by the domain definition)
#
# Note: The  binary must be parameter compatible to xterm!
#
  DEFAULT_XTERM_BINARY="/usr/openwin/bin/xterm"

# default parameter for the xterm
# (may be overwritten by the domain definition)
#
  DEFAULT_XTERM_PARAMETER="-sl 1000 -sb"

# default vncviewer binary
# (may be overwritten by the domain definition)
#
  DEFAULT_VNCVIEWER_BINARY="/opt/sfw/bin/vncviewer"

# default parameter for the vncviewer
# (may be overwritten by the domain definition)
#
  DEFAULT_VNCVIEWER_PARAMETER=""

# start the domain?
# (may be overwritten by the domain definition or
# by the parameter -x)
#
  DEFAULT_START_XEN_DOMAIN=${__TRUE}

# start the vnc viewer?
# (may be overwritten by the domain definition or
# by the parameter -g)
#
  DEFAULT_START_VNCVIEWER=${__TRUE}
  
# start the console window?
# (may be overwritten by the domain definition or
# by the parameter -c)
#
  DEFAULT_START_CONSOLE_WINDOW=${__TRUE}

# default type of the domain (either 32 for 32 Bit 
# or 64 for 64 Bit)
# (may be overwritten by the domain definition)
#
  DEFAULT_DOMAIN_TYPE="32"

# xm configuration 
#
  typeset -u XEN_CONFIG=""

# default VNC port
#
  DEFAULT_VNCVIEWER_PORT=5900

# no of pings to send before we start the VNC viewer 
# (may be overwritten by the domain definition)
#
  DEFAULT_PING_RETRY_COUNT=5

# no of seconds to wait after the IP stack of the domain is up until we 
# start the vncviewer
#
  DEFAULT_VNC_STARTUP_DELAY=5


# -----------------------------------------------------------------------------
# definitions for the Xen domains

#   "start_ubuntu6_img.sh")
#
  UBUNTU6_IMG_TITLE="Ubuntu6 (img) Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  UBUNTU6_IMG_CONFIG_FILE_NAME="ubuntu6_img.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  UBUNTU6_IMG_IP_ADDRESS="192.168.178.122"

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  UBUNTU6_IMG_HOSTNAME=""

# start the domain? (use default if empty)
#
  UBUNTU6_IMG_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  UBUNTU6_IMG_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  UBUNTU6_IMG_START_VNCVIEWER=${__TRUE}

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  UBUNTU6_IMG_PING_RETRY_COUNT=5

# Background color for the console window
#
  UBUNTU6_IMG_BG_COLOR="black"

# Background color for the console window
#
  UBUNTU6_IMG_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  UBUNTU6_IMG_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  UBUNTU6_IMG_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  UBUNTU6_IMG_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  UBUNTU6_IMG_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  UBUNTU6_IMG_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  UBUNTU6_IMG_DOMAIN_TYPE="32"


# -----------------------------------------------------------------------------
# definitions for the Xen domains

#   "start_centos1.sh")
#
  CENTOS1_TITLE="Centos1 Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  CENTOS1_CONFIG_FILE_NAME="centos1.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  CENTOS1_IP_ADDRESS="192.168.178.115"

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  CENTOS1_HOSTNAME=""

# start the domain? (use default if empty)
#
  CENTOS1_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  CENTOS1_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  CENTOS1_START_VNCVIEWER=${__TRUE}

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  CENTOS1_PING_RETRY_COUNT=5

# Background color for the console window
#
  CENTOS1_BG_COLOR="black"

# Background color for the console window
#
  CENTOS1_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  CENTOS1_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  CENTOS1_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  CENTOS1_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  CENTOS1_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  CENTOS1_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  CENTOS1_DOMAIN_TYPE="32"


# -----------------------------------------------------------------------------
#   "start_UBUNTU6.sh")
#
  UBUNTU6_TITLE="UBUNTU6 (/dev/sda5) Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  UBUNTU6_CONFIG_FILE_NAME="ubuntu6.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  UBUNTU6_IP_ADDRESS="192.168.178.121"

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  UBUNTU6_HOSTNAME=""

# start the domain?  (use default if empty)
#
  UBUNTU6_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  UBUNTU6_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  UBUNTU6_START_VNCVIEWER=${__TRUE}

# no of seconds to wait after the IP stack of the domain is up until we 
# start the vncviewer
#
  UBUNTU6_VNC_STARTUP_DELAY=30

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  UBUNTU6_PING_RETRY_COUNT=5

# Background color for the console window
#
  UBUNTU6_BG_COLOR="black"

# Background color for the console window
#
  UBUNTU6_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  UBUNTU6_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  UBUNTU6_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  UBUNTU6_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  UBUNTU6_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  UBUNTU6_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  UBUNTU6_DOMAIN_TYPE="32"


# -----------------------------------------------------------------------------
#   "start_debian.sh")
#
  DEBIAN_TITLE="Debian Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  DEBIAN_CONFIG_FILE_NAME="debian.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  DEBIAN_IP_ADDRESS="192.168.178.117"

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  DEBIAN_HOSTNAME=""

# start the domain?  (use default if empty)
#
  DEBIAN_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  DEBIAN_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  DEBIAN_START_VNCVIEWER=${__TRUE}

# no of seconds to wait after the IP stack of the domain is up until we 
# start the vncviewer
#
  DEBIAN_VNC_STARTUP_DELAY=30

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  DEBIAN_PING_RETRY_COUNT=5

# Background color for the console window
#
  DEBIAN_BG_COLOR="black"

# Background color for the console window
#
  DEBIAN_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  DEBIAN_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  DEBIAN_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  DEBIAN_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  DEBIAN_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  DEBIAN_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  DEBIAN_DOMAIN_TYPE="32"

# -----------------------------------------------------------------------------
#   "start_opensuse.sh")
#
  OPENSUSE_TITLE="openSUSE Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  OPENSUSE_CONFIG_FILE_NAME="openSUSE.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  OPENSUSE_IP_ADDRESS="192.168.178.116"

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  OPENSUSE_HOSTNAME=""

# start the domain? (use default if empty)
#
  OPENSUSE_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  OPENSUSE_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  OPENSUSE_START_VNCVIEWER=${__TRUE}

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  OPENSUSE_PING_RETRY_COUNT=5

# Background color for the console window
#
  OPENSUSE_BG_COLOR="black"

# Background color for the console window
#
  OPENSUSE_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  OPENSUSE_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  OPENSUSE_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  OPENSUSE_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  OPENSUSE_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  OPENSUSE_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  OPENSUSE_DOMAIN_TYPE="32"

# -----------------------------------------------------------------------------
#   "start_slackware.sh")
#
  SLACKWARE_TITLE="slackware Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  SLACKWARE_CONFIG_FILE_NAME="slackware.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  SLACKWARE_IP_ADDRESS=""

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  SLACKWARE_HOSTNAME=""

# start the domain? (use default if empty)
#
  SLACKWARE_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  SLACKWARE_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  SLACKWARE_START_VNCVIEWER=${__FALSE}

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  SLACKWARE_PING_RETRY_COUNT=5

# Background color for the console window
#
  SLACKWARE_BG_COLOR="black"

# Background color for the console window
#
  SLACKWARE_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  SLACKWARE_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  SLACKWARE_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  SLACKWARE_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  SLACKWARE_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  SLACKWARE_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  SLACKWARE_DOMAIN_TYPE="32"


# -----------------------------------------------------------------------------
#   "start_gentoo2006.sh")
#
  GENTOO2006_TITLE="GENTOO2006 Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  GENTOO2006_CONFIG_FILE_NAME="gentoo2006.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  GENTOO2006_IP_ADDRESS=""

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  GENTOO2006_HOSTNAME=""

# start the domain? (use default if empty)
#
  GENTOO2006_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  GENTOO2006_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  GENTOO2006_START_VNCVIEWER=${__FALSE}

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  GENTOO2006_PING_RETRY_COUNT=5

# Background color for the console window
#
  GENTOO2006_BG_COLOR="black"

# Background color for the console window
#
  GENTOO2006_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  GENTOO2006_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  GENTOO2006_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  GENTOO2006_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  GENTOO2006_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  GENTOO2006_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  GENTOO2006_DOMAIN_TYPE="32"

# -----------------------------------------------------------------------------
#   "start_mydomU.sh")
#
  MYDOMU_TITLE="Solaris 10 (SUNWXCall) Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  MYDOMU_CONFIG_FILE_NAME="mydomU.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  MYDOMU_IP_ADDRESS="192.168.178.119"

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  MYDOMU_HOSTNAME=""

# start the domain? (use default if empty)
#
  MYDOMU_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  MYDOMU_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  MYDOMU_START_VNCVIEWER=${__TRUE}

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  MYDOMU_PING_RETRY_COUNT=5

# no of seconds to wait after the IP stack of the domain is up until we 
# start the vncviewer
#
  MYDOMU_VNC_STARTUP_DELAY=20
  
# Background color for the console window
#
  MYDOMU_BG_COLOR="black"

# Background color for the console window
#
  MYDOMU_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  MYDOMU_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  MYDOMU_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  MYDOMU_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  MYDOMU_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  MYDOMU_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  MYDOMU_DOMAIN_TYPE="32"

# -----------------------------------------------------------------------------
#   "start_mydmoU1.sh")
#
  MYDOMU1_TITLE="Solaris 10 (SUNWCore) Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  MYDOMU1_CONFIG_FILE_NAME="mydomU1.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  MYDOMU1_IP_ADDRESS="192.168.178.118"

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  MYDOMU1_HOSTNAME=""

# start the domain? (use default if empty)
#
  MYDOMU1_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  MYDOMU1_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  MYDOMU1_START_VNCVIEWER=${__FALSE}

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  MYDOMU1_PING_RETRY_COUNT=5

# no of seconds to wait after the IP stack of the domain is up until we 
# start the vncviewer
#
  MYDOMU1_VNC_STARTUP_DELAY=20

# Background color for the console window
#
  MYDOMU1_BG_COLOR="black"

# Background color for the console window
#
  MYDOMU1_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  MYDOMU1_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  MYDOMU1_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  MYDOMU1_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  MYDOMU1_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  MYDOMU1_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  MYDOMU1_DOMAIN_TYPE="32"


# -----------------------------------------------------------------------------
#   "start_mydmoU1_64.sh")
#
  MYDOMU1_64_TITLE="Solaris 10 (SUNWCore) Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  MYDOMU1_64_CONFIG_FILE_NAME="mydomU1_64.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  MYDOMU1_64_IP_ADDRESS="192.168.178.118"

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  MYDOMU1_64_HOSTNAME=""

# start the domain? (use default if empty)
#
  MYDOMU1_64_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  MYDOMU1_64_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  MYDOMU1_64_START_VNCVIEWER=${__FALSE}

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  MYDOMU1_64_PING_RETRY_COUNT=5

# no of seconds to wait after the IP stack of the domain is up until we 
# start the vncviewer
#
  MYDOMU1_64_VNC_STARTUP_DELAY=20

# Background color for the console window
#
  MYDOMU1_64_BG_COLOR="black"

# Background color for the console window
#
  MYDOMU1_64_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  MYDOMU1_64_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  MYDOMU1_64_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  MYDOMU1_64_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  MYDOMU1_64_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  MYDOMU1_64_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  MYDOMU1_64_DOMAIN_TYPE="64"

# -----------------------------------------------------------------------------
#   "start_mydmoU_64.sh")
#
  MYDOMU_64_TITLE="Solaris 10 (SUNWCore) Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  MYDOMU_64_CONFIG_FILE_NAME="mydomU_64.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  MYDOMU_64_IP_ADDRESS="192.168.178.119"

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  MYDOMU_64_HOSTNAME=""

# start the domain? (use default if empty)
#
  MYDOMU_64_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  MYDOMU_64_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  MYDOMU_64_START_VNCVIEWER=${__TRUE}

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  MYDOMU_64_PING_RETRY_COUNT=5

# no of seconds to wait after the IP stack of the domain is up until we 
# start the vncviewer
#
  MYDOMU_64_VNC_STARTUP_DELAY=20

# Background color for the console window
#
  MYDOMU_64_BG_COLOR="black"

# Background color for the console window
#
  MYDOMU_64_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  MYDOMU_64_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  MYDOMU_64_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  MYDOMU_64_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  MYDOMU_64_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  MYDOMU_64_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  MYDOMU_64_DOMAIN_TYPE="64"


# -----------------------------------------------------------------------------
#   "start_sol10snv44.sh")
#
  SOL10SNV44_TITLE="Solaris 10 (snv44 from OpenSolaris) Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  SOL10SNV44_CONFIG_FILE_NAME="solaris-b44.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  SOL10SNV44_IP_ADDRESS="192.168.178.120"

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  SOL10SNV44_HOSTNAME=""

# start the domain? (use default if empty)
#
  SOL10SNV44_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  SOL10SNV44_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  SOL10SNV44_START_VNCVIEWER=${__FALSE}

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  SOL10SNV44_PING_RETRY_COUNT=5

# no of seconds to wait after the IP stack of the domain is up until we 
# start the vncviewer
#
  SOL10SNV44_VNC_STARTUP_DELAY=20
  
# Background color for the console window
#
  SOL10SNV44_BG_COLOR="black"

# Background color for the console window
#
  SOL10SNV44_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  SOL10SNV44_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  SOL10SNV44_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  SOL10SNV44_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  SOL10SNV44_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  SOL10SNV44_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  SOL10SNV44_DOMAIN_TYPE="32"


# -----------------------------------------------------------------------------
#   "start_SOL10SNV44_64.sh")
#
  SOL10SNV44_64_TITLE="Solaris 10 64 Bit (snv44 from OpenSolaris) Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  SOL10SNV44_64_CONFIG_FILE_NAME="solaris-b44.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  SOL10SNV44_64_IP_ADDRESS="192.168.178.120"

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  SOL10SNV44_64_HOSTNAME=""

# start the domain? (use default if empty)
#
  SOL10SNV44_64_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  SOL10SNV44_64_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  SOL10SNV44_64_START_VNCVIEWER=${__FALSE}

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  SOL10SNV44_64_PING_RETRY_COUNT=5

# no of seconds to wait after the IP stack of the domain is up until we 
# start the vncviewer
#
  SOL10SNV44_64_VNC_STARTUP_DELAY=20
  
# Background color for the console window
#
  SOL10SNV44_64_BG_COLOR="black"

# Background color for the console window
#
  SOL10SNV44_64_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  SOL10SNV44_64_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  SOL10SNV44_64_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  SOL10SNV44_64_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  SOL10SNV44_64_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  SOL10SNV44_64_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  SOL10SNV44_64_DOMAIN_TYPE="64"


# -----------------------------------------------------------------------------
# definitions for the Xen domains

#   "start_freebsd.sh")
#
  FREEBSD_TITLE="freebsd 7.0 Xen domain"
  
# Note: If the filename is not fully qualified the
#       file is searched in the directory with the
#       config files
#
  FREEBSD_CONFIG_FILE_NAME="freebsd70.phy"

# IP address of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  FREEBSD_IP_ADDRESS=""

# Hostname of the domain
# Note: If IP address and hostname is set, the IP address is ignored
#
  FREEBSD_HOSTNAME=""

# start the domain? (use default if empty)
#
  FREEBSD_START_XEN_DOMAIN=${__TRUE}

# Start the console window? (use default if empty)
#
  FREEBSD_START_CONSOLE_WINDOW=${__TRUE}

# Start a vncviewer? (use default if empty)
#
  FREEBSD_START_VNCVIEWER=${__FALSE}

# no of pings to send before we start the VNC viewer 
# (use default if empty)
#
  FREEBSD_PING_RETRY_COUNT=5

# Background color for the console window
#
  FREEBSD_BG_COLOR="black"

# Background color for the console window
#
  FREEBSD_FG_COLOR="yellow"

# xterm for the console (use default if empty)
#
  FREEBSD_XTERM_BINARY=""

# parameter for the xterm (use default if empty)
#
  FREEBSD_XTERM_PARAMETER=""

# add. parameter for the xterm 
#
  FREEBSD_XTERM_ADD_PARAMETER=""

# vncviewer for this domain (use default if empty)
#
  FREEBSD_VNCVIEWER_BINARY=""

# add. parameter for the vncviewer
#
  FREEBSD_VNCVIEWER_ADD_PARAMETER=""

# type of this domain (use default if empty)
#
  FREEBSD_DOMAIN_TYPE="32"


# only change the following variables if you know what you are doing #

## sample debug code:
## __DEBUG_CODE="  eval echo Entering the subroutine \$__FUNCTION ...  "

## Note: Use an include script for more complicate debug code, e.g.
## __DEBUG_CODE=" eval . /var/tmp/mydebugcode"
##

# Note:zenity is not used in this script
#
ZENITY_OK=0
DIALOG_OK=${ZENITY_OK}

ZENITY_CANCEL=1
DIALOG_CANCEL=${ZENITY_CANCEL}

ZENITY_ERROR=2 
DIALOG_ERROR=${ZENITY_ERROR}

ZENITY_ESC=3 
DIALOG_ESC=${ZENITY_ESC}

export ZENITY_OK ZENITY_CANCEL ZENITY_ERROR ZENITY_ESC
export DIALOG_OK DIALOG_ERROR DIALOG_CANCEL DIALOG_ESC

# no further internal variables defined yet
'
# end of config parameters


## __SHORT_DESC - short description (for help texts, etc)
##                Change to your need
##
typeset -r __SHORT_DESC="start a Xen DomU"

## __SCRIPT_VERSION - the version of your script 
##
typeset -r __SCRIPT_VERSION="v0.0.1"

## __SCRIPT_TEMPLATE_VERSION - version of the template
##
typeset -r __SCRIPT_TEMPLATE_VERSION="1.21.6 04/27/2006"

## __MUST_BE_ROOT (def.: false)
##   set to ${__TRUE} for scripts that must be executed by root only
##
__MUST_BE_ROOT=${__FALSE}

## __ONLY_ONCE (def.: false)
##   set to ${__TRUE} for scripts that can not run more than one 
##   instance at the same time
##
__ONLY_ONCE=${__FALSE}

## __REQUIRED_OS_VERSION
##   minimum OS version necessary, e.g. 5.10; "" - no minimum OS version check necessary
## 
__REQUIRED_OS_VERSION=""

## __VERBOSE_LEVEL - count of -v parameter (def. 0)
##
typeset -i __VERBOSE_LEVEL=0

## __RT_VERBOSE_LEVEL - level of -v for runtime  messages
##
## e.g. 1 = -v -v is necessary to print info messages of the runtime system
##      2 = -v -v -v is necessary to print info messages of the runtime system
##
##
__RT_VERBOSE_LEVEL=1

## __QUIET_MODE - do not  print messages to STDOUT (def.: false)
##   use the parameter -q/+q to change this variable
##
__QUIET_MODE=${__FALSE}


## __VERBOSE_MODE - print verbose messages (def. false)
##   use the parameter -v/+v to change this variable  
##
__VERBOSE_MODE=${__FALSE}


## __FORCE - do the action anyway (-> the function "die" will return 
##   if called with an RC not zero)
##   use the parameter -f/+f to change this variable
##
__FORCE=${__FALSE}

## __USE_COLORS - use colors (def. false) use the parameter -a/+a to 
##   change this variable
##
__USE_COLORS=${__FALSE}

## __USER_BREAK_ALLOWED - CTRL-C aborts program or not (def. true)
##   (no parameter to change this variable)
##
__USER_BREAK_ALLOWED=${__TRUE}

## __OVERWRITE mode - overwrite existing files or not (def. false
##   use the parameter -O/+O to change this variable
##
__OVERWRITE_MODE=${__FALSE}

## __DEBUG_MODE - use single step mode for main (def. false)
##   use the parameter -D/+D to change this variable
##
__DEBUG_MODE=${__FALSE}
__SCRIPT_ARRAY[0]=0

## __LIST_OF_TMP_MOUNTS - list of mounts that should be umounted at program end
##
__LIST_OF_TMP_MOUNTS=""

## __LIST_OF_TMP_DIRS - list of directories that should be removed at program end
##
__LIST_OF_TMP_DIRS=""

## __LIST_OF_TMP_FILES - list of files that should be removed at program end
##
__LIST_OF_TMP_FILES=""

## __EXITROUTINES - list of routines that should be executed before the script ends
##
__EXITROUTINES=""

## __REBOOT_REQUIRED - set to true to reboot automatically at 
##   script end (def. false)
##
__REBOOT_REQUIRED=${__FALSE}

## __REBOOT_PARAMETER - parameter for the reboot command (def.: none)
##
__REBOOT_PARAMETER=""

## __PRINT_LIST_OF_WARNINGS_MSGS
##   print the list of warning messages at program end (def. false)
##
__PRINT_LIST_OF_WARNINGS_MSGS=${__FALSE}

## __PRINT_LIST_OF_ERROR_MSGS
##   print the list of error messages at program end (def. false)
##
__PRINT_LIST_OF_ERROR_MSGS=${__FALSE}

## __PRINT_SUMMARIES - print error/warning msg summaries at script end
##
## print error and/or warning message summaries at program end
##  known values:
##       0 no summarys, 
##       1 = print error msgs,
##       2 = print warning msgs
##       3 = print error and warning mgs
## Use the parameter -S to change this variable
##
__PRINT_SUMMARIES=0

## __MAINRC - return code of the program 
##
__MAINRC=0


# -----------------------------------------------------------------------------
#

# -----------------------------------------------------------------------------
# init the global variables
#

## ##### defined variables that should not be changed
##

# init the variable for the TRAP handlers  
  __INCLUDE_SCRIPT_RUNNING=""

# 
# internal variables for push/pop
#
typeset -i __STACK_POINTER=0
__STACK[0]=${__STACK_POINTER}

#
# internal variables for the single-step routine
#
typeset -i __BREAKPOINT_LINE=0 
typeset -i __STEP_COUNT=0
typeset -i __TRACE_COUNT=0
__DEBUG_HISTFILE="/tmp/ksh.history.$$"

# delete the history file at program end
__LIST_OF_TMP_FILES="${__LIST_OF_TMP_FILES} ${__DEBUG_HISTFILE}"

__USER_RESPONSE_IS=""

## __SCRIPTNAME - name of the script without the path
##
typeset -r __SCRIPTNAME="${0##*/}"

## __SCRIPTDIR - path of the script (as entered by the user!)
##
__SCRIPTDIR="${0%/*}"

## __REAL_SCRIPTDIR - path of the script (real path, maybe a link)
##
__REAL_SCRIPTDIR=$( cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P )

## __CONFIG_FILE - name of the config file
##   (use ReadConfigFile to read the config file; 
##   use WriteConfigFile to write it)
##
## __CONFIG_FILE="${__SCRIPTNAME%.*}.conf"
__CONFIG_FILE="start_xen.conf"

## __HOSTNAME - hostname 
##
__HOSTNAME="$( uname -n )"

## __NODENAME - nodename 
##
__NODENAME=${__HOSTNAME}
[ -f /etc/nodename ] && __NODENAME="$( cat /etc/nodename )"

## __OS - Operating system (e.g. SunOS)
##
__OS="$( uname -s )"

## __OS_VERSION - Operating system version (e.g 5.8)
##
__OS_VERSION="$( uname -r )"


## __ZONENAME - name of the current zone if running in Solaris 10 or newer
## 
__ZONENAME="$( zonename 2>/dev/null )"


## __OS_RELEASE - Operating system release (e.g. Generic_112233-08)
##
__OS_RELEASE="$( uname -v )"

## __MACHINE_CLASS - Machine class (e.g sun4u)
##
__MACHINE_CLASS="$( uname -m )"

## __MACHINE_TYPE - machine type (e.g. SUNW,Ultra-4)
##
__MACHINE_TYPE="$( uname -i )"

## __MACHINE_SUBTYPE - machine type (e.g  Sun Fire 3800)
##
__MACHINE_SUBTYPE=""
if [ -x /usr/platform/${__MACHINE_TYPE}/sbin/prtdiag ] ; then
  ( set -- $( /usr/platform/${__MACHINE_TYPE}/sbin/prtdiag | grep "System Configuration" ) ; shift 5; echo $* ) | read  __MACHINE_SUBTYPE
fi

## __MACHINE_ARC - machine architecture (e.g. sparc)
##
__MACHINE_ARC="$( uname -p )"

## __START_DIR - working directory when starting the script
##
__START_DIR="$( pwd )"

## __LOGFILE - fully qualified name of the logfile used
##   Note: use -l to change the logfile
##
if [ -d /var/log ] ; then
  __DEF_LOGFILE="/var/log/${__SCRIPTNAME%.*}.LOG"
else
  __DEF_LOGFILE="/tmp/${__SCRIPTNAME%.*}.LOG"
fi

__LOGFILE=${__DEF_LOGFILE}

## __TEMPFILE1, __TEMPFILE2
##   temporary files (these files are deleted at program end)
##
__TEMPFILE1="/tmp/${__SCRIPTNAME}.$$.TEMP1"
__TEMPFILE2="/tmp/${__SCRIPTNAME}.$$.TEMP2"
__LIST_OF_TEMPFILES="${__LIST_OF_TEMPFILES} ${__TEMPFILE1} ${__TEMPFILE2}"

# lock file (used if ${__ONLY_ONCE} is ${__TRUE})
# Note: This is only a symbolic link
#
__LOCKFILE="/tmp/${__SCRIPTNAME}.lock"
__LOCKFILE_CREATED=${__FALSE}

## __NO_OF_WARNINGS - No of warnings found
##
typeset -i __NO_OF_WARNINGS=0

## __LIST_OF_WARNINGS - List of warning messages
##
__LIST_OF_WARNINGS=""

## __NO_OF_ERRORS - No of errors found
##
typeset -i __NO_OF_ERRORS=0

## __LIST_OF_ERRORS - List of error messages
##
__LIST_OF_ERRORS=""

## __LOGON_USERID - ID of the user opening the session  
##
__LOGIN_USERID=$( set -- $( who am i ) ; echo $1 )
[ "${__LOGIN_USERID}" = "" ] && __LOGIN_USERID=${LOGNAME}

## __USERID - ID of the user executing this script (e.g. xtrnaw7)
##
 __USERID=${__LOGIN_USERID}
[ -x /usr/ucb/whoami ] && __USERID=$( /usr/ucb/whoami )

## __RUNLEVEL - current runlevel
##
## __RUNLEVEL=$( set -- $( who -r )  ; echo $7 )
__RUNLEVEL=$( who -r  2>/dev/null | tr -s " " | cut -f8 -d " " )

# -----------------------------------------------------------------------------
# color variables


## Colorattributes:
## __COLOR_OFF, __COLOR_BOLD, __COLOR_NORMAL, - normal, __COLOR_UNDERLINE
## __COLOR_BLINK, __COLOR_REVERSE, __COLOR_INVISIBLE
##

__COLOR_OFF="\033[0;m"
__COLOR_BOLD="\033[1m"
__COLOR_NORMAL="\033[2m"
__COLOR_UNDERLINE="\033[4m"
__COLOR_BLINK="\033[5m"
__COLOR_REVERSE="\033[7m"
__COLOR_INVISIBLE="\033[8m"

## Foreground Color variables:
## __COLOR_FG_BLACK, __COLOR_FG_RED,     __COLOR_FG_GREEN, __COLOR_FG_YELLOW
## __COLOR_FG_BLUE,  __COLOR_FG_MAGENTA, __COLOR_FG_CYAN,  __COLOR_FG_WHITE
##
## Background Color variables:
## __COLOR_BG_BLACK, __COLOR_BG_RED,     __COLOR_BG_GREEN, __COLOR_BG_YELLOW
## __COLOR_BG_BLUE,  __COLOR_BG_MAGENTA, __COLOR_BG_CYAN,  __COLOR_BG_WHITE
##

__COLOR_FG_BLACK="\033[30m"
__COLOR_FG_RED="\033[31m"
__COLOR_FG_GREEN="\033[32m"
__COLOR_FG_YELLOW="\033[33m"
__COLOR_FG_BLUE="\033[34m"
__COLOR_FG_MAGENTA="\033[35m"
__COLOR_FG_CYAN="\033[36m"
__COLOR_FG_WHITE="\033[37m"

__COLOR_BG_BLACK="\033[40m"
__COLOR_BG_RED="\033[41m"
__COLOR_BG_GREEN="\033[42m"
__COLOR_BG_YELLOW="\033[43m"
__COLOR_BG_BLUE="\033[44m"
__COLOR_BG_MAGENTA="\033[45m"
__COLOR_BG_CYAN="\033[46m"
__COLOR_BG_WHITE="\033[47m"


# position cursor:       ESC[row,colH or ESC[row;colf  (1,1 = upper left corner)
# Clear rest of line:    ESC[K
# Clear screen:          ESC[2J
# Save Cursor Pos        ESC[s
# Restore Cursor Pos     ESC[u
# Cursor Up # lines      ESC{colsA
# Cursor down # lines    ESC{colsB
# Cursor right # columns ESC{colsC
# Cursor left # columns  ESC{colsD
# Get Cursor Pos         ESC[6n
#

# -----------------------------------------------------------------------------

## 
## ##### defined sub routines
##

## --------------------------------------
## ReadConfigFile
##
## read the config file
##
## usage: ReadConfigFile [configfile]
##
## where:   configfile - name of the config file
##              default: search ${__CONFIG_FILE} in the current directory,
##              in the home directory, and in /etc (in this order)
##
## returns: ${__TRUE} - ok config read
##             ${__FALSE} - error config file not found or not readable
##
ReadConfigFile() {
  typeset __FUNCTION="ReadConfigFile"; ${__DEBUG_CODE}

  typeset THIS_CONFIG="$1"
  typeset THISRC=${__FALSE}
  
  if [ "${THIS_CONFIG}"x = ""x ] ; then
    THIS_CONFIG="./${__CONFIG_FILE}"
    [ ! -f ${THIS_CONFIG} ] && THIS_CONFIG="${HOME}/${__CONFIG_FILE}"
    [ ! -f ${THIS_CONFIG} ] && THIS_CONFIG="/etc/${__CONFIG_FILE}"
  fi

  if [ -f ${THIS_CONFIG} ] ; then
    LogMsg "Reading the config file \"${THIS_CONFIG}\" ..." 

    includeScript ${THIS_CONFIG}

    THISRC=${__TRUE}    
  else
    LogMsg "No config file (\"${__CONFIG_FILE}\") found (use -C to create a default config file)"
  fi

  return ${THISRC}
}

## --------------------------------------
## WriteConfigFile
##
## write the variable ${__CONFIG_PARAMETER} to the config file
##
## usage: WriteConfigFile [configfile]
##
## where:  configfile - name of the config file
##            default: write ${__CONFIG_FILE} in the current directory
##
## returns: ${__TRUE} - ok config file written
##             ${__FALSE} - error writing the config file
##
WriteConfigFile() {
  typeset __FUNCTION="WriteConfigFile" ; ${__DEBUG_CODE} 

  typeset THIS_CONFIG_FILE="$1"
  typeset THISRC=${__FALSE}
  
  [ "${THIS_CONFIG_FILE}"x = ""x ] && THIS_CONFIG_FILE="./${__CONFIG_FILE}"

  [ -f "${THIS_CONFIG_FILE}" ] &&  BackupFileIfNecessary "${THIS_CONFIG_FILE}"
  LogMsg "Writing the config file \"${THIS_CONFIG_FILE}\" ..." 
   
cat <<EOT >"${THIS_CONFIG_FILE}"
# config file for $0
${__CONFIG_PARAMETER}
EOT
  THISRC=$?
  
  return ${THISRC}
}

## --------------------------------------
## NoOfStackElements
##
## return the no. of stack elements
##
## usage: NoOfStackElements; var=$?
##
## returns: no. of elements on the stack
##
## Note: NoOfStackElements, FlushStack, push and pop use only one global stack!
##
NoOfStackElements() {
  typeset __FUNCTION="NoOfStackElements";  ${__DEBUG_CODE}

  return ${__STACK_POINTER}
}

## --------------------------------------
## FlushStack
##
## flush the stack
##
## usage: FlushStack
##
## returns: no. of elements on the stack before flushing it
##
## Note: NoOfStackElements, FlushStack, push and pop use only one global stack!
##
FlushStack() {
  typeset __FUNCTION="FlushStack";    ${__DEBUG_CODE}

  typeset THISRC=${__STACK_POINTER}
  __STACK_POINTER=0
  return ${THISRC}
}

## --------------------------------------
## push
##
## push one or more values on the stack
##
## usage: push value1 [...] [value#]
##
## returns: -
##
## Note: NoOfStackElements, FlushStack, push and pop use only one global stack!
##
push() {
  typeset __FUNCTION="push";    ${__DEBUG_CODE}

   while [ $# -ne 0 ] ; do
   (( __STACK_POINTER=__STACK_POINTER+1 ))
    __STACK[${__STACK_POINTER}]="$1"
    shift
  done
}

## --------------------------------------
## pop
##
## pop one or more values from the stack
##
## usage: pop variable1 [...] [variable#]
##
## returns: -
##
## Note: NoOfStackElements, FlushStack, push and pop use only one global stack!
##
pop() {
  typeset __FUNCTION="pop";    ${__DEBUG_CODE}

  typeset NEWALUE=""

  while [ $# -ne 0 ] ; do
    if [ ${__STACK_POINTER} -eq 0 ] ; then
      NEWVALUE=""
    else
      NEWVALUE="${__STACK[${__STACK_POINTER}]}"
      (( __STACK_POINTER=__STACK_POINTER-1 ))
    fi
    eval $1="\"${NEWVALUE}\""
    shift
  done
}

## --------------------------------------
## SetWindowTitle
##
## change the title of an X window
##
## usage: SetWindowTitle "newtitle"
##
## returns: ${__TRUE} - ok, window title set
##          ${__FALSE} - error, don't know the terminal type; 
##                       window title NOT changed
##
## Note
##
## Original Author of this function (xtitle) is:
##  William Seppeler
##  Email:seppeler@yahoo.com
##
SetWindowTitle(){
  typeset __FUNCTION="SetWindowTitle";    ${__DEBUG_CODE}

  typeset NEW_TITLE="$*"

  typeset THISRC=${__FALSE}

  typeset -r ESC='\033'
  typeset -r BEL='\007'

  case ${TERM} in

    xterm*|dtterm|aixterm|rxvt)
      print "${ESC}]0;${NEW_TITLE}${BEL}\c"
      THISRC=${__TRUE}
      ;;

    sun-cmd)
      print "${ESC}]l${NEW_TITLE}${ESC}\\\\\c"
      #print "${ESC}]L${NEW_TITLE}${ESC}\\\\\c"
      THISRC=${__TRUE}
      ;;

    iris-ansi)
      print "${ESC}P1.y${NEW_TITLE}${ESC}\\\\\c"
     #print "${ESC}P3.y${NEW_TITLE}${ESC
      THISRC=${__TRUE}
      ;;
  esac     

  return ${THISRC}
}

## --------------------------------------
## SetDISPLAY
##
## try to set the variable DISPLAY
##
## usage: SetDISPLAY
##
## returns: the variable ${DISPLAY} is set or not
##
## Source: Solaris news group
##
SetDISPLAY(){
  typeset __FUNCTION="SetDISPLAY";    ${__DEBUG_CODE}

  if [ -z "${DISPLAY}" ] ; then
    typeset tty=`tty | sed "s@/dev/@@"`
    if [ "${tty}" != "not a tty" ] ; then
      typeset machine=`who | grep ${tty} | sed -e 's/^.*(//' -e 's/)//'`
      DISPLAY="${machine}:0" ; export DISPLAY
    fi
  fi
}

## --------------------------------------
## CheckYNParameter
##
## check if a parameter is y, n, 0, or 1
##
## usage: CheckYNParameter parameter
##
## returns: ${__TRUE} - the parameter is equal to yes
##             ${__FALSE} - the parameter is equal to no
##
CheckYNParameter(){
  typeset __FUNCTION="CheckYNParameter";    ${__DEBUG_CODE}

  typeset THISRC=255
  
  case $1 in
   "y" | "Y" | "yes" | "YES" | 0 ) THISRC=${__TRUE} ;;
   "n" | "N" | "no"  | "NO"  | 1 ) THISRC=${__FALSE} ;;
   * ) THISRC=255 ;;
  esac
  return ${THISRC}
}


## --------------------------------------
## ConvertToYesNo
##
## convert the value of a variable to y or n
##
## usage: ConvertToYesNo parameter
##
## returns: -
##          prints y, n or ? to STDOUT
##
ConvertToYesNo(){
  typeset __FUNCTION="ConvertToYesNo";    ${__DEBUG_CODE}

  case $1 in
   "y" | "Y" | "yes" | "YES" | 0 ) echo "y" ;;
   "n" | "N" | "no"  | "NO"  | 1 ) echo "n" ;;
   * ) echo "?" ;;
  esac
}

## --------------------------------------
## InvertSwitch
##
## invert a switch from true to false or vice versa
##
## usage: InvertSwitch variable
##
## returns nothing
##         switch the variable "variable" from ${__TRUE} to
##         ${__FALSE} or vice versa
##
InvertSwitch(){
  typeset __FUNCTION="InvertSwitch";    ${__DEBUG_CODE}

  eval "[ \$$1 -eq ${__TRUE} ] && $1=${__FALSE} || $1=${__TRUE} "
}

  
## --------------------------------------
## CheckInputDevice
##
## check if the input device is a terminal
##
## usage: CheckInputDevice
##
## returns: 0 - the input device is a terminal (interactive)
##              1 - the input device is NOT a terminal
##
CheckInputDevice(){
  typeset __FUNCTION="CheckInputDevice";    ${__DEBUG_CODE}

  tty -s
  return $?
}
  
## --------------------------------------
## GetProgramDirectory
##
## get the directory where a program resides
##
## usage: GetProgramDirectory [programpath/]programname [resultvar]
##
## returns: the variable PRGDIR contains the directory with the program
##              if the parameter resultvar is missing
##
GetProgramDirectory() {
  typeset __FUNCTION="GetProgramDirectory";    ${__DEBUG_CODE}

  typeset PRG=""
  typeset RESULTVAR=$2
    
  if [ ! -L $1 ] ; then
    PRG=$( cd -P -- "$(dirname -- "$(command -v -- "$1")")" && pwd -P )
  else  
# resolve links - $1 may be a softlink
    PRG="$1"
   
    while [ -h "$PRG" ] ; do
      ls=`ls -ld "$PRG"`
      link=`expr "$ls" : '.*-> \(.*\)$'`
      if expr "$link" : '.*/.*' > /dev/null; then
        PRG="$link"
      else
        PRG=`dirname "$PRG"`/"$link"
      fi
    done
    PRG="$(dirname $PRG)"
  fi

  if [ "${RESULTVAR}"x != ""x ] ; then
     eval ${RESULTVAR}=$PRG
  else 
    PRGDIR=$PRG
  fi
}

## --------------------------------------
## substr
##
## get a substring of a string
##
## usage: variable=$( substr sourceStr pos length )
##     or substr sourceStr pos length resultStr
##
## returns: 1 - parameter missing
##             0 - parameter okay
##
substr() {
  typeset __FUNCTION="substr";    ${__DEBUG_CODE}

  typeset resultstr=""
  typeset THISRC=1

  if [ "$1"x != ""x ] ; then 
    typeset s="$1"
    typeset p="$2"
    typeset l="$3"
    [ "$l"x = ""x ] && l=${#s}
    [ "$p"x = ""x ] && p=1
    resultstr="$( echo $s | cut -c${p}-$((${p}+${l}-1)) )"
    THISRC=0
  else
    THISRC=1
    resultstr="$1"
  fi

  if [ "$4"x != ""x ] ; then
    eval $4=\"${resultstr}\" 
  else
    echo "${resultstr}"
  fi

  return ${THISRC}
}

## --------------------------------------
## replacestr
##
## replace a substring with another substring
##
## usage: variable=$( replacestr sourceStr oldsubStr newsubStr )
##     or replacestr sourceStr oldsubStr newsubStr resultvariable
##
## returns: 0 - substring replaced
##              1 - substring not found
##             3 - error, parameter missing
##
##              writes the substr to STDOUT if resultvariable is missing
##
replacestr() {
  typeset __FUNCTION="replacestr";    ${__DEBUG_CODE}

  typeset THISRC=3
   
  typeset sourcestring="$1"
  typeset oldsubStr="$2"
  typeset newsubStr="$3"

  if [ "${sourcestring}"x != ""x -a "${oldsubStr}"x != ""x ] ; then
    if [[ "${sourcestring}" == *${oldsubStr}* ]] ; then
      sourcestring="${sourcestring%%${oldsubStr}*}${newsubStr}${sourcestring#*${oldsubStr}}" 
      THISRC=0
    else
      THISRC=1
    fi
  fi

  if [ "$4"x != ""x ] ; then
    eval $4=\"${sourcestring}\" 
  else
    echo "${sourcestring}"
  fi

  return ${THISRC}
}

## --------------------------------------
## pos
##
## get the first position of a substring in a string
##
## usage: pos searchstring sourcestring
##
## returns: 0 - searchstring is not part of sourcestring
##              else the position of searchstring in sourcestring
##
pos() {
  typeset __FUNCTION="pos";    ${__DEBUG_CODE}

  typeset searchstring="$1"
  typeset sourcestring="$2"
 
  if [[ "${sourcestring}" == *${searchstring}* ]] ; then
    typeset f=${sourcestring%%${searchstring}*}
    return $((  ${#f}+1 ))
  else
    return 0
  fi
}

## --------------------------------------
## lastpos
##
## get the last position of a substring in a string
##
## usage: lastpos searchstring sourcestring
##
## returns: 0 - searchstring is not part of sourcestring
##             else the position of searchstring in sourcestring
##
lastpos() {
  typeset __FUNCTION="lastpos";    ${__DEBUG_CODE}

  typeset searchstring="$1"
  typeset sourcestring="$2"

  if [[ "${sourcestring}" == *${searchstring}* ]] ; then
    typeset f=${sourcestring%${searchstring}*}
    return $((  ${#f}+1 ))
  else 
    return  0
  fi
}


## --------------------------------------
## isNumber
##
## check if a value is an integer 
##
## usage: isNumber testValue 
##
## returns: ${__TRUE} - testValue is a number else not
##
isNumber() {
  typeset __FUNCTION="isNumber";    ${__DEBUG_CODE}

  typeset TESTVAR="$(echo "$1" | sed 's/[0-9]*//g' )"
  [ "${TESTVAR}"x = ""x ] && return ${__TRUE} || return ${__FALSE}
}

## --------------------------------------
## ConvertToHex
##
## convert the value of a variable to a hex value
##
## usage: ConvertToHex value
##
## returns: -
##             prints the value in hex to STDOUT
##
ConvertToHex(){
  typeset __FUNCTION="ConvertToHex";    ${__DEBUG_CODE}

  typeset -i16 HEXVAR
  HEXVAR=$1
  echo ${HEXVAR##*#}
}  

## --------------------------------------
## ConvertToOctal
##
## convert the value of a variable to a octal value
##
## usage: ConvertToOctal value
##
## returns: -
##              prints the value in octal to STDOUT
##
ConvertToOctal(){
  typeset __FUNCTION="ConvertToOctal";    ${__DEBUG_CODE}

  typeset -i8 OCTVAR
  OCTVAR=$1
  echo ${OCTVAR##*#}
}  

## --------------------------------------
## ConvertToBinary
##
## convert the value of a variable to a binary value
##
## usage: ConvertToBinary value
##
## returns: -
##              prints the value in binary to STDOUT
##
ConvertToBinary(){
  typeset __FUNCTION="ConverToBinary";  ${__DEBUG_CODE}

  typeset -i2 BINVAR
  BINVAR=$1
  echo ${BINVAR##*#}
}  


## --------------------------------------
## toUppercase
##
## convert a string to uppercase
##
## usage: toUppercase sourceString | read resultString
##    or   targetString=$( toUppercase sourceString )
##    or   toUppercase sourceString resultString
##
## returns: writes the converted string to STDOUT if resultString is missing
##
toUppercase() {
  typeset __FUNCTION="toUppercase";    ${__DEBUG_CODE}

  typeset -u testvar="$1"

  if [ "$2"x != ""x ] ; then
    eval $2=\"${testvar}\" 
  else
    echo "${testvar}"
  fi
}

## --------------------------------------
## toLowercase
##
## convert a string to lowercase
##
## usage: toLowercase sourceString | read resultString
##    or   targetString=$( toLowercase sourceString )
##    or   toLowercase sourceString resultString
##
## returns: writes the converted string to STDOUT if resultString is missing
##
toLowercase() {
  typeset __FUNCTION="toLowercase";    ${__DEBUG_CODE}

  typeset -l testvar="$1"

  if [ "$2"x != ""x ] ; then
    eval $2=\"${testvar}\" 
  else
    echo "${testvar}"
  fi
}

## --------------------------------------
## executeCommand
##
## execute a command
##
## usage: executeCommand command parameter
##
## returns: the RC of the executed command
##
executeCommand() {
  typeset __FUNCTION="executeCommand";    ${__DEBUG_CODE}

  set +e

  LogInfo "Executing \"$@\" "  

  eval "$@"
}

## --------------------------------------
## executeCommandAndLog
##
## execute a command and write STDERR and STDOUT to the logfile
##
## usage: executeCommandAndLog command parameter
##
## returns: the RC of the executed command
##
executeCommandAndLog() {
  typeset __FUNCTION="executeCommandAndLog";    ${__DEBUG_CODE}

  set +e
  typeset THISRC=0

  LogRuntimeInfo "Executing \"$@\" "  

  if [ "${__LOGFILE}"x != ""x -a -f ${__LOGFILE} ] ; then
    eval "$@" 2>&1 | tee -a ${__LOGFILE}
    THISRC=$?
  else    
    eval "$@"
    THISRC=$?
  fi

  return ${THISRC}
}

## --------------------------------------
## executeCommandAndLog
##
## execute a command and write STDERR to the logfile
##
## usage: executeCommandAndLogSTDERR command parameter
##
## returns: the RC of the executed command
##
executeCommandAndLogSTDERR() {
  typeset __FUNCTION="executeCommandAndLogSTDERR";    ${__DEBUG_CODE}

  set +e
  typeset THISRC=0

  LogRuntimeInfo "Executing \"$@\" "  

  if [ "${__LOGFILE}"x != ""x -a -f ${__LOGFILE} ] ; then
    eval "$@" 2>>${__LOGFILE}
    THISRC=$?
  else    
    eval "$@"
    THISRC=$?
  fi

  return ${THISRC}
}

## --------------------------------------
## UserIsRoot
##
## validate the user id
##
## usage: UserIsRoot
##
## returns: ${__TRUE} - the user is root; else not
##
UserIsRoot() {
  typeset __FUNCTION="UserIsRoot";    ${__DEBUG_CODE}

  [ $( id | sed 's/uid=\([0-9]*\)(.*/\1/' ) = 0 ] && return ${__TRUE} || return ${__FALSE}
#) dummy comment for the syntax highlighting to work correct
}


## --------------------------------------
## UserIs
##
## validate the user id
##
## usage: UserIs USERID
##
## where: USERID - userid (e.g oracle)
##
## returns: 0 - the user is this user
##              1 - the user is NOT this user
##              2 - the user does not exist on this machine
##              3 - missing parameter
##
UserIs() {
  typeset __FUNCTION="UserIs";    ${__DEBUG_CODE}

  typeset THISRC=3
  typeset USERID=""
  
  if [ "$1"x != ""x ] ; then
    THISRC=2
    USERID=$( grep "^$1:" /etc/passwd | cut -d: -f3 )
    if [ "${USERID}"x != ""x ] ; then
      UID=`id | sed 's/uid=\([0-9]*\)(.*/\1/'`
      [ ${UID} = ${USERID} ] && THISRC=0 || THISRC=1   
    fi
  fi

  return ${THISRC}
}

## --------------------------------------
## GetCurrentUID
##
## get the UID of the current user
##
## usage: GetCurrentUID
##
## where: - 
##
## returns: the UID 
##
GetCurrentUID() {
  typeset __FUNCTION="GetCurrentUID";    ${__DEBUG_CODE}

  return  `id | sed 's/uid=\([0-9]*\)(.*/\1/'`
}

## --------------------------------------
## GetUserName
##
## get the name of a user
##
## usage: GetUserName UID
##
## where: UID - userid (e.g 1686)
##
## returns:  __USERNAME contains the user name or "" if
##              the userid does not exist on this machine
##
GetUserName() {
  typeset __FUNCTION="GetUserName";    ${__DEBUG_CODE}

  [ "$1"x != ""x ] &&  __USERNAME=$( grep ":$1:" /etc/passwd | cut -d: -f1 )  || __USERNAME=""
}

## --------------------------------------
## GetUID
##
## get the UID for a username
##
## usage: GetUID username
##
## where: username - user name (e.g nobody)
##
## returns:  __USER_ID contains the UID or "" if
##              the username does not exist on this machine
##
GetUID() {
  typeset __FUNCTION="GetUID";    ${__DEBUG_CODE}

  [ "$1"x != ""x ] &&  __USER_ID=$( grep "^$1:" /etc/passwd | cut -d: -f3 ) || __USER_ID=""
}


# ======================================
 
## --------------------------------------
## LogMsg
##
## print a message to STDOUT and write it also to the logfile
##
## usage: LogMsg message
##
## returns: -
##
## Notes: Use "-" to print a complete blank line
##
LogMsg() {
  typeset __FUNCTION="LogMsg";    ${__DEBUG_CODE}
  typeset THISRC=0
  
  if [ "$1"x = "-"x ] ; then
    shift
    typeset THISMSG="$*"
  elif [ "${__NO_TIME_STAMPS}"x = "${__TRUE}"x ] ; then
    typeset THISMSG="$*"
  else
    typeset THISMSG="[$(date +"%d.%m.%Y %H:%M:%S")] $*"
  fi
  
  [  ${__QUIET_MODE} -ne ${__TRUE} ] && echo "${THISMSG} "

  [ "${__LOGFILE}"x != ""x ] && [ -f "${__LOGFILE}" ] &&  echo "${THISMSG}" >>${__LOGFILE} 
  
  return ${THISRC}
}


## --------------------------------------
## LogOnly
##
## write a message to the logfile
##
## usage: LogOnly message
##
## returns: -
##
LogOnly() {
  typeset __FUNCTION="LogOnly";    ${__DEBUG_CODE}

  typeset THISMSG="[$(date +"%d.%m.%Y %H:%M:%S")] $*"

  [ "${__LOGFILE}"x != ""x ] && [ -f ${__LOGFILE} ] &&  echo "${THISMSG}" >>${__LOGFILE} 
}

## --------------------------------------
## LogInfo
##
## print a message to STDOUT and write it also to the logfile 
## only if in verbose mode
##
## usage: LogInfo [loglevel] message
##
## returns: -
##
## Notes: Output goes to STDERR, default loglevel is 0
##
LogInfo() {
  typeset __FUNCTION="LogInfo";    ${__DEBUG_CODE}

#  [ ${__VERBOSE_MODE} -eq ${__TRUE} ] && LogMsg "INFO: $*"

  typeset THISLEVEL=0
  
  if [ ${__VERBOSE_MODE} -eq ${__TRUE} ] ; then
    if [ $# -gt 1 ] ; then
      isNumber $1 
      if [ $? -eq ${__TRUE} ] ; then
        THISLEVEL=$1
        shift
      fi
    fi      
    [ ${__VERBOSE_LEVEL} -gt ${THISLEVEL} ]  && LogMsg "INFO: $*" >&2
  fi  
}

# internal sub routine for info messages
#
#
LogRuntimeInfo() {
  typeset __FUNCTION="LogRuntimeInfo";    ${__DEBUG_CODE}
  LogInfo "${__RT_VERBOSE_LEVEL}" "$*"
}


## --------------------------------------
## LogWarning
##
## print a warning to STDOUT and write it also to the logfile
##
## usage: LogWarning message
##
## returns: -
##
## Notes: Output goes to STDERR
##
LogWarning() {
  typeset __FUNCTION="LogWarning";    ${__DEBUG_CODE}

  LogMsg "WARNING: $*" >&2
  (( __NO_OF_WARNINGS = __NO_OF_WARNINGS +1 ))
  __LIST_OF_WARNINGS="${__LIST_OF_WARNINGS}
WARNING: $*"  
}

## --------------------------------------
## LogError
##
## print an error message to STDOUT and write it also to the logfile
##
## usage: LogError message
##
## returns: -
##
## Notes: Output goes to STDERR
##
LogError() {
  typeset __FUNCTION="LogError";    ${__DEBUG_CODE}

  LogMsg "ERROR: $*" >&2

  (( __NO_OF_ERRORS=__NO_OF_ERRORS + 1 ))  
  __LIST_OF_ERRORS="${__LIST_OF_ERRORS}
ERROR: $*"  
}


## ---------------------------------------
## BackupFileIfNecessary
##
## create a backup of a file if ${__OVERWRITE_MODE} is set to ${__FALSE}
##
## usage: BackupFileIfNecessary [file1} ... {filen}
##
## returns: 0 - done; else error
##
BackupFileIfNecessary() {
  typeset __FUNCTION="BackupFileIfNecessary";    ${__DEBUG_CODE}

 [ "${BACKUP_EXTENSION}"x = ""x ] && BACKUP_EXTENSION=".$$"
 
 typeset FILES_TO_BACKUP="$*"
 typeset CURFILE=""
 typeset CUR_BKP_FILE=""
 typeset THISRC=0
  
 if [ ${__OVERWRITE_MODE} -eq ${__FALSE} ] ; then
   for CURFILE in ${FILES_TO_BACKUP} ; do         
     [ ! -f ${CURFILE} ] && continue

     CUR_BKP_FILE="${CURFILE}${BACKUP_EXTENSION}"
     LogMsg "Creating a backup of \"${CURFILE}\" in \"${CUR_BKP_FILE}\" ..."
     cp "${CURFILE}" "${CUR_BKP_FILE}"
     THISRC=$?
     if [ ${THISRC} -ne 0 ] ; then
       LogError "Error creating the backup of the file \"${CURFILE}\""
       break
     fi
   done
 fi
}  
 
## ---------------------------------------
## CopyDirectory
##
## copy a directory 
##
## usage: CopyDirectory sourcedir targetDir
##
## returns:  0 - done; 
##              else error
##
CopyDirectory() {
  typeset __FUNCTION="CopyDirectory";    ${__DEBUG_CODE}

  typeset THISRC=1
  if [ "$1"x != ""x -a "$2"x != ""x  ] ; then
     if [ -d $1 -a -d $2 ] ; then
        LogMsg "Copying all files from \"$1\" to \"$2\" ..."
        cd $1
        find . -depth -print | cpio -pdumv $2
        THISRC=$?
        cd ${OLDPWD}
     fi
  fi

  return ${THISRC}
}


## --------------------------------------
## GetIPAddress
##
## Get the IP address for a hostname from the nameserver 
## (if defined & alive)
##
## Usage: GetIPAddress | read IPADDRESS
##
GetIPAddress() {
  typeset __FUNCTION="GetIPAddress";    ${__DEBUG_CODE}

  typeset THISHOST=$1
  typeset THISRC=""

  set -- $( grep "^nameserver" /etc/resolv.conf )
  if [ "$1"x = "nameserver"x ] ; then
    ping $2 1 2>&1 >/dev/null
    if [ $? -eq 0 ] ; then
      set -- $( which nslookup )
      if [ "$1"x != "no"x  ] ; then
        set -- `nslookup -silent ${THISHOST} | grep "^Address:" 2>/dev/null`
        [ "$3" = "Address:" ] && THISRC=$4
      fi
    fi
  fi
  echo ${THISRC}
}

## --------------------------------------
## AskUser
##
## Ask the user (or use defaults depending on the parameter -n and -y)
##
## Usage: AskUser "message" 
##        
## returns: ${__TRUE} - user input is yes
##              ${__FALSE} - user input is no
##              USER_INPUT contains the user input
##
## Notes: "all" is interpreted as yes for this and all other questions
##        "none" is interpreted as no for this and all other questions
##
AskUser() {
  typeset __FUNCTION="AskUser";    ${__DEBUG_CODE}

  typeset THISRC=""
  
  case ${__USER_RESPONSE_IS} in 

     
   "y" ) USER_INPUT="y" ; THISRC=${__TRUE} 
         ;;

   "n" ) USER_INPUT="n" ; THISRC=${__FALSE} 
         ;;
   
     * ) [ $# -ne 0 ] && LogMsg "$*"
         read USER_INPUT
         case ${USER_INPUT} in

           "y" | "Y" ) THISRC=${__TRUE}  ;;

           "n" | "N" ) THISRC=${__FALSE} ;;

           "all" ) __USER_RESPONSE_IS="y"  ; THISRC=${__TRUE}  ;;

           "none" )  __USER_RESPONSE_IS="n" ;  THISRC=${__FALSE} ;;

           "*" )  THISRC=${__FALSE} ;;

        esac
        ;;
  esac  

  return ${THISRC}
}

## --------------------------------------
## GetKeystroke
##
## read one key from STDIN
##
## Usage: GetKeystroke "message" 
##        
## returns: USER_INPUT contains the user input
##          
##          
##
GetKeystroke () {
  typeset __FUNCTION="GetKeystroke";    ${__DEBUG_CODE}

  trap "" 2 3
  [ $# -ne 0 ] && LogMsg "${THISMSG}"

  typeset oldSttySettings=$( stty -g )
  stty -echo raw
  USER_INPUT=$( dd count=1 2> /dev/null )
  stty $oldSttySettings
  trap 2 3
} 

## --------------------------------------
## RebootIfNecessary
##
## Check if a reboot is necessary
##
## Usage: RebootIfNecessary
##
## Notes
##   The routine asks the user if neither the parameter -y nor the 
##   parameter -n is used
##   Before using this routine uncomment the reboot command!
##
RebootIfNecessary() {
  typeset __FUNCTION="RebootIfNecessary";    ${__DEBUG_CODE}

  if [ ${__REBOOT_REQUIRED} -eq 0 ] ; then
    LogMsg "The changes made to the system require a reboot"

    AskUser "Do you want to reboot now (y/n, default is NO)?"
    if [ $? -eq ${__TRUE} ] ; then
      LogMsg "Rebooting now ..."
      echo "???" reboot ${__REBOOT_PARAMETER}
    fi
  fi
}

## ---------------------------------------
## die
##
## print a message and end the program
##
## usage: die returncode {message}
##
## returns: -
##
## Notes: 
##
## This routine 
##     - calls cleanup
##     - prints an error message if any (if returncode is not zero)
##       or the message if any (if returncode is zero)
##     - prints all warning messages again if ${__PRINT_LIST_OF_WARNING_MSGS} 
##       is ${__TRUE}
##     - prints all error messages again if ${__PRINT_LIST_OF_ERROR_MSGS} 
##       is ${__TRUE}
##     - prints a program end message and the program return code
## and
##     - and ends the program
##
## If the variable ${__FORCE} is ${__TRUE} and the return code is NOT zero
## die() will only print the error message and return
##
die() {
  typeset __FUNCTION="die";    ${__DEBUG_CODE}

  typeset THISRC=$1
  shift
  if [ "$*"x != ""x ] ; then
    [ ${THISRC} = 0 ] && LogMsg "$*" || LogError "$*"
  fi

  [ ${__FORCE} = ${__TRUE} -a ${THISRC} != 0 ] && return

  cleanup
  
  if [ "${__NO_OF_WARNINGS}" != "0" -a ${__PRINT_LIST_OF_WARNINGS_MSGS} -eq ${__TRUE} ] ; then
    LogMsg "*** CAUTION: One or more WARNINGS found ***"
    LogMsg "*** please check the logfile ***"
    
    LogMsg "Summary of warnings:
${__LIST_OF_WARNINGS}
"
  fi    

  if [ "${__NO_OF_ERRORS}" != "0" -a ${__PRINT_LIST_OF_ERROR_MSGS} -eq ${__TRUE} ] ; then
    LogMsg "*** CAUTION: One or more ERRORS found ***"
    LogMsg "*** please check the logfile ***"

    LogMsg "Summary of error messages
${__LIST_OF_ERRORS}
"
  fi    

  [[ -n ${__LOGFILE} ]] && LogMsg "The log file used was \"${__LOGFILE}\" "
  __QUIET_MODE=${__FALSE}
  LogMsg "${__SCRIPTNAME} ended on $( date )."
  LogMsg "The RC is ${THISRC}."

  __EXIT_VIA_DIE=${__TRUE} 

  if [ "${STARTED_VIA_GUI}" = ${__TRUE} ] ; then
    AskUser "Press enter to end the script (use the parameter +G to suppress this question)"
  fi
  
  exit ${THISRC}
}


# ======================================

## 
## ##### defined internal sub routines (do NOT use; these routines are called 
##       by the runtime system!)
##

# --------------------------------------
## CreateLockFile
#
# Create the lock file (which is really a symbolic link) if possible
#
# usage: CreateLockFile
#
# returns: 0 - lock created
#             1 - lock already exist or erro creating the lock
#
# Note: Use a symbolic link because this is always a atomic operation
#
CreateLockFile() {
  typeset __FUNCTION="CreateLockFile";    ${__DEBUG_CODE}

  typeset LN_RC=""

  ln -s  $0 "${__LOCKFILE}" 2>/dev/null
  LN_RC=$?
      
  if [ ${LN_RC} = 0 ] ; then
    __LOCKFILE_CREATED=${__TRUE}
    return 0 
  else
    return 1
  fi
}

# --------------------------------------
## RemoveLockFile
#
# Remove the lock file if possible
#
# usage: RemoveLockFile
#
# returns: 0 - lock file removed
#              1 - lock file does not exist
#              2 - error removing the lock file
#
RemoveLockFile() {
  typeset __FUNCTION="RemoveLockFile";    ${__DEBUG_CODE}

  [ ! -L "${__LOCKFILE}" ] && return 1
  if [ ${__LOCKFILE_CREATED} -eq ${__TRUE} ] ; then
    rm "${__LOCKFILE}" 1>/dev/null 2>/dev/null
    [ $? -eq 0 ] && return 0
  fi  
  return 2
}

# ======================================

# --------------------------------------
## CreateTemporaryFiles
#
# create the temporary files
#
# usage: CreateTemporaryFiles
#
# returns: -
#
CreateTemporaryFiles() {
  typeset __FUNCTION="CreateTemporaryFiles";    ${__DEBUG_CODE}

  typeset CURFILE=

  __TEMPFILE_CREATED=${__TRUE}

  LogRuntimeInfo "Creating the temporary files \"${__LIST_OF_TEMPFILES}\" ..."
  for CURFILE in ${__LIST_OF_TEMPFILES} ; do
    LogRuntimeInfo "Creating the temporary file \"${CURFILE}\" "
    echo >"${CURFILE}" || return $?

# delete the file a program end
    __LIST_OF_TMP_FILES="${__LIST_OF_TMP_FILES} ${CURFILE}"
  done

  return 0
}

# ======================================


# ======================================

##
## ---------------------------------------
## cleanup
##
## house keeping at program end
##
## usage: [called by the runtime system]
##
## returns: -
##
## notes: 
##  execution order is
##    - call exit routines from ${__EXITROUTINES}
##    - remove files from ${__LIST_OF_TMP_FILES}
##    - umount mount points ${__LIST_OF_TMP_MOUNTS}
##    - remove directories ${__LIST_OF_TMP_DIRS}
##
cleanup() {
  typeset __FUNCTION="cleanup";    ${__DEBUG_CODE}

  typeset EXIT_ROUTINE=
  typeset OLDPWD=$( pwd )

  cd /tmp

 
# call the defined exit routines
  if [ "${__EXITROUTINES}"x !=  ""x ] ; then
    LogRuntimeInfo "Executing the exit routines \"${__EXITROUTINES}\" ..."
    for EXIT_ROUTINE in ${__EXITROUTINES} ; do
      LogRuntimeInfo "Now calling the exit routine \"${EXIT_ROUTINE}\" ..."
      eval ${EXIT_ROUTINE}
    done
  fi

# remove temporary files
  for CURENTRY in ${__LIST_OF_TMP_FILES} ; do
    LogRuntimeInfo "Removing the file \"${CURENTRY}\" ..."
    if [ -f "${CURENTRY}" ] ; then
      rm "${CURENTRY}" 
      [ $? -ne 0 ] && LogWarning "Error removing the file \"${CURENTRY}\" "
    fi
  done
 
# remove temporary mounts
  typeset CURENTRY
  for CURENTRY in ${__LIST_OF_TMP_MOUNTS} ; do
    mount | grep "^${CURENTRY} " 1>/dev/null 2>/dev/null
    if [ $? -eq 0 ] ; then
      LogRuntimeInfo "Umounting \"${CURENTRY}\" ..."
      umount "${CURENTRY}" 
      [ $? -ne 0 ] && LogWarning "Error umounting \"${CURENTRY}\" "
    fi
  done

# remove temporary directories
  for CURENTRY in ${__LIST_OF_TMP_DIRS} ; do
    LogRuntimeInfo "Removing the directory \"${CURENTRY}\" ..."
    if [ -d "${CURENTRY}" ] ; then
      rm -r "${CURENTRY}" 2>/dev/null
      [ $? -ne 0 ] && LogWarning "Error removing the directory \"${CURENTRY}\" "
    fi
  done

  [ -d "${OLDPWD}" ] && cd "${OLDPWD}"
}



## ---------------------------------------
## includeScript
##
## include a script via . [scriptname]
##
## usage: includeScript [scriptname]
##
## returns: -
##
## notes: 
##
includeScript() {
  typeset __FUNCTION="includeScript";    ${__DEBUG_CODE}

  if [ $# -ne 0 ] ; then

    LogInfo "Including the script \"$*\" ..."

# set the variable for the TRAP handlers
    __INCLUDE_SCRIPT_RUNNING="$1"
    [ ! -f "$1" ] && die 247 "Include script \"$1\" not found"
  
# include the script
    . $*

# reset the variable for the TRAP handlers  
    __INCLUDE_SCRIPT_RUNNING=""

  fi
}

## 
## ##### defined trap handler (you may change them)
##


## ---------------------------------------
## GENERAL_SIGNAL_HANDLER
##
## general trap handler 
##
## usage: called automatically (parameter $1 is the signal number)
##
## returns: -
##
GENERAL_SIGNAL_HANDLER() {
  typeset __FUNCTION="GENERAL_SIGNAL_HANDLER";    ${__DEBUG_CODE}

  [ "${__INCLUDE_SCRIPT_RUNNING}"x != ""x ] && LogMsg "Trap occured inside of the include script \"${__INCLUDE_SCRIPT_RUNNING}\" "
  
  case $1 in 

    1 )
        LogWarning "HUP signal received."

        InvertSwitch __VERBOSE_MODE
        LogMsg "Switching verbose mode to $( ConvertToYesNo ${__VERBOSE_MODE} )"
        ;;

    2 )
        if [ ${__USER_BREAK_ALLOWED} -eq ${__TRUE} ] ; then
          die 252 "Script aborted by the user via signal BREAK (CTRL-C)" 
        else
          LogRuntimeInfo "Break signal (CTRL-C) received and ignored (Break is disabled)."
        fi
        ;;

    3 )
        die 251 "QUIT signal received" 
        ;;

   15 )
        die 253 "Script aborted by the external signal TERM" 
        ;;

   "exit" | 0 )
        if [ "${__EXIT_VIA_DIE}"x != "${__TRUE}"x ] ; then
          LogWarning "You should use the function \"die\" to end the program"
        fi    
        return
        ;;
       
    * ) die 254 "Unknown signal catched: $1 "
        ;;

  esac
}


# ======================================


## ---------------------------------------
## DebugHandler
##
## handler for single step mode
##
## usage: called automatically
##
## returns: the RC of the previous executed command
##
DebugHandler() {
  typeset __FUNCTION="DebugHandler";    ${__DEBUG_CODE}

  [ "${__DEBUG_MODE}" -ne ${__TRUE} ] && return ${__LAST_RC}

  stty erase ^H
  
  typeset __THIS_PID=$$

  typeset -i i=0
  typeset -i j=0

  if [ "${__USE_COLORS}"x = "${__TRUE}"x ] ; then
    typeset __LINE_COLOR="\033[0;36m\033[44m"
    typeset __CUR_LINE_COLOR="\033[0;34m\033[46m"
    typeset __DEBUG_MSG_COLOR="\033[0;31m\033[48m"
    typeset __COLOR_OFF="\033[0;m"   
  else
    typeset __LINE_COLOR=""
    typeset __CUR_LINE_COLOR=""
    typeset __DEBUG_MSG_COLOR=""
    typeset __COLOR_OFF=""
  fi

  COLUMNS=80
  [ -x /usr/openwin/bin/resize ] && eval $( /usr/openwin/bin/resize ) 
  eval "typeset -L${COLUMNS} LINE_VAR"
     
#  typeset  -L80 __LINE_VAR=""
  typeset __USERINPUT=""

  set -o emacs
  
  alias __A=$(print "\020")    # up arrow    -> Ctrl-P (previous cmd)
  alias __B=$(print "\016")    # down arrow  -> Ctrl-N (next cmd)
  alias __C=$(print "\006")    # right arrow -> Ctrl-F (move forward 1 char)
  alias __D=$(print "\002")    # left arrow  -> Ctrl-B (move backward 1 char)
  alias __H=$(print "\001")    # home        -> Ctrl-A (go to beginning of line)
  alias __P=$(print "\004")    # delete      -> Ctrl-D (delete char under cursor)
  alias __@=" "
  alias __Q=$(print "\005")    # end         -> Ctrl-E (go to end of line)
  alias __Z=$(print "\017")    # end         -> Ctrl-O (operate)

  export HISTFILE="${__DEBUG_HISTFILE}"
  
# check for the break points
  if [ "${__BREAKPOINT_LINE}"x != "0"x ] ; then
    if [ "${__BREAKPOINT_LINE}" -ge "${__LINENO}" ] ; then
      __LINE_VAR="*** DEBUG: Break point at line ${__LINENO} found"
      print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
      __BREAKPOINT_LINE=0
    else
      return ${__LAST_RC}
    fi
  fi

  if [ "${__STEP_COUNT}"x != "0"x ] ; then
    __STEP_COUNT=$(( __STEP_COUNT - 1 ))
    if [  "${__STEP_COUNT}"x = "0"x  ] ; then
      __LINE_VAR="*** DEBUG: Break point at line ${__LINENO} found"
      print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
    else
      return ${__LAST_RC}
    fi
  fi


# read the script into an array (only once!)
  if [ ${__SCRIPT_ARRAY[0]} = 0 ] ; then
    typeset oIFS=$IFS
    IFS="\n"

    i=1

    while read -r __SCRIPT_ARRAY[$i] ; do
      i=$(( i+1 ))
    done <$0

    __SCRIPT_ARRAY[0]=$i

    IFS=$oIFS
  fi

# define the variables for the output 

  i=${__SCRIPT_ARRAY[0]}
  eval "typeset -R${#i} NUM_VAR"  
  j=$(( ${COLUMNS} - ${#i} -1 ))
#  eval "typeset -L${j} __SRCLINE_VAR"  
  eval "typeset -L${COLUMNS} __SRCLINE_VAR"
  
  if [ "${__TRACE_COUNT}"x != "0"x ] ; then
    __SRCLINE_VAR="${NUM_VAR}>>> ${__SCRIPT_ARRAY[${__LINENO}]}"
    print -u 2 "${__CUR_LINE_COLOR}${__SRCLINE_VAR}"
    __TRACE_COUNT=$(( ${__TRACE_COUNT}-1 ))
    print "${__COLOR_OFF}"
    return ${__LAST_RC}
  fi 

# write the script to a file  
#  i=1
#  while [ i -lt ${__SCRIPT_ARRAY[0]} ] ; do 
#     echo "$i ${__SCRIPT_ARRAY[$i]}" >>./test.out
#     i=$(( i+1 ))
#  done
    
  __LINE_VAR=""   
  print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"

  __LINE_VAR="*** DEBUG: Executed line: ${__LINENO}"
  print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
  __LINE_VAR="*** DEBUG: Line Context:"
  print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"

  [ ${__LINENO} -gt 5 ] && i=$(( ${__LINENO}-5 )) || i=1
  typeset CUR_SRC_WIN_START=$i
  j=$(( ${__LINENO}+5 ))
  [ ${j} -gt ${__SCRIPT_ARRAY[0]} ] && j=${__SCRIPT_ARRAY[0]}

# write the context of the line just executed   
  while [ i -lt j ] ; do
    NUM_VAR=$i
    if [ $i -eq ${__LINENO} ] ; then
      __SRCLINE_VAR="${NUM_VAR}>>> ${__SCRIPT_ARRAY[$i]}"
      print -u 2 "${__CUR_LINE_COLOR}${__SRCLINE_VAR}"
    else
      __SRCLINE_VAR="${NUM_VAR}    ${__SCRIPT_ARRAY[$i]}"
      print -u 2 "${__LINE_COLOR}${__SRCLINE_VAR}"
    fi
      i=$(( i+1 ))
  done   
  print "${__COLOR_OFF}"
  
# read the user input
#
  __LINE_VAR="*** DEBUG: \$\$ is ${__THIS_PID}; \$? is ${__LAST_RC}; \$! is ${__LAST_BG_RC}"
  print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
  __LINE_VAR="*** DEBUG: Enter a command to execute or <enter> to execute the next command:"
  print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"

  while [ 1 = 1 ] ; do
    print -u 2 -n  "${__DEBUG_MSG_COLOR}DEBUG>>> "
    read -s __USERINPUT __USERPARMS __USERVALUE __USERVALUE2
  
    case ${__USERINPUT} in 

      "help" | "?" ) __LINE_VAR="*** DEBUG:Known commands"
           print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
cat 1>&2 <<EOT

  help                         - print this text
  trace count               - execute count lines
  trace off                   - turn single mode off
  trace at lineNo           - suspend single step until line linNo
  trace not lineNumber   - suspend single step for lineNumber statements
  show lineNo [count]    - show count (def. 10) lines after line lineNo
  exit [returncode]        - exit the program with RC returnCode (def.: 1)
  <return>                   - execute next statement (single step)
  everything else          - execute the command 

EOT
           ;; 
   
   
      "" ) break 
           ;;
           
      "trace"  ) :
          case ${__USERPARMS}  in 

            "off" )
              __LINE_VAR="*** DEBUG: Turning single step mode off"
              print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
              __DEBUG_MODE=${__FALSE} 
              break
              ;;
      
            "at" )
              if [ "${__USERVALUE}"x = ""x ] ; then
                __LINE_VAR="*** DEBUG: value missing"
                print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
                continue
              fi

              isNumber ${__USERVALUE} 2>/dev/null
              if [ $? -ne 0 ] ; then
                __LINE_VAR="*** DEBUG: \"${__USERVALUE}\" is not a number"
                print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
                continue
              fi         

              __LINE_VAR="*** DEBUG: Suspending single step until line ${__USERVALUE}"
              print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
              __BREAKPOINT_LINE=${__USERVALUE}      
              break
              ;;

            "not" )
              if [ "${__USERVALUE}"x = ""x ] ; then
                __LINE_VAR="*** DEBUG: value missing"
                print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
                continue
              fi

              isNumber ${__USERVALUE} 2>/dev/null
              if [ $? -ne 0 ] ; then
                __LINE_VAR="*** DEBUG: \"${__USERVALUE}\" is not a number"
                print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
                continue
              fi         

              __LINE_VAR="*** DEBUG: Suspending single step for the next ${__USERVALUE} statements"
              print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
              __STEP_COUNT=${__USERVALUE}      
              break
              ;;


            * )
              isNumber ${__USERPARMS} 2>/dev/null
              if [ $? -eq 0 ] ; then
                __TRACE_COUNT=${__USERPARMS}
                __LINE_VAR="*** DEBUG: Executing \"${__USERPARMS}\" lines"
                print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
                break
              else
                __LINE_VAR="*** DEBUG: unknown trace option \"${__USERPARMS}\" "
                print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"    
              fi
              ;;
      
          esac
          ;;   

      "show" )      
           [ "${__USERPARMS}"x = ""x ] && __USERPARMS=${CUR_SRC_WIN_START}

           isNumber ${__USERPARMS} 2>/dev/null
           if [ $? -ne 0 ] ; then
             __LINE_VAR="*** DEBUG: \"${__USERPARMS}\" is not a number"
             print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
             continue
           fi         

           if [ ${__USERPARMS} -lt 1 ] ; then
             __LINE_VAR="*** DEBUG: \"${__USERPARMS}\" is out of range"
             print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
             continue
           fi         

           if [ "${__USERPARMS}" -gt ${__SCRIPT_ARRAY[0]} ] ; then
             __LINE_VAR="*** DEBUG: \"${__USERPARMS}\" is out of range (last line is ${__SCRIPT_ARRAY[0]})"
             print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"    
             continue
           fi

           i=${__USERPARMS}

           if [ "${__USERVALUE}"x != ""x ] ; then
             isNumber ${__USERVALUE} 2>/dev/null
             if [ $? -ne 0 ] ; then
               __LINE_VAR="*** DEBUG: \"${__USERVALUE}\" is not a number"
               print -u 2 "${__DEBUG_MSG_COLOR}${__LINE_VAR}"
               continue
             fi         
             j=$(( ${i}+ ${__USERVALUE} -1 )) 
           else
             j=$(( ${i}+9 ))   
           fi

           [ ${j} -gt ${__SCRIPT_ARRAY[0]} ] && j=${__SCRIPT_ARRAY[0]}

           while [ i -le j ] ; do
             NUM_VAR=$i
             if [ $i -eq ${__LINENO} ] ; then
               __SRCLINE_VAR=">>> ${__SCRIPT_ARRAY[$i]}"
               print -u 2 "${__CUR_LINE_COLOR}${NUM_VAR} ${__SRCLINE_VAR}"
             else
               __SRCLINE_VAR="    ${__SCRIPT_ARRAY[$i]}"
               print -u 2 "${__LINE_COLOR}${NUM_VAR} ${__SRCLINE_VAR}"
             fi 
             i=$(( i+1 ))
           done      
     
           ;;
   
      "exit" | "quit" )  :
           print "${__COLOR_OFF}"
           [ "${__USERPARMS}"x = ""x ] && die 252 "Program aborted by the user"
           die ${__USERPARMS} 
           ;;

      * ) executeCommand ${__USERINPUT} ${__USERPARMS} ${__USERVALUE} ${__USERVALUE2}
            ;;
    esac
  done
  print "${__COLOR_OFF}"

  return ${__LAST_RC}
}


## 
## ##### defined sub routines 
##

## ---------------------------------------
## ShowShortUsage
##
## print the (short) usage help
##
## usage: ShowShortUsage
##
## returns: -
##
ShowShortUsage() {
  typeset __FUNCTION="ShowShortUsage";    ${__DEBUG_CODE}
  typeset DOMAIN_LIST=""
  typeset XENDOMAIN=""
  typeset XENTPYE=""
  typeset -L50 CURTITLE
  typeset -L15 CURDOMAIN
  typeset DOMAIN_TYPE
  
  
cat <<EOT
  ${__SCRIPTNAME} ${__SCRIPT_VERSION} - ${__SHORT_DESC}

  Usage: ${__SCRIPTNAME} [-v|+v] [-q|+q] [-h] [-l logfile|+l] [-y|+y] [-n|+n] 
                    [-D|+D] [-a|+a] [-O|+O] [-f|+f] [-C] [-H] [-S n] [-G|+G]
		    [-x|+x] [-c|+c] [-g|+g] [-o outputfile] [-X action] domain
  
  Known Xen domains:

EOT

  GetListOfKnownXenConfigs DOMAIN_LIST
  for XENDOMAIN in ${DOMAIN_LIST} ; do

    eval CURTITLE="\${${XENDOMAIN}_TITLE}"
    eval XENTYPE="\${${XENDOMAIN}_DOMAIN_TYPE}"
    [ "${XENTYPE}"x != ""x ] && DOMAIN_TYPE="${XENTYPE}" || DOMAIN_TYPE=${DEFAULT_DOMAIN_TYPE}
    
    CURDOMAIN="${XENDOMAIN}"
    echo "     ${CURDOMAIN} (${DOMAIN_TYPE} Bit) ${CURTITLE}"

  done    

}


## ---------------------------------------
## ShowUsage
##
## print the (long) usage help
##
## usage: ShowUsage
##
## returns: -
##
ShowUsage() {
  typeset __FUNCTION="ShowUsage";    ${__DEBUG_CODE}

  ShowShortUsage
cat <<EOT

 Note: Use -{switch} to turn an option on; use +{switch} to turn an option off

    Parameter:

      -v|+v - turn verbose mode on/off; current value: $( ConvertToYesNo "${__VERBOSE_MODE}" )
      -q|+q - turn quiet mode on/off; current value: $( ConvertToYesNo "${__QUIET_MODE}" )
      -h    - show usage 
      -l    - set the logfile 
              current value: ${NEW_LOGFILE:=${__DEF_LOGFILE}}
      +l    - do not write a logfile
      -y|+y - assume yes to all questions or not
      -n|+n - assume no to all questions or not
      -D|+D - run main in single step mode (and turn colors on) 
      -a|+a - turn colors on/off; current value: $( ConvertToYesNo "${__USE_COLORS}" )
      -O|+O - overwrite existing files or not; current value: $( ConvertToYesNo "${__OVERWRITE_MODE}" )
      -f|+f - force; do it anyway
       -C - write a default config file in the current directory and exit
      -S n  - print error/warning summaries: n = 0 no summarys, 1 = print error msgs,
              2 = print warning msgs, 3 = print error and warning mgs
              Default: ${__PRINT_SUMMARIES}
      -G|+G - wait/do not wait for return at script end; current value: $( ConvertToYesNo "${STARTED_VIA_GUI}" )
      -H    - write extended usage to STDERR
      
      -x|+x - start/do not start the Xen DomU
      -c|+c - start/do not start the console
      -g|+g - start/do not start the VNC Viewer
      -o outputfile - name of the outputfile 
      -X action
            - what to do; known actions:
	      START - start a domain
	      LIST - list all known domains
	      CHECK - check the configuration of a domain
	      STATUS - show the status of some or all domains
	 Current Action is "${ACTION}"  

      domain - name of the DomU domain
	          
EOT

  return 0      
}

# -----------------------------------------------------------------------------


# --------------------------------------
## GetListOfKnownXenConfigs
##
## get a list of all known Xen domains
##
## usage: GetListOfKnownXenConfigs [resultvar]
##
## returns: the number of found Domain definitions
##          
##          If resultvar is ommitted, the names of the domain configuration are printed to STDOUT
##          else the names of the domain configuration are saved in the result var
##
##
GetListOfKnownXenConfigs() {
  typeset __FUNCTION="GetListOfKnownXenConfigs";    ${__DEBUG_CODE}

# temporary clean the variable __CONFIG_PARAMETER
  typeset __CONFIG_PARAMETER=''

  typeset THISRC=0

  typeset DOMAIN_TITLES=""
  typeset DOMAIN_CONFIGFILE=""
  typeset CURTITLE=""
  typeset RESULTSTRING=""

  DOMAIN_TITLES="$( set | grep "_TITLE=" | cut -f1 -d '='  )"
  
  for CURTITLE in ${DOMAIN_TITLES} ; do
    DOMAIN_NAME="${CURTITLE%_*}"       
    eval DOMAIN_CONFIGFILE="\${${DOMAIN_NAME}_CONFIG_FILE_NAME}"
    if [ "${DOMAIN_CONFIGFILE}"x != ""x ] ; then
      RESULTSTRING="${RESULTSTRING} ${DOMAIN_NAME}"
      (( THISRC=THISRC+1 ))
    fi
  done

  if [ "$1"x != ""x ] ; then
    eval $1=\"${RESULTSTRING}\" 
  else
    echo "${RESULTSTRING}"
  fi

  return ${THISRC}     
}


# --------------------------------------
## get_status_of_xen_domain
##
## get the status of a Xen domain 
##
## usage: get_status_of_xen_domain domainID {printstatus}
##
## returns: ${__TRUE} - the domain is running
##          ${__FALSE} - the domain is not running
##          ${__INVALID_USAGE} - invalid usage
##
##          The output of xm list is printed to STDOUT if printstatus is not empty
##
get_status_of_xen_domain(){
  typeset __FUNCTION="get_status_of_xen_domain";    ${__DEBUG_CODE}
  typeset THISRC=${__INVALID_USAGE}

  if [ $# -ge 1 ] ; then
    typeset XEN_DOMAIN_ID=$1    
    typeset XEN_DOMAIN_RUNNING_MSG=""
  
    XEN_DOMAIN_RUNNING_MSG="$( "${XM_BINARY}" list "${XEN_DOMAIN_ID}"  2>&1 )"
    if [ $? -eq 0 ] ; then
      LogInfo "The Xen domain \"${XEN_DOMAIN_ID}\" is running"
      THISRC=${__TRUE}
      [ $# -gt 1 ] && echo "${XEN_DOMAIN_RUNNING_MSG}"
    else
      LogInfo "The Xen domain \"${XEN_DOMAIN_ID}\" is not running"
      THISRC=${__FALSE}
    fi   
  fi
  
  return ${THISRC}
}


# --------------------------------------
## is_console_attached
##
## check if a console is attached to a Xen Domain 
##
## usage: is_console_attached XEN_DOMAIN_NUM_ID
##
## returns: ${__TRUE} - a console is attached to the Xen Domain
##          ${__FALSE} - no console is attached to the Xen Domain
##          ${__INVALID_USAGE} - invalid usage
##
is_console_attached(){
  typeset __FUNCTION="is_console_attached";    ${__DEBUG_CODE}
  typeset THISRC=${__INVALID_USAGE}

  if [ $# -eq 1 ] ; then
    typeset XEN_DOMAIN_NUM_ID=$1
  
    ps -ef | grep "xenconsole ${XEN_DOMAIN_NUM_ID}" | grep -v grep >/dev/null
    if [ $? -eq  0 ] ; then
      LogInfo "There is already a console connected to the Xen domain \"${XEN_DOMAIN_ID}\" "
      THISRC=${__TRUE}
    else
      LogInfo "There is no console connected to the Xen domain \"${XEN_DOMAIN_ID}\" "
      THISRC=${__FALSE}
    fi  
  fi
  return ${THISRC}
}


# --------------------------------------
## is_vncviewer_attached
##
## check if a VNC viewer is attached to a Xen Domain 
##
## usage: is_vncviewer_attached XEN_DOMAIN_IP VNCVIEWER_PORT
##
## returns: 0 - a VNC viewer is attached to the Xen Domain
##          1 - no VNC viewer is attached to the Xen Domain but the port is still in use
##          2 - no VNC viewer is attached to the Xen Domain and the port is not in use
##         ${__INVALID_USAGE} - invalid usage
##
is_vncviewer_attached(){
  typeset __FUNCTION="is_vncviewer_attached";    ${__DEBUG_CODE}
  typeset THISRC=${__INVALID_USAGE}

  if [ $# -eq 2 ] ; then
    typeset DOMAIN_IP_ADDRESS=$1
    typeset VNCVIEWER_PORT=$2
 
    netstat -an | grep " ${DOMAIN_IP_ADDRESS}.${VNCVIEWER_PORT} "  >/dev/null 2>/dev/null
    if [ $? -eq 0 ] ; then
      ps -ef | grep -v grep | grep "${DOMAIN_IP_ADDRESS}:${VNCVIEWER_PORT}" >/dev/null
      if [ $? -eq 0 ] ; then    
        LogInfo "There is a vncviewer connected to the Xen domain \"${XEN_DOMAIN_ID}\" "
        THISRC=0
      else
        LogInfo "No vncviewer connected to the Xen domain \"${XEN_DOMAIN_ID}\" but the port \"${DOMAIN_IP_ADDRESS}:${VNCVIEWER_PORT}\" is still in use"
        THISRC=1
      fi
    else
      LogInfo "There is no vncviewer connected to the Xen domain \"${XEN_DOMAIN_ID}\" "
      THISRC=2
    fi
  fi
   
  return ${THISRC}
}


# --------------------------------------
## start_xen_domain
##
## start a Xen domain
##
## usage: start_xen_domain XEN_DOMAIN_ID XEN_DOMAIN_CONFIG_FILE 
##
## returns: ${__TRUE} - ok, domain started
##          ${__FALSE} - error starting the domain
##          ${__INVALID_USAGE} - invalid usage
##
## The global variable XEN_DOMAIN_STARTMSG contains STDOUT and STDERR from the xm command
##
start_xen_domain(){
  typeset __FUNCTION="start_xen_domain";    ${__DEBUG_CODE}
  typeset THISRC=${__INVALID_USAGE}

  if [ $# -eq 2 ] ; then
    typeset XEN_DOMAIN_ID="$1"
    typeset XEN_DOMAIN_CONFIG_FILE="$2"
    THISRC=${__FALSE}
    
    LogMsg "Starting the Xen domain \"${XEN_DOMAIN_ID}\" now ..."      
    XEN_DOMAIN_STARTMSG="$( "${XM_BINARY}" ${XM_PARAMETER} create "${XEN_DOMAIN_CONFIG_FILE}" 2>&1 )"
    [ $? -eq 0 ] && THISRC=${__TRUE}

    XEN_DOMAIN_JUST_STARTED=${__TRUE}
  fi
  
  return ${THISRC}
}


# --------------------------------------
## attach_console_to_xen_domain
##
## attach a console to a Xen domain
##
## usage: attach_console_to_xen_domain XEN_DOMAIN_ID XTERM_BINARY XTERM_PARAMETER WINDOW_TITLE
##
## returns: ${__TRUE} - ok
##          ${__FALSE} - error
##          ${__INVALID_USAGE} - invalid usage
##
attach_console_to_xen_domain(){
  typeset __FUNCTION="attach_console_to_xen_domain";    ${__DEBUG_CODE}
  typeset THISRC=${__INVALID_USAGE}

  if [ $# -eq 4 ] ; then
    typeset XEN_DOMAIN_ID=$1
    typeset XTERM_BINARY="$2"
    typeset XTERM_PARAMETER="$3"
    typeset WINDOW_TITLE="$4"
    THISRC=${__FALSE}  

    LogMsg "Attaching a terminal to the console of the Xen domain \"${XEN_DOMAIN_ID}\" ..."

    echo "\"${XM_BINARY}\" ${XM_PARAMETER} console \"${XEN_DOMAIN_ID}\" " >"${__TEMPFILE1}" 
    if [ $? -eq 0 ] ; then

      chmod 755 "${__TEMPFILE1}"
      if [ $? -eq 0 ] ; then    
        nohup "${XTERM_BINARY}" ${XTERM_PARAMETER} -T "${WINDOW_TITLE}" -e "${__TEMPFILE1}" 2>/dev/null 1>/dev/null &

        THISRC=${__TRUE}

# wait until the terminal is up and running before deleting the temporary file!
        sleep 3   
      else
        LogError "Can not change the mode of the temporary file \"${__TEMPFILE1}\" "
      fi
    else
      LogError "Can not create the temporary file \"${__TEMPFILE1}\" "
    fi
  fi

  return ${THISRC}
}


# --------------------------------------
## attach_vncviewer_to_xen_domain
##
## attach a vnc viewer to a Xen domain
##
## usage: attach_vncviewer_to_xen_domain XEN_DOMAIN_ID VNC_VIEWER_BINARY VNC_VIEWER_PARAMETER \
##          VNC_VIEWER_TARGET VNCVIEWER_PORT
##
## returns: ${__TRUE} - ok
##          ${__FALSE} - error
##          ${__INVALID_USAGE} - invalid usage
##
attach_vncviewer_to_xen_domain(){
  typeset __FUNCTION="attach_vncviewer_to_xen_domain";    ${__DEBUG_CODE}
  typeset THISRC=${__INVALID_USAGE}

  if [ $# -ge 4 ] ; then
    typeset XEN_DOMAIN_ID=$1
    typeset VNC_VIEWER_TARGET="$2"
    typeset VNC_VIEWER_PORT="$3"
    typeset VNC_VIEWER_BINARY="$4"
    typeset VNC_VIEWER_PARAMETER="$5"
    THISRC=${__FALSE}

    LogMsg "Starting the vncviewer for the Xen domain \"${XEN_DOMAIN_ID}\" ..."
    LogMsg "Waiting for the Xen domain \"${XEN_DOMAIN_ID}\" to come up ..."

    typeset CUR_COUNT=0
    typeset CUR_DOMAIN_IS_UP=${__FALSE}

    while [ ${CUR_COUNT} -lt ${PING_RETRY_COUNT} ] ; do
      echo ".\c"
      ping ${VNC_VIEWER_TARGET} >/dev/null 2>/dev/null
      if [ $? -eq 0 ] ; then
        CUR_DOMAIN_IS_UP=${__TRUE}
        break
      fi
      (( CUR_COUNT = CUR_COUNT+1 ))
    done
    echo ""

    if [ "${CUR_DOMAIN_IS_UP}" = ${__TRUE} ] ; then

# IP in the domain is up; now wait until the VNC server is running

      if [ ${XEN_DOMAIN_JUST_STARTED} = ${__TRUE} ] ; then
        LogMsg "Waiting ${CUR_VNC_STARTUP_DELAY} seconds before starting the VNC viewer ..."
        i=0
        while [ $i -lt ${CUR_VNC_STARTUP_DELAY} ] ; do
          sleep 1  ; echo ".\c"
  	  (( i = i + 1 ))
        done
        echo ""
      fi

      LogMsg "Starting the vncviewer for the Xen domain \"${XEN_DOMAIN_ID}\" ..."
      nohup "${VNCVIEWER_BINARY}" ${VNCVIEWER_PARAMETER} "${VNC_VIEWER_TARGET}:${VNC_VIEWER_PORT}" 1>/dev/null &
      THISRC=${__TRUE}
    else
      LogError "The Xen domain \"${XEN_DOMAIN_ID}\" is not reachable via IP"
    fi
  fi
  
  return ${THISRC}
}


# --------------------------------------
## get_domain_id
##
## get the domain ID
##
## usage: get_domain_id configfile
##
## returns: ${__TRUE} - okay, domain id found, variables set
##          ${__FALSE} - error
##          ${__INVALID_USAGE} - invalid usage
##
## This routine sets the following global variables:
##   XEN_DOMAIN_ID
##
#
get_domain_id(){
  typeset __FUNCTION="get_domain_id";    ${__DEBUG_CODE}
  typeset THISRC=${__INVALID_USAGE}

  if [ $# -eq 1 ] ; then
    typeset XEN_DOMAIN_CONFIG_FILE="$1"
    THISRC=${__FALSE}
    
    XEN_DOMAIN_ID=$( grep "name " "${XEN_DOMAIN_CONFIG_FILE}" | cut -f2 -d'"' )  
    [ "${XEN_DOMAIN_ID}"x != ""x ] && THISRC=${__TRUE}

    LogInfo "The Xen domain ID is \"${XEN_DOMAIN_ID}\""
  fi
  
  return ${THISRC}
}


# --------------------------------------
## get_domain_num_id
##
## get the domain numeric ID
##
## usage: get_domain_num_id XEN_DOMAIN_ID
##
## returns: ${__TRUE} - okay, domain id found, variables set
##          ${__FALSE} - error
##          ${__INVALID_USAGE} - invalid usage
##
## This routine sets the following global variables:
##   XEN_DOMAIN_NUM_ID
##
get_domain_num_id(){
  typeset __FUNCTION="get_domain_num_id";    ${__DEBUG_CODE}
  typeset THISRC=${__INVALID_USAGE}

  if [ $# -eq 1 ] ; then
    typeset XEN_DOMAIN_ID="$1"
    THISRC=${__FALSE}
    
    XEN_DOMAIN_NUM_ID=$( ${XM_BINARY} ${XM_PARAMETER} list "${XEN_DOMAIN_ID}" | tr -s " " | grep ${XEN_DOMAIN_ID} | cut -f2 -d " ")
    [ "${XEN_DOMAIN_NUM_ID}"x != ""x ] && THISRC=${__TRUE}

    LogInfo "The Xen domain numeric ID is \"${XEN_DOMAIN_NUM_ID}\""
  fi      

  return ${THISRC}
}

# --------------------------------------
## XenDomainConfigExists
##
## check if there a Xen domain config exists for a given domain name
##
## usage: XenDomainConfigExists domainname
##
## returns: ${__TRUE} - the Xen domain is known by this script
##          ${__FALSE} - the Xen domain is not known by this script
##          ${__INVALID_USAGE} - invalid usage
##
XenDomainConfigExists(){
  typeset __FUNCTION="XenDomainConfigExists";    ${__DEBUG_CODE}
  typeset THISRC=${__INVALID_USAGE}

  if [ $# -eq 1 ] ; then
    typeset XEN_CONFIG="$1"
    typeset XEN_CONFIG_TITLE=""
    THISRC=${__FALSE}
    
    if [ "${XEN_CONFIG}"x != ""x ] ; then

      set | grep "^${XEN_CONFIG}_TITLE=" >/dev/null
      if [ $? = 0 ] ; then
        eval XEN_CONFIG_TITLE="\${${XEN_CONFIG}_TITLE}"
        [ "${XEN_CONFIG_TITLE}"x != ""x ] && THISRC=${__TRUE}
      fi
    fi
  fi

  return ${THISRC}
}


# --------------------------------------
## SetXenDomainConfig_from_Parameter
##
## process the parameter
##
## usage: SetXenDomainConfig_from_Parameter 
##
## returns: ${__TRUE} - ok
##          ${__TRUE} - error
##
SetXenDomainConfig_from_Parameter(){
  typeset __FUNCTION="SetXenDomainConfig_from_Parameter";    ${__DEBUG_CODE}
  typeset THISRC=${__TRUE}

  [ "${PARAMETER_START_XEN_DOMAIN}"x != ""x ]     && CUR_START_XEN_DOMAIN="${PARAMETER_START_XEN_DOMAIN}"
  [ "${PARAMETER_START_CONSOLE_WINDOW}"x != ""x ] && CUR_START_CONSOLE_WINDOW="${PARAMETER_START_CONSOLE_WINDOW}"
  [ "${PARAMETER_START_VNCVIEWER}"x != ""x ]     && CUR_START_VNCVIEWER="${PARAMETER_START_VNCVIEWER}"
   
  return ${__THISRC} 
}


# --------------------------------------
## SetXenDomainConfig
##
## activate a Xen Domain configuration
##
## usage: SetXenDomainConfig domainname
##
## returns: ${__TRUE} - the Xen domain is set
##          ${__TRUE} - error
##
SetXenDomainConfig(){
  typeset __FUNCTION="SetXenDomainConfig";    ${__DEBUG_CODE}
  typeset THISRC=${__FALSE}

  typeset XEN_CONFIG="$1"

  XEN_DOMAIN_JUST_STARTED=${__FALSE}

  if [ "${XEN_CONFIG}"x != ""x ] ; then
    eval CUR_TITLE="\${${XEN_CONFIG}_TITLE}"

    eval CUR_IP_ADDRESS="\${${XEN_CONFIG}_IP_ADDRESS}"
    eval CUR_HOSTNAME="\${${XEN_CONFIG}_HOSTNAME}"

    eval CUR_CONFIG_FILE_NAME="\${${XEN_CONFIG}_CONFIG_FILE_NAME}"

    eval CUR_DOMAIN_TYPE="\${${XEN_CONFIG}_DOMAIN_TYPE}"

    eval CUR_START_CONSOLE_WINDOW="\${${XEN_CONFIG}_START_CONSOLE_WINDOW}"
    eval CUR_START_XEN_DOMAIN="\${${XEN_CONFIG}_START_XEN_DOMAIN}"
    eval CUR_START_VNCVIEWER="\${${XEN_CONFIG}_START_VNCVIEWER}"

    eval CUR_BG_COLOR="\${${XEN_CONFIG}_BG_COLOR}"
    eval CUR_FG_COLOR="\${${XEN_CONFIG}_FG_COLOR}"

    eval CUR_XTERM_BINARY="\${${XEN_CONFIG}_XTERM_BINARY}"
    eval CUR_XTERM_PARAMETER="\${${XEN_CONFIG}_XTERM_PARAMETER}"
    eval CUR_XTERM_ADD_PARAMETER="\${${XEN_CONFIG}_XTERM_ADD_PARAMETER}"

    eval CUR_VNCVIEWER_BINARY="\${${XEN_CONFIG}_VNCVIEWER_BINARY}"
    eval CUR_VNCVIEWER_PARAMETER="\${${XEN_CONFIG}_VNCVIEWER_PARAMETER}"
    eval CUR_VNCVIEWER_ADD_PARAMETER="\${${XEN_CONFIG}_VNCVIEWER_ADD_PARAMETER}"

    eval CUR_PING_RETRY_COUNT="\${${XEN_CONFIG}_PING_RETRY_COUNT}"

    eval CUR_VNC_STARTUP_DELAY="\${${XEN_CONFIG}_VNC_STARTUP_DELAY}"

    THISRC=${__TRUE}

  fi
  
  return ${THISRC}
}


# --------------------------------------
## SetXenDomainConfig_from_Defaults
##
## use defaults for all not yet set configuration values
##
## usage: SetXenDomainConfig_from_Defaults 
##
## returns: ${__TRUE} - ok
##          ${__TRUE} - error
##
SetXenDomainConfig_from_Defaults(){
  typeset __FUNCTION="SetXenDomainConfig_from_Defaults";    ${__DEBUG_CODE}
  typeset THISRC=${__TRUE}

# use general defaults if necessary

  [ "${CUR_XTERM_BINARY}"x = ""x ] && CUR_XTERM_BINARY="${XTERM_BINARY}"

  [ "${CUR_XTERM_PARAMETER}"x = ""x ] && CUR_XTERM_PARAMETER="${XTERM_PARAMETER}"

  [ "${CUR_VNCVIEWER_BINARY}"x = ""x ] && CUR_VNCVIEWER_BINARY="${VNCVIEWER_BINARY}"

  [ "${CUR_VNCVIEWER_PARAMETER}"x = ""x ] && CUR_VNCVIEWER_PARAMETER="${VNCVIEWER_PARAMETER}"

  [ "${CUR_DOMAIN_TYPE}"x = ""x ] && CUR_DOMAIN_TYPE="${DOMAIN_TYPE}"

  [ "${CUR_START_CONSOLE_WINDOW}"x = ""x ] && CUR_START_CONSOLE_WINDOW="${START_CONSOLE_WINDOW}"

  [ "${CUR_START_VNCVIEWER}"x = ""x ] && CUR_START_VNCVIEWER="${START_VNCVIEWER}"

  [ "${CUR_START_XEN_DOMAIN}"x = ""x ] && CUR_START_XEN_DOMAIN="${START_XEN_DOMAIN}"

  [ "${CUR_PING_RETRY_COUNT}"x = ""x ] && CUR_PING_RETRY_COUNT="${START_PING_RETRY_COUNT}"

  [ "${CUR_VNC_STARTUP_DELAY}"x = ""x ] && CUR_VNC_STARTUP_DELAY="${VNC_STARTUP_DELAY}"
  
# add domain specific values

  [ "${CUR_XTERM_ADD_PARAMETER}"x != ""x ] && CUR_XTERM_PARAMETER="${CUR_XTERM_PARAMETER} ${CUR_XTERM_ADD_PARAMETER}"
  [ "${CUR_VNCVIEWER_ADD_PARAMETER}"x != ""x ] && CUR_VNCVIEWER_PARAMETER="${CUR_VNCVIEWER_PARAMETER} ${CUR_VNCVIEWER_ADD_PARAMETER}"

  [ "${CUR_FG_COLOR}"x != ""x ] && CUR_XTERM_PARAMETER="${CUR_XTERM_PARAMETER} -fg ${CUR_FG_COLOR}"
  [ "${CUR_BG_COLOR}"x != ""x ] && CUR_XTERM_PARAMETER="${CUR_XTERM_PARAMETER} -bg ${CUR_BG_COLOR}"

  if [ -f "${CUR_CONFIG_FILE_NAME}" ] ; then
    CUR_XEN_DOMAIN_CONFIG_FILE="${CUR_CONFIG_FILE_NAME}"
  else
    CUR_XEN_DOMAIN_CONFIG_FILE="${XEN_CONFIGDIR}/${CUR_CONFIG_FILE_NAME}"
  fi

  if [ "${CUR_HOSTNAME}"x != ""x ] ; then
    CUR_VNCVIEWER_TARGET="${CUR_HOSTNAME}"
  else
    CUR_VNCVIEWER_TARGET="${CUR_IP_ADDRESS}"
  fi

  return ${THISRC}
}

# --------------------------------------
## CheckXenDomainConfigForStarting
##
## check the current Xen Domain configuration
##
## usage: CheckXenDomainConfigForStarting domainname
##
## returns: ${__TRUE} - the Xen domain configuration is okay
##          ${__FALSE} - the Xen domain configuration is not okay
##          ${__INVALID_USAGE} - invalid usage
##
CheckXenDomainConfigForStarting(){
  typeset __FUNCTION="CheckXenDomainConfigForStarting";    ${__DEBUG_CODE}
  typeset THISRC=${__INVALID_USAGE}

  if [ $# -eq 1 ] ; then
    typeset XEN_CONFIG="$1"
    typeset ENVIRONMENT_OKAY=${__TRUE}
    typeset ERROR_MESSAGES=""
    THISRC=${__FALSE}

    if [ "${XEN_CONFIG}"x != ""x ] ; then

# check the Xen version
#
      XEN_VERSION="$( pkginfo -l SUNWxenu | grep VERSION | tr -s " " | cut -f3 -d " " )"
      if [ "${XEN_VERSION}"x != "${TESTED_XEN_VERSION}"x ] ; then
        LogWarning "This script was only tested with Xen Version ${TESTED_XEN_VERSION}"
	LogWarning "The installed Xen version is \"${XEN_VERSION}\""
      fi
      
# check if Xen is running on this machine
#
      XEN_DAEMON_STATUS=$( svcs -o STATE -H ${XEN_FRMI})
      if [ "${XEN_DAEMON_STATUS}"x != "online"x ] ; then
        ERROR_MESSAGES="${ERROR_MESSAGES}
Looks like xend is NOT running on this machine
I was looking for the FRMI \"${XEN_FRMI}\" - 
maybe the FRMI of xend is different in the Xen drop you're using
If yes, change the variable \"DEFAULT_XEN_FRMI\" in the source code accordingly. "
        ENVIRONMENT_OKAY=${__FALSE}
      fi

# check if the xm binary exists
#    
      if [ "${XM_BINARY}"x = ""x ] ; then
        ERROR_MESSAGES="${ERROR_MESSAGES}
Variable XM_BINARY is empty"
        ENVIRONMENT_OKAY=${__FALSE}
      elif [ ! -x "${XM_BINARY}" ] ; then
        ERROR_MESSAGES="${ERROR_MESSAGES}
xm binary \"${XM_BINARY}\" not found or not executable"
        ENVIRONMENT_OKAY=${__FALSE}
      fi  
    
      if [ ${ENVIRONMENT_OKAY} -eq ${__TRUE} ] ; then
        THISRC=${__TRUE}
      else
        echo "${ERROR_MESSAGES}"
      fi
    fi
  fi
  
  return ${THISRC}
}

# --------------------------------------
## CheckXenDomainConfig
##
## check the current Xen Domain configuration
##
## usage: CheckXenDomainConfig domainname
##
## returns: ${__TRUE} - the Xen domain configuration is okay
##          ${__FALSE} - the Xen domain configuration is not okay
##          ${__INVALID_USAGE} - invalid usage
##
CheckXenDomainConfig(){
  typeset __FUNCTION="CheckXenDomainConfig";    ${__DEBUG_CODE}
  typeset THISRC=${__INVALID_USAGE}

  if [ $# -eq 1 ] ; then
    typeset XEN_CONFIG="$1"
    typeset ENVIRONMENT_OKAY=${__TRUE}
    typeset ERROR_MESSAGES=""
    THISRC=${__FALSE}

    if [ "${XEN_CONFIG}"x != ""x ] ; then

      CUR_MACHINE_TYPE="$( isainfo -b )"
      if [ "${CUR_MACHINE_TYPE}" != "${CUR_DOMAIN_TYPE}" ] ; then
        ERROR_MESSAGES="${ERROR_MESSAGES}
Can not run a ${CUR_DOMAIN_TYPE} Bit domU on a ${CUR_MACHINE_TYPE} Bit dom0"
        ENVIRONMENT_OKAY=${__FALSE}
      else
        LogMsg "Okay, this is a ${CUR_DOMAIN_TYPE} Bit domain and the the Dom0 is also ${CUR_MACHINE_TYPE} Bit"
      fi
      
      if [ "${XEN_CONFIGDIR}"x = ""x ] ; then
        ERROR_MESSAGES="${ERROR_MESSAGES}
Variable XEN_CONFIGDIR is empty"
        ENVIRONMENT_OKAY=${__FALSE}
      elif [ ! -d "${XEN_CONFIGDIR}" ] ; then
        ERROR_MESSAGES="${ERROR_MESSAGES}
xm config dir \"${XEN_CONFIGDIR}\" does not exist"
        ENVIRONMENT_OKAY=${__FALSE}
      else
        LogMsg "Okay, the domain config directroy \"${XEN_CONFIGDIR}\" exists."
      fi  

      if [ ! -r "${CUR_XEN_DOMAIN_CONFIG_FILE}" ] ; then  
        ERROR_MESSAGES="${ERROR_MESSAGES}
Can not read the Xen domain config file \"${CUR_XEN_DOMAIN_CONFIG_FILE}\" "
        ENVIRONMENT_OKAY=${__FALSE}
      else
        LogMsg "Okay, the domain config file \"${CUR_XEN_DOMAIN_CONFIG_FILE}\" exists."
      fi
    
      if [ ${CUR_START_VNCVIEWER} = ${__TRUE} ] ; then

        if [ "${CUR_VNCVIEWER_BINARY}"x = ""x ] ; then
          ERROR_MESSAGES="${ERROR_MESSAGES}
Variable VNCVIEWER_BINARY is empty"
          ENVIRONMENT_OKAY=${__FALSE}
        elif [ ! -x "${CUR_VNCVIEWER_BINARY}" ] ; then
          ERROR_MESSAGES="${ERROR_MESSAGES}
vncview binary \"${CUR_VNCVIEWER_BINARY}\" not found or not executable"
          ENVIRONMENT_OKAY=${__FALSE}
        fi  

        if [ "${CUR_IP_ADDRESS}"x = ""x -a "${CUR_HOSTNAME}"x = ""x ] ; then
          ERROR_MESSAGES="${ERROR_MESSAGES}
Neither IP_ADDRESS nor HOSTNAME is set for this domain - can not start the vncviewer"
          ENVIRONMENT_OKAY=${__FALSE}
        fi      
      fi

      if [ ${CUR_START_CONSOLE_WINDOW} = ${__TRUE} ] ; then
        if [ "${CUR_XTERM_BINARY}"x = ""x ] ; then
          ERROR_MESSAGES="${ERROR_MESSAGES}
Variable XTERM_BINARY is empty"
          ENVIRONMENT_OKAY=${__FALSE}
        elif [ ! -x "${CUR_XTERM_BINARY}" ] ; then
          ERROR_MESSAGES="${ERROR_MESSAGES}
vncview binary \"${CUR_XTERM_BINARY}\" not found or not executable"
          ENVIRONMENT_OKAY=${__FALSE}
        fi  
      fi
    
      if [ ${ENVIRONMENT_OKAY} -eq ${__TRUE} ] ; then
        THISRC=${__TRUE}
      else
        echo "${ERROR_MESSAGES}"
      fi
    fi
  fi  
  return ${THISRC}
}

# --------------------------------------
## YourRoutine
##
## description 
##
## usage: YourRoutine
##
## returns: ${__TRUE} - the input device is a terminal (interactive)
##          ${__FALSE} - the input device is NOT a terminal
##         ${__INVALID_USAGE} - invalid usage
##
YourRoutine(){
  typeset __FUNCTION="YourRoutine";    ${__DEBUG_CODE}
  typeset THISRC=${__INVALID_USAGE}

  if [ $# -eq 0 ] ; then
    THISRC=${__FALSE}
    
# add code here
  fi

  return ${THISRC}
}

# -----------------------------------------------------------------------------
# main:
#

# install trap handler
  trap "GENERAL_SIGNAL_HANDLER  1"  1
  trap "GENERAL_SIGNAL_HANDLER  2"  2
  trap "GENERAL_SIGNAL_HANDLER  3"  3
  trap "GENERAL_SIGNAL_HANDLER 15" 15
  trap "GENERAL_SIGNAL_HANDLER exit" exit

  
# use a temporary log file until we know the real log file
  __TEMPFILE_CREATED=${__FALSE}
  __MAIN_LOGFILE=${__LOGFILE}
  
  __LOGFILE="/tmp/${__SCRIPTNAME}.$$.TEMP"
  echo >${__LOGFILE}

  LogMsg "${__SCRIPTNAME} started on $( date ) "

  LogRuntimeInfo "Script template used is \"${__SCRIPT_TEMPLATE_VERSION}\" ."

  __WRITE_CONFIG_AND_EXIT=${__FALSE} 

# cleanup the environment
# (remove all variables ending with "_TITLE")
#
  for i in $( set | grep "_TITLE=" | cut -f1 -d "=" ) ; do 
    unset $i 
  done

# init the variables
#  
  eval "${__CONFIG_PARAMETER}"

# read the config file
#
  ReadConfigFile

# init variables with the defaults
#
# format var=${DEFAULT_var}
#

# process all variables beginning with DEFAULT_ 

  for CURVAR in $( set | grep "^DEFAULT_"  | cut -f1 -d"=" ) ; do
    P1="${CURVAR%%=*}"
    P2="${P1#DEFAULT_*}"

# for debugging
#    push_and_set __VERBOSE_MODE ${__TRUE}
#    push_and_set __VERBOSE_LEVEL ${__RT_VERBOSE_LEVEL}
#    LogInfo 0 "Setting variable $P2= \"$( eval "echo \"\$$P1\"")\" "
#    pop __VERBOSE_MODE
#    pop __VERBOSE_LEVEL
        
    eval "$P2="\"\$$P1\"""
   
  done

# save the parameter
#
  THIS_PARAMETER=$*

  INVALID_PARAMETER_FOUND=${__FALSE}

  __PRINT_USAGE=${__FALSE}

# variables used by getops:
#    OPTIND = index of the current argument
#    OPTARG = current function character
#
    
  while getopts :ynvCqhHDfl:aOS:xcgo:X:G CUR_SWITCH ; do

#    echo "CUR_SWITCH is $CUR_SWITCH"
#    echo "OPTIND = $OPTIND"
#    echo "OPTARG = $OPTARG"
#    echo "\$\* is \"$*\" "

    if [ "${CUR_SWITCH}" = ":" ] ; then
      CUR_SWITCH=${OPTARG}
      OPTARG=""
    fi

    case ${CUR_SWITCH} in 
    
       "C" ) __WRITE_CONFIG_AND_EXIT=${__TRUE}  ;;

      "+D" ) __DEBUG_MODE=${__FALSE}  ;;
      
       "D" ) __DEBUG_MODE=${__TRUE} ; __USE_COLORS=${__TRUE} ;;

      "+v" ) __VERBOSE_MODE=${__FALSE} ;;

       "v" ) __VERBOSE_MODE=${__TRUE} ; (( __VERBOSE_LEVEL=__VERBOSE_LEVEL+1 )) ;;

      "+q" ) __QUIET_MODE=${__FALSE} ;;

       "q" ) __QUIET_MODE=${__TRUE} ;;

      "+a" ) __USE_COLORS=${__FALSE} ;;

      "a"  ) __USE_COLORS=${__TRUE} ;;

      "+O" ) __OVERWRITE_MODE=${__FALSE} ;;

       "O" ) __OVERWRITE_MODE=${__TRUE} ;;

       "f" ) __FORCE=${__TRUE} ;;


      "+f" ) __FORCE=${__FALSE} ;;
       
       "l" ) NEW_LOGFILE="${OPTARG:=nul}" ;;

      "+l" ) NEW_LOGFILE="nul" ;;

      "+h" ) __PRINT_USAGE=${__TRUE} 
             __VERBOSE_MODE=${__TRUE}  ;;

       "h" ) __PRINT_USAGE=${__TRUE} ;;

       "H" ) 
echo " ----------------------------------------------------------------------------------" >&2
echo "                         ${__SCRIPTNAME} ${__SCRIPT_TEMPLATE_VERSION} ">&2
echo "                                Documentation" >&2
echo " ----------------------------------------------------------------------------------" >&2

             grep "^##" $0 | cut -c3-80 1>&2 ; die 0 ;;
                  

      "+y" ) __USER_RESPONSE_IS="" ;;

       "y" ) __USER_RESPONSE_IS="y" ;;

      "+n" ) __USER_RESPONSE_IS="" ;;

       "n" ) __USER_RESPONSE_IS="n" ;;

       "S"  ) case ${OPTARG} in

                0 | 1 | 2 | 3 ) : okay
                                    ;;

                * )  LogError "Unknown value for -S found found: \"${OPTARG}\""
                      INVALID_PARAMETER_FOUND=${__TRUE}
                      ;;
                esac
                ;;

       "G" ) STARTED_VIA_GUI=${__TRUE} ;;

      "+G" ) STARTED_VIA_GUI=${__FALSE} ;;
       
      "+x" ) PARAMETER_START_XEN_DOMAIN="${__FALSE}" 
	     ;;

       "x" ) PARAMETER_START_XEN_DOMAIN="${__TRUE}" 
	     ;;

      "+c" ) PARAMETER_START_CONSOLE_WINDOW="${__FALSE}" 
	     ;;

       "c" ) PARAMETER_START_CONSOLE_WINDOW="${__TRUE}"
	     ;;

      "+g" ) PARAMETER_START_VNCVIEWER="${__FALSE}" 
	     ;;

       "g" ) PARAMETER_START_VNCVIEWER="${__TRUE}" 
             ;;

       "X" ) ACTION="${OPTARG}"  ;;
            	     
       "o" ) OUTPUT_FILE="${OPTARG}"  ;;
            
	     		
        \? ) LogError "Unknown parameter found: \"${OPTARG}\" "
             INVALID_PARAMETER_FOUND=${__TRUE}
             break
	     ;;

         * ) LogError "Unknown parameter found: \"${CUR_SWITCH}\" "
             INVALID_PARAMETER_FOUND=${__TRUE}
             break ;;             

    esac
  done

  if [ ${__PRINT_USAGE} = ${__TRUE}  ] ; then
    if [ ${__VERBOSE_MODE} -eq ${__TRUE} ] ; then
      ShowUsage 
      __VERBOSE_MODE=${__FALSE}
    else
      ShowShortUsage 
      LogMsg "Use \"-v -h\" or \"+h\" for a long help text"
    fi
    die 1 ;   
  fi

  shift $(( OPTIND - 1 ))

  if [ $# -ne 0 ] ; then
    ACTION_PARAMETER="$1"
    XEN_CONFIG="$1"
    shift
  fi
  ACTION_PARAMETER2="$*"
    

# add parameter checking code here 
#
# set INVALID_PARAMETER_FOUND to ${__TRUE} if the script
# should abort due to an invalid parameter 
#
#  [ "${NOT_PROCESSED_PARAMETER}"x != ""x ] && INVALID_PARAMETER_FOUND=${__TRUE}
# 
  if [ "${NOT_PROCESSED_PARAMETER}"x != ""x ] ; then
    LogError "Unknown parameter: \"${NOT_PROCESSED_PARAMETER}\" "
    INVALID_PARAMETER_FOUND=${__TRUE}
  fi


  case ${__PRINT_SUMMARIES} in 
     0 )  __PRINT_LIST_OF_WARNINGS_MSGS=${__FALSE} 
           __PRINT_LIST_OF_ERROR_MSGS=${__FALSE}
           ;;

    1 )   __PRINT_LIST_OF_WARNINGS_MSGS=${__FALSE} 
           __PRINT_LIST_OF_ERROR_MSGS=${__TRUE}
           ;;

    2 )   __PRINT_LIST_OF_WARNINGS_MSGS=${__TRUE} 
           __PRINT_LIST_OF_ERROR_MSGS=${__FALSE}
           ;;

    3 )   __PRINT_LIST_OF_WARNINGS_MSGS=${__TRUE} 
           __PRINT_LIST_OF_ERROR_MSGS=${__TRUE}
           ;;

    * ) : this should never happen but who knows ...
          __PRINT_LIST_OF_WARNINGS_MSGS=${__FALSE} 
          __PRINT_LIST_OF_ERROR_MSGS=${__FALSE}
  esac
    
# exit the program if there are one or more invalid parameter
#
  if [ ${INVALID_PARAMETER_FOUND} -eq ${__TRUE} ] ; then
    LogError "One or more invalid parameters found"
    ShowShortUsage
    die 2
  fi
   
  LogRuntimeInfo "Parameter after the options are: " "\"$*\" "
  
# copy the temporary log file to the real log file

  if [ "${NEW_LOGFILE}"x = "nul"x ] ; then
    LogMsg "Running without a log file"
    __MAIN_LOGFILE=""
# delete the temporary logfile   
    rm ${__LOGFILE} 2>/dev/null
    __LOGFILE=""
  else
    [ "${NEW_LOGFILE}"x != ""x ] && __MAIN_LOGFILE=${NEW_LOGFILE}
    LogRuntimeInfo "Initializing the log file\"${__MAIN_LOGFILE}\" "

    touch ${__MAIN_LOGFILE} 2>/dev/null
    cat ${__LOGFILE} >>${__MAIN_LOGFILE} 2>/dev/null
    if [ $? -ne 0 ]   ; then
      LogWarning "Error writing to the logfile \"${__MAIN_LOGFILE}\"."
      LogWarning "Using the log file \"${__LOGFILE}\" "
    else
      rm ${__LOGFILE} 2>/dev/null
      __LOGFILE=${__MAIN_LOGFILE}       
    fi
    LogMsg "Using the log file \"${__LOGFILE}\" "
  fi

  LogRuntimeInfo "Parameter before getopt processing are: \"${THIS_PARAMETER}\" "
  LogRuntimeInfo "Not processed parameter after getopt processing are: \"${NOT_PROCESSED_PARAMETER}\" "


  if [ "${__REQUIRED_OS_VERSION}"x != ""x ] ; then

    LogRuntimeInfo "Curent OS version is \"${__OS_VERSION}\"; required OS version is \"${__REQUIRED_OS_VERSION}\""
    
    __OS_VERSION_OKAY=${__TRUE}
    
    __CUR_MAJOR_VER="${__OS_VERSION%.*}"
    __CUR_MINOR_VER="${__OS_VERSION#*.}"
  
    __REQ_MAJOR_VER="${__REQUIRED_OS_VERSION%.*}"
    __REQ_MINOR_VER="${__REQUIRED_OS_VERSION#*.}"

    [ "${__CUR_MAJOR_VER}" -lt "${__REQ_MAJOR_VER}" ] && __OS_VERSION_OKAY=${__FALSE}
    [ "${__CUR_MAJOR_VER}" -eq "${__REQ_MAJOR_VER}"  -a "${__CUR_MINOR_VER}" -lt "${__REQ_MINOR_VER}" ] && __OS_VERSION_OKAY=${__FALSE}
    
     [ ${__OS_VERSION_OKAY} = ${__FALSE} ] && die 248 "Unsupported OS Version: ${__OS_VERSION}; necessary OS version is ${__REQUIRED_OS_VERSION}"
      
  fi

  if [ ${__MUST_BE_ROOT} -eq ${__TRUE} ] ; then  
    UserIsRoot || die 249 "You must be root to execute this script" 
  fi

  if [ ${__ONLY_ONCE} -eq ${__TRUE} ] ; then
    CreateLockFile
    if [ $? -ne 0 ] ; then
      cat <<EOF

  ERROR:

  Either another instance of this script is already running 
  or the last execution of this script crashes.
  In the first case wait until the other instance ends; 
  in the second case delete the lock file 
  
      ${__LOCKFILE} 

  manually and restart the script.

EOF

      die 250
    fi

# remove the lock file at program end
    __EXITROUTINES="${__EXITROUTINES} RemoveLockFile"    
  fi

# __ABSOLUTE_SCRIPTDIR real absolute directory (no link)
  GetProgramDirectory $0 __ABSOLUTE_SCRIPTDIR
  
# create temporary files
  CreateTemporaryFiles


  if [ "${__DEBUG_MODE}" -eq ${__TRUE} ] ; then
     __LIST_OF_TMP_FILES="${__LIST_OF_TMP_FILES} ${__DEBUG_HISTFILE}"

    trap "__LAST_RC=\$?; __LAST_BG_RC=\$!; __LINENO=\$LINENO; DebugHandler"  DEBUG
:
    echo "INFO: Starting single step mode - works only for the main routine!"
  fi

# check for the parameter -C 
  if [   "${__WRITE_CONFIG_AND_EXIT}" = ${__TRUE} ] ; then
    NEW_CONFIG_FILE="${__CONFIG_FILE}"
    LogMsg "Creating the config file \"${NEW_CONFIG_FILE}\" ..."
    WriteConfigFile ${NEW_CONFIG_FILE}
    [ $? -ne 0 ] && die 246 "Error writing the config file \"${NEW_CONFIG_FILE}\""

    if [ ${__VERBOSE_MODE} = ${__TRUE} ] ; then
      LogInfo "Commands to create the symbolic links for the start scripts:"
      typeset -l SCRIPTNAME=""
      GetListOfKnownXenConfigs DOMAIN_LIST
      for XENDOMAIN in ${DOMAIN_LIST} ; do
        SCRIPTNAME="start_${XENDOMAIN}"
	echo "ln -s $0 ./${SCRIPTNAME}.sh"
      done    
    fi
    
    die 0 "Configfile \"${NEW_CONFIG_FILE}\" written successfully."    
  fi
  

# --- variables for the cleanup routine:
#
# add mounts that should be automatically be unmounted at script end to this variable
#
#  __LIST_OF_TMP_MOUNTS="${__LIST_OF_TMP_MOUNTS} "

# add directories that should be automatically removed at script end to this variable
#
#  __LIST_OF_TMP_DIRS="${__LIST_OF_TMP_DIRS} "

# add files that should be automatically removed at script end to this variable
#  __LIST_OF_TMP_FILES="${__LIST_OF_TMP_FILES} "

# add functions that should be called automatically at program end to this variable
#
#  __EXITROUTINES="${__EXITROUTINES} "    

# get name of the Xen domain to start if not entered as parameter
# (use the script name to retrieve the name)
#
  if [ "${XEN_CONFIG}"x = ""x ] ; then
    TEMPVAR="${__SCRIPTNAME#start_*}"
    XEN_CONFIG="${TEMPVAR%%.sh}"
    [  "${XEN_CONFIG}"x = ""x ] && die 10 "I don't know which Xen domain to start"
  fi

  LogInfo "ACTION is \"${ACTION}\""
  
  case "${ACTION}" in

    "writeconfig" )
    [ "${ACTION_PARAMETER2}"x != ""x ] && die 50 "Invalid parameter found:\"${ACTION_PARAMETER2}\""
    WriteConfigFile "${ACTION_PARAMETER}"
    ;;
          
    "list" ) 

    [ "${ACTION_PARAMETER}"x != ""x ] && die 50 "Invalid parameter found: \"${ACTION_PARAMETER} ${ACTION_PARAMETER2}\""

    GetListOfKnownXenConfigs DOMAIN_LIST

    if [ "${OUTPUT_FILE}"x != ""x ] ; then
      BackupFileIfNecessary "${OUTPUT_FILE}"
      LogMsg "Saving the list of known domains in the file \"${OUTPUT_FILE}\" ..."
      echo "${DOMAIN_LIST}" >"${OUTPUT_FILE}"
    else
      LogMsg "Known domains are"
      echo "${DOMAIN_LIST}" 
    fi   
    ;;

    "check" )
# check if we know the Xen domain
#
    DOMAINS_TO_CHECK=" ${ACTION_PARAMETER} ${ACTION_PARAMETER2}"

    for XEN_CONFIG in ${DOMAINS_TO_CHECK} ; do
      LogMsg "*** Checking the Xen domain \"${XEN_CONFIG}\" ..."
      XenDomainConfigExists "${XEN_CONFIG}"
      [ $? -ne 0 ] && die 10 "The Xen domain \"${XEN_CONFIG}\" is not known by this script"

     eval XEN_CONFIG_TITLE="\${${XEN_CONFIG}_TITLE}"

     LogMsg "The Xen domain to process is \"${XEN_CONFIG_TITLE}\" "

# set the configuration for this Xen domain
#
      SetXenDomainConfig "${XEN_CONFIG}"

# now process the parameter
#    
      SetXenDomainConfig_from_Parameter

# and last use defaults for all not set values
#  
      SetXenDomainConfig_from_Defaults
    
# now check the environment
#
      CONFIG_MSGS=$( CheckXenDomainConfig "${XEN_CONFIG}" )
      if  [ $? -ne ${__TRUE} ] ; then
        LogError "Errors in the configuration found: 
${CONFIG_MSGS}" 
        __MAINRC=5 
	LogError "One or more errors detected for the domain \"${XEN_CONFIG}\" "
      else

        LogMsg "The configuration of the Xen domain \"${XEN_CONFIG}\" is okay:
${CONFIG_MSGS}" 
              
      fi
    done


    ;;


    "status" )

    typeset -L20 PRINT_NAME="Xen Domain"
    typeset -L10 PRINT_STATUS="Running?"
    typeset -L10 PRINT_CONSOLE_STATUS="Console?"
    typeset -L20 PRINT_VNCVIEWER_STATUS="VNC Viewer?"
    typeset -L40 PRINT_ERROR_MSG=""
    
    LogMsg "-" "${PRINT_NAME}${PRINT_STATUS}${PRINT_CONSOLE_STATUS}${PRINT_VNCVIEWER_STATUS}"

    if [ "${ACTION_PARAMETER}"x != ""x ] ; then
      typeset -u DOMAIN_LIST="${ACTION_PARAMETER} ${ACTION_PARAMETER2}"
    else      
      GetListOfKnownXenConfigs DOMAIN_LIST
    fi
    
    for XENDOMAIN in ${DOMAIN_LIST} ; do
       XenDomainConfigExists "${XENDOMAIN}"
       if [ $? = ${__TRUE} ] ; then
         DOMAIN_STATUS="no"
         CONSOLE_STATUS="no"
	 VNCVIEWER_STATUS="no"

         LogInfo "Checking the Xen domain \"${XENDOMAIN}\""

         SetXenDomainConfig "${XENDOMAIN}"
	 SetXenDomainConfig_from_Defaults

         LogInfo "The config file is \"${CUR_XEN_DOMAIN_CONFIG_FILE}\""
         get_domain_id "${CUR_XEN_DOMAIN_CONFIG_FILE}"
	 LogInfo "The domain id is \"${XEN_DOMAIN_ID}\" "

	 
	 get_status_of_xen_domain "${XEN_DOMAIN_ID}"
	 if [ $? = ${__TRUE} ] ; then
	   DOMAIN_STATUS="yes"

  	   get_domain_num_id "${XEN_DOMAIN_ID}"
	   LogInfo "The domain numid is \"${XEN_DOMAIN_NUM_ID}\" "
	 
	   is_console_attached "${XEN_DOMAIN_NUM_ID}"
     	   [ $? = ${__TRUE} ] && CONSOLE_STATUS="yes"

           is_vncviewer_attached ${CUR_IP_ADDRESS} ${VNCVIEWER_PORT}
	   case $? in 
	     0 ) VNCVIEWER_STATUS="yes" ;;
	     1 ) VNCVIEWER_STATUS="(no, port in use)" ;;
	     * ) VNCVIEWER_STATUS="no" ;;
	   esac
        fi

        PRINT_NAME="${XENDOMAIN}"
	PRINT_STATUS="${DOMAIN_STATUS}"
	PRINT_CONSOLE_STATUS="${CONSOLE_STATUS}"
	PRINT_VNCVIEWER_STATUS="${VNCVIEWER_STATUS}"
        LogMsg "-" "${PRINT_NAME}${PRINT_STATUS}${PRINT_CONSOLE_STATUS}${PRINT_VNCVIEWER_STATUS}"

      else
         PRINT_NAME="${XENDOMAIN}"
	 PRINT_ERROR_MSG="- error in domain configuration"
         LogMsg "-" "${PRINT_NAME}${PRINT_ERROR_MSG}"
      fi
    done
    ;;
             

    "start" )


# check the Xen domain name
#
    if [ "${XEN_CONFIG}"x = "XEN"x -o "${XEN_CONFIG}"x = "DEFAULT"x ] ; then
      die 50 "\"XEN\" and \"DEFAULT\" are NOT allowed as Xen domain names"
    fi

# check if we know the Xen domain
#
    XenDomainConfigExists "${XEN_CONFIG}"
    [ $? -ne 0 ] && die 10 "The Xen domain \"${XEN_CONFIG}\" is not known by this script"

    eval XEN_CONFIG_TITLE="\${${XEN_CONFIG}_TITLE}"

    LogMsg "The Xen domain to process is \"${XEN_CONFIG_TITLE}\" "


# set the configuration for this Xen domain
#
    SetXenDomainConfig "${XEN_CONFIG}"

# now process the parameter
#    
    SetXenDomainConfig_from_Parameter

# and last use defaults for all not set values
#  
    SetXenDomainConfig_from_Defaults
  

# now check the environment
#
    CONFIG_MSGS=$( CheckXenDomainConfig "${XEN_CONFIG}" )
    if  [ $? -ne ${__TRUE} ] ; then
      LogError "Errors in the configuration found: 
${CONFIG_MSGS}" 
      die 5 "One or more errors detected"
    else
      LogInfo "The Xen domain configuration is okay:
${CONFIG_MSGS}"       
    fi

    CONFIG_MSGS=$( CheckXenDomainConfigForStarting "${XEN_CONFIG}" )
    if  [ $? -ne ${__TRUE} ] ; then
      LogError "Errors in the configuration found: 
${CONFIG_MSGS}" 
      die 5 "One or more errors detected"
    else
      LogInfo "The Xen configuration is okay:
${CONFIG_MSGS}"       
    fi

    for CURVAR in $( set | grep "^CUR_" | cut -f1 -d "=" ) ; do
      eval "LogInfo ${CURVAR} is : \"\$${CURVAR}\""
    done    

    LogInfo "Using the Xen domain config file \"${CUR_XEN_DOMAIN_CONFIG_FILE}\" ..."

    get_domain_id "${CUR_XEN_DOMAIN_CONFIG_FILE}"

# read the name from the domain config file
#
    [ "${XEN_DOMAIN_ID}"x = ""x ] && die 10 "Domain name not found in the Xen domain config file \"${CUR_XEN_DOMAIN_CONFIG_FILE}\""

# check if the domain is already running
#
    XEN_DOMAIN_RUNNING_MSG=$( get_status_of_xen_domain "${XEN_DOMAIN_ID}" )
    XEN_DOMAIN_RUNNING=$?

    LogInfo "XEN_DOMAIN_RUNNING is \"${XEN_DOMAIN_RUNNING}\" "  
    if [ "${XEN_DOMAIN_RUNNING}" = ${__TRUE} ] ; then

# the domain is already running
#
      get_domain_num_id "${XEN_DOMAIN_ID}"
    
# check if there is already a console attached to the Xen domain    
#
      is_console_attached "${XEN_DOMAIN_NUM_ID}"
      XEN_CONSOLE_ATTACHED=$?
    
# check if there is already a vncviewer attached to the Xen domain    
#
      is_vncviewer_attached ${CUR_IP_ADDRESS} ${VNCVIEWER_PORT}
      case $? in 

        0 ) XEN_VNCVIEWER_RUNNING=${__TRUE} 
	    ;;

	1 ) XEN_VNCVIEWER_RUNNING=2
	    ;;

        * ) XEN_VNCVIEWER_RUNNING=${__FALSE} 
	    ;;
      esac
    else
      XEN_CONSOLE_ATTACHED=${__FALSE}
      XEN_VNCVIEWER_RUNNING=${__FALSE}
    fi

    if [ ${CUR_START_XEN_DOMAIN} = ${__TRUE} ] ; then
      if [ "${XEN_DOMAIN_RUNNING}" = "${__TRUE}" ] ; then
        LogMsg "The Xen domain \"${XEN_DOMAIN_ID}\" is already running:"
        LogMsg - "${XEN_DOMAIN_RUNNING_MSG}"
      else
        start_xen_domain ${XEN_DOMAIN_ID} ${CUR_XEN_DOMAIN_CONFIG_FILE} 
        if [ $? -eq 0 ] ; then
          LogMsg "Xen domain \"${XEN_DOMAIN_ID}\" started"

          XEN_DOMAIN_RUNNING_MSG=$( get_status_of_xen_domain "${XEN_DOMAIN_ID}" "printStatus" )
          XEN_DOMAIN_RUNNING=$?
        else
          LogError "Error starting the Xen domain \"${XEN_DOMAIN_ID}\" started"
        fi
           LogMsg "-" "${XEN_DOMAIN_STARTMSG}"
      fi
    fi
  
    if [ ${CUR_START_CONSOLE_WINDOW} = ${__TRUE} ] ; then
      if [ "${XEN_DOMAIN_RUNNING}" != "${__TRUE}" ] ; then
        LogError "The Xen domain \"${XEN_DOMAIN_ID}\" is NOT running - can not attach to the console"
      else

# check if there is already a console attached to the Xen domain    
        if [ ${XEN_CONSOLE_ATTACHED} = ${__TRUE} ] ; then
          LogError "There is already a terminal attached to the console of the Xen domain \"${XEN_DOMAIN_ID}\""
        else
          attach_console_to_xen_domain ${XEN_DOMAIN_ID} "${CUR_XTERM_BINARY}" "${CUR_XTERM_PARAMETER}" "${CUR_TITLE}"
        fi
      fi
    fi
  
    if [ ${CUR_START_VNCVIEWER} = ${__TRUE} ] ; then
      if [ "${XEN_DOMAIN_RUNNING}" != "${__TRUE}" ] ; then
        die 20 "The Xen domain \"${XEN_DOMAIN_ID}\" is NOT running - can not start the vncviewer"
      else
        if [ ${XEN_VNCVIEWER_RUNNING} = 2 ] ; then
          LogWarning "No vncviewer connected to the Xen domain but the port is still in use - try again later"
        elif [ ${XEN_VNCVIEWER_RUNNING} = ${__TRUE} ] ; then
          LogError "There is already a vncviewer attached to the Xen domain \"${XEN_DOMAIN_ID}\""
        else
          attach_vncviewer_to_xen_domain ${XEN_DOMAIN_ID} \
            "${CUR_VNCVIEWER_TARGET}" "${VNCVIEWER_PORT}" \  
  	    "${CUR_VNCVIEWER_BINARY}" "${CUR_VNCVIEWER_PARAMETER}"
        fi
      fi
    fi
    ;;

    * ) die 205 "Unknown action \"${ACTION}\" " ;;
  esac
  
  die ${__MAINRC} 

exit

