#!/bin/bash
# vim: ts=4 sw=4 syn=sh et

# ESP - Enhanced Shell Prompt
# Created by Citizen Kepler
# Updated by Terrance Robotham and Ricky Grassmuck
# Maintained by Ausaf Lateef
# https://git.cpanel.net/a.lateef/ESP

# Shellcheck Global POSIX ignores
# shellcheck disable=SC2034,SC2039,SC2112,SC2113,SC2155

# ESP Version
readonly VERSION='2.0.7'

# Colors
export END=$(tput sgr0)
readonly END
export BOLD=$(tput bold)
readonly BOLD
export RED=$(tput setaf 1)
readonly RED
export GREEN=$(tput setaf 2)
readonly GREEN
export YELLOW=$(tput setaf 3)
readonly YELLOW
export BLUE=$(tput setaf 4)
readonly BLUE
export MAGENTA=$(tput setaf 5)
readonly MAGENTA
export CYAN=$(tput setaf 6)
readonly CYAN
export WHITE=$(tput setaf 7)
readonly WHITE

# Set display_ functions
function display_critical() {
    echo -ne "${RED}${BOLD}$1${END}"
}

#
# Display Alert Levels
# --------------------

# Graveyard!
function die() {
    display_critical "[FATAL] $1"
}

# Pre-flight check for ESP
if [[ $UID != 0 ]]; then
    die "ESP *MUST* be run as root!"
    return
fi

#
# Pre-flight check for cpanel
#

if [ ! -d /var/cpanel ]; then
    echo "${YELLOW} .: WARNING WARNING WARNING :."
    echo "==============================="
    echo "cPanel has not been detected.  This script has only been tested on cPanel"
    echo "Please Ctrl-C out of this script in the next 10 seconds otherwise it will run"
    for time in {10..0}; do
        echo "Proceeding in $time."
        sleep 1
    done
    echo "Forward March! ${END}"
fi

# Set other defaults
export STRACESTRLEN="${STRACESTRLEN:-8192}"

# This will need to be updated to account for Ubuntu
OS_MAJOR_VER=$(grep -o -P '[5-8]' /etc/redhat-release | head -n1)
export OS_MAJOR_VERSION

# Grab the Ticket number if it exists from the PS1 prompt
# Dev Note: Don't escape grep since we alias it
# shellcheck disable=SC1001
if [ "$(echo "${PS1}" | \grep -c "cPs#")" -ge 1 ]; then
    TICKET=$(echo "${PS1}" | awk '{{print $3}}' | cut -d \@ -f 2)
    readonly TICKET
else
    TICKET="$(whoami)"
    readonly TICKET
fi

# Set tech name or fall back to cptech if none specified
# We can grab it from the history file
#TECH=$(grep WHMuser /root/.bash_history.cpanel_ticket."${TICKET}" | awk '{print $2}' | cut -d "\"" -f 2) 
export TECH="${TECH:-cptech}"

# New model: create per-ticket directory rather than per analyst?
# /root/cptechs/1000000/analyst1 /root/cptechs/1000000/analyst2
cptechdir="/root/cptechs/${TICKET}/${TECH}"

# Create ${cptechdir}
mkdir -p "${cptechdir}"

## DO NOT TOUCH ANYTHING BEFORE THIS LINE ##

#
# Initial Setup
# -------------
#

# Remove env vars that we care about
unset VIMINIT
unset EXINIT
unset PROMPT_COMMAND

# Trim file path in the prompt
export PROMPT_DIRTRIM=4

# VIM: Forward March!
export VIMINIT="${esp_custom_vim:-:set syntax=on}"

# PS1 ONLY
function ps_display_critical() {
    echo -ne "${RED}${BOLD}$1${END}, "
}

function ps_display_warn() {
    echo -ne "${YELLOW}$1${END}, "
}

function ps_display_info() {
    echo -ne "${CYAN}$1${END}, "
}

alias ls="ls --color=auto"
alias ll="ls -lah --color"
alias showip2089="curl -s http://myip.cpanel.net:2089/v1.0/ ; echo"
alias whmapi1listapps="grep -h '^sub [a-z]' /usr/local/cpanel/Whostmgr/API/1/*.pm | sed -e 's/{//g' -e 's/sub //g' | sort"

function forceremove() {
    local FILE
    FILE=$*
    /bin/rm -f "${FILE}"
}

#
# ESP hook for startup
# --------------------

if [ "$(declare -Ff esp_hook_pre)" == "esp_hook_pre" ]; then
    esp_hook_pre
fi

#
# DNS Only Check
# --------------

if [ -e /var/cpanel/dnsonly ]; then
    export OS="DNSONLY"
    export esp_check_disable_backup=1
    export esp_check_disable_apache=1
    export esp_check_disable_mysql=1
    export esp_check_disable_mailserver=1
    export esp_check_disable_exim=1
    export esp_check_disable_ccs=1 
    echo "DNSONLY Detected, disabling checks for backups, Apache, MySQL, Mailserver, Exim, CCS"
fi

#
# Disabled Services Check
#

if [[ -e /etc/httpddisable || -e /etc/httpdisable || -e /etc/httpdisevil || -e /etc/apachedisable ]]; then
    export esp_check_disable_apache=1
    ps_display_warn "httpd-disable touchfile detected, disabling checks for Apache."
fi

if [[ -e /etc/cpimapdisable || -e /etc/imapdisable || -e /etc/imapddisable ]]; then
    export esp_check_disable_mailserver=1
    ps_display_warn "mailserver-disable touchfile detected, disabling checks for Dovecot."
fi

# Check if Exim is disabled
if [ -e /etc/eximdisable ]; then
    export esp_check_disable_exim=1
    ps_display_warn "smtp-disable touchfile detected, disabling checks for Exim."
fi

# Check if CCS is disabled
if [ -e /etc/cpanel-ccsdisable ]; then
    export esp_check_disable_ccs=1
    ps_display_warn "ccs-disable touchfile detected, disabling checks for CCS."
fi

#
# Initial Setup
# -------------
#

# DL_SCRIPTS is the directory where downloaded scripts will be stored
export DL_SCRIPTS="/root/cptechs/scripts"

#
# Editor detection
# ----------------

# This check is to set vim as the editor if avalable reverting back to
# vi if vim is not avalable. Also sets an alias for vim to vi if vim
# is not avalable.    Related Issue [#22]
if [ -f /usr/bin/vim ]; then
    export EDITOR="vim"
    export VISUAL="vim"
else
    export EDITOR="vi"
    export VISUAL="vi"
    alias vim="vi"
fi

# Include cPanel paths in $PATH
# Likely not needed anymore, can confirm tomorrow
export PATH=$PATH:/usr/local/cpanel/scripts/:/usr/local/cpanel/bin/

# Simple Alias to ensure color is not always set to on, that can cause issues with less
alias grep="grep --color=auto "

#
# List directory contents when changing directories.
# ----------------

# shellcheck disable=SC2154
function enable_auto_dir_listing() {	
    alias cd="cl"
    [ -z "$esp_dirlist_maxfiles" ] && export esp_dirlist_maxfiles=150
    [ -n "$esp_debug" ] && echo "Enabled auto directory content listing"
}

function disable_auto_dir_listing() {	
    unalias cd
    [ -z "$esp_dirlist_maxfiles" ] && export esp_dirlist_maxfiles=150
    [ -n "$esp_debug" ] && echo "Disabled auto directory content listing"
}
#
# Script Downloader
# ----------------

function esp_script_dl() {
    local SCRIPT="$1"
    local URL="$2"
    mkdir -p "${DL_SCRIPTS}"
    echo -ne "${YELLOW}${SCRIPT} not found, downloading...${END}"
    wget --quiet -P "${DL_SCRIPTS}" "${URL}"
    chmod u+x "${DL_SCRIPTS}"/*
    echo " ${YELLOW}Complete${END}"
}

#
# PS1 Checks
# ----------
#
# These functions below will be used in the Alerts line in the PS1
#

# This function will check for upcp in the process list,
#  displaying an alert if found.
function check_upcp() {
    # shellcheck disable=SC2154
    if [[ (-z $esp_check_disable_upcp) && (-z $esp_check_disable_all) ]]; then
        if pgrep -f '([c]Panel Update|[u]pcp)' >/dev/null; then
            ps_display_info "upcp"
        fi
    fi
}

# Check for yum lock

function check_yum() {
    # shellcheck disable=SC2154
    if [[ (-z $esp_check_disable_yum) && (-z $esp_check_disable_all) ]]; then
        if [ -f /var/run/yum.pid ]; then
            if pgrep -F /var/run/yum.pid >/dev/null; then
                ps_display_warn "yum"
            else
                ps_display_critical "Stale yum lock"
            fi
        fi
    fi
}

# Check to see if backups are found in the process list

function check_backups() {
    if [[ (-z $esp_check_disable_backup) && (-z $esp_check_disable_all) ]]; then
        if pgrep -f "/usr/local/cpanel/bin/backup|[c]pbackup" >/dev/null; then
            ps_display_warn "Backup (check for false positive)"
        fi
    fi
}

# This check will verify if apache is up and the server status page is found
function check_apache() {
    local httpdown
    local httpdport
    httpdown="Apache is DOWN!"
    httpdport=$(grep 'apache_port' /var/cpanel/cpanel.config | awk -F':' '{print $2}')
    if [[ (-z $esp_check_disable_apache) && (-z $esp_check_disable_all) ]]; then
        curl --silent --connect-timeout 1 http://localhost:"${httpdport}"/whm-server-status >/dev/null
        # shellcheck disable=SC2181
        [[ $? != 0 ]] && ps_display_critical "${httpdown}"
    fi
}

# This check will verify if exim is in the processlist
function check_exim() {
    local exidown="Exim is DOWN!"
    if [[ (-z $esp_check_disable_exim) && (-z $esp_check_disable_all) ]]; then
        if ! pgrep -f "exi[m]" >/dev/null; then
            ps_display_critical "${exidown}"
        fi
    fi
}

# This function uses an mysql ping to check for root mysql connectivity.
# If mysql is up, however if root can not connect to mysql it will fail

function check_mysql() {
    local mysqldown="MySQL is DOWN!"
    if [[ (-z $esp_check_disable_mysql) && (-z $esp_check_disable_all) ]]; then
        if ! mysqladmin ping 2>/dev/null 1>/dev/null; then
            ps_display_critical "${mysqldown}"
        fi
    fi
}

function check_mailserver() {
    local mailserverdown="Mailserver is DOWN!"
    if [[ (-z $esp_check_disable_mailserver) && (-z $esp_check_disable_all) ]]; then
        if ! pgrep -f "dovecot" >/dev/null; then
            ps_display_critical "${mailserverdown}"
        fi
    fi
}

function check_tailwatchd() {
    local tailwatchdown="Tailwatchd is DOWN!"
    # shellcheck disable=SC2154
    if [[ (-z $esp_check_disable_tailwatchd) && (-z $esp_check_disable_all) ]]; then
        if ! pgrep -f "tailwatchd" >/dev/null; then
            ps_display_critical "${tailwatchdown}"
        fi
    fi
}

function check_chkservd() {
    local chkservdsuspended="Chkservd is SUSPENDED!"
    # shellcheck disable=SC2154
    if [[ (-z $esp_check_disable_chkservd) && (-z $esp_check_disable_all) ]]; then
        if [ -e /var/run/chkservd.suspend ]; then
            ps_display_critical "${chkservdsuspended}"
        fi
    fi
}

function check_cpsrvd() {
    local cpsrvdown="cpsrvd is DOWN"
    # shellcheck disable=SC2154
    if [[ (-z $esp_check_disable_cpsrvd) && (-z $esp_check_disable_all) ]]; then
        if ! pgrep -f "cpsrvd" >/dev/null; then
            ps_display_critical "${cpsrvdown}"
        fi
    fi
}

function check_queueprocd() {
    local queueprocddown="queueprocd is DOWN"
    # shellcheck disable=SC2154
    if [[ (-z $esp_check_disable_all) ]]; then
        if ! pgrep -f "queueprocd" >/dev/null; then
            ps_display_critical "${queueprocddown}"
        fi
    fi
}

function check_ccs() {
    local ccsdown="CCS is DOWN!"
    local PATH='/var/cpanel/ccs/ccs-persistance.json'
    if [ -f "$PATH" ]; then
    # shellcheck disable=SC2154
	    if [[ (-z $esp_check_disable_ccs) && (-z $esp_check_disable_all) ]]; then
        	if ! pgrep -f "cpanel-ccs" >/dev/null; then
            ps_display_critical "${ccsdown}"
        	fi
    	fi
    else
	export esp_check_disable_ccs=1
    fi
}

#
# Quick Enable/Disable Checks
# ---------------------------
#

alias ec-all="unset esp_check_disable_all"
alias dc-all="export esp_check_disable_all=1"
alias ec-apache="unset esp_check_disable_apache"
alias dc-apache="export esp_check_disable_apache=1"
alias ec-mysql="unset esp_check_disable_mysql"
alias dc-mysql="export esp_check_disable_mysql=1"
alias ec-exim="unset esp_check_disable_exim"
alias dc-exim="export esp_check_disable_exim=1"
alias ec-mailserver="unset esp_check_disable_mailserver"
alias dc-mailserver="export esp_check_disable_mailserver=1"
alias ec-cpsrvd="unset esp_check_disable_cpsrvd"
alias dc-cpsrvd="export esp_check_disable_cpsrvd=1"
alias ec-yum="unset esp_check_disable_yum"
alias dc-yum="export esp_check_disable_yum=1"
alias ec-backup="unset esp_check_disable_backup"
alias dc-backup="export esp_check_disable_backup=1"
alias ec-tailwatchd="unset esp_check_disable_tailwatchd"
alias dc-tailwatchd="export esp_check_disable_tailwatchd=1"
alias ec-upcp="unset esp_check_disable_upcp"
alias dc-upcp="export esp_check_disable_upcp=1"
alias ec-ccs="unset esp_check_disable_ccs"
alias dc-ccs="export esp_check_disable_ccs=1"

esp_help_edchecks() {
    help_section "Quick Enable/Disable Checks"
    help_command "ec-(all | apache | mysql | exim | mailserver | cpsrvd | yum | backup | ccs | tailwatchd | upcp)" "Enable check for the specified service (or all)"
    help_command "dc-(all | apache | mysql | exim | mailserver | cpsrvd | yum | backup | ccs | tailwatchd | upcp)" "Disable check for the specified service (or all)"
}

#
# SSH Connection Functions
# ------------------------
#
# These functions will save and verify if new connections to the server via ssh are made.
# It stores the active tty/pts sessions and will alert the user if the change.
#

# Function to return the current active tty/pts sessions
function current_connected() {
    /usr/bin/w | awk '{print $2}' | tail -n +3 | sort
}

# Function to check for new connections and display warning if new connections are found.
function new_connected() {
    # shellcheck disable=SC2154
    if [[ (-z $esp_check_disable_ssh) && (-z $esp_check_disable_all) ]]; then
        if [ "$(current_connected)" != "$connected_users" ]; then
            echo -n "${YELLOW}SSH login/logout detected.${END} Use save_connected to dismiss, "
        fi
    fi
}

# Function to save the current users an dismiss the SSH warning
function save_connected() {
    export connected_users
    connected_users=$(current_connected)
}

#
# Command Aliases and help functions
# ----------------------------------
#
#
# Below are the extra commands and help functions for the script
# Each help and alias section is limited to one Category
#

# Misc. Utilities
# ---------------

function jq() {
    if [[ ! -e ${DL_SCRIPTS}/jq ]]; then
        esp_script_dl "jq" "https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64"
        mv "${DL_SCRIPTS}/jq-linux64" "${DL_SCRIPTS}/jq"
    fi
    # shellcheck disable=SC2068,SC2086
    ${DL_SCRIPTS}/jq ${@}
}

# Simple function to check if alias exists.
# Returns 0 if it does, returns 1 if it doesn't
function alias_check() {
    alias "${1}" > /dev/null 2>&1 && return 0;
    return 1;
}

#
# WHM / cPanel
# ------------

#
# Tweak Settings
# Credits: William Little
# -------------

# Check if acctinfo alias is set, if not(like when using a VM), lets just set it.
if ! alias_check acctinfo; then
    alias acctinfo='/usr/local/cpanel/3rdparty/bin/perl <(curl -s https://raw.githubusercontent.com/cPanelInc/tech-acctinfo/master/acctinfo)'
fi

function tweaksettings() {
    if [ "$#" -eq 0 ]; then
        awk -F'=' '/=/{print$1,$2}' /var/cpanel/cpanel.config | while read -r tweak val; do
            printf "${CYAN}Tweak:${END} %s ${CYAN}Value:${END} %s\\n" "$tweak" "$val"
            awk -F':' -v var="$tweak" '$1==var{f=1}/^$/{f=0}f && /label/{gsub(/\047/,"");$1="";print $0}f && /help/{gsub(/\047/,"");$1="";print $0}' /usr/local/cpanel/whostmgr/docroot/themes/x/tweaksettings/Main.yaml
            printf '\n'
        done
    else
        if [ "$#" -eq 1 ] && [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
            cat 1>&2 <<'EOF'
Usage: tweaksettings [-p|--pager] [-t|--tweak] [-h|--help]
This function provides WHM name/description and current values
By default, all values are listed
  -h|--help          print help
  -t|--tweak $tweak  print for given tweak name
  -p|--pager         print all values to pager
EOF
        else
            if [ "$#" -eq 1 ] && [ "$1" == "-p" ] || [ "$1" == "--pager" ]; then
                awk -F'=' '/=/{print$1,$2}' /var/cpanel/cpanel.config | while read -r tweak val; do
                    printf "${CYAN}Tweak:${END} %s ${CYAN}Value:${END} %s\\n" "$tweak" "$val"
                    awk -F':' -v var="$tweak" '$1==var{f=1}/^$/{f=0}f && /label/{gsub(/\047/,"");$1="";print $0}f && /help/{gsub(/\047/,"");$1="";print $0}' /usr/local/cpanel/whostmgr/docroot/themes/x/tweaksettings/Main.yaml
                    printf '\n'
                done | less -Ri
            else
                if [ "$#" -ge 2 ] && [ "$1" == "-t" ] || [ "$1" == "--tweak" ]; then
                    local tweak arg argar i
                    for arg in "$@"; do
                        argar+=("$arg")
                    done
                    for ((i = 1; i < ${#argar[@]}; i++)); do
                        if grep --color=auto -q "^${argar[$i]}:" /usr/local/cpanel/whostmgr/docroot/themes/x/tweaksettings/Main.yaml; then
                            val="$(awk -F'=' -v var="${argar[$i]}" '$1==var{print$2}' /var/cpanel/cpanel.config)"
                            printf "${CYAN}Tweak:${END} %s ${CYAN}Value:${END} %s\\n" "${argar[i]}" "$val"
                            awk -F':' -v var="${argar[$i]}" '$1==var{f=1}/^$/{f=0}f && /label/{gsub(/\047/,"");$1="";print $0}f && /help/{gsub(/\047/,"");$1="";printf $0"\n"}' /usr/local/cpanel/whostmgr/docroot/themes/x/tweaksettings/Main.yaml
                        else
                            printf "${RED}Tweak not found:${END} %s\\n" "$arg"
                        fi
                    done
                fi
            fi
        fi
    fi
}

#
# Enable/Disable Forkbomb protection
# ------------

function fork_bomb_protection() {
    local command=""
    if [[ "$#" -ne 1 ]]; then
        echo "Command only takes 1 argument. Either 'enable' or 'disable'."
        return 1
    fi
    case ${1} in
        enable)
            command="install_profile"
            ;;
        disable)
            command="remove_profile"
            ;;
        *)
            echo "Invalid Argument: ${1}"
            return 1;
            ;;
        esac
    
    /usr/local/cpanel/3rdparty/bin/perl -MCpanel::LoginProfile -le "print [Cpanel::LoginProfile::${command}('limits')]->[1];"
}

function esp_help_tweaksettings() {
    help_section "Tweak Settings"
    help_command "tweaksettings" "Get information on any available Tweak Setting, Args: tweaksettings [-h|--help] [-p|--pager] [-t|--tweak]"
}

#
# Backups
# -------

alias bktxt='date +.cpbak.${TECH}.%F.%T'
# Can discuss if needed, already have a separate function that does something similar
alias backup-report="curl -s --insecure https://raw.githubusercontent.com/CpanelInc/tech-TechScripts/master/backup_report.sh | sh"
function last-cpbackup() {
    if [ -d /usr/local/cpanel/logs/cpbackup ]; then
        # shellcheck disable=SC1001
        less "$(find /usr/local/cpanel/logs/cpbackup/*.log -type f | tail -1)"
    fi
}
function bke() {
    if [ ! -e "$*""$(bktxt)" ]; then bkc "$*"; fi
    vim "$*"
}
function cl() {
    # shellcheck disable=SC1001
    \cd "$@" || return
    # shellcheck disable=SC1001
    if [ "$(find . -maxdepth 1 | wc -l)" -lt "${esp_dirlist_maxfiles}" ]; then
        ls
    else
        echo "Directory listing disabled due to there being more than ${esp_dirlist_maxfiles} files to list"
    fi
}

function bkc() { cp -pav "$*" "$*$(bktxt)"; }
function bkm() { mv -v "$*" "$*$(bktxt)"; }
function b64-encdump() { echo "===" && gzip -c "$1" | base64 && echo "===" && echo "To decode run \"base64 -d <file>|gzip -d\""; }
function b64-encfile() { gzip -c "$1" | base64 >"$1".b64 && echo "Saved to $1.b64"; }
function b64-decfile() { base64 -d "$1" | gzip -d; }
function failed-backup-check() {
    for log in /usr/local/cpanel/logs/cpbackup/*; do
        printf -- "------------------------------\\n%s:\\n" "$log"
        while read -r err; do
            grep "$err" "$log"
        done <<EOF
Unable to get user id
Unable to load cPanel user data
You cannot copy the root user
pkgacct failed to copy daily backup
Could not use daily backup
Bailing out
The REMOTE_PASSWORD variable is missing
Unable to find domain name
Exiting with error code
Could not remove directory
Hook denied execution of pkgacct
Could not open
Could not chmod
Could not rename
failed to create the working dir
Unable to fork
Unable to waitpid
Unable to open
Failure dumping
Unable to read
does not appear to be valid XML
Could not create directory
mysqldump: Got error
mysqldump failed
EOF
    done
    unset log err
}

function backup-destinations() {
    grep -hoP '(?<=^id: ).+' /var/cpanel/backups/*.backup_destination | while read -r i; do /usr/local/cpanel/3rdparty/bin/perl -mCpanel::Backup::Transport -e 'use Data::Dumper; print Dumper(Cpanel::Backup::Transport->new()->get(@ARGV));' "$i"; done
}

esp_help_backup() {
    help_section "Backups"
    help_command "bke <file>" "Automatically creates a new backup of a file and opens the original"
    help_command "bkc <file>" "Makes a backup copy of a file with the standard backup text"
    help_command "bkm <file>" "Moves the file aside, renaming it with the standard backup text"
    help_command "bktxt" "Outputs the standard backup text featuring a timestamp"
    help_command "backup-report" "Returns a backup report"
    help_command "last-cpbackup" "Opens the last cpbackup log in less."
    help_command "b64-encdump <file>" "Dump out a file to terminal in base64."
    help_command "b64-encfile <file>" "Encode to a base64 file (will be named <file>.b64)."
    help_command "failed-backup-check" "Show parts of backup logs which failed"
    help_command "b64-decfile <file>" "Decode from a base64 file out to terminal."
    help_command "backup-destinations" "Print all backup destinations."
}

#
# System Information
# ------------------

alias server-type="strings /var/cpanel/envtype"
# shellcheck disable=SC1117
alias cpu-count="grep proc /proc/cpuinfo |wc -l"
alias cpu-info="grep model\\ name /proc/cpuinfo | sed s/model\\ name//g | uniq -c"
alias last-upcp="less /var/cpanel/updatelogs/last"
alias summ-upcp="less /var/cpanel/updatelogs/summary.log"
# Gonna need to request this be forked into CpanelInc/tech-TechScripts

function sysinfo() {
    TIER="$(grep -i cpanel= /etc/cpupdate.conf | cut -d'=' -f2)"
    INSTALLDATE="$(date -d @"$(stat -t /var/log/cpanel-install.log | awk '{print $14}')")"
    USERCOUNT="$(find /var/cpanel/users -type f | grep -c -E -v '(cp[0-9]{7}|system)')"
    echo "${YELLOW}cPanel Version:${END} $(cat /usr/local/cpanel/version) (Installed on $INSTALLDATE)"
    echo "${YELLOW}Release Tier:${END} ${TIER^}"

    if [[ -f "/etc/redhat-release" ]]; then
        echo "${YELLOW}OS:${END} $(cat /etc/redhat-release)"
    else
        echo "${YELLOW}OS:${END} $(grep "PRETTY" "/etc/os-release" | awk -F'=' '{print $2}' | sed 's/"//g')"
    fi
    echo "${YELLOW}Kernel:${END} $(uname -r)"
    echo "${YELLOW}Arch:${END} $(uname -m)"
    echo "${YELLOW}Environment:${END} $(cat /var/cpanel/envtype)"
    echo "${YELLOW}CPU:${END} $(grep 'model name' /proc/cpuinfo | head -1 | cut -d':' -f2) w/ $(grep -c proc /proc/cpuinfo) cores"
    echo "${YELLOW}Uptime:${END} $(uptime)"
    echo "${YELLOW}cPanel Users:${END} ${USERCOUNT}"
}

# Credits to William Little
function lst() {
    if [[ "$#" -eq 0 ]]; then
        local cwd
        cwd="$(pwd)"
        for each in ${cwd//\// }; do
            full+="/$each"
            # shellcheck disable=SC1001
            \stat -c '%a %U:%G(%u:%g) %F %n' "$full"
        done
        unset full each
    fi
    local i
    for i in "$@"; do
        for each in ${i//\// }; do
            full+="/$each"
            # shellcheck disable=SC1001
            \stat -c '%a %U:%G(%u:%g) %F %n' "$full"
            if [[ -f "$full" ]]; then
                sym="$(readlink -q "${full}")"
                if [[ "${sym:=null}" == null ]]; then
                    # shellcheck disable=SC1001
                    \lsattr "$full"
                else
                    # shellcheck disable=SC1001
                    \lsattr "$sym"
                fi
                unset sym
            fi
        done
        printf "\\n"
        unset full each
    done
}

function esp_help_sys-info() {
    help_section "System Information"
    help_command "sys-snap-install" "Installs sys-snap"
    help_command "sys-snap-start" "Starts sys-snap if already installed"
    help_command "cpu-count" "Displays the number of cpus installed"
    help_command "cpu-info" "Displays the number and type of CPUs installed"
    help_command "server-type" "Returns the server type from /v/c/envtype"
    help_command "last-upcp" "Displays the last UPCP log"
    help_command "summ-upcp" "Displays the UPCP Summary log"
    help_command "sysinfo" "Displays various system information items"
    help_command "lst" "Display directory (cwd) info"
    help_command "netspeed" "Run a network speed test (from speedtest.net)"
}

#
# Network Information
# -------------------

alias lsip='ifconfig | grep "inet addr"| grep -v "127.0.0.1"'
alias lsip-real="curl -s -4 http://myip.cpanel.net/v1.0"
alias lsip-mainip="strings /var/cpanel/mainip"
# undocumented shortcut for marco
alias localips='ips'

function ips() {
    ips="$(ifconfig | awk '/inet/ {if ($2!~/127.0|:$/) print $2}' | awk -F: '{print $2}')"
    echo "${ips}"
}

function fcrdns() {
    if [ -n "$1" ]; then
        esp_fcdns_check "$1"
    else
        # shellcheck disable=SC1001
        for IP in $(cat /var/cpanel/mainip && echo -e "" && awk '{print $1}' </etc/ips | cut -d \: -f 1); do
            esp_fcdns_check "$IP"
        done
    fi
}

function esp_fcdns_check() {
    local ip_to_check
    local rdns
    local rdns_ip

    ip_to_check="$1"
    rdns="$(dig @4.2.2.2 +time=1 +short -x "${ip_to_check}")"
    if [ -z "${rdns}" ]; then
        rdns="Failed"
        rdns_ip="N/A"
    else
        rdns_ip="$(dig @4.2.2.2 +time=1 +short -x "${ip_to_check}" | xargs dig +short)"
    fi
    if [ "${ip_to_check}" = "${rdns_ip}" ]; then
        echo "${YELLOW}${ip_to_check}${GREEN} PASSED FCrDNS validation ${END}${ip_to_check}${YELLOW}->${END}${rdns}${YELLOW}->${END}${rdns_ip}"
    else
        echo "${YELLOW}${ip_to_check}${RED} FAILED FCrDNS validation ${END}${ip_to_check}${YELLOW}->${END}${rdns}${YELLOW}->${END}${rdns_ip}"
    fi
}

function dbug-assl() {
    local domain
    domain="$1"
    /usr/local/cpanel/3rdparty/bin/perl -MCpanel::DnsRoots -e 'use Data::Dumper; print Dumper(Cpanel::DnsRoots::Resolver->new(debug => 1)->recursive_query("'"${domain}"'","A"));'
}

function esp_help_net() {
    help_section "Network Information"
    help_command "ips" "Quick listing of the IP addresses on the server, and only the ips (one per line)"
    help_command "lsip" "Displays all the ip addresses with subnet and Bcast addresses"
    help_command "lsip-real" "Displays the external ip address of the server seen by the internet."
    help_command "lsip-mainip" "Displays cPanel's mainip from /v/c/mainip"
    help_command "dbug-assl" "Debug a domain on AutoSSL"
    help_command "fcrdns" "Checks the rDNS and Forward-confirmed reverse DNS of all IPs, or an IP you specify"
}

#
# SSL
# ---

alias ssl-verify='openssl x509 -noout -text -in'

function sslshort() { openssl x509 -noout -text -in "$1" | grep -E "Issuer|Subject:|^[ ]*Not"; }

function esp_help_ssl() {
    help_section "SSL"
    help_command "ssl-verify" "Alias for openssl x509 -noout -text -in used to test certs"
    help_command "sslshort" "Brief output of ssl-verify, basically just the output you need."
}

#
# AutoSSL & Hostname SSL
# ----------------------

alias autossl-provider="python -m json.tool /var/cpanel/autossl.json | grep provider | grep -v properties"
alias hostname-ssl="/usr/local/cpanel/bin/checkallsslcerts --allow-retry --verbose"

function autossl-queue() {
    JSONFILE='/var/cpanel/autossl_queue_cpanel.json'
    SQLITE='/var/cpanel/autossl_queue_cpanel.sqlite'
    SQLITECMD='/usr/local/cpanel/3rdparty/bin/sqlite3'
    if [ ! -f $SQLITECMD ]; then
        die "cPanel SQLite Binary not found"
        return 1
    fi

    if [ -f $SQLITE ]; then
        while read -r line; do
            OID=$(echo "$line" | awk '{print $1}')
            VHOST=$(echo "$line" | awk '{print $2}')
            echo "Domain: ${VHOST}"
            echo "Order ID: ${OID}"
            echo -e "=========="
        done < <($SQLITECMD -separator ' ' $SQLITE 'SELECT order_item_id,vhost_name FROM requests')
    else
        echo "This server is still using the old JSON queue."
        echo "Support for this will be added to ESP soon. For now,"
        echo "manually lookup the certificate in Manage2"
        echo -e "\\n -- OR -- \\n"
        echo "python -m json.tool ${JSONFILE}"

    fi
}

function autossl-exclude() {
    local USER=${1}
    local PATH='/var/cpanel/ssl/autossl/excludes/'${1}'.json'
    if [ -f "$PATH" ]; then
        /usr/bin/python -m json.tool "${PATH}"
    else
        echo "${RED}User does not have any AutoSSL excluded domains or does not exist${END}"
    fi
}

function esp_help_AutoSSL() {
    help_section "AutoSSL"
    help_command "autossl-provider" "Checks the AutoSSL provider"
    help_command "hostname-ssl" "Runs the checkallsslcerts script"
    help_command "autossl-queue" "Parses AutoSSL queue (currently only sqlite)"
    help_command "autossl-rewrite" "Prints the current RewriteConditions needed for DCV checks"
    help_command "autossl-exclude" "Checks for AutoSSL excluded domains, usage: autossl-exclude <username>"
}

#
# Exim & Mail
# -----------

# Need to see if Peter can get this added to CpanelInc or if even needs to be in here
function rblcheck() {
    if [[ ! -e ${DL_SCRIPTS}/rblcheck ]]; then
        esp_script_dl rblcheck "https://raw.githubusercontent.com/cPanelPeter/rblcheck/master/rblcheck"
    fi

    # shellcheck disable=SC2068,SC2086
    ${DL_SCRIPTS}/rblcheck ${@}
}

function msp() {
    if [[ ! -e ${DL_SCRIPTS}/msp.pl ]]; then
        esp_script_dl msp.pl "https://raw.githubusercontent.com/CpanelInc/tech-SSE/master/msp.pl"
    fi

    # shellcheck disable=SC2068,SC2086
    ${DL_SCRIPTS}/msp.pl ${@}
}

function sse() {
    echo "sse has been renamed to msp, please use msp going forward"
    msp "${@}"
}

function esp_help_mail() {
    help_section "Exim & Mail"
    help_command "rblcheck" "Checks common blacklists for listings"
    help_command "sse" "Runs SSE Mail Checker"
}

#
# MySQL
# -----
alias mysqlerr='less /var/lib/mysql/$(hostname).err'

function esp_help_mysql() {
    help_section "MySQL & Databases"
    help_command "mysqlerr" "Opens the MySQL error log in less"
}

#
# PHP & Apache
# ---
alias phpinfo="/usr/local/cpanel/bin/rebuild_phpconf --current"
# Leaving this in since it's good for backup
alias ea-info="curl -s https://raw.githubusercontent.com/CpanelInc/tech-TechScripts/master/ea-precheck.sh | sh"

function add_tmp_lsws_admin_access() {
	local lsws_dir="/usr/local/lsws/admin"
	local tmp_pass='cpanel1234'
	local encrypt_pass
	local check_access

	encrypt_pass="$(${lsws_dir}/fcgi-bin/admin_php5 -q ${lsws_dir}/misc/htpasswd.php ${tmp_pass} )"

	echo "Backing up original htpasswd"
	cp -v "${lsws_dir}"/conf/htpasswd "${cptechdir}"/lsws_htpasswd_backup
	echo ""

	echo "Adding temp credentials to htpasswd"
	echo "${TECH}:${encrypt_pass}" | tee --append "${lsws_dir}"/conf/htpasswd
	echo ""

	check_access=$(grep -c "${TECH}" "${lsws_dir}"/conf/htpasswd)

	if [[ "${check_access}" -ge 1 ]]; then
		echo "Authorized Litespeed Web Admin access"
		printf "  User: %s\n  Pass: %s\n" "${TECH}" "${tmp_pass}"
	fi
}

function del_tmp_lsws_admin_access() {
	if [[ -f ${cptechdir}/lsws_htpasswd_backup ]]; then
	
		printf "\nMoving htpasswd with temp credentials\n\n"
		mv -v /usr/local/lsws/admin/conf/htpasswd "${cptechdir}"/lsws_tmp_htpasswd-"$(date +%s)" && \
	                printf "\n\nMoving original htpasswd back.\n\n" && \
			mv -v "${cptechdir}"/lsws_htpasswd_backup /usr/local/lsws/admin/conf/htpasswd && \
			printf "\nTemporary admin access removed.\n\n"
	else
		echo "${cptechdir}/lsws_htpasswd_backup does not exist and temporary credentials must be manually removed."
	fi 
}

function webstats-probe() {
    if [[ ! -e ${DL_SCRIPTS}/webstatsprobe.pl ]]; then
        esp_script_dl webstatsprobe.pl "https://raw.githubusercontent.com/CpanelInc/tech-WebStatsProbe/master/webstatsprobe.pl"
    fi

    # shellcheck disable=SC2068,SC2086
    ${DL_SCRIPTS}/webstatsprobe.pl ${@}
}

# Credits to William Little
function create-phpinfo() {
    if [[ "$#" -eq 0 ]]; then
        cwd="$(pwd)"
        if [[ "$cwd" =~ ^/home.?/.+ ]]; then
            _user="$(awk -F'/' '{print$3}' <<<"$cwd")"
            if [ ! -f "$cwd"/phpinfo.php ]; then
                printf 'Creating %s/phpinfo.php... ' "$cwd"
                printf '<?php phpinfo(); ?>\n' >>"$cwd"/phpinfo.php
                printf "chown'ing... "
                chown "$_user". "$cwd"/phpinfo.php
                printf "Done: %s/phpinfo.php\\n" "$cwd"
            else
                printf "%s/phpinfo.php already exists!\\n" "$cwd"
                # shellcheck disable=SC1001
                \ls -lah "$cwd"/phpinfo.php
            fi
        else
            printf "CWD doesn't appear valid: %s\\n" "$cwd"
        fi
        unset cwd _user
    elif [[ "$#" -eq 1 ]]; then
        if [[ "$1" == -p ]]; then
            printf '<?php phpinfo(); ?>\n'
        fi
    elif [[ "$#" -gt 1 ]]; then
        if [[ "$1" == -d ]]; then
            local dom
            for dom in "${@:2}"; do
                if [[ "$dom" =~ .+\..+ ]]; then
                    doc="$(awk -F':' -v var="${dom}" '$1==var{split($2,path,"=="); print path[5]}' /etc/userdatadomains)"
                    _user="$(awk -F'[: =]' -v var="$dom" '$1==var{print$3}' /etc/userdatadomains)"
                    if [[ ! "${doc:=null}" == null ]]; then
                        if [ ! -f "$doc"/phpinfo.php ]; then
                            printf 'Creating %s/phpinfo.php... ' "$doc"
                            printf '<?php phpinfo(); ?>\n' >>"$doc"/phpinfo.php
                            printf "chown'ing... "
                            chown "$_user". "$doc"/phpinfo.php
                            printf "Done: %s/phpinfo.php\\n" "$doc"
                        else
                            printf "%s/phpinfo.php already exists!\\n" "$doc"
                            # shellcheck disable=SC1001
                            \ls -lah "$doc"/phpinfo.php
                        fi
                    else
                        printf "Couldn't find %s in /etc/userdatadomains\\n" "$dom"
                    fi
                else
                    printf "%s is not a valid domain\\n" "$dom"
                fi
            done
        fi
    else
        printf "Unrecognized arg\\n"
    fi
}

function esp_help_PHP_Apache() {
    help_section "PHP & Apache"
    help_command "phpinfo" "Displays PHP handler information"
    help_command "ea-info" "Runs a cPanel script to test EA information (ea-precheck.sh)"
    help_command "webstats-probe" "Probe webstats to see what is going on"
    help_command "create-phpinfo" "Create PHP Info file under <user>"
    help_command "vhostphp" "Display PHP handler information for vhost"
}

#
# EasyApache 4
# ------------
alias fix-ea4-symlinks="/etc/yum/universal-hooks/multi_pkgs/posttrans/ea-__WILDCARD__/060-setup_apache_symlinks.pl"

# Credits to William Little
function vhostphp() {
    test -f /usr/local/cpanel/bin/whmapi1 || {
        printf >&2 "whmapi1 not found\\n"
        return
    }
    test -f /etc/cpanel/ea4/is_ea4 || {
        printf >&2 "Not EA4\\n"
        return
    }
    if [ "$#" -eq 0 ]; then
        /usr/local/cpanel/bin/whmapi1 php_get_vhost_versions | awk '/ +vhost:/{print $2,ver} {ver=$2}'
    else
        vhosts="$*"
        /usr/local/cpanel/bin/whmapi1 php_get_vhost_versions | awk '/ +vhost:/{print $2,ver} {ver=$2}' | grep -E "${vhosts// /|}"
    fi
}

function esp_help_EA4_PHP() {
    help_section "EasyApache 4 PHP Binaries"
    help_command "fix-ea4-symlinks" "Fixes missing EasyApache 4 symlinks"
    help_command "vhostphp <domain.tld>" "Gets PHP version used by a domain through WHM API1 (no argument returns PHP version used by each VirtualHost"
}

#
# Bash Navigation
# ---------------

alias cl-off="unalias cd"
alias badcd="unalias cd"
alias cl-on="alias cd=cl"
alias up="cd .."
alias la="ls -lah"

function esp_help_bash_nav() {
    help_section "Bash Navigation"
    help_command "cl directory" "Changes into a directory and outputs a ls"
    help_command "cl-on" "Enables cl for the cd command"
    help_command "cl-off" "clears the alias for cd=cl"
    help_command "la" "Alias for 'ls -lah'"
    help_command "up" "Jumps into the parent directory aka cd .."
    help_command "badcd" "Useful when the automatic cd&ls is messing up"
}

#
# Migrations
# ----------

alias cpeval2="curl -sk https://raw.githubusercontent.com/CpanelInc/cpeval2/master/cpeval2 | perl"
alias updateuserdomains-universal="lwp-request http://httpupdate.cpanel.net/cpanelsync/transfers_PUBLIC/pkgacct/ updateuserdomains-universal | perl"

# Discuss if this needs to be in here, last commit was 5 years ago
function cpmig() {
    if [[ ! -e ${DL_SCRIPTS}/cpmig.sh ]]; then
        esp_script_dl cpmig.sh "https://raw.githubusercontent.com/CpanelInc/cPMigration/PUBLIC/cpmig.sh"
    fi

    # shellcheck disable=SC2068,SC2086
    ${DL_SCRIPTS}/cpmig.sh ${@}
}

function esp_migrations() {
    help_section "Migration Tools"
    help_command "cpmig" "cPanel Migration Script"
    help_command "cpeval2" "cpeval2 Migration Script"
    help_command "updateuserdomains-universal" "Creates required files for cpeval2"
}

#
# VIRTFS TOOLBOX Commands
# --------------------------

function virtfs_mounts() {
    local USER=$1
    /usr/local/cpanel/3rdparty/bin/perl -MCpanel::Filesys::Virtfs -MData::Dumper -e 'my @blah = Cpanel::Filesys::Virtfs::get_virtfs_mounts(); foreach (@blah) { $_ =~  /((\/\w+)*\/?)/; print $1."\n"; }'
}

function virtfs_exim_deps() {
    local USER=$1
    /usr/local/cpanel/3rdparty/bin/perl -MCpanel::Filesys::Virtfs -MData::Dumper -e 'my @blah = Cpanel::Filesys::Virtfs::get_exim_deps(); foreach (@blah) { $_ =~  /((\/\w+)*\/?)/; print $1."\n"; }'
}

function virtfs_mount_points() {
    local USER=$1
    /usr/local/cpanel/3rdparty/bin/perl -MCpanel::Filesys::Virtfs -MData::Dumper -e 'my @blah = Cpanel::Filesys::Virtfs::get_virtfs_mount_points(); foreach (@blah) { $_ =~  /((\/\w+)*\/?)/; print $1."\n"; }'
}

function esp_help_virtfs() {
    help_section "Various utilities for obtaining virtfs information"
    help_command "virtfs_mounts" "Prints out the currently mounted virtfs mounts."
    help_command "virtfs_exim_deps" "Prints out virtfs exim dependencies"
    help_command "virtfs_mount_points" "Prints out all current virtfs mount points on the server"
}

#
# Other and Special Commands
# --------------------------

alias ssp="curl -sl https://ssp.cpanel.net/run | sh "
alias bugreport="curl -sl https://ssp.cpanel.net/run|sh -s -- --bugreport"
alias ssp-csi="curl -sk https://ssp.cpanel.net/run|sh -s -- --csi"
alias wo="/usr/local/cpanel/scripts/whoowns"
alias ccrpms="/usr/local/cpanel/scripts/check_cpanel_rpms"
alias fdrpms="/usr/local/cpanel/scripts/autorepair fix_duplicate_cpanel_rpms"
alias fixscreen="/bin/rpm --setugids screen && rpm --setperms screen"
alias cpversion="cat /usr/local/cpanel/version"
alias follow-upcp="/scripts/upcp --force --bg && tail -f /var/cpanel/updatelogs/last"

function csi() {
    if [[ ! -e ${DL_SCRIPTS}/csi.pl ]]; then
        esp_script_dl csi.pl "https://raw.githubusercontent.com/CpanelInc/tech-CSI/master/csi.pl"
    fi

    # shellcheck disable=SC2068,SC2086
    ${DL_SCRIPTS}/csi.pl ${@}
}

function pphist() {
    (
        IFS=$'\t'
        for i in "$@"; do perl -e 'my $lastts=0;$login=0;while(<>) { chomp; if(/^#((?:\d){10})$/) { $lastts=$1;  } elsif (m,^(export (PS1|LANG|HISTFILE|HISTFILESIZE)=.+|if \[ -x /scripts/autorepair.+|uname -a|alias rm=.echo .Are you sure.+|curl https://ssp.cpanel.net/run.sh|echo -ne ..033.0;cPTKT.+)$,) { $login=1;  } else { print "\n" if($login);$login=0;print  "".localtime($lastts)." $_\n"; }  }' <"${i}"; done
    )
}

function prepare_strace() {
    TSTAMP="$(date '+%Y%m%d-%H%M%S')"
    TDIR="${cptechdir}/strace-${TSTAMP}"
    mkdir -p "${TDIR}"
    echo "Working Directory: ${TDIR}"
}

# disable 2046 due to weird issues when quoting the $() stuff
# shellcheck disable=SC2046
function strace-cpsrvd() {
    prepare_strace
    if [[ ${OS_MAJOR_VER} == 7 ]]; then
	local PGREP="pgrep -a" 
    else
	local PGREP="pgrep"
    fi

    strace -vvttffT -s "${STRACESTRLEN}" -o "${TDIR}"/pid $(${PGREP} 'cpsrv[d]|whostmgr[d]|cpanel[d]|webmail[d]' | grep -E -v 'defunct' | tee "${TDIR}"/process-list.txt | awk '{ printf " -p "  $1; }')
}

# disable 1001 to ignore the regular / warning
# shellcheck disable=SC1001
function strace-phpuser() {
    prepare_strace

    local STRUSER
    local x
    local process

    STRUSER=$(pwd | cut -d \/ -f 3)
    x="1"

    killall -6 -u "${STRUSER}"

    while [ $x = 1 ]; do
        process=$(pgrep -u "${STRUSER}")
        if [ "${process}" ]; then
            x=0
        fi
    done

    strace -vvttffT -s "${STRACESTRLEN}" -o "${TDIR}"/pid -p "${process}"
}

# disable 2046 due to weird issues when quoting the $() stuff
# shellcheck disable=SC2046
function strace-httpd() {
    prepare_strace
    if [[ ${OS_MAJOR_VER} == 7 ]]; then
	local PGREP="pgrep -a" 
    else
	local PGREP="pgrep"
    fi
    strace -vvttffT -s "${STRACESTRLEN}" -o "${TDIR}"/pid $(${PGREP} httpd | grep -E -v 'defunct' | tee "${TDIR}"/process-list.txt | awk '{print "-p " $1 }')
}

# shellcheck disable=SC2013
# Written by Aaron Horsely and modified by Terrance Robotham
function saroverview() {
    BC='/usr/bin/bc'
    if [ -f $BC ]; then
        clear
        echo "== Server Time: =="
        date '+%F %r'
        echo -e "\\n== Memory Utilization Information: =="
        free -m | awk '{ if ($1 == "Mem:") { TOTAL=$2; USED=$3; FREE=$4; } if ($1 == "-/+") { BUFFERS=$3; CACHE=$4; } } END {printf "Total Memory\tActive Memory\tPercentage Used\n%dM\t\t%dM\t\t%.2f%%\n",TOTAL,BUFFERS,BUFFERS/TOTAL * 100; }'
        echo -e "\\n== Current Swap Usage: =="
        swapon -s | sed 1d | awk 'BEGIN { print "DEVICE\t\tUSED\t\tTOTAL\t\tPERCENT USED"; } { DEVICE=$1; TOTAL=($3/1024); USED=($4/1024); PERCENT=((USED/TOTAL)*100); printf "%s\t%.2fM\t%.2fM\t%.2f%%\n",DEVICE,USED,TOTAL,PERCENT; }' | column -s$'\t' -t
        echo -e "\\n== Top 10 Processes by Memory Usage: =="
        ps -eo user,pid,%mem,rsz,args --sort=-rsz | head -11 | awk '{print $1,$2,$3,$4,$5}' | column -t
        echo -e "\\n== Top 10 Processes By Swap Usage: =="
        (
            printf "%s\\t%s\\t%s\\n" "PID" "PROCESS" "SWAP"
            (for i in /proc/[0-9]*; do
                PROC=${i#/proc/}
                NAME=$(ps -p "${PROC}" -o comm --no-headers)
		for SWAP in $(grep Swap "${i}"/smaps 2>/dev/null | awk '{print $2}'); do (( SUM=SUM+SWAP )); done
                echo "${PROC} ${NAME} $(echo "scale=2; ${SUM}/1024" | bc)M"
                SUM=0
            done | grep -Pv '\b0M$' | sort -grk3,3 | head -10)
        ) | column -t
        echo -e "\\n== Top 10 Kernel Slab Caches: =="
        (
            echo "SIZE NAME"
            slabtop -o -s c | sed 1,7d | head -10 | awk '{ printf "%.2fM\t%s\n",gensub(/K$/,"","g",$(NF-1))/1024,$NF; }'
        ) | column -t
        echo -e "\\n== Last 30 Minutes Memory Usage: =="
        sar -r -s "$(date --date='-50 minutes' +%T)" | sed 1,2d
        echo -e "\\n== Last 30 Minutes Paging/Swap Statistics: =="
        sar -B -s "$(date --date='-50 minutes' +%T)" | sed 1,2d
        if [[ -f /tmp/sar-tempfile ]]; then forceremove /tmp/sar-tempfile; fi
        sar -B -r -o /tmp/sar-tempfile 1 10 >/dev/null
        echo -e "\\n== Current 1 Second Memory Usage Statistics (10 Count): =="
        sar -r -f /tmp/sar-tempfile | sed 1,2d
        echo -e "\\n== Current 1 Second Paging/Swap Statistics (10 Count): =="
        sar -B -f /tmp/sar-tempfile | sed 1,2d
        if [[ -f /tmp/sar-tempfile ]]; then forceremove /tmp/sar-tempfile; fi
    else
        echo "${RED}bc is not installed${END}"
    fi
}

function jsonpp() {
    # shellcheck disable=SC2211
    /usr/local/cpanel/3rdparty/perl/5*/bin/json_xs <"${1}"
}

function genpass() {
    STR=${1}
    STR="${STR:=14}"
    /usr/local/cpanel/3rdparty/bin/perl -MCpanel::PasswdStrength::Generate -e "print Cpanel::PasswdStrength::Generate::generate_password($STR)"
}

function getsum() {
    FILE=${1}
    for PRG in {md5,sha1,sha256,sha512}sum; do "${PRG}" "${FILE}"; done
}

function oddthings() {
    echo "${BOLD}oddthings${END}"
    lsof -Pni | grep -vE ':80|:443|:7984|:8984|imap|postgres|pop3|named|cpdavd|dovecot|exim|mysql|pure|pro|sshd|cpsrvd|spamd|ntpd|cPhulkd'
}

function showips() {
    ifconfig | awk '/127\./ { next; } /inet /{ print $2 }'
}

function docroot() {
    OWNER=$(/scripts/whoowns "${1}")
    cd "$(grep documentroot /var/cpanel/userdata/"${OWNER}"/"${1}" | cut -d' ' -f2)" || return
}

# shellcheck disable=SC2181
function genaccesshash() {
    if [ -z "${1}" ]; then
        UNAME='root'
    else
        UNAME=${1}
    fi
    echo "Generating hash for ${UNAME}.."
    /usr/local/cpanel/bin/mkaccesshash "${UNAME}"
    if [ $? -eq 0 ]; then
        echo "Access hash generated."
    fi
}

function createsess() {
    if [[ ${#} -lt 1 ]]; then
        echo "Must supply a User"
        echo "Ex. - createsess <user> [service]"
        return
    fi
    USER="${1}"
    if [[ -n ${2} ]]; then
        case "${2}" in
        whm)
            SERVICE='whostmgrd'
            ;;
        cpanel)
            SERVICE='cpaneld'
            ;;
        webmail)
            SERVICE='webmaild'
            ;;
        *)
            SERVICE="${2}"
            ;;
        esac
    else
        SERVICE='whostmgrd'
    fi
    whmapi1 create_user_session user="${USER}" service="${SERVICE}" locale="en"
}

function gendcv() {
    FILE=${1}
    CSRFILE=$(grep -v CERTIFICATE "${FILE}" | base64 -d | md5sum | awk '{print toupper($1)".txt"}')
    echo "$(
        grep -v CERTIFICATE "${FILE}" | base64 -d | sha256sum | awk '{print $1}'
        echo "comodoca.com"
    )" >"${CSRFILE}"
    echo "Created: ${CSRFILE}"
}

# shellcheck disable=SC2068,SC2086
function get_domain_status() {
    DOMAINS=$(awk -F':' '{print $1}' /etc/userdomains | grep -v "\\*")
    for d in ${DOMAINS[@]}; do
        curl -sIL "${d}" >/dev/null
        case $? in
        6)
            echo "${d}  |  Unable to resolve host" #| column -t -s'|' -o '  |  '
            ;;
        0)
            echo "${d}  |  $(curl -sIL "${d}" | grep HTTP | tail -n 1)" #| column -t -s'|' -o '  |  '
            ;;
        *)
            echo "${d}  |  $(curl -sSIL "${d}" 2>&1)" #| column -t -s'|' -o '  |  '
            ;;
        esac
    done
}

# shellcheck disable=SC2068,SC2086,SC2059,SC1117
function domain_check() {
    header="Domain|Result"
    status=$(get_domain_status)
    printf "${header}\n=========|======================\n${status}" | column -t -s'|' -o '  |  '
    echo ""
}

# shellcheck disable=SC2199,SC2059
function get-requires() {
    if [[ -z ${@} ]]; then
        echo "Must provide at least 1 RPM package name"
        return 1
    fi
    for pkg in "${@}"; do
        printf "\\n#######\\n ${pkg} \\n#######\\n\\n"
        rpm --test -e "${pkg}"
        printf "\\n#######\\n ${pkg} \\n#######\\n\\n"
    done
}

function esp_help_other() {
    help_section "Other and Special Commands"
    help_command "save_connected" "saves out the current SSH logins and dismisses the SSH login alert"
    help_command "ssp" "Run SSP"
    help_command "bugreport" "SSP bug report template"
    help_command "cphelp" "This help message"
    help_command "oddthings" "Shows odd things that are running on odd ports"
    help_command "wo" "Alias for /scripts/whoowns"
    help_command "showips" "Show server IPs"
    help_command "docroot <domain>" "Show document root for domain"
    help_command "genaccesshash <user>" "Generate access hash (for optional user)"
    help_command "ccrpms" "Alias for /scripts/check_cpanel_rpms"
    help_command "fdrpms" "Fix duplicate cPanel RPMs"
    help_command "csi" "Runs CSI"
    help_command "cpscan" "Runs cPScan"
    help_command "cpdoctor" "Runs cPDoctor"
    help_command "fixscreen" "Fix screen permissions/ownership"
    help_command "compare-mirrors" "cPanel mirrors comparison script"
    help_command "jsonpp" "JSON Pretty Print"
    help_command "createreseller" "Create cPanel reseller account"
    help_command "pphist <file>" "PrettyPrint History"
    help_command "genpass <num>" "Generate random Password"
    help_command "getsum <file>" "Generate hash sums for a file"
    help_command "createsess <user> <service>" "Creates session for user"
    help_command "gendcv <file>" "Generates DCV against CSR file"
    help_command "cpversion" "Print the cPanel version installed on the server"
    help_command "follow-upcp" "Start upcp in the background and tail the log file to follow progress"
    help_command "saroverview" "Show general overview with SAR"
    help_command "xscreen <socket_name> <command>" "Launches a screen session that executes the command provided. Screen session socket name is set with with the name provided"
    help_command "transfer <file>" "Transfers file to transfer.sh"
    help_command "domain_check" "Runs a cURL test on all domains in /etc/userdomains and outputs the results in a table"
    help_command "get-requires" "Runs a test to check what packages require the packages passed into the function"
    help_command "strace-cpsrvd" "Runs an strace against cpsrvd and friends."
    help_command "strace-phpuser" "Runs an strace against the first PHP process that spawns for user (must be in user's homedir)"
    help_command "strace-httpd" "Runs an strace against httpd."
}

#
# Functions to assist with displaying the help section
# ----------------------------------------------------

function help_section() {
    printf "\\n\\n${YELLOW}${BOLD} .: %s :. ${END}\\n" "$1"
}

function help_command() {
    printf "${GREEN}${BOLD}%16s ${END}%s\\n" "$1" "$2"
}

#
# The Actual Help Section
#
function cphelp() {
    esp_help_edchecks
    esp_help_tweaksettings
    esp_help_backup
    esp_help_sys-info
    esp_help_net
    esp_help_ssl
    esp_help_AutoSSL
    esp_help_mail
    esp_help_mysql
    esp_help_PHP_Apache
    esp_help_EA4_PHP
    esp_help_bash_nav
    esp_migrations
    esp_help_virtfs
    esp_help_other
}
#
# Setup some envs for the PS1 prompt
# ----------------------------------
HOSTNAME=$(hostname -f)
PS1_IP=$(curl -s -4 http://myip.cpanel.net/v1.0)
IP_ADDR=$(curl -s -4 http://myip.cpanel.net/v1.0)

export HOSTNAME
export PS1_IP
export IP_ADDR
#
# Set the functions active in the Prompt
# --------------------------------------

# shellcheck disable=SC2205
function PS1_Alerts() {
    (echo -ne "$(check_yum)$(check_cpsrvd)$(check_tailwatchd)$(check_chkservd)$(check_mailserver)$(check_upcp)$(check_backups)$(check_apache)$(check_queueprocd)$(check_ccs)$(new_connected)$(check_exim)$(check_mysql)") &
    local esp_echo_pid=$!
    local esp_adtempts=100
    local esp_alert_check_no=0
    local pid_check
    while [ "$(
        pid_check=$(ps --no-headers -p "${esp_echo_pid}" -o pid)
        if [ -z "$pid_check" ]; then echo "0"; else echo "1"; fi
    )" -eq 1 ]; do
        sleep 0.05
        if [ "$esp_alert_check_no" -gt "$esp_adtempts" ]; then
            kill "$!" >/dev/null
            echo "${RED}${BOLD}ESP CRITICAL ERROR!"
            echo -ne "${END}${YELLOW}"
            printf "It appears that the ESP alert checks hung, resultingi\\nin an safety timeout to kill the ESP alert checks to\\nprevent ESP from haning the entire shell.\\n\\nThis issue is often caused when an server is underi\\na DDoS attack causing the Apache check to hang when\\ndownloading the server status.  Please disable the\\nApache check with the following command:"
            echo "${MAGENTA}    # dc-apache${YELLOW}"
            printf "If you continue to see this DANGER ZONE message after\\ndisabling the Apache check it is recommended to\\ndisable all ESP Alert checks with this command:"
            echo "${MAGENTA}    # dc-all${CYAN}"
            echo "Please report this issue on github at the link below."
            echo "https://git.cpanel.net/a.lateef/ESP/-/issues"
        else
            esp_alert_check_no=$((esp_alert_check_no + 1))
        fi
    done
}

# set title bar name
echo -ne "\\033]0;cPTKT ${TICKET} - ESP\\007"

# Enable window size checking
shopt -s checkwinsize

export PROMPT_COMMAND=set_prompt

# shellcheck disable=SC2181
function set_prompt() {
	if [ -z "${NOPS1}" ]; then
	    PS1="\\n\\[${WHITE}\\][\\[${YELLOW}\\]\\H\\[${WHITE}\\]|\\[${YELLOW}\\]${IP_ADDR}\\[${WHITE}\\]] \\[${CYAN}\\][Alerts: $(PS1_Alerts)]\\n\\[${WHITE}\\][\\[${YELLOW}\\]\\D{%T}\\[${WHITE}\\]]\\[${END}\\]\\[${WHITE}\\][\\[${YELLOW}\\]${TICKET}\\[${WHITE}\\]]\\[${END}\\]\\[${WHITE}\\][\\[${GREEN}\\]\\w\\[${WHITE}\\]]\\[${CYAN}\\]\$\\[${END}\\] "
	    export PS1
	fi
}


save_connected

if [ "${SSP}" == "1" ]; then
    ssp
fi

if [ "${ESP_DIRLIST_ENABLED}" == "1" ]; then
    enable_auto_dir_listing
fi

#
# ESP hook for Post Startup
# -------------------------

if [ "$(declare -Ff esp_hook_post)" == "esp_hook_post" ]; then
    esp_hook_post
fi

echo
echo "${YELLOW}${BOLD}ESP version${END} ${WHITE}${BOLD}${VERSION}${END} ${YELLOW}${BOLD}loaded.${END}"
echo
echo "${YELLOW}${BOLD}Use cphelp for a listing of the extra commands available."
echo
echo "Hello ${TECH}! Successfully logged into ${TICKET}"
echo "${END}"
