Ptachirana skripta zbog vlasništva nad last-version-check.txt
[clamav-unofficial-sigs.git] / clamav-unofficial-sigs
index f6b8e8b..28c39e2 100755 (executable)
-#!/bin/bash
+#!/usr/bin/env bash
+# shellcheck disable=SC2119
+# shellcheck disable=SC2120
+# shellcheck disable=SC2128
+# shellcheck disable=SC2154
 ################################################################################
 # This is property of eXtremeSHOK.com
 # You are free to use, modify and distribute, however you may not remove this notice.
 # Copyright (c) Adrian Jon Kriel :: admin@extremeshok.com
 ################################################################################
 # This is property of eXtremeSHOK.com
 # You are free to use, modify and distribute, however you may not remove this notice.
 # Copyright (c) Adrian Jon Kriel :: admin@extremeshok.com
+# License: BSD (Berkeley Software Distribution)
 ################################################################################
 ################################################################################
-# 
-# Script updates can be found at: https://github.com/extremeshok/clamav-unofficial-sigs
 #
 #
-# Originially based on: 
-# Script provide by Bill Landry (unofficialsigs@gmail.com).
+# Script updates can be found at: https://github.com/extremeshok/clamav-unofficial-sigs
 #
 #
-# License: BSD (Berkeley Software Distribution)
+# Originially based on Script provided by Bill Landry (unofficialsigs@gmail.com).
 #
 ################################################################################
 #
 #    THERE ARE NO USER CONFIGURABLE OPTIONS IN THIS SCRIPT
 #
 ################################################################################
 #
 #    THERE ARE NO USER CONFIGURABLE OPTIONS IN THIS SCRIPT
-#   ALL CONFIGURATION OPTIONS ARE LOCATED IN THE INCLUDED CONFIGURATION FILE 
+#   ALL CONFIGURATION OPTIONS ARE LOCATED IN THE INCLUDED CONFIGURATION FILE
 #
 ################################################################################
 
 #
 ################################################################################
 
-################################################################################
-
-    ######  #######    #     # ####### #######    ####### ######  ### ####### 
-    #     # #     #    ##    # #     #    #       #       #     #  #     #    
-    #     # #     #    # #   # #     #    #       #       #     #  #     #    
-    #     # #     #    #  #  # #     #    #       #####   #     #  #     #    
-    #     # #     #    #   # # #     #    #       #       #     #  #     #    
-    #     # #     #    #    ## #     #    #       #       #     #  #     #    
-    ######  #######    #     # #######    #       ####### ######  ###    #    
+######  #######    #     # ####### #######    ####### ######  ### #######
+#     # #     #    ##    # #     #    #       #       #     #  #     #
+#     # #     #    # #   # #     #    #       #       #     #  #     #
+#     # #     #    #  #  # #     #    #       #####   #     #  #     #
+#     # #     #    #   # # #     #    #       #       #     #  #     #
+#     # #     #    #    ## #     #    #       #       #     #  #     #
+######  #######    #     # #######    #       ####### ######  ###    #
 
 ################################################################################
 
 # Detect to make sure the entire script is avilable, fail if the script is missing contents
 
 ################################################################################
 
 # Detect to make sure the entire script is avilable, fail if the script is missing contents
-if [ ! "$( tail -1 "$0" | head -1 | cut -c1-7 )" == "exit \$?" ] ; then
-  echo "FATAL ERROR: Script is incomplete, please redownload"
-  exit 1
+if [ "$(tail -n 1 "${0}" | head -n 1 | cut -c 1-7)" != "exit \$?" ] ; then
+       echo "FATAL ERROR: Script is incomplete, please redownload"
+       exit 1
 fi
 
 fi
 
-# trap the keyboard interrupt (ctrl+c)
+# Trap the keyboard interrupt (Ctrl + C)
 trap xshok_control_c SIGINT
 trap xshok_control_c SIGINT
-
 ################################################################################
 # HELPER FUNCTIONS
 ################################################################################
 
 ################################################################################
 # HELPER FUNCTIONS
 ################################################################################
 
-# Function to support user config settings for applying file and directory access permissions.
-function perms () {
-  if [ -n "$clam_user" ] && [ -n "$clam_group" ] ; then
+# Support user config settings for applying file and directory access permissions.
+function perms() {
+  if [ -n "${clam_user}" ] && [ -n "${clam_group}" ] ; then
     "${@:-}"
   fi
 }
 
     "${@:-}"
   fi
 }
 
-# Function to prompt a user if they should complete an action with Y or N
-# usage: xshok_prompt_confirm
-# if xshok_prompt_confirm; then
+# Prompt a user if they should complete an action with Y or N
+# Usage: xshok_prompt_confirm
+# if xshok_prompt_confirm ; then
 # xshok_prompt_confirm && echo "accepted"
 # xshok_prompt_confirm && echo "yes" || echo "no"
 # xshok_prompt_confirm && echo "accepted"
 # xshok_prompt_confirm && echo "yes" || echo "no"
-function xshok_prompt_confirm () { #optional_message
+# shellcheck disable=SC2120
+function xshok_prompt_confirm() { # optional_message
   message="${1:-Are you sure?}"
   while true; do
   message="${1:-Are you sure?}"
   while true; do
-    read -r -p "$message [y/N]" response  </dev/tty
-    case $response in
+    read -r -p "${message} [y/N]" response < /dev/tty
+    case "${response}" in
       [yY]) return 0 ;;
       [nN]) return 1 ;;
       [yY]) return 0 ;;
       [nN]) return 1 ;;
-      *) printf " \033[31m %s \n\033[0m" "invalid input"
-    esac 
-  done  
+      *) printf " \\033[31m %s \\n\\033[0m" "invalid input"
+    esac
+  done
 }
 
 }
 
-# Function to create a pid file
-function xshok_create_pid_file { #pid.file
-  if [ "$1" ] ; then
-    pidfile="$1"
-    echo $$ > "$pidfile"
-    if [ $? -ne 0 ] ;  then
-      xshok_pretty_echo_and_log "ERROR: Could not create PID file: $pidfile"
+# Create a pid file
+function xshok_create_pid_file() { # pid.file
+  if [ "${1}" ] ; then
+    pidfile="${1}"
+    if ! echo $$ > "${pidfile}" ; then
+      xshok_pretty_echo_and_log "ERROR: Could not create PID file: ${pidfile}"
       exit 1
     fi
   else
       exit 1
     fi
   else
-    xshok_pretty_echo_and_log "ERROR: Missing value for option" "="
+    xshok_pretty_echo_and_log "ERROR: Missing value for option"
     exit 1
   fi
 }
 
     exit 1
   fi
 }
 
-# Function to intercept ctrl+c and calls the cleanup function
-function xshok_control_c () {
-  echo -en "\n"
-  xshok_pretty_echo_and_log "--------------| Exiting ... Please wait |--------------" "-"
+# Intercept ctrl+c and calls the cleanup function
+function xshok_control_c() {
+  echo
+  xshok_pretty_echo_and_log "---------------| Exiting ... Please wait |---------------" "-"
   xshok_cleanup
   exit $?
 }
 
   xshok_cleanup
   exit $?
 }
 
-# cleanup function
-function xshok_cleanup () {
-  #wait for all processes to end
+# Cleanup function
+function xshok_cleanup() {
+  # Wait for all processes to end
   wait
   xshok_pretty_echo_and_log "      Powered By https://eXtremeSHOK.com      " "#"
   return $?
   wait
   xshok_pretty_echo_and_log "      Powered By https://eXtremeSHOK.com      " "#"
   return $?
-} 
+}
 
 
-# Function to check if the current running user is the root user, otherwise return false
-function xshok_is_root () {
-  if [ "$(uname -s)" = "SunOS" ] ; then
+# Check if the current running user is the root user, otherwise return false
+function xshok_is_root() {
+  if [ "$(uname -s)" == "SunOS" ] ; then
     id_bin="/usr/xpg4/bin/id"
   else
     id_bin="/usr/xpg4/bin/id"
   else
-    id_bin="$(which id)"
+    id_bin="$(command -v id 2> /dev/null)"
   fi
   fi
-  if [ "$($id_bin -u)" = 0 ] ; then
-    return 0 ;
+  if [ "$($id_bin -u)" == 0 ] ; then
+    return 0
   else
   else
-    return 1 ;  #not root
+    return 1 # Not root
   fi
 }
 
   fi
 }
 
-# Function to check if its a file, otherwise return false
-function xshok_is_file () { #"filepath"
-  filepath="$1"
+# Check if its a file, otherwise return false
+function xshok_is_file() { # filepath
+  filepath="${1}"
   if [ -f "${filepath}" ] ; then
     return 0 ;
   else
   if [ -f "${filepath}" ] ; then
     return 0 ;
   else
-    return 1 ;  #not a file
-  fi 
+    return 1 ; # Not a file
+  fi
 }
 
 }
 
-# Function to check if filepath is a subdir, otherwise return false
+# Check if filepath is a subdir, otherwise return false
 # Usage: xshok_is_subdir "filepath"
 # xshok_is_subdir "/root/" - false
 # xshok_is_subdir "/usr/local/etc" && echo "yes" - yes
 # Usage: xshok_is_subdir "filepath"
 # xshok_is_subdir "/root/" - false
 # xshok_is_subdir "/usr/local/etc" && echo "yes" - yes
-function xshok_is_subdir () { #filepath
-  filepath=$(echo "$1" | sed 's:/*$::')
+function xshok_is_subdir() { # filepath
+  shopt -s extglob; filepath="${filepath%%+(/)}"
   if [ -d "$filepath" ] ; then
     res="${filepath//[^\/]}"
     if [ "${#res}" -gt 1 ] ; then
       return 0 ;
     else
   if [ -d "$filepath" ] ; then
     res="${filepath//[^\/]}"
     if [ "${#res}" -gt 1 ] ; then
       return 0 ;
     else
-      return 1 ;  #not a subdir
+      return 1 ; # Not a subdir
     fi
   else
     fi
   else
-    return 1 ;  #not a dir
+    return 1 ; # Not a dir
   fi
 }
 
   fi
 }
 
-# Function to create a dir and set the ownership
-function xshok_mkdir_ownership () { #"path"
-  if [ "$1" ] ; then
-    mkdir -p "$1" 2>/dev/null
-    if [ $? -ne 0 ] ;  then
-      xshok_pretty_echo_and_log "ERROR: Could not create directory: $1"
+# Create a dir and set the ownership
+function xshok_mkdir_ownership() { # path
+  if [ "${1}" ] ; then
+    if ! mkdir -p "${1}" 2>/dev/null ; then
+      xshok_pretty_echo_and_log "ERROR: Could not create directory: ${1}"
       exit 1
     fi
       exit 1
     fi
-    perms chown -f "$clam_user:$clam_group" "$1" > /dev/null 2>&1
+    perms chown -f "${clam_user}:${clam_group}" "${1}" > /dev/null 2>&1
   else
   else
-    xshok_pretty_echo_and_log "ERROR: Missing value for option" "="
+    xshok_pretty_echo_and_log "ERROR: Missing value for option"
     exit 1
   fi
 }
 
     exit 1
   fi
 }
 
-# Function to check if a user and group exists on the system otherwise return false
-# Usage: 
+# Check if a user and group exists on the system otherwise return false
+# Usage:
 # xshok_is_subdir "username" && echo "user found" || echo "no"
 # xshok_is_subdir "username" "groupname" && echo "user and group found" || echo "no"
 # xshok_is_subdir "username" && echo "user found" || echo "no"
 # xshok_is_subdir "username" "groupname" && echo "user and group found" || echo "no"
-function xshok_user_group_exists () { #"username" "groupname"
-  if [ "$(uname -s)" = "SunOS" ] ; then
+function xshok_user_group_exists() { # username groupname
+  if [ "$(uname -s)" == "SunOS" ] ; then
     id_bin="/usr/xpg4/bin/id"
   else
     id_bin="/usr/xpg4/bin/id"
   else
-    id_bin="$(which id)"
-  fi
-  if [ "$1" ] ; then
-    $id_bin -u "$1" > /dev/null 2>&1
-    if [ $? -eq 0 ]; then
-      if [ "$2" ] ; then
-        $id_bin -g "$2" > /dev/null 2>&1
-        if [ $? -eq 0 ]; then
-          return 0 ; #user and group exists
+    id_bin="$(command -v id 2> /dev/null)"
+  fi
+
+  if [ "${2}" ] ; then
+    if [ "$(uname -s)" == "Darwin" ] ; then
+      #use ruby, as this is the best way. Ruby is always avilable as brew uses ruby
+      ruby -e 'require "etc"; puts Etc::getgrnam("_clamav").gid' > /dev/null 2>&1
+      ret="$?"
+    else
+      getent_bin="$(command -v getent 2> /dev/null)"
+      $getent_bin group "${2}" >/dev/null 2>&1
+      ret="$?"
+    fi
+  fi
+
+  if [ "${1}" ] ; then
+    if $id_bin -u "${1}" > /dev/null 2>&1 ; then
+      if [ "${2}" ] ; then
+        if [ "$ret" -eq 0 ] ; then
+          return 0 ; # User and group exists
         else
         else
-          return 1 ;  #group does NOT exist
+          return 1 ; # Group does NOT exist
         fi
         fi
-       else
-          return 0 ; #user exists
-       fi
+      else
+        return 0 ; # User exists
+      fi
     else
     else
-      return 1 ;  #user does NOT exist
+      return 1 ; # User does NOT exist
     fi
   else
     fi
   else
-    xshok_pretty_echo_and_log "ERROR: Missing value for option" "="
+    xshok_pretty_echo_and_log "ERROR: Missing value for option"
     exit 1
   fi
 }
 
     exit 1
   fi
 }
 
-# Function to handle comments with/out borders and logging.
+# Handle comments with/out borders and logging.
 # Usage:
 # Usage:
-# pretty_echo_and_log "one" 
+# pretty_echo_and_log "one"
 # one
 # one
-# pretty_echo_and_log "two" "-" 
+# pretty_echo_and_log "two" "-"
 # ---
 # two
 # ---
 # ---
 # two
 # ---
@@ -202,181 +211,258 @@ function xshok_user_group_exists () { #"username" "groupname"
 # ========
 # pretty_echo_and_log "" "/\" "7"
 # /\/\/\/\/\/\
 # ========
 # pretty_echo_and_log "" "/\" "7"
 # /\/\/\/\/\/\
-#type: e = error, w= warning ""
-function xshok_pretty_echo_and_log () { #"string" "repeating" "count" "type"
-  # handle comments
-  if [ "$comment_silence" = "no" ] ; then
-    if [ "${#@}" = "1" ] ; then
-      echo "$1"
+# type: e = error, w= warning, a = alert, n = notice
+# will auto detect using the first word "error,warning,alert,notice"
+# type e will make a == border
+# type w will make a -- border
+# type a will make a ** border
+# type n will make a ++ border
+function xshok_pretty_echo_and_log() { # "string" "repeating" "count" "type"
+       #detect if running under cron and silence
+       mystring="$1"
+       myrepeating="$2"
+       mycount="$3"
+       mytype="$4"
+       if [ "$comment_silence" != "yes" ] && [ "$force_verbose" != "yes" ]; then
+               if [ ! -t 1 ] ; then
+                       comment_silence="yes"
+               fi
+       fi
+       # always show errors and alerts
+       if [ -z "$mytype" ] ; then
+               shopt -s nocasematch
+               if [[ "$mystring" =~ "ERROR:" ]] || [[ "$mystring" =~ "ERROR " ]] ; then
+                       mytype="e"
+               elif [[ "$mystring" =~ "WARNING:" ]] || [[ "$mystring" =~ "WARNING " ]] ; then
+                       mytype="w"
+               elif [[ "$mystring" =~ "ALERT:" ]] || [[ "$mystring" =~ "ALERT " ]] ; then
+                       mytype="a"
+               elif [[ "$mystring" =~ "NOTICE:" ]] || [[ "$mystring" =~ "NOTICE " ]] ; then
+                       mytype="n"
+               fi
+       fi
+       if [ "$mytype" == "e" ] || [ "$mytype" == "a" ] ; then
+                       comment_silence="no"
+       fi
+       # Handle comments is not silenced or type
+  if [ "$comment_silence" != "yes" ] ; then
+               if [ -z "$myrepeating" ] ; then
+                       if [ "$mytype" == "e" ] ; then
+                               myrepeating="="
+                       elif [ "$mytype" == "w" ] ; then
+                               myrepeating="-"
+                       elif [ "$mytype" == "a" ] ; then
+                               myrepeating="*"
+                       elif [ "$mytype" == "n" ] ; then
+                               myrepeating="+"
+                       fi
+               fi
+    if [ -z "$myrepeating" ] ; then
+      echo "${mystring}"
     else
       myvar=""
     else
       myvar=""
-      if [ -n "$3" ] ; then
-        mycount="$3"
-      else
-        mycount="${#1}"
+      if [ -z "$mycount" ] ; then
+        mycount="${#mystring}"
       fi
       fi
-      for (( n = 0; n < mycount; n++ )) ; do 
-        myvar="$myvar$2"
+      for (( n = 0; n < mycount; n++ )) ; do
+        myvar="${myvar}${myrepeating}"
       done
       done
-      if [ "$1" != "" ] ; then
-        echo -e "$myvar\n$1\n$myvar"
-      else  
-        echo -e "$myvar"
+      if [ -n "${mystring}" ] ; then
+        echo -e "${myvar}\\n${1}\\n${myvar}"
+      else
+        echo -e "${myvar}"
       fi
     fi
   fi
       fi
     fi
   fi
-
-  # handle logging
+  # Handle logging
   if [ "$enable_log" == "yes" ] ; then
   if [ "$enable_log" == "yes" ] ; then
-    if [ ! -e "$log_file_path/$log_file_name" ] ; then
-        #xshok_mkdir_ownership "$log_file_path"
-        mkdir -p "$log_file_path"
-        touch "$log_file_path/$log_file_name" 2>/dev/null
-        perms chown -f "$clam_user:$clam_group" "$log_file_path/$log_file_name"
-    fi
-    if [ ! -w "$log_file_path/$log_file_name" ] ; then
-      echo "Warning: Logging Disabled, as file not writable: $log_file_path/$log_file_name"
-      enable_log="no"
-    else
-      echo "$(date "+%b %d %T")" "$1" >> "$log_file_path/$log_file_name"
-    fi 
+
+               #filter ===, ---
+               mystring=${1//===}
+               mystring=${mystring//---}
+
+               if [ ! -z "$mystring" ] ; then
+           if [ ! -z "$log_pipe_cmd" ] ; then
+             echo "${mystring}" | $log_pipe_cmd
+           else
+             if [ ! -e "${log_file_path}/${log_file_name}" ] ; then
+               # xshok_mkdir_ownership "$log_file_path"
+               mkdir -p "$log_file_path"
+               touch "${log_file_path}/${log_file_name}" 2>/dev/null
+               perms chown -f "${clam_user}:${clam_group}" "${log_file_path}/${log_file_name}"
+             fi
+             if [ ! -w "${log_file_path}/${log_file_name}" ] ; then
+               echo "WARNING: Logging Disabled, as file not writable: ${log_file_path}/${log_file_name}"
+               enable_log="no"
+             else
+               echo "$(date "+%b %d %T")" "${mystring}" >> "${log_file_path}/${log_file_name}"
+             fi
+           fi
+               fi
   fi
 }
 
   fi
 }
 
-# function to check if the $2 value is not null and does not start with -
-function xshok_check_s2 () { #value1 #value2
-  if [ "$1" ] ; then
-    if [[ "$1" =~ ^-.* ]] ; then
-      xshok_pretty_echo_and_log "ERROR: Missing value for option or value begins with -" "="
+# Check if the $2 value is not null and does not start with -
+function xshok_check_s2() { # value1 value2
+  if [ "${1}" ] ; then
+    if [[ "${1}" =~ ^-.* ]] ; then
+      xshok_pretty_echo_and_log "ERROR: Missing value for option or value begins with -"
       exit 1
     fi
   else
       exit 1
     fi
   else
-    xshok_pretty_echo_and_log "ERROR: Missing value for option" "="
+    xshok_pretty_echo_and_log "ERROR: Missing value for option"
     exit 1
   fi
 }
 
     exit 1
   fi
 }
 
-# function to count array elements and output the total element count
-# required due to compound array assignment
-# Usage:
-# array=("one" "two" "three")
-# xshok_array_count $array
-# 3
-function xshok_array_count () { #array
-  k_array=( "$@" )
-  if [ -n "${k_array[*]}" ] ; then
-    i="0"
-    for k in "${k_array[@]}" ; do
-      let i=$i+1;
-    done
-    echo "$i"
-  else
-    echo "0"
+# Time remaining information function
+function xshok_draw_time_remaining() { #time_remaining #update_hours #name
+  if [ "${1}" ] && [ "${2}" ] ; then
+    time_remaining="${1}"
+    hours_left="$((time_remaining / 3600))"
+    minutes_left="$((time_remaining % 3600 / 60))"
+    xshok_pretty_echo_and_log "${2} hours have not yet elapsed since the last ${3} update check"
+    xshok_pretty_echo_and_log "No update check was performed at this time" "-"
+    xshok_pretty_echo_and_log "Next check will be performed in approximately ${hours_left} hour(s), ${minutes_left} minute(s)"
   fi
 }
   fi
 }
-# function to auto update
-function xshok_auto_update() { #version
-  xshok_pretty_echo_and_log "Performing automatic update..."
-
-  # Download new version
-  echo -n "Downloading latest version..."
-  if ! wget --quiet --output-document="$0.tmp" $UPDATE_BASE/$SELF ; then
-    echo "Failed: Error while trying to wget new version!"
-    echo "File requested: $UPDATE_BASE/$SELF"
-    exit 1
-  fi
-  echo "Done."
 
 
-  # Copy over modes from old version
-  OCTAL_MODE=$(stat -c '%a' $SELF)
-  if ! chmod $OCTAL_MODE "$0.tmp" ; then
-    echo "Failed: Error while trying to set mode on $0.tmp."
-    exit 1
+# Download function
+function xshok_file_download() { #outputfile #url #notimestamp
+       if [ "$downloader_debug" == "yes" ] ; then
+               xshok_pretty_echo_and_log "url: ${2} >> outputfile: ${1} | ${3}"
+       fi
+  if [ "${1}" ] && [ "${2}" ] ; then
+               if [ -n "$curl_bin" ] ; then
+                       if [ -f "${1}" ] ; then
+                               # shellcheck disable=SC2086
+                               $curl_bin --fail --compressed $curl_proxy $curl_insecure $curl_output_level --connect-timeout "${downloader_connect_timeout}" --remote-time --location --retry "${downloader_tries}" --max-time "${downloader_max_time}" --time-cond "${1}" --output "${1}" "${2}"  2>&11
+                               result=$?
+                       else
+                               # shellcheck disable=SC2086
+                               $curl_bin --fail --compressed $curl_proxy $curl_insecure $curl_output_level --connect-timeout "${downloader_connect_timeout}" --remote-time --location --retry "${downloader_tries}" --max-time "${downloader_max_time}" --output "${1}" "${2}"  2>&11
+                               result=$?
+                       fi
+               else
+                       if [ ! "${3}" ] ; then
+                               # the following is required because wget, cannot do --timestamping and --output-document together
+                               this_dir="$PWD"
+                               output_file="$1"
+                               url="$2"
+                               output_dir="${output_file%/*}"
+                               output_file="${output_file##*/}"
+                               url_file="${url##*/}"
+                               wget_output_link=""
+
+                               cd "${output_dir}" || exit
+                               if [ "$output_file" != "$url_file" ] ; then
+                                       if [ ! -f "$url_file" ] ; then
+                                               if [ ! -f "$output_file" ] ; then
+                                                       touch "$output_file"
+                                               fi
+                                               ln -s  "$output_file" "$url_file"
+                                               wget_output_link="$url_file"
+                                       fi
+                               fi
+             # shellcheck disable=SC2086
+                               $wget_bin $wget_compression $wget_proxy $wget_insecure $wget_output_level --connect-timeout="${downloader_connect_timeout}" --random-wait --tries="${downloader_tries}" --timeout="${downloader_max_time}" --timestamping "${2}" 2>&12
+                               result=$?
+                               if [ ! -n "$wget_output_link" ] ; then
+                                       if [ -L "$wget_output_link" ] ; then
+                                               rm -f "$wget_output_link"
+                                       fi
+                               fi
+                               cd "$this_dir" || exit
+                       else
+                               # shellcheck disable=SC2086
+                               $wget_bin $wget_compression $wget_proxy $wget_insecure $wget_output_level --connect-timeout="${downloader_connect_timeout}" --random-wait --tries="${downloader_tries}" --timeout="${downloader_max_time}" --output-document="${1}" "${2}" 2>&12
+                               result=$?
+                       fi
+    fi
+    return $result
   fi
   fi
-
-  # Generate the update script
-  cat > xshok_update_script.sh << EOF
-#!/bin/bash
-# Overwrite old file with new
-if mv "$0.tmp" "$0"; then
-  echo "Done. Update complete."
-  rm \$0
-else
-  echo "Failed! The update was not completed."
-fi
-EOF
-
-
-  echo -n "Inserting update process..."
-  
-  #replaced with $0, so code will update and then call itself with the same parameters it had
-  #exec /bin/bash xshok_update_script.sh
-  exec "$0" "$@"
 }
 
 }
 
-#function to handle list of database files
-function clamav_files () {
-  echo "$clam_dbs/$db" >> "$current_tmp"
-  if [ "$keep_db_backup" = "yes" ] ; then
-    echo "$clam_dbs/$db-bak" >> "$current_tmp"
+# Handle list of database files
+function clamav_files() {
+  echo "${clam_dbs}/${db}" >> "${current_tmp}"
+  if [ "$keep_db_backup" == "yes" ] ; then
+    echo "${clam_dbs}/${db}-bak" >> "${current_tmp}"
   fi
 }
 
   fi
 }
 
-# Function to manage the databases and allow multi-dimensions as well as global overrides
-# since the datbases are basically a multi-dimentional associative arrays in bash
-# ratings: LOW| MEDIUM| HIGH| REQUIRED| LOWONLY| MEDIUMONLY| LOWMEDIUMONLY | MEDIUMHIGHONLY | HIGHONLY| DISABLED
-function xshok_database () { #database #rating
-
-  # assign
-  current_dbs="$1"
-  current_rating="$2"
-  # zero
-  new_dbs=""
-
-  if [ -n "$current_dbs" ] ; then
-    if [ "$(xshok_array_count "$current_dbs")" -ge "1" ] ; then
-      for db_name in $current_dbs ; do
-        #checks
-        if [ "$enable_yararules" == "no" ] ; then #yararules are disabled
-            if [[ "$db_name" = *".yar"* ]] ; then # if it's the value you want to delete
-              continue # skip to the next value
-            fi
+# Manage the databases and allow multi-dimensions as well as global overrides
+# Since the datbases are basically a multi-dimentional associative arrays in bash
+# ratings: LOW | MEDIUM | HIGH | REQUIRED | LOWONLY | MEDIUMONLY | LOWMEDIUMONLY | MEDIUMHIGHONLY | HIGHONLY | DISABLED
+function xshok_database() { # rating database_array
+  # Assign
+  current_rating="${1}"
+  declare -a current_dbs=( "${@:2}" )
+  # Zero
+  declare -a new_dbs=( )
+  if [ -n "${current_dbs[0]}" ] ; then
+    if [ ${#current_dbs} -ge 1 ] ; then
+      for db_name in "${current_dbs[@]}" ; do
+        # Checks
+        if [ "$enable_yararules" == "no" ] ; then # YARA rules are disabled
+          if [[ "$db_name" == *".yar"* ]] ; then # If it's the value you want to delete
+            continue # Skip to the next value
+          fi
         fi
         fi
-        if [ "$current_rating" == "" ] ; then #yararules are disabled
-          new_dbs="$new_dbs $db_name"
+        if [ -z "$current_rating" ] ; then # YARA rules are disabled
+          new_dbs+=( "$db_name" )
         else
         else
-          if [[ ! "$db_name" = *"|"* ]] ; then # this old format
-            new_dbs="$new_dbs $db_name"
+          if [[ ! "$db_name" = *"|"* ]] ; then # This old format
+            new_dbs+=( "$db_name" )
           else
           else
-            db_name_rating=$(echo "$db_name" | cut -d "|" -f2)
-            db_name=$(echo "$db_name" | cut -d "|" -f1)
+            db_name_rating="${db_name#*|}"
+            db_name="${db_name%|*}"
 
             if [ "$db_name_rating" != "DISABLED" ] ; then
               if [ "$db_name_rating" == "$current_rating" ] ; then
 
             if [ "$db_name_rating" != "DISABLED" ] ; then
               if [ "$db_name_rating" == "$current_rating" ] ; then
-                new_dbs="$new_dbs $db_name"
+                new_dbs+=( "$db_name" )
               elif [ "$db_name_rating" == "REQUIRED" ] ; then
               elif [ "$db_name_rating" == "REQUIRED" ] ; then
-                new_dbs="$new_dbs $db_name"
+                new_dbs+=( "$db_name" )
               elif [ "$current_rating" == "LOW" ] ; then
               elif [ "$current_rating" == "LOW" ] ; then
-                if [ "$db_name_rating" == "LOWONLY" ] || [ "$db_name_rating" == "LOW" ]  || [ "$db_name_rating" == "LOWMEDIUM" ] ; then
-                  new_dbs="$new_dbs $db_name"   
+                if [ "$db_name_rating" == "LOWONLY" ] || [ "$db_name_rating" == "LOW" ] || [ "$db_name_rating" == "LOWMEDIUMONLY" ] ; then
+                  new_dbs+=( "$db_name" )
                 fi
               elif [ "$current_rating" == "MEDIUM" ] ; then
                 fi
               elif [ "$current_rating" == "MEDIUM" ] ; then
-                if [ "$db_name_rating" == "MEDIUMONLY" ] || [ "$db_name_rating" == "MEDIUM" ] || [ "$db_name_rating" == "LOW" ] || [ "$db_name_rating" == "LOWMEDIUM" ] ; then
-                  new_dbs="$new_dbs $db_name"
+                if [ "$db_name_rating" == "MEDIUMONLY" ] || [ "$db_name_rating" == "MEDIUM" ] || [ "$db_name_rating" == "LOW" ] || [ "$db_name_rating" == "LOWMEDIUMONLY" ]  || [ "$db_name_rating" == "MEDIUMHIGHONLY" ] ; then
+                  new_dbs+=( "$db_name" )
                 fi
               elif [ "$current_rating" == "HIGH" ] ; then
                 fi
               elif [ "$current_rating" == "HIGH" ] ; then
-                if [ "$db_name_rating" == "HIGH" ] || [ "$db_name_rating" == "MEDIUM" ] || [ "$db_name_rating" == "LOW" ] ; then
-                  new_dbs="$new_dbs $db_name"
+                if [ "$db_name_rating" == "HIGHONLY" ] || [ "$db_name_rating" == "HIGH" ] || [ "$db_name_rating" == "MEDIUM" ] || [ "$db_name_rating" == "LOW" ] || [ "$db_name_rating" == "MEDIUMHIGHONLY" ] ; then
+                  new_dbs+=( "$db_name" )
                 fi
                 fi
-              fi
+                                                       elif [ "$current_rating" == "LOWONLY" ] ; then
+                                                               if [ "$db_name_rating" == "LOWONLY" ] || [ "$db_name_rating" == "LOW" ] ; then
+                                                                       new_dbs+=( "$db_name" )
+                                                               fi
+                                                       elif [ "$current_rating" == "MEDIUMONLY" ] ; then
+                                                               if [ "$db_name_rating" == "MEDIUMONLY" ] || [ "$db_name_rating" == "MEDIUM" ] ; then
+                                                                       new_dbs+=( "$db_name" )
+                                                               fi
+                                                       elif [ "$current_rating" == "LOWMEDIUMONLY" ] ; then
+                                                               if [ "$db_name_rating" == "LOWMEDIUMONLY" ] || [ "$db_name_rating" == "LOW" ]  || [ "$db_name_rating" == "MEDIUM" ] ; then
+                                                                       new_dbs+=( "$db_name" )
+                                                               fi
+                                                       elif [ "$current_rating" == "MEDIUMHIGHONLY" ] ; then
+                                                               if [ "$db_name_rating" == "MEDIUMHIGHONLY" ] || [ "$db_name_rating" == "MEDIUM" ] || [ "$db_name_rating" == "HIGH" ] ; then
+                                                                       new_dbs+=( "$db_name" )
+                                                               fi
+                                                       elif [ "$current_rating" == "HIGHONLY" ] ; then
+                                                               if [ "$db_name_rating" == "HIGHONLY" ] || [ "$db_name_rating" == "HIGH" ] ; then
+                                                                       new_dbs+=( "$db_name" )
+                                                               fi
+                                                       fi
             fi
           fi
         fi
       done
     fi
   fi
             fi
           fi
         fi
       done
     fi
   fi
-  echo "$new_dbs" | xargs #remove extra whitespace
-
+  echo "${new_dbs[@]}" | xargs # Remove extra whitespace
 }
 
 ################################################################################
 }
 
 ################################################################################
@@ -384,47 +470,46 @@ function xshok_database () { #database #rating
 ################################################################################
 
 
 ################################################################################
 
 
-#generates a man config and installs it
-function install_man () {
+# Generates a man config and installs it
+function install_man() {
 
   if [ -n "$pkg_mgr" ] || [ -n "$pkg_rm" ] ; then
 
   if [ -n "$pkg_mgr" ] || [ -n "$pkg_rm" ] ; then
-    echo "This script (clamav-unofficial-sigs) was installed on the system via '$pkg_mgr'"
+    xshok_pretty_echo_and_log "This script (clamav-unofficial-sigs) was installed on the system via ${pkg_mgr}"
     exit 1
   fi
 
     exit 1
   fi
 
+  xshok_pretty_echo_and_log ""
+  xshok_pretty_echo_and_log "Generating man file for install...."
 
 
-  echo ""
-  echo "Generating man file for install...."
-  
-  #Use defined varibles or attempt to use default varibles
+  # Use defined varibles or attempt to use default varibles
 
 
-  if [ ! -e "$man_dir/$man_filename" ] ; then
+  if [ ! -e "${man_dir}/${man_filename}" ] ; then
     mkdir -p "$man_dir"
     mkdir -p "$man_dir"
-    touch "$man_dir/$man_filename" 2>/dev/null
+    touch "${man_dir}/${man_filename}" 2>/dev/null
   fi
   fi
-  if [ ! -w "$man_dir/$man_filename" ] ; then
-    echo "ERROR: man install aborted, as file not writable: $man_dir/$man_filename"
+  if [ ! -w "${man_dir}/${man_filename}" ] ; then
+    xshok_pretty_echo_and_log "ERROR: man install aborted, as file not writable: ${man_dir}/${man_filename}"
   else
 
   else
 
-BOLD="\fB"
-#REV=""
-NORM="\fR"
-manresult=$(help_and_usage "man")
+    BOLD="\\fB"
+    #REV=""
+    NORM="\\fR"
+    manresult="$(help_and_usage "man")"
 
 
-#Our template..
-  cat << EOF > "$man_dir/$man_filename"
+    # Our template..
+    cat << EOF > "${man_dir}/${man_filename}"
 
 
-.\" Manual page for eXtremeSHOK.com ClamAV Unofficial Signature Updater
-.TH clamav-unofficial-sigs 8 "$script_version_date" "Version: $script_version" "SCRIPT COMMANDS"
+.\\" Manual page for eXtremeSHOK.com ClamAV Unofficial Signature Updater
+.TH clamav-unofficial-sigs 8 "${script_version_date}" "Version: ${script_version}" "SCRIPT COMMANDS"
 .SH NAME
 .SH NAME
-clamav-unofficial-sigs \- Download, test, and install third-party ClamAV signature databases.
+clamav-unofficial-sigs \\- Download, test, and install third-party ClamAV signature databases.
 .SH SYNOPSIS
 .B clamav-unofficial-sigs
 .RI [ options ]
 .SH DESCRIPTION
 .SH SYNOPSIS
 .B clamav-unofficial-sigs
 .RI [ options ]
 .SH DESCRIPTION
-\fBclamav-unofficial-sigs\fP provides a simple way to download, test, and update third-party signature databases provided by Sanesecurity, FOXHOLE, OITC, Scamnailer, BOFHLAND, CRDF, Porcupine, Securiteinfo, MalwarePatrol, Yara-Rules Project, etc. It will also generate and install cron, logrotate, and man files.
+\\fBclamav-unofficial-sigs\\fP provides a simple way to download, test, and update third-party signature databases provided by Sanesecurity, FOXHOLE, OITC, Scamnailer, BOFHLAND, CRDF, Porcupine, Securiteinfo, MalwarePatrol, Yara-Rules Project, etc. It will also generate and install cron, logrotate, and man files.
 .SH UPDATES
 .SH UPDATES
-Script updates can be found at: \fBhttps://github.com/extremeshok/clamav-unofficial-sigs\fP
+Script updates can be found at: \\fBhttps://github.com/extremeshok/clamav-unofficial-sigs\\fP
 .SH OPTIONS
 This script follows the standard GNU command line syntax.
 .LP
 .SH OPTIONS
 This script follows the standard GNU command line syntax.
 .LP
@@ -439,7 +524,7 @@ You are free to use, modify and distribute, however you may not remove this noti
 .SH LICENSE
 BSD (Berkeley Software Distribution)
 .SH BUGS
 .SH LICENSE
 BSD (Berkeley Software Distribution)
 .SH BUGS
-Report bugs to \fBhttps://github.com/extremeshok/clamav-unofficial-sigs\fP
+Report bugs to \\fBhttps://github.com/extremeshok/clamav-unofficial-sigs\\fP
 .SH AUTHOR
 Adrian Jon Kriel :: admin@extremeshok.com
 Originially based on Script provide by Bill Landry
 .SH AUTHOR
 Adrian Jon Kriel :: admin@extremeshok.com
 Originially based on Script provide by Bill Landry
@@ -447,44 +532,44 @@ Originially based on Script provide by Bill Landry
 
 EOF
 
 
 EOF
 
-  fi 
-  echo "Completed: man installed, as file: $man_dir/$man_filename"
+  fi
+  xshok_pretty_echo_and_log "Completed: man installed, as file: ${man_dir}/${man_filename}"
 }
 
 
 }
 
 
-#generates a logrotate config and installs it
-function install_logrotate () {
+# Generate a logrotate config and install it
+function install_logrotate() {
 
   if [ -n "$pkg_mgr" ] || [ -n "$pkg_rm" ] ; then
 
   if [ -n "$pkg_mgr" ] || [ -n "$pkg_rm" ] ; then
-    echo "This script (clamav-unofficial-sigs) was installed on the system via '$pkg_mgr'"
+    xshok_pretty_echo_and_log "This script (clamav-unofficial-sigs) was installed on the system via ${pkg_mgr}"
     exit 1
   fi
 
     exit 1
   fi
 
-  echo ""
-  echo "Generating logrotate file for install...."
-  
-  #Use defined varibles or attempt to use default varibles
+  xshok_pretty_echo_and_log ""
+  xshok_pretty_echo_and_log "Generating logrotate file for install...."
+
+  # Use defined varibles or attempt to use default varibles
 
 
-  if [ ! -n "$logrotate_user" ] ; then
-    logrotate_user="$clam_user";
+  if [ -z "$logrotate_user" ] ; then
+    logrotate_user="${clam_user}";
   fi
   fi
-  if [ ! -n "$logrotate_group" ] ; then
-    logrotate_group="$clam_group";
+  if [ -z "$logrotate_group" ] ; then
+    logrotate_group="${clam_group}";
   fi
   fi
-  if [ ! -n "$logrotate_log_file_full_path" ] ; then
-    logrotate_log_file_full_path="$log_file_path/$log_file_name"
+  if [ -z "$logrotate_log_file_full_path" ] ; then
+    logrotate_log_file_full_path="${log_file_path}/${log_file_name}"
   fi
 
 
   fi
 
 
-  if [ ! -e "$logrotate_dir/$logrotate_filename" ] ; then
+  if [ ! -e "${logrotate_dir}/${logrotate_filename}" ] ; then
     mkdir -p "$logrotate_dir"
     mkdir -p "$logrotate_dir"
-    touch "$logrotate_dir/$logrotate_filename" 2>/dev/null
+    touch "${logrotate_dir}/${logrotate_filename}" 2>/dev/null
   fi
   fi
-  if [ ! -w "$logrotate_dir/$logrotate_filename" ] ; then
-    echo "ERROR: logrotate install aborted, as file not writable: $logrotate_dir/$logrotate_filename"
+  if [ ! -w "${logrotate_dir}/${logrotate_filename}" ] ; then
+    xshok_pretty_echo_and_log "ERROR: logrotate install aborted, as file not writable: ${logrotate_dir}/${logrotate_filename}"
   else
   else
-#Our template..
-  cat << EOF > "$logrotate_dir/$logrotate_filename"
+    # Our template..
+    cat << EOF > "${logrotate_dir}/${logrotate_filename}"
 # https://eXtremeSHOK.com ######################################################
 # This file contains the logrotate settings for clamav-unofficial-sigs.sh
 ###################
 # https://eXtremeSHOK.com ######################################################
 # This file contains the logrotate settings for clamav-unofficial-sigs.sh
 ###################
@@ -494,8 +579,8 @@ function install_logrotate () {
 ##################
 #
 # Script updates can be found at: https://github.com/extremeshok/clamav-unofficial-sigs
 ##################
 #
 # Script updates can be found at: https://github.com/extremeshok/clamav-unofficial-sigs
-# 
-# Originially based on: 
+#
+# Originially based on:
 # Script provide by Bill Landry (unofficialsigs@gmail.com).
 #
 # License: BSD (Berkeley Software Distribution)
 # Script provide by Bill Landry (unofficialsigs@gmail.com).
 #
 # License: BSD (Berkeley Software Distribution)
@@ -515,49 +600,51 @@ $logrotate_log_file_full_path {
   missingok
   notifempty
   compress
   missingok
   notifempty
   compress
-  create 0644 $logrotate_user $logrotate_group
+  create 0640 ${logrotate_user} ${logrotate_group}
 }
 
 EOF
 
 }
 
 EOF
 
-  fi 
-  echo "Completed: logrotate installed, as file: $logrotate_dir/$logrotate_filename"
+  fi
+  xshok_pretty_echo_and_log "Completed: logrotate installed, as file: ${logrotate_dir}/${logrotate_filename}"
 }
 
 }
 
-#generates a cron config and installs it
-function install_cron () {
+# Generate a cron config and install it
+function install_cron() {
 
   if [ -n "$pkg_mgr" ] || [ -n "$pkg_rm" ] ; then
 
   if [ -n "$pkg_mgr" ] || [ -n "$pkg_rm" ] ; then
-    echo "This script (clamav-unofficial-sigs) was installed on the system via '$pkg_mgr'"
+    xshok_pretty_echo_and_log "This script (clamav-unofficial-sigs) was installed on the system via {$pkg_mgr}"
     exit 1
   fi
 
     exit 1
   fi
 
-  echo ""
-  echo "Generating cron file for install...."
-  
-  #Use defined varibles or attempt to use default varibles
-  if [ ! -n "$cron_minute" ] ; then
-    cron_minute=$(( ( RANDOM % 59 )  + 1 ));
+  xshok_pretty_echo_and_log ""
+  xshok_pretty_echo_and_log "Generating cron file for install...."
+
+  # Use defined varibles or attempt to use default varibles
+  if [ -z "$cron_minute" ] ; then
+    cron_minute="$(( ( RANDOM % 59 ) + 1 ))"
+  fi
+  if [ -z "$cron_user" ] ; then
+    cron_user="${clam_user}";
   fi
   fi
-  if [ ! -n "$cron_user" ] ; then
-    cron_user="$clam_user";
+  if [ -z "$cron_bash" ] ; then
+    cron_bash="$(command -v bash 2> /dev/null)"
   fi
   fi
-  if [ ! -n "$cron_bash" ] ; then
-    cron_bash=$(which bash)
-  fi  
-  if [ ! -n "$cron_script_full_path" ] ; then
+  if [ -z "$cron_script_full_path" ] ; then
     cron_script_full_path="$this_script_full_path"
     cron_script_full_path="$this_script_full_path"
-  fi  
-
-  if [ ! -e "$cron_dir/$cron_filename" ] ; then
+  fi
+  if [ "$cron_sudo" == "yes" ] ; then
+    cron_sudo="sudo -u"
+  fi
+  if [ ! -e "${cron_dir}/${cron_filename}" ] ; then
     mkdir -p "$cron_dir"
     mkdir -p "$cron_dir"
-    touch "$cron_dir/$cron_filename" 2>/dev/null
+    touch "${cron_dir}/${cron_filename}" 2>/dev/null
   fi
   fi
-  if [ ! -w "$cron_dir/$cron_filename" ] ; then
-    echo "ERROR: cron install aborted, as file not writable: $cron_dir/$cron_filename"
+  if [ ! -w "${cron_dir}/${cron_filename}" ] ; then
+    xshok_pretty_echo_and_log "ERROR: cron install aborted, as file not writable: ${cron_dir}/${cron_filename}"
   else
   else
-#Our template..
-  cat << EOF > "$cron_dir/$cron_filename"
+    # Our template..
+    cat << EOF > "${cron_dir}/${cron_filename}"
 # https://eXtremeSHOK.com ######################################################
 # This file contains the cron settings for clamav-unofficial-sigs.sh
 ###################
 # https://eXtremeSHOK.com ######################################################
 # This file contains the cron settings for clamav-unofficial-sigs.sh
 ###################
@@ -567,8 +654,8 @@ function install_cron () {
 ##################
 #
 # Script updates can be found at: https://github.com/extremeshok/clamav-unofficial-sigs
 ##################
 #
 # Script updates can be found at: https://github.com/extremeshok/clamav-unofficial-sigs
-# 
-# Originially based on: 
+#
+# Originially based on:
 # Script provide by Bill Landry (unofficialsigs@gmail.com).
 #
 # License: BSD (Berkeley Software Distribution)
 # Script provide by Bill Landry (unofficialsigs@gmail.com).
 #
 # License: BSD (Berkeley Software Distribution)
@@ -581,148 +668,284 @@ function install_cron () {
 # currently supports updating third-party signature databases provided
 # by Sanesecurity, SecuriteInfo, MalwarePatrol, OITC, etc.
 #
 # currently supports updating third-party signature databases provided
 # by Sanesecurity, SecuriteInfo, MalwarePatrol, OITC, etc.
 #
-# The script is set to run hourly, at a random minute past the hour, and the 
+# The script is set to run hourly, at a random minute past the hour, and the
 # script itself is set to randomize the actual execution time between
 # 60 - 600 seconds.  To Adjust the cron values, edit your configs and run
 # bash clamav-unofficial-sigs.sh --install-cron to generate a new file.
 # script itself is set to randomize the actual execution time between
 # 60 - 600 seconds.  To Adjust the cron values, edit your configs and run
 # bash clamav-unofficial-sigs.sh --install-cron to generate a new file.
-
-$cron_minute * * * * $cron_user [ -x $cron_script_full_path ] && $cron_bash $cron_script_full_path > /dev/null
+MAILTO=root
+$cron_minute * * * * ${cron_sudo} ${cron_user} [ -x ${cron_script_full_path} ] && ${cron_bash} ${cron_script_full_path}
 
 # https://eXtremeSHOK.com ######################################################
 
 EOF
 
 
 # https://eXtremeSHOK.com ######################################################
 
 EOF
 
-  fi 
-  echo "Completed: cron installed, as file: $cron_dir/$cron_filename"
+  fi
+  xshok_pretty_echo_and_log "Completed: cron installed, as file: ${cron_dir}/${cron_filename}"
+}
+
+# Auto upgrade the master.conf and the
+function xshok_upgrade() {
+
+       if [ "$allow_upgrades" == "no" ] ; then
+               xshok_pretty_echo_and_log "ERROR: --upgrade has been disabled, allow_upgrades=no"
+               exit 1
+       fi
+       if ! xshok_is_root ; then
+               xshok_pretty_echo_and_log "ERROR: Only root can run the upgrade"
+               exit 1
+       fi
+
+       xshok_pretty_echo_and_log "Checking for updates ..."
+
+       found_upgrade="no"
+       if [ -n "$curl_bin" ] ; then
+               # shellcheck disable=SC2086
+               latest_version="$($curl_bin --compressed $curl_proxy $curl_insecure $curl_output_level --connect-timeout "${downloader_connect_timeout}" --remote-time --location --retry "${downloader_tries}" --max-time "${downloader_max_time}" "https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/clamav-unofficial-sigs.sh" 2>&11 | $grep_bin "^script_version=" | head -n1 | cut -d '"' -f 2)"
+               # shellcheck disable=SC2086
+               latest_config_version="$($curl_bin --compressed $curl_proxy $curl_insecure $curl_output_level --connect-timeout "${downloader_connect_timeout}" --remote-time --location --retry "${downloader_tries}" --max-time "${downloader_max_time}" "https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/config/master.conf" 2>&11 | $grep_bin "^config_version=" | head -n1 | cut -d '"' -f 2)"
+       else
+               # shellcheck disable=SC2086
+               latest_version="$($wget_bin $wget_compression $wget_proxy $wget_insecure $wget_output_level --connect-timeout="${downloader_connect_timeout}" --random-wait --tries="${downloader_tries}" --timeout="${downloader_max_time}" "https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/clamav-unofficial-sigs.sh" -O - 2>&12 | $grep_bin "^script_version=" | head -n1 | cut -d '"' -f 2)"
+               # shellcheck disable=SC2086
+               latest_config_version="$($wget_bin $wget_compression $wget_proxy $wget_insecure $wget_output_level --connect-timeout="${downloader_connect_timeout}" --random-wait --tries="${downloader_tries}" --timeout="${downloader_max_time}" "https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/config/master.conf" -O - 2>&12 | $grep_bin "^config_version=" | head -n1 | cut -d '"' -f 2)"
+       fi
+
+  # config_dir/master.conf
+       if [ "$latest_config_version" ] ; then
+               # shellcheck disable=SC2183,SC2086
+               if [ "$(printf "%02d%02d%02d%02d" ${latest_config_version//./ })" -gt "$(printf "%02d%02d%02d%02d" ${config_version//./ })" ] ; then
+                       found_upgrade="yes"
+                       xshok_pretty_echo_and_log "ALERT: Upgrading config from v${config_version} to v${latest_config_version}"
+                       if [ -w "${config_dir}/master.conf" ] && [ -f "${config_dir}/master.conf" ] ; then
+                               echo "Downloading https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/config/master.conf"
+                               xshok_file_download "${work_dir}/master.conf.tmp" "https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/config/master.conf" "notimestamp"
+                               ret="$?"
+                               if [ "$ret" -ne 0 ] ; then
+                                       xshok_pretty_echo_and_log "ERROR: Could not download https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/config/master.conf"
+                                       exit 1
+                               fi
+                               if ! $grep_bin -m 1 "config_version" "${work_dir}/master.conf.tmp" > /dev/null 2>&1 ; then
+                                       echo "ERROR: Downloaded master.conf is incomplete, please re-run"
+                                       exit 1
+                               fi
+                               # Copy over permissions from old version
+                         OCTAL_MODE="$(stat -c "%a" "${config_dir}/master.conf")"
+                               xshok_pretty_echo_and_log "Running update process"
+                               if ! mv -f "${work_dir}/master.conf.tmp" "${config_dir}/master.conf" ; then
+                                       xshok_pretty_echo_and_log "ERROR: failed moving ${work_dir}/master.conf.tmp to ${config_dir}/master.conf"
+                                       exit 1
+                               fi
+                               if ! chmod "$OCTAL_MODE" "${config_dir}/master.conf" ; then
+                                        xshok_pretty_echo_and_log "ERROR: unable to set permissions on ${config_dir}/master.conf"
+                                        exit 1
+                               fi
+                               xshok_pretty_echo_and_log "Completed"
+                       else
+                                xshok_pretty_echo_and_log "ERROR: ${config_dir}/master.conf is not a file or is not writable"
+                                exit 1
+                 fi
+               fi
+       fi
+
+       if [ "$latest_version" ] ; then
+               # shellcheck disable=SC2183,SC2086
+               if [ "$(printf "%02d%02d%02d%02d" ${latest_version//./ })" -gt "$(printf "%02d%02d%02d%02d" ${script_version//./ })" ] ; then
+                       found_upgrade="yes"
+           xshok_pretty_echo_and_log "ALERT:  Upgrading script from v${script_version} to v${latest_version}"
+                       if [ -w "${config_dir}/master.conf" ] && [ -f "${config_dir}/master.conf" ] ; then
+                               echo "Downloading https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/clamav-unofficial-sigs.sh"
+                               xshok_file_download "${work_dir}/clamav-unofficial-sigs.sh.tmp" "https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/clamav-unofficial-sigs.sh" "notimestamp"
+                         ret=$?
+                               if [ "$ret" -ne 0 ] ; then
+                                       xshok_pretty_echo_and_log "ERROR: Could not download https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/clamav-unofficial-sigs.sh"
+                                       exit 1
+                               fi
+                               # Detect to make sure the entire script is avilable, fail if the script is missing contents
+                               if [ "$(tail -n 1 "${work_dir}/clamav-unofficial-sigs.sh.tmp" | head -n 1 | cut -c 1-7)" != "exit \$?" ] ; then
+                                       echo "ERROR: Downloaded clamav-unofficial-sigs.sh is incomplete, please re-run"
+                                       exit 1
+                               fi
+                               # Copy over permissions from old version
+                         OCTAL_MODE="$(stat -c "%a" "${this_script_full_path}")"
+
+                               xshok_pretty_echo_and_log "Inserting update process..."
+                         # Generate the update script
+                         cat > "${work_dir}/xshok_update_script.sh" << EOF
+#!/usr/bin/env bash
+echo "Running update process"
+# Overwrite old file with new
+if ! mv -f "${work_dir}/clamav-unofficial-sigs.sh.tmp" "${this_script_full_path}" ; then
+  echo  "ERROR: failed moving ${work_dir}/clamav-unofficial-sigs.sh.tmp to ${this_script_full_path}"
+  rm -f \$0
+       exit 1
+fi
+if ! chmod "$OCTAL_MODE" "${this_script_full_path}" ; then
+        echo "ERROR: unable to set permissions on ${this_script_full_path}"
+        rm -f \$0
+        exit 1
+fi
+       echo "Completed"
+       # echo "---------------------"
+       # echo "Optional, run as root: "
+       # echo "clamav-unofficial-sigs.sh --install-all"
+       echo "---------------------"
+       echo "Run once as root: "
+       echo "clamav-unofficial-sigs.sh --force"
+
+       #remove the tmp script before exit
+       rm -f \$0
+EOF
+                 # Replaced with $0, so code will update and then call itself with the same parameters it had
+                       #exec "${0}" "$@"
+                       bash_bin="$(command -v bash 2> /dev/null)"
+                 exec "$bash_bin" "${work_dir}/xshok_update_script.sh"
+                       echo "Running once as root"
+               else
+                        xshok_pretty_echo_and_log "ERROR: ${config_dir}/master.conf is not a file or is not writable"
+                        exit 1
+               fi
+       fi
+fi
+
+if [ "$found_upgrade" == "no" ] ; then
+       xshok_pretty_echo_and_log "No updates available"
+fi
 }
 
 
 }
 
 
-#decode a third-party signature either by signature name
-function decode_third_party_signature_by_signature_name () {
-  echo ""
-  echo "Input a third-party signature name to decode (e.g: Sanesecurity.Junk.15248) or"
-  echo "a hexadecimal encoded data string and press enter (do not include '.UNOFFICIAL'"
-  echo "in the signature name nor add quote marks to any input string):"
+# Decode a third-party signature either by signature name
+function decode_third_party_signature_by_signature_name() {
+  xshok_pretty_echo_and_log ""
+  xshok_pretty_echo_and_log "Input a third-party signature name to decode (e.g: Sanesecurity.Junk.15248) or"
+  xshok_pretty_echo_and_log "a hexadecimal encoded data string and press enter:"
   read -r input
   read -r input
-  input=$(echo "$input" | tr -d "'" | tr -d '"')
-  if echo "$input" | $grep_bin "\." > /dev/null ; then
+       # Remove quotes and .UNOFFICIAL from the whitelist input string
+  input="$(echo "${input}" | tr -d "'" | tr -d '"' | tr -d '`')"
+       input=${input/\.UNOFFICIAL/}
+  if echo "${input}" | $grep_bin "\\." > /dev/null ; then
     cd "$clam_dbs" || exit
     cd "$clam_dbs" || exit
-    sig=$($grep_bin "$input:" ./*.ndb)
+    sig="$($grep_bin "${input}:" ./*.ndb)"
     if [ -n "$sig" ] ; then
     if [ -n "$sig" ] ; then
-      db_file=$(echo "$sig" | cut -d ':' -f1)
-      echo "$input found in: $db_file"
-      echo "$input signature decodes to:"
-      echo "$sig" | cut -d ":" -f5 | perl -pe 's/([a-fA-F0-9]{2})|(\{[^}]*\}|\([^)]*\))/defined $2 ? $2 : chr(hex $1)/eg'
+      db_file="${sig%:*}"
+      xshok_pretty_echo_and_log "${input} found in: ${db_file}"
+      xshok_pretty_echo_and_log "${input} signature decodes to:"
+      xshok_pretty_echo_and_log "$sig" | cut -d ":" -f 5 | perl -pe 's/([a-fA-F0-9]{2})|(\{[^}]*\}|\([^)]*\))/defined $2 ? $2 : chr(hex $1)/eg'
     else
     else
-      echo "Signature '$input' could not be found."
-      echo "This script will only decode ClamAV 'UNOFFICIAL' third-Party,"
-      echo "non-image based, signatures as found in the *.ndb databases."
+      xshok_pretty_echo_and_log "Signature ${input} could not be found."
+      xshok_pretty_echo_and_log "This script will only decode ClamAV 'UNOFFICIAL' third-Party,"
+      xshok_pretty_echo_and_log "non-image based, signatures as found in the *.ndb databases."
     fi
   else
     fi
   else
-    echo "Here is the decoded hexadecimal input string:"
-    echo "$input" | perl -pe 's/([a-fA-F0-9]{2})|(\{[^}]*\}|\([^)]*\))/defined $2 ? $2 : chr(hex $1)/eg'
+    xshok_pretty_echo_and_log "Here is the decoded hexadecimal input string:"
+    echo "${input}" | perl -pe 's/([a-fA-F0-9]{2})|(\{[^}]*\}|\([^)]*\))/defined $2 ? $2 : chr(hex $1)/eg'
   fi
 }
 
   fi
 }
 
-#Hexadecimal encode an entire input string
-function hexadecimal_encode_entire_input_string () {
-  echo ""
-  echo "Input the data string that you want to hexadecimal encode and then press enter.  Do not include"
-  echo "any quotes around the string unless you want them included in the hexadecimal encoded output:"
+# Hexadecimal encode an entire input string
+function hexadecimal_encode_entire_input_string() {
+  xshok_pretty_echo_and_log ""
+  xshok_pretty_echo_and_log "Input the data string that you want to hexadecimal encode and then press enter.  Do not include"
+  xshok_pretty_echo_and_log "any quotes around the string unless you want them included in the hexadecimal encoded output:"
   read -r input
   read -r input
-  echo "Here is the hexadecimal encoded input string:"
-  echo "$input" | perl -pe 's/(.)/sprintf("%02lx", ord $1)/eg'
+  xshok_pretty_echo_and_log "Here is the hexadecimal encoded input string:"
+  echo "${input}" | perl -pe 's/(.)/sprintf("%02lx", ord $1)/eg'
 }
 
 }
 
-#Hexadecimal encode a formatted input string
-function hexadecimal_encode_formatted_input_string () {
-  echo ""
-  echo "Input a formated data string containing spacing fields '{}, (), *' that you want to hexadecimal"
-  echo "encode, without encoding the spacing fields, and then press enter.  Do not include any quotes"
-  echo "around the string unless you want them included in the hexadecimal encoded output:"
+# Hexadecimal encode a formatted input string
+function hexadecimal_encode_formatted_input_string() {
+  xshok_pretty_echo_and_log ""
+  xshok_pretty_echo_and_log "Input a formated data string containing spacing fields '{}, (), *' that you want to hexadecimal"
+  xshok_pretty_echo_and_log "encode, without encoding the spacing fields, and then press enter.  Do not include any quotes"
+  xshok_pretty_echo_and_log "around the string unless you want them included in the hexadecimal encoded output:"
   read -r input
   read -r input
-  echo "Here is the hexadecimal encoded input string:"
-  echo "$input" | perl -pe 's/(\{[^}]*\}|\([^)]*\)|\*)|(.)/defined $1 ? $1 : sprintf("%02lx", ord $2)/eg'
+  xshok_pretty_echo_and_log "Here is the hexadecimal encoded input string:"
+  echo "${input}" | perl -pe 's/(\{[^}]*\}|\([^)]*\)|\*)|(.)/defined $1 ? $1 : sprintf("%02lx", ord $2)/eg'
 }
 
 }
 
-#GPG verify a specific Sanesecurity database file
-function gpg_verify_specific_sanesecurity_database_file () { #databasefile
-  echo ""
-  if [ "$1" ] ; then
-    db_file=$(echo "$1" | awk -F '/' '{print $NF}')
-    if [ -r "$work_dir_sanesecurity/$db_file" ] ; then
-      echo "GPG signature testing database file: $work_dir_sanesecurity/$db_file"
-      if [ -r "$work_dir_sanesecurity/$db_file".sig ] ; then
-        "$gpg_bin" -q --trust-model always --no-default-keyring --homedir "$work_dir_gpg" --keyring "$work_dir_gpg"/ss-keyring.gpg --verify "$work_dir_sanesecurity"/"$db_file".sig "$work_dir_sanesecurity"/"$db_file"
-        if [ "$?" != "0" ]; then
-          "$gpg_bin" -q --always-trust --no-default-keyring --homedir "$work_dir_gpg" --keyring "$work_dir_gpg"/ss-keyring.gpg --verify "$work_dir_sanesecurity"/"$db_file".sig "$work_dir_sanesecurity"/"$db_file"
-          if [ "$?" == "0" ]; then
-            exit 0
+# GPG verify a specific Sanesecurity database file
+function gpg_verify_specific_sanesecurity_database_file() { # databasefile
+  xshok_pretty_echo_and_log ""
+  if [ "$enable_gpg" == "no" ] ; then
+    xshok_pretty_echo_and_log "GnuPG / signature verification disabled" "-"
+  else
+    if [ "${1}" ] ; then
+      db_file="$(echo "${1}" | awk -F "/" '{print $NF}')"
+      if [ -r "${work_dir_sanesecurity}/${db_file}" ] ; then
+        xshok_pretty_echo_and_log "GPG signature testing database file: ${work_dir_sanesecurity}/${db_file}"
+        if [ -r "${work_dir_sanesecurity}/${db_file}.sig" ] ; then
+          if ! "$gpg_bin" -q --trust-model always --no-default-keyring --homedir "${work_dir_gpg}" --keyring "${work_dir_gpg}/ss-keyring.gpg" --verify "${work_dir_sanesecurity}/${db_file}.sig" "${work_dir_sanesecurity}/${db_file}" ; then
+            if "$gpg_bin" -q --always-trust --no-default-keyring --homedir "${work_dir_gpg}" --keyring "${work_dir_gpg}/ss-keyring.gpg" --verify "${work_dir_sanesecurity}/${db_file}.sig" "${work_dir_sanesecurity}/${db_file}" ; then
+              exit 0
+            else
+              exit 1
+            fi
           else
           else
-            exit 1
+            exit 0
           fi
         else
           fi
         else
-          exit 0
+          xshok_pretty_echo_and_log "Signature ${db_file}.sig cannot be found."
         fi
       else
         fi
       else
-        echo "Signature '$db_file.sig' cannot be found."
+        xshok_pretty_echo_and_log "File ${db_file} cannot be found or is not a Sanesecurity database file."
+        xshok_pretty_echo_and_log "Only the following Sanesecurity and OITC databases can be GPG signature tested:"
+        ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "${work_dir_sanesecurity}"
       fi
     else
       fi
     else
-      echo "File '$db_file' cannot be found or is not a Sanesecurity database file."
-      echo "Only the following Sanesecurity and OITC databases can be GPG signature tested:"
-      ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_sanesecurity"
+      xshok_pretty_echo_and_log "ERROR: Missing value for option"
+      exit 1
     fi
     fi
-  else
-    xshok_pretty_echo_and_log "ERROR: Missing value for option" "="
     exit 1
   fi
 }
 
     exit 1
   fi
 }
 
-#Output system and configuration information
-function output_system_configuration_information () {
-  echo ""
-  echo "*** SCRIPT VERSION ***"
-  echo "$this_script_name $script_version ($script_version_date)"
-  echo "*** SYSTEM INFORMATION ***"
+# Output system and configuration information
+function output_system_configuration_information() {
+  xshok_pretty_echo_and_log ""
+  xshok_pretty_echo_and_log "*** SCRIPT INFORMATION ***"
+  xshok_pretty_echo_and_log "${this_script_name} ${script_version} (${script_version_date})"
+       xshok_pretty_echo_and_log "Master.conf Version: ${config_version}"
+       xshok_pretty_echo_and_log "Minimum required config: ${minimum_required_config_version}"
+  xshok_pretty_echo_and_log "*** SYSTEM INFORMATION ***"
   $uname_bin -a
   $uname_bin -a
-  echo "*** CLAMSCAN LOCATION & VERSION ***"
-  echo "$clamscan_bin"
+  xshok_pretty_echo_and_log "*** CLAMSCAN LOCATION & VERSION ***"
+  xshok_pretty_echo_and_log "${clamscan_bin}"
   $clamscan_bin --version | head -1
   $clamscan_bin --version | head -1
-  echo "*** RSYNC LOCATION & VERSION ***"
-  echo "$rsync_bin"
+  xshok_pretty_echo_and_log "*** RSYNC LOCATION & VERSION ***"
+  xshok_pretty_echo_and_log "${rsync_bin}"
   $rsync_bin --version | head -1
   $rsync_bin --version | head -1
-  if [ "$wget_bin" != "" ] ; then
-    echo "*** WGET LOCATION & VERSION ***"
-    echo "$wget_bin"
-    $wget_bin --version | head -1
+  if [ -n "$curl_bin" ] ; then
+               xshok_pretty_echo_and_log "*** CURL LOCATION & VERSION ***"
+               xshok_pretty_echo_and_log "${curl_bin}"
+               $curl_bin --version | head -1
   else
   else
-    echo "*** CURL LOCATION & VERSION ***"
-    echo "$curl_bin"
-    $curl_bin --version | head -1
-  fi
-  echo "*** GPG LOCATION & VERSION ***"
-  echo "$gpg_bin"
-  $gpg_bin --version | head -1
-  echo "*** SCRIPT WORKING DIRECTORY INFORMATION ***"
-  echo "$work_dir"
-  echo "*** CLAMAV DIRECTORY INFORMATION ***"
-  echo "$clam_dbs"
-  echo "*** SCRIPT CONFIGURATION SETTINGS ***"
+               xshok_pretty_echo_and_log "*** WGET LOCATION & VERSION ***"
+               xshok_pretty_echo_and_log "${wget_bin}"
+               $wget_bin --version | head -1
+  fi
+  if [ "$enable_gpg" == "yes" ] ; then
+    xshok_pretty_echo_and_log "*** GPG LOCATION & VERSION ***"
+    xshok_pretty_echo_and_log "${gpg_bin}"
+    $gpg_bin --version | head -1
+  fi
+  xshok_pretty_echo_and_log "*** DIRECTORY INFORMATION ***"
+  xshok_pretty_echo_and_log "Working Directory: ${work_dir}"
+  xshok_pretty_echo_and_log "Clam Database Directory: ${clam_dbs}"
   if [ "$custom_config" != "no" ] ; then
     if [ -d "$custom_config" ] ; then
       # Assign the custom config dir and remove trailing / (removes / and //)
   if [ "$custom_config" != "no" ] ; then
     if [ -d "$custom_config" ] ; then
       # Assign the custom config dir and remove trailing / (removes / and //)
-      echo "Custom Configuration Directory: $config_dir"
+      xshok_pretty_echo_and_log "Custom Configuration Directory: ${custom_config}"
     else
     else
-      echo "Custom Configuration File: $custom_config"
+      xshok_pretty_echo_and_log "Custom Configuration File: ${custom_config}"
     fi
   else
     fi
   else
-    echo "Configuration Directory: $config_dir"
+    xshok_pretty_echo_and_log "Configuration Directory: ${config_dir}"
   fi
   fi
+       xshok_pretty_echo_and_log ""
 }
 
 }
 
-#Make a signature database from an ascii file
-function make_signature_database_from_ascii_file () {
-  echo ""
+# Make a signature database from an ascii file
+function make_signature_database_from_ascii_file() {
+  xshok_pretty_echo_and_log ""
   echo "
   The '-m' script flag provides a way to create a ClamAV hexadecimal signature database (*.ndb) file
   from a list of data strings stored in a clear-text ascii file, with one data string entry per line.
   echo "
   The '-m' script flag provides a way to create a ClamAV hexadecimal signature database (*.ndb) file
   from a list of data strings stored in a clear-text ascii file, with one data string entry per line.
@@ -768,304 +991,325 @@ function make_signature_database_from_ascii_file () {
     echo -n "Enter the source file as /path/filename: "
     read -r source
     if [ -r "$source" ] ; then
     echo -n "Enter the source file as /path/filename: "
     read -r source
     if [ -r "$source" ] ; then
-      source_file=$(basename "$source")
+      source_file="$(basename "$source")"
 
 
-      echo "What signature prefix would you like to use?  For example: 'Phish.Domains'"
-      echo "will create signatures that looks like: 'Phish.Domains.1:4:*:HexSigHere'"
+      xshok_pretty_echo_and_log "What signature prefix would you like to use?  For example: 'Phish.Domains'"
+      xshok_pretty_echo_and_log "will create signatures that looks like: 'Phish.Domains.1:4:*:HexSigHere'"
 
       echo -n "Enter signature prefix: "
       read -r prefix
 
       echo -n "Enter signature prefix: "
       read -r prefix
-      path_file=$(echo "$source" | cut -d "." -f-1 | command sed 's/$/.ndb/')
-      db_file=$(basename "$path_file")
+      path_file="$(echo "$source" | cut -d "." -f -1 | command sed 's/$/.ndb/')"
+      db_file="$(basename "$path_file")"
       rm -f "$path_file"
       rm -f "$path_file"
-      total=$(wc -l "$source" | cut -d " " -f1)
-      line_num=1
+      total="$(wc -l "$source" | cut -d " " -f 1)"
+      line_num="1"
 
       while read -r line ; do
 
       while read -r line ; do
-        line_prefix=$(echo "$line" | awk -F ':' '{print $1}')
-        if [ "$line_prefix" = "-" ] ; then
-          echo "$line" | cut -d ":" -f2- | perl -pe 's/(.)/sprintf("%02lx", ord $1)/eg' | command sed "s/^/$prefix\.$line_num:4:\*:/" >> "$path_file"
-        elif [ "$line_prefix" = "=" ] ; then
-          echo "$line" | cut -d ":" -f2- | perl -pe 's/(\{[^}]*\}|\([^)]*\)|\*)|(.)/defined $1 ? $1 : sprintf("%02lx", ord $2)/eg' | command sed "s/^/$prefix\.$line_num:4:\*:/" >> "$path_file"
+        line_prefix="$(echo "$line" | awk -F ":" '{print $1}')"
+        if [ "$line_prefix" == "-" ] ; then
+          echo "$line" | cut -d ":" -f 2- | perl -pe 's/(.)/sprintf("%02lx", ord $1)/eg' | command sed "s/^/$prefix\\.$line_num:4:\\*:/" >> "$path_file"
+        elif [ "$line_prefix" == "=" ] ; then
+          echo "$line" | cut -d ":" -f 2- | perl -pe 's/(\{[^}]*\}|\([^)]*\)|\*)|(.)/defined $1 ? $1 : sprintf("%02lx", ord $2)/eg' | command sed "s/^/$prefix\\.$line_num:4:\\*:/" >> "$path_file"
         else
         else
-          echo "$line" | perl -pe 's/(.)/sprintf("%02lx", ord $1)/eg' | command sed "s/^/$prefix\.$line_num:4:\*:/" >> "$path_file"
+          echo "$line" | perl -pe 's/(.)/sprintf("%02lx", ord $1)/eg' | command sed "s/^/$prefix\\.$line_num:4:\\*:/" >> "$path_file"
         fi
         fi
-        echo "Hexadecimal encoding $source_file line: $line_num of $total"
-        line_num=$((line_num + 1))
+        xshok_pretty_echo_and_log "Hexadecimal encoding ${source_file} line: ${line_num} of ${total}"
+        line_num="$((line_num + 1))"
       done < "$source"
     else
       done < "$source"
     else
-      echo "Source file not found, exiting..."
+      xshok_pretty_echo_and_log "Source file not found, exiting..."
       exit
     fi
 
 
       exit
     fi
 
 
-    echo "Signature database file created at: $path_file"
-    if $clamscan_bin --quiet -d "$path_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
+    xshok_pretty_echo_and_log "Signature database file created at: ${path_file}"
+    if $clamscan_bin --quiet -d "$path_file" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
 
 
-      echo "Clamscan reports database integrity tested good."
+      xshok_pretty_echo_and_log "Clamscan reports database integrity tested good."
 
 
-      echo -n "Would you like to move '$db_file' into '$clam_dbs' and reload databases?"
+      echo -n "Would you like to move '${db_file}' into '${clam_dbs}' and reload databases?"
       if xshok_prompt_confirm ; then
       if xshok_prompt_confirm ; then
-        if ! cmp -s "$path_file" "$clam_dbs/$db_file" ; then
+        if ! cmp -s "$path_file" "${clam_dbs}/${db_file}" ; then
           if $rsync_bin -pcqt "$path_file" "$clam_dbs" ; then
           if $rsync_bin -pcqt "$path_file" "$clam_dbs" ; then
-            perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
+            perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
             perms chmod -f 0644 "$clam_dbs"/"$db_file"
             if [ "$selinux_fixes" == "yes" ] ; then
             perms chmod -f 0644 "$clam_dbs"/"$db_file"
             if [ "$selinux_fixes" == "yes" ] ; then
-              restorecon "$clam_dbs/$db_file"
+              restorecon "${clam_dbs}/${db_file}"
             fi
             $clamd_restart_opt
 
             fi
             $clamd_restart_opt
 
-            echo "Signature database '$db_file' was successfully implemented and ClamD databases reloaded."
+            xshok_pretty_echo_and_log "Signature database '${db_file}' was successfully implemented and ClamD databases reloading."
           else
 
           else
 
-            echo "Failed to add/update '$db_file', ClamD database not reloaded."
+            xshok_pretty_echo_and_log "Failed to add/update '${db_file}', ClamD database not reloading."
           fi
         else
 
           fi
         else
 
-          echo "Database '$db_file' has not changed - skipping"
+          xshok_pretty_echo_and_log "Database '${db_file}' has not changed - skipping"
         fi
       else
 
         fi
       else
 
-        echo "No action taken."
+        xshok_pretty_echo_and_log "No action taken."
       fi
     else
 
       fi
     else
 
-      echo "Clamscan reports that '$db_file' signature database integrity tested bad."
+      xshok_pretty_echo_and_log "Clamscan reports that '${db_file}' signature database integrity tested bad."
     fi
   fi
 }
 
     fi
   fi
 }
 
-#Remove the clamav-unofficial-sigs script
-function remove_script () {
-  echo ""
+# Remove the clamav-unofficial-sigs script
+function remove_script() {
+  xshok_pretty_echo_and_log ""
   if [ -n "$pkg_mgr" ] || [ -n "$pkg_rm" ] ; then
   if [ -n "$pkg_mgr" ] || [ -n "$pkg_rm" ] ; then
-    echo "This script (clamav-unofficial-sigs) was installed on the system via '$pkg_mgr'"
-    echo "use '$pkg_rm' to remove the script and all of its associated files and databases from the system."
+    xshok_pretty_echo_and_log "This script (clamav-unofficial-sigs) was installed on the system via '${pkg_mgr}'"
+    xshok_pretty_echo_and_log "use '${pkg_rm}' to remove the script and all of its associated files and databases from the system."
 
   else
 
   else
-    cron_file_full_path="$cron_dir/$cron_filename"
-    logrotate_file_full_path="$logrotate_dir/$logrotate_filename"
-    man_file_full_path="$man_dir/$man_filename"
-    
-    echo "This will remove the workdir ($work_dir), logrotate file ($logrotate_file_full_path), cron file ($cron_file_full_path), man file ($man_file_full_path)"
-    echo "Are you sure you want to remove the clamav-unofficial-sigs script and all of its associated files, third-party databases, and work directory from the system?"
+    cron_file_full_path="${cron_dir}/${cron_filename}"
+    logrotate_file_full_path="${logrotate_dir}/${logrotate_filename}"
+    man_file_full_path="${man_dir}/${man_filename}"
+
+    xshok_pretty_echo_and_log "This will remove the workdir (${work_dir}), logrotate file (${logrotate_file_full_path}), cron file (${cron_file_full_path}), man file (${man_file_full_path})"
+    xshok_pretty_echo_and_log "Are you sure you want to remove the clamav-unofficial-sigs script and all of its associated files, third-party databases, and work directory from the system?"
     if xshok_prompt_confirm ; then
     if xshok_prompt_confirm ; then
-      echo "This can not be undone are you sure ?"
+      xshok_pretty_echo_and_log "This can not be undone are you sure ?"
       if xshok_prompt_confirm ; then
       if xshok_prompt_confirm ; then
-        if [ -r "$work_dir_work_configs/purge.txt" ] ; then
+        if [ -r "${work_dir_work_configs}/purge.txt" ] ; then
 
           while read -r file ; do
             xshok_is_file "$file" && rm -f -- "$file"
 
           while read -r file ; do
             xshok_is_file "$file" && rm -f -- "$file"
-            echo "     Removed file: $file"
-          done < "$work_dir_work_configs"/purge.txt
+            xshok_pretty_echo_and_log "     Removed file: ${file}"
+          done < "${work_dir_work_configs}/purge.txt"
           if [ -r "$cron_file_full_path" ] ; then
             xshok_is_file "$cron_file_full_path" && rm -f "$cron_file_full_path"
           if [ -r "$cron_file_full_path" ] ; then
             xshok_is_file "$cron_file_full_path" && rm -f "$cron_file_full_path"
-            echo "     Removed file: $cron_file_full_path"
+            xshok_pretty_echo_and_log "     Removed file: ${cron_file_full_path}"
           fi
           if [ -r "$logrotate_file_full_path" ] ; then
             xshok_is_file "$logrotate_file_full_path" && rm -f "$logrotate_file_full_path"
           fi
           if [ -r "$logrotate_file_full_path" ] ; then
             xshok_is_file "$logrotate_file_full_path" && rm -f "$logrotate_file_full_path"
-            echo "     Removed file: $logrotate_file_full_path"
+            xshok_pretty_echo_and_log "     Removed file: ${logrotate_file_full_path}"
           fi
           if [ -r "$man_file_full_path" ] ; then
             xshok_is_file "$man_file_full_path" && rm -f "$man_file_full_path"
           fi
           if [ -r "$man_file_full_path" ] ; then
             xshok_is_file "$man_file_full_path" && rm -f "$man_file_full_path"
-            echo "     Removed file: $man_file_full_path"
+            xshok_pretty_echo_and_log "     Removed file: ${man_file_full_path}"
           fi
           fi
-          
-          #rather keep the configs
+
+          # Rather keep the configs
           #rm -f -- "$default_config" && echo "     Removed file: $default_config"
           #rm -f -- "$default_config" && echo "     Removed file: $default_config"
-          #rm -f -- "$0" && echo "     Removed file: $0"
-          xshok_is_subdir "$work_dir" && rm -rf -- "$work_dir" && echo "     Removed script working directories: $work_dir"
+          #rm -f -- "${0}" && echo "     Removed file: $0"
+          xshok_is_subdir "$work_dir" && rm -rf -- "${work_dir:?}" && echo "     Removed script working directories: ${work_dir}"
 
 
-          echo "  The clamav-unofficial-sigs script and all of its associated files, third-party"
-          echo "  databases, and work directories have been successfully removed from the system."
+          xshok_pretty_echo_and_log "  The clamav-unofficial-sigs script and all of its associated files, third-party"
+          xshok_pretty_echo_and_log "  databases, and work directories have been successfully removed from the system."
 
         else
 
         else
-          echo "  Cannot locate 'purge.txt' file in $work_dir_work_configs."
-          echo "  Files and signature database will need to be removed manually."
+          xshok_pretty_echo_and_log "  Cannot locate 'purge.txt' file in ${work_dir_work_configs}."
+          xshok_pretty_echo_and_log "  Files and signature database will need to be removed manually."
         fi
       else
         fi
       else
-        echo "Aborted"
+        xshok_pretty_echo_and_log "Aborted"
       fi
     else
       fi
     else
-      echo "Aborted"
+      xshok_pretty_echo_and_log "Aborted"
     fi
   fi
 }
 
     fi
   fi
 }
 
-#Clamscan integrity test a specific database file
-function clamscan_integrity_test_specific_database_file () { #databasefile
-  echo ""
-  if [ "$1" ] ; then
-    input=$(echo "$1" | awk -F '/' '{print $NF}')
-    db_file=$(find "$work_dir" -name "$input")
+# Clamscan integrity test a specific database file
+function clamscan_integrity_test_specific_database_file() { # databasefile
+  xshok_pretty_echo_and_log ""
+  if [ "${1}" ] ; then
+    input="$(echo "${1}" | awk -F "/" '{print $NF}')"
+    db_file="$(find "$work_dir" -name "$input")"
     if [ -r "$db_file" ] ; then
     if [ -r "$db_file" ] ; then
-      echo "Clamscan integrity testing: $db_file"
-
-      $clamscan_bin --quiet -d "$db_file" "$work_dir_work_configs/scan-test.txt"
-      if [ "$?" -eq "0" ]; then
-        echo "Clamscan reports that '$input' database integrity tested GOOD"
+      xshok_pretty_echo_and_log "Clamscan integrity testing: ${db_file}"
+      if $clamscan_bin --quiet -d "$db_file" "${work_dir_work_configs}/scan-test.txt" ; then
+        xshok_pretty_echo_and_log "Clamscan reports that '${input}' database integrity tested GOOD"
         exit 0
       else
         exit 0
       else
-        echo "Clamscan reports that '$input' database integrity tested BAD"
+        xshok_pretty_echo_and_log "Clamscan reports that '${input}' database integrity tested BAD"
         exit 1
       fi
     else
         exit 1
       fi
     else
-      echo "File '$input' cannot be found."
-      echo "Here is a list of third-party databases that can be clamscan integrity tested:"
+      xshok_pretty_echo_and_log "File '${input}' cannot be found."
+      xshok_pretty_echo_and_log "Here is a list of third-party databases that can be clamscan integrity tested:"
 
 
-      echo "=== Sanesecurity ==="
+      xshok_pretty_echo_and_log "=== Sanesecurity ==="
       ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_sanesecurity"
       ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_sanesecurity"
-      
-      echo "=== SecuriteInfo ==="
+
+      xshok_pretty_echo_and_log "=== SecuriteInfo ==="
       ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_securiteinfo"
       ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_securiteinfo"
-      
-      echo "=== MalwarePatrol ==="
+
+      xshok_pretty_echo_and_log "=== MalwarePatrol ==="
       ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_malwarepatrol"
 
       ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_malwarepatrol"
 
-      echo "=== Linux Malware Detect ==="
+      xshok_pretty_echo_and_log "=== Linux Malware Detect ==="
       ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_linuxmalwaredetect"
 
       ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_linuxmalwaredetect"
 
-      echo "=== Linux Malware Detect ==="
+      xshok_pretty_echo_and_log "=== Linux Malware Detect ==="
       ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_yararulesproject"
 
       ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_yararulesproject"
 
-      echo "=== User Defined Databases ==="
+      xshok_pretty_echo_and_log "=== User Defined Databases ==="
       ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_add"
 
       ls --ignore "*.sig" --ignore "*.md5" --ignore "*.ign2" "$work_dir_add"
 
-      echo "Check the file name and try again..."
-    fi 
+      xshok_pretty_echo_and_log "Check the file name and try again..."
+    fi
   else
   else
-    xshok_pretty_echo_and_log "ERROR: Missing value for option" "="
+    xshok_pretty_echo_and_log "ERROR: Missing value for option"
     exit 1
   fi
 }
 
     exit 1
   fi
 }
 
-#output names of any third-party signatures that triggered during the HAM directory scan
-function output_signatures_triggered_during_ham_directory_scan () {
-  echo ""
+# Output names of any third-party signatures that triggered during the HAM directory scan
+function output_signatures_triggered_during_ham_directory_scan() {
+  xshok_pretty_echo_and_log ""
   if [ -n "$ham_dir" ] ; then
   if [ -n "$ham_dir" ] ; then
-    if [ -r "$work_dir_work_configs/whitelist.hex" ] ; then
-      echo "The following third-party signatures triggered hits during the HAM Directory scan:"
+    if [ -r "${work_dir_work_configs}/whitelist.hex" ] ; then
+      xshok_pretty_echo_and_log "The following third-party signatures triggered hits during the HAM Directory scan:"
 
 
-      $grep_bin -h -f "$work_dir_work_configs/whitelist.hex" "$work_dir"/*/*.ndb | cut -d ":" -f1
+      $grep_bin -h -f "${work_dir_work_configs}/whitelist.hex" "$work_dir"/*/*.ndb | cut -d ":" -f 1
+      $grep_bin -h -f "${work_dir_work_configs}/whitelist.hex" "$work_dir"/*/*.db | cut -d "=" -f 1
     else
     else
-      echo "No third-party signatures have triggered hits during the HAM Directory scan."
+      xshok_pretty_echo_and_log "No third-party signatures have triggered hits during the HAM Directory scan."
     fi
   else
     fi
   else
-    echo "Ham directory scanning is not currently enabled in the script's configuration file."
+    xshok_pretty_echo_and_log "Ham directory scanning is not currently enabled in the script's configuration file."
   fi
 }
 
   fi
 }
 
-#Adds a signature whitelist entry in the newer ClamAV IGN2 format
-function add_signature_whitelist_entry () {
-  echo ""
-  echo "Input a third-party signature name that you wish to whitelist due to false-positives"
-  echo "and press enter (do not include '.UNOFFICIAL' in the signature name nor add quote"
-  echo "marks to the input string):"
-
-  read -r input
+# Adds a signature whitelist entry in the newer ClamAV IGN2 format
+function add_signature_whitelist_entry() { #signature
+  xshok_pretty_echo_and_log "Signature Whitelist" "="
+       if [ -n "$1" ] ; then
+               input="$1"
+       else
+               xshok_pretty_echo_and_log "Input a third-party signature name that you wish to whitelist and press enter"
+               read -r input
+       fi
   if [ -n "$input" ] ; then
   if [ -n "$input" ] ; then
+               xshok_pretty_echo_and_log "Processing: ${input}"
     cd "$clam_dbs" || exit
     cd "$clam_dbs" || exit
-    input=$(echo "$input" | tr -d "'" | tr -d '"')
-    sig_full=$($grep_bin -H "$input" ./*.*db)
-    sig_name=$(echo "$sig_full" | cut -d ":" -f2)
+               # Remove quotes and .UNOFFICIAL from the string
+               input="$(echo "${input}" | tr -d "'" | tr -d '"' | tr -d '`"')"
+               input=${input/\.UNOFFICIAL/}
+
+    sig_full="$($grep_bin -H -m 1 "$input" ./*.*db)"
+               sig_extension=${sig_full%%\:*}
+               sig_extension=${sig_extension##*\.}
+               shopt -s nocasematch
+               if [ "$sig_extension" == "hdb" ] || [ "$sig_extension" == "hsb" ] || [ "$sig_extension" == "hdu " ] || [ "$sig_extension" == "hsu" ] || [ "$sig_extension" == "mdb" ] || [ "$sig_extension" == "msb" ] || [ "$sig_extension" == "mdu" ] || [ "$sig_extension" == "msu" ] ; then
+                       # Hash-based Signature Database
+                       position="4"
+               else
+                       position="2"
+               fi
+    sig_name="$(echo "$sig_full" | cut -d ":" -f $position | cut -d "=" -f 1)"
+
     if [ -n "$sig_name" ] ; then
     if [ -n "$sig_name" ] ; then
-      if ! $grep_bin "$sig_name" my-whitelist.ign2 > /dev/null 2>&1 ; then
-        cp -f my-whitelist.ign2 "$work_dir_work_configs" 2>/dev/null
-        echo "$sig_name" >> "$work_dir_work_configs/my-whitelist.ign2"
-        echo "$sig_full" >> "$work_dir_work_configs/tracker.txt"
-        if $clamscan_bin --quiet -d "$work_dir_work_configs/my-whitelist.ign2" "$work_dir_work_configs/scan-test.txt" ; then
-          if $rsync_bin -pcqt "$work_dir_work_configs/my-whitelist.ign2" "$clam_dbs" ; then
-            perms chown -f "$clam_user:$clam_group" my-whitelist.ign2
-
-            if [ ! -s "$work_dir_work_configs/monitor-ign.txt" ] ; then 
+      if ! $grep_bin -m 1 "$sig_name" my-whitelist.ign2 > /dev/null 2>&1 ; then
+        cp -f -p my-whitelist.ign2 "$work_dir_work_configs" 2>/dev/null
+        echo "$sig_name" >> "${work_dir_work_configs}/my-whitelist.ign2"
+        echo "$sig_full" >> "${work_dir_work_configs}/tracker.txt"
+        if $clamscan_bin --quiet -d "${work_dir_work_configs}/my-whitelist.ign2" "${work_dir_work_configs}/scan-test.txt" ; then
+          if $rsync_bin -pcqt "${work_dir_work_configs}/my-whitelist.ign2" "$clam_dbs" ; then
+            perms chown -f "${clam_user}:${clam_group}" my-whitelist.ign2
+
+            if [ ! -s "${work_dir_work_configs}/monitor-ign.txt" ] ; then
               # Create "monitor-ign.txt" file for clamscan database integrity testing.
               # Create "monitor-ign.txt" file for clamscan database integrity testing.
-              echo "This is the monitor ignore file..." > "$work_dir_work_configs/monitor-ign.txt"
+              echo "This is the monitor ignore file..." > "${work_dir_work_configs}/monitor-ign.txt"
             fi
 
             fi
 
-            perms chmod -f 0644 my-whitelist.ign2 "$work_dir_work_configs/monitor-ign.txt"
+            perms chmod -f 0644 my-whitelist.ign2 "${work_dir_work_configs}/monitor-ign.txt"
             if [ "$selinux_fixes" == "yes" ] ; then
             if [ "$selinux_fixes" == "yes" ] ; then
-              restorecon "$clam_dbs/local.ign"
+              restorecon "${clam_dbs}/local.ign"
             fi
             fi
+                                               do_clamd_reload="4"
             clamscan_reload_dbs
 
             clamscan_reload_dbs
 
-            echo "Signature '$input' has been added to my-whitelist.ign2 and"
-            echo "all databases have been reloaded.  The script will track any changes"
-            echo "to the offending signature and will automatically remove it if the"
-            echo "signature is modified or removed from the third-party database."
+            xshok_pretty_echo_and_log "Signature '${input}' has been added to my-whitelist.ign2 and"
+            xshok_pretty_echo_and_log "all databases have been reloaded.  The script will track any changes"
+            xshok_pretty_echo_and_log "to the offending signature and will automatically remove it if the"
+            xshok_pretty_echo_and_log "signature is modified or removed from the third-party database."
           else
 
           else
 
-            echo "Failed to successfully update my-whitelist.ign2 file - SKIPPING."
+            xshok_pretty_echo_and_log "Failed to successfully update my-whitelist.ign2 file - SKIPPING."
           fi
         else
 
           fi
         else
 
-          echo "Clamscan reports my-whitelist.ign2 database integrity is bad - SKIPPING."
+          xshok_pretty_echo_and_log "Clamscan reports my-whitelist.ign2 database integrity is bad - SKIPPING."
         fi
       else
 
         fi
       else
 
-        echo "Signature '$input' already exists in my-whitelist.ign2 - no action taken."
+        xshok_pretty_echo_and_log "Signature '${input}' already exists in my-whitelist.ign2 - no action taken."
       fi
     else
 
       fi
     else
 
-      echo "Signature '$input' could not be found."
+      xshok_pretty_echo_and_log "Signature '${input}' could not be found."
 
 
-      echo "This script will only create a whitelise entry in my-whitelist.ign2 for ClamAV"
-      echo "'UNOFFICIAL' third-Party signatures as found in the *.ndb *.hdb *.db databases."
+      xshok_pretty_echo_and_log "This script will only create a whitelise entry in my-whitelist.ign2 for ClamAV"
+      xshok_pretty_echo_and_log "'UNOFFICIAL' third-Party signatures as found in the *.ndb *.hdb *.db databases."
     fi
   else
     fi
   else
-    echo "No input detected - no action taken."
+    xshok_pretty_echo_and_log "No input detected - no action taken."
   fi
 }
 
   fi
 }
 
-#Clamscan reload database
-function clamscan_reload_dbs () {
+# Clamscan reload database
+function clamscan_reload_dbs() {
   # Reload all clamd databases if updates detected and $reload_dbs" is set to "yes"
   # Reload all clamd databases if updates detected and $reload_dbs" is set to "yes"
-  if [ "$reload_dbs" = "yes" ] ; then
+  if [ "$reload_dbs" == "yes" ] ; then
     if [ "$do_clamd_reload" != "0" ] ; then
     if [ "$do_clamd_reload" != "0" ] ; then
-      if [ "$do_clamd_reload" = "1" ] ; then
+      if [ "$do_clamd_reload" == "1" ] ; then
         xshok_pretty_echo_and_log "Update(s) detected, reloading ClamAV databases" "="
         xshok_pretty_echo_and_log "Update(s) detected, reloading ClamAV databases" "="
-      elif [ "$do_clamd_reload" = "2" ] ; then
+      elif [ "$do_clamd_reload" == "2" ] ; then
         xshok_pretty_echo_and_log "Database removal(s) detected, reloading ClamAV databases" "="
         xshok_pretty_echo_and_log "Database removal(s) detected, reloading ClamAV databases" "="
-      elif [ "$do_clamd_reload" = "3" ] ; then      
+      elif [ "$do_clamd_reload" == "3" ] ; then
         xshok_pretty_echo_and_log "File 'local.ign' has changed, reloading ClamAV databases" "="
         xshok_pretty_echo_and_log "File 'local.ign' has changed, reloading ClamAV databases" "="
-      elif [ "$do_clamd_reload" = "4" ] ; then      
+      elif [ "$do_clamd_reload" == "4" ] ; then
         xshok_pretty_echo_and_log "File 'my-whitelist.ign2' has changed, reloading ClamAV databases" "="
       else
         xshok_pretty_echo_and_log "Update(s) detected, reloading ClamAV databases" "="
       fi
 
         xshok_pretty_echo_and_log "File 'my-whitelist.ign2' has changed, reloading ClamAV databases" "="
       else
         xshok_pretty_echo_and_log "Update(s) detected, reloading ClamAV databases" "="
       fi
 
-      if [[ $($clamd_reload_opt 2>&1) = *"ERROR"* ]] ; then
-        xshok_pretty_echo_and_log "ERROR: Failed to reload, trying again" "-"
+      if [[ "$($clamd_reload_opt 2>&1)" = *"ERROR"* ]] ; then
+        xshok_pretty_echo_and_log "ERROR: Failed to reload, trying again"
         if [ -r "$clamd_pid" ] ; then
         if [ -r "$clamd_pid" ] ; then
-          mypid=$(cat "$clamd_pid")
-          kill -USR2 "$mypid"
-          if [ $? -eq  0 ] ; then
-            xshok_pretty_echo_and_log "ClamAV databases Reloaded" "="
+          mypid="$(cat "$clamd_pid")"
+
+          if kill -USR2 "$mypid" ; then
+            xshok_pretty_echo_and_log "ClamAV databases reloading" "="
           else
           else
-            xshok_pretty_echo_and_log "ERROR: Failed to reload, forcing clamd to restart" "-"
-            if [ -z "$clamd_restart_opt" ] ; then      
-              xshok_pretty_echo_and_log "WARNING: Check the script's configuration file, 'reload_dbs' enabled but no 'clamd_restart_opt'" "*"
+            xshok_pretty_echo_and_log "ERROR: Failed to reload, forcing clamd to restart"
+            if [ -z "$clamd_restart_opt" ] ; then
+              xshok_pretty_echo_and_log "WARNING: Check the script's configuration file, 'reload_dbs' enabled but no 'clamd_restart_opt'"
             else
             else
-              $clamd_restart_opt
-              xshok_pretty_echo_and_log "ClamAV Restarted" "="
+              if $clamd_restart_opt > /dev/null ; then
+                xshok_pretty_echo_and_log "ClamAV Restarted" "="
+              else
+                xshok_pretty_echo_and_log "ClamAV NOT Restarted" "-"
+              fi
             fi
           fi
         else
             fi
           fi
         else
-          xshok_pretty_echo_and_log "ERROR: Failed to reload, forcing clamd to restart" "="
-          if [ -z "$clamd_restart_opt" ] ; then      
-            xshok_pretty_echo_and_log "WARNING: Check the script's configuration file, 'reload_dbs' enabled but no 'clamd_restart_opt'" "*"
+          xshok_pretty_echo_and_log "ERROR: Failed to reload, forcing clamd to restart"
+          if [ -z "$clamd_restart_opt" ] ; then
+            xshok_pretty_echo_and_log "WARNING: Check the script's configuration file, 'reload_dbs' enabled but no 'clamd_restart_opt'"
           else
           else
-            $clamd_restart_opt
-            xshok_pretty_echo_and_log "ClamAV Restarted" "="
+            if $clamd_restart_opt > /dev/null ; then
+              xshok_pretty_echo_and_log "ClamAV Restarted" "="
+            else
+              xshok_pretty_echo_and_log "ClamAV NOT Restarted" "-"
+            fi
           fi
           fi
-        fi   
+        fi
       else
       else
-        xshok_pretty_echo_and_log "ClamAV databases Reloaded" "="
+        xshok_pretty_echo_and_log "ClamAV databases reloading" "="
       fi
       fi
-    else   
+    else
       xshok_pretty_echo_and_log "No updates detected, ClamAV databases were not reloaded" "="
     fi
       xshok_pretty_echo_and_log "No updates detected, ClamAV databases were not reloaded" "="
     fi
-  else      
-    xshok_pretty_echo_and_log "Database reload has been disabled in the configuration file" "="  
+  else
+    xshok_pretty_echo_and_log "Database reload has been disabled in the configuration file" "="
   fi
 
 }
   fi
 
 }
@@ -1073,31 +1317,31 @@ function clamscan_reload_dbs () {
 # If ClamD status check is enabled ("clamd_socket" variable is uncommented
 # and the socket path is correctly specified in "User Edit" section above),
 # then test to see if clamd is running or not.
 # If ClamD status check is enabled ("clamd_socket" variable is uncommented
 # and the socket path is correctly specified in "User Edit" section above),
 # then test to see if clamd is running or not.
-function check_clamav () {
+function check_clamav() {
   if [ -n "$clamd_socket" ] ; then
     if [ -S "$clamd_socket" ] ; then
       if [ "$(perl -e 'use IO::Socket::UNIX; print $IO::Socket::UNIX::VERSION,"\n"' 2>/dev/null)" ] ; then
   if [ -n "$clamd_socket" ] ; then
     if [ -S "$clamd_socket" ] ; then
       if [ "$(perl -e 'use IO::Socket::UNIX; print $IO::Socket::UNIX::VERSION,"\n"' 2>/dev/null)" ] ; then
-        io_socket1=1
-        if [ "$(perl -MIO::Socket::UNIX -we '$s = IO::Socket::UNIX->new(shift); $s->print("PING"); print $s->getline; $s->close' "$clamd_socket" 2>/dev/null)" = "PONG" ] ; then
-          io_socket2=1
+        io_socket1="1"
+        if [ "$(perl -MIO::Socket::UNIX -we '$s = IO::Socket::UNIX->new(shift); $s->print("PING"); print $s->getline; $s->close' "$clamd_socket" 2>/dev/null)" == "PONG" ] ; then
+          io_socket2="1"
           xshok_pretty_echo_and_log "ClamD is running" "="
         fi
       else
           xshok_pretty_echo_and_log "ClamD is running" "="
         fi
       else
-        socat="$(which socat 2>/dev/null)"
+        socat="$(command -v socat 2>/dev/null)"
         if [ -n "$socat" ] && [ -x "$socat" ] ; then
         if [ -n "$socat" ] && [ -x "$socat" ] ; then
-          socket_cat1=1
-          if [ "$( (echo "PING"; sleep 1;) | socat - "$clamd_socket" 2>/dev/null)" = "PONG" ] ; then
-            socket_cat2=1
+          socket_cat1="1"
+          if [ "$( (echo "PING"; sleep 1;) | socat - "$clamd_socket" 2>/dev/null)" == "PONG" ] ; then
+            socket_cat2="1"
             xshok_pretty_echo_and_log "ClamD is running" "="
           fi
         fi
       fi
       if [ -z "$io_socket1" ] && [ -z "$socket_cat1" ] ; then
             xshok_pretty_echo_and_log "ClamD is running" "="
           fi
         fi
       fi
       if [ -z "$io_socket1" ] && [ -z "$socket_cat1" ] ; then
-        xshok_pretty_echo_and_log "WARNING: socat or perl module 'IO::Socket::UNIX' not found, cannot test if ClamD is running" "*"
+        xshok_pretty_echo_and_log "WARNING: socat or perl module 'IO::Socket::UNIX' not found, cannot test if ClamD is running"
       else
         if [ -z "$io_socket2" ] && [ -z "$socket_cat2" ] ; then
 
       else
         if [ -z "$io_socket2" ] && [ -z "$socket_cat2" ] ; then
 
-          xshok_pretty_echo_and_log "ALERT: CLAMD IS NOT RUNNING!" "="
+          xshok_pretty_echo_and_log "ALERT: CLAMD IS NOT RUNNING!"
           if [ -n "$clamd_restart_opt" ] ; then
             xshok_pretty_echo_and_log "Attempting to start ClamD..." "-"
             if [ -n "$io_socket1" ] ; then
           if [ -n "$clamd_restart_opt" ] ; then
             xshok_pretty_echo_and_log "Attempting to start ClamD..." "-"
             if [ -n "$io_socket1" ] ; then
@@ -1105,16 +1349,16 @@ function check_clamav () {
               if [ "$(perl -MIO::Socket::UNIX -we '$s = IO::Socket::UNIX->new(shift); $s->print("PING"); print $s->getline; $s->close' "$clamd_socket" 2>/dev/null)" = "PONG" ] ; then
                 xshok_pretty_echo_and_log "ClamD was successfully started" "="
               else
               if [ "$(perl -MIO::Socket::UNIX -we '$s = IO::Socket::UNIX->new(shift); $s->print("PING"); print $s->getline; $s->close' "$clamd_socket" 2>/dev/null)" = "PONG" ] ; then
                 xshok_pretty_echo_and_log "ClamD was successfully started" "="
               else
-                xshok_pretty_echo_and_log "ERROR: CLAMD FAILED TO START" "="
+                xshok_pretty_echo_and_log "ERROR: CLAMD FAILED TO START"
                 exit 1
               fi
             else
               if [ -n "$socket_cat1" ] ; then
                 $clamd_restart_opt > /dev/null && sleep 5
                 exit 1
               fi
             else
               if [ -n "$socket_cat1" ] ; then
                 $clamd_restart_opt > /dev/null && sleep 5
-                if [ "$( (echo "PING"; sleep 1;) | socat - "$clamd_socket" 2>/dev/null)" = "PONG" ] ; then
+                if [ "$( (echo "PING"; sleep 1;) | socat - "$clamd_socket" 2>/dev/null)" == "PONG" ] ; then
                   xshok_pretty_echo_and_log "ClamD was successfully started" "="
                 else
                   xshok_pretty_echo_and_log "ClamD was successfully started" "="
                 else
-                  xshok_pretty_echo_and_log "ERROR: CLAMD FAILED TO START" "="
+                  xshok_pretty_echo_and_log "ERROR: CLAMD FAILED TO START"
                   exit 1
                 fi
               fi
                   exit 1
                 fi
               fi
@@ -1123,209 +1367,324 @@ function check_clamav () {
         fi
       fi
     else
         fi
       fi
     else
-      xshok_pretty_echo_and_log "WARNING: $clamd_socket is not a usable socket" "*"
+      xshok_pretty_echo_and_log "WARNING: ${clamd_socket} is not a usable socket"
     fi
   else
     fi
   else
-    xshok_pretty_echo_and_log "WARNING: clamd_socket is not defined in the configuration file" "*"
+    xshok_pretty_echo_and_log "WARNING: clamd_socket is not defined in the configuration file"
   fi
 }
 
   fi
 }
 
-#function to check for a new version
-function check_new_version () {
-  if [ "$wget_bin" != "" ] ; then
-    latest_version="$($wget_bin https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/clamav-unofficial-sigs.sh -O - 2> /dev/null | $grep_bin  "script""_version=" | cut -d\" -f2)"
-  else
-    latest_version="$($curl_bin https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/clamav-unofficial-sigs.sh 2> /dev/null | $grep_bin  "script""_version=" | cut -d\" -f2)"
-  fi
+# Check for a new version
+function check_new_version() {
+       found_upgrade="no"
+  if [ -n "$curl_bin" ] ; then
+               # shellcheck disable=SC2086
+               latest_version="$($curl_bin --compressed $curl_proxy $curl_insecure $curl_output_level --connect-timeout "${downloader_connect_timeout}" --remote-time --location --retry "${downloader_tries}" --max-time "${downloader_max_time}" "https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/clamav-unofficial-sigs.sh" 2>&11 | $grep_bin "^script_version=" | head -n1 | cut -d '"' -f 2)"
+               # shellcheck disable=SC2086
+               latest_config_version="$($curl_bin --compressed $curl_proxy $curl_insecure $curl_output_level --connect-timeout "${downloader_connect_timeout}" --remote-time --location --retry "${downloader_tries}" --max-time "${downloader_max_time}" "https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/config/master.conf" 2>&11 | $grep_bin "^config_version=" | head -n1 | cut -d '"' -f 2)"
+       else
+               # shellcheck disable=SC2086
+               latest_version="$($wget_bin $wget_compression $wget_proxy $wget_insecure $wget_output_level --connect-timeout="${downloader_connect_timeout}" --random-wait --tries="${downloader_tries}" --timeout="${downloader_max_time}" "https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/clamav-unofficial-sigs.sh" -O - 2>&12 | $grep_bin "^script_version=" | head -n1 | cut -d '"' -f 2)"
+               # shellcheck disable=SC2086
+               latest_config_version="$($wget_bin $wget_compression $wget_proxy $wget_insecure $wget_output_level --connect-timeout="${downloader_connect_timeout}" --random-wait --tries="${downloader_tries}" --timeout="${downloader_max_time}" "https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/${git_branch}/config/master.conf" -O - 2>&12 | $grep_bin "^config_version=" | head -n1 | cut -d '"' -f 2)"
+       fi
   if [ "$latest_version" ] ; then
   if [ "$latest_version" ] ; then
-    if [ ! "$latest_version" == "$script_version" ] ; then
-      xshok_pretty_echo_and_log "New version : v$latest_version @ https://github.com/extremeshok/clamav-unofficial-sigs" "-"
+               # shellcheck disable=SC2183,SC2086
+               if [ "$(printf "%02d%02d%02d%02d" ${latest_version//./ })" -gt "$(printf "%02d%02d%02d%02d" ${script_version//./ })" ] ; then
+      xshok_pretty_echo_and_log "ALERT: New version : v${latest_version} @ https://github.com/extremeshok/clamav-unofficial-sigs"
+                       found_upgrade="yes"
+    fi
+  fi
+  if [ "$latest_config_version" ] ; then
+               # shellcheck disable=SC2183,SC2086
+               if [ "$(printf "%02d%02d%02d%02d" ${latest_config_version//./ })" -gt "$(printf "%02d%02d%02d%02d" ${config_version//./ })" ] ; then
+      xshok_pretty_echo_and_log "ALERT: New config version : v${latest_config_version} @ https://github.com/extremeshok/clamav-unofficial-sigs"
+                       found_upgrade="yes"
     fi
   fi
     fi
   fi
+
+if [ "$found_upgrade" == "yes" ] && [ "$allow_upgrades" == "yes" ] ; then
+       xshok_pretty_echo_and_log "Quickly upgrade, run the following command as root:"
+       xshok_pretty_echo_and_log "${this_script_name} --upgrade"
+fi
+
 }
 
 }
 
-#function for help and usage
-##usage: 
+# Display help and usage
+# Usage:
 # help_and_usage "1" - enables the man output formatting
 # help_and_usage - normal help output formatting
 # help_and_usage "1" - enables the man output formatting
 # help_and_usage - normal help output formatting
-function help_and_usage () {
-
-  if [ "$1" ] ; then
-    #option_format_start
-    ofs="\fB"
-    #option_format_end
-    ofe="\fR"
-    #option_format_blankline
+function help_and_usage() {
+
+  if [ "${1}" ] ; then
+    # option_format_start
+    ofs="\\fB"
+    # option_format_end
+    ofe="\\fR"
+    # option_format_blankline
     ofb=".TP"
     ofb=".TP"
-    #option_format_tab_line
+    # option_format_tab_line
     oft=" "
   else
     oft=" "
   else
-    #option_format_start
+    # option_format_start
     ofs="${BOLD}"
     ofs="${BOLD}"
-    #option_format_end
-    ofe="${NORM}\t"
-    #option_format_blankline
-    ofb="\n"
-    #option_format_tab_line
-    oft="\n\t"
-  fi
-
-helpcontents=$(cat << EOF
-$ofs Usage: $(basename "$0") $ofe [OPTION] [PATH|FILE]
-$ofb
-$ofs -c, --config $ofe Use a specific configuration file or directory $oft eg: '-c /your/dir' or ' -c /your/file.name'  $oft Note: If a directory is specified the directory must contain atleast:  $oft master.conf, os.conf or user.conf $oft Default Directory: $config_dir
-$ofb 
-$ofs -F, --force $ofe Force all databases to be downloaded, could cause ip to be blocked
-$ofb 
-$ofs -h, --help $ofe Display this script's help and usage information
-$ofb 
-$ofs -V, --version $ofe Output script version and date information
-$ofb 
-$ofs -v, --verbose $ofe Be verbose, enabled when not run under cron
-$ofb 
-$ofs -s, --silence $ofe Only output error messages, enabled when run under cron
-$ofb 
-$ofs -d, --decode-sig $ofe Decode a third-party signature either by signature name $oft (eg: Sanesecurity.Junk.15248) or hexadecimal string. $oft This flag will 'NOT' decode image signatures
-$ofb 
-$ofs -e, --encode-string $ofe Hexadecimal encode an entire input string that can $oft be used in any '*.ndb' signature database file
-$ofb 
-$ofs -f, --encode-formatted $ofe Hexadecimal encode a formatted input string containing $oft signature spacing fields '{}, (), *', without encoding $oft the spacing fields, so that the encoded signature $oft can be used in any '*.ndb' signature database file
-$ofb 
-$ofs -g, --gpg-verify $ofe GPG verify a specific Sanesecurity database file $oft eg: '-g filename.ext' (do not include file path)
-$ofb 
-$ofs -i, --information $ofe Output system and configuration information for $oft viewing or possible debugging purposes
-$ofb 
-$ofs -m, --make-database $ofe Make a signature database from an ascii file containing $oft data strings, with one data string per line.  Additional $oft information is provided when using this flag
-$ofb 
-$ofs -t, --test-database $ofe Clamscan integrity test a specific database file $oft eg: '-t filename.ext' (do not include file path)
-$ofb 
-$ofs -o, --output-triggered $ofe If HAM directory scanning is enabled in the script's $oft configuration file, then output names of any third-party $oft signatures that triggered during the HAM directory scan
-$ofb 
-$ofs -w, --whitelist $ofe Adds a signature whitelist entry in the newer ClamAV IGN2 $oft format to 'my-whitelist.ign2' in order to temporarily resolve $oft a false-positive issue with a specific third-party signature. $oft Script added whitelist entries will automatically be removed $oft if the original signature is either modified or removed from $oft the third-party signature database
-$ofb 
-$ofs --check-clamav $ofe If ClamD status check is enabled and the socket path is correctly $oft specifiedthen test to see if clamd is running or not
-$ofb 
-$ofs --install-all $ofe Install and generate the cron, logroate and man files, autodetects the values $oft based on your config files
-$ofb
-$ofs --install-cron $ofe Install and generate the cron file, autodetects the values $oft based on your config files
-$ofb 
-$ofs --install-logrotate $ofe Install and generate the logrotate file, autodetects the $oft values based on your config files
-$ofb 
-$ofs --install-man $ofe Install and generate the man file, autodetects the $oft values based on your config files
-$ofb 
-$ofs --remove-script $ofe Remove the clamav-unofficial-sigs script and all of $oft its associated files and databases from the system
-$ofb 
+    # option_format_end
+    ofe="${NORM}\\t"
+    # option_format_blankline
+    ofb="\\n"
+    # option_format_tab_line
+    oft="\\n\\t"
+  fi
+
+  helpcontents="$(cat << EOF
+${ofs} Usage: $(basename "$0") ${ofe} [OPTION] [PATH|FILE]
+${ofb}
+${ofs} -c, --config ${ofe} Use a specific configuration file or directory ${oft} eg: '-c /your/dir' or ' -c /your/file.name'  ${oft} Note: If a directory is specified the directory must contain atleast:  ${oft} master.conf, os.conf or user.conf ${oft} Default Directory: ${config_dir}
+${ofb}
+${ofs} -F, --force ${ofe} Force all databases to be downloaded, could cause ip to be blocked
+${ofb}
+${ofs} -h, --help ${ofe} Display this script's help and usage information
+${ofb}
+${ofs} -V, --version ${ofe} Output script version and date information
+${ofb}
+${ofs} -v, --verbose ${ofe} Be verbose, enabled when not run under cron
+${ofb}
+${ofs} -s, --silence ${ofe} Only output error messages, enabled when run under cron
+${ofb}
+${ofs} -d, --decode-sig ${ofe} Decode a third-party signature either by signature name ${oft} (eg: Sanesecurity.Junk.15248) or hexadecimal string. ${oft} This flag will 'NOT' decode image signatures
+${ofb}
+${ofs} -e, --encode-string ${ofe} Hexadecimal encode an entire input string that can ${oft} be used in any '*.ndb' signature database file
+${ofb}
+${ofs} -f, --encode-formatted ${ofe} Hexadecimal encode a formatted input string containing ${oft} signature spacing fields '{}, (), *', without encoding ${oft} the spacing fields, so that the encoded signature ${oft} can be used in any '*.ndb' signature database file
+${ofb}
+${ofs} -g, --gpg-verify ${ofe} GPG verify a specific Sanesecurity database file ${oft} eg: '-g filename.ext' (do not include file path)
+${ofb}
+${ofs} -i, --information ${ofe} Output system and configuration information for ${oft} viewing or possible debugging purposes
+${ofb}
+${ofs} -m, --make-database ${ofe} Make a signature database from an ascii file containing ${oft} data strings, with one data string per line.  Additional ${oft} information is provided when using this flag
+${ofb}
+${ofs} -t, --test-database ${ofe} Clamscan integrity test a specific database file ${oft} eg: '-t filename.ext' (do not include file path)
+${ofb}
+${ofs} -o, --output-triggered ${ofe} If HAM directory scanning is enabled in the script's ${oft} configuration file, then output names of any third-party ${oft} signatures that triggered during the HAM directory scan
+${ofb}
+${ofs} -w, --whitelist <signature-name> ${ofe} Adds a signature whitelist entry in the newer ClamAV IGN2 ${oft} format to 'my-whitelist.ign2' in order to temporarily resolve ${oft} a false-positive issue with a specific third-party signature. ${oft} Script added whitelist entries will automatically be removed ${oft} if the original signature is either modified or removed from ${oft} the third-party signature database
+${ofb}
+${ofs} --check-clamav ${ofe} If ClamD status check is enabled and the socket path is correctly ${oft} specifiedthen test to see if clamd is running or not
+${ofb}
+${ofs} --upgrade ${ofe} Upgrades this script and master.conf to the latest available version
+${ofb}
+${ofs} --install-all ${ofe} Install and generate the cron, logroate and man files, autodetects the values ${oft} based on your config files
+${ofb}
+${ofs} --install-cron ${ofe} Install and generate the cron file, autodetects the values ${oft} based on your config files
+${ofb}
+${ofs} --install-logrotate ${ofe} Install and generate the logrotate file, autodetects the ${oft} values based on your config files
+${ofb}
+${ofs} --install-man ${ofe} Install and generate the man file, autodetects the ${oft} values based on your config files
+${ofb}
+${ofs} --remove-script ${ofe} Remove the clamav-unofficial-sigs script and all of ${oft} its associated files and databases from the system
+${ofb}
 EOF
 EOF
-  ) #this is very important...
-
-  if [ "$1" ] ; then
+  )" # This is very important
+  if [ "${1}" ] ; then
     echo "${helpcontents//-/\\-}"
   else
     echo -e "$helpcontents"
   fi
 }
     echo "${helpcontents//-/\\-}"
   else
     echo -e "$helpcontents"
   fi
 }
-
 ################################################################################
 # MAIN PROGRAM
 ################################################################################
 
 ################################################################################
 # MAIN PROGRAM
 ################################################################################
 
-#Script Info
-script_version="5.4.1"
-script_version_date="20 July 2016"
-minimum_required_config_version="65"
-minimum_yara_clamav_version="0.99"
+# Script Info
+script_version="7.0.1"
+script_version_date="2020-01-25"
+minimum_required_config_version="91"
+minimum_yara_clamav_version="0.100"
+
+# Discover script: name, full_path and path
+this_script_full_path="${BASH_SOURCE[0]}"
+# follow the symlinks
+while [ -h "$this_script_full_path" ]; do
+  this_script_path="$( cd -P "$( dirname "$this_script_full_path" )" >/dev/null 2>&1 && pwd )"
+  this_script_full_path="$(readlink "$this_script_full_path")"
+       # if relative symlink, then resolve the path
+  if [[ $this_script_full_path != /* ]] ; then
+    this_script_full_path="$this_script_path/$this_script_full_path"
+  fi
+done
+this_script_path="$( cd -P "$( dirname "$this_script_full_path" )" >/dev/null 2>&1 && pwd )"
+this_script_name="$(basename "$this_script_full_path")"
+
+if [ -z "$this_script_full_path" ] || [ -z "$this_script_path" ] || [ -z "$this_script_name" ] ; then
+       echo "ERROR: could not determin script name and fullpath"
+       exit 1
+fi
 
 
-#default config files
-config_dir="/etc/clamav-unofficial-sigs"
-config_files=("$config_dir/master.conf" "$config_dir/os.conf" "$config_dir/user.conf")
+#allow for other negatives besides no.
+#disabled_values_array=("0 no No NO false False FALSE off Off OFF disable Disable DISABLE disabled Disabled DISABLED")
+# if [[ " ${disabled_values_array[@]} " =~ " ${value} " ]]; then
+#     # whatever you want to do when arr contains value
+# fi
+#
+# if [[ ! " ${disabled_values_array[@]} " =~ " ${value} " ]]; then
+#     # whatever you want to do when arr doesn't contain value
+# fi
 
 
-#Initialise 
+# Initialise
 config_version="0"
 do_clamd_reload="0"
 comment_silence="no"
 config_version="0"
 do_clamd_reload="0"
 comment_silence="no"
+force_verbose="no"
 logging_enabled="no"
 force_updates="no"
 logging_enabled="no"
 force_updates="no"
+force_wget="no"
 enable_log="no"
 custom_config="no"
 we_have_a_config="0"
 
 enable_log="no"
 custom_config="no"
 we_have_a_config="0"
 
-## Solaris which function returns garbage when the program is not found
-## only define the new which function if running under Solaris
-if [ "$(uname -s)" = "SunOS" ] ; then
-  which () {
-    # use the switch -p to ignore ksh internal commands
-    ksh whence -p "$@"
-  }
-fi
 
 
-#Default Binaries & Commands
-clamd_reload_opt="clamdscan --reload"
-uname_bin=$(which uname)
-clamscan_bin=$(which clamscan)
-rsync_bin=$(which rsync)
-#detect support for wget
-if [ -x /usr/sfw/bin/wget ] ; then
-  wget_bin="/usr/sfw/bin/wget"
+# Attempt to scan for a valid config dir
+if [ -f "/etc/clamav-unofficial-sigs/master.conf" ] ; then
+  config_dir="/etc/clamav-unofficial-sigs"
+elif [ -f "/usr/local/etc/clamav-unofficial-sigs/master.conf" ] ; then
+  config_dir="/usr/local/etc/clamav-unofficial-sigs/"
+elif [ -f "/opt/zimbra/conf/clamav-unofficial-sigs/master.conf" ] ; then
+  config_dir="/opt/zimbra/conf/clamav-unofficial-sigs/"
+else
+  xshok_pretty_echo_and_log "ERROR: config_dir (/etc/clamav-unofficial-sigs/master.conf) could not be found"
+  exit 1
+fi
+# Default config files
+if [ -r "${config_dir}/master.conf" ] ; then
+       config_files+=( "${config_dir}/master.conf" )
 else
 else
-  wget_bin=$(which wget)
+       xshok_pretty_echo_and_log "ERROR: ${config_dir}/master.conf is not readable"
+       exit 1
 fi
 fi
-if [ "$wget_bin" == "" ] ; then
-  curl_bin=$(which curl)
+if [ -r "${config_dir}/os.conf" ] ; then
+       config_files+=( "${config_dir}/os.conf" )
+else
+       #find the a suitable os.*.conf file
+       os_config_number=$(find "$config_dir" -type f -iname "os.*.conf" | wc -l)
+       if [ "$os_config_number" == "0" ] ; then
+               xshok_pretty_echo_and_log "WARNING: no os.conf or os.*.conf found"
+       elif [ "$os_config_number" == "1" ] ; then
+               config_file="$(find "$config_dir" -type f -iname "os.*.conf" | head -n1)"
+               if [ -r "${config_file}" ]; then
+                       config_files+=( "${config_file}" )
+               else
+                       xshok_pretty_echo_and_log "WARNING: ${config_file} is not readable"
+               fi
+       else
+               xshok_pretty_echo_and_log "WARNING: Too many os.*.conf configs found"
+       fi
+fi
+if [ -r "${config_dir}/user.conf" ] ; then
+       config_files+=( "${config_dir}/user.conf" )
+else
+       xshok_pretty_echo_and_log "WARNING: ${config_dir}/user.conf is not readable"
+fi
+
+# Solaris command -v function returns garbage when the program is not found
+# only define the new command -v function if running under Solaris
+if [ "$(uname -s)" == "SunOS" ] ; then
+  function which() {
+    # Use the switch -p to ignore ksh internal commands
+    ksh whence -p "$@"
+  }
 fi
 fi
-#detect supprot for gnu grep
+
+# Default Binaries & Commands
+uname_bin="$(command -v uname 2> /dev/null)"
+clamscan_bin="$(command -v clamscan 2> /dev/null)"
+rsync_bin="$(command -v rsync 2> /dev/null)"
+
+# Detect supprot for gnu grep
 if [ -x /usr/gnu/bin/grep ] ; then
   grep_bin="/usr/gnu/bin/grep"
 else
 if [ -x /usr/gnu/bin/grep ] ; then
   grep_bin="/usr/gnu/bin/grep"
 else
-  grep_bin=$(which grep)
+  grep_bin="$(command -v grep 2> /dev/null)"
+fi
+# Detect support for tar
+if [ -z "$tar_bin" ]; then
+       tar_bin="$(command -v tar 2> /dev/null)"
+fi
+# Detect support for curl
+if [ -z "$curl_bin" ]; then
+       curl_bin="$(command -v curl 2> /dev/null)"
+fi
+# Detect support for wget
+if [ -z "$wget_bin" ]; then
+       if [ -x /usr/sfw/bin/wget ] ; then
+         wget_bin="/usr/sfw/bin/wget"
+       else
+         wget_bin="$(command -v wget 2> /dev/null)"
+       fi
+fi
+if [ -z "$wget_bin" ] && [ -z "$curl_bin" ]; then
+  curl_bin="$(command -v curl 2> /dev/null)"
+  if [ -z "$curl_bin" ] ; then
+    xshok_pretty_echo_and_log "ERROR: both wget and curl commands are missing, One of them is required"
+    exit 1
+  fi
 fi
 fi
-if [ -x /opt/csw/bin/gpg ] ; then
-  gpg_bin="/opt/csw/bin/gpg"
-else
-  gpg_bin=$(which gpg)
+
+if [ ! -z "$wget_bin" ] ; then
+  # wget compression support
+  if $wget_bin --help | $grep_bin -q "compression=TYPE" ; then
+    wget_compression="--compression=auto"
+  else
+    wget_compression=""
+  fi
 fi
 fi
-if [ "$gpg_bin" == "" ] ; then
-  gpg_bin=$(which gpg2)
+# Detect support for dig or host
+dig_bin="$(command -v dig 2> /dev/null)"
+if [ -z "$dig_bin" ] ; then
+  host_bin="$(command -v host 2> /dev/null)"
+  if [ -z "$host_bin" ] ; then
+    xshok_pretty_echo_and_log "ERROR: both dig and host commands are missing, One of them is required"
+    exit 1
+  fi
 fi
 fi
-
-#Detect if terminal
+# Detect if terminal
 if [ -t 1 ] ; then
 if [ -t 1 ] ; then
-  #Set fonts
-  ##Usage: echo "${BOLD}-a${NORM}"
-  BOLD=$(tput bold)
+  # Set fonts
+  # Usage: echo "${BOLD}-a${NORM}"
+  BOLD="$(tput bold)"
   #REV=$(tput smso)
   #REV=$(tput smso)
-  NORM=$(tput sgr0)
-  #Verbose
+  NORM="$(tput sgr0)"
+  # Verbose
   force_verbose="yes"
 else
   force_verbose="yes"
 else
-  #Null Fonts
-  BOLD=''
-  #REV=''
-  NORM=''
-  #silence
+  # Null fonts
+  BOLD=""
+  #REV=""
+  NORM=""
+  # Silence
   force_verbose="no"
 fi
 
 
 # Generic command line options
 while true ; do
   force_verbose="no"
 fi
 
 
 # Generic command line options
 while true ; do
-  case "$1" in
-    -c | --config ) xshok_check_s2 "$2"; custom_config="$2"; shift 2; break ;;
-    -F | --force ) force_updates="yes"; shift 1; break ;;
-    -v | --verbose ) force_verbose="yes"; shift 1; break ;;
-    -s | --silence ) force_verbose="no"; shift 1; break ;;
-    * ) break ;;
+  case "${1}" in
+    -c|--config) xshok_check_s2 "${2}"; custom_config="${2}"; shift 2; break ;;
+    -F|--force) force_updates="yes"; shift 1; break ;;
+    -v|--verbose) force_verbose="yes"; shift 1; break ;;
+    -s|--silence) force_verbose="no"; shift 1; break ;;
+    *) break ;;
   esac
 done
 
   esac
 done
 
-#Set the verbosity
+# Set the verbosity
 if [ "$force_verbose" == "yes" ] ; then
 if [ "$force_verbose" == "yes" ] ; then
-  #verbose
+  # Verbose
   downloader_silence="no"
   rsync_silence="no"
   gpg_silence="no"
   comment_silence="no"
 else
   downloader_silence="no"
   rsync_silence="no"
   gpg_silence="no"
   comment_silence="no"
 else
-  #silence
+  # Silence
   downloader_silence="yes"
   rsync_silence="yes"
   gpg_silence="yes"
   downloader_silence="yes"
   rsync_silence="yes"
   gpg_silence="yes"
 
 xshok_pretty_echo_and_log "" "#" "80"
 xshok_pretty_echo_and_log " eXtremeSHOK.com ClamAV Unofficial Signature Updater"
 
 xshok_pretty_echo_and_log "" "#" "80"
 xshok_pretty_echo_and_log " eXtremeSHOK.com ClamAV Unofficial Signature Updater"
-xshok_pretty_echo_and_log " Version: v$script_version ($script_version_date)"
-xshok_pretty_echo_and_log " Required Configuration Version: v$minimum_required_config_version"
+xshok_pretty_echo_and_log " Version: v${script_version} (${script_version_date})"
+xshok_pretty_echo_and_log " Required Configuration Version: v${minimum_required_config_version}"
 xshok_pretty_echo_and_log " Copyright (c) Adrian Jon Kriel :: admin@extremeshok.com"
 xshok_pretty_echo_and_log "" "#" "80"
 
 # Generic command line options
 while true ; do
 xshok_pretty_echo_and_log " Copyright (c) Adrian Jon Kriel :: admin@extremeshok.com"
 xshok_pretty_echo_and_log "" "#" "80"
 
 # Generic command line options
 while true ; do
-  case "$1" in
-    -h | --help ) help_and_usage; exit; break ;;
-    -V | --version ) exit; break ;;
-    * ) break ;;
+  case "${1}" in
+    -h|--help) help_and_usage; exit ;;
+    -V|--version) exit ;;
+    *) break ;;
   esac
 done
 
   esac
 done
 
-## CONFIG LOADING AND ERROR CHECKING ##############################################
+# CONFIG LOADING AND ERROR CHECKING ##############################################
 if [ "$custom_config" != "no" ] ; then
   if [ -d "$custom_config" ] ; then
     # Assign the custom config dir and remove trailing / (removes / and //)
 if [ "$custom_config" != "no" ] ; then
   if [ -d "$custom_config" ] ; then
     # Assign the custom config dir and remove trailing / (removes / and //)
-    config_dir=$(echo "$custom_config" | sed 's:/*$::')
-    config_files=("$config_dir/master.conf" "$config_dir/os.conf" "$config_dir/user.conf")
+    shopt -s extglob; config_dir="${custom_config%%+(/)}"
+               config_files=()
+               if [ -r "${config_dir}/master.conf" ] ; then
+                       config_files+=( "${config_dir}/master.conf" )
+               else
+                       xshok_pretty_echo_and_log "WARNING: ${config_dir}/master.conf not found"
+               fi
+               #find the a suitable os.conf or os.*.conf file
+               config_file="$(find "$config_dir" -type f -iname "os.conf" -o -iname "os.*.conf" | tail -n1)"
+               if [ -r "${config_file}" ] ; then
+                       config_files+=( "${config_file}" )
+               else
+                       xshok_pretty_echo_and_log "WARNING: ${config_dir}/os.conf not found"
+               fi
+               if [ -r "${config_dir}/user.conf" ] ; then
+                       config_files+=( "${config_dir}/user.conf" )
+               else
+                       xshok_pretty_echo_and_log "WARNING: ${config_dir}/user.conf not found"
+               fi
   else
   else
-    config_files=("$custom_config")
+    config_files=( "$custom_config" )
   fi
 fi
 
 for config_file in "${config_files[@]}" ; do
   fi
 fi
 
 for config_file in "${config_files[@]}" ; do
-  if [ -r "$config_file" ] ; then #exists and readable
+  if [ -r "$config_file" ] ; then # Exists and readable
     we_have_a_config="1"
     we_have_a_config="1"
-    #config stripping
-    xshok_pretty_echo_and_log "Loading config: $config_file" "="
-
-   
-
-    if [ "$(uname -s)" = "SunOS" ] ; then
-      #Solaris FIXES only, i had issues with running with a single command..
-      clean_config=$(command sed -e '/^#.*/d' "$config_file") # comment line
-      clean_config=$(echo "$clean_config" | sed -e 's/#[[:space:]].*//') # comment line (duplicated)
-      clean_config=$(echo "$clean_config" | sed -e '/^[[:blank:]]*#/d;s/#.*//') #comments at end of line
-      clean_config=$(echo "$clean_config" | sed -e 's/^[ \t]*//;s/[ \t]*$//') #trailing and leading whitespace
-      clean_config=$(echo "$clean_config" | sed -e '/^\s*$/d') #blank lines
-    else 
-      # delete lines beginning with #
-      # delete from ' #' to end of the line
-      # delete from '# ' to end of the line
-      # delete both trailing and leading whitespace
-      # delete all trailing whitespace
-      # delete all empty lines
-      clean_config=$(command sed -e '/^#.*/d' -e 's/[[:space:]]#.*//' -e 's/#[[:space:]].*//' -e 's/^[ \t]*//;s/[ \t]*$//' -e '/^\s*$/d' "$config_file")
+    # Config stripping
+    xshok_pretty_echo_and_log "Loading config: ${config_file}"
+
+    if [ "$(uname -s)" == "SunOS" ] ; then
+      # Solaris FIXES only, i had issues with running with a single command..
+      clean_config="$(command sed -e '/^#.*/d' "$config_file")" # Comment line
+      #clean_config="$(echo "$clean_config" | sed -e 's/#[[:space:]].*//')" # Comment line (duplicated)
+      clean_config=${clean_config//\#*/} # Comment line (duplicated)
+      clean_config="$(echo "$clean_config" | sed -e '/^[[:blank:]]*#/d;s/#.*//')" # Comments at end of line
+      #clean_config="$(echo "$clean_config" | sed -e 's/^[ \t]*//;s/[ \t]*$//')" # trailing and leading whitespace
+      clean_config="$(echo "$clean_config" | xargs)"
+      clean_config="$(echo "$clean_config" | sed -e '/^\s*$/d')" # Blank lines
+
+    elif [ "$(uname -s)" == "Darwin" ] ; then
+      # MacOS / OS X fixes, had issues with running with a single command and with SunOS work around..
+      clean_config="$(command sed -e '/^#.*/d' "$config_file")" # Comment line
+      clean_config="$(echo "$clean_config" | sed -e 's/#[[:space:]].*//')" # Comment line (duplicated)
+      clean_config="$(echo "$clean_config" | sed -e '/^[[:blank:]]*#/d;s/#.*//')" # Comments at end of line
+      #clean_config="$(echo "$clean_config" | sed -e 's/^[ \t]*//;s/[ \t]*$//')" # trailing and leading whitespace
+      #clean_config="$(echo "$clean_config" | xargs)"
+      clean_config="$(echo "$clean_config" | sed -e '/^\s*$/d')" # Blank lines
+
+    else
+      # Delete lines beginning with #
+      # Delete from " #" to end of the line
+      # Delete from "# " to end of the line
+      # Delete both trailing and leading whitespace
+      # Delete all trailing whitespace
+      # Delete all empty lines
+      clean_config="$(command sed -e '/^#.*/d' -e 's/[[:space:]]#.*//' -e 's/#[[:space:]].*//' -e 's/^[ \t]*//;s/[ \t]*$//' -e '/^\s*$/d' "$config_file")"
     fi
     fi
-    
-    ### config error checking
-    # check "" are an even number
+
+    #fix eval of |
+    clean_config="${clean_config//|/\\|}"
+
+    # Config error checking
+    # Check "" are an even number
     config_check="${clean_config//[^\"]}"
     config_check="${clean_config//[^\"]}"
-    if [ $(( ${#config_check} % 2)) -eq 1 ] ; then 
-      xshok_pretty_echo_and_log "ERROR: Your configuration has errors, every \" requires a closing \"" "="     
+    if [ "$(( ${#config_check} % 2 ))" -eq 1 ] ; then
+      xshok_pretty_echo_and_log "ERROR: Your configuration has errors, every \" requires a closing \""
       exit 1
     fi
 
       exit 1
     fi
 
-    # check there is an = for every set of "" #optional whitespace \s* between = and "
-    config_check_vars=$(echo "$clean_config" | $grep_bin -c '=\s*\"' )
+    # Check there is an = for every set of "" optional whitespace \s* between = and "
+    config_check_vars="$(echo "$clean_config" | $grep_bin -c '=\s*\"' )"
 
 
-    if [ $(( ${#config_check} / 2)) -ne "$config_check_vars" ] ; then 
-      xshok_pretty_echo_and_log "ERROR: Your configuration has errors, every = requires a pair of \"\"" "="    
+    if [ $(( ${#config_check} / 2 )) -ne "$config_check_vars" ] ; then
+      xshok_pretty_echo_and_log "ERROR: Your configuration has errors, every = requires a pair of \"\""
       exit 1
     fi
 
       exit 1
     fi
 
-    #config loading
+    # backslash pipe
+    #clean_config="${clean_config//|/\|}"
+
+    # Config loading
     for i in "${clean_config[@]}" ; do
       eval "$(echo "${i}" | command sed -e 's/[[:space:]]*$//' 2> /dev/null)"
     done
     for i in "${clean_config[@]}" ; do
       eval "$(echo "${i}" | command sed -e 's/[[:space:]]*$//' 2> /dev/null)"
     done
@@ -1408,155 +1800,207 @@ for config_file in "${config_files[@]}" ; do
 done
 
 
 done
 
 
-
 # Assign the log_file_path earlier and remove trailing / (removes / and //)
 # Assign the log_file_path earlier and remove trailing / (removes / and //)
-log_file_path=$(echo "$log_file_path" | sed 's:/*$::')
-#Only start logging once all the configs have been loaded
+shopt -s extglob; log_file_path="${log_file_path%%+(/)}"
+# Only start logging once all the configs have been loaded
 if [ "$logging_enabled" == "yes" ] ; then
   enable_log="yes"
 fi
 
 if [ "$logging_enabled" == "yes" ] ; then
   enable_log="yes"
 fi
 
-## Make sure we have a readable config file
+# Make sure we have a readable config file
 if [ "$we_have_a_config" == "0" ] ; then
 if [ "$we_have_a_config" == "0" ] ; then
-  xshok_pretty_echo_and_log "ERROR: Config file/s could NOT be read/loaded" "="
+  xshok_pretty_echo_and_log "ERROR: Config file/s could NOT be read/loaded"
+  xshok_pretty_echo_and_log "Note: Possible fix would be to checkl the config dir ${config_dir} exists and contains config files"
   exit 1
 fi
 
   exit 1
 fi
 
-#prevent some issues with an incomplete or only a user.conf being loaded
-if [ $config_version  == "0" ] ; then
-  xshok_pretty_echo_and_log "ERROR: Config file/s are missing important contents" "="
+# Prevent some issues with an incomplete or only a user.conf being loaded
+if [ "$config_version" == "0" ] ; then
+  xshok_pretty_echo_and_log "ERROR: Config file/s are missing important contents"
   xshok_pretty_echo_and_log "Note: Possible fix would be to point the script to the dir with the configs"
   exit 1
 fi
 
   xshok_pretty_echo_and_log "Note: Possible fix would be to point the script to the dir with the configs"
   exit 1
 fi
 
-#config version validation
-if [ $config_version -lt $minimum_required_config_version ] ; then
-  xshok_pretty_echo_and_log "ERROR: Your config version $config_version is not compatible with the min required version $minimum_required_config_version" "="
+# Config version validation
+if [ "$config_version" -lt "$minimum_required_config_version" ] ; then
+  xshok_pretty_echo_and_log "ERROR: Your config version ${config_version} is not compatible with the min required version ${minimum_required_config_version}"
   exit 1
 fi
 
 # Check to see if the script's "USER CONFIGURATION FILE" has been completed.
 if [ "$user_configuration_complete" != "yes" ] ; then
   exit 1
 fi
 
 # Check to see if the script's "USER CONFIGURATION FILE" has been completed.
 if [ "$user_configuration_complete" != "yes" ] ; then
-  xshok_pretty_echo_and_log "WARNING: SCRIPT CONFIGURATION HAS NOT BEEN COMPLETED" "*"
-  xshok_pretty_echo_and_log "Please review the script configuration files."
+  xshok_pretty_echo_and_log "WARNING: SCRIPT CONFIGURATION HAS NOT BEEN COMPLETED"
+  xshok_pretty_echo_and_log "Please review the script configuration files"
+  xshok_pretty_echo_and_log "and uncomment the following line in user.conf"
+  xshok_pretty_echo_and_log "#user_configuration_complete=\"yes\""
   exit 1
 fi
 
 # Assign the directories and remove trailing / (removes / and //)
   exit 1
 fi
 
 # Assign the directories and remove trailing / (removes / and //)
-work_dir=$(echo "$work_dir" | sed 's:/*$::')
+shopt -s extglob; work_dir="${work_dir%%+(/)}"
 
 
-#Allow overriding of all the individual workdirs, this is mainly to aid package maintainers
-if [ ! -n "$work_dir_sanesecurity" ] ; then
-  work_dir_sanesecurity=$(echo "$work_dir/$sanesecurity_dir" | sed 's:/*$::')
+# Allow overriding of all the individual workdirs, this is mainly to aid package maintainers
+if [ -z "$work_dir_sanesecurity" ] ; then
+  work_dir_sanesecurity="$(echo "${work_dir}/${sanesecurity_dir}" | sed 's:/*$::')"
+else
+  shopt -s extglob; work_dir_sanesecurity="${work_dir_sanesecurity%%+(/)}"
+fi
+if [ -z "$work_dir_securiteinfo" ] ; then
+  work_dir_securiteinfo="$(echo "${work_dir}/${securiteinfo_dir}" | sed 's:/*$::')"
 else
 else
-  work_dir_sanesecurity=$(echo "$work_dir_sanesecurity" | sed 's:/*$::')
+  shopt -s extglob; work_dir_securiteinfo="${work_dir_securiteinfo%%+(/)}"
 fi
 fi
-if [ ! -n "$work_dir_securiteinfo" ] ; then
-  work_dir_securiteinfo=$(echo "$work_dir/$securiteinfo_dir" | sed 's:/*$::')
+if [ -z "$work_dir_linuxmalwaredetect" ] ; then
+  work_dir_linuxmalwaredetect="$(echo "${work_dir}/${linuxmalwaredetect_dir}" | sed 's:/*$::')"
 else
 else
-  work_dir_securiteinfo=$(echo "$work_dir_securiteinfo" | sed 's:/*$::')
+  shopt -s extglob; work_dir_malwarepatrol="${work_dir_malwarepatrol%%+(/)}"
 fi
 fi
-if [ ! -n "$work_dir_linuxmalwaredetect" ] ; then
-  work_dir_linuxmalwaredetect=$(echo "$work_dir/$linuxmalwaredetect_dir" | sed 's:/*$::')
+if [ -z "$work_dir_malwarepatrol" ] ; then
+  work_dir_malwarepatrol="$(echo "${work_dir}/${malwarepatrol_dir}" | sed 's:/*$::')"
 else
 else
-  work_dir_linuxmalwaredetect=$(echo "$work_dir_linuxmalwaredetect" | sed 's:/*$::')
+  shopt -s extglob; work_dir_malwarepatrol="${work_dir_malwarepatrol%%+(/)}"
 fi
 fi
-if [ ! -n "$work_dir_malwarepatrol" ] ; then
-  work_dir_malwarepatrol=$(echo "$work_dir/$malwarepatrol_dir" | sed 's:/*$::')
+if [ -z "$work_dir_urlhaust" ] ; then
+  work_dir_urlhaus="$(echo "${work_dir}/${urlhaus_dir}" | sed 's:/*$::')"
 else
 else
-  work_dir_malwarepatrol=$(echo "$work_dir_malwarepatrol" | sed 's:/*$::')
+  shopt -s extglob; work_dir_urlhaus="${work_dir_urlhaus%%+(/)}"
 fi
 fi
-if [ ! -n "$work_dir_yararulesproject" ] ; then
-  work_dir_yararulesproject=$(echo "$work_dir/$yararulesproject_dir" | sed 's:/*$::')
+if [ -z "$work_dir_yararulesproject" ] ; then
+  work_dir_yararulesproject="$(echo "${work_dir}/${yararulesproject_dir}" | sed 's:/*$::')"
 else
 else
-  work_dir_yararulesproject=$(echo "$work_dir_yararulesproject" | sed 's:/*$::')
+  shopt -s extglob; work_dir_yararulesproject="${work_dir_yararulesproject%%+(/)}"
 fi
 fi
-if [ ! -n "$work_dir_add" ] ; then
-  work_dir_add=$(echo "$work_dir/$add_dir" | sed 's:/*$::')
+if [ -z "$work_dir_add" ] ; then
+  work_dir_add="$(echo "${work_dir}/${add_dir}" | sed 's:/*$::')"
 else
 else
-  work_dir_add=$(echo "$work_dir_add" | sed 's:/*$::')
+  shopt -s extglob; work_dir_add="${work_dir_add%%+(/)}"
 fi
 fi
-if [ ! -n "$work_dir_work_configs" ] ; then
-  work_dir_work_configs=$(echo "$work_dir/$work_dir_configs" | sed 's:/*$::')
+if [ -z "$work_dir_work_configs" ] ; then
+  work_dir_work_configs="$(echo "${work_dir}/${work_dir_configs}" | sed 's:/*$::')"
 else
 else
-  work_dir_work_configs=$(echo "$work_dir_work_configs" | sed 's:/*$::')
+  shopt -s extglob; work_dir_work_configs="${work_dir_work_configs%%+(/)}"
 fi
 fi
-if [ ! -n "$work_dir_gpg" ] ; then
-  work_dir_gpg=$(echo "$work_dir/$gpg_dir" | sed 's:/*$::')
+if [ -z "${work_dir_gpg}" ] ; then
+  work_dir_gpg="$(echo "${work_dir}/${gpg_dir}" | sed 's:/*$::')"
 else
 else
-  work_dir_gpg=$(echo "$work_dir_gpg" | sed 's:/*$::')
+  shopt -s extglob; work_dir_gpg="${work_dir_gpg%%+(/)}"
 fi
 
 fi
 
-if [ ! -n "$work_dir_pid" ] ; then
-  work_dir_pid=$(echo "$work_dir/$pid_dir" | sed 's:/*$::')
+if [ -z "$work_dir_pid" ] ; then
+  work_dir_pid="$(echo "${work_dir}/${pid_dir}" | sed 's:/*$::')"
 else
 else
-  work_dir_pid=$(echo "$work_dir_pid" | sed 's:/*$::')
+  shopt -s extglob; work_dir_pid="${work_dir_pid%%+(/)}"
 fi
 
 # Assign defaults if not defined
 fi
 
 # Assign defaults if not defined
-if [ ! -n "$cron_dir" ] ; then
+if [ -z "$cron_dir" ] ; then
   cron_dir="/etc/cron.d"
 fi
   cron_dir="/etc/cron.d"
 fi
-cron_dir=$(echo "$cron_dir" | sed 's:/*$::')
-if [ ! -n "$cron_filename" ] ; then
+shopt -s extglob; cron_dir="${cron_dir%%+(/)}"
+if [ -z "$cron_filename" ] ; then
   cron_filename="clamav-unofficial-sigs"
 fi
   cron_filename="clamav-unofficial-sigs"
 fi
-if [ ! -n "$logrotate_dir" ] ; then
+if [ -z "$logrotate_dir" ] ; then
   logrotate_dir="/etc/logrotate.d"
 fi
   logrotate_dir="/etc/logrotate.d"
 fi
-logrotate_dir=$(echo "$logrotate_dir" | sed 's:/*$::')
-if [ ! -n "$logrotate_filename" ] ; then
+shopt -s extglob; logrotate_dir="${logrotate_dir%%+(/)}"
+if [ -z "$logrotate_filename" ] ; then
   logrotate_filename="clamav-unofficial-sigs"
   logrotate_filename="clamav-unofficial-sigs"
-fi  
-if [ ! -n "$man_dir" ] ; then
+fi
+if [ -z "$man_dir" ] ; then
   man_dir="/usr/share/man/man8"
 fi
   man_dir="/usr/share/man/man8"
 fi
-man_dir=$(echo "$man_dir" | sed 's:/*$::')
-if [ ! -n "$man_filename" ] ; then
+shopt -s extglob; man_dir="${man_dir%%+(/)}"
+if [ -z "$man_filename" ] ; then
   man_filename="clamav-unofficial-sigs.8"
   man_filename="clamav-unofficial-sigs.8"
-fi  
-if [ ! -n "$man_log_file_full_path" ] ; then
-  man_log_file_full_path="$log_file_path/$log_file_name"
 fi
 fi
+if [ -z "$man_log_file_full_path" ] ; then
+  man_log_file_full_path="${log_file_path}/${log_file_name}"
+fi
+# dont assign , but remove trailing /
+shopt -s extglob; clam_dbs="${clam_dbs%%+(/)}"
 
 
-### SANITY checks
-#Check default Binaries & Commands are defined
-if [ "$clamd_reload_opt" == "" ] ; then
-  xshok_pretty_echo_and_log "ERROR: Missing clamd_reload_opt" "="
-  exit 1
+# Force wget over curl.
+if [ ! -z "$wget_bin" ] && [ "$force_wget" == "yes" ] ; then
+               xshok_pretty_echo_and_log "NOTICE: Forcing wget"
+         curl_bin=""
 fi
 fi
-if [ "$uname_bin" == "" ] ; then
-  xshok_pretty_echo_and_log "ERROR: uname (uname_bin) not found" "="
+
+# SANITY checks
+# Check default Binaries & Commands are defined
+if [ "$reload_dbs" == "yes" ] ; then
+  if [ -z "$clamd_reload_opt" ] ; then
+    xshok_pretty_echo_and_log "ERROR: Missing clamd_reload_opt"
+    exit 1
+  fi
+fi
+if [ -z "$uname_bin" ] ; then
+  xshok_pretty_echo_and_log "ERROR: uname (uname_bin) not found"
   exit 1
 fi
   exit 1
 fi
-if [ "$clamscan_bin" == "" ] ; then
-  xshok_pretty_echo_and_log "ERROR: clamscan binary (clamscan_bin) not found" "="
+if [ -z "$clamscan_bin" ] ; then
+       if [ "${1}" != "--remove-script" ] ; then
+       xshok_pretty_echo_and_log "ERROR: clamscan binary (clamscan_bin) not found"
+       fi
   exit 1
 fi
   exit 1
 fi
-if [ "$rsync_bin" == "" ] ; then
-  xshok_pretty_echo_and_log "ERROR: rsync binary (rsync_bin) not found" "="
+if [ -z "$rsync_bin" ] ; then
+  xshok_pretty_echo_and_log "ERROR: rsync binary (rsync_bin) not found"
   exit 1
 fi
   exit 1
 fi
-if [ "$wget_bin" == "" ] ; then
-  if [ "$curl_bin" == "" ] ; then
-    xshok_pretty_echo_and_log "ERROR: wget and curl binaries not found, script requires either wget or curl" "="
+if [ -z "$curl_bin" ] ; then
+  if [ -z "$wget_bin" ] ; then
+    xshok_pretty_echo_and_log "ERROR: wget and curl binaries not found, script requires either wget or curl"
     exit 1
   fi
 fi
     exit 1
   fi
 fi
-if [ "$gpg_bin" == "" ] ; then
-  xshok_pretty_echo_and_log "ERROR: gpg binary (gpg_bin) not found" "="
+# Check if GPG is enabled and the binary is found
+if [ "$enable_gpg" == "yes" ] ; then
+  if [ -z "$gpg_bin" ] ; then
+    if [ -x /opt/csw/bin/gpg ] ; then
+      gpg_bin="/opt/csw/bin/gpg"
+    else
+      gpg_bin="$(command -v gpg 2> /dev/null)"
+    fi
+    if [ -z "$gpg_bin" ] ; then
+      gpg_bin="$(command -v gpg2 2> /dev/null)"
+    fi
+  fi
+  if [ -z "$gpg_bin" ] ; then
+    enable_gpg="no"
+  fi
+  if [ ! -x "$gpg_bin" ] ; then
+    enable_gpg="no"
+  fi
+fi
+if [ "$enable_gpg" != "yes" ] ; then
+  xshok_pretty_echo_and_log "NOTICE: GnuPG / signature verification disabled"
+fi
+# Check default directories are defined
+if [ -z "$work_dir" ] ; then
+  xshok_pretty_echo_and_log "ERROR: working directory (work_dir) not defined"
   exit 1
 fi
   exit 1
 fi
-#Check default directories are defined
-if [ "$work_dir" == "" ] ; then
-  xshok_pretty_echo_and_log "ERROR: working directory (work_dir) not defined" "="
+if [ -z "$clam_dbs" ] ; then
+  xshok_pretty_echo_and_log "ERROR: clam database directory (clam_dbs) not defined"
+  exit 1
+fi
+# Check default directories are writable
+if [ -e "$work_dir" ] ; then
+  if [ ! -w "$work_dir" ] ; then
+    xshok_pretty_echo_and_log "ERROR: working directory (work_dir) not writable ${work_dir}"
+    exit 1
+  fi
+fi
+if [ ! -w "$clam_dbs" ] ; then
+  xshok_pretty_echo_and_log "ERROR: clam database directory (clam_dbs) not writable ${clam_dbs}"
   exit 1
 fi
 
 # Reset the update timers to force a full update.
 if [ "$force_updates" == "yes" ] ; then
   exit 1
 fi
 
 # Reset the update timers to force a full update.
 if [ "$force_updates" == "yes" ] ; then
-  xshok_pretty_echo_and_log "Force Updates: enabled" 
-  sanesecurity_update_hours="0"    
+  xshok_pretty_echo_and_log "NOTICE: forcing updates"
+  sanesecurity_update_hours="0"
   securiteinfo_update_hours="0"
   linuxmalwaredetect_update_hours="0"
   malwarepatrol_update_hours="0"
   securiteinfo_update_hours="0"
   linuxmalwaredetect_update_hours="0"
   malwarepatrol_update_hours="0"
@@ -1570,55 +2014,86 @@ if [ "$enable_locking" == "yes" ] ; then
   xshok_mkdir_ownership "$work_dir_pid"
   pid_file_fullpath="$work_dir_pid/clamav-unofficial-sigs.pid"
   if [ -f "$pid_file_fullpath" ] ; then
   xshok_mkdir_ownership "$work_dir_pid"
   pid_file_fullpath="$work_dir_pid/clamav-unofficial-sigs.pid"
   if [ -f "$pid_file_fullpath" ] ; then
-    pid_file_pid=$(cat "$pid_file_fullpath")
-    ps -p "$pid_file_pid" > /dev/null 2>&1
-    if [ $? -eq 0 ] ; then 
-      xshok_pretty_echo_and_log "ERROR: Only one instance can run at the same time." "="
+    pid_file_pid="$(cat "$pid_file_fullpath")"
+    if ps -p "$pid_file_pid" > /dev/null 2>&1 ; then
+      xshok_pretty_echo_and_log "ERROR: Only one instance can run at the same time."
       exit 1
     else
       xshok_create_pid_file "$pid_file_fullpath"
     fi
   else
       exit 1
     else
       xshok_create_pid_file "$pid_file_fullpath"
     fi
   else
-      xshok_create_pid_file "$pid_file_fullpath"
+    xshok_create_pid_file "$pid_file_fullpath"
   fi
   fi
-  # run this wehen the script exits
+  # Run this wehen the script exits
   trap -- "rm -f $pid_file_fullpath" EXIT
 fi
 
 # Verify the clam_user and clam_group actually exists on the system
   trap -- "rm -f $pid_file_fullpath" EXIT
 fi
 
 # Verify the clam_user and clam_group actually exists on the system
-if ! xshok_user_group_exists "$clam_user" "$clam_group" ; then
-  xshok_pretty_echo_and_log "ERROR: Either the user: $clam_user and/or group: $clam_group does not exist on the system." "="
+if ! xshok_user_group_exists "${clam_user}" "${clam_group}" ; then
+  xshok_pretty_echo_and_log "ERROR: Either the user: ${clam_user} and/or group: ${clam_group} does not exist on the system."
   exit 1
 fi
 
   exit 1
 fi
 
-# Silence rsync output and only report errors - useful if script is run via cron.
-if [ "$rsync_silence" = "yes" ] ; then
-  rsync_output_level="--quiet"
-else
-  rsync_output_level="--progress"
+# If the local rsync client supports the "--no-motd" flag, then enable it.
+if $rsync_bin --help | $grep_bin -q "no-motd" > /dev/null ; then
+  no_motd="--no-motd"
 fi
 
 fi
 
-# If the local rsync client supports the '--no-motd' flag, then enable it.
-if $rsync_bin --help | $grep_bin 'no-motd' > /dev/null ; then
-  no_motd="--no-motd"
+# If the local rsync client supports the "--contimeout" flag, then enable it.
+if $rsync_bin --help | $grep_bin -q "contimeout" > /dev/null ; then
+  connect_timeout="--contimeout=${rsync_connect_timeout}"
 fi
 
 fi
 
-# If the local rsync client supports the '--contimeout' flag, then enable it.
-if $rsync_bin --help | $grep_bin 'contimeout' > /dev/null ; then
-  connect_timeout="--contimeout=$rsync_connect_timeout"
+if [ "$debug" == "yes" ] ; then
+        downloader_debug="yes"
+        clamscan_debug="yes"
+        curl_debug="yes"
+        wget_debug="yes"
+        rsync_debug="yes"
+fi
+# Show clamscan errors
+if [ "$clamscan_debug" == "yes" ] ; then
+       exec 10>&2
+else
+       exec 10>/dev/null
+fi
+# Show curl errors
+if [ "$curl_debug" == "yes" ] ; then
+       exec 11>&2
+else
+       exec 11>/dev/null
+fi
+# Show wget errors
+if [ "$wget_debug" == "yes" ] ; then
+       exec 12>&2
+else
+       exec 12>/dev/null
+fi
+# Show rsync errors
+if [ "$rsync_debug" == "yes" ] ; then
+       exec 13>&2
+else
+       exec 13>/dev/null
 fi
 
 # Silence wget output and only report errors - useful if script is run via cron.
 fi
 
 # Silence wget output and only report errors - useful if script is run via cron.
-if [ "$downloader_silence" = "yes" ] ; then
-  wget_output_level="--quiet" #--quiet
+if [ "$downloader_silence" == "yes" ] && [ "$downloader_debug" != "yes" ]  ; then
+  wget_output_level="--quiet"
   curl_output_level="--silent --show-error"
 else
   wget_output_level="--no-verbose"
   curl_output_level=""
 fi
 
   curl_output_level="--silent --show-error"
 else
   wget_output_level="--no-verbose"
   curl_output_level=""
 fi
 
-#suppress ssl warnings
-if [ "$downloader_ignore_ssl" = "yes" ] ; then
+# Silence rsync output and only report errors - useful if script is run via cron.
+if [ "$rsync_silence" == "yes" ] && [ "$rsync_debug" != "yes" ] ; then
+  rsync_output_level="--quiet"
+else
+  rsync_output_level="--progress"
+fi
+
+# Suppress ssl warnings
+if [ "$downloader_ignore_ssl" == "yes" ] ; then
   wget_insecure="--no-check-certificate"
   curl_insecure="--insecure"
 else
   wget_insecure="--no-check-certificate"
   curl_insecure="--insecure"
 else
@@ -1626,46 +2101,41 @@ else
   curl_insecure=""
 fi
 
   curl_insecure=""
 fi
 
-# This scripts name and path
-this_script_name="$(basename "$0")"
-this_script_path="$( cd "$(dirname "$0")" ; pwd -P )"
-this_script_full_path="$this_script_path/$this_script_name"
-
-#set the script to 755 permissions
+# Set the script to 755 permissions
 if xshok_is_root ; then
   if [ "$setmode" == "yes" ] ; then
 if xshok_is_root ; then
   if [ "$setmode" == "yes" ] ; then
-    if [ ! -x "$this_script_path/$this_script_name" ] ; then
-      chmod 755 "$this_script_path/$this_script_name"
-      xshok_pretty_echo_and_log "Fixing permission on $this_script_path/$this_script_name" "="
+    if [ ! -x "${this_script_path}/${this_script_name}" ] ; then
+      chmod 755 "${this_script_path}/${this_script_name}"
+      xshok_pretty_echo_and_log "Fixing permission on ${this_script_path}/${this_script_name}" "="
     fi
   fi
 else
     fi
   fi
 else
-  #disable setmode
+  # Disable setmode
   setmode="no"
 fi
   setmode="no"
 fi
-
 ################################################################################
 # MAIN LOGIC
 ################################################################################
 
 while true; do
 ################################################################################
 # MAIN LOGIC
 ################################################################################
 
 while true; do
-  case "$1" in
-    -d | --decode-sig ) decode_third_party_signature_by_signature_name; exit; break ;;
-    -e | --encode-string ) hexadecimal_encode_entire_input_string; exit; break ;;
-    -f | --encode-formatted ) hexadecimal_encode_formatted_input_string; exit; break ;;
-    -g | --gpg-verify ) xshok_check_s2 "$2"; gpg_verify_specific_sanesecurity_database_file "$2"; exit; break ;;
-    -i | --information ) output_system_configuration_information; exit; break ;;
-    -m | --make-database ) make_signature_database_from_ascii_file; exit; break ;;
-    -t | --test-database ) xshok_check_s2 "$2"; clamscan_integrity_test_specific_database_file "$2"; exit; break ;;
-    -o | --output-triggered ) output_signatures_triggered_during_ham_directory_scan; exit; break ;;
-    -w | --whitelist ) add_signature_whitelist_entry; exit; break ;;
-    --check-clamav ) check_clamav; exit; break ;;
-    --install-all ) install_cron; install_logrotate; install_man; exit; break ;;
-    --install-cron ) install_cron; exit; break ;;
-    --install-logrotate ) install_logrotate; exit; break ;;
-    --install-man ) install_man; exit; break ;;
-    --remove-script ) remove_script; exit; break ;;
-    * ) break ;;
+  case "${1}" in
+    -d|--decode-sig) decode_third_party_signature_by_signature_name; exit ;;
+    -e|--encode-string) hexadecimal_encode_entire_input_string; exit ;;
+    -f|--encode-formatted) hexadecimal_encode_formatted_input_string; exit ;;
+    -g|--gpg-verify) xshok_check_s2 "${2}"; gpg_verify_specific_sanesecurity_database_file "${2}"; exit ;;
+    -i|--information) output_system_configuration_information; exit ;;
+    -m|--make-database) make_signature_database_from_ascii_file; exit ;;
+    -t|--test-database) xshok_check_s2 "${2}"; clamscan_integrity_test_specific_database_file "${2}"; exit ;;
+    -o|--output-triggered) output_signatures_triggered_during_ham_directory_scan; exit ;;
+    -w|--whitelist) add_signature_whitelist_entry "${2}"; exit ;;
+    --check-clamav) check_clamav; exit ;;
+    --upgrade) xshok_upgrade; exit ;;
+    --install-all) install_cron; install_logrotate; install_man; exit ;;
+    --install-cron) install_cron; exit ;;
+    --install-logrotate) install_logrotate; exit ;;
+    --install-man) install_man; exit ;;
+    --remove-script) remove_script; exit ;;
+    *) break ;;
   esac
 done
 
   esac
 done
 
@@ -1673,13 +2143,13 @@ xshok_pretty_echo_and_log "Preparing Databases" "="
 
 # Check yararule support is available
 if [ "$enable_yararules" == "yes" ] ; then
 
 # Check yararule support is available
 if [ "$enable_yararules" == "yes" ] ; then
-  current_clamav_version=$($clamscan_bin -V | cut -d " " -f2 | cut -d "/" -f1 | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }')
-  minimum_yara_clamav_version=$(echo "$minimum_yara_clamav_version" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }')
-  #Check current clamav version against the minimum required version for yara support
-  if [ "$current_clamav_version" -lt "$minimum_yara_clamav_version" ] ; then #older
+  current_clamav_version="$($clamscan_bin -V | cut -d " " -f 2 | cut -d "/" -f 1 | awk -F "." '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }')"
+  minimum_yara_clamav_version="$(echo "$minimum_yara_clamav_version" | awk -F "." '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }')"
+  # Check current clamav version against the minimum required version for yara support
+  if [ "$current_clamav_version" -lt "$minimum_yara_clamav_version" ] ; then # Older
     yararulesproject_enabled="no"
     enable_yararules="no"
     yararulesproject_enabled="no"
     enable_yararules="no"
-    xshok_pretty_echo_and_log "Notice: Yararules Disabled due to clamav being older than the minimum required version"
+    xshok_pretty_echo_and_log "Yararules Disabled due to clamav being older than the minimum required version"
   fi
 else
   yararulesproject_enabled="no"
   fi
 else
   yararulesproject_enabled="no"
@@ -1690,41 +2160,68 @@ fi
 if [ "$sanesecurity_enabled" == "yes" ] ; then
   if [ -n "$sanesecurity_dbs" ] ; then
     if [ -n "$sanesecurity_dbs_rating" ] ; then
 if [ "$sanesecurity_enabled" == "yes" ] ; then
   if [ -n "$sanesecurity_dbs" ] ; then
     if [ -n "$sanesecurity_dbs_rating" ] ; then
-      sanesecurity_dbs="$(xshok_database "$sanesecurity_dbs" "$sanesecurity_dbs_rating")"
+      temp_db="$(xshok_database "$sanesecurity_dbs_rating" "${sanesecurity_dbs[@]}")"
     else
     else
-      sanesecurity_dbs="$(xshok_database "$sanesecurity_dbs" "$default_dbs_rating")"
+      temp_db="$(xshok_database "$default_dbs_rating" "${sanesecurity_dbs[@]}")"
     fi
     fi
+    sanesecurity_dbs=( )
+    #sanesecurity_dbs=( $temp_db )
+    read -r -a sanesecurity_dbs <<< "$temp_db"
   fi
 fi
 if [ "$securiteinfo_enabled" == "yes" ] ; then
   if [ -n "$securiteinfo_dbs" ] ; then
     if [ -n "$securiteinfo_dbs_rating" ] ; then
   fi
 fi
 if [ "$securiteinfo_enabled" == "yes" ] ; then
   if [ -n "$securiteinfo_dbs" ] ; then
     if [ -n "$securiteinfo_dbs_rating" ] ; then
-      securiteinfo_dbs="$(xshok_database "$securiteinfo_dbs" "$securiteinfo_dbs_rating")"
+      temp_db="$(xshok_database "$securiteinfo_dbs_rating" "${securiteinfo_dbs[@]}")"
     else
     else
-      securiteinfo_dbs="$(xshok_database "$securiteinfo_dbs" "$default_dbs_rating")"
+      temp_db="$(xshok_database "$default_dbs_rating" "${securiteinfo_dbs[@]}")"
     fi
     fi
+    securiteinfo_dbs=( )
+    #securiteinfo_dbs=( $temp_db )
+    read -r -a securiteinfo_dbs <<< "$temp_db"
   fi
 fi
 if [ "$linuxmalwaredetect_enabled" == "yes" ] ; then
   if [ -n "$linuxmalwaredetect_dbs" ] ; then
     if [ -n "$linuxmalwaredetect_dbs_rating" ] ; then
   fi
 fi
 if [ "$linuxmalwaredetect_enabled" == "yes" ] ; then
   if [ -n "$linuxmalwaredetect_dbs" ] ; then
     if [ -n "$linuxmalwaredetect_dbs_rating" ] ; then
-      linuxmalwaredetect_dbs="$(xshok_database "$linuxmalwaredetect_dbs" "$linuxmalwaredetect_dbs_rating")"
+      temp_db="$(xshok_database "$linuxmalwaredetect_dbs_rating" "${linuxmalwaredetect_dbs[@]}")"
     else
     else
-      linuxmalwaredetect_dbs="$(xshok_database "$linuxmalwaredetect_dbs" "$default_dbs_rating")"
+      temp_db="$(xshok_database "$default_dbs_rating" "${linuxmalwaredetect_dbs[@]}")"
     fi
     fi
+    linuxmalwaredetect_dbs=( )
+    #linuxmalwaredetect_dbs=( $temp_db )
+    read -r -a linuxmalwaredetect_dbs <<< "$temp_db"
   fi
 fi
 if [ "$yararulesproject_enabled" == "yes" ] ; then
   if [ -n "$yararulesproject_dbs" ] ; then
     if [ -n "$yararulesproject_dbs_rating" ] ; then
   fi
 fi
 if [ "$yararulesproject_enabled" == "yes" ] ; then
   if [ -n "$yararulesproject_dbs" ] ; then
     if [ -n "$yararulesproject_dbs_rating" ] ; then
-      yararulesproject_dbs="$(xshok_database "$yararulesproject_dbs" "$yararulesproject_dbs_rating")"
+      temp_db="$(xshok_database "$yararulesproject_dbs_rating" "${yararulesproject_dbs[@]}")"
     else
     else
-      yararulesproject_dbs="$(xshok_database "$yararulesproject_dbs" "$default_dbs_rating")"
+      temp_db="$(xshok_database "$default_dbs_rating" "${yararulesproject_dbs[@]}")"
     fi
     fi
+    yararulesproject_dbs=( )
+    #yararulesproject_dbs=( $temp_db )
+    read -r -a yararulesproject_dbs <<< "$temp_db"
+  fi
+fi
+if [ "$urlhaus_enabled" == "yes" ] ; then
+  if [ -n "$urlhaus_dbs" ] ; then
+    if [ -n "$urlhaus_dbs_rating" ] ; then
+      temp_db="$(xshok_database "$urlhaus_dbs_rating" "${urlhaus_dbs[@]}")"
+    else
+      temp_db="$(xshok_database "$default_dbs_rating" "${urlhaus_dbs[@]}")"
+    fi
+    urlhaus_dbs=( )
+    #urlhaus_dbs=( $temp_db )
+    read -r -a urlhaus_dbs <<< "$temp_db"
   fi
 fi
   fi
 fi
-
 # Set the variables for MalwarePatrol
 # Set the variables for MalwarePatrol
+if [ "$malwarepatrol_product_code" != "8" ] ; then
+       # assumption, free product code is always 8 (non-free product code is never 8)
+       malwarepatrol_free="no"
+fi
 if [ "$malwarepatrol_free" == "yes" ] ; then
   malwarepatrol_product_code="8"
   malwarepatrol_list="clamav_basic"
 if [ "$malwarepatrol_free" == "yes" ] ; then
   malwarepatrol_product_code="8"
   malwarepatrol_list="clamav_basic"
@@ -1737,44 +2234,47 @@ else
     malwarepatrol_product_code=8
   fi
 fi
     malwarepatrol_product_code=8
   fi
 fi
+
 if [ $malwarepatrol_list == "clamav_basic" ] ; then
   malwarepatrol_db="malwarepatrol.db"
 else
   malwarepatrol_db="malwarepatrol.ndb"
 fi
 if [ $malwarepatrol_list == "clamav_basic" ] ; then
   malwarepatrol_db="malwarepatrol.db"
 else
   malwarepatrol_db="malwarepatrol.ndb"
 fi
-malwarepatrol_url="$malwarepatrol_url?product=$malwarepatrol_product_code&list=$malwarepatrol_list"
+malwarepatrol_url="${malwarepatrol_url}?receipt=${malwarepatrol_receipt_code}&product=${malwarepatrol_product_code}&list=${malwarepatrol_list}"
 
 # If "ham_dir" variable is set, then create initial whitelist files (skipped if first-time script run).
 test_dir="$work_dir/test"
 if [ -n "$ham_dir" ] && [ -d "$work_dir" ] && [ ! -d "$test_dir" ] ; then
   if [ -d "$ham_dir" ] ; then
     xshok_mkdir_ownership "$test_dir"
 
 # If "ham_dir" variable is set, then create initial whitelist files (skipped if first-time script run).
 test_dir="$work_dir/test"
 if [ -n "$ham_dir" ] && [ -d "$work_dir" ] && [ ! -d "$test_dir" ] ; then
   if [ -d "$ham_dir" ] ; then
     xshok_mkdir_ownership "$test_dir"
-    cp -f "$work_dir"/*/*.ndb "$test_dir"
-    $clamscan_bin --infected --no-summary -d "$test_dir" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' >> "$work_dir_work_configs/whitelist.txt"
-    $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir"/* | cut -d "*" -f2 | sort | uniq > "$work_dir_work_configs/whitelist.hex"
+    cp -f -p "$work_dir"/*/*.ndb "$test_dir"
+    cp -f -p "$work_dir"/*/*.db "$test_dir"
+    $clamscan_bin --infected --no-summary -d "$test_dir" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' >> "${work_dir_work_configs}/whitelist.txt"
+    $grep_bin -h -f "${work_dir_work_configs}/whitelist.txt" "${test_dir}/*.ndb" | cut -d "*" -f 2 | sort | uniq > "${work_dir_work_configs}/whitelist.hex"
+    $grep_bin -h -f "${work_dir_work_configs}/whitelist.txt" "${test_dir}/*.db" | cut -d "=" -f 2 | awk '{ printf("=%s\n", $1);}' | sort | uniq >> "${work_dir_work_configs}/whitelist.hex"
     cd "$test_dir" || exit
     for db_file in * ; do
     cd "$test_dir" || exit
     for db_file in * ; do
-      [[ -e $db_file ]] || break # handle the case of no files
-      $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$db_file" > "$db_file-tmp"
+      [[ -e ${db_file} ]] || break # Handle the case of no files
+      $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "$db_file" > "$db_file-tmp"
       mv -f "$db_file-tmp" "$db_file"
       mv -f "$db_file-tmp" "$db_file"
-      if $clamscan_bin --quiet -d "$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
+      if $clamscan_bin --quiet -d "$db_file" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
         if $rsync_bin -pcqt "$db_file" "$clam_dbs" ; then
         if $rsync_bin -pcqt "$db_file" "$clam_dbs" ; then
-          perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
+          perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
           if [ "$selinux_fixes" == "yes" ] ; then
           if [ "$selinux_fixes" == "yes" ] ; then
-            restorecon "$clam_dbs/$db_file"
+            restorecon "${clam_dbs}/${db_file}"
           fi
           do_clamd_reload=1
         fi
       fi
     done
           fi
           do_clamd_reload=1
         fi
       fi
     done
-    if [ -r "$work_dir_work_configs/whitelist.hex" ] ; then
-      xshok_pretty_echo_and_log "Initial HAM directory scan whitelist file created in $work_dir_work_configs"
+    if [ -r "${work_dir_work_configs}/whitelist.hex" ] ; then
+      xshok_pretty_echo_and_log "Initial HAM directory scan whitelist file created in ${work_dir_work_configs}"
     else
       xshok_pretty_echo_and_log "No false-positives detected in initial HAM directory scan"
     fi
   else
     else
       xshok_pretty_echo_and_log "No false-positives detected in initial HAM directory scan"
     fi
   else
-    xshok_pretty_echo_and_log "WARNING: Cannot locate HAM directory: $ham_dir"
-    xshok_pretty_echo_and_log "Skipping initial whitelist file creation.  Fix 'ham_dir' path in config file"
+    xshok_pretty_echo_and_log "WARNING: Cannot locate HAM directory: ${ham_dir}"
+    xshok_pretty_echo_and_log "Skipping initial whitelist file creation. Fix 'ham_dir' path in config file"
   fi
 fi
 
   fi
 fi
 
@@ -1786,60 +2286,54 @@ xshok_mkdir_ownership "$work_dir_linuxmalwaredetect"
 xshok_mkdir_ownership "$work_dir_sanesecurity"
 xshok_mkdir_ownership "$work_dir_yararulesproject"
 xshok_mkdir_ownership "$work_dir_work_configs"
 xshok_mkdir_ownership "$work_dir_sanesecurity"
 xshok_mkdir_ownership "$work_dir_yararulesproject"
 xshok_mkdir_ownership "$work_dir_work_configs"
-xshok_mkdir_ownership "$work_dir_gpg"
+xshok_mkdir_ownership "${work_dir_gpg}"
 xshok_mkdir_ownership "$work_dir_add"
 
 # Set secured access permissions to the GPG directory
 xshok_mkdir_ownership "$work_dir_add"
 
 # Set secured access permissions to the GPG directory
-perms chmod -f 0700 "$work_dir_gpg"
+perms chmod -f 0700 "${work_dir_gpg}"
 
 
-# If we haven't done so yet, download Sanesecurity public GPG key and import to custom keyring.
-if [ ! -s "$work_dir_gpg/publickey.gpg" ] ; then
-  if [ "$wget_bin" != "" ] ; then
-    #echo $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_gpg/publickey.gpg" "$sanesecurity_gpg_url"
-    $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_gpg/publickey.gpg" "$sanesecurity_gpg_url"
-    ret="$?"
-  else
-    #echo $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_gpg/publickey.gpg" "$sanesecurity_gpg_url"
-    $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_gpg/publickey.gpg" "$sanesecurity_gpg_url"
+if [ "$enable_gpg" == "yes" ] ; then
+  # If we haven't done so yet, download Sanesecurity public GPG key and import to custom keyring.
+  if [ ! -s "${work_dir_gpg}/publickey.gpg" ] ; then
+    xshok_file_download "${work_dir_gpg}/publickey.gpg" "$sanesecurity_gpg_url"
     ret="$?"
     ret="$?"
-  fi    
-  if [ "$ret" != "0" ] ; then
-    xshok_pretty_echo_and_log "ALERT: Could not download Sanesecurity public GPG key" "*"
-    exit 1
-  else
-    xshok_pretty_echo_and_log "Sanesecurity public GPG key successfully downloaded"
-    rm -f -- "$work_dir_gpg/ss-keyring.gp*"
-    if ! $gpg_bin -q --no-options --no-default-keyring --homedir "$work_dir_gpg" --keyring "$work_dir_gpg/ss-keyring.gpg" --import "$work_dir_gpg/publickey.gpg" 2>/dev/null ; then
-      xshok_pretty_echo_and_log "ALERT: could not import Sanesecurity public GPG key to custom keyring" "*"
+    if [ "$ret" -ne 0 ] ; then
+      xshok_pretty_echo_and_log "ALERT: Could not download Sanesecurity public GPG key"
       exit 1
     else
       exit 1
     else
-      chmod -f 0644 "$work_dir_gpg/*.*"
-      xshok_pretty_echo_and_log "Sanesecurity public GPG key successfully imported to custom keyring"
+      xshok_pretty_echo_and_log "Sanesecurity public GPG key successfully downloaded"
+      rm -f -- "${work_dir_gpg}/ss-keyring.gp*"
+      if ! $gpg_bin -q --no-options --no-default-keyring --homedir "${work_dir_gpg}" --keyring "${work_dir_gpg}/ss-keyring.gpg" --import "${work_dir_gpg}/publickey.gpg" 2>/dev/null ; then
+        xshok_pretty_echo_and_log "ALERT: could not import Sanesecurity public GPG key to custom keyring"
+        exit 1
+      else
+        chmod -f 0644 "${work_dir_gpg}/*.*"
+        xshok_pretty_echo_and_log "Sanesecurity public GPG key successfully imported to custom keyring"
+      fi
     fi
   fi
     fi
   fi
-fi
-
-# If custom keyring is missing, try to re-import Sanesecurity public GPG key.
-if [ ! -s "$work_dir_gpg/ss-keyring.gpg" ] ; then
-  rm -f -- "$work_dir_gpg/ss-keyring.gp*"
-  if ! $gpg_bin -q --no-options --no-default-keyring --homedir "$work_dir_gpg" --keyring "$work_dir_gpg/ss-keyring.gpg" --import "$work_dir_gpg/publickey.gpg" 2>/dev/null ; then
-    xshok_pretty_echo_and_log "ALERT: Custom keyring MISSING or CORRUPT!  Could not import Sanesecurity public GPG key to custom keyring" "*"
-    exit 1
-  else
-    chmod -f 0644 "$work_dir_gpg/*.*"
-    xshok_pretty_echo_and_log "Sanesecurity custom keyring MISSING!  GPG key successfully re-imported to custom keyring"
+  # If custom keyring is missing, try to re-import Sanesecurity public GPG key.
+  if [ ! -s "${work_dir_gpg}/ss-keyring.gpg" ] ; then
+    rm -f -- "${work_dir_gpg}/ss-keyring.gp*"
+    if ! $gpg_bin -q --no-options --no-default-keyring --homedir "${work_dir_gpg}" --keyring "${work_dir_gpg}/ss-keyring.gpg" --import "${work_dir_gpg}/publickey.gpg" 2>/dev/null ; then
+      xshok_pretty_echo_and_log "ALERT: Custom keyring MISSING or CORRUPT!  Could not import Sanesecurity public GPG key to custom keyring"
+      exit 1
+    else
+      chmod -f 0644 "${work_dir_gpg}/*.*"
+      xshok_pretty_echo_and_log "Sanesecurity custom keyring MISSING!  GPG key successfully re-imported to custom keyring"
+    fi
   fi
 fi
 
 # Database update check, time randomization section.  This script now
 # provides support for both bash and non-bash enabled system shells.
   fi
 fi
 
 # Database update check, time randomization section.  This script now
 # provides support for both bash and non-bash enabled system shells.
-if [ "$enable_random" = "yes" ] ; then
+if [ "$enable_random" == "yes" ] ; then
   if [ -n "$RANDOM" ] ; then
   if [ -n "$RANDOM" ] ; then
-    sleep_time=$((RANDOM * $((max_sleep_time - min_sleep_time)) / 32767 + min_sleep_time))
+    sleep_time="$((RANDOM * $((max_sleep_time - min_sleep_time)) / 32767 + min_sleep_time))"
   else
   else
-    sleep_time=0
+    sleep_time="0"
     while [ "$sleep_time" -lt "$min_sleep_time" ] || [ "$sleep_time" -gt "$max_sleep_time" ] ; do
     while [ "$sleep_time" -lt "$min_sleep_time" ] || [ "$sleep_time" -gt "$max_sleep_time" ] ; do
-      sleep_time=$(head -1 /dev/urandom | cksum | awk '{print $2}')
+      sleep_time="$(head -n 1 /dev/urandom | cksum | awk '{print $2}')"
     done
   fi
   if [ ! -t 0 ] ; then
     done
   fi
   if [ ! -t 0 ] ; then
@@ -1850,8 +2344,12 @@ if [ "$enable_random" = "yes" ] ; then
 fi
 
 # Create "scan-test.txt" file for clamscan database integrity testing.
 fi
 
 # Create "scan-test.txt" file for clamscan database integrity testing.
-if [ ! -s "$work_dir_work_configs/scan-test.txt" ] ; then
-  echo "This is the clamscan test file..." > "$work_dir_work_configs/scan-test.txt"
+if [ ! -s "${work_dir_work_configs}/scan-test.txt" ] ; then
+  echo "This is the clamscan test file..." > "${work_dir_work_configs}/scan-test.txt"
+fi
+
+if [ -z "$git_branch" ] ; then
+       git_branch="master"
 fi
 
 # If rsync proxy is defined in the config file, then export it for use.
 fi
 
 # If rsync proxy is defined in the config file, then export it for use.
 
 # Create $current_dbsfiles containing lists of current and previously active 3rd-party databases
 # so that databases and/or backup files that are no longer being used can be removed.
 
 # Create $current_dbsfiles containing lists of current and previously active 3rd-party databases
 # so that databases and/or backup files that are no longer being used can be removed.
-current_tmp="$work_dir_work_configs/current-dbs.tmp"
-current_dbs="$work_dir_work_configs/current-dbs.txt"
+current_tmp="${work_dir_work_configs}/current-dbs.tmp"
+
+current_dbs_file="${work_dir_work_configs}/current-dbs.txt"
 
 if [ "$sanesecurity_enabled" == "yes" ] ; then
 
 if [ "$sanesecurity_enabled" == "yes" ] ; then
-  # Create the Sanesecurity rsync "include" file (defines which files to download).
-  sanesecurity_include_dbs="$work_dir_work_configs/ss-include-dbs.txt"
-  if [ -n "$sanesecurity_dbs" ] ; then
-    rm -f -- "$sanesecurity_include_dbs" "$work_dir_sanesecurity/*.sha256"
-    for db in $sanesecurity_dbs ; do
-      echo "$db" >> "$sanesecurity_include_dbs"
-      echo "$db.sig" >> "$sanesecurity_include_dbs"
-      
-      echo "$work_dir_sanesecurity/$db" >> "$current_tmp"
-      echo "$work_dir_sanesecurity/$db.sig" >> "$current_tmp"
+  # Create the Sanesecurity rsync "include" file (defines command -v files to download).
+  sanesecurity_include_dbs="${work_dir_work_configs}/ss-include-dbs.txt"
+  if [ -n "${sanesecurity_dbs[0]}" ] ; then
+    rm -f -- "${sanesecurity_include_dbs}" "${work_dir_sanesecurity}/*.sha256"
+    for db_file in "${sanesecurity_dbs[@]}" ; do
+      echo "$db_file" >> "${sanesecurity_include_dbs}"
+      echo "${db_file}.sig" >> "${sanesecurity_include_dbs}"
+      echo "${work_dir_sanesecurity}/${db_file}" >> "${current_tmp}"
+      echo "${work_dir_sanesecurity}/${db_file}.sig" >> "${current_tmp}"
       clamav_files
     done
   fi
 fi
 if [ "$securiteinfo_enabled" == "yes" ] ; then
       clamav_files
     done
   fi
 fi
 if [ "$securiteinfo_enabled" == "yes" ] ; then
-  if [ -n "$securiteinfo_dbs" ] ; then
-    for db in $securiteinfo_dbs ; do
-      echo "$work_dir_securiteinfo/$db" >> "$current_tmp"
+  if [ -n "${securiteinfo_dbs[0]}" ] ; then
+    for db in "${securiteinfo_dbs[@]}" ; do
+      echo "${work_dir_securiteinfo}/${db}" >> "${current_tmp}"
       clamav_files
     done
   fi
 fi
 if [ "$linuxmalwaredetect_enabled" == "yes" ] ; then
       clamav_files
     done
   fi
 fi
 if [ "$linuxmalwaredetect_enabled" == "yes" ] ; then
-  if [ -n "$linuxmalwaredetect_dbs" ] ; then
-    for db in $linuxmalwaredetect_dbs ; do
-      echo "$work_dir_linuxmalwaredetect/$db" >> "$current_tmp"
+  if [ -n "${linuxmalwaredetect_dbs[0]}" ] ; then
+    for db in "${linuxmalwaredetect_dbs[@]}" ; do
+      echo "${work_dir_linuxmalwaredetect}/${db}" >> "${current_tmp}"
       clamav_files
     done
   fi
 fi
 if [ "$malwarepatrol_enabled" == "yes" ] ; then
   if [ -n "$malwarepatrol_db" ] ; then
       clamav_files
     done
   fi
 fi
 if [ "$malwarepatrol_enabled" == "yes" ] ; then
   if [ -n "$malwarepatrol_db" ] ; then
-    echo "$work_dir_malwarepatrol/$malwarepatrol_db" >> "$current_tmp"
+    echo "${work_dir_malwarepatrol}/${malwarepatrol_db}" >> "${current_tmp}"
     clamav_files
   fi
 fi
 if [ "$yararulesproject_enabled" == "yes" ] ; then
     clamav_files
   fi
 fi
 if [ "$yararulesproject_enabled" == "yes" ] ; then
-  if [ -n "$yararulesproject_dbs" ] ; then
-    for db in $yararulesproject_dbs ; do
-      if echo "$db" | $grep_bin -q "/"; then
-        db=$(echo "$db" | cut -d"/" -f2)
+  if [ -n "${yararulesproject_dbs[0]}" ] ; then
+    for db in "${yararulesproject_dbs[@]}" ; do
+      if echo "$db" | $grep_bin -q "/" ; then
+        db="$(echo "$db" | cut -d "/" -f 2)"
       fi
       fi
-      echo "$work_dir_yararulesproject/$db" >> "$current_tmp"
+      echo "${work_dir_yararulesproject}/${db}" >> "${current_tmp}"
       clamav_files
     done
   fi
 fi
 if [ "$additional_enabled" == "yes" ] ; then
   if [ -n "$additional_dbs" ] ; then
       clamav_files
     done
   fi
 fi
 if [ "$additional_enabled" == "yes" ] ; then
   if [ -n "$additional_dbs" ] ; then
-    for db in $additional_dbs ; do
-      echo "$work_dir_add/$db" >> "$current_tmp"
+    for db in "${additional_dbs[@]}" ; do
+      echo "${work_dir_add}/${db}" >> "${current_tmp}"
       clamav_files
     done
   fi
 fi
       clamav_files
     done
   fi
 fi
-sort "$current_tmp" > "$current_dbs" 2>/dev/null
-rm -f "$current_tmp"
+sort "${current_tmp}" > "$current_dbs_file" 2>/dev/null
+rm -f "${current_tmp}"
 
 # Remove 3rd-party databases and/or backup files that are no longer being used.
 if [ "$remove_disabled_databases" == "yes" ] ; then
 
 # Remove 3rd-party databases and/or backup files that are no longer being used.
 if [ "$remove_disabled_databases" == "yes" ] ; then
-  previous_dbs="$work_dir_work_configs/previous-dbs.txt"
-  sort "$current_dbs" > "$previous_dbs" 2>/dev/null
-  #do not remove the current_dbs
-  #rm -f "$current_dbs"
+  previous_dbs="${work_dir_work_configs}/previous-dbs.txt"
+  sort "$current_dbs_file" > "$previous_dbs" 2>/dev/null
+  # Do not remove the current_dbs_file
+  #rm -f "$current_dbs_file"
 
 
-  db_changes="$work_dir_work_configs/db-changes.txt"
+  db_changes="${work_dir_work_configs}/db-changes.txt"
   if [ ! -s "$previous_dbs" ] ; then
   if [ ! -s "$previous_dbs" ] ; then
-    cp -f "$current_dbs" "$previous_dbs" 2>/dev/null
+    cp -f -p "$current_dbs_file" "$previous_dbs" 2>/dev/null
   fi
   fi
-  diff "$current_dbs" "$previous_dbs" 2>/dev/null | $grep_bin '>' | awk '{print $2}' > "$db_changes"
+  diff "$current_dbs_file" "$previous_dbs" 2>/dev/null | $grep_bin ">" | awk '{print $2}' > "$db_changes"
   if [ -r "$db_changes" ] ; then
     if $grep_bin -vq "bak" "$db_changes" 2>/dev/null ; then
   if [ -r "$db_changes" ] ; then
     if $grep_bin -vq "bak" "$db_changes" 2>/dev/null ; then
-      do_clamd_reload=2
+      do_clamd_reload="2"
     fi
     while read -r file ; do
       rm -f -- "$file"
     fi
     while read -r file ; do
       rm -f -- "$file"
-      xshok_pretty_echo_and_log "Unused/Disabled file removed: $file"
+      xshok_pretty_echo_and_log "Unused/Disabled file removed: ${file}"
     done < "$db_changes"
   fi
 fi
 
 # Create "purge.txt" file for package maintainers to support package uninstall.
     done < "$db_changes"
   fi
 fi
 
 # Create "purge.txt" file for package maintainers to support package uninstall.
-purge="$work_dir_work_configs/purge.txt"
-cp -f "$current_dbs" "$purge"
-{ 
-echo "$work_dir_work_configs/current-dbs.txt"
-echo "$work_dir_work_configs/db-changes.txt"
-echo "$work_dir_work_configs/last-mbl-update.txt"
-echo "$work_dir_work_configs/last-si-update.txt"
-echo "$work_dir_work_configs/local.ign"
-echo "$work_dir_work_configs/monitor-ign.txt"
-echo "$work_dir_work_configs/my-whitelist.ign2"
-echo "$work_dir_work_configs/tracker.txt"
-echo "$work_dir_work_configs/previous-dbs.txt"
-echo "$work_dir_work_configs/scan-test.txt"
-echo "$work_dir_work_configs/ss-include-dbs.txt"
-echo "$work_dir_work_configs/whitelist.hex"
-echo "$work_dir_gpg/publickey.gpg"
-echo "$work_dir_gpg/secring.gpg"
-echo "$work_dir_gpg/ss-keyring.gpg*"
-echo "$work_dir_gpg/trustdb.gpg"
-echo "$log_file_path/$log_file_name*"
-echo "$work_dir_work_configs/purge.txt" 
+purge="${work_dir_work_configs}/purge.txt"
+cp -f -p "$current_dbs_file" "$purge"
+{
+  echo "${work_dir_work_configs}/current-dbs.txt"
+  echo "${work_dir_work_configs}/db-changes.txt"
+  echo "${work_dir_work_configs}/last-mbl-update.txt"
+  echo "${work_dir_work_configs}/last-si-update.txt"
+  echo "${work_dir_work_configs}/local.ign"
+  echo "${work_dir_work_configs}/monitor-ign.txt"
+  echo "${work_dir_work_configs}/my-whitelist.ign2"
+  echo "${work_dir_work_configs}/tracker.txt"
+  echo "${work_dir_work_configs}/previous-dbs.txt"
+  echo "${work_dir_work_configs}/scan-test.txt"
+  echo "${work_dir_work_configs}/ss-include-dbs.txt"
+  echo "${work_dir_work_configs}/whitelist.hex"
+  echo "${work_dir_gpg}/publickey.gpg"
+  echo "$work_dir_gpg/secring.gpg"
+  echo "${work_dir_gpg}/ss-keyring.gpg*"
+  echo "$work_dir_gpg/trustdb.gpg"
+  echo "${log_file_path}/${log_file_name}*"
+  echo "${work_dir_work_configs}/purge.txt"
 } >> "$purge"
 
 # Check and save current system time since epoch for time related database downloads.
 # However, if unsuccessful, issue a warning that we cannot calculate times since epoch.
 } >> "$purge"
 
 # Check and save current system time since epoch for time related database downloads.
 # However, if unsuccessful, issue a warning that we cannot calculate times since epoch.
-if [ -n "$securiteinfo_dbs" ] || [ -n "$malwarepatrol_db" ] ; then
-  current_time=$(date "+%s" 2> /dev/null)
+if [ -n "${securiteinfo_dbs[0]}" ] || [ -n "$malwarepatrol_db" ] ; then
+  current_time="$(date "+%s" 2> /dev/null)"
   current_time="${current_time//[^0-9]/}"
   current_time="$((current_time + 0))"
   if [ "$current_time" -le 0 ] ; then
   current_time="${current_time//[^0-9]/}"
   current_time="$((current_time + 0))"
   if [ "$current_time" -le 0 ] ; then
-    current_time=$(perl -le print+time 2> /dev/null)
+    current_time="$(perl -le print+time 2> /dev/null)"
   fi
   if [ "$current_time" -le 0 ] ; then
   fi
   if [ "$current_time" -le 0 ] ; then
-    xshok_pretty_echo_and_log "WARNING: No support for 'date +%s' or 'perl' was not found , SecuriteInfo and MalwarePatrol updates bypassed" "="
-    securiteinfo_dbs=""
-    malwarepatrol_db=""
+    xshok_pretty_echo_and_log "WARNING: No support for 'date +%s' or 'perl' was not found , SecuriteInfo and MalwarePatrol updates bypassed"
+    securiteinfo_dbs=()
+    malwarepatrol_db=()
   fi
 fi
   fi
 fi
-
 ################################################################
 # Check for Sanesecurity database & GPG signature file updates #
 ################################################################
 if [ "$sanesecurity_enabled" == "yes" ] ; then
 ################################################################
 # Check for Sanesecurity database & GPG signature file updates #
 ################################################################
 if [ "$sanesecurity_enabled" == "yes" ] ; then
-  if [ -n "$sanesecurity_dbs" ] ; then
-  ##if [ ${#sanesecurity_dbs[@]} -lt "1" ] ; then ##will not work due to compound array assignment
-    if [ "$(xshok_array_count "$sanesecurity_dbs")" -lt "1" ] ; then
+  if [ -n "${sanesecurity_dbs[0]}" ] ; then
+    if [ ${#sanesecurity_dbs} -lt 1 ] ; then
       xshok_pretty_echo_and_log "Failed sanesecurity_dbs config is invalid or not defined - SKIPPING"
     else
       xshok_pretty_echo_and_log "Failed sanesecurity_dbs config is invalid or not defined - SKIPPING"
     else
-      if [ -r "$work_dir_work_configs/last-ss-update.txt" ] ; then
-        last_sanesecurity_update=$(cat "$work_dir_work_configs/last-ss-update.txt")
+      if [ -r "${work_dir_work_configs}/last-ss-update.txt" ] ; then
+        last_sanesecurity_update="$(cat "${work_dir_work_configs}/last-ss-update.txt")"
       else
         last_sanesecurity_update="0"
       fi
       db_file=""
       else
         last_sanesecurity_update="0"
       fi
       db_file=""
-      update_interval=$((sanesecurity_update_hours * 3600))
-      time_interval=$((current_time - last_sanesecurity_update))
+      update_interval="$((sanesecurity_update_hours * 3600))"
+      time_interval="$((current_time - last_sanesecurity_update))"
       if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
       if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
-        echo "$current_time" > "$work_dir_work_configs/last-ss-update.txt"
+        echo "$current_time" > "${work_dir_work_configs}/last-ss-update.txt"
         xshok_pretty_echo_and_log "Sanesecurity Database & GPG Signature File Updates" "="
         xshok_pretty_echo_and_log "Checking for Sanesecurity updates..."
         xshok_pretty_echo_and_log "Sanesecurity Database & GPG Signature File Updates" "="
         xshok_pretty_echo_and_log "Checking for Sanesecurity updates..."
-
-        sanesecurity_mirror_ips=$(dig +ignore +short "$sanesecurity_url")
-        #add fallback to host if dig returns no records
-        if [ "$(xshok_array_count  "$sanesecurity_mirror_ips")" -lt 1 ] ; then
-          sanesecurity_mirror_ips=$(host -t A "$sanesecurity_url" | sed -n '/has address/{s/.*address \([^ ]*\).*/\1/;p;}')
+                               # shellcheck disable=SC2086
+        sanesecurity_mirror_ips="$(dig $dig_proxy +ignore +short "$sanesecurity_url")"
+        # Add fallback to host if dig returns no records
+        if [ ${#sanesecurity_mirror_ips} -lt 1 ] ; then
+                                       # shellcheck disable=SC2086
+          sanesecurity_mirror_ips="$(host $host_proxy -t A "$sanesecurity_url" | sed -n '/has address/{s/.*address \([^ ]*\).*/\1/;p;}')"
         fi
 
         fi
 
-        if [ "$(xshok_array_count  "$sanesecurity_mirror_ips")" -ge "1" ] ; then
+        if [ ${#sanesecurity_mirror_ips} -ge 1 ] ; then
           for sanesecurity_mirror_ip in $sanesecurity_mirror_ips ; do
             sanesecurity_mirror_name=""
           for sanesecurity_mirror_ip in $sanesecurity_mirror_ips ; do
             sanesecurity_mirror_name=""
-            sanesecurity_mirror_name=$(dig +short -x "$sanesecurity_mirror_ip" | command sed 's/\.$//')
-            #add fallback to host if dig returns no records
-            if [ "$sanesecurity_mirror_name" == "" ] ; then
-              sanesecurity_mirror_name=$(host "$sanesecurity_mirror_ip" | sed -n '/name pointer/{s/.*pointer \([^ ]*\).*\.$/\1/;p;}')
+                                               # shellcheck disable=SC2086
+            sanesecurity_mirror_name="$(dig $dig_proxy +short -x "$sanesecurity_mirror_ip" | command sed 's/\.$//')"
+            # Add fallback to host if dig returns no records
+            if [ -z "$sanesecurity_mirror_name" ] ; then
+                                                       # shellcheck disable=SC2086
+              sanesecurity_mirror_name="$(host $host_proxy "$sanesecurity_mirror_ip" | sed -n '/name pointer/{s/.*pointer \([^ ]*\).*\.$/\1/;p;}')"
             fi
             sanesecurity_mirror_site_info="$sanesecurity_mirror_name $sanesecurity_mirror_ip"
             fi
             sanesecurity_mirror_site_info="$sanesecurity_mirror_name $sanesecurity_mirror_ip"
-            xshok_pretty_echo_and_log "Sanesecurity mirror site used: $sanesecurity_mirror_site_info"
-            $rsync_bin $rsync_output_level $no_motd --files-from="$sanesecurity_include_dbs" -ctuz $connect_timeout --timeout="$rsync_max_time" "rsync://$sanesecurity_mirror_ip/sanesecurity" "$work_dir_sanesecurity" 2>/dev/null
-            if [ "$?" -eq "0" ] ; then #the correct way
+            xshok_pretty_echo_and_log "Sanesecurity mirror site used: ${sanesecurity_mirror_site_info}"
+            # shellcheck disable=SC2086
+            $rsync_bin $rsync_output_level $no_motd --files-from="${sanesecurity_include_dbs}" -ctuz $connect_timeout --timeout="$rsync_max_time" "rsync://${sanesecurity_mirror_ip}/sanesecurity" "$work_dir_sanesecurity" 2>&13
+            ret="$?"
+            if [ "$ret" -eq 0 ] || [ "$ret" -eq 23 ] ; then # The correct way, 23 is some files were not transfered, can be ignored and we can assume a success
               sanesecurity_rsync_success="1"
               sanesecurity_rsync_success="1"
-              for db_file in $sanesecurity_dbs ; do
-                if ! cmp -s "$work_dir_sanesecurity/$db_file" "$clam_dbs/$db_file" ; then
-                  xshok_pretty_echo_and_log "Testing updated Sanesecurity database file: $db_file"
-                  if ! $gpg_bin --trust-model always -q --no-default-keyring --homedir "$work_dir_gpg" --keyring "$work_dir_gpg/ss-keyring.gpg" --verify "$work_dir_sanesecurity/$db_file.sig" "$work_dir_sanesecurity/$db_file" 2>/dev/null ; then
-                    $gpg_bin --always-trust -q --no-default-keyring --homedir "$work_dir_gpg" --keyring "$work_dir_gpg/ss-keyring.gpg" --verify "$work_dir_sanesecurity/$db_file.sig" "$work_dir_sanesecurity/$db_file" 2>/dev/null
-                    ret="$?"
-                  else
-                    ret="0"  
-                  fi
-                  if [ "$ret" -eq "0" ] ; then
-                    test "$gpg_silence" = "no" && xshok_pretty_echo_and_log "Sanesecurity GPG Signature tested good on $db_file database"
-                    true
-                  else
-                    xshok_pretty_echo_and_log "Sanesecurity GPG Signature test FAILED on $db_file database - SKIPPING" 
-                    false
-                  fi
-                if [ "$?" -eq "0" ] ; then
-                  db_ext=$(echo "$db_file" | cut -d "." -f2)
-                  if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
-                    if $clamscan_bin --quiet -d "$work_dir_sanesecurity/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
-                      xshok_pretty_echo_and_log "Clamscan reports Sanesecurity $db_file database integrity tested good"
-                      true
-                    else
-                      xshok_pretty_echo_and_log "Clamscan reports Sanesecurity $db_file database integrity tested BAD"
-                      if [ "$remove_bad_database" == "yes" ] ; then
-                        if rm -f "$work_dir_sanesecurity/$db_file" ; then
-                          xshok_pretty_echo_and_log "Removed invalid database: $work_dir_sanesecurity/$db_file"
-                        fi
-                      fi
-                      false
-                    fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$work_dir_sanesecurity/$db_file" "$clam_dbs" 2>/dev/null ; then
-                      perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
-                      if [ "$selinux_fixes" == "yes" ] ; then
-                        restorecon "$clam_dbs/$db_file"
-                      fi
-                      xshok_pretty_echo_and_log "Successfully updated Sanesecurity production database file: $db_file"
-                      sanesecurity_update=1
-                      do_clamd_reload=1
+              for db_file in "${sanesecurity_dbs[@]}" ; do
+                if ! cmp -s "${work_dir_sanesecurity}/${db_file}" "${clam_dbs}/${db_file}" ; then
+                  xshok_pretty_echo_and_log "Testing updated Sanesecurity database file: ${db_file}"
+
+                  if [ "$enable_gpg" == "yes" ] ; then
+                    if ! $gpg_bin --trust-model always -q --no-default-keyring --homedir "${work_dir_gpg}" --keyring "${work_dir_gpg}/ss-keyring.gpg" --verify "${work_dir_sanesecurity}/${db_file}.sig" "${work_dir_sanesecurity}/${db_file}" 2>/dev/null ; then
+                      $gpg_bin --always-trust -q --no-default-keyring --homedir "${work_dir_gpg}" --keyring "${work_dir_gpg}/ss-keyring.gpg" --verify "${work_dir_sanesecurity}/${db_file}.sig" "${work_dir_sanesecurity}/${db_file}" 2>/dev/null
+                      ret="$?"
                     else
                     else
-                      xshok_pretty_echo_and_log "Failed to successfully update Sanesecurity production database file: $db_file - SKIPPING"
-                      false
+                      ret="0"
                     fi
                     fi
-                  else
-                    $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$work_dir_sanesecurity/$db_file" > "$test_dir/$db_file"
-                    $clamscan_bin --infected --no-summary -d "$test_dir/$db_file" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "$work_dir_work_configs/whitelist.txt"
-                    $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir/$db_file" | cut -d "*" -f2 | sort | uniq >> "$work_dir_work_configs/whitelist.hex"
-                    $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$test_dir/$db_file" > "$test_dir/$db_file-tmp"
-                    mv -f "$test_dir/$db_file-tmp" "$test_dir/$db_file"
-                    if $clamscan_bin --quiet -d "$test_dir/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
-                      xshok_pretty_echo_and_log "Clamscan reports Sanesecurity $db_file database integrity tested good"
-                      true
+                    if [ "$ret" -eq 0 ] ; then
+                      test "$gpg_silence" = "no" && xshok_pretty_echo_and_log "Sanesecurity GPG Signature tested good on ${db_file} database"
                     else
                     else
-                      xshok_pretty_echo_and_log "Clamscan reports Sanesecurity $db_file database integrity tested BAD"
-                      ##DO NOT KILL THIS DB
-                      false
-                    fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$test_dir/$db_file" "$clam_dbs" 2>/dev/null ; then
-                      perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
-                      if [ "$selinux_fixes" == "yes" ] ; then
-                        restorecon "$clam_dbs/$db_file"
+                      xshok_pretty_echo_and_log "Sanesecurity GPG Signature test FAILED on ${db_file} database - SKIPPING"
+                    fi
+                  fi
+                  if [ "$ret" -eq 0 ] ; then
+                    db_ext="${db_file#*.}"
+                    if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
+                      if $clamscan_bin --quiet -d "${work_dir_sanesecurity}/${db_file}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                        xshok_pretty_echo_and_log "Clamscan reports Sanesecurity ${db_file} database integrity tested good"
+                        true
+                      else
+                        xshok_pretty_echo_and_log "Clamscan reports Sanesecurity ${db_file} database integrity tested BAD"
+                        if [ "$remove_bad_database" == "yes" ] ; then
+                          if rm -f "${work_dir_sanesecurity}/${db_file}" ; then
+                            xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_sanesecurity}/${db_file}"
+                          fi
+                        fi
+                        false
+                        fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${db_file}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${work_dir_sanesecurity}/${db_file}" "$clam_dbs" 2>&13 ; then
+                        perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
+                        if [ "$selinux_fixes" == "yes" ] ; then
+                          restorecon "${clam_dbs}/${db_file}"
+                        fi
+
+                        xshok_pretty_echo_and_log "Successfully updated Sanesecurity production database file: ${db_file}"
+                        sanesecurity_update=1
+                        do_clamd_reload=1
+                      else
+                        xshok_pretty_echo_and_log "Failed to successfully update Sanesecurity production database file: ${db_file} - SKIPPING"
+                        false
                       fi
                       fi
-                      xshok_pretty_echo_and_log "Successfully updated Sanesecurity production database file: $db_file"
-                      sanesecurity_update=1
-                      do_clamd_reload=1
                     else
                     else
-                      xshok_pretty_echo_and_log "Failed to successfully update Sanesecurity production database file: $db_file - SKIPPING"
+                      $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${work_dir_sanesecurity}/${db_file}" > "${test_dir}/${db_file}"
+                      $clamscan_bin --infected --no-summary -d "${test_dir}/${db_file}" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "${work_dir_work_configs}/whitelist.txt"
+                      $grep_bin -h -f "${work_dir_work_configs}/whitelist.hex" "${test_dir}/${db_file}" | cut -d "*" -f 2 | sort | uniq >> "${work_dir_work_configs}/whitelist.hex-tmp"
+                      mv -f "${work_dir_work_configs}/whitelist.hex-tmp" "${work_dir_work_configs}/whitelist.hex"
+                      $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${test_dir}/${db_file}" > "${test_dir}/${db_file}-tmp"
+                      mv -f "${test_dir}/${db_file}-tmp" "${test_dir}/${db_file}"
+                      if $clamscan_bin --quiet -d "${test_dir}/${db_file}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                        xshok_pretty_echo_and_log "Clamscan reports Sanesecurity ${db_file} database integrity tested good"
+                        true
+                      else
+                        xshok_pretty_echo_and_log "Clamscan reports Sanesecurity ${db_file} database integrity tested BAD"
+                        # DO NOT KILL THIS DB
+                        false
+                        fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${db_file}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${test_dir}/${db_file}" "$clam_dbs" 2>&13 ; then
+                        perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
+                        if [ "$selinux_fixes" == "yes" ] ; then
+                          restorecon "${clam_dbs}/${db_file}"
+                        fi
+                        xshok_pretty_echo_and_log "Successfully updated Sanesecurity production database file: ${db_file}"
+                        sanesecurity_update=1
+                        do_clamd_reload=1
+                      else
+                        xshok_pretty_echo_and_log "Failed to successfully update Sanesecurity production database file: ${db_file} - SKIPPING"
+                      fi
                     fi
                   fi
                 fi
                     fi
                   fi
                 fi
-              fi
               done
               done
-              if [ "$sanesecurity_update" != "1" ] ; then
+              if [ ! "$sanesecurity_update" == "1" ] ; then
                 xshok_pretty_echo_and_log "No Sanesecurity database file updates found" "-"
                 break
               else
                 break
               fi
             else
                 xshok_pretty_echo_and_log "No Sanesecurity database file updates found" "-"
                 break
               else
                 break
               fi
             else
-              xshok_pretty_echo_and_log "Connection to $sanesecurity_mirror_site_info failed - Trying next mirror site..."
+              xshok_pretty_echo_and_log "Connection to ${sanesecurity_mirror_site_info} failed - Trying next mirror site..."
             fi
           done
             fi
           done
-          if [ "$sanesecurity_rsync_success" != "1" ] ; then
+          if [ ! "$sanesecurity_rsync_success" == "1" ] ; then
             xshok_pretty_echo_and_log "Access to all Sanesecurity mirror sites failed - Check for connectivity issues"
             xshok_pretty_echo_and_log "or signature database name(s) misspelled in the script's configuration file."
           fi
             xshok_pretty_echo_and_log "Access to all Sanesecurity mirror sites failed - Check for connectivity issues"
             xshok_pretty_echo_and_log "or signature database name(s) misspelled in the script's configuration file."
           fi
@@ -2117,27 +2621,26 @@ if [ "$sanesecurity_enabled" == "yes" ] ; then
         fi
       else
         xshok_pretty_echo_and_log "Sanesecurity Database File Updates" "="
         fi
       else
         xshok_pretty_echo_and_log "Sanesecurity Database File Updates" "="
-
-        time_remaining=$((update_interval - time_interval))
-        hours_left=$((time_remaining / 3600))
-        minutes_left=$((time_remaining % 3600 / 60))
-        xshok_pretty_echo_and_log "$sanesecurity_update_hours hours have not yet elapsed since the last sanesecurity update check"
-        xshok_pretty_echo_and_log "No update check was performed at this time" "-"
-        xshok_pretty_echo_and_log "Next check will be performed in approximately $hours_left hour(s), $minutes_left minute(s)"
+        xshok_draw_time_remaining "$((update_interval - time_interval))" "$sanesecurity_update_hours" "Sanesecurity"
       fi
     fi
   fi
 else
       fi
     fi
   fi
 else
-  if [ -n "$sanesecurity_dbs" ] ; then
+  if [ -n "${sanesecurity_dbs[0]}" ] ; then
     if [ "$remove_disabled_databases" == "yes" ] ; then
       xshok_pretty_echo_and_log "Removing disabled Sanesecurity Database files"
     if [ "$remove_disabled_databases" == "yes" ] ; then
       xshok_pretty_echo_and_log "Removing disabled Sanesecurity Database files"
-      for db_file in $sanesecurity_dbs ; do
-        if [ -r "$work_dir_sanesecurity/$db_file" ] ; then
-          rm -f "$work_dir_sanesecurity/$db_file"*
+      for db_file in "${sanesecurity_dbs[@]}" ; do
+        if echo "$db_file" | $grep_bin -q "|" ; then
+          db_file="${db_file%|*}"
+        fi
+        if [ -r "${work_dir_sanesecurity}/${db_file}" ] ; then
+          xshok_pretty_echo_and_log "Removing ${work_dir_sanesecurity}/${db_file}"
+          rm -f "${work_dir_sanesecurity}/${db_file}"
           do_clamd_reload=1
         fi
           do_clamd_reload=1
         fi
-        if [ -r "$clam_dbs/$db_file" ] ; then
-          rm -f "$clam_dbs/$db_file"
+        if [ -r "${clam_dbs}/${db_file}" ] ; then
+          xshok_pretty_echo_and_log "Removing ${clam_dbs}/${db_file}"
+          rm -f "${clam_dbs}/${db_file}"
           do_clamd_reload=1
         fi
       done
           do_clamd_reload=1
         fi
       done
@@ -2146,144 +2649,132 @@ else
 fi
 
 ##############################################################################################################################################
 fi
 
 ##############################################################################################################################################
-# Check for updated SecuriteInfo database files every set number of  hours as defined in the "USER CONFIGURATION" section of this script #
+# Check for updated SecuriteInfo database files every set number of hours as defined in the "USER CONFIGURATION" section of this script      #
 ##############################################################################################################################################
 if [ "$securiteinfo_enabled" == "yes" ] ; then
   if [ "$securiteinfo_authorisation_signature" != "YOUR-SIGNATURE-NUMBER" ] ; then
 ##############################################################################################################################################
 if [ "$securiteinfo_enabled" == "yes" ] ; then
   if [ "$securiteinfo_authorisation_signature" != "YOUR-SIGNATURE-NUMBER" ] ; then
-    if [ -n "$securiteinfo_dbs" ] ; then
-      if [ "$(xshok_array_count "$securiteinfo_dbs")" -lt "1" ] ; then
+    if [ -n "${securiteinfo_dbs[0]}" ] ; then
+      if [ ${#securiteinfo_dbs} -lt 1 ] ; then
         xshok_pretty_echo_and_log "Failed securiteinfo_dbs config is invalid or not defined - SKIPPING"
       else
         xshok_pretty_echo_and_log "Failed securiteinfo_dbs config is invalid or not defined - SKIPPING"
       else
-      rm -f "$work_dir_securiteinfo/*.gz"
-      if [ -r "$work_dir_work_configs/last-si-update.txt" ] ; then
-        last_securiteinfo_update=$(cat "$work_dir_work_configs/last-si-update.txt")
-      else
-        last_securiteinfo_update="0"
-      fi
-      db_file=""
-      loop=""
-      update_interval=$((securiteinfo_update_hours * 3600))
-      time_interval=$((current_time - last_securiteinfo_update))
-      if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
-        echo "$current_time" > "$work_dir_work_configs/last-si-update.txt"
-        xshok_pretty_echo_and_log "SecuriteInfo Database File Updates" "="
-        xshok_pretty_echo_and_log "Checking for SecuriteInfo updates..."
-        securiteinfo_updates="0" 
-        for db_file in $securiteinfo_dbs ; do
-          if [ "$loop" = "1" ] ; then
-            xshok_pretty_echo_and_log "---"      
-          fi
-          xshok_pretty_echo_and_log "Checking for updated SecuriteInfo database file: $db_file"
-          securiteinfo_db_update="0"
-          if [ "$wget_bin" != "" ] ; then
-            $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_securiteinfo/$db_file" "$securiteinfo_url/$securiteinfo_authorisation_signature/$db_file"
-            ret="$?"
-          else
-            $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_securiteinfo/$db_file" "$securiteinfo_url/$securiteinfo_authorisation_signature/$db_file"
+        rm -f "${work_dir_securiteinfo}/*.gz"
+        if [ -r "${work_dir_work_configs}/last-si-update.txt" ] ; then
+          last_securiteinfo_update="$(cat "${work_dir_work_configs}/last-si-update.txt")"
+        else
+          last_securiteinfo_update="0"
+        fi
+        db_file=""
+        loop=""
+        update_interval="$((securiteinfo_update_hours * 3600))"
+        time_interval="$((current_time - last_securiteinfo_update))"
+        if [ "$time_interval" -ge "$((update_interval - 600))" ] ; then
+          echo "$current_time" > "${work_dir_work_configs}/last-si-update.txt"
+          xshok_pretty_echo_and_log "SecuriteInfo Database File Updates" "="
+          xshok_pretty_echo_and_log "Checking for SecuriteInfo updates..."
+          securiteinfo_updates="0"
+          for db_file in "${securiteinfo_dbs[@]}" ; do
+            if [ "$loop" == "1" ] ; then
+              xshok_pretty_echo_and_log "---"
+            fi
+            xshok_pretty_echo_and_log "Checking for updated SecuriteInfo database file: ${db_file}"
+            securiteinfo_db_update="0"
+            xshok_file_download "${work_dir_securiteinfo}/${db_file}" "${securiteinfo_url}/${securiteinfo_authorisation_signature}/${db_file}"
             ret="$?"
             ret="$?"
-          fi
-          if [ "$ret" -eq "0" ] ; then
-            loop="1"
-            if ! cmp -s "$work_dir_securiteinfo/$db_file" "$clam_dbs/$db_file" ; then
-              if [ "$?" -eq "0" ] ; then
-                db_ext=$(echo "$db_file" | cut -d "." -f2)
-
-
-                xshok_pretty_echo_and_log "Testing updated SecuriteInfo database file: $db_file"
-                if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ]
-                  then
-                  if $clamscan_bin --quiet -d "$work_dir_securiteinfo/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null
-                    then
-                    xshok_pretty_echo_and_log "Clamscan reports SecuriteInfo $db_file database integrity tested good"
+            if [ "$ret" -eq 0 ] ; then
+              loop="1"
+              if ! cmp -s "${work_dir_securiteinfo}/${db_file}" "${clam_dbs}/${db_file}" ; then
+                db_ext="${db_file#*.}"
+
+                xshok_pretty_echo_and_log "Testing updated SecuriteInfo database file: ${db_file}"
+                if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
+                  if $clamscan_bin --quiet -d "${work_dir_securiteinfo}/${db_file}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                    xshok_pretty_echo_and_log "Clamscan reports SecuriteInfo ${db_file} database integrity tested good"
                     true
                   else
                     true
                   else
-                    xshok_pretty_echo_and_log "Clamscan reports SecuriteInfo $db_file database integrity tested BAD"
+                    xshok_pretty_echo_and_log "Clamscan reports SecuriteInfo ${db_file} database integrity tested BAD"
                     if [ "$remove_bad_database" == "yes" ] ; then
                     if [ "$remove_bad_database" == "yes" ] ; then
-                      if rm -f "$work_dir_securiteinfo/$db_file" ; then
-                        xshok_pretty_echo_and_log "Removed invalid database: $work_dir_securiteinfo/$db_file"
+                      if rm -f "${work_dir_securiteinfo}/${db_file}" ; then
+                        xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_securiteinfo}/${db_file}"
                       fi
                     fi
                     false
                       fi
                     fi
                     false
-                  fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$work_dir_securiteinfo/$db_file" "$clam_dbs" 2>/dev/null ; then
-                  perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
-                  if [ "$selinux_fixes" == "yes" ] ; then
-                    restorecon "$clam_dbs/$db_file"
+                    fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${db_file}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${work_dir_securiteinfo}/${db_file}" "$clam_dbs" 2>&13 ; then
+                    perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
+                    if [ "$selinux_fixes" == "yes" ] ; then
+                      restorecon "${clam_dbs}/${db_file}"
+                    fi
+                    xshok_pretty_echo_and_log "Successfully updated SecuriteInfo production database file: ${db_file}"
+                    securiteinfo_updates=1
+                    securiteinfo_db_update=1
+                    do_clamd_reload=1
+                  else
+                    xshok_pretty_echo_and_log "Failed to successfully update SecuriteInfo production database file: ${db_file} - SKIPPING"
                   fi
                   fi
-                  xshok_pretty_echo_and_log "Successfully updated SecuriteInfo production database file: $db_file"
-                  securiteinfo_updates=1
-                  securiteinfo_db_update=1
-                  do_clamd_reload=1
-                else
-                  xshok_pretty_echo_and_log "Failed to successfully update SecuriteInfo production database file: $db_file - SKIPPING"
-                fi
-              else
-                $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$work_dir_securiteinfo/$db_file" > "$test_dir/$db_file"
-                $clamscan_bin --infected --no-summary -d "$test_dir/$db_file" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "$work_dir_work_configs/whitelist.txt"
-                $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir/$db_file" | cut -d "*" -f2 | sort | uniq >> "$work_dir_work_configs/whitelist.hex"
-                $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$test_dir/$db_file" > "$test_dir/$db_file-tmp"
-                mv -f "$test_dir/$db_file-tmp" "$test_dir/$db_file"
-                if $clamscan_bin --quiet -d "$test_dir/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null
-                  then
-                  xshok_pretty_echo_and_log "Clamscan reports SecuriteInfo $db_file database integrity tested good"
-                  true
                 else
                 else
-                  xshok_pretty_echo_and_log "Clamscan reports SecuriteInfo $db_file database integrity tested BAD"
-                  rm -f "$work_dir_securiteinfo/$db_file"
-                  if [ "$remove_bad_database" == "yes" ] ; then
-                    if rm -f "$work_dir_securiteinfo/$db_file" ; then
-                      xshok_pretty_echo_and_log "Removed invalid database: $work_dir_securiteinfo/$db_file"
+                  $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${work_dir_securiteinfo}/${db_file}" > "${test_dir}/${db_file}"
+                  $clamscan_bin --infected --no-summary -d "${test_dir}/${db_file}" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "${work_dir_work_configs}/whitelist.txt"
+                  $grep_bin -h -f "${work_dir_work_configs}/whitelist.txt" "${test_dir}/${db_file}" | cut -d "*" -f 2 | sort | uniq >> "${work_dir_work_configs}/whitelist.hex"
+                  $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${test_dir}/${db_file}" > "${test_dir}/${db_file}-tmp"
+                  mv -f "${test_dir}/${db_file}-tmp" "${test_dir}/${db_file}"
+                  if $clamscan_bin --quiet -d "${test_dir}/${db_file}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                    xshok_pretty_echo_and_log "Clamscan reports SecuriteInfo ${db_file} database integrity tested good"
+                    true
+                  else
+                    xshok_pretty_echo_and_log "Clamscan reports SecuriteInfo ${db_file} database integrity tested BAD"
+                    rm -f "${work_dir_securiteinfo}/${db_file}"
+                    if [ "$remove_bad_database" == "yes" ] ; then
+                      if rm -f "${work_dir_securiteinfo}/${db_file}" ; then
+                        xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_securiteinfo}/${db_file}"
+                      fi
                     fi
                     fi
+                    false
+                    fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${db_file}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${test_dir}/${db_file}" "$clam_dbs" 2>&13 ; then
+                    perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
+                    if [ "$selinux_fixes" == "yes" ] ; then
+                      restorecon "${clam_dbs}/${db_file}"
+                    fi
+                    xshok_pretty_echo_and_log "Successfully updated SecuriteInfo production database file: ${db_file}"
+                    securiteinfo_updates=1
+                    securiteinfo_db_update=1
+                    do_clamd_reload=1
+                  else
+                    xshok_pretty_echo_and_log "Failed to successfully update SecuriteInfo production database file: ${db_file} - SKIPPING"
                   fi
                   fi
-                  false
-                fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$test_dir/$db_file" "$clam_dbs" 2>/dev/null ; then
-                perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
-                if [ "$selinux_fixes" == "yes" ] ; then
-                  restorecon "$clam_dbs/$db_file"
                 fi
                 fi
-                xshok_pretty_echo_and_log "Successfully updated SecuriteInfo production database file: $db_file"
-                securiteinfo_updates=1
-                securiteinfo_db_update=1
-                do_clamd_reload=1
-              else
-                xshok_pretty_echo_and_log "Failed to successfully update SecuriteInfo production database file: $db_file - SKIPPING"
               fi
               fi
+            else
+              xshok_pretty_echo_and_log "Failed connection to ${securiteinfo_url} - SKIPPED SecuriteInfo ${db_file} update"
+            fi
+            if [ "$securiteinfo_db_update" != "1" ] ; then
+              xshok_pretty_echo_and_log "No updated SecuriteInfo ${db_file} database file found" "-"
             fi
             fi
+          done
+          if [ "$securiteinfo_updates" != "1" ] ; then
+            xshok_pretty_echo_and_log "No SecuriteInfo database file updates found" "-"
           fi
           fi
+        else
+          xshok_pretty_echo_and_log "SecuriteInfo Database File Updates" "="
+          xshok_draw_time_remaining "$((update_interval - time_interval))" "$securiteinfo_update_hours" "SecuriteInfo"
         fi
         fi
-      else
-        xshok_pretty_echo_and_log "Failed connection to $securiteinfo_url - SKIPPED SecuriteInfo $db_file update"
       fi
       fi
-      if [ "$securiteinfo_db_update" != "1" ] ; then          
-        xshok_pretty_echo_and_log "No updated SecuriteInfo $db_file database file found" "-"
-      fi
-    done
-    if [ "$securiteinfo_updates" != "1" ] ; then
-      xshok_pretty_echo_and_log "No SecuriteInfo database file updates found" "-"
     fi
     fi
-  else
-    xshok_pretty_echo_and_log "SecuriteInfo Database File Updates" "="
-
-    time_remaining=$((update_interval - time_interval))
-    hours_left=$((time_remaining / 3600))
-    minutes_left=$((time_remaining % 3600 / 60))
-    xshok_pretty_echo_and_log "$securiteinfo_update_hours hours have not yet elapsed since the last SecuriteInfo update check"
-    xshok_pretty_echo_and_log "No update check was performed at this time" "-"
-    xshok_pretty_echo_and_log "Next check will be performed in approximately $hours_left hour(s), $minutes_left minute(s)"
-  fi
-  fi
-  fi
   fi
 else
   if [ -n "$securiteinfo_dbs" ] ; then
     if [ "$remove_disabled_databases" == "yes" ] ; then
       xshok_pretty_echo_and_log "Removing disabled SecuriteInfo Database files"
   fi
 else
   if [ -n "$securiteinfo_dbs" ] ; then
     if [ "$remove_disabled_databases" == "yes" ] ; then
       xshok_pretty_echo_and_log "Removing disabled SecuriteInfo Database files"
-      for db_file in $securiteinfo_dbs ; do
-        if [ -r "$work_dir_securiteinfo/$db_file" ] ; then
-          rm -f "$work_dir_securiteinfo/$db_file"
+      for db_file in "${securiteinfo_dbs[@]}" ; do
+        if echo "$db_file" | $grep_bin -q "|" ; then
+          db_file="${db_file%|*}"
+        fi
+        if [ -r "${work_dir_securiteinfo}/${db_file}" ] ; then
+          xshok_pretty_echo_and_log "Removing ${work_dir_securiteinfo}/${db_file}"
+          rm -f "${work_dir_securiteinfo}/${db_file}"
           do_clamd_reload=1
         fi
           do_clamd_reload=1
         fi
-        if [ -r "$clam_dbs/$db_file" ] ; then
-          rm -f "$clam_dbs/$db_file"
+        if [ -r "${clam_dbs}/${db_file}" ] ; then
+          xshok_pretty_echo_and_log "Removing ${clam_dbs}/${db_file}"
+          rm -f "${clam_dbs}/${db_file}"
           do_clamd_reload=1
         fi
       done
           do_clamd_reload=1
         fi
       done
@@ -2291,144 +2782,160 @@ else
   fi
 fi
 
   fi
 fi
 
-
 ##############################################################################################################################################
 ##############################################################################################################################################
-# Check for updated linuxmalwaredetect database files every set number of hours as defined in the "USER CONFIGURATION" section of this script 
+# Check for updated LinuxMalwareDetect database files every set number of hours as defined in the "USER CONFIGURATION" section of this script
 ##############################################################################################################################################
 if [ "$linuxmalwaredetect_enabled" == "yes" ] ; then
 ##############################################################################################################################################
 if [ "$linuxmalwaredetect_enabled" == "yes" ] ; then
-  if [ -n "$linuxmalwaredetect_dbs" ] ; then
-    if [ "$(xshok_array_count "$linuxmalwaredetect_dbs")" -lt "1" ] ; then
+  if [ -n "${linuxmalwaredetect_dbs[0]}" ] ; then
+    if [ ${#linuxmalwaredetect_dbs} -lt 1 ] ; then
       xshok_pretty_echo_and_log "Failed linuxmalwaredetect_dbs config is invalid or not defined - SKIPPING"
     else
       xshok_pretty_echo_and_log "Failed linuxmalwaredetect_dbs config is invalid or not defined - SKIPPING"
     else
-    rm -f "$work_dir_linuxmalwaredetect/*.gz"
-    if [ -r "$work_dir_work_configs/last-linuxmalwaredetect-update.txt" ] ; then
-      last_linuxmalwaredetect_update=$(cat "$work_dir_work_configs/last-linuxmalwaredetect-update.txt")
-    else
-      last_linuxmalwaredetect_update="0"
-    fi
-    db_file=""
-    loop=""
-    update_interval=$((linuxmalwaredetect_update_hours * 3600))
-    time_interval=$((current_time - last_linuxmalwaredetect_update))
-    if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
-      echo "$current_time" > "$work_dir_work_configs/last-linuxmalwaredetect-update.txt"
-
-      xshok_pretty_echo_and_log "linuxmalwaredetect Database File Updates" "="
-      xshok_pretty_echo_and_log "Checking for linuxmalwaredetect updates..."
-      linuxmalwaredetect_updates="0"
-      for db_file in $linuxmalwaredetect_dbs ; do
-        if [ "$loop" = "1" ] ; then
-          xshok_pretty_echo_and_log "---"      
+      rm -f "${work_dir_linuxmalwaredetect}/*.gz"
+      if [ -r "${work_dir_work_configs}/last-linuxmalwaredetect-update.txt" ] ; then
+        last_linuxmalwaredetect_update="$(cat "${work_dir_work_configs}/last-linuxmalwaredetect-update.txt")"
+      else
+        last_linuxmalwaredetect_update="0"
+      fi
+      db_file=""
+      loop=""
+      update_interval="$((linuxmalwaredetect_update_hours * 3600))"
+      time_interval="$((current_time - last_linuxmalwaredetect_update))"
+      if [ "$time_interval" -ge "$((update_interval - 600))" ] ; then
+        echo "$current_time" > "${work_dir_work_configs}/last-linuxmalwaredetect-update.txt"
+
+        xshok_pretty_echo_and_log "LinuxMalwareDetect Database File Updates" "="
+        xshok_pretty_echo_and_log "Checking for LinuxMalwareDetect updates..."
+
+        # Check for a new version
+        found_upgrade="no"
+        if [ -n "$curl_bin" ] ; then
+          # shellcheck disable=SC2086
+          latest_linuxmalwaredetect_version="$($curl_bin --compressed $curl_proxy $curl_insecure $curl_output_level --connect-timeout "${downloader_connect_timeout}" --remote-time --location --retry "${downloader_tries}" --max-time "${downloader_max_time}" "$linuxmalwaredetect_version_url" 2>&11 | head -n1 | xargs)"
+        else
+          # shellcheck disable=SC2086
+          latest_linuxmalwaredetect_version="$($wget_bin $wget_compression $wget_proxy $wget_insecure $wget_output_level --connect-timeout="${downloader_connect_timeout}" --random-wait --tries="${downloader_tries}" --timeout="${downloader_max_time}" "$linuxmalwaredetect_version_url" -O - 2>&12 | $grep_bin "^script_version=" | head -n1 | xargs)"
         fi
         fi
-        xshok_pretty_echo_and_log "Checking for updated linuxmalwaredetect database file: $db_file"
 
 
-        linuxmalwaredetect_db_update="0"
-        if [ "$wget_bin" != "" ] ; then
-          $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_linuxmalwaredetect/$db_file" "$linuxmalwaredetect_url/$db_file"
-          ret="$?"
-        else
-          $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_linuxmalwaredetect/$db_file" "$linuxmalwaredetect_url/$db_file"
-          ret="$?"
+        if [ "$latest_linuxmalwaredetect_version" ] ; then
+          # shellcheck disable=SC2183,SC2086
+          if [ -f "${work_dir_linuxmalwaredetect}/current_linuxmalwaredetect_version" ] ; then
+            current_linuxmalwaredetect_version="$(head -n1 "${work_dir_linuxmalwaredetect}/current_linuxmalwaredetect_version" | xargs)"
+          else
+            current_linuxmalwaredetect_version="-1"
+          fi
+          if [ "$latest_linuxmalwaredetect_version" != "$current_linuxmalwaredetect_version" ] ; then
+            xshok_pretty_echo_and_log "LinuxMalwareDetect Database File Updates" "="
+            found_upgrade="yes"
+          fi
         fi
         fi
-        if [ "$ret" -eq "0" ] ; then
-          loop="1"
-          if ! cmp -s "$work_dir_linuxmalwaredetect/$db_file" "$clam_dbs/$db_file" ; then
-            if [ "$?" -eq "0" ] ; then
-              db_ext=$(echo "$db_file" | cut -d "." -f2)
 
 
-              xshok_pretty_echo_and_log "Testing updated linuxmalwaredetect database file: $db_file"
-              if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
-                if $clamscan_bin --quiet -d "$work_dir_linuxmalwaredetect/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null
-                  then
-                  xshok_pretty_echo_and_log "Clamscan reports linuxmalwaredetect $db_file database integrity tested good"
-                  true
-                else
-                  xshok_pretty_echo_and_log "Clamscan reports linuxmalwaredetect $db_file database integrity tested BAD"
-                  if [ "$remove_bad_database" == "yes" ] ; then
-                    if rm -f "$work_dir_linuxmalwaredetect/$db_file" ; then
-                      xshok_pretty_echo_and_log "Removed invalid database: $work_dir_linuxmalwaredetect/$db_file"
+        if [ "$found_upgrade" == "yes" ] ; then
+          xshok_file_download "${work_dir_linuxmalwaredetect}/sigpack.tgz" "${linuxmalwaredetect_sigpack_url}"
+          ret="$?"
+          if [ "$ret" -eq 0 ] ; then
+                                               # shellcheck disable=SC2035
+            $tar_bin --strip-components=1 --wildcards --overwrite -xzf "${work_dir_linuxmalwaredetect}/sigpack.tgz" --directory "${work_dir_linuxmalwaredetect}" */rfxn.*
+            for db_file in "${linuxmalwaredetect_dbs[@]}" ; do
+              if [ "$loop" == "1" ] ; then
+                xshok_pretty_echo_and_log "---"
+              fi
+              loop="1"
+              if ! cmp -s "${work_dir_linuxmalwaredetect}/${db_file}" "${clam_dbs}/${db_file}" ; then
+                db_ext="${db_file#*.}"
+
+                xshok_pretty_echo_and_log "Testing updated LinuxMalwareDetect database file: ${db_file}"
+                if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
+                  if $clamscan_bin --quiet -d "${work_dir_linuxmalwaredetect}/${db_file}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                    xshok_pretty_echo_and_log "Clamscan reports LinuxMalwareDetect ${db_file} database integrity tested good"
+                    true
+                  else
+                    xshok_pretty_echo_and_log "Clamscan reports LinuxMalwareDetect ${db_file} database integrity tested BAD"
+                    if [ "$remove_bad_database" == "yes" ] ; then
+                      if rm -f "${work_dir_linuxmalwaredetect}/${db_file}" ; then
+                        xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_linuxmalwaredetect}/${db_file}"
+                      fi
+                    fi
+                    false
+                    fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${db_file}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${work_dir_linuxmalwaredetect}/${db_file}" "$clam_dbs" 2>&13 ; then
+                    perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
+                    if [ "$selinux_fixes" == "yes" ] ; then
+                      restorecon "${clam_dbs}/local.ign"
                     fi
                     fi
+                    xshok_pretty_echo_and_log "Successfully updated LinuxMalwareDetect production database file: ${db_file}"
+                    do_clamd_reload=1
+                  else
+                    xshok_pretty_echo_and_log "Failed to successfully update LinuxMalwareDetect production database file: ${db_file} - SKIPPING"
                   fi
                   fi
-                  false
-                fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$work_dir_linuxmalwaredetect/$db_file" "$clam_dbs" 2>/dev/null ; then
-                perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
-                if [ "$selinux_fixes" == "yes" ] ; then
-                  restorecon "$clam_dbs/local.ign"
-                fi
-                xshok_pretty_echo_and_log "Successfully updated linuxmalwaredetect production database file: $db_file"
-                linuxmalwaredetect_updates=1
-                linuxmalwaredetect_db_update=1
-                do_clamd_reload=1
-              else
-                xshok_pretty_echo_and_log "Failed to successfully update linuxmalwaredetect production database file: $db_file - SKIPPING"
-              fi
-            else
-              $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$work_dir_linuxmalwaredetect/$db_file" > "$test_dir/$db_file"
-              $clamscan_bin --infected --no-summary -d "$test_dir/$db_file" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "$work_dir_work_configs/whitelist.txt"
-              $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir/$db_file" | cut -d "*" -f2 | sort | uniq >> "$work_dir_work_configs/whitelist.hex"
-              $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$test_dir/$db_file" > "$test_dir/$db_file-tmp"
-              mv -f "$test_dir/$db_file-tmp" "$test_dir/$db_file"
-              if $clamscan_bin --quiet -d "$test_dir/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
-                xshok_pretty_echo_and_log "Clamscan reports linuxmalwaredetect $db_file database integrity tested good"
-                true
-              else
-                xshok_pretty_echo_and_log "Clamscan reports linuxmalwaredetect $db_file database integrity tested BAD"
-                if [ "$remove_bad_database" == "yes" ] ; then
-                  if rm -f "$work_dir_linuxmalwaredetect/$db_file" ; then
-                    xshok_pretty_echo_and_log "Removed invalid database: $work_dir_linuxmalwaredetect/$db_file"
+                else
+                  $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${work_dir_linuxmalwaredetect}/${db_file}" > "${test_dir}/${db_file}"
+                  $clamscan_bin --infected --no-summary -d "${test_dir}/${db_file}" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "${work_dir_work_configs}/whitelist.txt"
+                  $grep_bin -h -f "${work_dir_work_configs}/whitelist.txt" "${test_dir}/${db_file}" | cut -d "*" -f 2 | sort | uniq >> "${work_dir_work_configs}/whitelist.hex"
+                  $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${test_dir}/${db_file}" > "${test_dir}/${db_file}-tmp"
+                  mv -f "${test_dir}/${db_file}-tmp" "${test_dir}/${db_file}"
+                  if $clamscan_bin --quiet -d "${test_dir}/${db_file}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                    xshok_pretty_echo_and_log "Clamscan reports LinuxMalwareDetect ${db_file} database integrity tested good"
+                    true
+                  else
+                    xshok_pretty_echo_and_log "Clamscan reports LinuxMalwareDetect ${db_file} database integrity tested BAD"
+                    if [ "$remove_bad_database" == "yes" ] ; then
+                      if rm -f "${work_dir_linuxmalwaredetect}/${db_file}" ; then
+                        xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_linuxmalwaredetect}/${db_file}"
+                      fi
+                    fi
+                    false
+                    fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${db_file}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${test_dir}/${db_file}" "$clam_dbs" 2>&13 ; then
+                    perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
+                    if [ "$selinux_fixes" == "yes" ] ; then
+                      restorecon "${clam_dbs}/${db_file}"
+                    fi
+                    xshok_pretty_echo_and_log "Successfully updated LinuxMalwareDetect production database file: ${db_file}"
+                    do_clamd_reload=1
+                  else
+                    xshok_pretty_echo_and_log "Failed to successfully update LinuxMalwareDetect production database file: ${db_file} - SKIPPING"
                   fi
                 fi
                   fi
                 fi
-                false
-              fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$test_dir/$db_file" "$clam_dbs" 2>/dev/null ;  then
-              perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
-              if [ "$selinux_fixes" == "yes" ] ; then
-                restorecon "$clam_dbs/$db_file"
               fi
               fi
-              xshok_pretty_echo_and_log "Successfully updated linuxmalwaredetect production database file: $db_file"
-              linuxmalwaredetect_updates=1
-              linuxmalwaredetect_db_update=1
-              do_clamd_reload=1
-            else
-              xshok_pretty_echo_and_log "Failed to successfully update linuxmalwaredetect production database file: $db_file - SKIPPING"
-            fi
+
+            done
+            #save the current version
+            echo "$latest_linuxmalwaredetect_version" > "${work_dir_linuxmalwaredetect}/current_linuxmalwaredetect_version"
+
+          else
+            xshok_pretty_echo_and_log "WARNING: Failed connection to ${linuxmalwaredetect_sigpack_url} - SKIPPED LinuxMalwareDetect update"
           fi
           fi
+        else
+          xshok_pretty_echo_and_log "No LinuxMalwareDetect database file updates found" "-"
         fi
         fi
+      else
+        xshok_pretty_echo_and_log "LinuxMalwareDetect Database File Updates" "="
+        xshok_draw_time_remaining "$((update_interval - time_interval))" "$linuxmalwaredetect_update_hours" "linuxmalwaredetect"
       fi
       fi
-    else
-      xshok_pretty_echo_and_log "WARNING: Failed connection to $linuxmalwaredetect_url - SKIPPED linuxmalwaredetect $db_file update"
-    fi
-    if [ "$linuxmalwaredetect_db_update" != "1" ] ; then
-
-      xshok_pretty_echo_and_log "No updated linuxmalwaredetect $db_file database file found"
     fi
     fi
-  done
-  if [ "$linuxmalwaredetect_updates" != "1" ] ; then
-    xshok_pretty_echo_and_log "No linuxmalwaredetect database file updates found" "-"
   fi
 else
   fi
 else
+  if [ -n "${linuxmalwaredetect_dbs[0]}" ] ; then
+    if [ "$remove_disabled_databases" == "yes" ] ; then
+      xshok_pretty_echo_and_log "Removing disabled LinuxMalwareDetect Database files"
 
 
-  xshok_pretty_echo_and_log "linuxmalwaredetect Database File Updates" "="
+      if [ -f "${work_dir_linuxmalwaredetect}/current_linuxmalwaredetect_version" ] ; then
+        rm -f "${work_dir_linuxmalwaredetect}/current_linuxmalwaredetect_version"
+      fi
+      if [ -f "${work_dir_linuxmalwaredetect}/sigpack.tgz" ] ; then
+        rm -f "${work_dir_linuxmalwaredetect}/sigpack.tgz"
+      fi
 
 
-  time_remaining=$((update_interval - time_interval))
-  hours_left=$((time_remaining / 3600))
-  minutes_left=$((time_remaining % 3600 / 60))
-  xshok_pretty_echo_and_log "$linuxmalwaredetect_update_hours hours have not yet elapsed since the last linux malware detect update check"
-  xshok_pretty_echo_and_log "No update check was performed at this time" "-"
-  xshok_pretty_echo_and_log "Next check will be performed in approximately $hours_left hour(s), $minutes_left minute(s)"
-fi
-fi
-fi
-else
-  if [ -n "$linuxmalwaredetect_dbs" ] ; then
-    if [ "$remove_disabled_databases" == "yes" ] ; then
-      xshok_pretty_echo_and_log "Removing disabled linuxmalwaredetect Database files"
-      for db_file in $linuxmalwaredetect_dbs ; do
-        if [ -r "$work_dir_linuxmalwaredetect/$db_file" ] ; then
-          rm -f "$work_dir_linuxmalwaredetect/$db_file"
+      for db_file in "${linuxmalwaredetect_dbs[@]}" ; do
+        if echo "$db_file" | $grep_bin -q "|" ; then
+          db_file="${db_file%|*}"
+        fi
+        if [ -r "${work_dir_linuxmalwaredetect}/${db_file}" ] ; then
+          xshok_pretty_echo_and_log "Removing ${work_dir_linuxmalwaredetect}/${db_file}"
+          rm -f "${work_dir_linuxmalwaredetect}/${db_file}"
           do_clamd_reload=1
         fi
           do_clamd_reload=1
         fi
-        if [ -r "$clam_dbs/$db_file" ] ; then
-          rm -f "$clam_dbs/$db_file"
+        if [ -r "${clam_dbs}/${db_file}" ] ; then
+          xshok_pretty_echo_and_log "Removing ${clam_dbs}/${db_file}"
+          rm -f "${clam_dbs}/${db_file}"
           do_clamd_reload=1
         fi
       done
           do_clamd_reload=1
         fi
       done
@@ -2437,330 +2944,406 @@ else
 fi
 
 
 fi
 
 
-##########################################################################################################################################
-# Download MalwarePatrol database file every set number of hours as defined in the "USER CONFIGURATION" section of this script.    #
+#########################################################################################################################################
+# Download MalwarePatrol database file every set number of hours as defined in the "USER CONFIGURATION" section of this script.          #
 ##########################################################################################################################################
 if [ "$malwarepatrol_enabled" == "yes" ] ; then
   if [ "$malwarepatrol_receipt_code" != "YOUR-RECEIPT-NUMBER" ] ; then
 ##########################################################################################################################################
 if [ "$malwarepatrol_enabled" == "yes" ] ; then
   if [ "$malwarepatrol_receipt_code" != "YOUR-RECEIPT-NUMBER" ] ; then
-    if [ -n "$malwarepatrol_db" ] ; then
-      if [ -r "$work_dir_work_configs/last-mbl-update.txt" ] ; then
-        last_malwarepatrol_update=$(cat "$work_dir_work_configs/last-mbl-update.txt")
-      else
-        last_malwarepatrol_update="0"
-      fi
-      db_file=""
-      update_interval=$((malwarepatrol_update_hours * 3600))
-      time_interval=$((current_time - last_malwarepatrol_update))
-      if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
-        echo "$current_time" > "$work_dir_work_configs"/last-mbl-update.txt
-        xshok_pretty_echo_and_log "Checking for MalwarePatrol updates..."
-        # Delete the old MBL (mbl.db) database file if it exists and start using the newer
-        # format (mbl.ndb) database file instead.
-        # test -e $clam_dbs/$malwarepatrol_db -o -e $clam_dbs/$malwarepatrol_db-bak && rm -f -- "$clam_dbs/mbl.d*"
-
-        # remove the .db is th new format if ndb and
-        # symetrically
-        if [ "$malwarepatrol_db" == "malwarepatrol.db" ] && [ -f "$clam_dbs/malwarepatrol.ndb" ] ; then
-          rm "$clam_dbs/malwarepatrol.ndb";
+    if [ -n "${malwarepatrol_db}" ] ; then
+        rm -f "${work_dir_malwarepatrol}/*.gz"
+        if [ -r "${work_dir_work_configs}/last-mbl-update.txt" ] ; then
+          last_malwarepatrol_update="$(cat "${work_dir_work_configs}/last-mbl-update.txt")"
+        else
+          last_malwarepatrol_update="0"
         fi
         fi
+        loop=""
+        update_interval="$((malwarepatrol_update_hours * 3600))"
+        time_interval="$((current_time - last_malwarepatrol_update))"
+        if [ "$time_interval" -ge "$((update_interval - 600))" ] ; then
+          echo "$current_time" > "${work_dir_work_configs}/last-mbl-update.txt"
+          xshok_pretty_echo_and_log "MalwarePatrol Database File Updates" "="
+          xshok_pretty_echo_and_log "Checking for MalwarePatrol updates..."
+          malwarepatrol_updates="0"
+
+          # Cleanup any not required database files
+          if [ "$malwarepatrol_db" == "malwarepatrol.db" ] && [ -f "${clam_dbs}/malwarepatrol.ndb" ] ; then
+            rm -f "${clam_dbs}/malwarepatrol.ndb";
+          fi
+          if [ "$malwarepatrol_db" == "malwarepatrol.ndb" ] && [ -f "${clam_dbs}/malwarepatrol.db" ] ; then
+            rm -f "${clam_dbs}/malwarepatrol.db";
+          fi
 
 
-        if [ "$malwarepatrol_db" == "malwarepatrol.ndb" ] && [ -f "$clam_dbs/malwarepatrol.db" ] ; then
-          rm "$clam_dbs/malwarepatrol.db";
-        fi
+            if [ "$loop" == "1" ] ; then
+              xshok_pretty_echo_and_log "---"
+            fi
+            xshok_pretty_echo_and_log "Checking for updated MalwarePatrol database file: ${malwarepatrol_db}"
+            malwarepatrol_db_update="0"
 
 
-        xshok_pretty_echo_and_log "MalwarePatrol $db_file Database File Update" "="
+            xshok_file_download "${work_dir_malwarepatrol}/${malwarepatrol_db}" "${malwarepatrol_url}&receipt=${malwarepatrol_receipt_code}"
 
 
-        malwarepatrol_reloaded=0
-        if [ "$malwarepatrol_free" == "yes" ] ; then
-          if [ "$wget_bin" != "" ] ; then
-            $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_malwarepatrol/$malwarepatrol_db" "$malwarepatrol_url&receipt=$malwarepatrol_receipt_code"
-            ret="$?"
-          else
-            $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_malwarepatrol/$malwarepatrol_db" "$malwarepatrol_url&receipt=$malwarepatrol_receipt_code"
             ret="$?"
             ret="$?"
-          fi
-          if [ "$ret" -eq "0" ] ; then
-            if ! cmp -s "$work_dir_malwarepatrol/$malwarepatrol_db" "$clam_dbs/$malwarepatrol_db" ; then
-              if [ "$?" -eq "0" ] ; then
-                malwarepatrol_reloaded=1
-              else
-                malwarepatrol_reloaded=2
+            if [ "$ret" -eq 0 ] ; then
+              loop="1"
+              if ! cmp -s "${work_dir_malwarepatrol}/${malwarepatrol_db}" "${clam_dbs}/${malwarepatrol_db}" ; then
+                db_ext="${malwarepatrol_db#*.}"
+
+                xshok_pretty_echo_and_log "Testing updated MalwarePatrol database file: ${malwarepatrol_db}"
+                if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
+                  if $clamscan_bin --quiet -d "${work_dir_malwarepatrol}/${malwarepatrol_db}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                    xshok_pretty_echo_and_log "Clamscan reports MalwarePatrol ${malwarepatrol_db} database integrity tested good"
+                    true
+                  else
+                    xshok_pretty_echo_and_log "Clamscan reports MalwarePatrol ${malwarepatrol_db} database integrity tested BAD"
+                    if [ "$remove_bad_database" == "yes" ] ; then
+                      if rm -f "${work_dir_malwarepatrol}/${malwarepatrol_db}" ; then
+                        xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_malwarepatrol}/${malwarepatrol_db}"
+                      fi
+                    fi
+                    false
+                    fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${malwarepatrol_db}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${work_dir_malwarepatrol}/${malwarepatrol_db}" "$clam_dbs" 2>&13 ; then
+                    perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${malwarepatrol_db}"
+                    if [ "$selinux_fixes" == "yes" ] ; then
+                      restorecon "${clam_dbs}/${malwarepatrol_db}"
+                    fi
+                    xshok_pretty_echo_and_log "Successfully updated MalwarePatrol production database file: ${malwarepatrol_db}"
+                    malwarepatrol_updates=1
+                    malwarepatrol_db_update=1
+                    do_clamd_reload=1
+                  else
+                    xshok_pretty_echo_and_log "Failed to successfully update MalwarePatrol production database file: ${malwarepatrol_db} - SKIPPING"
+                  fi
+                else
+                  $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${work_dir_malwarepatrol}/${malwarepatrol_db}" > "${test_dir}/${malwarepatrol_db}"
+                  $clamscan_bin --infected --no-summary -d "${test_dir}/${malwarepatrol_db}" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "${work_dir_work_configs}/whitelist.txt"
+                  $grep_bin -h -f "${work_dir_work_configs}/whitelist.txt" "${test_dir}/${malwarepatrol_db}" | cut -d "*" -f 2 | sort | uniq >> "${work_dir_work_configs}/whitelist.hex"
+                  $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${test_dir}/${malwarepatrol_db}" > "${test_dir}/${malwarepatrol_db}-tmp"
+                  mv -f "${test_dir}/${malwarepatrol_db}-tmp" "${test_dir}/${malwarepatrol_db}"
+                  if $clamscan_bin --quiet -d "${test_dir}/${malwarepatrol_db}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                    xshok_pretty_echo_and_log "Clamscan reports MalwarePatrol ${malwarepatrol_db} database integrity tested good"
+                    true
+                  else
+                    xshok_pretty_echo_and_log "Clamscan reports MalwarePatrol ${malwarepatrol_db} database integrity tested BAD"
+                    rm -f "${work_dir_malwarepatrol}/${malwarepatrol_db}"
+                    if [ "$remove_bad_database" == "yes" ] ; then
+                      if rm -f "${work_dir_malwarepatrol}/${malwarepatrol_db}" ; then
+                        xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_malwarepatrol}/${malwarepatrol_db}"
+                      fi
+                    fi
+                    false
+                    fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${malwarepatrol_db}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${test_dir}/${malwarepatrol_db}" "$clam_dbs" 2>&13 ; then
+                    perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${malwarepatrol_db}"
+                    if [ "$selinux_fixes" == "yes" ] ; then
+                      restorecon "${clam_dbs}/${malwarepatrol_db}"
+                    fi
+                    xshok_pretty_echo_and_log "Successfully updated MalwarePatrol production database file: ${malwarepatrol_db}"
+                    malwarepatrol_updates=1
+                    malwarepatrol_db_update=1
+                    do_clamd_reload=1
+                  else
+                    xshok_pretty_echo_and_log "Failed to successfully update MalwarePatrol production database file: ${malwarepatrol_db} - SKIPPING"
+                  fi
+                fi
               fi
               fi
+            else
+              xshok_pretty_echo_and_log "Failed connection to ${malwarepatrol_url} - SKIPPED MalwarePatrol ${malwarepatrol_db} update"
             fi
             fi
-          else # wget failed
-            malwarepatrol_reloaded=-1
+            if [ "$malwarepatrol_db_update" != "1" ] ; then
+              xshok_pretty_echo_and_log "No updated MalwarePatrol ${malwarepatrol_db} database file found" "-"
+            fi
+          if [ "$malwarepatrol_updates" != "1" ] ; then
+            xshok_pretty_echo_and_log "No MalwarePatrol database file updates found" "-"
           fi
           fi
+        else
+          xshok_pretty_echo_and_log "MalwarePatrol Database File Updates" "="
+          xshok_draw_time_remaining "$((update_interval - time_interval))" "$malwarepatrol_update_hours" "malwarepatrol"
+        fi
+      fi
+    fi
+else
+  if [ -n "$malwarepatrol_dbs" ] ; then
+    if [ "$remove_disabled_databases" == "yes" ] ; then
+      xshok_pretty_echo_and_log "Removing disabled MalwarePatrol Database files"
+        if [ -r "${work_dir_malwarepatrol}/${malwarepatrol_db}" ] ; then
+          xshok_pretty_echo_and_log "Removing ${work_dir_malwarepatrol}/${malwarepatrol_db}"
+          rm -f "${work_dir_malwarepatrol}/${malwarepatrol_db}"
+          do_clamd_reload=1
+        fi
+        if [ -r "${clam_dbs}/${malwarepatrol_db}" ] ; then
+          xshok_pretty_echo_and_log "Removing ${clam_dbs}/${malwarepatrol_db}"
+          rm -f "${clam_dbs}/${malwarepatrol_db}"
+          do_clamd_reload=1
+        fi
+    fi
+  fi
+fi
 
 
-        else # The not free branch
-          if [ "$wget_bin" != "" ] ; then
-            $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_malwarepatrol/$malwarepatrol_db.md5" "$malwarepatrol_url&receipt=$malwarepatrol_receipt_code&hash=1"
-            ret="$?"
-          else
-            $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_malwarepatrol/$malwarepatrol_db.md5" "$malwarepatrol_url&receipt=$malwarepatrol_receipt_code&hash=1"
-            ret="$?"
+##############################################################################################################################################
+# Check for updated urlhaus database files every set number of hours as defined in the "USER CONFIGURATION" section of this script
+##############################################################################################################################################
+if [ "$urlhaus_enabled" == "yes" ] ; then
+  if [ -n "${urlhaus_dbs[0]}" ] ; then
+    if [ ${#urlhaus_dbs} -lt 1 ] ; then
+      xshok_pretty_echo_and_log "Failed urlhaus_dbs config is invalid or not defined - SKIPPING"
+    else
+      rm -f "${work_dir_urlhaus}/*.gz"
+      if [ -r "${work_dir_work_configs}/last-urlhaus-update.txt" ] ; then
+        last_urlhaus_update="$(cat "${work_dir_work_configs}/last-urlhaus-update.txt")"
+      else
+        last_urlhaus_update="0"
+      fi
+      db_file=""
+      loop=""
+      update_interval="$((urlhaus_update_hours * 3600))"
+      time_interval="$((current_time - last_urlhaus_update))"
+      if [ "$time_interval" -ge "$((update_interval - 600))" ] ; then
+        echo "$current_time" > "${work_dir_work_configs}/last-urlhaus-update.txt"
+
+        xshok_pretty_echo_and_log "Yara-Rules Database File Updates" "="
+        xshok_pretty_echo_and_log "Checking for urlhaus updates..."
+        urlhaus_updates="0"
+        for db_file in "${urlhaus_dbs[@]}" ; do
+          if echo "$db_file" | $grep_bin -q "/" ; then
+            yr_dir="/$(echo "$db_file" | cut -d "/" -f 1)"
+            db_file="$(echo "$db_file" | cut -d "/" -f 2)"
+          else yr_dir=""
           fi
           fi
-          if [ "$ret" -eq "0" ] ; then
-            if [ -f "$clam_dbs/$malwarepatrol_db" ] ; then
-              malwarepatrol_md5=$(openssl md5 -r "$clam_dbs/$malwarepatrol_db" 2>/dev/null | cut -d" " -f1)
-              if [ ! "$malwarepatrol_md5" ] ; then
-                #fallback for missing -r option
-                malwarepatrol_md5=$(openssl md5 "$clam_dbs/$malwarepatrol_db" 2>/dev/null | cut -d" " -f2)
-              fi
-            fi
-            malwarepatrol_md5_new=$(cat "$work_dir_malwarepatrol/$malwarepatrol_db.md5")
-            if [ -n "$malwarepatrol_md5_new" ] && [ "$malwarepatrol_md5" != "$malwarepatrol_md5_new" ] ; then
-              if [ "$wget_bin" != "" ] ; then
-                $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_malwarepatrol/$malwarepatrol_db" "$malwarepatrol_url&receipt=$malwarepatrol_receipt_code"
-                ret="$?"
+          if [ "$loop" == "1" ] ; then
+            xshok_pretty_echo_and_log "---"
+          fi
+          xshok_pretty_echo_and_log "Checking for updated urlhaus database file: ${db_file}"
+          urlhaus_db_update="0"
+          if xshok_file_download "${work_dir_urlhaus}/${db_file}" "${urlhaus_url}/${db_file}" ; then
+            loop="1"
+            if ! cmp -s "${work_dir_urlhaus}/${db_file}" "${clam_dbs}/${db_file}" ; then
+              db_ext="${db_file#*.}"
+              xshok_pretty_echo_and_log "Testing updated urlhaus database file: ${db_file}"
+              if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
+                if $clamscan_bin --quiet -d "${work_dir_urlhaus}/${db_file}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                  xshok_pretty_echo_and_log "Clamscan reports urlhaus ${db_file} database integrity tested good"
+                  true
+                else
+                  xshok_pretty_echo_and_log "Clamscan reports urlhaus ${db_file} database integrity tested BAD"
+                  if [ "$remove_bad_database" == "yes" ] ; then
+                    if rm -f "${work_dir_urlhaus}/${db_file}" ; then
+                      xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_urlhaus}/${db_file}"
+                    fi
+                  fi
+                  false
+                  fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${db_file}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${work_dir_urlhaus}/${db_file}" "$clam_dbs" 2>&13 ; then
+                  perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
+                  if [ "$selinux_fixes" == "yes" ] ; then
+                    restorecon "${clam_dbs}/${db_file}"
+                  fi
+                  xshok_pretty_echo_and_log "Successfully updated urlhaus production database file: ${db_file}"
+                  urlhaus_updates=1
+                  urlhaus_db_update=1
+                  do_clamd_reload=1
+                else
+                  xshok_pretty_echo_and_log "Failed to successfully update urlhaus production database file: ${db_file} - SKIPPING"
+                fi
               else
               else
-                $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_malwarepatrol/$malwarepatrol_db" "$malwarepatrol_url&receipt=$malwarepatrol_receipt_code"
-                ret="$?"
+                $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${work_dir_urlhaus}/${db_file}" > "${test_dir}/${db_file}"
+                $clamscan_bin --infected --no-summary -d "${test_dir}/${db_file}" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "${work_dir_work_configs}/whitelist.txt"
+                $grep_bin -h -f "${work_dir_work_configs}/whitelist.txt" "${test_dir}/${db_file}" | cut -d "*" -f 2 | sort | uniq >> "${work_dir_work_configs}/whitelist.hex"
+                $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${test_dir}/${db_file}" > "${test_dir}/${db_file}-tmp"
+                mv -f "${test_dir}/${db_file}-tmp" "${test_dir}/${db_file}"
+                if $clamscan_bin --quiet -d "${test_dir}/${db_file}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                  xshok_pretty_echo_and_log "Clamscan reports urlhaus ${db_file} database integrity tested good"
+                  true
+                else
+                  xshok_pretty_echo_and_log "Clamscan reports urlhaus ${db_file} database integrity tested BAD"
+                  if [ "$remove_bad_database" == "yes" ] ; then
+                    if rm -f "${work_dir_urlhaus}/${db_file}" ; then
+                      xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_urlhaus}/${db_file}"
+                    fi
+                  fi
+                  false
+                  fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${db_file}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${test_dir}/${db_file}" "$clam_dbs" 2>&13 ; then
+                  perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
+                  if [ "$selinux_fixes" == "yes" ] ; then
+                    restorecon "${clam_dbs}/${db_file}"
+                  fi
+                  xshok_pretty_echo_and_log "Successfully updated urlhaus production database file: ${db_file}"
+                  urlhaus_updates=1
+                  urlhaus_db_update=1
+                  do_clamd_reload=1
+                else
+                  xshok_pretty_echo_and_log "Failed to successfully update urlhaus production database file: ${db_file} - SKIPPING"
+                fi
               fi
               fi
-              if [ "$ret" -eq "0" ] ; then
-                malwarepatrol_reloaded=1
-              else # wget DB fail
-                malwarepatrol_reloaded=-1
-              fi # wget DB
-            fi # MD5 not equal
-          else # wget MD5 fail
-            malwarepatrol_reloaded=-1
-          fi # wget md5
-        fi
 
 
-        case "$malwarepatrol_reloaded" in 
-          1) # database was updated, need test and reload 
-          xshok_pretty_echo_and_log "Testing updated MalwarePatrol database file: $malwarepatrol_db"
-          if $clamscan_bin --quiet -d "$work_dir_malwarepatrol/$malwarepatrol_db" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
-            xshok_pretty_echo_and_log "Clamscan reports MalwarePatrol $malwarepatrol_db database integrity tested good"
-            true
-          else
-            xshok_pretty_echo_and_log "Clamscan reports MalwarePatrol $malwarepatrol_db database integrity tested BAD"
-            if [ "$remove_bad_database" == "yes" ] ; then
-              if rm -f "$work_dir_malwarepatrol/$malwarepatrol_db" ; then
-                xshok_pretty_echo_and_log "Removed invalid database: $work_dir_malwarepatrol/$malwarepatrol_db"
-              fi
             fi
             fi
-            false
-          fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$malwarepatrol_db" "$clam_dbs/$malwarepatrol_db-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$work_dir_malwarepatrol/$malwarepatrol_db" "$clam_dbs" 2>/dev/null ; then
-          perms chown -f "$clam_user:$clam_group" "$clam_dbs/$malwarepatrol_db"
-          if [ "$selinux_fixes" == "yes" ] ; then
-            restorecon "$clam_dbs/$malwarepatrol_db"
+          else
+            xshok_pretty_echo_and_log "WARNING: Failed connection to $urlhaus_url - SKIPPED urlhaus ${db_file} update"
           fi
           fi
-          xshok_pretty_echo_and_log "Successfully updated MalwarePatrol production database file: $malwarepatrol_db"
-          do_clamd_reload=1
-        else
-          xshok_pretty_echo_and_log "Failed to successfully update MalwarePatrol production database file: $malwarepatrol_db - SKIPPING"
-        fi
-        ;; # The strange case when $? != 0 in the original
-        2)
-        $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$work_dir_malwarepatrol/$malwarepatrol_db" > "$test_dir/$malwarepatrol_db"
-        $clamscan_bin --infected --no-summary -d "$test_dir/$malwarepatrol_db" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "$work_dir_work_configs/whitelist.txt"
-        $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir/$malwarepatrol_db" | cut -d "*" -f2 | sort | uniq >> "$work_dir_work_configs/whitelist.hex"
-        $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$test_dir/$malwarepatrol_db" > "$test_dir/$malwarepatrol_db-tmp"
-        mv -f "$test_dir/$malwarepatrol_db-tmp" "$test_dir/$malwarepatrol_db"
-        if $clamscan_bin --quiet -d "$test_dir/$malwarepatrol_db" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
-          xshok_pretty_echo_and_log "Clamscan reports MalwarePatrol $malwarepatrol_db database integrity tested good"
-          true
-        else
-          xshok_pretty_echo_and_log "Clamscan reports MalwarePatrol $malwarepatrol_db database integrity tested BAD"
-          if [ "$remove_bad_database" == "yes" ] ; then
-            if rm -f "$test_dir/$malwarepatrol_db" ; then
-              xshok_pretty_echo_and_log "Removed invalid database: $test_dir/$malwarepatrol_db"
-            fi
+          if [ "$urlhaus_db_update" != "1" ] ; then
+            xshok_pretty_echo_and_log "No updated urlhaus ${db_file} database file found"
           fi
           fi
-          false
-        fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$malwarepatrol_db" "$clam_dbs/$malwarepatrol_db-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$test_dir/$malwarepatrol_db" "$clam_dbs" 2>/dev/null ; then
-        perms chown -f "$clam_user:$clam_group" "$clam_dbs/$malwarepatrol_db"
-        if [ "$selinux_fixes" == "yes" ] ; then
-          restorecon "$clam_dbs/$malwarepatrol_db"
+        done
+        if [ "$urlhaus_updates" != "1" ] ; then
+          xshok_pretty_echo_and_log "No urlhaus database file updates found" "-"
         fi
         fi
-        xshok_pretty_echo_and_log "Successfully updated MalwarePatrol production database file: $malwarepatrol_db"
-        do_clamd_reload=1
       else
       else
-        xshok_pretty_echo_and_log "Failed to successfully update MalwarePatrol production database file: $malwarepatrol_db - SKIPPING"
-      fi
-      ;;
-      0) # The database did not update
-      xshok_pretty_echo_and_log "MalwarePatrol signature database ($malwarepatrol_db) did not change - skipping"
-      ;;
-      -1) # wget failed
-      xshok_pretty_echo_and_log "WARNING - Failed connection to $malwarepatrol_url - SKIPPED MalwarePatrol $malwarepatrol_db update"
-      ;;
-    esac
 
 
-  else
-
-    xshok_pretty_echo_and_log "MalwarePatrol Database File Update" "="
-
-    time_remaining=$((update_interval - time_interval))
-    hours_left=$((time_remaining / 3600))
-    minutes_left=$((time_remaining % 3600 / 60))
-    xshok_pretty_echo_and_log "$malwarepatrol_update_hours hours have not yet elapsed since the last MalwarePatrol download"
-    xshok_pretty_echo_and_log "No database download was performed at this time" "-"
-    xshok_pretty_echo_and_log "Next download will be performed in approximately $hours_left hour(s), $minutes_left minute(s)"
+        xshok_pretty_echo_and_log "Yara-Rules Database File Updates" "="
+        xshok_draw_time_remaining "$((update_interval - time_interval))" "$urlhaus_update_hours" "urlhaus"
+      fi
+    fi
   fi
   fi
-fi
-fi
 else
 else
-  if [ -n "$malwarepatrol_db" ] ; then
+  if [ -n "${urlhaus_dbs[0]}" ] ; then
     if [ "$remove_disabled_databases" == "yes" ] ; then
     if [ "$remove_disabled_databases" == "yes" ] ; then
-      xshok_pretty_echo_and_log "Removing disabled MalwarePatrol Database file"
-      if [ -r "$work_dir_malwarepatrol/$malwarepatrol_db" ] ; then
-        rm -f "$work_dir_malwarepatrol/$malwarepatrol_db"
-        do_clamd_reload=1
-      fi
-      if [ -r "$clam_dbs/$malwarepatrol_db" ] ; then
-        rm -f "$clam_dbs/$malwarepatrol_db"
-        do_clamd_reload=1
-      fi
+      xshok_pretty_echo_and_log "Removing disabled urlhaus Database files"
+      for db_file in "${urlhaus_dbs[@]}" ; do
+        if echo "$db_file" | $grep_bin -q "/" ; then
+          db_file="$(echo "$db_file" | cut -d "/" -f 2)"
+        fi
+        if echo "$db_file" | $grep_bin -q "|" ; then
+          db_file="${db_file%|*}"
+        fi
+        if [ -r "${work_dir_urlhaus}/${db_file}" ] ; then
+          rm -f "${work_dir_urlhaus}/${db_file}"
+          do_clamd_reload="1"
+        fi
+        if [ -r "${clam_dbs}/${db_file}" ] ; then
+          rm -f "${clam_dbs}/${db_file}"
+          do_clamd_reload=1
+        fi
+      done
     fi
   fi
 fi
 
 ##############################################################################################################################################
     fi
   fi
 fi
 
 ##############################################################################################################################################
-# Check for updated yararulesproject database files every set number of hours as defined in the "USER CONFIGURATION" section of this script 
+# Check for updated yararulesproject database files every set number of hours as defined in the "USER CONFIGURATION" section of this script
 ##############################################################################################################################################
 if [ "$yararulesproject_enabled" == "yes" ] ; then
 ##############################################################################################################################################
 if [ "$yararulesproject_enabled" == "yes" ] ; then
-  if [ -n "$yararulesproject_dbs" ] ; then
-    if [ "$(xshok_array_count "$yararulesproject_dbs")" -lt "1" ] ; then
+  if [ -n "${yararulesproject_dbs[0]}" ] ; then
+    if [ ${#yararulesproject_dbs} -lt 1 ] ; then
       xshok_pretty_echo_and_log "Failed yararulesproject_dbs config is invalid or not defined - SKIPPING"
     else
       xshok_pretty_echo_and_log "Failed yararulesproject_dbs config is invalid or not defined - SKIPPING"
     else
-    rm -f "$work_dir_yararulesproject/*.gz"
-    if [ -r "$work_dir_work_configs/last-yararulesproject-update.txt" ] ; then
-      last_yararulesproject_update=$(cat "$work_dir_work_configs/last-yararulesproject-update.txt")
-    else
-      last_yararulesproject_update="0"
-    fi
-    db_file=""
-    loop=""
-    update_interval=$((yararulesproject_update_hours * 3600))
-    time_interval=$((current_time - last_yararulesproject_update))
-    if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
-      echo "$current_time" > "$work_dir_work_configs/last-yararulesproject-update.txt"
-
-      xshok_pretty_echo_and_log "Yara-Rules Database File Updates" "="
-      xshok_pretty_echo_and_log "Checking for yararulesproject updates..."
-      yararulesproject_updates="0"
-      for db_file in $yararulesproject_dbs ; do
-        if echo "$db_file" | $grep_bin -q "/"; then
-          yr_dir="/"$(echo "$db_file" | cut -d"/" -f1)
-          db_file=$(echo "$db_file" | cut -d"/" -f2)
-        else yr_dir=""
-        fi
-        if [ "$loop" = "1" ] ; then
-          xshok_pretty_echo_and_log "---"      
-        fi
-        xshok_pretty_echo_and_log "Checking for updated yararulesproject database file: $db_file"
-
-        yararulesproject_db_update="0"
-          if [ "$wget_bin" != "" ] ; then
-            $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_yararulesproject/$db_file" "$yararulesproject_url/$yr_dir/$db_file"
-            ret="$?"
-          else
-            $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_yararulesproject/$db_file" "$yararulesproject_url/$yr_dir/$db_file"
-            ret="$?"
+      rm -f "${work_dir_yararulesproject}/*.gz"
+      if [ -r "${work_dir_work_configs}/last-yararulesproject-update.txt" ] ; then
+        last_yararulesproject_update="$(cat "${work_dir_work_configs}/last-yararulesproject-update.txt")"
+      else
+        last_yararulesproject_update="0"
+      fi
+      db_file=""
+      loop=""
+      update_interval="$((yararulesproject_update_hours * 3600))"
+      time_interval="$((current_time - last_yararulesproject_update))"
+      if [ "$time_interval" -ge "$((update_interval - 600))" ] ; then
+        echo "$current_time" > "${work_dir_work_configs}/last-yararulesproject-update.txt"
+
+        xshok_pretty_echo_and_log "Yara-Rules Database File Updates" "="
+        xshok_pretty_echo_and_log "Checking for yararulesproject updates..."
+        yararulesproject_updates="0"
+        for db_file in "${yararulesproject_dbs[@]}" ; do
+          if echo "$db_file" | $grep_bin -q "/" ; then
+            yr_dir="/$(echo "$db_file" | cut -d "/" -f 1)"
+            db_file="$(echo "$db_file" | cut -d "/" -f 2)"
+          else yr_dir=""
           fi
           fi
-          if [ "$ret" -eq "0" ] ; then
-          loop="1"
-          if ! cmp -s "$work_dir_yararulesproject/$db_file" "$clam_dbs/$db_file" ; then
-            if [ "$?" -eq "0" ] ; then
-              db_ext=$(echo "$db_file" | cut -d "." -f2)
-
-              xshok_pretty_echo_and_log "Testing updated yararulesproject database file: $db_file"
+          if [ "$loop" == "1" ] ; then
+            xshok_pretty_echo_and_log "---"
+          fi
+          xshok_pretty_echo_and_log "Checking for updated yararulesproject database file: ${db_file}"
+          yararulesproject_db_update="0"
+          if xshok_file_download "${work_dir_yararulesproject}/${db_file}" "$yararulesproject_url/$yr_dir/${db_file}" ; then
+            loop="1"
+            if ! cmp -s "${work_dir_yararulesproject}/${db_file}" "${clam_dbs}/${db_file}" ; then
+              db_ext="${db_file#*.}"
+              xshok_pretty_echo_and_log "Testing updated yararulesproject database file: ${db_file}"
               if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
               if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
-                if $clamscan_bin --quiet -d "$work_dir_yararulesproject/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null
-                  then
-                  xshok_pretty_echo_and_log "Clamscan reports yararulesproject $db_file database integrity tested good"
+                if $clamscan_bin --quiet -d "${work_dir_yararulesproject}/${db_file}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                  xshok_pretty_echo_and_log "Clamscan reports yararulesproject ${db_file} database integrity tested good"
                   true
                 else
                   true
                 else
-                  xshok_pretty_echo_and_log "Clamscan reports yararulesproject $db_file database integrity tested BAD"
+                  xshok_pretty_echo_and_log "Clamscan reports yararulesproject ${db_file} database integrity tested BAD"
                   if [ "$remove_bad_database" == "yes" ] ; then
                   if [ "$remove_bad_database" == "yes" ] ; then
-                    if rm -f "$work_dir_yararulesproject/$db_file" ; then
-                      xshok_pretty_echo_and_log "Removed invalid database: $work_dir_yararulesproject/$db_file"
+                    if rm -f "${work_dir_yararulesproject}/${db_file}" ; then
+                      xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_yararulesproject}/${db_file}"
                     fi
                   fi
                   false
                     fi
                   fi
                   false
-                fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$work_dir_yararulesproject/$db_file" "$clam_dbs" 2>/dev/null ; then
-                perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
-                if [ "$selinux_fixes" == "yes" ] ; then
-                  restorecon "$clam_dbs/$db_file"
+                  fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${db_file}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${work_dir_yararulesproject}/${db_file}" "$clam_dbs" 2>&13 ; then
+                  perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
+                  if [ "$selinux_fixes" == "yes" ] ; then
+                    restorecon "${clam_dbs}/${db_file}"
+                  fi
+                  xshok_pretty_echo_and_log "Successfully updated yararulesproject production database file: ${db_file}"
+                  yararulesproject_updates=1
+                  yararulesproject_db_update=1
+                  do_clamd_reload=1
+                else
+                  xshok_pretty_echo_and_log "Failed to successfully update yararulesproject production database file: ${db_file} - SKIPPING"
                 fi
                 fi
-                xshok_pretty_echo_and_log "Successfully updated yararulesproject production database file: $db_file"
-                yararulesproject_updates=1
-                yararulesproject_db_update=1
-                do_clamd_reload=1
-              else
-                xshok_pretty_echo_and_log "Failed to successfully update yararulesproject production database file: $db_file - SKIPPING"
-              fi
-            else
-              $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$work_dir_yararulesproject/$db_file" > "$test_dir/$db_file"
-              $clamscan_bin --infected --no-summary -d "$test_dir/$db_file" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "$work_dir_work_configs/whitelist.txt"
-              $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir/$db_file" | cut -d "*" -f2 | sort | uniq >> "$work_dir_work_configs/whitelist.hex"
-              $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$test_dir/$db_file" > "$test_dir/$db_file-tmp"
-              mv -f "$test_dir/$db_file-tmp" "$test_dir/$db_file"
-              if $clamscan_bin --quiet -d "$test_dir/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
-                xshok_pretty_echo_and_log "Clamscan reports yararulesproject $db_file database integrity tested good"
-                true
               else
               else
-                xshok_pretty_echo_and_log "Clamscan reports yararulesproject $db_file database integrity tested BAD"
-                if [ "$remove_bad_database" == "yes" ] ; then
-                  if rm -f "$work_dir_yararulesproject/$db_file" ; then
-                    xshok_pretty_echo_and_log "Removed invalid database: $work_dir_yararulesproject/$db_file"
+                $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${work_dir_yararulesproject}/${db_file}" > "${test_dir}/${db_file}"
+                $clamscan_bin --infected --no-summary -d "${test_dir}/${db_file}" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "${work_dir_work_configs}/whitelist.txt"
+                $grep_bin -h -f "${work_dir_work_configs}/whitelist.txt" "${test_dir}/${db_file}" | cut -d "*" -f 2 | sort | uniq >> "${work_dir_work_configs}/whitelist.hex"
+                $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${test_dir}/${db_file}" > "${test_dir}/${db_file}-tmp"
+                mv -f "${test_dir}/${db_file}-tmp" "${test_dir}/${db_file}"
+                if $clamscan_bin --quiet -d "${test_dir}/${db_file}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                  xshok_pretty_echo_and_log "Clamscan reports yararulesproject ${db_file} database integrity tested good"
+                  true
+                else
+                  xshok_pretty_echo_and_log "Clamscan reports yararulesproject ${db_file} database integrity tested BAD"
+                  if [ "$remove_bad_database" == "yes" ] ; then
+                    if rm -f "${work_dir_yararulesproject}/${db_file}" ; then
+                      xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_yararulesproject}/${db_file}"
+                    fi
                   fi
                   fi
+                  false
+                  fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${db_file}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${test_dir}/${db_file}" "$clam_dbs" 2>&13 ; then
+                  perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
+                  if [ "$selinux_fixes" == "yes" ] ; then
+                    restorecon "${clam_dbs}/${db_file}"
+                  fi
+                  xshok_pretty_echo_and_log "Successfully updated yararulesproject production database file: ${db_file}"
+                  yararulesproject_updates=1
+                  yararulesproject_db_update=1
+                  do_clamd_reload=1
+                else
+                  xshok_pretty_echo_and_log "Failed to successfully update yararulesproject production database file: ${db_file} - SKIPPING"
                 fi
                 fi
-                false
-              fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$test_dir/$db_file" "$clam_dbs" 2>/dev/null ; then
-              perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
-              if [ "$selinux_fixes" == "yes" ] ; then
-                restorecon "$clam_dbs/$db_file"
               fi
               fi
-              xshok_pretty_echo_and_log "Successfully updated yararulesproject production database file: $db_file"
-              yararulesproject_updates=1
-              yararulesproject_db_update=1
-              do_clamd_reload=1
-            else
-              xshok_pretty_echo_and_log "Failed to successfully update yararulesproject production database file: $db_file - SKIPPING"
+
             fi
             fi
+          else
+            xshok_pretty_echo_and_log "WARNING: Failed connection to $yararulesproject_url - SKIPPED yararulesproject ${db_file} update"
           fi
           fi
+          if [ "$yararulesproject_db_update" != "1" ] ; then
+            xshok_pretty_echo_and_log "No updated yararulesproject ${db_file} database file found"
+          fi
+        done
+        if [ "$yararulesproject_updates" != "1" ] ; then
+          xshok_pretty_echo_and_log "No yararulesproject database file updates found" "-"
         fi
         fi
+      else
+
+        xshok_pretty_echo_and_log "Yara-Rules Database File Updates" "="
+        xshok_draw_time_remaining "$((update_interval - time_interval))" "$yararulesproject_update_hours" "yararulesproject"
       fi
       fi
-    else
-      xshok_pretty_echo_and_log "WARNING: Failed connection to $yararulesproject_url - SKIPPED yararulesproject $db_file update"
-    fi
-    if [ "$yararulesproject_db_update" != "1" ] ; then
-      xshok_pretty_echo_and_log "No updated yararulesproject $db_file database file found"
     fi
     fi
-  done
-  if [ "$yararulesproject_updates" != "1" ] ; then
-    xshok_pretty_echo_and_log "No yararulesproject database file updates found" "-"
   fi
 else
   fi
 else
-
-  xshok_pretty_echo_and_log "Yara-Rules Database File Updates" "="
-
-  time_remaining=$((update_interval - time_interval))
-  hours_left=$((time_remaining / 3600))
-  minutes_left=$((time_remaining % 3600 / 60))
-  xshok_pretty_echo_and_log "$yararulesproject_update_hours hours have not yet elapsed since the last yararulesproject database update check"
-  xshok_pretty_echo_and_log "No update check was performed at this time" "-"
-  xshok_pretty_echo_and_log "Next check will be performed in approximately $hours_left hour(s), $minutes_left minute(s)"
-fi
-fi
-fi
-else
-  if [ -n "$yararulesproject_dbs" ] ; then
+  if [ -n "${yararulesproject_dbs[0]}" ] ; then
     if [ "$remove_disabled_databases" == "yes" ] ; then
       xshok_pretty_echo_and_log "Removing disabled yararulesproject Database files"
     if [ "$remove_disabled_databases" == "yes" ] ; then
       xshok_pretty_echo_and_log "Removing disabled yararulesproject Database files"
-      for db_file in $yararulesproject_dbs ; do
-        if echo "$db_file" | $grep_bin -q "/"; then
-          db_file=$(echo "$db_file" | cut -d"/" -f2)
+      for db_file in "${yararulesproject_dbs[@]}" ; do
+        if echo "$db_file" | $grep_bin -q "/" ; then
+          db_file="$(echo "$db_file" | cut -d "/" -f 2)"
         fi
         fi
-        if [ -r "$work_dir_yararulesproject/$db_file" ] ; then
-          rm -f "$work_dir_yararulesproject/$db_file"
-          do_clamd_reload=1
+        if echo "$db_file" | $grep_bin -q "|" ; then
+          db_file="${db_file%|*}"
+        fi
+        if [ -r "${work_dir_yararulesproject}/${db_file}" ] ; then
+          rm -f "${work_dir_yararulesproject}/${db_file}"
+          do_clamd_reload="1"
         fi
         fi
-        if [ -r "$clam_dbs/$db_file" ] ; then
-          rm -f "$clam_dbs/$db_file"
+        if [ -r "${clam_dbs}/${db_file}" ] ; then
+          rm -f "${clam_dbs}/${db_file}"
           do_clamd_reload=1
         fi
       done
           do_clamd_reload=1
         fi
       done
@@ -2769,161 +3352,157 @@ else
 fi
 
 ##############################################################################################################################################
 fi
 
 ##############################################################################################################################################
-# Check for updated additional database files every set number of hours as defined in the "USER CONFIGURATION" section of this script 
+# Check for updated additional database files every set number of hours as defined in the "USER CONFIGURATION" section of this script
 ##############################################################################################################################################
 if [ "$additional_enabled" == "yes" ] ; then
   if [ -n "$additional_dbs" ] ; then
 ##############################################################################################################################################
 if [ "$additional_enabled" == "yes" ] ; then
   if [ -n "$additional_dbs" ] ; then
-    if [ "$(xshok_array_count "$additional_dbs")" -lt "1" ] ; then
+    if [ ${#additional_dbs} -lt 1 ] ; then
       xshok_pretty_echo_and_log "Failed additional_dbs config is invalid or not defined - SKIPPING"
     else
       xshok_pretty_echo_and_log "Failed additional_dbs config is invalid or not defined - SKIPPING"
     else
-    rm -f "$work_dir_add/*.gz"
-    if [ -r "$work_dir_work_configs/last-additional-update.txt" ] ; then
-      last_additional_update=$(cat "$work_dir_work_configs/last-additional-update.txt")
-    else
-      last_additional_update="0"
-    fi
-    db_file=""
-    loop=""
-    update_interval=$((additional_update_hours * 3600))
-    time_interval=$((current_time - last_additional_update))
-    if [ "$time_interval" -ge $((update_interval - 600)) ] ; then
-      echo "$current_time" > "$work_dir_work_configs/last-additional-update.txt"
-
-      xshok_pretty_echo_and_log "Additional Database File Updates" "="
-      xshok_pretty_echo_and_log "Checking for additional updates..."
-      additional_updates="0"
-      for db_url in $additional_dbs ; do
-        # left for future dir manipulation       
-        # if echo "$db_file" | $grep_bin -q "/"; then
-        #   add_dir="/"$(echo "$db_file" | cut -d"/" -f1)
-        #   db_file=$(echo "$db_file" | cut -d"/" -f2)
-        # else 
-        #   add_dir=""
-        # fi
-       db_file=$(basename "$db_url")
-
-        if [ "$loop" = "1" ] ; then
-          xshok_pretty_echo_and_log "---"      
-        fi
-        xshok_pretty_echo_and_log "Checking for updated additional database file: $db_file"
+      rm -f "${work_dir_add}/*.gz"
+      if [ -r "${work_dir_work_configs}/last-additional-update.txt" ] ; then
+        last_additional_update="$(cat "${work_dir_work_configs}/last-additional-update.txt")"
+      else
+        last_additional_update="0"
+      fi
+      db_file=""
+      loop=""
+      update_interval="$((additional_update_hours * 3600))"
+      time_interval="$((current_time - last_additional_update))"
+      if [ "$time_interval" -ge "$((update_interval - 600))" ] ; then
+        echo "$current_time" > "${work_dir_work_configs}/last-additional-update.txt"
+
+        xshok_pretty_echo_and_log "Additional Database File Updates" "="
+        xshok_pretty_echo_and_log "Checking for additional updates..."
+        additional_updates="0"
+        for db_url in "${additional_dbs[@]}" ; do
+          # Left for future dir manipulation
+          # if echo "$db_file" | $grep_bin -q "/" ; then
+          #   add_dir="/$(echo "$db_file" | cut -d "/" -f 1)"
+          #   db_file="$(echo "$db_file" | cut -d "/" -f 2)"
+          # else
+          #   add_dir=""
+          # fi
+
+          #cleanup any leading and trailing whitespace.
+          db_url="$(echo -e "$db_url" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
+
+          db_file="$(basename "$db_url")"
+
+          if [ "$loop" == "1" ] ; then
+            xshok_pretty_echo_and_log "---"
+          fi
+          xshok_pretty_echo_and_log "Checking for updated additional database file: ${db_file}"
 
 
-        additional_db_update="0"
+          additional_db_update="0"
 
 
-        if [ "$(echo "$db_url" | cut -d ":" -f1)" = "rsync" ] ; then
-          $rsync_bin $rsync_output_level $no_motd -ctuz $connect_timeout --timeout="$rsync_max_time" --exclude=*.txt --exclude=*.sha256 --exclude=*.sig --exclude=*.gz "$db_url" "$work_dir_add" 2>/dev/null
-          ret="$?"
-        else
-          if [ "$wget_bin" != "" ] ; then
-            $wget_bin $wget_proxy_https $wget_proxy_http $wget_insecure $wget_output_level --connect-timeout="$downloader_connect_timeout" --random-wait --tries="$downloader_tries" --timeout="$downloader_max_time" --output-document="$work_dir_add/$db_file" "$db_url"
+          if [ "${db_url%:*}" == "rsync" ] ; then
+            # shellcheck disable=SC2086
+            $rsync_bin $rsync_output_level $no_motd -ctuz $connect_timeout --timeout="$rsync_max_time" --exclude=*.txt --exclude=*.sha256 --exclude=*.sig --exclude=*.gz "$db_url" "$work_dir_add" 2>&13
             ret="$?"
           else
             ret="$?"
           else
-            $curl_bin $curl_proxy $curl_insecure $curl_output_level --connect-timeout "$downloader_connect_timeout" --remote-time --location --retry "$downloader_tries" --max-time "$downloader_max_time" --output "$work_dir_add/$db_file" "$db_url"
+            xshok_file_download "${work_dir_add}/${db_file}" "$db_url"
             ret="$?"
           fi
             ret="$?"
           fi
-        fi
-
-        ##this needs enhancement for rsync, as it will only work with single files... maybe better to process each file inside work_dir_add in its own for loop.
-        if [ "$ret" -eq "0" ] ; then
-          loop="1"
-          if ! cmp -s "$work_dir_add/$db_file" "$clam_dbs/$db_file" ; then
-            if [ "$?" -eq "0" ] ; then
-              db_ext=$(echo "$db_file" | cut -d "." -f2)
 
 
-              xshok_pretty_echo_and_log "Testing updated additional database file: $db_file"
+          # This needs enhancement for rsync, as it will only work with single files...
+          # Maybe better to process each file inside work_dir_add in its own for loop.
+          if [ "$ret" -eq 0 ] ; then
+            loop="1"
+            if ! cmp -s "${work_dir_add}/${db_file}" "${clam_dbs}/${db_file}" ; then
+              db_ext="${db_file#*.}"
+              xshok_pretty_echo_and_log "Testing updated additional database file: ${db_file}"
               if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
               if [ -z "$ham_dir" ] || [ "$db_ext" != "ndb" ] ; then
-                if $clamscan_bin --quiet -d "$work_dir_add/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null
-                  then
-                  xshok_pretty_echo_and_log "Clamscan reports additional $db_file database integrity tested good"
+                if $clamscan_bin --quiet -d "${work_dir_add}/${db_file}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                  xshok_pretty_echo_and_log "Clamscan reports additional ${db_file} database integrity tested good"
                   true
                 else
                   true
                 else
-                  xshok_pretty_echo_and_log "Clamscan reports additional $db_file database integrity tested BAD"
+                  xshok_pretty_echo_and_log "Clamscan reports additional ${db_file} database integrity tested BAD"
                   if [ "$remove_bad_database" == "yes" ] ; then
                   if [ "$remove_bad_database" == "yes" ] ; then
-                    if rm -f "$work_dir_add/$db_file" ; then
-                      xshok_pretty_echo_and_log "Removed invalid database: $work_dir_add/$db_file"
+                    if rm -f "${work_dir_add}/${db_file}" ; then
+                      xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_add}/${db_file}"
                     fi
                   fi
                   false
                     fi
                   fi
                   false
-                fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$work_dir_add/$db_file" "$clam_dbs" 2>/dev/null ; then
-                perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
-                if [ "$selinux_fixes" == "yes" ] ; then
-                  restorecon "$clam_dbs/$db_file"
+                  fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${db_file}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${work_dir_add}/${db_file}" "$clam_dbs" 2>&13 ; then
+                  perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
+                  if [ "$selinux_fixes" == "yes" ] ; then
+                    restorecon "${clam_dbs}/${db_file}"
+                  fi
+                  xshok_pretty_echo_and_log "Successfully updated additional production database file: ${db_file}"
+                  additional_updates=1
+                  additional_db_update=1
+                  do_clamd_reload=1
+                else
+                  xshok_pretty_echo_and_log "Failed to successfully update additional production database file: ${db_file} - SKIPPING"
                 fi
                 fi
-                xshok_pretty_echo_and_log "Successfully updated additional production database file: $db_file"
-                additional_updates=1
-                additional_db_update=1
-                do_clamd_reload=1
               else
               else
-                xshok_pretty_echo_and_log "Failed to successfully update additional production database file: $db_file - SKIPPING"
-              fi
-            else
-              $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$work_dir_add/$db_file" > "$test_dir/$db_file"
-              $clamscan_bin --infected --no-summary -d "$test_dir/$db_file" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "$work_dir_work_configs/whitelist.txt"
-              $grep_bin -h -f "$work_dir_work_configs/whitelist.txt" "$test_dir/$db_file" | cut -d "*" -f2 | sort | uniq >> "$work_dir_work_configs/whitelist.hex"
-              $grep_bin -h -v -f "$work_dir_work_configs/whitelist.hex" "$test_dir/$db_file" > "$test_dir/$db_file-tmp"
-              mv -f "$test_dir/$db_file-tmp" "$test_dir/$db_file"
-              if $clamscan_bin --quiet -d "$test_dir/$db_file" "$work_dir_work_configs/scan-test.txt" 2>/dev/null ; then
-                xshok_pretty_echo_and_log "Clamscan reports additional $db_file database integrity tested good"
-                true
-              else
-                xshok_pretty_echo_and_log "Clamscan reports additional $db_file database integrity tested BAD"
-                if [ "$remove_bad_database" == "yes" ] ; then
-                  if rm -f "$work_dir_add/$db_file" ; then
-                    xshok_pretty_echo_and_log "Removed invalid database: $work_dir_add/$db_file"
+                $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${work_dir_add}/${db_file}" > "${test_dir}/${db_file}"
+                $clamscan_bin --infected --no-summary -d "${test_dir}/${db_file}" "$ham_dir"/* | command sed 's/\.UNOFFICIAL FOUND//' | awk '{print $NF}' > "${work_dir_work_configs}/whitelist.txt"
+                if [[ "${work_dir_add}/${db_file}" == *.db ]] ; then
+                  $grep_bin -h -f "${work_dir_work_configs}/whitelist.hex" "${test_dir}/${db_file}" | cut -d "=" -f 2 | awk '{ printf("=%s\n", $1);}' |sort | uniq >> "${work_dir_work_configs}/whitelist.hex-tmp"
+                  mv -f "${work_dir_work_configs}/whitelist.hex-tmp" "${work_dir_work_configs}/whitelist.hex"
+                else
+                  $grep_bin -h -f "${work_dir_work_configs}/whitelist.hex" "${test_dir}/${db_file}" | cut -d "=" -f 2 | sort | uniq >> "${work_dir_work_configs}/whitelist.hex-tmp"
+                  mv -f "${work_dir_work_configs}/whitelist.hex-tmp" "${work_dir_work_configs}/whitelist.hex"
+                fi
+                $grep_bin -h -v -f "${work_dir_work_configs}/whitelist.hex" "${test_dir}/${db_file}" > "${test_dir}/${db_file}-tmp"
+                mv -f "${test_dir}/${db_file}-tmp" "${test_dir}/${db_file}"
+                if $clamscan_bin --quiet -d "${test_dir}/${db_file}" "${work_dir_work_configs}/scan-test.txt" 2>&10 ; then
+                  xshok_pretty_echo_and_log "Clamscan reports additional ${db_file} database integrity tested good"
+                  true
+                else
+                  xshok_pretty_echo_and_log "Clamscan reports additional ${db_file} database integrity tested BAD"
+                  if [ "$remove_bad_database" == "yes" ] ; then
+                    if rm -f "${work_dir_add}/${db_file}" ; then
+                      xshok_pretty_echo_and_log "Removed invalid database: ${work_dir_add}/${db_file}"
+                    fi
                   fi
                   fi
+                  false
+                  fi && (test "$keep_db_backup" = "yes" && cp -f -p  "${clam_dbs}/${db_file}" "${clam_dbs}/${db}_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "${test_dir}/${db_file}" "$clam_dbs" 2>&13 ; then
+                  perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/${db_file}"
+                  if [ "$selinux_fixes" == "yes" ] ; then
+                    restorecon "${clam_dbs}/${db_file}"
+                  fi
+                  xshok_pretty_echo_and_log "Successfully updated additional production database file: ${db_file}"
+                  additional_updates=1
+                  additional_db_update=1
+                  do_clamd_reload=1
+                else
+                  xshok_pretty_echo_and_log "Failed to successfully update additional production database file: ${db_file} - SKIPPING"
                 fi
                 fi
-                false
-              fi && (test "$keep_db_backup" = "yes" && cp -f "$clam_dbs/$db_file" "$clam_dbs/$db_file-bak" 2>/dev/null ; true) && if $rsync_bin -pcqt "$test_dir/$db_file" "$clam_dbs" 2>/dev/null ; then
-              perms chown -f "$clam_user:$clam_group" "$clam_dbs/$db_file"
-              if [ "$selinux_fixes" == "yes" ] ; then
-                restorecon "$clam_dbs/$db_file"
               fi
               fi
-              xshok_pretty_echo_and_log "Successfully updated additional production database file: $db_file"
-              additional_updates=1
-              additional_db_update=1
-              do_clamd_reload=1
-            else
-              xshok_pretty_echo_and_log "Failed to successfully update additional production database file: $db_file - SKIPPING"
             fi
             fi
+          else
+            xshok_pretty_echo_and_log "WARNING: Failed connection to ${db_url} - SKIPPED additional ${db_file} update"
+          fi
+          if [ "$additional_db_update" != "1" ] ; then
+            xshok_pretty_echo_and_log "No updated additional ${db_file} database file found"
           fi
           fi
+        done
+        if [ "$additional_updates" != "1" ] ; then
+          xshok_pretty_echo_and_log "No additional database file updates found" "-"
         fi
         fi
+      else
+        xshok_pretty_echo_and_log "Additional Database File Updates" "="
+        xshok_draw_time_remaining "$((update_interval - time_interval))" "$additional_update_hours" "additionaldatabaseupdate"
       fi
       fi
-    else
-      xshok_pretty_echo_and_log "WARNING: Failed connection to $additional_url - SKIPPED additional $db_file update"
     fi
     fi
-    if [ "$additional_db_update" != "1" ] ; then
-      xshok_pretty_echo_and_log "No updated additional $db_file database file found"
-    fi
-  done
-  if [ "$additional_updates" != "1" ] ; then
-    xshok_pretty_echo_and_log "No additional database file updates found" "-"
   fi
 else
   fi
 else
-
-  xshok_pretty_echo_and_log "Additional Database File Updates" "="
-
-  time_remaining=$((update_interval - time_interval))
-  hours_left=$((time_remaining / 3600))
-  minutes_left=$((time_remaining % 3600 / 60))
-  xshok_pretty_echo_and_log "$additional_update_hours hours have not yet elapsed since the last additional database update check"
-  xshok_pretty_echo_and_log "No update check was performed at this time" "-"
-  xshok_pretty_echo_and_log "Next check will be performed in approximately $hours_left hour(s), $minutes_left minute(s)"
-fi
-fi
-fi
-else
   if [ -n "$additional_dbs" ] ; then
     if [ "$remove_disabled_databases" == "yes" ] ; then
       xshok_pretty_echo_and_log "Removing disabled additional Database files"
   if [ -n "$additional_dbs" ] ; then
     if [ "$remove_disabled_databases" == "yes" ] ; then
       xshok_pretty_echo_and_log "Removing disabled additional Database files"
-      for db_file in $additional_dbs ; do
-        if echo "$db_file" | $grep_bin -q "/"; then
-          db_file=$(echo "$db_file" | cut -d"/" -f2)
+      for db_file in "${additional_dbs[@]}" ; do
+        if echo "$db_file" | $grep_bin -q "/" ; then
+          db_file="$(echo "$db_file" | cut -d "/" -f 2)"
         fi
         fi
-        if [ -r "$work_dir_add/$db_file" ] ; then
-          rm -f "$work_dir_add/$db_file"
+        if [ -r "${work_dir_add}/${db_file}" ] ; then
+          rm -f "${work_dir_add}/${db_file}"
           do_clamd_reload=1
         fi
           do_clamd_reload=1
         fi
-        if [ -r "$clam_dbs/$db_file" ] ; then
-          rm -f "$clam_dbs/$db_file"
+        if [ -r "${clam_dbs}/${db_file}" ] ; then
+          rm -f "${clam_dbs}/${db_file}"
           do_clamd_reload=1
         fi
       done
           do_clamd_reload=1
         fi
       done
@@ -2936,48 +3515,46 @@ fi
 ###################################################
 # Check to see if the local.ign file exists, and if it does, check to see if any of the script
 # added bypass entries can be removed due to offending signature modifications or removals.
 ###################################################
 # Check to see if the local.ign file exists, and if it does, check to see if any of the script
 # added bypass entries can be removed due to offending signature modifications or removals.
-if [ -r "$clam_dbs/local.ign" ] && [ -s "$work_dir_work_configs/monitor-ign.txt" ] ; then
+if [ -r "${clam_dbs}/local.ign" ] && [ -s "${work_dir_work_configs}/monitor-ign.txt" ] ; then
   ign_updated=0
   cd "$clam_dbs" || exit
   ign_updated=0
   cd "$clam_dbs" || exit
-  cp -f local.ign "$work_dir_work_configs/local.ign"
-  cp -f "$work_dir_work_configs/monitor-ign.txt" "$work_dir_work_configs/monitor-ign-old.txt"
+  cp -f -p local.ign "${work_dir_work_configs}/local.ign"
+  cp -f -p "${work_dir_work_configs}/monitor-ign.txt" "${work_dir_work_configs}/monitor-ign-old.txt"
 
   xshok_pretty_echo_and_log "" "=" "80"
   while read -r entry ; do
 
   xshok_pretty_echo_and_log "" "=" "80"
   while read -r entry ; do
-    sig_file=$(echo "$entry" | tr -d "\r" | awk -F ":" '{print $1}')
-    sig_hex=$(echo "$entry" | tr -d "\r" | awk -F ":" '{print $NF}')
-    sig_name_old=$(echo "$entry" | tr -d "\r" | awk -F ":" '{print $3}')
-    sig_ign_old=$($grep_bin ":$sig_name_old" "$work_dir_work_configs/local.ign")
-    sig_old=$(echo "$entry" | tr -d "\r" | cut -d ":" -f3-)
-    sig_new=$($grep_bin -hwF ":$sig_hex" "$sig_file" | tr -d "\r" 2>/dev/null)
-    sig_mon_new=$($grep_bin -HwF -n ":$sig_hex" "$sig_file" | tr -d "\r")
+    sig_file="$(echo "$entry" | tr -d "\\r" | awk -F ":" '{print $1}')"
+    sig_hex="$(echo "$entry" | tr -d "\\r" | awk -F ":" '{print $NF}')"
+    sig_name_old="$(echo "$entry" | tr -d "\\r" | awk -F ":" '{print $3}')"
+    sig_ign_old="$($grep_bin ":$sig_name_old" "${work_dir_work_configs}/local.ign")"
+    sig_old="$(echo "$entry" | tr -d "\\r" | cut -d ":" -f 3-)"
+    sig_new="$($grep_bin -hwF ":$sig_hex" "$sig_file" | tr -d "\\r" 2>/dev/null)"
+    sig_mon_new="$($grep_bin -HwF -n ":$sig_hex" "$sig_file" | tr -d "\\r")"
     if [ -n "$sig_new" ] ; then
       if [ "$sig_old" != "$sig_new" ] || [ "$entry" != "$sig_mon_new" ] ; then
     if [ -n "$sig_new" ] ; then
       if [ "$sig_old" != "$sig_new" ] || [ "$entry" != "$sig_mon_new" ] ; then
-        sig_name_new=$(echo "$sig_new" | tr -d "\r" | awk -F ":" '{print $1}')
-        sig_ign_new=$(echo "$sig_mon_new" | cut -d ":" -f1-3)
-        perl -i -ne "print unless /$sig_ign_old/" "$work_dir_work_configs/monitor-ign.txt"
-        echo "$sig_mon_new" >> "$work_dir_work_configs/monitor-ign.txt"
-        perl -p -i -e "s/$sig_ign_old/$sig_ign_new/" "$work_dir_work_configs/local.ign"
-        xshok_pretty_echo_and_log "$sig_name_old hexadecimal signature is unchanged, however signature name and/or line placement"
-        xshok_pretty_echo_and_log "in $sig_file has changed to $sig_name_new - updated local.ign to reflect this change."
+        sig_name_new="$(echo "$sig_new" | tr -d "\\r" | awk -F ":" '{print $1}')"
+        sig_ign_new="$(echo "$sig_mon_new" | cut -d ":" -f 1-3)"
+        perl -i -ne "print unless /$sig_ign_old/" "${work_dir_work_configs}/monitor-ign.txt"
+        echo "$sig_mon_new" >> "${work_dir_work_configs}/monitor-ign.txt"
+        perl -p -i -e "s/$sig_ign_old/$sig_ign_new/" "${work_dir_work_configs}/local.ign"
+        xshok_pretty_echo_and_log "${sig_name_old} hexadecimal signature is unchanged, however signature name and/or line placement"
+        xshok_pretty_echo_and_log "in ${sig_file} has changed to ${sig_name_new} - updated local.ign to reflect this change."
         ign_updated=1
       fi
     else
         ign_updated=1
       fi
     else
-      perl -i -ne "print unless /$sig_ign_old/" "$work_dir_work_configs/monitor-ign.txt" "$work_dir_work_configs/local.ign"
+      perl -i -ne "print unless /$sig_ign_old/" "${work_dir_work_configs}/monitor-ign.txt" "${work_dir_work_configs}/local.ign"
 
 
-      xshok_pretty_echo_and_log "$sig_name_old signature has been removed from $sig_file, entry removed from local.ign."
+      xshok_pretty_echo_and_log "${sig_name_old} signature has been removed from ${sig_file}, entry removed from local.ign."
       ign_updated=1
     fi
       ign_updated=1
     fi
-  done < "$work_dir_work_configs/monitor-ign-old.txt"
-  if [ "$ign_updated" = "1" ] ; then
-    if $clamscan_bin --quiet -d "$work_dir_work_configs/local.ign" "$work_dir_work_configs/scan-test.txt"
-      then
-      if $rsync_bin -pcqt "$work_dir_work_configs/local.ign" "$clam_dbs"
-        then
-        perms chown -f "$clam_user:$clam_group" "$clam_dbs/local.ign"
-        perms chmod -f 0644 "$clam_dbs/local.ign" "$work_dir_work_configs/monitor-ign.txt"
+  done < "${work_dir_work_configs}/monitor-ign-old.txt"
+  if [ "$ign_updated" == "1" ] ; then
+    if $clamscan_bin --quiet -d "${work_dir_work_configs}/local.ign" "${work_dir_work_configs}/scan-test.txt" ; then
+      if $rsync_bin -pcqt "${work_dir_work_configs}/local.ign" "$clam_dbs" ; then
+        perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/local.ign"
+        perms chmod -f 0644 "${clam_dbs}/local.ign" "${work_dir_work_configs}/monitor-ign.txt"
         if [ "$selinux_fixes" == "yes" ] ; then
         if [ "$selinux_fixes" == "yes" ] ; then
-          restorecon "$clam_dbs/local.ign"
+          restorecon "${clam_dbs}/local.ign"
         fi
         do_clamd_reload=3
       else
         fi
         do_clamd_reload=3
       else
@@ -2993,39 +3570,39 @@ fi
 
 # Check to see if my-whitelist.ign2 file exists, and if it does, check to see if any of the script
 # added whitelist entries can be removed due to offending signature modifications or removals.
 
 # Check to see if my-whitelist.ign2 file exists, and if it does, check to see if any of the script
 # added whitelist entries can be removed due to offending signature modifications or removals.
-if [ -r "$clam_dbs/my-whitelist.ign2" ] && [ -s "$work_dir_work_configs/tracker.txt" ] ; then
+if [ -r "${clam_dbs}/my-whitelist.ign2" ] && [ -s "${work_dir_work_configs}/tracker.txt" ] ; then
   ign2_updated=0
   cd "$clam_dbs" || exit
   ign2_updated=0
   cd "$clam_dbs" || exit
-  cp -f my-whitelist.ign2 "$work_dir_work_configs/my-whitelist.ign2"
+  cp -f -p my-whitelist.ign2 "${work_dir_work_configs}/my-whitelist.ign2"
 
   xshok_pretty_echo_and_log "" "=" "80"
 
   while read -r entry ; do
 
   xshok_pretty_echo_and_log "" "=" "80"
 
   while read -r entry ; do
-    sig_file=$(echo "$entry" | cut -d ":" -f1)
-    sig_full=$(echo "$entry" | cut -d ":" -f2-)
-    sig_name=$(echo "$entry" | cut -d ":" -f2)
+    sig_file="$(echo "$entry" | cut -d ":" -f 1)"
+    sig_full="$(echo "$entry" | cut -d ":" -f 2-)"
+    sig_name="$(echo "$entry" | cut -d ":" -f 2)"
     if ! $grep_bin -F "$sig_full" "$sig_file" > /dev/null 2>&1 ; then
     if ! $grep_bin -F "$sig_full" "$sig_file" > /dev/null 2>&1 ; then
-      perl -i -ne "print unless /$sig_name$/" "$work_dir_work_configs/my-whitelist.ign2"
-      perl -i -ne "print unless /:$sig_name:/" "$work_dir_work_configs/tracker-tmp.txt"
+      perl -i -ne "print unless /$sig_name$/" "${work_dir_work_configs}/my-whitelist.ign2"
+      perl -i -ne "print unless /:$sig_name:/" "${work_dir_work_configs}/tracker-tmp.txt"
 
 
-      xshok_pretty_echo_and_log "$sig_name signature no longer exists in $sig_file, whitelist entry removed from my-whitelist.ign2"
-      ign2_updated=1
+      xshok_pretty_echo_and_log "${sig_name} signature no longer exists in ${sig_file}, whitelist entry removed from my-whitelist.ign2"
+      ign2_updated="1"
     fi
     fi
-  done < "$work_dir_work_configs/tracker.txt"
-  mv -f "$work_dir_work_configs/tracker-tmp.txt" "$work_dir_work_configs/tracker.txt"
+  done < "${work_dir_work_configs}/tracker.txt"
+  if [ -f "${work_dir_work_configs}/tracker-tmp.txt" ] ; then
+    mv -f "${work_dir_work_configs}/tracker-tmp.txt" "${work_dir_work_configs}/tracker.txt"
+  fi
+
 
   xshok_pretty_echo_and_log "" "=" "80"
 
   xshok_pretty_echo_and_log "" "=" "80"
-  if [ "$ign2_updated" = "1" ]
-    then
-    if $clamscan_bin --quiet -d "$work_dir_work_configs/my-whitelist.ign2" "$work_dir_work_configs/scan-test.txt"
-      then
-      if $rsync_bin -pcqt "$work_dir_work_configs/my-whitelist.ign2" "$clam_dbs"
-        then
-        perms chown -f "$clam_user:$clam_group" "$clam_dbs/my-whitelist.ign2"
-        perms chmod -f 0644 "$clam_dbs/my-whitelist.ign2" "$work_dir_work_configs/tracker.txt"
+  if [ "$ign2_updated" == "1" ] ; then
+    if $clamscan_bin --quiet -d "${work_dir_work_configs}/my-whitelist.ign2" "${work_dir_work_configs}/scan-test.txt" ; then
+      if $rsync_bin -pcqt "${work_dir_work_configs}/my-whitelist.ign2" "$clam_dbs" ; then
+        perms chown -f "${clam_user}:${clam_group}" "${clam_dbs}/my-whitelist.ign2"
+        perms chmod -f 0644 "${clam_dbs}/my-whitelist.ign2" "${work_dir_work_configs}/tracker.txt"
         if [ "$selinux_fixes" == "yes" ] ; then
         if [ "$selinux_fixes" == "yes" ] ; then
-          restorecon "$clam_dbs/my-whitelist.ign2"
-          restorecon "$work_dir_work_configs/tracker.txt"
+          restorecon "${clam_dbs}/my-whitelist.ign2"
+          restorecon "${work_dir_work_configs}/tracker.txt"
         fi
         do_clamd_reload=4
       else
         fi
         do_clamd_reload=4
       else
@@ -3041,50 +3618,77 @@ fi
 
 # Check for non-matching whitelist.hex signatures and remove them from the whitelist file (signature modified or removed).
 if [ -n "$ham_dir" ] ; then
 
 # Check for non-matching whitelist.hex signatures and remove them from the whitelist file (signature modified or removed).
 if [ -n "$ham_dir" ] ; then
-  if [ -r "$work_dir_work_configs/whitelist.hex" ] ; then
-    $grep_bin -h -f "$work_dir_work_configs/whitelist.hex" "$work_dir"/*/*.ndb | cut -d "*" -f2 | tr -d "\r" | sort | uniq > "$work_dir_work_configs/whitelist.tmp"
-    mv -f "$work_dir_work_configs/whitelist.tmp" "$work_dir_work_configs/whitelist.hex"
-    rm -f "$work_dir_work_configs/whitelist.txt"
-    rm -f "$test_dir"/*.*
-    xshok_pretty_echo_and_log "WARNING: Signature(s) triggered on HAM directory scan - signature(s) removed" "*"
+  if [ -r "${work_dir_work_configs}/whitelist.hex" ] ; then
+    $grep_bin -h -f "${work_dir_work_configs}/whitelist.hex" "$work_dir"/*/*.ndb | cut -d "*" -f 2 | tr -d "\\r" | sort | uniq > "${work_dir_work_configs}/whitelist.tmp"
+    $grep_bin -h -f "${work_dir_work_configs}/whitelist.hex" "$work_dir"/*/*.db | cut -d "=" -f 2 | awk '{ printf("=%s\n", $1);}' | sort | uniq >> "${work_dir_work_configs}/whitelist.tmp"
+    mv -f "${work_dir_work_configs}/whitelist.tmp" "${work_dir_work_configs}/whitelist.hex"
+    rm -f "${work_dir_work_configs}/whitelist.txt"
+    rm -f "${test_dir}/*.*"
+    xshok_pretty_echo_and_log "WARNING: Signature(s) triggered on HAM directory scan - signature(s) removed"
   else
     xshok_pretty_echo_and_log "No signatures triggered on HAM directory scan" "="
   fi
 fi
   else
     xshok_pretty_echo_and_log "No signatures triggered on HAM directory scan" "="
   fi
 fi
-
 # Set appropriate directory and file permissions to all production signature files
 # and set file access mode to 0644 on all working directory files.
 
 # Set appropriate directory and file permissions to all production signature files
 # and set file access mode to 0644 on all working directory files.
 
-if [ "$setmode" = "yes" ] ; then
+if [ "$setmode" == "yes" ] ; then
   xshok_pretty_echo_and_log "Setting permissions and ownership" "="
   xshok_pretty_echo_and_log "Setting permissions and ownership" "="
-  perms chown -f -R "$clam_user:$clam_group" "$work_dir"
-  if ! find "$work_dir" -type f -exec chmod -f 0644 {} + 2>/dev/null ; then
+  perms chown -f -R "${clam_user}:${clam_group}" "$work_dir"
+  if ! find "$work_dir" -type f -exec chmod -f 0644 "{}" "+" 2>/dev/null ; then
     if ! find "$work_dir" -type f -print0 | xargs -0 chmod -f 0644 2>/dev/null ; then
     if ! find "$work_dir" -type f -print0 | xargs -0 chmod -f 0644 2>/dev/null ; then
-      if ! find "$work_dir" -type f -print0 | xargs chmod -f 0644 2>/dev/null ; then
-        find "$work_dir" -type f -exec chmod -f 0644 {} \;
-      fi
+      find "$work_dir" -type f -exec chmod -f 0644 "{}" ";"
     fi
   fi
 
     fi
   fi
 
-# If enabled, set file access mode for all production signature database files to 0644.
-  perms chown -f -R "$clam_user:$clam_group" "$clam_dbs"
-  if ! find "$clam_dbs" -type f -exec chmod -f 0644 {} + 2>/dev/null ; then
+  # If enabled, set file access mode for all production signature database files to 0644.
+  perms chown -f -R "${clam_user}:${clam_group}" "$clam_dbs"
+  if ! find "$clam_dbs" -type f -exec chmod -f 0644 "{}" "+" 2>/dev/null ; then
     if ! find "$clam_dbs" -type f -print0 | xargs -0 chmod -f 0644 2>/dev/null ; then
     if ! find "$clam_dbs" -type f -print0 | xargs -0 chmod -f 0644 2>/dev/null ; then
-      if ! find "$clam_dbs" -type f -print0 | xargs chmod -f 0644 2>/dev/null ; then
-        find "$clam_dbs" -type f -exec chmod -f 0644 {} \;
-      fi
+      find "$clam_dbs" -type f -exec chmod -f 0644 "{}" ";"
     fi
   fi
 fi
 
     fi
   fi
 fi
 
-# Reload all clamd databases  
+# Reload all clamd databases
 clamscan_reload_dbs
 
 xshok_pretty_echo_and_log "Issue tracker : https://github.com/extremeshok/clamav-unofficial-sigs/issues" "-"
 
 clamscan_reload_dbs
 
 xshok_pretty_echo_and_log "Issue tracker : https://github.com/extremeshok/clamav-unofficial-sigs/issues" "-"
 
-check_new_version
+if [ "$allow_update_checks" != "no" ] ; then
+
+       if [ -r "${work_dir_work_configs}/last-version-check.txt" ] ; then
+         last_version_check="$(cat "${work_dir_work_configs}/last-version-check.txt")"
+       else
+         last_version_check="0"
+       fi
+       db_file=""
+       update_check_interval="$((update_check_hours * 3600))"
+       time_interval="$((current_time - last_version_check))"
+       if [ "$time_interval" -ge $((update_check_interval - 600)) ] ; then
+         echo "$current_time" > "${work_dir_work_configs}/last-version-check.txt"
+               if xshok_is_root ; then
+                       perms chown -f "${clam_user}:${clam_group}" "${work_dir_work_configs}/last-version-check.txt"
+               fi              
+               check_new_version
+       fi
+
+fi
 
 xshok_cleanup
 
 
 xshok_cleanup
 
+# Set the permission of the log file, to fix any permission errors, this is done to fix cron errors after running the script as root.
+if xshok_is_root ; then
+       if [ "$enable_log" == "yes" ] ; then
+               # check if the file is owned by root (the current user)
+               if [ -O "${log_file_path}/${log_file_name}" ] ; then
+                       # checks the file is writable and a file (not a symlink/link)
+                       if [ -w "${log_file_path}/${log_file_name}" ] && [ -f "${log_file_path}/${log_file_name}" ] ; then
+                               perms chown -f "${clam_user}:${clam_group}" "${log_file_path}/${log_file_name}"
+                       fi
+               fi
+       fi
+fi
+
 # And lastly we exit, Note: the exit is always on the 2nd last line
 exit $?
 # And lastly we exit, Note: the exit is always on the 2nd last line
 exit $?