#! /bin/bash

# A function to find the pid of a program.
pidofproc()
{
  pid=""
  # Test syntax.
  if [ $# = 0 ]; then
    echo "Usage: pidofproc {program} {port}"
    return 1
  fi

  # Get base program name
  base=$(basename $1)

  # First try "pidof"
  if [ ! -z "${PIDOF}" -a -x "${PIDOF}" ]; then
    pid=$(${PIDOF} $1)
    if [ "$pid" != "" ]; then
      echo $pid
      return 0
    fi
  fi

  # Next try "pgrep"
  if [ ! -z "${PGREP}" -a -x "${PGREP}" ]; then
    pid=$(${PGREP} -f $base)
    if [ "$pid" != "" ]; then
      echo $pid | cut -d' ' -f 1
      return 0
    fi
  fi

  # Finally try to extract it from ps
  pid=$(ps | grep ${base} | awk '{print $1}' | head -n1)
  echo $pid
  return 0
}

checkPid()
{
  pid="$1"
  wait="${2:-0}"
  waittext="${3:-}"
  output=""

  if [ -z "$pid" ]; then
    return 1
  fi

  start=$(date +%s)
  end=$(expr $start + $wait)

  while [ "$(date +%s)" -lt "$end" ] && ${PS} -p "$pid" >/dev/null 2>&1; do
    if [ "${waittext}" ]; then
      printf "%s" "$waittext"
      output="yes"
    fi
    # not all systems offer floating point numbers as sleep parameter, therefore try both.
    sleep 0.1 || sleep 1
  done
  if [ "${output}" ]; then printf " "; fi
  ${PS} -p "$pid" >/dev/null 2>&1
  return $?
}

# A function to stop a program.
killproc()
{
  RC=0
  # Test syntax.
  if [ $# = 0 ]; then
    echo "Usage: killproc {program} {port} [signal]"
    return 1
  fi

  notset=0
  # check for third arg to be kill level
  if [ "$3" != "" ]; then
    killlevel=$3
  else
    notset=1
    killlevel="-9"
  fi

  # Get base program name
  base=$(basename $1)

  # Find pid.
  pid=$(pidofproc $base $2)

  # Kill it.
  if checkPid "$pid"; then
    if [ "$notset" = "1" ]; then
      # TERM first, then KILL if not dead
      kill -TERM $pid 2>/dev/null
      if checkPid "$pid" 3 "."; then
        kill -KILL $pid 2>/dev/null
      fi
      if checkPid "$pid" 3 "_"; then
        failure
      else
        success
      fi
    else
      if kill $killlevel $pid 2>/dev/null; then
        success "sent signal $killlevel"
      else
        failure
      fi
    fi
  else
    success "already stopped"
  fi
  return $RC
}

# Checks if the Database can be connected to
check_database()
{
  echo "Checking Database connection for $1"
  log_file="${tmp}/bareos-$1-config-test.out"
  "$2" -f -t "${@:3}" &>"$log_file"

  if grep -q "Could not open Catalog" "$log_file"; then
    echo "Fail: Could not connect to the Catalog when running $2 -t ${*:3}, see below." >&2
    cat "$log_file"
    return 2
  fi
  return 0
}
# Checks if the configuration outputs warnings
check_config()
{
  echo "Checking Configuration for $1"
  log_file="${tmp}/bareos-$1-config-test.out"
  "$2" -t "${@:3}" &>"$log_file"

  if ! ${IGNORE_CONFIG_WARNINGS}; then
    if grep -q "There are configuration warnings" "$log_file"; then
      echo "Fail: There are configuration warnings when running $2 -t ${*:3}, see below." >&2
      cat "$log_file"
      return 7
    fi
  else
    cat "$log_file"
  fi
  return 0
}

status()
{
  # Test syntax.
  if [ $# = 0 ]; then
    echo "Usage: status {program} {port}"
    return 1
  fi

  # Get base program name
  base=$(basename $1)

  # Find pid.
  pid=$(pidofproc $base $2)

  if checkPid "$pid"; then
    echo "$base (pid $pid) is running..."
    return 0
  fi

  # See if the subsys lock exists
  if [ -f ${SUBSYSDIR}/$base ]; then
    echo "$base dead but subsys locked"
    return 2
  fi

  echo "$base is stopped"

  return 3
}

success()
{
  MESSAGE="OK"
  if [ "$1" ]; then
    MESSAGE="OK ($1)"
  fi
  echo $MESSAGE
  return 0
}

failure()
{
  rc=$?
  echo "failed (rc=$rc)"
  return $rc
}
