#!/bin/bash

########################################################################
#
#PROJECT:      Unified Sessions Manager
#AUTHOR:       Arno-Can Uestuensoez - acue@UnifiedSessionsManager.org
#MAINTAINER:   Arno-Can Uestuensoez - acue_sf1@sourceforge.net
#SHORT:        ctys
#CALLFULLNAME: Commutate To Your Session
#LICENCE:      GPL3
#VERSION:      01_03_002a02
#
########################################################################
#
# Copyright (C) 2007 Arno-Can Uestuensoez (UnifiedSessionsManager.org)
#
########################################################################


################################################################
#                   Begin of FrameWork                         #
################################################################


#FUNCBEG###############################################################
#
#PROJECT:
MYPROJECT="Unified Sessions Manager"
#
#NAME:
#  ctys
#
#AUTHOR:
AUTHOR="Arno-Can Uestuensoez - acue@UnifiedSessionsManager.org"
#MAINTAINER:
MAINTAINER="Arno-Can Uestuensoez - acue_sf1@sourceforge.net"
#
#FULLNAME:
FULLNAME="Unified Sessions Manager"
#
#CALLFULLNAME:
CALLFULLNAME="Commutate To Your Session"
#
#LICENCE:
LICENCE=GPL3
#
#TYPE:
#  bash-script
#
#VERSION:
VERSION=01_03_003a01
#DESCRIPTION:
#  Main untility of project ctys for manging sessions.
#
#EXAMPLE:
#
#PARAMETERS:
#  Use '-h' for initial help.
#
#OUTPUT:
#  RETURN:
#  VALUES:
#
#FUNCEND###############################################################

################################################################
#                     Global shell options.                    #
################################################################
shopt -s nullglob



################################################################
#       System definitions - do not change these!              #
################################################################
#Execution anchor
MYHOST=`uname -n`
MYCALLPATHNAME=$0
MYCALLNAME=`basename $MYCALLPATHNAME`

if [ -n "${MYCALLPATHNAME##/*}" ];then
    MYCALLPATHNAME=${PWD}/${MYCALLPATHNAME}
fi
MYCALLPATH=`dirname $MYCALLPATHNAME`
###################################################
#load basic library required for bootstrap        #
###################################################
MYBOOTSTRAP=${MYCALLPATH}/bootstrap
if [ ! -d "${MYBOOTSTRAP}" ];then
  echo "${MYCALLNAME}:$LINENO:ERROR:Missing:MYBOOTSTRAP=${MYBOOTSTRAP}"
cat <<EOF  

DESCRIPTION:
  This directory contains the common mandatory bootstrap functions.
  Your installation my be erroneous.  

SOLUTION-PROPOSAL:
  First of all check your installation, because an error at this level
  might - for no reason - bypass the final tests.

  If this does not help please send a bug-report.

EOF
  exit 1
fi

MYBOOTSTRAP=${MYBOOTSTRAP}/bootstrap.01.01.001
if [ ! -f "${MYBOOTSTRAP}" ];then
  echo "${MYCALLNAME}:$LINENO:ERROR:Missing:MYBOOTSTRAP=${MYBOOTSTRAP}"
cat <<EOF  

DESCRIPTION:
  This file contains the common mandatory bootstrap functions required
  for start-up of any shell-script within this package.

  It seems though your installation is erroneous or you detected a bug.  

SOLUTION-PROPOSAL:
  First of all check your installation, because an error at this level
  might - for no reason - bypass the final tests.

  When your installation seems to be OK, you may try to set a TEMPORARY
  symbolic link to one of the files named as "bootstrap.<highest-version>".
  
    ln -s ${MYBOOTSTRAP} bootstrap.<highest-version>

  in order to continue for now. 

  Be aware, that any installation containing the required file will replace
  the symbolic link, because as convention the common boostrap files are
  never symbolic links, thus only recognized as a temporary workaround to 
  be corrected soon.

  If this does not work you could try one of the other versions.

  Please send a bug-report.

EOF
  exit 1
fi

###################################################
#Start bootstrap now                              #
###################################################
. ${MYBOOTSTRAP}
###################################################
#OK - utilities to find components of this version#
#available now.                                   #
###################################################

#
#set real path to install, resolv symbolic links
_MYCALLPATHNAME=`bootstrapGetRealPathname ${MYCALLPATHNAME}`
MYCALLPATH=`dirname ${_MYCALLPATHNAME}`
#
###################################################
#Now find libraries might perform reliable.       #
###################################################


#current language, not really NLS
MYLANG=${MYLANG:-en}

#path for various loads: libs, help, macros, plugins
MYLIBPATH=${CTYS_LIBPATH:-`dirname $MYCALLPATH`}

#path for various loads: libs, help, macros, plugins
MYHELPPATH=${MYLIBPATH}/help/${MYLANG}


###################################################
#Check master hook                                #
###################################################
bootstrapCheckInitialPath
###################################################
#OK - Now should work.                            #
###################################################

MYCONFPATH=${MYLIBPATH}/conf/ctys
if [ ! -d "${MYCONFPATH}" ];then
  echo "${MYCALLNAME}:$LINENO:ERROR:Missing:MYCONFPATH=${MYCONFPATH}"
  exit 1
fi

if [ -f "${MYCONFPATH}/versinfo.conf" ];then
    . ${MYCONFPATH}/versinfo.conf
fi

MYMACROPATH=${MYCONFPATH}/macros
if [ ! -d "${MYMACROPATH}" ];then
  echo "${MYCALLNAME}:$LINENO:ERROR:Missing:MYMACROPATH=${MYMACROPATH}"
  exit 1
fi

MYPKGPATH=${MYLIBPATH}/plugins
if [ ! -d "${MYPKGPATH}" ];then
  echo "${MYCALLNAME}:$LINENO:ERROR:Missing:MYPKGPATH=${MYPKGPATH}"
  exit 1
fi

MYINSTALLPATH= #Value is assigned in base. Symbolic links are replaced by target


##############################################
#load basic library required for bootstrap   #
##############################################
. ${MYLIBPATH}/lib/base
. ${MYLIBPATH}/lib/libManager
#
#Germish: "Was the egg or the chicken first?"
#
#..and prevent real load order for later display.
#
bootstrapRegisterLib
baseRegisterLib
libManagerRegisterLib
##############################################
#Now the environment is armed, so let's go.  #
##############################################

if [ ! -d "${MYINSTALLPATH}" ];then
    ABORT=1;
    printERR $LINENO $BASH_SOURCE ${ABORT} "Missing:MYINSTALLPATH=${MYINSTALLPATH}"
    gotoHell ${ABORT}
fi

MYOPTSFILES=${MYOPTSFILES:-$MYLIBPATH/help/$MYLANG/085_base_options} 
checkFileListElements "${MYOPTSFILES}"
if [ $? -ne 0 ];then
    ABORT=1;
    printERR $LINENO $BASH_SOURCE ${ABORT} "Missing:MYOPTSFILES=${MYOPTSFILES}"
    gotoHell ${ABORT}
fi

################################################################
#                     End of FrameWork                         #
################################################################


#path to directory containing the default mapping db
if [ ! -d "${HOME}/.ctys/db/default" ];then
  echo "${MYCALLNAME}:$LINENO:ERROR:Missing standard directory:$MYCONFPATH/groups"
  echo "${MYCALLNAME}:$LINENO:ERROR:Has to be present at least, check your installation"
  exit 1

fi
DEFAULT_DBPATHLST=${DEFAULT_DBPATHLST:-$HOME/.ctys/db/default}

#path to directory containing the default mapping db
if [ -d "${MYCONFPATH}/db/default" ];then
    DEFAULT_DBPATHLST=${DEFAULT_DBPATHLST:-$MYCONFPATH/db/default}
fi


#Source pre-set environment from user
if [ -f "${HOME}/.ctys/ctys.conf" ];then
  . "${HOME}/.ctys/ctys.conf"
fi

#Source pre-set environment from installation 
if [ -f "${MYCONFPATH}/ctys.conf" ];then
  . "${MYCONFPATH}/ctys.conf"
fi

#system tools
if [ -f "${HOME}/.ctys/systools.conf" ];then
    . "${HOME}/.ctys/systools.conf"
else

    if [ -f "${MYCONFPATH}/conf/ctys/systools.conf" ];then
	. "${MYCONFPATH}/conf/ctys/systools.conf"
    else
	if [ -f "${MYCALLPATH}/../conf/ctys/systools.conf" ];then
	    . "${MYCALLPATH}/../conf/ctys/systools.conf"
	else
	    ABORT=1;
	    printERR $LINENO $BASH_SOURCE ${ABORT} "Missing system tools configuration file:\"systools.conf\""
	    printERR $LINENO $BASH_SOURCE ${ABORT} "Check your installation."
	    gotoHell ${ABORT}
	fi
    fi
fi

################################################################
#    Default definitions - User-Customizable  from shell       #
################################################################

###################
#generic
DEFAULT_CTRL_SESSIONTYPE=${DEFAULT_CTRL_SESSIONTYPE:-VNC}
DEFAULT_CTRL_SCOPE=${DEFAULT_CTRL_SCOPE:-USER}
DEFAULT_KILL_DELAY_POWEROFF=${DEFAULT_KILL_DELAY_POWEROFF:-20}
DEFAULT_LIST_CONTENT=${DEFAULT_LIST_CONTENT:-ALL,FULLPATH,BOTH}


###################
#CREATE

###################
#LIST
DEFAULT_CTRL_MODE_ARGS_LIST=${DEFAULT_CTRL_MODE_ARGS_LIST:-"label,id,user,group,pid"}
#DEFAULT_LIST_CTRL_SCOPE="USRLST"
#DEFAULT_LIST_CTRL_SCOPE_ARGS="all"

###################
#ENUMERATE
DEFAULT_CTRL_MODE_ARGS_ENUMERATE=${DEFAULT_CTRL_MODE_ARGS_ENUMERATE:-'.'}

###################
#CREATE
DEFAULT_CTRL_MODE_ARGS=${DEFAULT_CTRL_MODE_ARGS_CREATE:-'1,DEFAULT,REUSE'}



################################################################
#Globalized convenience settings for Basic-Community-Packages  #
################################################################

#Common: Defines the timeout an established port-forwarding tunnel by 
#OpenSSH.
#Should wait for it's first and only one (just an wannabee oneshot - within
#the period any number of connects are possible) connection. This is choosen,
#because because now no precautions have to be and are not implemented for
#cancellation of no longer required tunnels. So you might no set a high value,
#just smallerr than a minute.
#Existing ports are not reused anyway, because the next tunnel-request
#increments the highest present for a new tunnel.
#
#APPLY:Increment when clients do not connect with ConnectionForwarding.
SSH_ONESHOT_TIMEOUT=${SSH_ONESHOT_TIMEOUT:-20}


#Common: Defines the timeout to delay the start of a client after server
#
#APPLY:Increment this value when clients do not connect.
R_CLIENT_DELAY=${R_CLIENT_DELAY:-2}

#Common: Defines the timeout after all XClients of one desktop are 
#started. Due to problems with reliability a shift of distinguished 
#windows seems not to work(at least in my environment on CentOS-5.0/Gnome).
#So current desktop is switched for default pop-up on target desktop
#which could take some time until the window actually is displayed.
#When the desktop is meanwhile switched the window will be positioned 
#on the current if not yet displayed.
#Depends on actual base, it seems that at least 5seconds are required,
#for safety 8 seconds are choosen.
#
#APPLY:Increment this value when clients pop-up on wrong desktop.
X_DESKTOPSWITCH_DELAY=${X_DESKTOPSWITCH_DELAY:-8}



################################################################
#Basic-Package Settings: VNC
#
#General remarks: 
# The geometry parameter will be reset - for server too - when selected
# at the CLI by "-g" option. So the value here is just a default, when no 
# call parameter is supported.
#

#Bulk: Defines the timeout to wait between bulk creation of sessions 
R_CREATE_TIMEOUT=${R_CREATE_TIMEOUT:-5}


#Bulk: Defines the maximum allowed number of sessions to be created by a bulk call.
#ATTENTION:Mistakenly using e.g. 1000 will probably force you to reboot your machines!!!!
#A call of "ctys -a cancel=all poorHost" might help?!
#
#APPLY:Increment this when more VNC-bulk sessions on a node are required.
R_CREATE_MAX=${R_CREATE_MAX:-20}


#######wrapper for vncviewer
export VNCVIEWER=${VNCVIEWER:-$MYCALLPATH/ctys-callVncviewer}
#viewer default parameters
#keep "hextile" for being generic for VMware-WS6 too(see pg. 183).
export VNCVIEWER_OPT=${VNCVIEWER_OPT:-"-AutoSelect=0 -PreferredEncoding hextile -FullColour"}
#ffs.:"copyrect"

#######wrapper for vncserver
export VNCSERVER=${VNCSERVER:-$MYCALLPATH/ctys-callVncserver}
#server default parameters
export VNCSERVER_OPT=${VNCSERVER_OPT:-"-depth 24 -geometry 1280x1024 -nohttpd -localhost -nolisten tcp "}



################################################################
#Basic-Package Settings: XEN
#ffs.



################################################################
#      Internal control flow - do not change these!            #
################################################################
CTRL_SESSIONTYPE=DEFAULT
PACKAGES_KNOWNTYPES=

unset CTRL_XTOOLKITOPTS;

unset CTRL_SESSIONID;
unset CTRL_SESSIONIDARGS;
unset CTRL_SESSIONFLAG;
CTRL_MODE=CREATE
#unset CTRL_MODE_ARGS
#CTRL_MODE_ARGS="1,DEFAULT,REUSE"
CTRL_MODE_ARGS=DEFAULT
CTRL_SCOPE=DEFAULT
unset CTRL_SCOPE_ARGS
unset CTRL_SCOPE_CONCAT
CTRL_SSH=1;
unset CTRL_SSH_PSEUDOTTY;
unset CTRL_EXECLOCAL;
unset CTRL_NOEXEC;
unset CTRL_LISTSES;
unset CTRL_TERSE;
CTRL_PRINTINFO=0;
CTRL_ASYNC=DEFAULT;

unset CTRL_WMCTRL_DESK
unset CTRL_MDESK;
 
unset CTRL_GEOMETRY;
unset CTRL_REMOTERESOLUTION;
unset CTRL_FORCE;
unset CTRL_ALLOWAMBIGIOUS;
#CTRL_WARNING=1;

unset R_HOSTS;
unset R_OPTS;
export R_OPTS="";
#unset R_TEXT;
unset X_OPTS;


#to be used for cache of all tools, if not set else
export DBPATHLST=${DBPATHLST:-$DEFAULT_DBPATHLST}


#Options for formatting text with "pr" when printing out the embedded help.
PR_OPTS=${PR_OPTS:--o 5 -l 76}

#Using this as a ready to use option, some lengthy keywords for now,
#but recognition has priority over string replace-functions!
CTRL_CLIENTLOCATION=${CTRL_CLIENTLOCATION:-"-L DisplayForwarding"};


#Base for remapping of local client access ports for ConnectionForwarding
LOCAL_PORTREMAP=${LOCAL_PORTREMAP:-5950}

#Is defined to be used when set, so it is foreseen as test-path for remote call
#R_PATH

#Is defined to be used when set, so it is foreseen as test-path for local call
#L_PATH


#assure for append...
if [ -n "$CTYS_GROUPS_PATH" ];then
    mstr=$HOME/.ctys/groups
    CTYS_GROUPS_PATH=${CTYS_GROUPS_PATH//$mstr}
    mstr=$MYCONFPATH/groups
    CTYS_GROUPS_PATH=${CTYS_GROUPS_PATH//$mstr}
fi

if [ -n "$CTYS_GROUPS_PATH" ];then
    checkPathElements CTYS_GROUPS_PATH ${CTYS_GROUPS_PATH}
fi

if [ ! -d "${HOME}/.ctys/groups" ];then
    ABORT=1;
    printERR $LINENO $BASH_SOURCE ${ABORT} "Missing standard directory:${HOME}/.ctys/groups"
    printERR $LINENO $BASH_SOURCE ${ABORT} "Has to be present at least, check your installation"
    gotoHell ${ABORT}
fi

if [ ! -d "${MYCONFPATH}/groups" ];then
    ABORT=1;
    printERR $LINENO $BASH_SOURCE ${ABORT} "Missing standard directory:${MYCONFPATH}/groups"
    printERR $LINENO $BASH_SOURCE ${ABORT} "Has to be present at least, check your installation"
    gotoHell ${ABORT}
fi

CTYS_GROUPS_PATH="${HOME}/.ctys/groups:${MYCONFPATH}/groups${CTYS_GROUPS_PATH:+:$CTYS_GROUPS_PATH}"




################################################################
#                    Initial call trace                        #
################################################################
printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE ""
printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE "-----------------------------------------------------------------------------"
printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE "TRACE:CALL-PARAMS:"
printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE "<${0} ${*}>"
printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE "-----------------------------------------------------------------------------"
printVerboseDebug ${DBG_LVL_MAINT} $LINENO $BASH_SOURCE "TRACE:ENV-PARAMS:"
printVerboseDebug ${DBG_LVL_MAINT} $LINENO $BASH_SOURCE "<PATH=${PATH}>"
printVerboseDebug ${DBG_LVL_MAINT} $LINENO $BASH_SOURCE "<LD_PLUGIN_PATH=${LD_PLUGIN_PATH}>"
printVerboseDebug ${DBG_LVL_MAINT} $LINENO $BASH_SOURCE "<RS_PREFIX_L=${RS_PREFIX_L}>"
printVerboseDebug ${DBG_LVL_MAINT} $LINENO $BASH_SOURCE "<RS_PREFIX_R=${RS_PREFIX_R}>"
printVerboseDebug ${DBG_LVL_MAINT} $LINENO $BASH_SOURCE "-----------------------------------------------------------------------------"
printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE ""




#################################################################################
#load libraries and plugins                                                     #
#################################################################################
#
#Remark: The online help is loaded only when requested by user.
#        The runtime modules are loaded "by-startup-scan" not on demand.
#
#        - BASE-libs and CORE-plugins with related help:
#          are loaded - due to beeing prerequisite - as hardcoded entities.
#          Related help is loaded when requested, but on-demand as said.
#
#        - ADD-ON-PACKAGES
#          Loaded "by-startup-scan".
#
#        - ADD-ON-MACROS
#          CONFIG-MACROS: Loaded as given by User-Option.
#

#########################################################################
#libraries - generic functions                                          #
#########################################################################

#These will be hardcoded and just sourced, but are completely unmanaged.
. ${MYLIBPATH}/lib/cli/cli
. ${MYLIBPATH}/lib/misc
. ${MYLIBPATH}/lib/security
. ${MYLIBPATH}/lib/help/help
. ${MYLIBPATH}/lib/geometry/geometry
. ${MYLIBPATH}/lib/wmctrlEncapsulation
. ${MYLIBPATH}/lib/groups



#########################################################################
#plugins - project specific commons and feature plugins                 #
#########################################################################


#These will be loaded in given path-order, units within the given
#directories are loaded in alphabetical order.
#There is one hard-coded exception for the CORE directory:

#
#CORE:
#
#  Units within CORE are just loaded and registered, but will not
#  be called for generic initialization. This is due to the design,
#  that core modules are hardcoded project specific libraries 
#  handeled as building blocks. 
#
PLUGINPATHS=${MYINSTALLPATH}/plugins/CORE

#
#GENERIC:
#
#  Units within GENERIC perform common tasks which span multiple plugins, but 
#  are frequently tied together. One example is the call of LIST, where normally 
#  all selected - as default ALL enabled - types will be listed and displayed in 
#  a unified manner.
#  Thus these calls are not scheduled as own jobs, but as calls/callbacks from
#  a generic dispatcher executed as remote controller.
#
PLUGINPATHS=${MYINSTALLPATH}/plugins/GENERIC

#
#HOSTs+VMs+GUESTs:
#
#  Whereas the remaining are seen as dynamic attached hooks representing
#  pluggable add-ons.
#
PLUGINPATHS=${PLUGINPATHS}:${MYINSTALLPATH}/plugins/HOSTs
PLUGINPATHS=${PLUGINPATHS}:${MYINSTALLPATH}/plugins/VMs
PLUGINPATHS=${PLUGINPATHS}:${MYINSTALLPATH}/plugins/PMs
PLUGINPATHS=${PLUGINPATHS}:${MYINSTALLPATH}/plugins/GUESTs

#
#The environment variable LD_PLUGIN_PATH is similiar to LD_LIBRARY_PATH,
#loading bash plugins.
#
LD_PLUGIN_PATH=${LD_PLUGIN_PATH}:${PLUGINPATHS}



#
#Pre-fetch, whether checks for compatibility should be restrictive and terminating
#or more in a relay-manner, not ultimately due to various versions, configurations
#and installed components.
#
_t=`echo " $* "| sed -n '/ -e /p'`
if [ -n "${_t}" ];then
    CTRL_EXECLOCAL=1;
    printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE "$FUNCNAME:CTRL_EXECLOCAL"
fi

#
#  This function analyses an ARGV for occurance of "-t" option, which 
#  is the type of session to be handeled. If not found the pre-set
#  default will be assumed.
#
#  Once the decision is made, the appropriate module will be loaded
#  by source-ing. Therefore the Name of the plugin will be returned to be 
#  "sourced" in global namespace.
#
#  The former approach of automatic sourcing all available modules during
#  startup will still be possible, when setting the environment variable
#  "CTYS_MULTITYPE". This is more flexible due to possibility of combined
#  and intermixed calls, but requires some "stripping" of the sources to
#  reduce resource requirements when loading multiple plugins. 
#
#  CTYS_MULTITYPE may contain ALL or a ":"/colon separated list with
#  plugins to be loaded.
#
#  However, the next version is planned to be reworked or written in Perl.
#  A scripting language at all seems to be most appropriate to this task.
#
_t=`echo " $* "| sed -n 's/(.*)//g;s/^.* -T/-T/;s/-T \([a-zA-Z0-9,]*[^ ]\).*$/\1/p'`
if [ -n "${_t}" ];then
    CTYS_MULTITYPE=`echo "${_t}"|tr '[:lower:]' '[:upper:]'`
    printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE "$FUNCNAME:CTYS_MULTITYPE=$CTYS_MULTITYPE"
fi
if [ -z "${CTYS_MULTITYPE}" ];then
    _t=`echo " $* "| sed -n 's/^.* -t/-t/;s/-t \([a-zA-Z0-9]*\) .*$/\1/p'`
    if [ -n "${_t}" ];then
	CTRL_SESSIONTYPE=`echo "${_t}"|tr '[:lower:]' '[:upper:]'`
	CTYS_MULTITYPE=${CTRL_SESSIONTYPE}
    else
	_t=`echo " $* "| sed -n 's/^.* -a/-a/;s/-a \([a-zA-Z0-9]*\)[= ].*$/\1/p'`
	case $_t in
	    LIST|ENUMERATE|SHOW|INFO)CTYS_MULTITYPE=ALL;;
	esac
    fi
    printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE "$FUNCNAME:CTRL_SESSIONTYPE=$CTRL_SESSIONTYPE"
fi



#
#Perform the initialization according and based on LD_PLUGIN_PATH.
#
initPackages



#Make functions available 
#acue:4testAndDebugOnly:export -f `typeset -F|awk '{print $3}'`


#################################################################################
#prepare execution                                                              #
#################################################################################

#The special case of handling local call without a execution-target.
#Exception is given, when "-l" option is present, than the 
#"missing execution-target" is virtually handeled as a seperate target,
#requiring explicit context options.
if [ "${*//-l/}" == "${*}" ];then
    orgArgs=$*
    printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE "$FUNCNAME:orgArgs=$orgArgs"
fi


#Therefore global arguments are superposed by more specific arguments in the 
#following order. The priotrity is as common given to:
#
# - For 1.:     first-wins => Environment could customize
# - Remaining:  last-wins  => Present Call-Options predominate
#
# 1. defaults - hardcoded or inherited from calling shell
# 2. global CLI options for client and server
# 3. globals call-option for call-target "... -- '(<remote-global>)'...":
#     - server
#     - client if executed remotely on server site (Display Forwarding)
# 4. target specific context-options of call:
#      "... -- '(<remote-global>)' <taget>'(<context-options>)'"
#
#=>Resulting in actual call options.
#
#...could be perfect, of course.
#
#fetch global options for all given nodes
fetchOptions LOCAL $@


#now do the remaining part manually
shift $(( OPTIND - 1))

#
#now the remote part =>
#

# After the "--" the first entry is global remote parameter for all
# remote sessions, when no hostname-prefix exists. This could be varied
# by host specific options.
#
# Example:
#
#   The following example shows three hosts, where each has a different 
#   debugging level.
#
#   First of all the debugging flag and level is not forward propagated,
#   and as common for all environment settings "the last wins".
#
#     "...-d 6 -- ( -d 3 ) host01 host02( -d 1) host02(-d 0)..."
#
#   So, the given scenario results in the following situation:
#
#     -> localhost:   -d 6          = -d 6
#     -> host01:      -d 3          = -d 3
#     -> host02:      -d 3 -> -d 1  = -d 1
#     -> host03:      -d 3 -> -d 0  = -d 0
#
#
printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE "$FUNCNAME:remaining for fetchArguments:\$*=\"$*\""
if [ -n "$*" ];then
    fetchArguments $@
else
    if [ -n "${orgArgs}" ];then
	remain="`cliOptionsStrip KEEP '-d' -- ${orgArgs}`"
	if [ -n "${remain}" ];then
	    remain="(${remain})"
	fi
    fi
    fetchArguments "${remain}"
fi

printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE "$FUNCNAME:Finalize execCalls"
#################################################################################
#Check whether remote execution requested                                       #
#################################################################################
if [ -z "${ABORT}" -a -z "${CTRL_EXECLOCAL}" ];then
  #Prepare call array, by performing options-expansion/permutation/correlation, 
  #call grouping, and call ordering, and last but not least 
  #apply consistency checks.
  #
  buildExecCalls
fi

printVerboseDebug ${DBG_LVL_UID} $LINENO $BASH_SOURCE "$FUNCNAME:Process execCalls"

#################################################################################
#End of prerequisite-checks...                                                  #
#...commit for execution                                                        #
#################################################################################
if [ -n "${ABORT}" ]; then
  gotoHell ${ABORT}
fi


#################################################################################
#execute call...                                                                #
#  ...handle calls from prepared array as resulting form buildExecCalls         #
#    ...on individual entities                                                  #
#      ...based on user+host                                                    #
#        ...by local and/or remote execution.                                   #
#################################################################################
doExecCalls


#################################################################################
#End of commutation...                                                          #
#...beeing here seems to be a successful task was done.                         #
#################################################################################
gotoHell 0 
