#!/bin/bash
# info: list system services
# options: [FORMAT]
#
# The function for obtaining the list of configured system services.


#----------------------------------------------------------#
#                    Variable&Function                     #
#----------------------------------------------------------#

# Argument definition
format=${1-shell}

# Includes
source $VESTA/func/main.sh
source $VESTA/conf/vesta.conf

export PATH=$PATH:/sbin

debug=0

# JSON list function
json_list() {
    IFS=$'\n'
    i=1
    objects=$(echo -e "$data" |grep NAME |wc -l)
    echo "{"
    while read str; do
        eval $str
        echo -n '    "'$NAME'": {
        "SYSTEM": "'$SYSTEM'",
        "STATE": "'$STATE'",
        "CPU": "'$CPU'",
        "MEM": "'$MEM'",
        "RTIME": "'$RTIME'"
    }'
        if [ "$i" -lt "$objects" ]; then
            echo ','
        else
            echo
        fi
        ((i++))
    done < <(echo -e "$data" |grep NAME)
    echo '}'
}

# SHELL list function
shell_list() {
    IFS=$'\n'
    echo "NAME   STATE   CPU   MEM   UPTIME"
    echo "----   -----   ---   ---   ------"
    while read str; do
        eval $str
        if [ "$STATE" = "stopped" ]; then
            STATE='off'
        fi
        echo "$NAME $STATE $CPU $MEM $RTIME"
    done < <(echo -e "$data" |grep NAME)
}

# PLAIN list function
plain_list() {
    IFS=$'\n'
    while read str; do
        eval $str
        echo -e "$NAME\t$SYSTEM\t$STATE\t$CPU\t$MEM\t$RTIME"
    done < <(echo -e "$data" |grep NAME)
}

# CSV list function
csv_list() {
    IFS=$'\n'
    echo "NAME,SYSTEM,STATE,CPU,MEM,RTIME"
    while read str; do
        eval $str
        echo "$NAME,\"$SYSTEM\",$STATE,$CPU,$MEM,$RTIME"
    done < <(echo -e "$data" |grep NAME)
}

# Get service state function
get_srv_state() {
    srv=$1
    name=${2-$1}
    procfolder=$4
    procfile=$5
    state='running'
    mem=0
    cpu=0
    rtime="0"

    if [ $debug -eq 1 ]; then
        echo "---------------------"
        echo "$srv = $name"
    fi
    # Searching related pids
    if [ -z $3 ]; then
        pids=$(pidof $name |tr ' ' '|')
    else
        pids=$(pidof -x $name |tr ' ' '|')
    fi
    if [ -z "$pids" ] && [ "$name" != 'nginx' ]; then
        pids=$(pgrep $name |tr '\n' '|')
    fi
    if [ "$name" = 'elasticsearch' ]; then
        pids=$(ps -Af | grep 'elasticsearch' | grep -v 'grep' | awk '{print $2}' | tr '\n' '|')
    fi
    if [ "$name" = 'vesta-nginx' ]; then
        pids=$(ps -Af | grep 'vesta/nginx' | grep -v 'grep' | awk '{print $2}' | tr '\n' '|')
    fi
    if [ "$name" = 'vesta-php' ]; then
        pids=$(ps -Af | grep 'vesta/php' | grep -v 'grep' | awk '{print $2}' | tr '\n' '|')
    fi
    if [ $debug -eq 1 ]; then
        echo "pids = $pids"
    fi

    # Checking pid
    if [ -n "$pids" ]; then
        pid=$(echo "$pids" |cut -f 1 -d '|')
        pids=${pids%|}
        pids=$(egrep "$pids" $tmp_file)

        # Calculating CPU usage
        cpu=$(echo "$pids" |awk '{ sum += $2} END {print sum}')

        # Calculating memory usage
        mem=$(echo "$pids" |awk '{sum += $3} END {print sum/1024 }')
        mem=$(echo "${mem%%.*}")

        # Searching pid file
        pid_file=''
        if [ ! -z "$procfolder" ]; then
            if [ -f "/var/run/$procfolder/$srv.pid" ]; then
                pid_file="/var/run/$procfolder/$srv.pid"
            fi
        fi
        if [ -z "$pid_file" ] && [ ! -z "$procfolder" ] && [ ! -z "$procfile" ]; then
            if [ -f "/var/run/$procfolder/$procfile.pid" ]; then
                pid_file="/var/run/$procfolder/$procfile.pid"
            fi
        fi
        if [ -z "$pid_file" ] && [ -z "$procfolder" ] && [ ! -z "$procfile" ]; then
            if [ -f "/var/run/$procfile.pid" ]; then
                pid_file="/var/run/$procfile.pid"
            fi
        fi
        if [ -z "$pid_file" ] && [ -e "/var/run/$srv.pid" ]; then
            pid_file="/var/run/$srv.pid"
        fi
        if [ -z "$pid_file" ] && [ -e "/var/run/$srv/$srv.pid" ]; then
            pid_file="/var/run/$srv/$srv.pid"
        fi
        if [ -z "$pid_file" ] && [ -e "/var/run/$name/$name.pid" ]; then
            pid_file="/var/run/$name/$name.pid"
        fi
        if [ -z "$pid_file" ] && [ -f "/var/run/$name.pid" ]; then
            pid_file="/var/run/$name.pid"
        fi
        if [ -z "$pid_file" ] && [ -e "/proc/$pid" ]; then
            pid_file="/proc/$pid"
        fi

        if [ $debug -eq 1 ]; then
            echo "$srv = $name = $pid_file"
        fi
        # Calculating uptime
        if [ -n "$pid_file" ]; then
            mtime=$(stat -c "%Y" $pid_file)
            rtime=$((ctime - mtime))
            rtime=$((rtime  / 60))
        else
            rtime=0
        fi
        if [ "$pid_file" = "/proc/$pid" ]; then
            if [ $debug -eq 1 ]; then
                echo "getting pid lifetime via ps"
            fi            
            rtime=$(ps -p $pid -o etimes | tail -n 1 | awk '{print $1}')
            rtime=$((rtime  / 60))
        fi
    else
        state='stopped'
        mem=0
        cpu=0
        rtime="0"
    fi
}


#----------------------------------------------------------#
#                       Action                             #
#----------------------------------------------------------#

# Saving current proccess list
tmp_file=$(mktemp)
ps -eo pid,pcpu,size > $tmp_file

# Checking current time
ctime=$(date +%s)

# Checking WEB system
if [ ! -z "$WEB_SYSTEM" ] && [ "$WEB_SYSTEM" != 'remote' ]; then
    get_srv_state $WEB_SYSTEM
    data="NAME='$WEB_SYSTEM' SYSTEM='web server' STATE='$state' CPU='$cpu'"
    data="$data MEM='$mem' RTIME='$rtime'"
fi

# Checking WEB Proxy
if [ ! -z "$PROXY_SYSTEM" ] && [ "$PROXY_SYSTEM" != 'remote' ]; then
    get_srv_state $PROXY_SYSTEM
    data="$data\nNAME='$PROXY_SYSTEM' SYSTEM='reverse proxy' STATE='$state'"
    data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi

# Checking WEB Backend
if [ "$WEB_BACKEND" != 'remote' ]; then
    php_versions=$(ls /usr/sbin/php*fpm* | cut -d'/' -f4 | sed 's|php-fpm||')
    for version in $php_versions; do
        proc_name="php-fpm${version}"
        service_name="php${version}-fpm"
        get_srv_state "$service_name" "$proc_name" '' 'php'
        data="$data\nNAME='$service_name' SYSTEM='backend server' STATE='$state'"
        data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
    done
fi

# DNS
service=$DNS_SYSTEM
if [ ! -z "$service" ] && [ "$service" != 'remote' ]; then
    proc_name='named'
    get_srv_state $service $proc_name
    data="$data\nNAME='$service' SYSTEM='dns server' STATE='$state'"
    data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi

# Checking MAIL system
if [ ! -z "$MAIL_SYSTEM" ] && [ "$MAIL_SYSTEM" != 'remote' ]; then
    if [ "$MAIL_SYSTEM" = "exim4" ]; then
        get_srv_state "$MAIL_SYSTEM" "$MAIL_SYSTEM" '' 'exim4' 'exim'
    else
        get_srv_state $MAIL_SYSTEM
    fi
    data="$data\nNAME='$MAIL_SYSTEM' SYSTEM='mail server' STATE='$state'"
    data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi

# Checking MAIL IMAP
if [ ! -z "$IMAP_SYSTEM" ] && [ "$IMAP_SYSTEM" != 'remote' ]; then
    if [ "$IMAP_SYSTEM" = "dovecot" ]; then
        get_srv_state "$IMAP_SYSTEM" "$IMAP_SYSTEM" '' 'dovecot' 'master'
    else
        get_srv_state $IMAP_SYSTEM
    fi
    data="$data\nNAME='$IMAP_SYSTEM' SYSTEM='pop/imap server' STATE='$state'"
    data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi

# Checking MAIL ANTIVIRUS
if [ ! -z "$ANTIVIRUS_SYSTEM" ] && [ "$ANTIVIRUS_SYSTEM" != 'remote' ]; then
    if [ -d "/etc/sysconfig" ]; then
        if [ "$ANTIVIRUS_SYSTEM" == 'clamav' ];then
            ANTIVIRUS_SYSTEM='clamd'
        fi
        get_srv_state $ANTIVIRUS_SYSTEM
    else
        if [ "$ANTIVIRUS_SYSTEM" == 'clamav-daemon' ];then
            proc_name='clamd'
        fi
        get_srv_state $ANTIVIRUS_SYSTEM $proc_name '' 'clamav' 'clamd'
    fi
    data="$data\nNAME='$ANTIVIRUS_SYSTEM' SYSTEM='email antivirus'"
    data="$data STATE='$state' CPU='$cpu' MEM='$mem' RTIME='$rtime'"
    proc_name=''
    if [ ! -d "/etc/sysconfig" ]; then
        if [ "$ANTIVIRUS_SYSTEM" == 'clamav-daemon' ];then
            get_srv_state "clamav-freshclam" "freshclam"
            data="$data\nNAME='clamav-freshclam' SYSTEM='email antivirus updater'"
            data="$data STATE='$state' CPU='$cpu' MEM='$mem' RTIME='$rtime'"
            proc_name=''
        fi
    fi
fi

# Checking MAIL ANTISPAM
if [ ! -z "$ANTISPAM_SYSTEM" ] && [ "$ANTISPAM_SYSTEM" != 'remote' ]; then
    get_srv_state $ANTISPAM_SYSTEM spamd
    data="$data\nNAME='$ANTISPAM_SYSTEM' SYSTEM='email antispam'"
    data="$data STATE='$state' CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi

# Checking DB system
if [ ! -z "$DB_SYSTEM" ] && [ "$DB_SYSTEM" != 'remote' ]; then
    for db in ${DB_SYSTEM//,/ }; do
        proc_name=''
        service="$db"
        if [ "$service" = 'mysql' ]; then
            proc_name='mysqld'
            release=$(cat /etc/debian_version | tr "." "\n" | head -n1)
            if [ "$release" -gt 10 ] && [ ! -f "/etc/apt/sources.list.d/mysql.list" ]; then
                service='mariadb'
                proc_name='mariadbd'
            fi
            if [ -f "/etc/apt/sources.list.d/mariadb.list" ]; then
                service='mariadb'
                proc_name='mariadbd'
            fi
            if [ -d "/etc/sysconfig" ]; then
                service='mysqld'
                proc_name='mysqld'
                if [ -e "/usr/lib/systemd/system/mariadb.service" ]; then
                    service='mariadb'
                fi
            fi
        fi
        if [ "$service" == 'pgsql' ]; then
            service='postgresql'
            proc_name='postmaster'
            if [ ! -d "/etc/sysconfig" ]; then
                proc_name='postgres'
            fi
            if [ ! -e '/etc/init.d/postgresql' ]; then
                proc_name='postgres'
            fi
        fi
        get_srv_state $service $proc_name '' 'mysqld' 'mysqld'
        data="$data\nNAME='$service' SYSTEM='database server' STATE='$state'"
        data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
        proc_name=''
    done
fi

# Checking FTP system
if [ ! -z "$FTP_SYSTEM" ] && [ "$FTP_SYSTEM" != 'remote' ]; then
    get_srv_state $FTP_SYSTEM
    data="$data\nNAME='$FTP_SYSTEM' SYSTEM='ftp server' STATE='$state'"
    data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi

# Checking CRON system
if [ ! -z "$CRON_SYSTEM" ] && [ "$CRON_SYSTEM" != 'remote' ]; then
    get_srv_state "$CRON_SYSTEM" "$CRON_SYSTEM" '' '' 'crond'
    data="$data\nNAME='$CRON_SYSTEM' SYSTEM='job scheduler' STATE='$state'"
    data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi

# Checking SSH daemon
if [ -e "/etc/ssh/sshd_config" ]; then
    get_srv_state 'ssh' 'ssh' '' '' 'sshd'
    data="$data\nNAME='ssh' SYSTEM='SSH Access' STATE='$state'"
    data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi

# Checking Vesta nginx
get_srv_state 'vesta' 'vesta-nginx' '' '' 'vesta-nginx'
data="$data\nNAME='vesta-nginx' SYSTEM='Vesta nginx service' STATE='$state'"
data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"

# Checking Vesta php-fpm
get_srv_state 'vesta' 'vesta-php' '' '' 'vesta-php'
data="$data\nNAME='vesta-php' SYSTEM='Vesta php service' STATE='$state'"
data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"

# Checking FIREWALL system
if [ ! -z "$FIREWALL_SYSTEM" ] && [ "$FIREWALL_SYSTEM" != 'remote' ]; then
    state="stopped"
    /sbin/iptables -L vesta >/dev/null 2>&1
    if [ "$?" -eq 0 ]; then
        state="running"
    fi
    data="$data\nNAME='$FIREWALL_SYSTEM' SYSTEM='firewall'"
    data="$data STATE='$state' CPU='0' MEM='0' RTIME='0'"
fi

# Checking FIREWALL Fail2ban extention
if [ ! -z "$FIREWALL_EXTENSION" ]; then
    get_srv_state "$FIREWALL_EXTENSION" 'fail2ban-server' 'script'
    data="$data\nNAME='$FIREWALL_EXTENSION' SYSTEM='brute-force monitor'"
    data="$data STATE='$state' CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi

# Checking ElasticSearch
if [ -d "/etc/elasticsearch" ]; then
    get_srv_state 'elasticsearch'
    data="$data\nNAME='elasticsearch' SYSTEM='ElasticSearch' STATE='$state'"
    data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi

# Checking Redis
if [ -d "/etc/redis" ]; then
    get_srv_state 'redis' 'redis-server' '' 'redis' 'redis-server'
    data="$data\nNAME='redis' SYSTEM='Redis' STATE='$state'"
    data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi

# Checking Memcached
if [ -f "/etc/memcached.conf" ]; then
    get_srv_state 'memcached'
    data="$data\nNAME='memcached' SYSTEM='Memcached' STATE='$state'"
    data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi


# Listing data
case $format in
    json)   json_list ;;
    plain)  plain_list ;;
    csv)    csv_list ;;
    shell)  shell_list |column -t ;;
esac


#----------------------------------------------------------#
#                       Vesta                              #
#----------------------------------------------------------#

exit