#!/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

# 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
        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}
    state='running'

    # 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

    # Checking pid
    if [ ! -z "$pids" ]; then
        pid=$(echo "$pids" |cut -f 1 -d '|')
        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 [ -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" ] && [ -e "/proc/$pid" ]; then
            pid_file="/proc/$pid"
        fi

        # Calculating uptime
        if [ ! -z "$pid_file" ]; then
            mtime=$(stat -c "%Y" $pid_file)
            rtime=$((ctime - mtime))
            rtime=$((rtime  / 60))
        else
            rtime=0
        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 Backend
if [ ! -z "$WEB_BACKEND" ] && [ "$WEB_BACKEND" != 'remote' ]; then
    proc_name=$(ls /usr/sbin/php*fpm* | rev | cut -d'/' -f 1 | rev)
    get_srv_state $proc_name
    data="$data\nNAME='$WEB_BACKEND' SYSTEM='backend server' STATE='$state'"
    data="$data CPU='$cpu' 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

# 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
    get_srv_state $MAIL_SYSTEM
    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
    get_srv_state $IMAP_SYSTEM
    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
    fi
    data="$data\nNAME='$ANTIVIRUS_SYSTEM' SYSTEM='email antivirus'"
    data="$data STATE='$state' CPU='$cpu' MEM='$mem' RTIME='$rtime'"
    proc_name=''
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
            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
        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
    data="$data\nNAME='$CRON_SYSTEM' SYSTEM='job scheduler' STATE='$state'"
    data="$data CPU='$cpu' MEM='$mem' RTIME='$rtime'"
fi

# 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

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


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

exit
