#!/bin/bash

# MIT License:
#
# Copyright (c) 2016-2018, Alexander I. Chebykin
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

#################################################################
# CAI CP v.0.9.1
#
# @module     : Bash script module
# @author     : Alexander I. Chebykin <alex.chebykin@gmail.com>
# @copyright  : Copyright (c) 2016-2018 Alexander I. Chebykin
# @version    : 0.9.1
# @build date : 2018-08-23
# @license    : MIT
# @link       : https://github.com/CAI79/CAI-CP
#################################################################

skeleton() {
    cmd_arp=`which arp`
    cmd_awk=`which awk`
    cmd_cat=`which cat`
    cmd_date=`which date`
    cmd_df=`which df`
    cmd_free=`which free`
    cmd_grep=`which grep`
    cmd_hostname=`which hostname`
    cmd_iostat=`which iostat`
    cmd_ip=`which ip`
    cmd_lsb_release=`which lsb_release`
    cmd_lscpu=`which lscpu`
    cmd_netstat=`which netstat`
    cmd_ps=`which ps`
    cmd_sed=`which sed`
    cmd_smartctl=`which smartctl`
    cmd_smbstatus=`which smbstatus`
    cmd_sort=`which sort`
    cmd_ss=`which ss`
    cmd_uname=`which uname`
    cmd_w=`which w`

    result=$()
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

_print_parsed() {
  while read data; do
#    echo -n "$data" | sed -r "s/\"/\\\\\"/g" | tr -d "\n";
    echo -n "$data" | tr -d "\n";
  done;
}

#########################
# Common info functions #
#########################
cpu() {
    cmd_awk=`which awk`
    cmd_cat=`which cat`

    result=$({ $cmd_cat /proc/stat; sleep "1"; $cmd_cat /proc/stat; } \
            | $cmd_awk '/^cpu* / {usr=$2-usr; sys=$4-sys; idle=$5-idle; iow=$6-iow} END \
                  {total=usr+sys+idle+iow; printf "%.2f\n", (total-idle)*100/total}' \
            | $cmd_awk -F " " '{print "{\n   \"cpu\": " $1 "\n}"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# CPU(s) count
cpu_count() {
    cmd_awk=`which awk`
    cmd_grep=`which grep`
    cmd_lscpu=`which lscpu`

    result=$($cmd_lscpu \
            | $cmd_grep '^CPU(s):' \
            | $cmd_awk '{ print "{\n\t\"cpu(s)\": " $2 "\n}" }')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# CPU(s) load information
cpu_load() {
    cmd_awk=`which awk`
    cmd_cat=`which cat`
    cmd_grep=`which grep`
    cmd_lscpu=`which lscpu`

    cpus=$($cmd_lscpu \
            | $cmd_grep '^CPU(s):' \
            | $cmd_awk '{ print $2 }')

    i=0

    while [ $i -lt $cpus ]
    do
        if [ "$i" -ne 0 ]; then 
            result="$result,"
        fi
        result+=$(
        { $cmd_cat /proc/stat; sleep "1"; $cmd_cat /proc/stat; } \
        | $cmd_awk '/^cpu'$i' / {usr=$2-usr; sys=$4-sys; idle=$5-idle; iow=$6-iow} END \
                {total=usr+sys+idle+iow; printf "%.2f\n", (total-idle)*100/total}' \
        | $cmd_awk -F " " '{print "\n   \"cpu'$i'\": " int($1) "\n"}'
        )
        (( i++ ))
    done
echo "{$result}" | _print_parsed
}

# CPU information
cpu_info() {
    cmd_awk=`which awk`
    cmd_lscpu=`which lscpu`

    result=$($cmd_lscpu \
                    | $cmd_awk -F: '{print "\""$1"\": \""$2"\"," }'\
                    )

    echo "[{" ${result%?} "}]" | _print_parsed
}

# General OS information
general_info() {
    cmd_awk=`which awk`
    cmd_cat=`which cat`
    cmd_date=`which date`
    cmd_hostname=`which hostname`
    cmd_lsb_release=`which lsb_release`
    cmd_sed=`which sed`
    cmd_uname=`which uname`

    function displaytime {
        local T=$1
        local D=$((T/60/60/24))
        local H=$((T/60/60%24))
        local M=$((T/60%60))
        local S=$((T%60))
        [[ $D > 0 ]] && printf '%d days ' $D
        [[ $H > 0 ]] && printf '%d hours ' $H
        [[ $M > 0 ]] && printf '%d minutes ' $M
        [[ $D > 0 || $H > 0 || $M > 0 ]] && printf 'and '
        printf '%d seconds\n' $S
    }

    lsbRelease=$($cmd_lsb_release -ds | $cmd_sed -e 's/^"//'  -e 's/"$//')
    uname=$($cmd_uname -r | $cmd_sed -e 's/^"//'  -e 's/"$//')
    os=`echo $lsbRelease $uname`
    hostname=$($cmd_hostname)
    uptime_seconds=$($cmd_cat /proc/uptime | $cmd_awk '{print $1}')
    server_time=$($cmd_date)

    echo "[{ \"OS\": \"$os\", \
             \"Hostname\": \"$hostname\", \
             \"Uptime\": \" $(displaytime ${uptime_seconds%.*}) \", \
             \"Server Time\": \"$server_time\" }]" \
            | _print_parsed
}

# OS distriboutive info
os_distr() {
    cmd_lsb_release=`which lsb_release`
    cmd_sed=`which sed`
    cmd_uname=`which uname`

    lsbRelease=$($cmd_lsb_release -ds | $cmd_sed -e 's/^"//' -e 's/"$//')
    osFamily=$($cmd_uname)

    echo "{ \"Distr\": \"$lsbRelease\", \
             \"Family\": \"$osFamily\" }" \
            | _print_parsed
}

# Running processes list
processes() {
    cmd_awk=`which awk`
    cmd_ps=`which ps`
    cmd_sed=`which sed`
    cmd_sort=`which sort`

    result=$($cmd_ps -eafw \
            | $cmd_sed -e '1d' \
            | $cmd_sort -k1 \
            | $cmd_awk 'BEGIN \
                            {print "["} \
                            {if (NR > 1) print ","} \
                            {print "\t{"} \
                            {printf("\t\t\"uid\": \"%s\", \
                                    \n\t\t\"pid\": %s, \
                                    \n\t\t\"ppid\": %s, \
                                    \n\t\t\"c\": %s, \
                                    \n\t\t\"stime\": \"%s\", \
                                    \n\t\t\"tty\": \"%s\", \
                                    \n\t\t\"time\": \"%s\", \
                                    \n\t\t\"cmd\": \"%s\"\n\t}", $1, $2, $3, $4, $5, $6, $7, $8)} \
                        END \
                        {print "\n\t]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# Server name
srv_name() {
    cmd_awk=`which awk`
    cmd_uname=`which uname`

    result=$($cmd_uname -n | $cmd_awk '{ print "{\n\t\"server_name\": \"" $1 "\"\n}" }')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

##############################
# File system info functions #
##############################

# File system info
fs() {
    cmd_awk=`which awk`
    cmd_df=`which df`
    cmd_sed=`which sed`
    cmd_sort=`which sort`

    result=$($cmd_df -h -T \
            | $cmd_sed -e '1d' \
            | $cmd_sort -k1,1 -k7,7 \
            | $cmd_awk 'BEGIN \
                            {print "["} \
                            {if (NR > 1) print ","} \
                            {print "\t{"} \
                            {printf("\t\t\"fs\": \"%s\", \
                                    \n\t\t\"type\": \"%s\", \
                                    \n\t\t\"size\": \"%s\", \
                                    \n\t\t\"used\": \"%s\", \
                                    \n\t\t\"free\": \"%s\", \
                                    \n\t\t\"percent\": \"%s\", \
                                    \n\t\t\"mount\": \"%s\"\n\t}", $1, $2, $3, $4, $5, $6, $7)} \
                        END{print "\n]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# HDD S.M.A.R.T. status
hdd_smart() {
    cmd_awk=`which awk`
    cmd_sed=`which sed`
    cmd_smartctl=`which smartctl`

    result=$(sudo $cmd_smartctl --scan \
            | $cmd_awk '{printf("%s ", $1)} {system("sudo smartctl -H \"" $1 "\" \
                                                    | sed -n '5p'")}' \
            | $cmd_sed -e '/^$/d' \
            | $cmd_awk 'BEGIN \
                            {print "["} \
                            {if (NR > 1) print ","} \
                            {print "\t{"} \
                            {printf("\t\t\"drive\": \"%s\",\n\t\t\"status\": \"%s\"\n\t}", $1, $NF)} \
                        END \
                        {print "\n]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# HDD temperature info
hdd_temp() {
    cmd_awk=`which awk`
    cmd_smartctl=`which smartctl`

    path=`pwd`

    result=$($cmd_smartctl --scan \
            | $cmd_awk '{system("./smart_temp.sh \"" $1 "\"")}' \
            | $cmd_awk -F: 'BEGIN \
                                {print "["} \
                                {if (NR > 1) print ","} \
                                {print "\t{"} \
                                {FS=": "} \
                                {printf("\t\t\"drive\": \"%s\", \
                                        \n\t\t\"model\": \"%s\", \
                                        \n\t\t\"temperature\": \"%s\"\n\t}", $1, $2, $3)} \
                            END\
                            {print "\n]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# IO statistics
io_stat() {
    cmd_awk=`which awk`
    cmd_iostat=`which iostat`
    cmd_sed=`which sed`
    cmd_sort=`which sort`

    result=$($cmd_iostat \
            | $cmd_sed -e '1,6d;/^$/d' \
            | $cmd_sort -k1 \
            | $cmd_awk 'BEGIN \
                            {print "["} \
                            {if (NR > 1) print ","} \
                            {print "\t{"} \
                            {printf("\t\t\"device\": \"%s\", \
                                    \n\t\t\"tps\": %s, \
                                    \n\t\t\"kB_read/s\": %s, \
                                    \n\t\t\"kB_wrtn/s\": %s, \
                                    \n\t\t\"kB_read\": %s, \
                                    \n\t\t\"kB_wrtn\": %s\n\t}", $1, $2, $3, $4, $5, $6)} \
                        END \
                        {print "\n\t]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

#########################
# Memory info functions #
#########################

# General memory information
mem_info() {
    cmd_awk=`which awk`
    cmd_cat=`which cat`
    cmd_sed=`which sed`

    result=$($cmd_cat /proc/meminfo \
                    | $cmd_awk -F: 'BEGIN {print "{"} {print "\"" $1 "\": \"" $2 "\"," } END {print "}"}' \
                    | $cmd_sed 'N;$s/,\n/\n/;P;D')

    echo "[" ${result%?} "}]" | _print_parsed
}

# Memory usage information
#
# Based on Linux Dash codebase: https://github.com/afaqurk/linux-dash
#
# References:
#   Calculations: http://zcentric.com/2012/05/29/mapping-procmeminfo-to-output-of-free-command/
#   Fields: https://www.kernel.org/doc/Documentation/filesystems/proc.txt
mem() {
    cmd_awk=`which awk`
    cmd_cat=`which cat`
    cmd_grep=`which grep`

    memInfoFile="/proc/meminfo"

    memInfo=`$cmd_cat $memInfoFile | $cmd_grep 'MemTotal\|MemFree\|Buffers\|Cached'`

    echo $memInfo \
            | $cmd_awk '{print "{ \"total\": " ($2/1024) ", \"used\": " ( ($2-($5+$8+$11))/1024 ) " }"  }' \
            | _print_parsed
}

# Swap memory info
swap() {
    cmd_awk=`which awk`
    cmd_free=`which free`
    cmd_sed=`which sed`

#    result=$($cmd_free -m \
#            | $cmd_sed -e '1d' -e '2d' -e '3d' \
#            | $cmd_awk 'BEGIN \
#                            {print "{"} \
#                            {if (NR > 1) print ","} \
#                            {printf("\n\t\"total\": %s, \n\t\"used\": %s", $2, $3)} \
#                        END{print "\n}"}')
    result=$($cmd_free -m \
            | $cmd_sed '/Swap:/!d' \
            | $cmd_awk 'BEGIN \
                            {print "{"} \
                            {if (NR > 1) print ","} \
                            {printf("\n\t\"total\": %s, \n\t\"used\": %s", $2, $3)} \
                        END{print "\n}"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

##########################
# Network info functions #
##########################

# ARP cache table
#
# Based on Linux Dash codebase: https://github.com/afaqurk/linux-dash
arp_cache() {
    cmd_awk=`which awk`
    cmd_sed=`which sed`
    if hash arp 2>/dev/null; then cmd_arp=`which arp`
    else cmd_arp="ip neigh"
    fi
    
    result=$($cmd_arp | \
            $cmd_awk 'BEGIN {print "["} NR>1 \
                        {if ( NF==6 ) {print "{ \"addr\": \"" $1 "\", " \
                                                "\"hw_type\": \"" $2 "\", " \
                                                "\"hw_addr\": \"" $3 "\", " \
                                                "\"flags\": \"" $4 "\", " \
                                                "\"mask\": \"" $5 "\" , " \
                                                "\"iface\": \"" $6 "\" }, "} \
                        if ( NF==5 ) {print "{ \"addr\": \"" $1 "\", " \
                                                "\"hw_type\": \"" $2 "\", " \
                                                "\"hw_addr\": \"" $3 "\", " \
                                                "\"flags\": \"" $4 "\", " \
                                                "\"mask\": \"\", " \
                                                "\"iface\": \"" $5 "\" }, "} \
                        if ( NF==4 ) {print "{ \"addr\": \"" $1 "\", " \
                                                "\"hw_type\": \"" $2 "\", " \
                                                "\"hw_addr\": \"" $3 "\", " \
                                                "\"flags\": \"\", " \
                                                "\"mask\": \"\", " \
                                                "\"iface\": \"" $4 "\" }, "} \
                        if ( NF==3 ) {print "{ \"addr\": \"" $1 "\", " \
                                                "\"hw_type\": \"\", " \
                                                "\"hw_addr\": \"" $2 "\", " \
                                                "\"flags\": \"\", " \
                                                "\"mask\": \"\", " \
                                                "\"iface\": \"" $3 "\" }, "} \
                        } \
                    END {print "]"}' \
        | $cmd_sed 'N;$s/},/}/;P;D')

    if [ -z "$result" ];  then echo {}
        else echo $result | _print_parsed
    fi
}

# IP addresses
#
# Based on Linux Dash codebase: https://github.com/afaqurk/linux-dash
ip_addr() {
    cmd_awk=`which awk`
    cmd_grep=`which grep`
    cmd_ifconfig=`which ifconfig`
    cmd_tr=`which tr`
    cmd_dig=`which dig`

    externalIp=`$cmd_dig +short myip.opendns.com @resolver1.opendns.com`

    $cmd_ifconfig \
                | $cmd_grep -B1 "inet addr" \
                | $cmd_awk '{ if ( $1 == "inet" ) { print $2 } else if ( $2 == "Link" ) { printf "%s:" ,$1 } }' \
                | $cmd_awk -v exIp="$externalIp" -F: 'BEGIN {print "["} { print "{ \"interface\": \"" $1 "\", \"ip\": \"" $3 "\" },"} END {print "{ \"interface\": \"external\", \"ip\": \""exIp"\" } ]"}' \
                | $cmd_tr -d '\r\n' 
}

# Network bandwith
net_band() {
    cmd_awk=`which awk`
    cmd_cat=`which cat`
    cmd_sed=`which sed`

    result=$($cmd_cat /proc/net/dev \
            | $cmd_awk 'BEGIN\
                            {print "["} NR>2 \
                            {print "{ \"interface\": \"" $1 "\"," " \"tx\": " $2 "," " \"rx\": " $10 " }," } \
                        END\
                        {print "]"}' \
            | $cmd_sed 'N;$s/,\n/\n/;P;D')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# Network connections
net_conn() {
    cmd_awk=`which awk`
    cmd_sed=`which sed`
    cmd_sort=`which sort`
    cmd_ss=`which ss`

    result=$($cmd_ss \
            | $cmd_sed -e '1d;/u_str/d' \
            | $cmd_sort -k1 \
            | $cmd_awk 'BEGIN \
                        {print "["} \
                        {if (NR > 1) print ","} \
                        {print "\t{"} \
                        {printf("\t\t\"netid\": \"%s\", \
                                \n\t\t\"state\": \"%s\", \
                                \n\t\t\"rcvq\": %s, \
                                \n\t\t\"sendq\": %s, \
                                \n\t\t\"local\": \"%s\", \
                                \n\t\t\"peer\": \"%s\"\n\t}", $1, $2, $3, $4, $5, $6)} \
                        END{print "\n]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# Download transfer rate
#
# Based on Linux Dash codebase: https://github.com/afaqurk/linux-dash
net_download_transfer_rate() {
    files=(/sys/class/net/*)
    pos=$(( ${#files[*]} - 1 ))
    last=${files[$pos]}

    json_output="{"

    for interface in "${files[@]}"
    do
        basename=$(basename "$interface")

        # find the number of bytes transfered for this interface
        in1=$(cat /sys/class/net/"$basename"/statistics/rx_bytes)

        # wait a second
        sleep 1

        # check same interface again
        in2=$(cat /sys/class/net/"$basename"/statistics/rx_bytes)

        # get the difference (transfer rate)
        in_bytes=$((in2 - in1))

        # convert transfer rate to KB
        in_kbytes=$((in_bytes / 1024))

        # convert transfer rate to KB
        json_output="$json_output \"$basename\": $in_kbytes"

        # if it is not the last line
        if [[ ! $interface == $last ]]
        then
            # add a comma to the line (JSON formatting)
            json_output="$json_output,"
        fi
    done

    # close the JSON object & print to screen
    echo "$json_output}" | _print_parsed
}

# Upload transfer rate
#
# Based on Linux Dash codebase: https://github.com/afaqurk/linux-dash
net_upload_transfer_rate() {
    files=(/sys/class/net/*)
    pos=$(( ${#files[*]} - 1 ))
    last=${files[$pos]}

    json_output="{"

    for interface in "${files[@]}"
    do
        basename=$(basename "$interface")

        # find the number of bytes transfered for this interface
        out1=$(cat /sys/class/net/"$basename"/statistics/tx_bytes)

        # wait a second
        sleep 1

        # check same interface again
        out2=$(cat /sys/class/net/"$basename"/statistics/tx_bytes)

        # get the difference (transfer rate)
        out_bytes=$((out2 - out1))

        # convert transfer rate to KB
        out_kbytes=$((out_bytes / 1024))

        # convert transfer rate to KB
        json_output="$json_output \"$basename\": $out_kbytes"

        # if it is not the last line
        if [[ ! $interface == $last ]]
        then
            # add a comma to the line (JSON formatting)
            json_output="$json_output,"
        fi
    done

    # close the JSON object & print to screen
    echo "$json_output}" | _print_parsed
}

# Online users info
users_online() {
    cmd_awk=`which awk`
    cmd_netstat=`which netstat`
    cmd_sed=`which sed`
    cmd_smbstatus=`which smbstatus`
    cmd_sort=`which sort`
    cmd_w=`which w`

    result=$($cmd_w \
            | $cmd_sed -e '1,2d' \
            | $cmd_awk 'BEGIN \
                        {print "["} \
                        {if (NR > 1) print ","} \
                        {print "\t{"} \
                        {printf("\t\t\"user\": \"%s\", \
                                \n\t\t\"tty\": \"%s\", \
                                \n\t\t\"from\": \"%s\", \
                                \n\t\t\"login\": \"%s\", \
                                \n\t\t\"idle\": \"%s\", \
                                \n\t\t\"jcpu\": \"%s\", \
                                \n\t\t\"pcpu\": \"%s\", \
                                \n\t\t\"what\": \"%s %s %s\"\n\t}", \
                                $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)} \
                        END \
                        {print "\n]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# IP routing table
ip_route() {
    if hash netstat 2>/dev/null; then ip_route_netstat
    else ip_route_ip
    fi
}

# IP routing table (ip)
ip_route_ip() {
    cmd_awk=`which awk`
    cmd_ip=`which ip`
    cmd_sed=`which sed`

    result=$($cmd_ip r \
            | $cmd_awk 'BEGIN \
                            {print "["} \
                            {if (NR > 1) print ","} \
                            {print "\t{\"route\": \""} \
                            {print } \
                            {print "\"\n\t}"} \
                        END \
                        {print "\n\t]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# IP routing table (netstat)
ip_route_netstat() {
    cmd_awk=`which awk`
    cmd_netstat=`which netstat`
    cmd_sed=`which sed`

    result=$($cmd_netstat -r \
            | $cmd_sed -e '1,2d' \
            | $cmd_awk 'BEGIN \
                            {print "["} \
                            {if (NR > 1) print ","} \
                            {print "\t{"} \
                            {printf("\t\t\"destination\": \"%s\", \
                                    \n\t\t\"gateway\": \"%s\", \
                                    \n\t\t\"genmask\": \"%s\", \
                                    \n\t\t\"flags\": \"%s\", \
                                    \n\t\t\"mss\": %s, \
                                    \n\t\t\"window\": %s, \
                                    \n\t\t\"irtt\": %s, \
                                    \n\t\t\"iface\": \"%s\"\n\t}", $1, $2, $3, $4, $5, $6, $7, $8)} \
                        END \
                        {print "\n\t]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# Multicast groups
net_multicast() {
    cmd_awk=`which awk`
    cmd_netstat=`which netstat`
    cmd_sed=`which sed`
    cmd_sort=`which sort`

    result=$($cmd_netstat -g \
            | $cmd_sed -e '1,3d' \
            | $cmd_sort -k1 \
            | $cmd_awk 'BEGIN \
                            {print "["} \
                            {if (NR > 1) print ","} \
                            {print "\t{"} \
                            {printf("\t\t\"interface\": \"%s\", \
                                    \n\t\t\"refcnt\": %s, \
                                    \n\t\t\"group\": \"%s\"\n\t}", $1, $2, $3)} \
                        END \
                        {print "\n\t]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# Listening sockets
listen_socks() {
    if hash netstat 2>/dev/null; then listen_socks_netstat
    else listen_socks_ss
    fi
}

# Listening sockets (ss)
listen_socks_ss() {
    cmd_awk=`which awk`
    cmd_ss=`which ss`
    cmd_sed=`which sed`

    result=$($cmd_ss -ltn \
            | $cmd_sed -e '1d' \
            | $cmd_awk 'BEGIN \
                        {print "["} \
                        {if (NR > 1) print ","} \
                        {print "\t{"} \
                        {printf("\t\t\"state\": \"%s\", \
                                \n\t\t\"recv-q\": %s, \
                                \n\t\t\"send-q\": %s, \
                                \n\t\t\"local address:port\": \"%s\", \
                                \n\t\t\"peer addr:port\": \"%s\"\n\t}", $1, $2, $3, $4, $5)} \
                    END \
                    {print "\n\t]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# Listening sockets (netstat)
listen_socks_netstat() {
    cmd_awk=`which awk`
    cmd_netstat=`which netstat`
    cmd_sed=`which sed`

    result=$($cmd_netstat -l \
            | $cmd_sed -n '/tcp/p;/udp/p;/raw/p' \
            | $cmd_awk 'BEGIN \
                        {print "["} \
                        {if (NR > 1) print ","} \
                        {print "\t{"} \
                        {printf("\t\t\"proto\": \"%s\", \
                                \n\t\t\"recv-q\": %s, \
                                \n\t\t\"send-q\": %s, \
                                \n\t\t\"localaddr\": \"%s\", \
                                \n\t\t\"foreignaddr\": \"%s\", \
                                \n\t\t\"state\": \"%s\"\n\t}", $1, $2, $3, $4, $5, $6, $7)} \
                    END \
                    {print "\n\t]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# Active unix domain sockets
active_unix_socks() {
    if hash netstat 2>/dev/null; then active_unix_socks_netstat
    else active_unix_socks_ss
    fi
}

# Active unix domain sockets (ss)
active_unix_socks_ss() {
    cmd_awk=`which awk`
    cmd_ss=`which ss`
    cmd_sed=`which sed`
    cmd_sort=`which sort`

    result=$($cmd_ss -x \
            | $cmd_sed -e '1d' \
            | $cmd_sort -k6 \
            | $cmd_awk 'BEGIN \
                            {print "["} \
                            {if (NR > 1) print ","} \
                            {print "\t{"} \
                            {printf("\t\t\"netid\": \"%s\", \
                                    \n\t\t\"state\": \"%s\", \
                                    \n\t\t\"recv-q\": %s, \
                                    \n\t\t\"send-q\": %s, \
                                    \n\t\t\"local address:port\": \"%s:%s\", \
                                    \n\t\t\"peer address:port\": \"%s:%s\"\n\t}", $1, $2, $3, $4, $5, $6, $7, $8)} \
                        END \
                        {print "\n\t]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# Active unix domain sockets (netstat)
active_unix_socks_netstat() {
    cmd_awk=`which awk`
    cmd_netstat=`which netstat`
    cmd_sed=`which sed`
    cmd_sort=`which sort`

    result=$($cmd_netstat -l \
            | $cmd_sed -n '/unix/p' \
            | $cmd_sort -k6 \
            | $cmd_awk 'BEGIN \
                            {print "["} \
                            {if (NR > 1) print ","} \
                            {print "\t{"} \
                            {printf("\t\t\"proto\": \"%s\", \
                                    \n\t\t\"refcnt\": %s, \
                                    \n\t\t\"flags\": \"%s%s%s\", \
                                    \n\t\t\"type\": \"%s\", \
                                    \n\t\t\"state\": \"%s\", \
                                    \n\t\t\"i-node\": \"%s\", \
                                    \n\t\t\"path\": \"%s\"\n\t}", $1, $2, $3, $4, $5, $6, $7, $8, $9)} \
                        END \
                        {print "\n\t]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# Check is application installed or not
check_app() {
    cmd_awk=`which awk`

    result=$(whereis -S /opt -f $1 \
            | $cmd_awk -F: '{if(length($2)==0) { installed="false"; } else { installed="true"; } \
                            print \
                            "{ \
                                \"binary\": \""$1"\", \
                                \"location\": \""$2"\", \
                                \"installed\": "installed" \
                            }"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# SMB processes
smb_proc() {
    cmd_awk=`which awk`
    cmd_sed=`which sed`
    cmd_smbstatus=`which smbstatus`
    cmd_sort=`which sort`

    result=$(sudo $cmd_smbstatus -pf \
            | $cmd_sed -e '1,4d' \
            | $cmd_sort -k1 \
            | $cmd_awk 'BEGIN \
                            {print "["} \
                            {if (NR > 1) print ","} \
                            {print "\t{"} \
                            {printf("\t\t\"pid\": %s, \
                                    \n\t\t\"username\": \"%s\", \
                                    \n\t\t\"group\": \"%s\", \
                                    \n\t\t\"machine\": \"%s\", \
                                    \n\t\t\"protocol ver\": \"%s\", \
                                    \n\t\t\"encryption\": \"%s\", \
                                    \n\t\t\"signing\": \"%s\"\n\t}", $1, $2, $3, $4, $5, $6, $7)} \
                        END \
                        {print "\n\t]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# SMB shares
smb_shares() {
    cmd_awk=`which awk`
    cmd_sed=`which sed`
    cmd_smbstatus=`which smbstatus`
    cmd_sort=`which sort`

    result=$(sudo $cmd_smbstatus -Sf \
            | $cmd_sed -e '1,3d;/^\s*$/d' \
            | $cmd_sort -k1 \
            | $cmd_awk 'BEGIN \
                            {print "["} \
                            {if (NR > 1) print ","} \
                            {print "\t{"} \
                            {printf("\t\t\"service\": \"%s\", \
                                    \n\t\t\"pid\": %s, \
                                    \n\t\t\"machine\": \"%s\", \
                                    \n\t\t\"connected at\": \"%s %s %s %s %s %s\", \
                                    \n\t\t\"encryption\": \"%s\", \
                                    \n\t\t\"signing\": \"%s\"\n\t}", $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)} \
                        END \
                        {print "\n\t]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

# SMB locked files
smb_locks() {
    cmd_awk=`which awk`
    cmd_sed=`which sed`
    cmd_smbstatus=`which smbstatus`
    cmd_sort=`which sort`

    result=$(sudo $cmd_smbstatus -Lf \
            | $cmd_sed -e '1,3d;/^\s*$/d' \
            | $cmd_sort -k1 \
            | $cmd_awk 'BEGIN \
                            {print "["} \
                            {if (NR > 1) print ","} \
                            {fname = ""} \
                            {ftime = ""} \
                            {for (i = 8; i < NF - 4; i++) fname = fname" "$i} \
                            {for (i = NF - 4; i < NF; i++) ftime = ftime" "$i} \
                            {print "\t{"} \
                            {printf("\t\t\"pid\": %s, \
                                    \n\t\t\"uid\": %s, \
                                    \n\t\t\"deny mode\": \"%s\", \
                                    \n\t\t\"access\": \"%s\", \
                                    \n\t\t\"r/w\": \"%s\", \
                                    \n\t\t\"oplock\": \"%s\", \
                                    \n\t\t\"share path\": \"%s\", \
                                    \n\t\t\"name\": \"%s\", \
                                    \n\t\t\"time\": \"%s\"\n\t}", $1, $2, $3, $4, $5, $6, $7, fname, ftime)} \
                        END \
                        {print "\n\t]"}')
    if [ -z "$result" ]; then echo {}
    else echo $result | _print_parsed
    fi
}

function_name="$1"
parameter="$2"

${function_name} ${parameter}
