#!/bin/sh
# @(#) rcfunctions Linux - B.08.40 ($Revision: 29.5 $)
# Eloquence common startup/shutdown functions
#
# (C) Copyright Marxmeier Software AG, 2002-2024
#
# This file is installed as /opt/eloquence/8.4/etc/rcfunctions
# It is sourced by the eloquence startup/shutdown script
#

### default ###

# debug logging
eq_debug=0

# Binaries
ELOQUENCE=${ELOQUENCE:=/opt/eloquence/8.4}
ELOQSD=${ELOQUENCE}/bin/eloqsd
ELOQDB=${ELOQUENCE}/bin/eloqdb
ELOQWEBD2=${ELOQUENCE}/bin/eloqwebd2
ELOQLD=${ELOQUENCE}/bin/eloqld

# start eloquence by default
START_ELOQ=1

# require root for startup/shutdown
START_STOP_AS_ROOT=0

# default eloqsd mode
START_ELOQSD=0
ELOQSD_ARGS=""

# default eloqdb mode
START_ELOQDB=0
ELOQDB_DEFAULT_ARGS=""

# default eloqwebd2 mode
START_ELOQWEBD2=0
ELOQWEBD2_ARGS=""

# default eloqld mode
START_ELOQLD=0
ELOQLD_ARGS=""

# default eloqdb instance
ELOQDB_CFG[0]="eloqdb.cfg"

# location of pid files
pid_dir=/var/opt/eloquence/8.4/run

# progress messages default to a nop
eq_act_msg1=eq_nop
eq_act_msg2=eq_nop
eq_stat_msg1=eq_nop
eq_stat_msg2=eq_nop
eq_warn_msg=eq_nop

# status codes (as defined by LSB)
eq_rc_ok=0
eq_rc_failed=1
eq_rc_badarg=2
eq_rc_notimplemented=3
eq_rc_perm=4
eq_rc_notinstalled=5
eq_rc_notconfigured=6
eq_rc_notrunning=7

# status codes for status option (as defined by LSB)
eq_stat_ok=0
eq_stat_deadpid=1
eq_stat_varlock=2
eq_stat_stopped=3
eq_stat_unknown=4

# Some old Linux ps binaries use BSD style, allow to redefine behavior
eq_checkproc=eq__checkproc
eq_child_procs=eq__child_procs


### functions ###

typeset -i eq_rval=0
eq_rmsg=""

# add log message

function eq_log_msg
{
   test -n "$1" && eq_rmsg="$eq_rmsg\n$*"
}

# do nothing

function eq_nop
{
   :
}

# add debug message

function eq_debug_msg
{
   [ ${eq_debug:-0} -gt 1 ] && eq_rmsg="$eq_rmsg\ndebug: $*"
}

# start process

function eq_run
{
   typeset _cmd _msg _rc

   _cmd=$1

   if [ ${eq_debug:-0} -gt 1 ]; then
      eq_rmsg="$eq_rmsg\n>> $_cmd"
      _rc=0
   elif [ ${eq_debug:-0} -gt 0 ]; then
      eq_rmsg="$eq_rmsg\n>> $_cmd"
      _msg=$($_cmd 2>&1)
      _rc=$?
      [ $_rc -ne 0 ] && {
         eq_rval=1
         eq_log_msg "Failed: $_rc"
      }
      eq_log_msg "$_msg"
   else
      _msg=$($_cmd 2>&1)
      _rc=$?
      [ $_rc -ne 0 ] && {
         eq_rval=1
         eq_log_msg ">> $_cmd\nFailed: $_rc"
      }
      eq_log_msg "$_msg"
   fi
   return $_rc
}

# eq_instance_filter()
# check if current instance should be considered
# usage: eq_instance_filter instance

function eq_instance_filter
{
   typeset _id

# empty argument
   test -n "$eq_arg_list" || return 0

   _id=$1
   for arg_id in $eq_arg_list
   do
      if [ "$_id" = $arg_id ]; then
         break;
      fi
   done
   test "$_id" = $arg_id || return 1
   eq_accepted_args="$_id $eq_accepted_args"
   return 0
}

# iterate defined eloqdb instances

function eq_foreach
{
   typeset fn inst_id inst_cfg_file inst_start 
   typeset inst_service inst_args inst_runpfx inst_eloqdb
   typeset -i i inst_cnt

   fn=$1

   inst_cnt=${#ELOQDB_CFG[*]}
   eq_debug_msg "# inst_cnt = $inst_cnt"

   i=0
   while [ $inst_cnt -gt 0 ]
   do
      # config file

      inst_cfg_file=${ELOQDB_CFG[i]:-NOTSET}
      if [ "$inst_cfg_file" = "NOTSET" ]; then
	 let i=i+1
	 continue
      fi
      eq_debug_msg "# inst_cfg_file = $inst_cfg_file"

      inst_start=${ELOQDB_START[i]:-1}
      eq_debug_msg "# inst_start = $inst_start"

      if [ "${inst_cfg_file##/*}" != "" ]; then
	 inst_cfg_file=/etc/opt/eloquence/8.4/$inst_cfg_file
      fi
      eq_debug_msg "# inst_cfg_file = $inst_cfg_file"

      if [ ! -s "$inst_cfg_file" ]; then
         eq_log_msg "Note: eloqdb[$i]: configuration file does not exist, ignored:"
         eq_log_msg $inst_cfg_file
	 let inst_cnt=inst_cnt-1 i=i+1
	 continue
      fi

      # arguments

      inst_args=${ELOQDB_ARGS[i]:-NOTSET}
      if [ "$inst_args" = "NOTSET" ]; then
	 inst_args=$ELOQDB_DEFAULT_ARGS
      fi
      eq_debug_msg "# inst_args = $inst_args"

      # service

      inst_service=${ELOQDB_SERVICE[i]:-NOTSET}
      if [ "$inst_service" = "NOTSET" ]; then
         inst_service=$(grep -i "^[ 	]*service[ 	]*=" "$inst_cfg_file" | 
                        cut -d= -f2 | cut -d/ -f1 | head -1 | tr -d ' ')
         [ -z "$inst_service" ] && inst_service="eloqdb"
      else
         inst_args="$inst_args -s $inst_service"
      fi
      eq_debug_msg "# inst_service = $inst_service"

      # instance id

      inst_id=${ELOQDB_ID[i]:-NOTSET}
      if [ "$inst_id" = "NOTSET" ]; then
	 inst_id=$inst_service
      fi
      eq_debug_msg "# inst_id = $inst_id"

      # wrapper program (eg. mem window on HP-UX)

      inst_runpfx=${ELOQDB_RUNPFX[i]:-}
      eq_debug_msg "# inst_pfx = $inst_runpfx"

      # binary

      inst_eloqdb=$(eq_find_bin eloqdb ${ELOQDB_VER[i]:-})
      eq_debug_msg "# inst_eloqdb = inst_eloqdb"
      
      # user

      inst_user="root"
      [ $START_STOP_AS_ROOT = 0 ] && eq_is_not_root && {
         inst_user=$(grep -i "^[ 	]*uid[ 	]*=" "$inst_cfg_file" | 
                     cut -d= -f2 | head -1 | tr -d ' ')
         [ -z "$inst_user" ] && inst_user="root"
         eq_debug_msg "# inst_user = $inst_user"
      }

      # callback

      if [ $eq_todo = start -o $eq_todo = restart ]; then
         if [ $inst_start -eq 0 -a -z "$eq_arg_list" ]; then
            let inst_cnt=inst_cnt-1 i=i+1
	    continue
         fi
      fi

      $fn "$inst_id" "$inst_cfg_file" "$inst_service" "$inst_args" "$inst_runpfx" "$inst_start" "$inst_user" "$inst_eloqdb"
      let inst_cnt=inst_cnt-1 i=i+1
   done
}

# check if user is not root

function eq_is_not_root
{
   typeset _uid

   _uid=$(id -u)
   test "$_uid" != 0
}

# check if user matches (or is root)

function eq_is_matching_user
{
   typeset user _uid _uid_name

   user=$1
   
   _uid=$(id -u)
   [ "$_uid" = 0 ] && return 0

   _uid_name=$(id -un)
   test "$user" = "$_uid" -o "$user" = "$_uid_name"
}

# make sure a process is terminated

function eq_verify_terminated
{
   typeset pid tmp_pid_list
   typeset -i timeout

   eq_debug_msg "# eq_verify_terminated"

   timeout=90
   while [ $timeout -gt 0 ]
   do
      let timeout=timeout-1
      tmp_pid_list=""

      for pid in $eq_pid_list
      do
         kill -0 $pid 2>/dev/null
         if [ $? -eq 0 ]; then
            eq_debug_msg "process $pid did not (yet) die"
	    tmp_pid_list="${tmp_pid_list:-} $pid"
         else
            eq_debug_msg "process $pid is gone"
         fi
      done
      
      test -z "$tmp_pid_list" && return 0
      eq_pid_list=$tmp_pid_list
      sleep 1
   done

# send USR1 signal to trigger thread status dump
   kill -USR1 $eq_pid_list 2>&1
   sleep 1

# finally, kill remaining processes
   eq_log_msg $(kill -KILL $eq_pid_list 2>&1)
   return 0
}

# check if process is running
# actual function depends on OS

function eq__checkproc
{
   typeset _cmd _pid

   _cmd=${1##*/}
   _pid=$2
   ps -p $_pid 2>/dev/null | fgrep -q $_cmd
}

function eq__child_procs
{
   typeset _pid

   _pid=$1
   ps -el | awk "{ if(\$5 == \"$_pid\") print \$4; }"
}

function eq__checkproc_bsd
{
   typeset _cmd _pid

   _cmd=${1##*/}
   _pid=$2
   ps p $_pid 2>/dev/null | fgrep -q $_cmd
}

function eq__child_procs_bsd
{
   typeset _pid

   _pid=$1
   ps alx | awk "{ if(\$4 == \"$_pid\") print \$3; }"
}

# check for extra command line args that were not processed

function eq_check_args
{
   typeset _id _ok

   eq_bad_args=""
   test -n "$eq_arg_list" || return 0

   for _id in $eq_arg_list
   do
      for _ok in $eq_accepted_args
      do
         if [ "$_id" = "$_ok" ]; then
	    break;
         fi
      done
      test "$_id" = "$_ok" || eq_bad_args="$_id $eq_bad_args"
   done

   if [ ! -z "$eq_bad_args" ]; then
      eq_log_msg "WARNING: Unknown argument(s) ignored: $eq_bad_args"
      eq_warn_msg "WARNING: Unknown argument(s) ignored: $eq_bad_args"
      [ $eq_rval = 0 ] && eq_rval=2
   fi
   test -z "$eq_bad_args"
}

# read pid from file and verify its sane
# otherwise a user could trick root

function eq_get_pid
{
   typeset _pid_file _pid
   
   _pid_file="$*"
   _pid=$(head -n1 "$_pid_file" 2>/dev/null | sed -ne '/^[0-9]*$/p')
   [ "$_pid" -gt 1 ] && echo "$_pid"
}

# find EQ binary
# user may override entire path, version or binary

function eq_find_bin
{
   typeset _def _ver
   
   _def="$1"
   _ver="$2"

# unspecified
   if [ -z "$_ver" ]; then
      echo "$ELOQUENCE/bin/$_def"

# binary name
   elif [ -x "$ELOQUENCE/bin/$_ver" ]; then
      echo "$ELOQUENCE/bin/$_ver"

# version
   elif [ -x "/opt/eloquence/$_ver/bin/$_def" ]; then
      echo "/opt/eloquence/$_ver/bin/$_def"

# relative path
   elif [ -x "/opt/eloquence/$_ver" ]; then
      echo "/opt/eloquence/$_ver"

# absolute path
   else
      echo "$_ver"
   fi
}


### replication ###

# iterate defined eloqdb instances

function eq_foreach_repl
{
   typeset fn inst_id inst_cfg_file inst_start
   typeset inst_args inst_runpfx inst_dbrepl eloqdb_cfg
   typeset -i i inst_cnt

   fn=$1

   inst_cnt=${#REPL_CFG[*]}
   eq_debug_msg "# repl_inst_cnt = $inst_cnt"

   i=0
   while [ $inst_cnt -gt 0 ]
   do
      # dbrepl config file, ignore entry if not specified

      inst_cfg_file=${REPL_CFG[i]:-NOTSET}
      if [ "$inst_cfg_file" = "NOTSET" ]; then
	 let i=i+1
	 continue
      fi

      if [ "${inst_cfg_file##/*}" != "" ]; then
	 inst_cfg_file=/etc/opt/eloquence/8.4/$inst_cfg_file
      fi
      eq_debug_msg "# repl_inst_cfg_file = $inst_cfg_file"

      if [ ! -r "$inst_cfg_file" ]; then
         eq_log_msg "Note: repl[$i]: configuration file does not exist, ignored"
	 let inst_cnt=inst_cnt-1 i=i+1
	 continue
      fi

      # eloqdb config file, ignore entry if not configured
      
      eloqdb_cfg=$(grep -i "^[ 	]*master[ 	]*=" "$inst_cfg_file" | 
                   cut -d= -f2 | head -1 | tr -d ' ')
      if [ -z "$eloqdb_cfg" ]; then
         eq_log_msg "Note: repl[$i]: master not configured, ignored"
	 let inst_cnt=inst_cnt-1 i=i+1
	 continue
      fi

      if [ "${eloqdb_cfg##/*}" != "" ]; then
	 eloqdb_cfg=/etc/opt/eloquence/8.4/$eloqdb_cfg
      fi
      eq_debug_msg "# repl_eloqdb_cfg = $eloqdb_cfg"

      # arguments

      inst_args=${REPL_ARGS[i]:-NOTSET}
      if [ "$inst_args" = "NOTSET" ]; then
	 inst_args=$REPL_DEFAULT_ARGS
      fi
      eq_debug_msg "# repl_inst_args = $inst_args"

      # autostart (default off)

      inst_start=${REPL_START[i]:-0}
      eq_debug_msg "# repl_inst_start = $inst_start"

      # repl instance id (default derived from eloqdb service name)

      inst_id=${REPL_ID[i]:-NOTSET}
      if [ "$inst_id" = "NOTSET" ]; then
         inst_id=$(grep -i "^[ 	]*service[ 	]*=" "$eloqdb_cfg" | 
                   cut -d= -f2 | head -1 | tr -d ' ')
         [ -z "$inst_id" ] && inst_id="eloqdb"
	 inst_id="${inst_id}-r"
      fi
      eq_debug_msg "# repl_inst_id = $inst_id"
      
      # wrapper program (no practical use for dbrepl)

      inst_runpfx=${REPL_RUNPFX[i]:-}
      eq_debug_msg "# repl_inst_pfx = $inst_runpfx"

      # binary

      inst_dbrepl=$(eq_find_bin dbrepl ${REPL_VER[i]:-})
      eq_debug_msg "# repl_inst_dbrepl = $inst_dbrepl"

      # user (root or current user)

      inst_user="root"
      [ $START_STOP_AS_ROOT = 0 ] && eq_is_not_root && {
         inst_user=$(grep -i "^[ 	]*uid[ 	]*=" "$eloqdb_cfg" | 
                     cut -d= -f2 | head -1 | tr -d ' ')
         [ -z "$inst_user" ] && inst_user="root"
         eq_debug_msg "# repl_inst_user = $inst_user"
      }
      
      # callback

      if [ $eq_todo = start -o $eq_todo = restart ]; then
         if [ $inst_start -eq 0 -a -z "$eq_arg_list" ]; then
            let inst_cnt=inst_cnt-1 i=i+1
	    continue
         fi
      fi

      $fn "$inst_id" "$inst_cfg_file" "$inst_args" \
      "$inst_runpfx" "$inst_start" "$inst_user" "$inst_dbrepl"
      let inst_cnt=inst_cnt-1 i=i+1
   done
}


### eloqsd ###

function eq_eloqsd_start
{
   typeset msg pid_file pid pfx stat eloqsd
   typeset -i stat

   eq_debug_msg "# eq_eloqsd_start"

   test -z "$eq_arg_list" -a $START_ELOQSD -eq 0 && return 0
   eq_is_not_root && return 0
   eq_instance_filter eloqsd || return 0

   eq_log_msg "Starting eloqsd daemon"
   $eq_act_msg1 "Starting eloqsd daemon"
   stat=$eq_rc_ok
   
   pfx=${ELOQSD_RUNPFX:-}
   eloqsd=$(eq_find_bin eloqsd ${ELOQSD_VER:-})

   pid_file=$pid_dir/eloqsd.pid
   if [ ! -f $pid_file ]; then
      eq_run "$pfx $eloqsd $ELOQSD_ARGS -p $pid_file"
      [ $? -ne 0 ] && stat=$eq_rc_failed
   else
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $eloqsd $pid
      if [ $? != 0 ]; then
         eq_log_msg "Note: eloqsd process $pid is not active (stale pid file)"
	 eq_log_msg $(rm -f "$pid_file" 2>&1)
	 eq_run "$pfx $eloqsd $ELOQSD_ARGS -p $pid_file"
	 [ $? -ne 0 ] && stat=$eq_rc_failed
      else
         eq_log_msg "eloqsd process is already active (pid $pid)"
         $eq_act_msg2 $stat
	 return
      fi
   fi

   # detection of startup problems is not reliable as long as the 
   # binary exists. so we check if the server pid file exists and
   # the process is still there. note there is an obvious race 
   # condition here as there is no guarantee the server process has
   # made sufficient progress ...

   sleep 1
   if [ ! -f "$pid_file" ]; then
      eq_log_msg "eloqsd process is not active (no pid file)"
      stat=$eq_rc_failed
      eq_rval=1
   else
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $eloqsd $pid
      if [ $? != 0 ]; then
         eq_log_msg "eloqsd process $pid is not active (stale pid file)"
         stat=$eq_rc_failed
         eq_rval=1
      fi
   fi

   $eq_act_msg2 $stat
}

function eq_eloqsd_stop
{
   typeset msg pid_file pid eloqsd
   typeset -i stat

   eq_debug_msg "# eq_eloqsd_stop"

   eq_is_not_root && return 0
   eq_instance_filter eloqsd || return 0

   eq_log_msg "Stopping eloqsd daemon"
   $eq_act_msg1 "Stopping eloqsd daemon"
   stat=$eq_rc_notrunning

   eloqsd=$(eq_find_bin eloqsd ${ELOQSD_VER:-})

   pid_file=$pid_dir/eloqsd.pid
   if [ -f $pid_file ]; then
      pid=$(eq_get_pid $pid_file)
      test -n "$pid" && $eq_checkproc $eloqsd $pid
      if [ $? != 0 ]; then
         eq_log_msg "Note: eloqsd process $pid is not active (stale pid file)"
      else
         eq_log_msg $(kill -TERM $pid 2>&1)
	 child_pid=$($eq_child_procs $pid)
	 eq_pid_list="${eq_pid_list:-} $pid $child_pid"
	 stat=$eq_rc_ok
      fi
      eq_log_msg $(rm -f "$pid_file" 2>&1)
   fi

   $eq_act_msg2 $stat
}

function eq_eloqsd_status
{
   typeset pid_file pid eloqsd

   eq_instance_filter eloqsd || return 0
   eq_debug_msg "# eq_eloqsd_status"

   eloqsd=$(eq_find_bin eloqsd ${ELOQSD_VER:-})

   pid_file=$pid_dir/eloqsd.pid
   if [ ! -f $pid_file ]; then
      $eq_stat_msg1 "eloqsd process is not active"
      $eq_stat_msg2 $eq_stat_stopped
   else
      pid=$(eq_get_pid $pid_file)
      test -n "$pid" && $eq_checkproc $eloqsd $pid
      if [ $? != 0 ]; then
         $eq_stat_msg1 "eloqsd process $pid is not active (stale pid file)"
         $eq_stat_msg2 $eq_stat_deadpid
      else
         $eq_stat_msg1 "eloqsd process is active (pid $pid)"
         $eq_stat_msg2 $eq_stat_ok
      fi
   fi
}


### eloqdb ###

# eq_eloqdb_start()
# start an eloqdb instance

function eq_eloqdb_start
{
   typeset id cfg_file service args pfx
   typeset msg pid_file pid user eloqdb
   typeset -i stat

   id=$1
   cfg_file=$2
   service=$3
   args=$4
   pfx=$5
   user=$7
   eloqdb=$8

   eq_debug_msg "# eq_eloqdb_start $id"

   test -z "$eq_arg_list" -a $START_ELOQDB -eq 0 && return 0
   eq_is_matching_user "$user" || return 0
   eq_instance_filter "$id" || return 0

   eq_log_msg "Starting eloqdb[$id] daemon"
   $eq_act_msg1 "Starting eloqdb[$id] daemon"
   stat=$eq_rc_ok

   pid_file=$pid_dir/eloqdb_$id.pid
   if [ ! -f "$pid_file" ]; then
      eq_run "$pfx $eloqdb -c $cfg_file $args -p $pid_file"
      [ $? != 0 ] && stat=$eq_rc_failed
   else
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $eloqdb $pid
      if [ $? != 0 ]; then
         eq_log_msg "Note: eloqdb[$id] process $pid is not active (stale pid file)"
	 eq_log_msg $(rm -f "$pid_file" 2>&1)
	 eq_run "$pfx $eloqdb -c $cfg_file $args -p $pid_file"
         [ $? != 0 ] && stat=$eq_rc_failed
      else
         eq_log_msg "eloqdb[$id] process is already active (pid $pid)"
         $eq_act_msg2 $stat
	 return
      fi
   fi

   # detection of startup problems is not reliable as long as the 
   # binary exists. so we check if the server pid file exists and
   # the process is still there. note there is an obvious race 
   # condition here as there is no guarantee the server process has
   # made sufficient progress ...

   sleep 1
   if [ ! -f "$pid_file" ]; then
      eq_log_msg "eloqdb[$id] process is not active (no pid file)"
      stat=$eq_rc_failed
      eq_rval=1
   else
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $eloqdb $pid
      if [ $? != 0 ]; then
         eq_log_msg "eloqdb[$id] process $pid is not active (stale pid file)"
         stat=$eq_rc_failed
         eq_rval=1
      fi
   fi

   $eq_act_msg2 $stat
}

# eq_eloqdb_stop()
# stop an eloqdb instance

function eq_eloqdb_stop
{
   typeset id cfg_file service args pfx
   typeset msg pid_file pid user eloqdb
   typeset -i stat

   id=$1
   cfg_file=$2
   service=$3
   args=$4
   pfx=$5
   user=$7
   eloqdb=$8

   eq_debug_msg "# eq_eloqdb_stop $id $user"

   eq_is_matching_user "$user" || return 0
   eq_instance_filter "$id" || return 0

   eq_log_msg "Stopping eloqdb[$id] daemon"
   $eq_act_msg1 "Stopping eloqdb[$id] daemon"
   stat=$eq_rc_notrunning
   
   pid_file=$pid_dir/eloqdb_$id.pid
   if [ -f "$pid_file" ]; then
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $eloqdb $pid
      if [ $? != 0 ]; then
         eq_log_msg "Note: eloqdb[$id] process $pid is not active (stale pid file)"
      else
         eq_log_msg $(kill -TERM $pid 2>&1)
         child_pid=$($eq_child_procs $pid)
         eq_pid_list="${eq_pid_list:-} $pid $child_pid"
         stat=$eq_rc_ok
      fi
      eq_log_msg $(rm -f "$pid_file" 2>&1)
   fi

   $eq_act_msg2 $stat
}

# eq_eloqdb_status()
# display status of an eloqdb instance

function eq_eloqdb_status
{
   typeset id cfg_file service args pfx
   typeset pid_file pid eloqdb

   id=$1
   cfg_file=$2
   service=$3
   args=$4
   pfx=$5
   eloqdb=$8

   eq_instance_filter "$id" || return 0
   pid_file=$pid_dir/eloqdb_$id.pid
   if [ ! -f "$pid_file" ]; then
      $eq_stat_msg1 "eloqdb[$id] process is not active"
      $eq_stat_msg2 $eq_stat_stopped
   else
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $eloqdb $pid
      if [ $? != 0 ]; then
         $eq_stat_msg1 "eloqdb[$id] process $pid is not active (stale pid file)"
         $eq_stat_msg2 $eq_stat_deadpid
      else
         $eq_stat_msg1 "eloqdb[$id] process is active (pid $pid)"
         $eq_stat_msg2 $eq_stat_ok
      fi
   fi
}

# eq_eloqdb_info()
# configuration information for an eloqdb instance

function eq_eloqdb_info
{
   typeset id cfg_file service args pfx start user eloqdb

   id=$1
   cfg_file=$2
   service=$3
   args=$4
   pfx=$5
   start=$6
   user=$7
   eloqdb=$8

   eq_instance_filter "$id" || return 0
   echo " eloqdb instance id = $id"
   echo "  configuration file = $cfg_file"
   echo "  service = $service"
   [ -z "$args" ] || echo "  args = $args"
   [ -z "$pfx"  ] || echo "  run prefix = $pfx"
   echo "  automatic start = $start"
   echo "  user = $user"
   echo "  eloqdb = $eloqdb"
}


### repl ###

# eq_repl_start()
# start dbrepl instance(s)

function eq_repl_start
{
   typeset id cfg_file args pfx
   typeset msg pid_file pid user dbrepl
   typeset -i stat

   id="$1"
   cfg_file="$2"
   args="$3"
   pfx="$4"
   user="$6"
   dbrepl="$7"

   eq_debug_msg "# eq_repl_start $id"

   test -z "$eq_arg_list" -a $START_ELOQDB -eq 0 && return 0
   eq_is_matching_user "$user" || return 0
   eq_instance_filter "$id" || return 0

   eq_log_msg "Starting dbrepl[$id] process"
   $eq_act_msg1 "Starting dbrepl[$id] process"
   stat=$eq_rc_ok

   pid_file=$pid_dir/repl_$id.pid
   if [ ! -f "$pid_file" ]; then
      eq_run "$pfx $dbrepl -C $cfg_file $args -DP $pid_file"
      [ $? != 0 ] && stat=$eq_rc_failed
   else
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $dbrepl $pid
      if [ $? != 0 ]; then
         eq_log_msg "Note: dbrepl[$id] process $pid is not active (stale pid file)"
	 eq_log_msg $(rm -f "$pid_file" 2>&1)
         eq_run "$pfx $dbrepl -C $cfg_file $args -DP $pid_file"
         [ $? != 0 ] && stat=$eq_rc_failed
      else
         eq_log_msg "dbrepl[$id] process is already active (pid $pid)"
         $eq_act_msg2 $stat
	 return
      fi
   fi

   # detection of startup problems is not reliable as long as the 
   # binary exists. so we check if the pid file exists and
   # the process is still there. note there is an obvious race 
   # condition here as there is no guarantee the process has
   # made sufficient progress ...

   sleep 1
   if [ ! -f "$pid_file" ]; then
      eq_log_msg "dbrepl[$id] process is not active (no pid file)"
      stat=$eq_rc_failed
      eq_rval=1
   else
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $dbrepl $pid
      if [ $? != 0 ]; then
         eq_log_msg "dbrepl[$id] process $pid is not active (stale pid file)"
         stat=$eq_rc_failed
         eq_rval=1
      fi
   fi

   $eq_act_msg2 $stat
}

# eq_repl_stop()
# stop dbrepl instance(s)

function eq_repl_stop
{
   typeset id cfg_file args pfx
   typeset msg pid_file pid user dbrepl
   typeset -i stat

   id="$1"
   cfg_file="$2"
   args="$3"
   pfx="$4"
   user="$6"
   dbrepl="$7"

   eq_debug_msg "# eq_repl_stop $id $user"

   eq_is_matching_user "$user" || return 0
   eq_instance_filter "$id" || return 0

   eq_log_msg "Stopping dbrepl[$id] process"
   $eq_act_msg1 "Stopping dbrepl[$id] process"
   stat=$eq_rc_notrunning
   
   pid_file=$pid_dir/repl_$id.pid
   if [ -f "$pid_file" ]; then
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $dbrepl $pid
      if [ $? != 0 ]; then
         eq_log_msg "Note: dbrepl[$id] process $pid is not active (stale pid file)"
      else
         eq_log_msg $(kill -TERM $pid 2>&1)
         child_pid=$($eq_child_procs $pid)
         eq_pid_list="${eq_pid_list:-} $pid $child_pid"
         stat=$eq_rc_ok
      fi
      eq_log_msg $(rm -f "$pid_file" 2>&1)
   fi

   $eq_act_msg2 $stat
}

# eq_repl_status()
# display status of dbrepl instance(s)

function eq_repl_status
{
   typeset id
   typeset pid_file pid dbrepl

   id="$1"
   dbrepl="$7"

   eq_instance_filter "$id" || return 0
   pid_file=$pid_dir/repl_$id.pid
   if [ ! -f "$pid_file" ]; then
      $eq_stat_msg1 "dbrepl[$id] process is not active"
      $eq_stat_msg2 $eq_stat_stopped
   else
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $dbrepl $pid
      if [ $? != 0 ]; then
         $eq_stat_msg1 "dbrepl[$id] process $pid is not active (stale pid file)"
         $eq_stat_msg2 $eq_stat_deadpid
      else
         $eq_stat_msg1 "dbrepl[$id] process is active (pid $pid)"
         $eq_stat_msg2 $eq_stat_ok
      fi
   fi
}

# eq_repl_info()
# configuration information for a replication instance

function eq_repl_info
{
   typeset id cfg_file args pfx start user dbrepl

   id="$1"
   cfg_file="$2"
   args="$3"
   pfx="$4"
   start="$5"
   user="$6"
   dbrepl="$7"

   eq_instance_filter "$id" || return 0
   echo " dbrepl instance id = $id"
   echo "  configuration file = $cfg_file"
   [ -z "$args" ] || echo "  args = $args"
   [ -z "$pfx" ] || echo "  run prefix = $pfx"
   echo "  automatic start = $start"
   echo "  user = $user"
   echo "  dbrepl = $dbrepl"
}


### eloqwebd2 ###

function eq_eloqwebd2_start
{
   typeset msg pid_file pid pfx stat eloqwebd2
   typeset -i stat

   eq_debug_msg "# eq_eloqwebd2_start"

   test -z "$eq_arg_list" -a $START_ELOQWEBD2 -eq 0 && return 0
   eq_is_not_root && return 0
   eq_instance_filter eloqwebd2 || return 0

   eq_log_msg "Starting eloqwebd2 daemon"
   $eq_act_msg1 "Starting eloqwebd2 daemon"
   stat=$eq_rc_ok
   
   pfx=${ELOQWEBD2_RUNPFX:-}
   eloqwebd2=$(eq_find_bin eloqwebd2 ${ELOQWEBD2_VER:-})

   pid_file=$pid_dir/eloqwebd2.pid
   if [ ! -f $pid_file ]; then
      eq_run "$pfx $eloqwebd2 $ELOQWEBD2_ARGS -p $pid_file"
      [ $? -ne 0 ] && stat=$eq_rc_failed
   else
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $eloqwebd2 $pid
      if [ $? != 0 ]; then
         eq_log_msg "Note: eloqwebd2 process $pid is not active (stale pid file)"
	 eq_log_msg $(rm -f "$pid_file" 2>&1)
	 eq_run "$pfx $eloqwebd2 $ELOQWEBD2_ARGS -p $pid_file"
	 [ $? -ne 0 ] && stat=$eq_rc_failed
      else
         eq_log_msg "eloqwebd2 process is already active (pid $pid)"
         $eq_act_msg2 $stat
	 return
      fi
   fi

   # detection of startup problems is not reliable as long as the 
   # binary exists. so we check if the server pid file exists and
   # the process is still there. note there is an obvious race 
   # condition here as there is no guarantee the server process has
   # made sufficient progress ...

   sleep 1
   if [ ! -f "$pid_file" ]; then
      eq_log_msg "eloqwebd2 process is not active (no pid file)"
      stat=$eq_rc_failed
      eq_rval=1
   else
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $eloqwebd2 $pid
      if [ $? != 0 ]; then
         eq_log_msg "eloqwebd2 process $pid is not active (stale pid file)"
         stat=$eq_rc_failed
         eq_rval=1
      fi
   fi

   $eq_act_msg2 $stat
}

function eq_eloqwebd2_stop
{
   typeset msg pid_file pid eloqwebd2
   typeset -i stat

   eq_debug_msg "# eq_eloqwebd2_stop"

   eq_is_not_root && return 0
   eq_instance_filter eloqwebd2 || return 0

   eq_log_msg "Stopping eloqwebd2 daemon"
   $eq_act_msg1 "Stopping eloqwebd2 daemon"
   stat=$eq_rc_notrunning

   eloqwebd2=$(eq_find_bin eloqwebd2 ${ELOQWEBD2_VER:-})

   pid_file=$pid_dir/eloqwebd2.pid
   if [ -f $pid_file ]; then
      pid=$(eq_get_pid $pid_file)
      test -n "$pid" && $eq_checkproc $eloqwebd2 $pid
      if [ $? != 0 ]; then
         eq_log_msg "Note: eloqwebd2 process $pid is not active (stale pid file)"
      else
         eq_log_msg $(kill -TERM $pid 2>&1)
	 child_pid=$($eq_child_procs $pid)
	 eq_pid_list="${eq_pid_list:-} $pid $child_pid"
	 stat=$eq_rc_ok
      fi
      eq_log_msg $(rm -f "$pid_file" 2>&1)
   fi

   $eq_act_msg2 $stat
}

function eq_eloqwebd2_status
{
   typeset pid_file pid eloqwebd2

   eq_instance_filter eloqwebd2 || return 0
   eq_debug_msg "# eq_eloqwebd2_status"

   eloqwebd2=$(eq_find_bin eloqwebd2 ${ELOQWEBD2_VER:-})

   pid_file=$pid_dir/eloqwebd2.pid
   if [ ! -f $pid_file ]; then
      $eq_stat_msg1 "eloqwebd2 process is not active"
      $eq_stat_msg2 $eq_stat_stopped
   else
      pid=$(eq_get_pid $pid_file)
      test -n "$pid" && $eq_checkproc $eloqwebd2 $pid
      if [ $? != 0 ]; then
         $eq_stat_msg1 "eloqwebd2 process $pid is not active (stale pid file)"
         $eq_stat_msg2 $eq_stat_deadpid
      else
         $eq_stat_msg1 "eloqwebd2 process is active (pid $pid)"
         $eq_stat_msg2 $eq_stat_ok
      fi
   fi
}


### eloqld ###

function eq_eloqld_start
{
   typeset msg pid_file pid pfx stat eloqld
   typeset -i stat

   eq_debug_msg "# eq_eloqld_start"

   test -z "$eq_arg_list" -a $START_ELOQLD -eq 0 && return 0
   eq_is_not_root && return 0
   eq_instance_filter eloqld || return 0

   eq_log_msg "Starting eloqld daemon"
   $eq_act_msg1 "Starting eloqld daemon"
   stat=$eq_rc_ok
   
   pfx=${ELOQLD_RUNPFX:-}
   eloqld=$(eq_find_bin eloqld ${ELOQLD_VER:-})

   pid_file=$pid_dir/eloqld.pid
   if [ ! -f $pid_file ]; then
      eq_run "$pfx $eloqld $ELOQLD_ARGS -p $pid_file"
      [ $? -ne 0 ] && stat=$eq_rc_failed
   else
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $eloqld $pid
      if [ $? != 0 ]; then
         eq_log_msg "Note: eloqld process $pid is not active (stale pid file)"
	 eq_log_msg $(rm -f "$pid_file" 2>&1)
	 eq_run "$pfx $eloqld $ELOQLD_ARGS -p $pid_file"
	 [ $? -ne 0 ] && stat=$eq_rc_failed
      else
         eq_log_msg "eloqld process is already active (pid $pid)"
         $eq_act_msg2 $stat
	 return
      fi
   fi

   # detection of startup problems is not reliable as long as the 
   # binary exists. so we check if the server pid file exists and
   # the process is still there. note there is an obvious race 
   # condition here as there is no guarantee the server process has
   # made sufficient progress ...

   sleep 1
   if [ ! -f "$pid_file" ]; then
      eq_log_msg "eloqld process is not active (no pid file)"
      stat=$eq_rc_failed
      eq_rval=1
   else
      pid=$(eq_get_pid "$pid_file")
      test -n "$pid" && $eq_checkproc $eloqld $pid
      if [ $? != 0 ]; then
         eq_log_msg "eloqld process $pid is not active (stale pid file)"
         stat=$eq_rc_failed
         eq_rval=1
      fi
   fi

   $eq_act_msg2 $stat
}

function eq_eloqld_stop
{
   typeset msg pid_file pid eloqld
   typeset -i stat

   eq_debug_msg "# eq_eloqld_stop"

   eq_is_not_root && return 0
   eq_instance_filter eloqld || return 0

   eq_log_msg "Stopping eloqld daemon"
   $eq_act_msg1 "Stopping eloqld daemon"
   stat=$eq_rc_notrunning

   eloqld=$(eq_find_bin eloqld ${ELOQLD_VER:-})

   pid_file=$pid_dir/eloqld.pid
   if [ -f $pid_file ]; then
      pid=$(eq_get_pid $pid_file)
      test -n "$pid" && $eq_checkproc $eloqld $pid
      if [ $? != 0 ]; then
         eq_log_msg "Note: eloqld process $pid is not active (stale pid file)"
      else
         eq_log_msg $(kill -TERM $pid 2>&1)
	 child_pid=$($eq_child_procs $pid)
	 eq_pid_list="${eq_pid_list:-} $pid $child_pid"
	 stat=$eq_rc_ok
      fi
      eq_log_msg $(rm -f "$pid_file" 2>&1)
   fi

   $eq_act_msg2 $stat
}

function eq_eloqld_status
{
   typeset pid_file pid eloqld

   eq_instance_filter eloqld || return 0
   eq_debug_msg "# eq_eloqld_status"

   eloqld=$(eq_find_bin eloqld ${ELOQLD_VER:-})

   pid_file=$pid_dir/eloqld.pid
   if [ ! -f $pid_file ]; then
      $eq_stat_msg1 "eloqld process is not active"
      $eq_stat_msg2 $eq_stat_stopped
   else
      pid=$(eq_get_pid $pid_file)
      test -n "$pid" && $eq_checkproc $eloqld $pid
      if [ $? != 0 ]; then
         $eq_stat_msg1 "eloqld process $pid is not active (stale pid file)"
         $eq_stat_msg2 $eq_stat_deadpid
      else
         $eq_stat_msg1 "eloqld process is active (pid $pid)"
         $eq_stat_msg2 $eq_stat_ok
      fi
   fi
}
