#!/bin/bash

[ "${DEBUG}" = "yes" ] || DEBUG="no"
[ -z "${DIST_UPGRADE_ENABLED}" ] && DIST_UPGRADE_ENABLED="yes"

# --------------------------------------------------------------------------
#
# Logging functions idea from
# http://www.cubicrace.com/2016/03/efficient-logging-mechnism-in-shell.html
#
# --------------------------------------------------------------------------


#LOGFILE=SystemOut.log
TMP_DIR="/var/tmp/$( basename ${0} ).tmp.$$"
touch "${LOGFILE}"
tmp="${0}.tmp.$$"

# User variables:
USERNAME="${1}"
[ -z "${USERNAME}" ] && USERNAME="user"
USERPASSWORD="${2}"
[ -z "${USERPASSWORD}" ] && USERPASSWORD="ChangeMe"
USERHOME="/home/${USERNAME}"

function ENTRY(){
    local cfn="${FUNCNAME[1]}"
    local tstamp=`date`
    local msg="> ${cfn} ${FUNCNAME}"
    echo -e "[${tstamp}] [DEBUG]\t${msg}" >> "${LOGFILE}"
}

function RETURN(){
    local cfn="${FUNCNAME[1]}"
    local tstamp=`date`
    local msg="< ${cfn} ${FUNCNAME}"
    echo -e "[${tstamp}] [DEBUG]\t${msg}" >> "${LOGFILE}"
}

function INFO()
{
    local msg="${1}"
    local tstamp=`date`
    echo -e "[${tstamp}] [INFO]\t${msg}" >> "${LOGFILE}"
}

function ERROR()
{
    local msg="${1}"
    local tstamp=`date`
    echo -e "[${tstamp}] [ERROR]\t${msg}" >> "${LOGFILE}"
}

function DEBUG()
{
    local msg="${1}"
    local tstamp=`date`
    echo -e "[${tstamp}] [DEBUG]\t${msg}" >> ${LOGFILE}
}

# --------------------------------------------------------------
# RSB custom code
# --------------------------------------------------------------
export IP=`ifconfig  | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}' | tail -1`
export DATE=`date +%Y-%m-%d:%H:%M:%S`
export DEBIAN_FRONTEND=noninteractive


function L_LOG () {
    echo "-------------------------------------------------------------" >> "${LOGFILE}"
}

function LOG_INFO()
{
#    [ "${DEBUG}" = "yes" ] && ENTRY
    local title
    local result=""
    [ -n "${1}" ] && title="${1}" || title="${JOB_NAME}"
    [ -n "${2}" ] && result="${2}"
    INFO "${title}"
    [ ! -z "${LOG}" ] && INFO "${LOG}"
    [ ! -z "${result}" ] && INFO "${result}"
    L_LOG
    LOG=""
#    [ "${DEBUG}" = "yes" ] && RETURN
}

function LOG_ERROR()
{
#    [ "${DEBUG}" = "yes" ] && ENTRY
    local title
    local result=""
    [ -n "${1}" ] && title="${1}" || title="${JOB_NAME}"
    [ -n "${2}" ] && result="${2}"
    ERROR "${title}"
    [ ! -z "${LOG}" ] && ERROR "${LOG}"
    [ ! -z "${result}" ] && ERROR "${result}"
    L_LOG
    LOG=""
#    [ "${DEBUG}" = "yes" ] && RETURN
}

function LOG_DEBUG()
{
#    [ "${DEBUG}" = "yes" ] && ENTRY
    local title
    local result=""
    [ -n "${1}" ] && title="${1}" || title="${JOB_NAME}"
    [ -n "${2}" ] && result="${2}"
    DEBUG "${title}"
    [ ! -z "${LOG}" ] && DEBUG "${LOG}"
    [ ! -z "${result}" ] && DEBUG "${result}"
    L_LOG
    LOG=""
#    [ "${DEBUG}" = "yes" ] && RETURN
}


function LOG_RC () {
#    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc
    _rc=${1}
    if [ ${_rc} -ne 0 ] ; then
        LOG_ERROR "${JOB_NAME}" "Failed! Rc: [${_rc}]"
    else
        LOG_INFO "${JOB_NAME}" "Success."
    fi
#    [ "${DEBUG}" = "yes" ] && RETURN
}


function RM_FILES () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _main_rc=1
    local _rc=1
    local f
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Removing file:"
    if [ -z "${*}" ] ; then
        LOG="RM_FILES(): Argument missing!"
        LOG_RC ${_main_rc}
    else
        _main_rc=0
        for f in "${@}" ; do
            JOB_NAME="Removing file: '${f}'"
            _rc=1
            if [ -e "${f}" -o -L "${f}" ] ; then
                LOG="$( rm -f ${opts} "${f}" 2>&1 )"
                _rc=$?
                [ ${_rc} -ne 0 ] && _main_rc=${_rc}
            else
                LOG="'${f}': file not found !"
            fi
            LOG_RC ${_rc}
        done
    fi
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_main_rc}
}

function RM_DIRS () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _main_rc=1
    local _rc=1
    local d
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Removing directory:"
    if [ -z "${*}" ] ; then
        LOG="RM_DIRS(): Argument missing!"
        LOG_RC ${_main_rc}
    else
        _main_rc=0
        for d in "${@}" ; do
            JOB_NAME="Removing directory: '${d}'"
            if [ -d "${d}" ] ; then
                if [ "${d}" = "/" ] ; then
                    LOG="Can not remove this directory: '${d}'"
                    _main_rc=5
                else
                    LOG="$( rm -rf ${opts} "${d}" 2>&1 )"
                    _rc=$?
                    [ ${_rc} -ne 0 ] && _main_rc=${_rc}
                fi
            else
                LOG="'${d}': directory does not exists."
            fi
            LOG_RC ${_rc}
        done
    fi
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_main_rc}
}

function APT_CLEAN () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc
    local opts="-qq"
    [ ${DEBUG} = "yes" ] && opts=""
    JOB_NAME="Perform APT Clean"
    LOG="$( apt-get ${opts} clean 2>&1 )"
    _rc=$?
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function APT_UPDATE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc
    local _main_rc=0
    local opts="-qq"
    [ ${DEBUG} = "yes" ] && opts=""
    #
    JOB_NAME="Perform APT Update"
    LOG="$( apt-get ${opts} update 2>&1 )"
    _rc=$?
    LOG_RC ${_rc}
    [ ${_rc} -ne 0 ] && _main_rc=${_rc}
    #
    JOB_NAME="Perform APT -f install"
    LOG="$( apt-get ${opts} -f install 2>&1 )"
    _rc=$?
    LOG_RC ${_rc}
    [ ${_rc} -ne 0 ] && _main_rc=${_rc}
    #
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_main_rc}
}

function APT_DIST_UPGRADE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc
    local opts="-qq"
    [ ${DEBUG} = "yes" ] && opts=""
    JOB_NAME="Perform APT Dist-Upgrade"
    LOG="$( apt-get ${opts} -y --force-yes dist-upgrade 2>&1 )"
    _rc=$?
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function APT_INSTALL () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local opts="-qq"
    [ ${DEBUG} = "yes" ] && opts=""
    [ "${ALLOW_UNAUTH_PKGS}" = "yes" ] && opts="${opts} --allow-unauthenticated"
    if [ -z "${1}" ] ; then
        ERROR "APT_INSTALL(): Argument(s) missing!"
    else
        JOB_NAME="Perform APT Install ${*}"
        LOG="$( apt-get ${opts} -y install ${*} 2>&1 )"
        _rc=$?
        LOG_RC ${_rc}
    fi
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function APT_REMOVE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local opts="-qq"
    [ ${DEBUG} = "yes" ] && opts=""
    JOB_NAME="Perform APT Remove"
    if [ -z "${1}" ] ; then
        LOG="APT_REMOVE(): Argument(s) missing!"
    else
        JOB_NAME="${JOB_NAME} ${*}"
#        LOG="$(apt-get -qq -y remove ${*} 2>&1)"
        LOG="$( apt-get ${opts} -y purge ${*} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function APT_AUTOREMOVE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc
    local opts="-qq"
    [ ${DEBUG} = "yes" ] && opts=""
    JOB_NAME="Perform APT Auto-Remove"
    LOG="$( apt-get ${opts} -y autoremove 2>&1 )"
    _rc=$?
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function ADD_APT_REPO () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _repo
    JOB_NAME="Add APT Repository"
    if [ -z "${1}" ] ; then
        LOG="ADD_APT_REPO(): Argument missing!"
    else
        _repo="${1}"
        JOB_NAME="${JOB_NAME} -> '${_repo}'"
        LOG="$( add-apt-repository -y ${_repo} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function DEL_APT_REPO () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _repo
    JOB_NAME="Remove APT Repository"
    if [ -z "${1}" ] ; then
        LOG="DEL_APT_REPO(): Argument missing!"
    else
        _repo="${1}"
        JOB_NAME="${JOB_NAME} -> '${_repo}'"
        LOG="$( add-apt-repository -y -r ${_repo} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function ADD_APT_KEY_URL () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _url
    JOB_NAME="Add APT Key"
    if [ -z "${1}" ] ; then
        LOG="ADD_APT_KEY_URL(): Argument missing!"
    else
        _url="${1}"
        JOB_NAME="${JOB_NAME} -> '${_url}'"
        LOG="$( wget -qO - ${_url} | apt-key add - 2>&1 )"
        _rc=$?
        LOG_RC ${_rc}
    fi
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function ADD_APT_KEY_FILE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _file
    JOB_NAME="Add APT Key"
    if [ -z "${1}" ] ; then
        LOG="ADD_APT_KEY_FILE(): Argument missing!"
    else
        _file="${1}"
        JOB_NAME="${JOB_NAME} -> '${_file}'"
        LOG="$( apt-key add ${_file} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function YUM_DIST_UPGRADE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Perform YUM Dist-Upgrade"
    LOG="$( yum ${opts} -y update 2>&1 )"
    _rc=$?
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function YUM_INSTALL () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    if [ -z "${1}" ] ; then
        ERROR "YUM_INSTALL(): Argument(s) missing!"
    else
        JOB_NAME="Perform YUM Install ${*}"
        LOG="$( yum ${opts} -y install ${*} 2>&1 )"
        _rc=$?
        LOG_RC ${_rc}
    fi
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function YUM_GROUPINSTALL () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local g
    local _main_rc=1
    local _rc
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    if [ -z "${1}" ] ; then
        ERROR "YUM_GROUPINSTALL(): Argument(s) missing!"
    else
        _main_rc=0
        for g in "${@}" ; do
            JOB_NAME="Perform YUM Group Install [${g}]"
            LOG="$( yum ${opts} -y groupinstall "${g}" 2>&1 )"
            _rc=$?
            LOG_RC ${_rc}
            [ ${_rc} -ne 0 ] && _main_rc=${_rc}
        done
    fi
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_main_rc}
}

function YUM_REMOVE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Perform YUM Remove"
    if [ -z "${1}" ] ; then
        LOG="YUM_REMOVE(): Argument(s) missing!"
    else
        JOB_NAME="${JOB_NAME} ${*}"
        LOG="$( yum ${opts} -y remove ${*} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function YUM_GROUPREMOVE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local g
    local _main_rc=1
    local _rc
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    if [ -z "${1}" ] ; then
        ERROR "YUM_GROUPREMOVE(): Argument(s) missing!"
    else
        _main_rc=0
        for g in "${@}" ; do
            JOB_NAME="Perform YUM Group Remove [${g}]"
            LOG="$( yum ${opts} -y groupremove "${g}" 2>&1 )"
            _rc=$?
            LOG_RC ${_rc}
            [ ${_rc} -ne 0 ] && _main_rc=${_rc}
        done
    fi
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_main_rc}
}

function YUM_CLEAN () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Perform YUM Clean ALL"
    LOG="$( yum ${opts} -y clean all 2>&1 )"
    _rc=$?
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function GIT_CLONE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _url
    local _dst
    local opts="-q"
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Cloning repository:"
    if [ -z "${1}" ] ; then
        LOG="GIT_CLONE(): Argument missing!"
    else
        _url="${1}"
        _dst="${2}"
        JOB_NAME="${JOB_NAME} '${_url}'"
        [ ! -z "${_dst}" ] && JOB_NAME="${JOB_NAME} -> '${_dst}'"
        LOG="$( git clone ${opts} "${_url}" "${_dst}" 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function CHOWN_FILE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local f
    local _owner
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Changing owner"
    if [ -z "${2}" ] ; then
        LOG="CHOWN_FILE(): Argument(s) missing!"
    else
        _owner="${1}"
        f="${2}"
        JOB_NAME="${JOB_NAME} of '${f}' file -> '${_owner}'"
        if [ -e "${f}" ] ; then
            LOG="$( chown ${opts} ${_owner} "${f}" 2>&1 )"
            _rc=$?
        else
            LOG="'${f}': file does not exists."
        fi
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function CHOWN_DIR () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local d
    local _owner
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Changing owner"
    if [ -z "${2}" ] ; then
        LOG="CHOWN_DIR(): Argument(s) missing!"
    else
        _owner="${1}"
        d="${2}"
        JOB_NAME="${JOB_NAME} of '${d}' directory -> '${_owner}'"
        if [ -d "${d}" ] ; then
            LOG="$( chown -R ${opts} ${_owner} "${d}" 2>&1 )"
            _rc=$?
        else
            LOG="'${d}': Directory does not exists."
        fi
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function CHMOD_FILE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local f
    local _mode
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Changing mode"
    if [ -z "${2}" ] ; then
        LOG="CHMOD_FILE(): Argument(s) missing!"
    else
        _mode="${1}"
        f="${2}"
        JOB_NAME="${JOB_NAME} of '${f}' -> '${_mode}'"
        if [ -e "${f}" ] ; then
            LOG="$( chmod ${opts} ${_mode} "${f}" 2>&1 )"
            _rc=$?
        else
            LOG="'${f}': file does not exists."
        fi
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function CHMOD_DIR () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local d
    local _mode
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Changing mode"
    if [ -z "${2}" ] ; then
        LOG="CHMOD_DIR(): Argument(s) missing!"
    else
        _mode="${1}"
        d="${2}"
        JOB_NAME="${JOB_NAME} of '${d}' -> '${_mode}'"
        if [ -d "${d}" ] ; then
            LOG="$( chmod -R ${opts} ${_mode} "${d}" 2>&1 )"
            _rc=$?
        else
            LOG="'${d}': directory does not exists."
        fi
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function CP_FILE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _src
    local _dst
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Copying"
    if [ -z "${2}" ] ; then
        LOG="CP_FILE(): Argument(s) missing!"
    else
        _src="${1}"
        _dst="${2}"
        JOB_NAME="Copying '${_src}' -> '${_dst}'"
        if [ -e "${_src}" ] ; then
            LOG="$( cp -f ${opts} "${_src}" "${_dst}" 2>&1 )"
            _rc=$?
        else
            LOG="'${_src}': file does not exists."
        fi
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function CP_DIR () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _src
    local _dst
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Copying"
    if [ -z "${2}" ] ; then
        LOG="CP_DIR(): Argument(s) missing!"
    else
        _src="${1}"
        _dst="${2}"
        JOB_NAME="Copying '${_src}' -> '${_dst}'"
        if [ -e "${_src}" ] ; then
            LOG="$( cp -rf ${opts} "${_src}" "${_dst}" 2>&1 )"
            _rc=$?
        else
            LOG="'${_src}': file does not exists."
        fi
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function MV () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _src
    local _dst
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Moving"
    if [ -z "${2}" ] ; then
        LOG="MV(): Argument(s) missing!"
    else
        _src="${1}"
        _dst="${2}"
        JOB_NAME="Moving '${_src}' -> '${_dst}'"
        if [ -e "${_src}" ] ; then
            LOG="$( mv -f ${opts} "${_src}" "${_dst}" 2>&1 )"
            _rc=$?
        else
            LOG="'${_src}': file does not exists."
        fi
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function SVC_ENABLE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _svc
    JOB_NAME="Enabling service:"
    if [ -z "${1}" ] ; then
        LOG="SVC_ENABLE(): Argument missing!"
    else
        _svc="${1}"
        JOB_NAME="${JOB_NAME} '${_svc}'"
        LOG="$( systemctl enable ${_svc} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function SVC_DISABLE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _svc
    JOB_NAME="Disabling service:"
    if [ -z "${1}" ] ; then
        LOG="SVC_DISABLE(): Argument missing!"
    else
        _svc="${1}"
        JOB_NAME="${JOB_NAME} '${_svc}'"
        LOG="$( systemctl disable ${_svc} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function SVC_START () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _svc
    JOB_NAME="Starting service:"
    if [ -z "${1}" ] ; then
        LOG="SVC_START(): Argument missing!"
    else
        _svc="${1}"
        JOB_NAME="${JOB_NAME} '${_svc}'"
        LOG="$( systemctl start ${_svc} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function SVC_STOP () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _svc
    JOB_NAME="Stopping service:"
    if [ -z "${1}" ] ; then
        LOG="SVC_STOP(): Argument missing!"
    else
        _svc="${1}"
        JOB_NAME="${JOB_NAME} '${_svc}'"
        LOG="$( systemctl stop ${_svc} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function SVC_RESTART () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _svc
    JOB_NAME="Restarting service:"
    if [ -z "${1}" ] ; then
        LOG="SVC_RESTART(): Argument missing!"
    else
        _svc="${1}"
        JOB_NAME="${JOB_NAME} '${_svc}'"
        LOG="$( systemctl restart ${_svc} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function SYSTEMD_RELOAD () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    JOB_NAME="Reloading SystemD configuration"
    LOG="$( systemctl daemon-reload 2>&1 )"
    _rc=$?
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function MKDIR () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local d
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Creating directory:"
    if [ -z "${*}" ] ; then
        LOG="MKDIR(): Argument missing!"
    else
        d="${1}"
        _rc=0
        JOB_NAME="Creating directory: '${d}'"
        if [ ! -d "${d}" ] ; then
            LOG="$( mkdir -p ${opts} "${d}" 2>&1 )"
            _rc=$?
        else
            LOG="'${d}': directory already exists"
        fi
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function MKDIR_TMP () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=0
    if [ ! -d "${TMP_DIR}" ] ; then
        MKDIR "${TMP_DIR}"
        _rc=$?
    fi
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function WGET () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _url
    local opts="-nc -q --no-check-certificate"
    local path="-P ${TMP_DIR}/"
    [ ${DEBUG} = "yes" ] && opts="-nc -v -S --no-check-certificate"
    if [ -z "${1}" ] ; then
        LOG="WGET(): Argument(s) missing!"
    else
        if [ ! -z "${2}" ] ; then
            path="-O ${2}"
        fi
        _url="${1}"
        JOB_NAME="Fetching: '${_url}'"
#        JOB_NAME="${JOB_NAME} '${_url}'"
        LOG="$( wget ${opts} ${path} ${_url} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function TAR_ZXF () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _tar
    local opts=""
    local path="."
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Extracting:"
    if [ -z "${1}" ] ; then
        LOG="TAR_ZXF(): Argument missing!"
    else
        if [ ! -z "${2}" ] ; then
            path="${2}"
        fi
        _tar="${1}"
        JOB_NAME="${JOB_NAME} '${_tar}' -> '${path}'"
        if [ ! -e "${_tar}" ] ; then
            LOG="TAR_ZXF(): '${_tar}': file not found!"
        else
            LOG="$( tar ${opts} -zxf "${_tar}" -C "${path}" 2>&1 )"
            _rc=$?
        fi
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function UNZIP () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _zip
    local path="."
    JOB_NAME="Unzipping:"
    if [ -z "${1}" ] ; then
        LOG="UNZIP(): Argument missing!"
    else
        if [ ! -z "${2}" ] ; then
            path="${2}"
        fi
        _zip="${1}"
        JOB_NAME="${JOB_NAME} '${_zip}' -> '${path}'"
        if [ ! -e "${_zip}" ] ; then
            LOG="UNZIP(): '${_zip}': file not found!"
        else
            LOG="$( unzip -d "${path}" "${_zip}" 2>&1 )"
            _rc=$?
        fi
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function DPKG_CHECK () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _pkg
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-D1"
#    JOB_NAME="Checking status of package:"
    if [ -z "${1}" ] ; then
        LOG="DPKG_CHECK(): Argument missing!"
        LOG_RC 1
    else
        _pkg="${1}"
        JOB_NAME="${JOB_NAME} '${_pkg}'"
        LOG="$( dpkg ${opts} -s ${_pkg} 2>&1 )"
        _rc=$?
    fi
#    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function DPKG_INSTALL () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _pkg
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-D1"
    JOB_NAME="Installing:"
    if [ -z "${1}" ] ; then
        LOG="DPKG_INSTALL(): Argument missing!"
    else
        _pkg="${1}"
        JOB_NAME="${JOB_NAME} '${_pkg}'"
        if [ ! -e "${_pkg}" ] ; then
            LOG="'${_pkg}': file not found!"
        else
            LOG="$( dpkg ${opts} -i "${_pkg}" 2>&1 )"
            _rc=$?
        fi
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function DPKG_REMOVE () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _pkg
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-D1"
    JOB_NAME="Removing:"
    if [ -z "${1}" ] ; then
        LOG="DPKG_REMOVE(): Argument missing!"
    else
        _pkg="${1}"
        JOB_NAME="${JOB_NAME} '${_pkg}'"
#        LOG="$( dpkg ${opts} -r ${_pkg} 2>&1 )"
        LOG="$( dpkg ${opts} --purge ${_pkg} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}


function RPM_CHECK () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _pkg
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
#    JOB_NAME="Checking status of package:"
    if [ -z "${1}" ] ; then
        LOG="DPKG_CHECK(): Argument missing!"
        LOG_RC 1
    else
        _pkg="${1}"
        JOB_NAME="${JOB_NAME} '${_pkg}'"
        LOG="$( rpm ${opts} -q ${_pkg} 2>&1 )"
        _rc=$?
    fi
#    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}


function PIP_INSTALL () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Perform PIP Install"
    if [ -z "${1}" ] ; then
        LOG="PIP_INSTALL(): Argument(s) missing!"
    else
        JOB_NAME="${JOB_NAME} ${*}"
        LOG="$( pip install ${opts} ${*} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function PIP_UNINSTALL () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local opts=""
    [ ${DEBUG} = "yes" ] && opts="-v"
    JOB_NAME="Perform PIP Uninstall"
    if [ -z "${1}" ] ; then
        LOG="PIP_INSTALL(): Argument(s) missing!"
    else
        JOB_NAME="${JOB_NAME} ${*}"
        LOG="$( pip uninstall ${opts} -y ${*} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function MONIT_RELOAD () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    JOB_NAME="'monit' reload"
    systemctl is-active monit > /dev/null 2>&1
    if [ $? -ne 0 ] ; then
        LOG="'monit' service is not active"
    else
        LOG="$( monit reload 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function RUN_LOG () {
    [ "${DEBUG}" = "yes" ] && ENTRY
    local _rc=1
    local _cmd
    JOB_NAME="Running command:"
    if [ -z "${1}" ] ; then
        LOG="RUN_LOG(): Argument missing!"
    else
        _cmd="${1}"
        JOB_NAME="${JOB_NAME} [${_cmd}]"
        LOG="$( eval ${_cmd} 2>&1 )"
        _rc=$?
    fi
    LOG_RC ${_rc}
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}

function AUTOCONF_UPDATE () {
    local _autoconf_src_path
    local _oWD
    local _rc=1

    _oWD=$( pwd )
    while true ; do
        WGET "http://ftp.gnu.org/gnu/autoconf/autoconf-latest.tar.gz" || break
        TAR_ZXF "${TMP_DIR}/autoconf-latest.tar.gz" "${TMP_DIR}/" || break
        _autoconf_src_path=$( find "${TMP_DIR}/" -maxdepth 1 -type d -name "auto*" 2> /dev/null )
        [ -z "${_autoconf_src_path}" ] && break
        [ ! -d "${_autoconf_src_path}" ] && break
        cd "${_autoconf_src_path}"
        RUN_LOG "./configure" || break
        RUN_LOG "make" || break
        RUN_LOG "make install" || break
        _rc=0
        break
    done
    cd "${_oWD}"

    return ${_rc}
}



# ----------------------------------------------------------
# Prepare environment functions
# ----------------------------------------------------------

function _prep_env () {
    local d
    for d in \
      "Documents" \
      "Downloads" \
      "Torrents" \
      "Watch" \
      "tmp" \
      "log"
    do
        [ ! -d "/etc/skel/${d}" ] && MKDIR "/etc/skel/${d}"
    done

    # get new scripts
    WGET "${SUPPORT}/rsb-scripts/common/changeseedboxpass"
    if [ $? -eq 0 ] ; then
        if [ -f "${TMP_DIR}/changeseedboxpass" ] ; then
            MV "${TMP_DIR}/changeseedboxpass" "/usr/local/bin/changeseedboxpass"
            CHOWN_FILE root:root "/usr/local/bin/changeseedboxpass"
            CHMOD_FILE 755 "/usr/local/bin/changeseedboxpass"
        fi
    fi

    # Remove obsolete scripts
    [ -d "/opt/install_scripts" ] && RM_DIRS "/opt/install_scripts"

    # Initialize global variables
    FIRST_UID=$( grep -e '^UID_MIN\s*' "/etc/login.defs" | awk '{print $2}' )
}


function _create_std_user () {
    local _uid
    local _g
    local _rc
    local _main_rc=0
    _uid=`id -u "user" 2>/dev/null`
    if [ ! -z "${_uid}" ] ; then
        INFO "'user': account exists!"
    else
        # Add regular user's account
        case "${LSB_VENDOR}" in
          "CentOS")
              RUN_LOG "adduser -c 'RapidSeedbox.com User' -m user"
              _rc=$?
              ;;
          "Debian"|"Ubuntu")
              RUN_LOG "adduser --gecos 'RapidSeedbox.com User' --disabled-password user"
              _rc=$?
              ;;
          *)
              _rc=1
              ;;
        esac
        if [ ${_rc} -ne 0 ] ; then
            _main_rc=${_rc}
        else
            # set user's password
            RUN_LOG "echo 'user:ChangeMe' | chpasswd"
            _rc=$?
            [ ${_rc} -ne 0 ] && _main_rc=${_rc}
            # Modify new user's group membership
            for _g in sudo www-data ; do
                grep -e "^${_g}:" "/etc/group" > /dev/null 2>&1
                if [ $? -eq 0 ] ; then
                    RUN_LOG "usermod -a -G ${_g} user"
                    _rc=$?
                    [ ${_rc} -ne 0 ] && _main_rc=${_rc}
                fi
            done
        fi
    fi
    L_LOG
    return ${_main_rc}
}

function _prep_ssh () {

    local sshd_restart="no"
    local f

    # Configure sshd
    INFO "Configuring SSH service"
    for f in \
        "users-rapidseedbox-com-ca.pub" \
        "revoked_keys"
    do
        if [ ! -f "/etc/ssh/${f}" ] ; then
            WGET "${SUPPORT}/ssh/${f}" \
                 "/etc/ssh/${f}" \
              || return 1
            if [ ! -s "/etc/ssh/${f}" -a "${f}" != "revoked_keys" ] ; then
                 ERROR "'/etc/ssh/${f}': Empty file downloaded!"
                 RM_FILES "/etc/ssh/${f}"
                 return 1
            fi
        fi
    done

    # set TrustedUserCAKeys
    RUN_LOG "grep -e '^TrustedUserCAKeys' '/etc/ssh/sshd_config'"
    if [ $? -eq 0 ] ; then
        RUN_LOG "grep -e '^TrustedUserCAKeys /etc/ssh/users-rapidseedbox-com-ca.pub' '/etc/ssh/sshd_config'"
        if [ $? -ne 0 ] ; then
            RUN_LOG "sed -i -e 's#^TrustedUserCAKeys.*#TrustedUserCAKeys /etc/ssh/users-rapidseedbox-com-ca.pub#g' '/etc/ssh/sshd_config'"
            [ $? -eq 0 ] && sshd_restart="yes"
        fi
    else
        RUN_LOG "echo 'TrustedUserCAKeys /etc/ssh/users-rapidseedbox-com-ca.pub' >> '/etc/ssh/sshd_config'"
        [ $? -eq 0 ] && sshd_restart="yes"
    fi

    # set RevokedKeys
    RUN_LOG "grep -e '^RevokedKeys' '/etc/ssh/sshd_config'"
    if [ $? -eq 0 ] ; then
        RUN_LOG "grep -e '^RevokedKeys /etc/ssh/revoked_keys' '/etc/ssh/sshd_config'"
        if [ $? -ne 0 ] ; then
            RUN_LOG "sed -i -e 's#^RevokedKeys.*#RevokedKeys /etc/ssh/revoked_keys#g' '/etc/ssh/sshd_config'"
            [ $? -eq 0 ] && sshd_restart="yes"
        fi
    else
        RUN_LOG "echo 'RevokedKeys /etc/ssh/revoked_keys' >> '/etc/ssh/sshd_config'"
        [ $? -eq 0 ] && sshd_restart="yes"
    fi

    if [ "${sshd_restart}" = "yes" ] ; then
        SVC_RESTART "ssh"
    fi

    L_LOG
    return 0
}


function _prep_apache2_centos() {
    RPM_CHECK "httpd"
    [ $? -eq 0 ] && return 0
    YUM_INSTALL "httpd" || return 1
}


function _prep_apache2_deb() {
    DPKG_CHECK "apache2"
    [ $? -eq 0 ] && return 0
    APT_INSTALL "apache2" "apache2-utils" || return 1
    MKDIR "/etc/apache2/userconf-enabled" || return 1
    cat <<EOF > "/etc/apache2/sites-available/rsb.conf" 2>> "${LOGFILE}"
<VirtualHost _default_:443>
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/html
	ErrorLog \${APACHE_LOG_DIR}/error.log
	CustomLog \${APACHE_LOG_DIR}/access.log combined
	SSLEngine on
	SSLCertificateFile /etc/ssl/private/apache2.pem
	SSLCertificateKeyFile /etc/ssl/private/apache2.pem
	<FilesMatch "\.(cgi|shtml|phtml|php)$">
		SSLOptions +StdEnvVars
	</FilesMatch>
	<Directory /usr/lib/cgi-bin>
		SSLOptions +StdEnvVars
	</Directory>

        <IfModule mod_userdir.c>
                UserDir /home/*
                UserDir disabled root
                HeaderName HEADER.html
                ReadmeName README.html
                <Directory /home/*>
                        AllowOverride FileInfo AuthConfig Limit Indexes
                        Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
                        <Limit GET POST OPTIONS>
                                Require all granted
                        </Limit>
                        <LimitExcept GET POST OPTIONS>
                                Require all denied
                        </LimitExcept>
                </Directory>
        </IfModule>

        <IfModule mod_proxy.c>
                 ProxyRequests off
                 ProxyPreserveHost On
                 RewriteEngine on
                 RewriteRule ^/rutorrent$ /rutorrent/ [R]
                 ProxyPass /rutorrent http://127.0.0.1:8080/
                 ProxyPassReverse /rutorrent http://127.0.0.1:8080/
                 IncludeOptional userconf-enabled/*.conf
        </IfModule>
</VirtualHost>
EOF

    # User access file
    cat <<EOF > "/etc/skel/.htaccess" 2>> "${LOGFILE}"
AuthType Digest
AuthName "apache2"
AuthUserFile /etc/apache2/users.password
Require user ###USERNAME###
EOF
    CHMOD_FILE 640 "/etc/skel/.htaccess"

    if [ -d "/etc/monit/conf.d" ] ; then
        cat <<EOF > "/etc/monit/conf.d/apache2" 2>> "${LOGFILE}"
check process apache2 with pidfile /var/run/apache2/apache2.pid
   group apache
   start program = "/bin/systemctl restart apache2"
   stop program  = "/bin/systemctl stop apache2"
   if 5 restarts within 20 cycles then timeout
   depend apache_bin
   depend apache_rc

check file apache_bin with path /usr/sbin/apache2
   group apache
   include /etc/monit/templates/rootbin

check file apache_rc with path /etc/init.d/apache2
   group apache
   include /etc/monit/templates/rootbin
EOF
    fi

    if [ -f "/etc/fail2ban/jail.d" ] ; then
        cat <<EOF > "/etc/fail2ban/jail.d/apache.conf" 2>> "${LOGFILE}"
[apache-auth]
enabled = true

[apache-badbots]
enabled = true

[apache-noscript]
enabled = true

[apache-overflows]
enabled = true

[apache-nohome]
enabled = true

[apache-botsearch]
enabled = true

[apache-fakegooglebot]
enabled = true

[apache-modsecurity]
enabled = true

[apache-shellshock]
enabled = true
EOF
    fi

    # Enable SSL module
    RUN_LOG "a2enmod ssl"
    # Disable default site configuration
    RUN_LOG "a2dissite 000-default"
    # Define server name
    echo -ne "ServerName $( hostname )" > "/etc/apache2/conf-available/fqdn.conf"
    RUN_LOG "a2enconf fqdn.conf"
    # RSB site configuration
    RUN_LOG "a2enmod proxy"
    RUN_LOG "a2enmod proxy_http"
    RUN_LOG "a2enmod headers"
    RUN_LOG "a2enmod rewrite"
    RUN_LOG "a2enmod auth_digest"
    RUN_LOG "a2ensite rsb.conf"
    # Symlink RSB certificate
    RUN_LOG "ln -s rsb.pem /etc/ssl/private/apache2.pem"

    # Modify user group membership
    RUN_LOG "usermod -a -G www-data ${USERNAME}"

    # Allow apache group to write to user's Download directory
    RUN_LOG "setfacl -Rm g:www-data:rwX,d:g:www-data:rwX /etc/skel/Downloads"
    RUN_LOG "setfacl -Rm g:www-data:rwX,d:g:www-data:rwX ${USERHOME}/Downloads"

    # Generate selfsigned certificate
    RUN_LOG "make-ssl-cert generate-default-snakeoil --force-overwrite 2>&1"
    RUN_LOG "cat '/etc/ssl/certs/ssl-cert-snakeoil.pem' \
                 '/etc/ssl/private/ssl-cert-snakeoil.key' \
               > '/etc/ssl/private/rsb.pem'"
    CHMOD_FILE 0600 "/etc/ssl/private/rsb.pem 2>&1"
    RM_FILES "/etc/ssl/certs/ssl-cert-snakeoil.pem" \
             "/etc/ssl/private/ssl-cert-snakeoil.key"
    RUN_LOG "find /etc/ssl/certs -lname ssl-cert-snakeoil.pem -exec rm -v {} \; 2>&1"

    # Restart services which depends on certificates
    SVC_RESTART "apache2"

    return 0
}



# ----------------------------------------------------------
# Script entry/exit functions
# ----------------------------------------------------------

function SCRIPTEXIT(){

    operation1=""
    operation2=""
    timeAndDate=$( date )
    script_name=$( basename "${0}" )

    #
    # Common tasks
    case "${LSB_VENDOR}" in
      "CentOS")
          YUM_CLEAN
          ;;
      "Debian"|"Ubuntu")
          APT_CLEAN
          ;;
    esac
    [ -e "${tmp}" ] && RM_FILES  "${tmp}"
    RM_DIRS   "${TMP_DIR}"
    RM_FILES  "./functions.sh" "/var/lock/whmcs_client_installers.status"

    case ${script_name} in
    install_*)
        operation1="installing"
        operation2="Installation"
        ;;
    uninstall_*)
        operation1="uninstalling"
        operation2="Uninstallation"
        ;;
    esac

    cd ~/
#    ./slackpost "rsb-installers" "${timeAndDate} :: finished ${operation1} '${APP}' for ${IP} - exit code: [${main_rc}]" > /dev/null 2>&1

    if [ ! -z "${main_rc}" ] ; then
        echo -e "\n\n" >> "${LOGFILE}"
        L_LOG
        JOB_NAME="${operation2} status for '${APP}'"
        LOG=""
        LOG_RC ${main_rc}
    fi

    echo -e "\n\n" >> "${LOGFILE}"
    L_LOG
    echo "${FUNCNAME}: ${script_name}" >> "${LOGFILE}"
    L_LOG
    echo -e "\n\n\n\n\n\n" >> "${LOGFILE}"

    echo "${main_rc}"
    >&2 echo "${main_rc}"
    exit ${main_rc}

}

function VALIDATE_USER() {
    USERUID=$( id -u "${USERNAME}" 2>/dev/null )
    if [ -z "${USERUID}" ] ; then
        ERROR "'${USERNAME}': account not found !"
        ERROR "Can not continue. Exiting..."
        L_LOG
        main_rc=1
        SCRIPTEXIT
    fi
#    USERHOME="/home/${USERNAME}"
}


function SCRIPTENTRY(){

    operation1=""
    timeAndDate=$( date )
    script_name=$( basename "${0}" )

    [ -e "${LOGFILE}" ] && echo -e "\n\n\n\n" >> "${LOGFILE}"
    L_LOG
    echo "${FUNCNAME}: ${script_name}" >> "${LOGFILE}"
    L_LOG

    case ${script_name} in
    install_*)
        operation1="installing"
        ;;
    uninstall_*)
        operation1="uninstalling"
        ;;
    esac

#    ./slackpost "rsb-installers" "${timeAndDate} :: started ${operation1} '${APP}' for ${IP}" > /dev/null 2>&1

    echo "${script_name}|$(date -u '+%s')" > "/var/lock/whmcs_client_installers.status"

    #
    # Perform common installation tasks
    #

    MKDIR_TMP
    if [ $? -ne 0 ] ; then
        main_rc=1
        SCRIPTEXIT
    fi

    RUN_LOG "which lsb_release 2>&1"
    if [ $? -ne 0 ] ; then
        ERROR "Can not continue, sorry!"
        main_rc=1
        SCRIPTEXIT
    fi

    LSB_VENDOR=$( lsb_release -si 2>&1 )
    if [ $? -ne 0 ] ; then
        ERROR "Error getting LSB Release information!"
        main_rc=1
        SCRIPTEXIT
    else
        INFO "LSB Vendor: ${LSB_VENDOR}"
    fi
    LSB_VENDOR_L=$( echo "${LSB_VENDOR}" | tr '[:upper:]' '[:lower:]' )
    LSB_RELEASE=$( lsb_release -sr | awk -F'.' '{print $1}' )
    [ "${LSB_VENDOR}" = "CentOS" ] && LSB_RELEASE=$( echo "${LSB_RELEASE}" | awk -F'.' '{print $1}' )
    LSB_CODENAME=$( lsb_release -sc )
    LSB_DESCRIPTION=$( lsb_release -sd )
    L_LOG

    case "${LSB_VENDOR}" in
      "CentOS")
          YUM_INSTALL \
              "bash-completion" \
              "mc" \
              "monit" \
              "cronie" \
              "logrotate" \
              "mlocate" \
              "less"
          if [ $? -ne 0 ] ; then
              ERROR "Error(s) installing essential packages for '${LSB_VENDOR}' ${LSB_RELEASE} !"
              L_LOG
              main_rc=1
              SCRIPTEXIT
          fi
          # Update distribution
          if [ "${DIST_UPGRADE_ENABLED}" = "yes" ] ; then
              YUM_DIST_UPGRADE
          fi

          # Prepare environment
          _prep_env
          _create_std_user
          _prep_ssh

          # Add extra repositories
          if [ "${LSB_RELEASE}" = "6" ] ; then
              RUN_LOG "rpm -Uvh http://li.nux.ro/download/nux/dextop/el6/x86_64/nux-dextop-release-0-2.el6.nux.noarch.rpm 2>&1"
          elif [ "${LSB_RELEASE}" = "7" ] ; then
              RUN_LOG "rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm 2>&1"
          fi

          ;;
      "Debian"|"Ubuntu")
          JOB_NAME="Regenerating 'en' locale"
          LOG="$( locale-gen en > /dev/null 2>&1 )"
          LOG_RC $?

          APT_UPDATE

          case "${LSB_VENDOR}" in
             "Debian")
                 DEB_MIRROR="http://ftp.nl.debian.org/debian"
#                 DEB_MIRROR="http://httpredir.debian.org/debian"
                 cat <<-EOF > "${rootfs}/etc/apt/sources.list"
		deb ${DEB_MIRROR} ${LSB_CODENAME} main contrib non-free
		deb-src ${DEB_MIRROR} ${LSB_CODENAME} main contrib non-free
		deb ${DEB_MIRROR} ${LSB_CODENAME}-updates main contrib non-free
		deb-src ${DEB_MIRROR} ${LSB_CODENAME}-updates main contrib non-free
		deb http://security.debian.org/ ${LSB_CODENAME}/updates main contrib non-free
		deb-src http://security.debian.org/ ${LSB_CODENAME}/updates main contrib non-free
		deb ${DEB_MIRROR} ${LSB_CODENAME}-backports main contrib non-free
		deb-src ${DEB_MIRROR} ${LSB_CODENAME}-backports main contrib non-free
		EOF
                 ;;
             "Ubuntu")
                 case "${LSB_CODENAME}" in
                   "yakkety")
                       cat <<-EOF > "/etc/apt/sources.list"
			deb http://archive.ubuntu.com/ubuntu ${LSB_CODENAME} main restricted universe
			deb http://archive.ubuntu.com/ubuntu ${LSB_CODENAME}-updates main restricted universe
			deb http://security.ubuntu.com/ubuntu ${LSB_CODENAME}-backports main restricted universe multiverse
			deb http://security.ubuntu.com/ubuntu ${LSB_CODENAME}-security main restricted universe multiverse
			EOF
                      ;;
                   *)
                       cat <<-EOF > "/etc/apt/sources.list"
			deb mirror://mirrors.ubuntu.com/mirrors.txt ${LSB_CODENAME} main restricted universe multiverse
			deb mirror://mirrors.ubuntu.com/mirrors.txt ${LSB_CODENAME}-updates main restricted universe multiverse
			deb mirror://mirrors.ubuntu.com/mirrors.txt ${LSB_CODENAME}-backports main restricted universe multiverse
			deb mirror://mirrors.ubuntu.com/mirrors.txt ${LSB_CODENAME}-security main restricted universe multiverse
			EOF
                      ;;
                 esac
                 ;;
          esac

          # Prepare environment
          _prep_env
          _create_std_user
          _prep_ssh

          # Tweaks :)
          case "${LSB_CODENAME}" in
             "wily")
                 INFO "Workaround for '${LSB_CODENAME}':"
                 INFO "    For details see:   https://bugs.launchpad.net/ubuntu/+source/apt/+bug/1479045"
                 RM_DIRS "/var/lib/apt/lists/partial"
                 ;;
            *)
                 ;;
          esac

          APT_UPDATE

          case "${LSB_VENDOR}" in
             "Debian")
                 APT_INSTALL \
                      "bash-completion" \
                      "mlocate" \
                      "man-db" \
                      "mc" \
                      "monit" \
                      "cron" \
                      "logrotate" \
                      "less" \
                      "diffutils" \
                      "apt-transport-https" \
                      "software-properties-common"
                 ;;
             "Ubuntu")
                 APT_INSTALL \
                      "bash-completion" \
                      "mlocate" \
                      "man-db" \
                      "mc" \
                      "monit" \
                      "cron" \
                      "logrotate" \
                      "less" \
                      "diffutils" \
                      "ppa-purge" \
                      "software-properties-common" \
                      "python-software-properties"
                 if [ $? -ne 0 ] ; then
                     ERROR "Error(s) installing essential packages for '${LSB_VENDOR}' ${LSB_RELEASE} !"
                     L_LOG
                     main_rc=1
                     SCRIPTEXIT
                 fi
                 case "${LSB_CODENAME}" in
                   "wily"|"vivid"|"xenial")
                       APT_INSTALL \
                          "apt-transport-https" \
                          "debconf-utils"
                       ;;
                   "yakkety")
                       APT_INSTALL "debconf"
                       ;;
                 esac
                 if [ $? -ne 0 ] ; then
                     ERROR "Error(s) installing essential packages for '${LSB_VENDOR}' ${LSB_RELEASE} !"
                     L_LOG
                     main_rc=1
                     SCRIPTEXIT
                 fi
                 ;;
             *)
                 ;;
          esac

          # Tweaks for various stuff :((((
          ADD_APT_KEY_URL "https://linux-packages.resilio.com/resilio-sync/key.asc"

          # Update distribution
          if [ "${DIST_UPGRADE_ENABLED}" = "yes" ] ; then
              APT_DIST_UPGRADE
          fi
          ;;
      *)
          ERROR "Unsupported distribution: '${LSB_VENDOR}'"
          L_LOG
          main_rc=1
          SCRIPTEXIT
          ;;
    esac

    # Check if Apache2 is needed
    if [ "${USE_APACHE2}" = "yes" ] ; then
        if [ "${LSB_VENDOR}" = "Debian" -o "${LSB_VENDOR}" = "Ubuntu" ] ; then
            _prep_apache2_deb
        elif [ "${LSB_VENDOR}" = "CentOS" ] ; then
            _prep_apache2_centos
        fi
    fi

    # Update application
    INFO "Checking if 'install-app' update available ..."
    L_LOG
    WGET "${SUPPORT}/rsb-scripts/common/install-app"
    if [ $? -eq 0 ] ; then
        if [ -s "${TMP_DIR}/install-app" ] ; then
            RUN_LOG "diff '${TMP_DIR}/install-app' '/usr/local/bin/install-app'"
            if [ $? -ne 0 ] ; then
                INFO "Updating 'install-app' ..."
                MV "${TMP_DIR}/install-app" "/usr/local/bin/install-app"
                CHOWN_FILE root:root "/usr/local/bin/install-app"
                CHMOD_FILE 755 "/usr/local/bin/install-app"
            else
                INFO "'install-app' is up to date."
            fi
        fi
    fi
    L_LOG
}




# ----------------------------------------------------------
# Application installation checks functions
# ----------------------------------------------------------

# Check if it safe to install/uninstall application.
# Application name is passed via $1 or determined by $APP content.
# Returns:  0     - if it is safe to install/uninstall application.
#           1     - if required parameter(s) missing.
#           111   - if app is installed and installation requested.
#           112   - if app is not installed and uninstallation was requested.
# 
function CHECK_APP_DEB () {
    [ "${DEBUG}" = "yes" ] && ENTRY

    local app
    local o_app
    local script_name
    local op
    local op_RC
    local _pkg
    local _rc

    script_name=`basename "${0}"`
    LOG=""
    _rc=0

    case ${script_name} in
    install_*)
        op="install"
        ;;
    uninstall_*)
        op="uninstall"
        ;;
    *)
        op="${2}"
        ;;
    esac

    o_app="${1}"
    [ -z "${o_app}" ] && o_app="${APP}"
    if [ -z "${o_app}" ] ; then
        LOG "CHECK_APP (): Argument(s) missing"
        _rc=1
        LOG_RC ${_rc}
        return ${_rc}
    fi

    app=`echo "${o_app}" | tr '[:upper:]' '[:lower:]'`

    case ${app} in

    # Check dpkg package status
    ampache|aria2|brave|dropbox|filezilla|firefox|handbrake|midori|openbox|pidgin|pyload|qupzilla|syncthing|uget|vlc|xrdp|youtube-dl)
        _rc=0
        DPKG_CHECK "${app}"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;

    # Check ${APP_DIRECTORY} existence
    btsync|couchpotato|"deluge (latest)"|"deluge 1.3.5"|"deluge 1.3.6"|"deluge 1.3.7"|"deluge 1.3.8"|"deluge 1.3.9"|"deluge 1.3.10"|"deluge 1.3.11"|"deluge 1.3.12"|elfinder|flexget|headphones|nzbget|plexpy|"plex trakt scrobbler"|pydio|sabnzbd|sickbeard|sickrage|utorrent|vnc)
        _rc=0
        if [ -z "${APP_DIRECTORY}" ] ; then
            LOG="CHECK_APP(): \$APP_DIRECTORY is not defined!"
           _rc=1
        else
            if [ -d "${APP_DIRECTORY}" ] ; then
                [ "${op}" = "install" ]   && _rc=111
            else
                [ "${op}" = "uninstall" ] && _rc=112
            fi
        fi
        ;;

    # Check "non-standard" apps :)
    7zip)
        _rc=0
        DPKG_CHECK "p7zip-full"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "cinnamon desktop")
        _rc=0
        DPKG_CHECK "cinnamon"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "emby server")
        _rc=0
        DPKG_CHECK "emby-server"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "fixes for cuteftp users")
        _rc=0
        ;;
    "fixes for kodi sftp connection")
        _rc=0
        ;;
    "gnome desktop")
        _rc=0
        DPKG_CHECK "ubuntu-desktop"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "google chrome")
        _rc=0
        DPKG_CHECK "google-chrome-stable"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "icewm desktop")
        _rc=0
        DPKG_CHECK "icewm"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    jdownloader)
        _rc=0
        DPKG_CHECK "jdownloader-installer"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "kde desktop")
        _rc=0
        DPKG_CHECK "kubuntu-desktop"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "lxde desktop")
        _rc=0
        DPKG_CHECK "lxde"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "mate desktop")
        _rc=0
        DPKG_CHECK "mate-desktop-environment"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "openbox desktop")
        _rc=0
        DPKG_CHECK "openbox"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    opera)
        _rc=0
        DPKG_CHECK "opera-stable"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    plex)
        _rc=0
        DPKG_CHECK "plexmediaserver"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "resilio sync")
        _rc=0
        if [ -z "${APP_DIRECTORY}" ] ; then
            LOG="CHECK_APP(): \$APP_DIRECTORY is not defined!"
           _rc=1
        else
            if [ -d "${APP_DIRECTORY}" ] ; then
                [ "${op}" = "install" ]   && _rc=111
            else
                [ "${op}" = "uninstall" ] && _rc=112
            fi
        fi
        ;;
    "rutorrent"|"rutorrent (rtorrent 0.9.2)"|"rutorrent (rtorrent 0.9.3)"|"rutorrent (rtorrent 0.9.4)"|"rutorrent (rtorrent 0.9.6)")
        _rc=0
        if [ -z "${APP_DIRECTORY}" ] ; then
            LOG="CHECK_APP(): \$APP_DIRECTORY is not defined!"
           _rc=1
        else
            if [ -d "${APP_DIRECTORY}/conf/users/${USERNAME}" ] ; then
                [ "${op}" = "install" ]   && _rc=111
            else
                [ "${op}" = "uninstall" ] && _rc=112
            fi
        fi
        ;;
    sonarr)
        _rc=0
        DPKG_CHECK "nzbdrone"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    thunderbird)    
        case "${LSB_VENDOR}" in
          "Debian")
              _pkg="icedove"
              ;;
          "Ubuntu")
              _pkg="thunderbird"
              ;;
        esac
        _rc=0
        DPKG_CHECK "${_pkg}"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "tor browser")
        _rc=0
        DPKG_CHECK "tor-browser"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "utorrent 2.2.1 (wine)")
        _rc=0
        test -e "${APP_DIRECTORY}/utorrent_2.2.1_build_25302.exe"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    vivaldi)
        _rc=0
        DPKG_CHECK "vivaldi-stable"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    wine)
        _rc=0
        case "${LSB_VENDOR}" in
          "Debian")
              DPKG_CHECK "wine"
              if [ $? -eq 0 ] ; then
                  [ "${op}" = "install" ]   && _rc=111
              else
                  [ "${op}" = "uninstall" ] && _rc=112
              fi
              ;;
          "Ubuntu")
              DPKG_CHECK "wine1.8"
              if [ $? -eq 0 ] ; then
                  [ "${op}" = "install" ]   && _rc=111
              else
                  [ "${op}" = "uninstall" ] && _rc=112
              fi
              ;;
        esac
        ;;
    "x2go server")
        _rc=0
        DPKG_CHECK "x2goserver"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "xfce desktop")
        _rc=0
        DPKG_CHECK "xubuntu-desktop"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "yandex browser")
        _rc=0
        DPKG_CHECK "yandex-browser-beta"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;

    *)
        LOG="CHECK_APP (): No check procedure defined for: '${o_app}'"
        _rc=1
        ;;
    esac

    JOB_NAME="Application installation status"
#    if [ -z "${LOG}" ] ; then
        [ ${_rc} -eq 111 ] && LOG="CHECK_APP(): '${o_app}' is already installed"
        [ ${_rc} -eq 112 ] && LOG="CHECK_APP(): '${o_app}' is not installed"
        [ ${_rc} -eq 1 ]   && LOG="CHECK_APP(): '${o_app}': Critical error!"
        [ ${_rc} -eq 0 ]   && LOG="CHECK_APP(): '${o_app}': OK to ${op}"
        LOG_RC ${_rc}
#    fi

    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}


# Check if it safe to install/uninstall application.
# Application name is passed via $1 or determined by $APP content.
# Returns:  0     - if it is safe to install/uninstall application.
#           1     - if required parameter(s) missing.
#           111   - if app is installed and installation requested.
#           112   - if app is not installed and uninstallation was requested.
# 
function CHECK_APP_YUM () {
    [ "${DEBUG}" = "yes" ] && ENTRY

    local app
    local o_app
    local script_name
    local op
    local op_RC
    local _pkg
    local _rc

    script_name=$( basename "${0}" )
    LOG=""
    _rc=0

    case ${script_name} in
    install_*)
        op="install"
        ;;
    uninstall_*)
        op="uninstall"
        ;;
    *)
        op="${2}"
        ;;
    esac

    o_app="${1}"
    [ -z "${o_app}" ] && o_app="${APP}"
    if [ -z "${o_app}" ] ; then
        LOG "CHECK_APP_YUM (): Argument(s) missing"
        _rc=1
        LOG_RC ${_rc}
        return ${_rc}
    fi

    app=$( echo "${o_app}" | tr '[:upper:]' '[:lower:]' )

    case ${app} in

#    # Check dpkg package status
#    ampache|aria2|brave|dropbox|filezilla|firefox|handbrake|midori|openbox|pidgin|pyload|qupzilla|syncthing|uget|vlc|xrdp|youtube-dl)
#        _rc=0
#        DPKG_CHECK "${app}"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#
#    # Check ${APP_DIRECTORY} existence
#    btsync|couchpotato|"deluge (latest)"|"deluge 1.3.5"|"deluge 1.3.6"|"deluge 1.3.7"|"deluge 1.3.8"|"deluge 1.3.9"|"deluge 1.3.10"|"deluge 1.3.11"|"deluge 1.3.12"|elfinder|flexget|headphones|nzbget|plexpy|"plex trakt scrobbler"|pydio|sabnzbd|sickbeard|sickrage|utorrent|vnc)
#        _rc=0
#        if [ -z "${APP_DIRECTORY}" ] ; then
#            LOG="CHECK_APP(): \$APP_DIRECTORY is not defined!"
#           _rc=1
#        else
#            if [ -d "${APP_DIRECTORY}" ] ; then
#                [ "${op}" = "install" ]   && _rc=111
#            else
#                [ "${op}" = "uninstall" ] && _rc=112
#            fi
#        fi
#        ;;
#
    # Check "non-standard" apps :)
    "7zip")
        _rc=0
        RPM_CHECK "p7zip"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
#    "cinnamon desktop")
#        _rc=0
#        DPKG_CHECK "cinnamon"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    "emby server")
#        _rc=0
#        DPKG_CHECK "emby-server"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    "fixes for cuteftp users")
#        _rc=0
#        ;;
#    "fixes for kodi sftp connection")
#        _rc=0
#        ;;
#    "gnome desktop")
#        _rc=0
#        DPKG_CHECK "ubuntu-desktop"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    "google chrome")
#        _rc=0
#        DPKG_CHECK "google-chrome-stable"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    "icewm desktop")
#        _rc=0
#        DPKG_CHECK "icewm"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    jdownloader)
#        _rc=0
#        DPKG_CHECK "jdownloader-installer"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    "kde desktop")
#        _rc=0
#        DPKG_CHECK "kubuntu-desktop"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    "lxde desktop")
#        _rc=0
#        DPKG_CHECK "lxde"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    "mate desktop")
#        _rc=0
#        DPKG_CHECK "mate-desktop-environment"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    "openbox desktop")
#        _rc=0
#        DPKG_CHECK "openbox"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    opera)
#        _rc=0
#        DPKG_CHECK "opera-stable"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    plex)
#        _rc=0
#        DPKG_CHECK "plexmediaserver"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    "resilio sync")
#        _rc=0
#        if [ -z "${APP_DIRECTORY}" ] ; then
#            LOG="CHECK_APP(): \$APP_DIRECTORY is not defined!"
#           _rc=1
#        else
#            if [ -d "${APP_DIRECTORY}" ] ; then
#                [ "${op}" = "install" ]   && _rc=111
#            else
#                [ "${op}" = "uninstall" ] && _rc=112
#            fi
#        fi
#        ;;
    "rutorrent"|"rutorrent (rtorrent 0.9.2)"|"rutorrent (rtorrent 0.9.3)"|"rutorrent (rtorrent 0.9.4)"|"rutorrent (rtorrent 0.9.6)")
        _rc=0
        if [ -z "${APP_DIRECTORY}" ] ; then
            LOG="CHECK_APP(): \$APP_DIRECTORY is not defined!"
           _rc=1
        else
            if [ -d "${APP_DIRECTORY}/conf/users/${USERNAME}" ] ; then
                [ "${op}" = "install" ]   && _rc=111
            else
                [ "${op}" = "uninstall" ] && _rc=112
            fi
        fi
        ;;
#    sonarr)
#        _rc=0
#        DPKG_CHECK "nzbdrone"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    thunderbird)    
#        case "${LSB_VENDOR}" in
#          "Debian")
#              _pkg="icedove"
#              ;;
#          "Ubuntu")
#              _pkg="thunderbird"
#              ;;
#        esac
#        _rc=0
#        DPKG_CHECK "${_pkg}"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    "tor browser")
#        _rc=0
#        DPKG_CHECK "tor-browser"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    "utorrent 2.2.1 (wine)")
#        _rc=0
#        test -e "${APP_DIRECTORY}/utorrent_2.2.1_build_25302.exe"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    vivaldi)
#        _rc=0
#        DPKG_CHECK "vivaldi-stable"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#    wine)
#        _rc=0
#        case "${LSB_VENDOR}" in
#          "Debian")
#              DPKG_CHECK "wine"
#              if [ $? -eq 0 ] ; then
#                  [ "${op}" = "install" ]   && _rc=111
#              else
#                  [ "${op}" = "uninstall" ] && _rc=112
#              fi
#              ;;
#          "Ubuntu")
#              DPKG_CHECK "wine1.8"
#              if [ $? -eq 0 ] ; then
#                  [ "${op}" = "install" ]   && _rc=111
#              else
#                  [ "${op}" = "uninstall" ] && _rc=112
#              fi
#              ;;
#        esac
#        ;;
    "x2go server")
        _rc=0
        RPM_CHECK "x2goserver"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
    "xfce desktop")
        _rc=0
        RPM_CHECK "xfdesktop"
        if [ $? -eq 0 ] ; then
            [ "${op}" = "install" ]   && _rc=111
        else
            [ "${op}" = "uninstall" ] && _rc=112
        fi
        ;;
#    "yandex browser")
#        _rc=0
#        DPKG_CHECK "yandex-browser-beta"
#        if [ $? -eq 0 ] ; then
#            [ "${op}" = "install" ]   && _rc=111
#        else
#            [ "${op}" = "uninstall" ] && _rc=112
#        fi
#        ;;
#
    *)
        LOG="CHECK_APP (): No check procedure defined for: '${o_app}'"
        _rc=1
        ;;
    esac

    JOB_NAME="Application installation status"
#    if [ -z "${LOG}" ] ; then
        [ ${_rc} -eq 111 ] && LOG="CHECK_APP(): '${o_app}' is already installed"
        [ ${_rc} -eq 112 ] && LOG="CHECK_APP(): '${o_app}' is not installed"
        [ ${_rc} -eq 1 ]   && LOG="CHECK_APP(): '${o_app}': Critical error!"
        [ ${_rc} -eq 0 ]   && LOG="CHECK_APP(): '${o_app}': OK to ${op}"
        LOG_RC ${_rc}
#    fi

    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}


function CHECK_APP () {
    local _rc
    [ "${DEBUG}" = "yes" ] && ENTRY
    case "${LSB_VENDOR}" in
      "CentOS")
          CHECK_APP_YUM "${1}"
          _rc=$?
          ;;
      "Debian"|"Ubuntu")
          CHECK_APP_DEB "${1}"
          _rc=$?
          ;;
    esac
    [ "${DEBUG}" = "yes" ] && RETURN
    return ${_rc}
}
