#!/bin/bash
#
# MailScanner Configuration script for RPM based systems
# 
# This script installs the required software for
# MailScanner via yum and CPAN based on user input.  
#
# Tested distributions:     CentOS 7,8,9 or equivalent
#                           Fedora 37
#
# Updated: 17 Feb 2023
# MailScanner Team <https://www.mailscanner.info>

# clear the screen. yay!
clear

# check for missing path to /usr/local/bin
if [[ !($PATH =~ /\/usr\/local\/bin/) ]]; then
  export PATH="$PATH:/usr/local/bin"
fi

# unattended configuration: command line parameter parsing
parsedCommands=0;
while [ $# -gt 0 ]; do
    case "$1" in
         --update)
            # Set update mode and move forward
            arg_MTA="none";
            arg_installClamav=0;
            arg_configClamav=0;
            arg_installCPAN=1;
            arg_ramdiskSize=0
            arg_installEPEL=0;
            arg_installPowerTools=0;
            arg_installTNEF=0;
            arg_installUnrar=0;
            arg_installidn=0;
            arg_SELPermissive=0;
            arg_update=1;
            ((parsedCommands++));
        ;;

        --MTA=*)
            case ${1#*=} in
            "sendmail")  arg_MTA="sendmail"; ((parsedCommands++));;
            "postfix")   arg_MTA="postfix"; ((parsedCommands++));;
            "exim")      arg_MTA="exim4-base"; ((parsedCommands++));;
            "none")      arg_MTA=; ((parsedCommands++));;
            *)
                printf "Error: Invalid value for MTA: select one of 'sendmail', 'postfix', 'exim' or 'none'.\n"
                exit 1
            esac
        ;;

        --installClamav=*)
            if [[ ${1#*=} =~ ^([yY])$ ]]; then
                arg_installClamav=1;
                ((parsedCommands++));
            elif [[ ${1#*=} =~ ^([nN])$ ]]; then
                arg_installClamav=0;
                ((parsedCommands++));
            else
                printf "Error: Invalid value for installClamav: only Y or N values are accepted.\n"
                exit 1
            fi
        ;;
        
        --configClamav=*)
            if [[ ${1#*=} =~ ^([yY])$ ]]; then
                arg_configClamav=1;
                ((parsedCommands++));
            elif [[ ${1#*=} =~ ^([nN])$ ]]; then
                arg_configClamav=0;
                ((parsedCommands++));
            else
                printf "Error: Invalid value for configClamav: only Y or N values are accepted.\n"
                exit 1
            fi
        ;;

        --installCPAN=*)
            if [[ ${1#*=} =~ ^([yY])$ ]]; then
                arg_installCPAN=1;
                ((parsedCommands++));
            elif [[ ${1#*=} =~ ^([nN])$ ]]; then
                arg_installCPAN=0;
                ((parsedCommands++));
            else
                printf "Error: Invalid value for installCPAN: only Y or N values are accepted.\n"
                exit 1
            fi
        ;;

        --ramdiskSize=*)
            if [[ ${1#*=} =~ ^-?[0-9]+$ ]]; then
                arg_ramdiskSize="${1#*=}";
                ((parsedCommands++));
            else
                printf "Error: Invalid value for ramdiskSize: only integer values are accepted.\n"
                exit 1
            fi
        ;;

        --installEPEL=*)
            if [[ ${1#*=} =~ ^([yY])$ ]]; then
                arg_installEPEL=1;
                ((parsedCommands++));
            elif [[ ${1#*=} =~ ^([nN])$ ]]; then
                arg_installEPEL=0;
                ((parsedCommands++));
            else
                printf "Error: Invalid value for installEPEL: only Y or N values are accepted.\n"
                exit 1
            fi
        ;;

         --installPowerTools=*)
            if [[ ${1#*=} =~ ^([yY])$ ]]; then
                arg_installPowerTools=1;
                ((parsedCommands++));
            elif [[ ${1#*=} =~ ^([nN])$ ]]; then
                arg_installPowerTools=0;
                ((parsedCommands++));
            else
                printf "Error: Invalid value for installPowerTools: only Y or N values are accepted.\n"
                exit 1
            fi
        ;;

        --installTNEF=*)
            if [[ ${1#*=} =~ ^([yY])$ ]]; then
                arg_installTNEF=1;
                ((parsedCommands++));
            elif [[ ${1#*=} =~ ^([nN])$ ]]; then
                arg_installTNEF=0;
                ((parsedCommands++));
            else
                printf "Error: Invalid value for installTNEF: only Y or N values are accepted.\n"
                exit 1
            fi
        ;;

        --installUnrar=*)
            if [[ ${1#*=} =~ ^([yY])$ ]]; then
                arg_installUnrar=1;
                ((parsedCommands++));
            elif [[ ${1#*=} =~ ^([nN])$ ]]; then
                arg_installUnrar=0;
                ((parsedCommands++));
            else
                printf "Error: Invalid value for installUnrar: only Y or N values are accepted.\n"
                exit 1
            fi
        ;;

        --installidn=*)
            if [[ ${1#*=} =~ ^([yY])$ ]]; then
                arg_installidn=1;
                ((parsedCommands++));
            elif [[ ${1#*=} =~ ^([nN])$ ]]; then
                arg_installidn=0;
                ((parsedCommands++));
            else
                printf "Error: Invalid value for installidn: only Y or N values are accepted.\n"
                exit 1
            fi
        ;;

        --SELPermissive=*)
            if [[ ${1#*=} =~ ^([yY])$ ]]; then
                arg_SELPermissive=1;
                ((parsedCommands++));
            elif [[ ${1#*=} =~ ^([nN])$ ]]; then
                arg_SELPermissive=0;
                ((parsedCommands++));
            else
                printf "Error: Invalid value for SELPermissive: only Y or N values are accepted.\n"
                exit 1
            fi
        ;;

        --help)
            printf "MailScanner Installation for Red Hat Based Systems\n\n"
            printf "Usage: %s [--update] [--MTA=sendmail|postfix|exim|none] [--installEPEL=Y|N] [--installClamav=Y|N] [--configClamav=Y|N] [--installTNEF=Y|N] [--installUnrar=Y|N] [--installCPAN=Y|N] [--installDf=Y|N] [--ignoreDeps=Y|N] [--SELPermissive=Y|N] [--ramdiskSize=value]\n\n" "$0"
            printf -- "--update              Perform an update on an existing install using the following options (can be overridden):\n"
            printf    "                        --MTA=none               (assumed already installed)\n"
            printf    "                        --installEPEL=N          (assumed already installed)\n"
            printf    "                        --installPowerTools=N    (assumed already installed)\n"
            printf    "                        --installClamav=N        (assumed already installed)\n"
            printf    "                        --configClamav=N         (assumed already installed)\n"
            printf    "                        --installTNEF=N          (assumed already installed)\n"
            printf    "                        --installUnrar=N         (assumed already installed)\n"
            printf    "                        --installCPAN=Y\n"
            printf    "                        --SELPermissive=N        (assumed already configured)\n"
            printf    "                        --ramdiskSize=0          (assumed already configured)\n\n"
            printf -- "--MTA=value             Select the Mail Transfer Agent (MTA) to be installed            (sendmail|postfix|exim|none)\n"
            printf    "                        Recommended: sendmail\n\n"
            printf -- "--installEPEL=Y|N       Install and use EPEL repository                                 (Y or N)\n"
            printf    "                        Recommended: Y (yes)\n\n"
            printf -- "--installPowerTools=Y|N Install and use PowerTools repository (CentOS/RHEL 8)           (Y or N)\n"
            printf    "                        Recommended: Y (yes)\n\n"
            printf -- "--installClamav=Y|N     Install or update ClamAV during installation (requires EPEL)    (Y or N)\n"
            printf    "                        Recommended: Y (yes)\n\n"
            printf -- "--configClamav=Y|N      Configure ClamAV                                                (Y or N)\n"
            printf    "                        Recommended: Y (yes)\n\n"
            printf -- "--installTNEF=Y|N       Install tnef via RPM                                            (Y or N)\n"
            printf    "                        Recommended: Y (yes)\n\n"
            printf -- "--installUnrar=Y|N      Install unrar via RPM                                           (Y or N)\n"
            printf    "                        Recommended: Y (yes)\n\n"
            printf -- "--installidn=Y|N        Install perl-Net-LibIDN via RPM (EL 9 Only)                     (Y or N)\n"
            printf    "                        Recommended: Y (yes)\n\n"
            printf -- "--installCPAN=Y|N       Install missing perl modules via CPAN                           (Y or N)\n"
            printf    "                        Recommended: Y (yes)\n\n"
            printf -- "--SELPermissive=Y|N     Set SELinux to Permissive mode                                  (Y or N)\n"
            printf    "                        Recommended: Y (yes)\n\n"
            printf -- "--ramdiskSize=value     Create a RAMDISK for incoming spool directory                   (integer value or 0 for none)\n"
            printf    "                        Suggestions:\n";
            printf    "                        None         0\n";
            printf    "                        Small        256\n";
            printf    "                        Medium       512\n";
            printf    "                        Large        1024 or 2048\n";
            printf    "                        Enterprise   4096 or 8192\n";
            exit 0
        ;;

        *)
            printf "Error: Invalid argument \"%s\".\n\n" "$1"
            printf "See help with %s --help\n" "$0"
            exit 1
    esac
    shift
done

# where i started for RPM install
THISCURRPMDIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )

# Function used to Wait for n seconds
timewait () {
    DELAY=$1
    sleep $DELAY
}

# Check for root user
if [ $(whoami) != "root" ]; then
    clear
    echo;
    echo "Configuration must be run as root. Aborting. Use 'su -' to switch to the root environment."; echo;
    exit 192
fi

# bail if yum is not installed
if [ ! -x '/usr/bin/yum' ]; then
    clear
    echo;
    echo "Yum package manager is not installed. You must install this before starting";
    echo "the MailScanner configuration process. Configuration aborted."; echo;
    exit 192
else
    YUM='/usr/bin/yum';
fi

# confirm the RHEL release is known before continuing
FEDORA=
RHEL=
if [ ! -f '/etc/redhat-release' ]; then
    # this is mostly to prevent accidental configuration on a non redhat based system
    echo "Unable to determine distribution release from /etc/redhat-release or /etc/fedora-release. Configuration aborted."; echo;
    exit 192
else
    # figure out what release is being used
    if grep -qs 'release 7' /etc/redhat-release ; then
            # RHEL 7
            RHEL=7
    elif grep -qs 'release 8' /etc/redhat-release ; then
            # RHEL 8
            RHEL=8
    elif grep -qs 'release 9' /etc/redhat-release ; then
            # RHEL 8
            RHEL=9
    else
            # No supported release match
            RHEL=0
    fi
fi

# maybe it is fedora

# Is this a Fedora System?
if [ -f /etc/fedora-release ]; then
    if grep -qs 'release 37' /etc/fedora-release ; then
        # Fedora 29
        FEDORA=37
        else
        # Unsupported release
        FEDORA=0
    fi
fi

# user info screen before the install process starts
echo "MailScanner Configuration for RPM Based Systems"; echo; echo;
echo "This will INSTALL or UPGRADE the required software for MailScanner on RPM based systems";
echo "via the Yum package manager. Supported distributions are CentOS 7,8,9 and associated";
echo "variants. Internet connectivity is required for"; 
echo "this configuration script to execute. "; echo;
echo;
echo "WARNING - Make a backup of any custom configuration files if upgrading - WARNING";
echo;
echo "To install SpamAssassin 4.0, an unprivileged user 'sabuild' will be created and granted";
echo "temporary sudo privileges. This is necessary to obtain a successful build. sudo privileges";
echo "will be removed after install, and you can optionally remove the 'sabuild' user at any time";
echo;
echo "You may press CTRL + C at any time to abort the configuration. Note that you may see";
echo "some errors during the perl module installation. You may safely ignore errors regarding";
echo "failed tests if you opt to use CPAN. You may also ignore 'No package available' notices";
echo "during the yum installation of packages."; echo;
if [ "$parsedCommands" -eq 0 ]; then
    echo "When you are ready to continue, press return ... ";
    read foobar
fi

# ask if the user wants an mta installed
clear
echo;
echo "Do you want to install a Mail Transfer Agent (MTA)?"; echo;
echo "I can install an MTA via the Yum package manager to save you the trouble of having to do";
echo "this later. If you plan on using an MTA that is not listed below, you will have install ";
echo "it manually yourself if you have not already done so.";
echo;
echo "1 - sendmail";
echo "2 - postfix";
echo "3 - exim";
echo "N - Do not install";
echo;
echo "Recommended: 1 (sendmail)"; echo;
if [ -z "${arg_MTA+x}" ]; then
    read -r -p "Install an MTA? [1] : " response
    if [[ $response =~ ^([nN][oO])$ ]]; then
        # do not install
        MTAOPTION=
    elif [ -z $response ]; then
        # sendmail default
        MTAOPTION="sendmail";
    elif [ $response -eq 1 ]; then
        # sendmail 
        MTAOPTION="sendmail";
    elif [ $response -eq 2 ]; then
        # sendmail 
        MTAOPTION="postfix";
    elif [ $response -eq 3 ]; then
        # sendmail 
        MTAOPTION="exim";
    else
        MTAOPTION=
    fi
else
    if [[ "${arg_MTA+x}" == "none" ]]; then
      MTAOPTION=
    else
      MTAOPTION=${arg_MTA};
    fi
fi

# no longer asking - just get spamassassin installed
SA=1
SAOPTION="spamassassin"

EPEL=0
EPELOPTION=
if [ -z $FEDORA ]; then
    # ask if the user wants to install EPEL
    clear
    echo;
    echo "Do you want to install EPEL? (Extra Packages for Enterprise Linux)"; echo;
    echo "Installing EPEL will make more yum packages available, such as extra perl modules"; 
    echo "and ClamAV, which is recommended. This will also reduce the number of Perl modules";
    echo "installed via CPAN. Note that EPEL is considered a third party repository. On RHEL 9, the CRB repository will also be enabled."; 
    echo;
    echo "Recommended: Y (yes)"; echo;
    if [ -z "${arg_installEPEL+x}" ]; then
        read -r -p "Install EPEL? [n/Y] : " response
        if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
            # user wants EPEL installed
            EPEL=1
            EPELOPTION="epel-release";
        elif [ -z $response ]; then    
            # user wants EPEL installed
            EPEL=1
            EPELOPTION="epel-release";
        else
            # user does not want EPEL
            EPEL=0
            EPELOPTION=
        fi
    else
        EPEL=${arg_installEPEL};
        if [ $EPEL -eq 1 ]; then
            EPELOPTION="epel-release";
        fi
    fi
fi


if [[ $RHEL -eq 8 ]]; then
    # ask if the user wants to install PowerTools
    clear
    echo;
    echo "Do you want to install RHEL PowerTools Repository?"; echo;
    echo "Installing PowerTools will make more yum packages available, such as re2c,"; 
    echo "which is recommended."; 
    echo;
    echo "Recommended: Y (yes)"; echo;
    if [ -z "${arg_installPowerTools+x}" ]; then
        read -r -p "Install PowerTools? [n/Y] : " response
        if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
            # user wants PowerTools installed
            POWERTOOLS=1
            POWERTOOLSOPTION="dnf-plugins-core";
        elif [ -z $response ]; then    
            POWERTOOLS=1
            POWERTOOLSOPTION="dnf-plugins-core";
        else
            POWERTOOLS=0
            POWERTOOLSOPTION="dnf-plugins-core";
        fi
    else
        POWERTOOLS=${arg_installPowerTools};
        if [ $POWERTOOLS -eq 1 ]; then
            POWERTOOLSOPTION="dnf-plugins-core";
        fi
    fi
fi

# ask if the user wants ClamAV installed if they selected EPEL
if [[ $EPEL -eq 1 || -n $FEDORA ]]; then
    clear
    echo;
    echo "Do you want to install or update ClamAV during this installation process?"; echo;
    echo "This package is recommended unless you plan on using a different virus scanner.";
    echo "Note that you may use more than one virus scanner at once with MailScanner.";
    echo;
    echo "Recommended: Y (yes)"; echo;
    if [ -z "${arg_installClamav+x}" ]; then
        read -r -p "Install or update ClamAV? [n/Y] : " response

        if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
            # user wants clam av installed
            # some of these options may result in a 'no package available' on
            # some distributions, but that is ok
            CAV=1
            CAVOPTION="clamav clamd clamav-update clamav-server clamav-devel";
        elif [ -z $response ]; then  
            CAV=1
            CAVOPTION="clamav clamd clamav-update clamav-server clamav-devel";
        else
            # user does not want clam av
            CAV=0
            CAVOPTION=
        fi
    else
        CAV=${arg_installClamav}
        CAVOPTION=
        if [ ${CAV} -eq 1 ]; then
            CAVOPTION="clamav clamd clamav-update clamav-server clamav-devel";
        fi
    fi
else
    # user did not select EPEL so clamav is not available via yum
    CAV=0
    CAVOPTION=
fi

# Check if clamav is being installed on CentOS/RHEL 7+ and ask if user wants to configure
if [[ $RHEL -ge 7 && $CAV -eq 1 ]]; then
    clear
    echo;
    echo "Do you want to configure clam AV during this installation process?"; echo;
    echo;
    echo "Choosing yes will install required configuration files and settings for";
    echo "ClamAV to function out of the box on CentOS/RHEL 7+ installations";
    echo;
    echo "Recommended: Y (yes)"; echo;
    if [ -z "${arg_configClamav+x}" ]; then
        read -r -p "Configure ClamAV? [n/Y] : " response

        if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
            # user wants clam av configured
            CONFCAV=1
        elif [ -z $response ]; then
            CONFCAV=1
        else
            CONFCAV=0
        fi
    fi
else
    # Not CentOS/RHEL7 or Clam not being installed/updated
    CONFCAV=0
fi

# ask if the user wants to install tnef by RPM if missing
TNEF="tnef";
TNEFOPTION=0
if [ -z $FEDORA ]; then
    clear
    echo;
    echo "Do you want to install tnef via RPM if missing?"; echo;
    echo "I will attempt to install tnef via the Yum Package Manager, but if not found I can ";
    echo "install this from an RPM provided by the MailScanner Community Project. Tnef allows";
    echo "MailScanner to handle Microsoft specific winmail.dat files.";
    echo;
    echo "Recommended: Y (yes)"; echo;
    if [ -z "${arg_installTNEF+x}" ]; then
        read -r -p "Install missing tnef via RPM? [n/Y] : " response

        if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
            # user wants to use RPM for missing tnef
            TNEFOPTION=1
        elif [ -z $response ]; then 
            # user wants to use RPM for missing tnef
            TNEFOPTION=1
        else
            # user does not want to use RPM
            TNEFOPTION=0
        fi
    else
        TNEFOPTION=${arg_installTNEF}
    fi
fi

if [ -z $FEDORA ]; then
    # ask if the user wants to install unrar by RPM if missing
    clear
    echo;
    echo "Do you want to install unrar via RPM if missing?"; echo;
    echo "I will attempt to install unrar via the Yum Package Manager, but if not found I can ";
    echo "install this from an RPM provided by MailScanner Community Project. unrar allows";
    echo "MailScanner to handle archives compressed with rar.";
    echo;
    echo "Recommended: Y (yes)"; echo;
    if [ -z "${arg_installUnrar+x}" ]; then
        read -r -p "Install missing unrar via RPM? [n/Y] : " response
        if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
            # user wants to use RPM for missing unrar
            UNRAROPTION=1
        elif [ -z $response ]; then 
            # user wants to use RPM for missing unrar
            UNRAROPTION=1
        else
            # user does not want to use RPM
            UNRAROPTION=0
        fi
    else
        UNRAROPTION=${arg_installUnrar}
    fi
fi

if [ $RHEL -eq 9 ]; then
    # ask if the user wants to install perl-Net-LibIDN by RPM if missing
    clear
    echo;
    echo "Do you want to install perl-Net-LibIDN via RPM if missing?"; echo;
    echo "I will attempt to install perl-Net-LibIDN via the Yum Package Manager, but if not found I can ";
    echo "install this from an RPM provided by MailScanner Community Project. perl-Net-LibIDN allows";
    echo "SpamAssassin to handle internationalized domain names.";
    echo;
    echo "Recommended: Y (yes)"; echo;
    if [ -z "${arg_installidn+x}" ]; then
        read -r -p "Install missing perl-Net-LibIDN via RPM? [n/Y] : " response
        if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
            # user wants to use RPM for missing perl-Net-LibIDN
            IDNOPTION=1
        elif [ -z $response ]; then 
            # user wants to use RPM for missing perl-Net-LibIDN
            IDNOPTION=1
        else
            # user does not want to use RPM
            IDNOPTION=0
        fi
    else
        IDNOPTION=${arg_installidn}
    fi
fi

# ask if the user wants missing modules installed via CPAN
clear
echo;
echo "Do you want to install missing perl modules via CPAN?"; echo;
echo "I will attempt to install Perl modules via yum, but some may not be unavailable during the";
echo "installation process. Missing modules will likely cause MailScanner to malfunction.";
echo;
echo "Recommended: Y (yes)"; echo;
if [ -z "${arg_installCPAN+x}" ]; then
    read -r -p "Install missing Perl modules via CPAN? [n/Y] : " response

    if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
        # user wants to use CPAN for missing modules
        CPANOPTION=1
    elif [ -z $response ]; then 
         # user wants to use CPAN for missing modules
        CPANOPTION=1
    else
        # user does not want to use CPAN
        CPANOPTION=0
    fi
fi

# ask about setting permissive mode for SeLinux
clear
echo;
echo "Set PERMISSIVE mode for SELinux?"; echo;
echo "SELinux will cause problems for virus scanners accessing the working directory";
echo "used when processing email. Enabling permissive mode will allow the virus scanner";
echo "to access the files that need to be scanned until you can create a policy to ";
echo "allow working directory file access while in ENFORCING mode. If you have already";
echo "disabled SELinux selecting 'yes' will not change that. Note that a reboot is ";
echo "required after the installation for this to take effect.";
echo;
echo "Recommended: Y (yes)"; echo;
if [ -z "${arg_SELPermissive+x}" ]; then
    read -r -p "Set permissive mode for SELinux? [n/Y] : " response

    if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]; then
        # user wants to set permissive mode
        SELMODE=1
    elif [ -z $response ]; then 
         # user wants to set permissive mode
        SELMODE=1
    else
        # user does not want to change SELinux
        SELMODE=0
    fi
else
    SELMODE=${arg_SELPermissive}
fi
# ask if the user wants to add a ramdisk
clear
echo;
echo "Do you want to create a RAMDISK?"; echo;
echo "This will create a mount in /etc/fstab that attaches the processing"; 
echo "directory /var/spool/MailScanner/incoming to a RAMDISK, which greatly"; 
echo "increases processing speed at the cost of the reservation of some of";
echo "the system RAM. The size depends on the number of MailScanner children,";
echo "the number of messages per batch, and incoming email volume."
echo;
echo "Specify a size in MB or leave blank for none.";
echo;
echo "Suggestions:";
echo "		None		0";
echo "		Small		256";
echo "		Medium		512";
echo " 		Large 		1024 or 2048";
echo " 		Enterprise	4096 or 8192";
echo;
echo "Example: 1024"; echo;
if [ -z "${arg_ramdiskSize+x}" ]; then
    read -r -p "Specify a RAMDISK size? [0] : " RAMDISKSIZE

    if [[ $RAMDISKSIZE =~ ^[0-9]+$ ]]; then
        if [ $RAMDISKSIZE -ne 0 ]; then
            # user wants ramdisk
            RAMDISK=1
        else
            RAMDISK=0
        fi
    else
        # no ramdisk
        RAMDISK=0
    fi
else
   if [ ${arg_ramdiskSize} -eq 0 ]; then
        # no ramdisk
        RAMDISK=0;
    else
        RAMDISK=1;
        RAMDISKSIZE=${arg_ramdiskSize};
    fi
fi

# base system packages
BASEPACKAGES="
            binutils            gcc             glibc-devel 
            libaio              make            man-pages 
            man-pages-overrides patch           rpm
            tar                 time            unzip
            which               zip             libtool-ltdl
            perl                curl            wget
            openssl             openssl-devel   bzip2-devel
            libmaxminddb-devel  libidn-devel    libidn2-devel
            pyzor               re2c            unrar
            tnef                p7zip           p7zip-plugins
            sudo
"

# Packages (maybe) available in the yum base of RHEL 7,8,9
# and EPEL. If the user elects not to use EPEL or if the 
# package is not available for their distro release it
# will be ignored during the install.
#
MOREPACKAGES="
            perl-Archive-Tar            perl-Archive-Zip            perl-bignum
            perl-Carp                   perl-Compress-Zlib          perl-Compress-Raw-Zlib
            perl-Convert-BinHex         perl-Convert-TNEF           perl-Data-Dumper
            perl-Date-Parse             perl-DBD-SQLite             perl-DBI
            perl-Digest-HMAC            perl-Digest-MD5             perl-Digest-SHA1
            perl-DirHandle              perl-ExtUtils-MakeMaker     perl-Fcntl
            perl-File-Basename          perl-File-Copy              perl-File-Path
            perl-File-Spec              perl-File-Temp              perl-FileHandle
            perl-Filesys-Df             perl-Getopt-Long            perl-Inline-C
            perl-IO                     perl-IO-File                perl-IO-Pipe
            perl-IO-stringy             perl-HTML-Entities          perl-HTML-Parser
            perl-HTML-Tagset            perl-HTML-TokeParser        perl-Mail-Field
            perl-Mail-Header            perl-Mail-IMAPClient        perl-Mail-Internet
            perl-Math-BigInt            perl-Math-BigRat            perl-MIME-Base64
            perl-MIME-Decoder           perl-MIME-Decoder-UU        perl-MIME-Head
            perl-MIME-Parser            perl-MIME-QuotedPrint       perl-MIME-tools
            perl-MIME-WordDecoder       perl-Net-CIDR               perl-Net-DNS
            perl-Net-IP                 perl-OLE-Storage_Lite       perl-Pod-Escapes
            perl-Pod-Simple             perl-POSIX                  perl-Scalar-Util
            perl-Socket                 perl-Storable               perl-Test-Harness
            perl-Test-Pod               perl-Test-Simple            perl-Time-HiRes
            perl-Time-localtime         perl-Sys-Hostname-Long      perl-Sys-SigAction
            perl-Sys-Syslog             perl-Env                    perl-Filesys-Df
            perl-IO-Wrap                perl-CPAN                   perl-Data-Dump
            perl-DB_File                perl-Razor2-Client-Agent    perl-File-ShareDir-Install
            perl-Digest                 perl-Encode-Detect          perl-Error
            perl-ExtUtils-CBuilder      perl-ExtUtils-ParseXS       perl-Inline
            perl-IO-String              perl-IO-Zlib                perl-IP-Country
            perl-Mail-SPF               perl-Mail-SPF-Query         perl-Module-Build
            perl-Net-CIDR-Lite          perl-Mail-DKIM              perl-Net-LDAP
            perl-NetAddr-IP             perl-Parse-RecDescent       perl-MailTools
            perl-Test-Manifest          perl-Text-Balanced          perl-URI
            perl-version                perl-IO-Compress-Bzip2      perl-Sendmail-PMilter
            perl-Math-Int64             perl-IP-Country-DB_File     perl-namespace-autoclean
            perl-Data-IEEE754           perl-Data-Printer           perl-Data-Validate-IP
            perl-List-AllUtils          perl-List-SomeUtils         perl-Net-DNS-Nameserver
            perl-List-UtilsBy           perl-MaxMind-DB-Metadata    perl-MaxMind-DB-Reader
            perl-Module-Runtime         perl-Moo                    perl-MooX-StrictConstructor
            perl-Role-Tiny              perl-strictures             perl-DBD-mysql
            perl-Sub-Quote              perl-Math-Int128            perl-Net-Works-Network
            perl-MaxMind-DB-Reader-XS   perl-Geo-IP                 perl-GeoIP2-Database-Reader
            perl-HTTP-Date              perl-LWP-Protocol-https     perl-Net-DNS-Resolver-Programmable
            perl-Net-LibIDN             perl-Net-LibIDN2            perl-Test-Perl-Critic
            perl-Devel-Cycle            perl-Perl-Critic-Policy     perl-Perl-Critic-Policy-TestingAndDebugging-ProhibitNoStrict
            perl-TimeDate               perl-YAML                   perl-Perl-Critic-Policy-Perlsecret
            perl-Path-Class             perl-Test-Fatal             perl-Test-Number-Delta
            perl-Data-Dumper-Concise    perl-DateTime               perl-Test-Warnings
            perl-autodie                perl-Test-Requires          perl-Test-Tester
            perl-Clone-PP               perl-File-HomeDir           perl-Sort-Naturally
            perl-JSON-MaybeXS           perl-Test-LeakTrace         perl-Throwable
            perl-Alien-Build            perl-Alien-Libxml2          perl-Alien-Build-Plugin-Download-GitLab
            perl-BSD-Resource           perl-DBIx-Simple            perl-Email-Abstract
            perl-Email-Address-XS       perl-Email-Date-Format      perl-Email-MessageID
            perl-Email-MIME             perl-Email-MIME-ContentType perl-Email-MIME-Encodings
            perl-Email-Sender           perl-Email-Simple           perl-FFI-CheckLib
            perl-File-chdir             perl-IO-Socket-INET6        perl-Mail-DMARC
            perl-MIME-Types             perl-MooX-Types-MooseLike   perl-Net-IDN-Encode
            perl-Net-IMAP-Simple        perl-Net-Patricia           perl-Net-SMTPS
            perl-Regexp-Common          perl-Test-Exception         perl-Test-Output
            perl-Test-Regexp            perl-XML-LibXML             perl-XML-NamespaceSupport
            perl-XML-SAX                perl-XML-SAX-Base
"

# the array of perl modules needed
ARMOD=();
ARMOD+=('Archive::Tar');            ARMOD+=('Archive::Zip');                ARMOD+=('bignum');     
ARMOD+=('Carp');                    ARMOD+=('Compress::Zlib');              ARMOD+=('Compress::Raw::Zlib');     
ARMOD+=('Convert::BinHex');         ARMOD+=('Convert::TNEF');               ARMOD+=('Data::Dumper');     
ARMOD+=('Date::Parse');             ARMOD+=('DBD::SQLite');                 ARMOD+=('DBI');     
ARMOD+=('Digest::HMAC');            ARMOD+=('Digest::MD5');                 ARMOD+=('Digest::SHA1');     
ARMOD+=('DirHandle');               ARMOD+=('ExtUtils::MakeMaker');         ARMOD+=('Fcntl');     
ARMOD+=('File::Basename');          ARMOD+=('File::Copy');                  ARMOD+=('File::Path');     
ARMOD+=('File::Spec');              ARMOD+=('File::Temp');                  ARMOD+=('FileHandle');     
ARMOD+=('Filesys::Df');             ARMOD+=('Getopt::Long');                ARMOD+=('Inline::C');     
ARMOD+=('IO');                      ARMOD+=('IO::File');                    ARMOD+=('IO::Pipe');     
ARMOD+=('IO::Stringy');             ARMOD+=('HTML::Entities');              ARMOD+=('HTML::Parser');     
ARMOD+=('HTML::Tagset');            ARMOD+=('HTML::TokeParser');            ARMOD+=('Mail::Field');     
ARMOD+=('Mail::Header');            ARMOD+=('Mail::IMAPClient');            ARMOD+=('Mail::Internet');     
ARMOD+=('Math::BigInt');            ARMOD+=('Math::BigRat');                ARMOD+=('MIME::Base64');     
ARMOD+=('MIME::Decoder');           ARMOD+=('MIME::Decoder::UU');           ARMOD+=('MIME::Head');     
ARMOD+=('MIME::Parser');            ARMOD+=('MIME::QuotedPrint');           ARMOD+=('MIME::Tools');     
ARMOD+=('MIME::WordDecoder');       ARMOD+=('Net::CIDR');                   ARMOD+=('Net::DNS');     
ARMOD+=('Net::IP');                 ARMOD+=('OLE::Storage_Lite');           ARMOD+=('Pod::Escapes');     
ARMOD+=('Pod::Simple');             ARMOD+=('POSIX');                       ARMOD+=('Scalar::Util');     
ARMOD+=('Socket');                  ARMOD+=('Storable');                    ARMOD+=('Test::Harness');     
ARMOD+=('Test::Pod');               ARMOD+=('Test::Simple');                ARMOD+=('Time::HiRes');     
ARMOD+=('Time::localtime');         ARMOD+=('Sys::Hostname::Long');         ARMOD+=('Sys::SigAction');     
ARMOD+=('Sys::Syslog');             ARMOD+=('Env');                         ARMOD+=('Filesys::Df');     
ARMOD+=('IO::Wrap');                ARMOD+=('CPAN');                        ARMOD+=('Data::Dump');     
ARMOD+=('DB_File');                 ARMOD+=('Razor2::Client::Agent');       ARMOD+=('File::ShareDir::Install');     
ARMOD+=('Digest');                  ARMOD+=('Encode::Detect');              ARMOD+=('Error');     
ARMOD+=('ExtUtils::CBuilder');      ARMOD+=('ExtUtils::ParseXS');           ARMOD+=('Inline');     
ARMOD+=('IO::String');              ARMOD+=('IO::Zlib');                    ARMOD+=('IP::Country');     
ARMOD+=('Mail::SPF');               ARMOD+=('Mail::SPF::Query');            ARMOD+=('Module::Build');     
ARMOD+=('Net::CIDR::Lite');         ARMOD+=('Mail::DKIM');                  ARMOD+=('Net::LDAP');     
ARMOD+=('NetAddr::IP');             ARMOD+=('Parse::RecDescent');           ARMOD+=('MailTools');     
ARMOD+=('Test::Manifest');          ARMOD+=('Text::Balanced');              ARMOD+=('URI');        
ARMOD+=('version');                 ARMOD+=('IO::Compress::Bzip2');         ARMOD+=('Sendmail::PMilter');     
ARMOD+=('Math::Int64');             ARMOD+=('IP::Country::DB_File');        ARMOD+=('namespace::autoclean');     
ARMOD+=('Data::IEEE754');           ARMOD+=('Data::Printer');               ARMOD+=('Data::Validate::IP');     
ARMOD+=('List::AllUtils');          ARMOD+=('List::SomeUtils');             ARMOD+=('Net::DNS::Nameserver');     
ARMOD+=('List::UtilsBy');           ARMOD+=('MaxMind::DB::Metadata');       ARMOD+=('MaxMind::DB::Reader');     
ARMOD+=('Module::Runtime');         ARMOD+=('Moo');                         ARMOD+=('MooX::StrictConstructor');     
ARMOD+=('Role::Tiny');              ARMOD+=('strictures');                  ARMOD+=('DBD::mysql');     
ARMOD+=('Sub::Quote');              ARMOD+=('Math::Int128');                ARMOD+=('Net::Works::Network');     
ARMOD+=('MaxMind::DB::Reader::XS'); ARMOD+=('Geo::IP');                     ARMOD+=('GeoIP2::Database::Reader');     
ARMOD+=('HTTP::Date');              ARMOD+=('LWP::Protocol::https');        ARMOD+=('Net::DNS::Resolver::Programmable');
ARMOD+=('Net::LibIDN');             ARMOD+=('Net::LibIDN2');                ARMOD+=('Test::Perl::Critic');     
ARMOD+=('Devel::Cycle');            ARMOD+=('Perl::Critic::Policy');        ARMOD+=('Perl::Critic::Policy::TestingAndDebugging::ProhibitNoStrict');
ARMOD+=('TimeDate');                ARMOD+=('YAML');                        ARMOD+=('Perl::Critic::Policy::Perlsecret');
ARMOD+=('Path::Class');             ARMOD+=('Test::Fatal');                 ARMOD+=('Test::Number::Delta');
ARMOD+=('Data::Dumper::Concise');   ARMOD+=('DateTime');                    ARMOD+=('Test::Warnings');
ARMOD+=('autodie');                 ARMOD+=('Test::Requires');              ARMOD+=('Test::Tester');
ARMOD+=('Clone::PP');               ARMOD+=('File::HomeDir');               ARMOD+=('Sort::Naturally');
ARMOD+=('JSON::MaybeXS');           ARMOD+=('Test::LeakTrace');             ARMOD+=('Throwable');
ARMOD+=('Alien::Build');            ARMOD+=('Alien::Libxml2');              ARMOD+=('Alien::Build::Plugin::Download::GitLab');
ARMOD+=('BSD::Resource');           ARMOD+=('DBIx::Simple');                ARMOD+=('Email::Abstract');
ARMOD+=('Email::Address::XS');      ARMOD+=('Email::Date::Format');         ARMOD+=('Email::MessageID');
ARMOD+=('Email::MIME');             ARMOD+=('Email::MIME::ContentType');    ARMOD+=('Email::MIME::Encodings');
ARMOD+=('Email::Sender');           ARMOD+=('Email::Simple');               ARMOD+=('FFI::CheckLib');
ARMOD+=('File::chdir');             ARMOD+=('IO::Socket::INET6');           ARMOD+=('Mail::DMARC');
ARMOD+=('MIME::Types');             ARMOD+=('MooX::Types::MooseLike');      ARMOD+=('Net::IDN::Encode');
ARMOD+=('Net::IMAP::Simple');       ARMOD+=('Net::Patricia');               ARMOD+=('Net::SMTPS');
ARMOD+=('Regexp::Common');          ARMOD+=('Test::Exception');             ARMOD+=('Test::Output');
ARMOD+=('Test::Regexp');            ARMOD+=('XML::LibXML');                 ARMOD+=('XML::NamespaceSupport');
ARMOD+=('XML::SAX');                ARMOD+=('XML::SAX::Base');

# SA and plugins
SAMOD=();
SAMOD+=('Mail::SpamAssassin');
SAMOD+=('Mail::SpamAssassin::Plugin::Rule2XSBody');
SAMOD+=('Mail::SpamAssassin::Plugin::DCC');
SAMOD+=('Mail::SpamAssassin::Plugin::Pyzor');

# logging starts here
(
clear
echo;
echo "Installation/configuration results are being logged to /var/log/mailscanner-configuration.log";
echo;
timewait 1

# install the basics
echo "Installing required base system utilities.";
echo "You can safely ignore 'No package available' errors.";
echo;
timewait 2

# install base packages
if [ -n "$EPELOPTION" ]; then
  $YUM -y install $EPELOPTION
  if [ $RHEL -eq 9 ]; then
    dnf config-manager --set-enabled crb
  fi
fi
if [ -n "$POWERTOOLSOPTION" ]; then
  $YUM -y install $POWERTOOLSOPTION
fi
$YUM -y --skip-broken install $BASEPACKAGES

# install this separate in case it conflicts
if [ "x$MTAOPTION" != "x" ]; then
    $YUM -y install $MTAOPTION
    if [ $? != 0 ]; then
        echo "Error installing $MTAOPTION MTA"
        echo "This usually means an MTA is already installed."
    fi
    if [ $MTAOPTION = "sendmail" ]; then
        mkdir -p /var/spool/mqueue.in
    fi
fi

# make sure rpm is available
if [ -x /bin/rpm ]; then
    RPM=/bin/rpm
elif [ -x /usr/bin/rpm ]; then
    RPM=/usr/bin/rpm
else
    clear
    echo;
    echo "The 'rpm' command cannot be found. I have already attempted to install this";
    echo "package, but it is still not found. Please ensure that you have network";
    echo "access to the internet and try running the installation again.";
    echo;
    exit 1
fi

# check for curl
if [ ! -x /usr/bin/curl ]; then
    clear
    echo;
    echo "The curl command cannot be found. I have already attempted to install this";
    echo "package, but it is still not found. Please ensure that you have network access";
    echo "to the internet and try running the installation again.";
    echo;
    exit 1
else
    CURL='/usr/bin/curl';
fi

# create the cpan config if there isn't one and the user
# elected to use CPAN
if [ $CPANOPTION -eq 1 ]; then
    # user elected to use CPAN option
    if [ ! -f '/root/.cpan/CPAN/MyConfig.pm' ]; then
        echo;
        echo "CPAN config missing. Creating one ..."; echo;
        mkdir -p /root/.cpan/CPAN
        cd /root/.cpan/CPAN
        $CURL -LO https://mirrors.efa-project.org/msv5/CPAN/RHEL/root/MyConfig.pm
        cd "$THISCURRPMDIR"
    fi
    AUTOCPAN=1
    # Install cpanminus
    $YUM -y install cpanminus
    if [ $? -ne 0 ]; then
        echo "Error installing cpanminus, falling back to perl invocation method."
        AUTOCPAN=0
    fi
    timewait 1
fi

# Enable PowerTools Repo if requested
if [[ $POWERTOOLS -eq 1 && $RHEL -eq 8 ]]; then
    $YUM config-manager --set-enabled PowerTools
fi

# install required perl packages that are available via yum along
# with EPEL packages if the user elected to do so.
#
# some items may not be available depending on the distribution 
# release but those items will be checked after this and installed
# via cpan if the user elected to do so.
clear
echo;
echo "Installing available Perl packages, ClamAV (if elected)";
echo "via yum. You can safely ignore any";
echo "subsequent 'No package available' errors."; echo;
timewait 3
$YUM -y --skip-broken install $TNEF $MOREPACKAGES $CAVOPTION

# install missing tnef if the user elected to do so
if [ $TNEFOPTION -eq 1 ]; then
    # user elected to use tnef RPM option
    if [ ! -x '/usr/bin/tnef' ]; then
        cd /tmp
        rm -f tnef-1.4.18*
        clear
        echo;
        echo "Tnef missing. Installing via RPM ..."; echo;

        if [ $RHEL -eq 9 ]; then
          $CURL -LO https://mirrors.efa-project.org/msv5/EL9/tnef-1.4.18-1.el9.x86_64.rpm
          if [ -f 'tnef-1.4.18-1.el9.x86_64.rpm' ]; then
            $RPM -Uvh tnef-1.4.18-1.el9.x86_64.rpm
          fi
        elif [ $RHEL -eq 8 ]; then
          $CURL -LO https://mirrors.efa-project.org/msv5/EL8/tnef-1.4.18-1.el8.x86_64.rpm
          if [ -f 'tnef-1.4.18-1.el8.x86_64.rpm' ]; then
            $RPM -Uvh tnef-1.4.18-1.el8.x86_64.rpm
          fi
        elif [ $RHEL -eq 7 ]; then
          $CURL -LO https://mirrors.efa-project.org/msv5/EL7/tnef-1.4.18-1.el7.x86_64.rpm
          if [ -f 'tnef-1.4.18-1.el7.x86_64.rpm' ]; then
            $RPM -Uvh tnef-1.4.18-1.el7.x86_64.rpm
          fi
        else
          echo "NOTICE: I cannot find a suitable RPM to install tnef";
          timewait 5
        fi

        # back to where i started
        rm -f tnef-1.4.18*
        cd "$THISCURRPMDIR"
    fi
fi

# install missing unrar if the user elected to do so
if [ $UNRAROPTION -eq 1 ]; then
    # user elected to use unrar RPM option
    if [ ! -x '/usr/bin/unrar' ]; then
        cd /tmp
        rm -f unrar-6.2.5*
        clear
        echo;
        echo "unrar missing. Installing via RPM ..."; echo;

        if [ $RHEL -eq 9 ]; then
          $CURL -LO https://mirrors.efa-project.org/msv5/EL9/unrar-6.2.5-1.el9.x86_64.rpm
          if [ -f 'unrar-6.2.5-1.el9.x86_64.rpm' ]; then
            $RPM -Uvh unrar-6.2.5-1.el9.x86_64.rpm
          fi
        elif [ $RHEL -eq 8 ]; then
          $CURL -LO https://mirrors.efa-project.org/msv5/EL8/unrar-6.2.5-1.el8.x86_64.rpm
          if [ -f 'unrar-6.2.5-1.el8.x86_64.rpm' ]; then
            $RPM -Uvh unrar-6.2.5-1.el8.x86_64.rpm
          fi
        elif [ $RHEL -eq 7 ]; then
          $CURL -LO https://mirrors.efa-project.org/msv5/EL7/unrar-6.1.7-1.el7.x86_64.rpm
          if [ -f 'unrar-6.1.7-1.el7.x86_64.rpm' ]; then
            $RPM -Uvh unrar-6.1.7-1.el7.x86_64.rpm
          fi
        else
          echo "NOTICE: I cannot find a suitable RPM to install unrar";
          timewait 5
        fi
        
        # back to where i started
        rm -f unrar-6.2.5*
        cd "$THISCURRPMDIR"
    fi
fi

if [ $RHEL -eq 9 ]; then
    # install missing perl-Net-LibIDN if the user elected to do so
    if [ $IDNOPTION -eq 1 ]; then
        # user elected to use perl-Net-LibIDN RPM option
        $RPM -q perl-Net-LibIDN
        if [ $? -ne 0 ]; then
            cd /tmp
            rm -f perl-Net-LibIDN-0.12*
            clear
            echo;
            echo "perl-Net-LibIDN missing. Installing via RPM ..."; echo;

            if [ $RHEL -eq 9 ]; then
            $CURL -LO https://mirrors.efa-project.org/msv5/EL9/perl-Net-LibIDN-0.12-1.x86_64.rpm
            if [ -f 'perl-Net-LibIDN-0.12-1.x86_64.rpm' ]; then
                $RPM -Uvh perl-Net-LibIDN-0.12-1.x86_64.rpm
            fi
            else
            echo "NOTICE: I cannot find a suitable RPM to install perl-Net-LibIDN";
            timewait 5
            fi
            
            # back to where i started
            rm -f perl-Net-LibIDN-0.12*
            cd "$THISCURRPMDIR"
        fi
    fi
fi

# fix the stupid line in /etc/freshclam.conf that disables freshclam 
if [ $CAV -eq 1 ]; then
    COUT='#Example';
    if [ -f '/etc/freshclam.conf' ]; then
        perl -pi -e 's/Example/'$COUT'/;' /etc/freshclam.conf
    fi
    freshclam
fi

# Configure clamav if required
if [ $CONFCAV -eq 1 ]; then
    # Enable config
    sed -i '/^Example/ c\#Example' /etc/clamd.d/scan.conf
    sed -i '/#LocalSocket \/var\/run\/clamd.scan\/clamd.sock/ c\LocalSocket /var/run/clamd.scan/clamd.sock' /etc/clamd.d/scan.conf
    sed -i '/#LocalSocket \/run\/clamd.scan\/clamd.sock/ c\LocalSocket /var/run/clamd.scan/clamd.sock' /etc/clamd.d/scan.conf
    sed -i '/#LogFile \/var\/log\/clamd.scan/ c\LogFile /var/log/clamd.scan' /etc/clamd.d/scan.conf
    chown -R clamscan:mtagroup /var/run/clamd.scan
    echo "d /run/clamd.scan 0750 clamscan mtagroup -" > /usr/lib/tmpfiles.d/clamd.scan.conf
    echo "d /run/clamd.scan 0750 clamscan mtagroup -" > /etc/tmpfiles.d/clamd.scan.conf
    touch /var/log/clamd.scan
    chown clamscan:clamscan /var/log/clamd.scan
    usermod -G mtagroup,virusgroup,clamupdate clamscan
fi

# now check for missing perl modules and install them via cpan
# if the user elected to do so
clear; echo;
echo "Checking Perl Modules ... "; echo;
timewait 2
# used to trigger a wait if something this missing
PMODWAIT=0

for i in "${ARMOD[@]}"
do
    perldoc -l $i >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        if [ $CPANOPTION -eq 1 ]; then
            clear
            echo "$i is missing. Installing via CPAN ..."; echo;
            timewait 1
            if [ $AUTOCPAN -eq 0 ]; then
                perl -MCPAN -e "CPAN::Shell->force(qw(install $i ));"
            else
                cpanm --force --no-interactive $i
            fi
        else
            echo "WARNING: $i is missing. You should fix this.";
            PMODWAIT=5
        fi
    else
        echo "$i => OK";
    fi
done

function install_sa() {
    # Create sabuild user and set up for sudo build (SA 4.0+)
    useradd -m -s /sbin/nologin sabuild &>/dev/null
    id -u sabuild &>/dev/null
    if [ $? -eq 0 ]; then
        echo "sabuild    ALL=(ALL)    NOPASSWD: ALL" > /etc/sudoers.d/sabuild
        if [ ! -f '/home/sabuild/.cpan/CPAN/MyConfig.pm' ]; then
            echo;
            echo "CPAN config missing. Creating one ..."; echo;
            mkdir -p /home/sabuild/.cpan/CPAN
            cd /home/sabuild/.cpan/CPAN
            $CURL -LO https://mirrors.efa-project.org/msv5/CPAN/RHEL/sabuild/MyConfig.pm
            chown -R sabuild:sabuild /home/sabuild/.cpan
            cd "$THISCURRPMDIR"
        fi

        for i in "${SAMOD[@]}"
        do
            perldoc -l $i >/dev/null 2>&1
            if [[ $? -ne 0 || $1 == "update" ]]; then
                if [ $CPANOPTION -eq 1 ]; then
                    clear
                    echo "$i is missing or needs updated. Installing via CPAN ..."; echo;
                    timewait 1
                    su - sabuild -s /bin/bash -c "echo \"\\\n\" | perl -MCPAN -e \"CPAN::Shell->force(qw(install $i ));\""
                else
                    echo "WARNING: $i is missing. You should fix this.";
                    PMODWAIT=5
                fi
            else
                echo "$i => OK";
            fi
        done

        # Cleanup, just revoke sudo privs
        rm -f /etc/sudoers.d/sabuild
    else
        echo "Unable to create sabuild user, cannot install spamassassin"
        echo "You should fix this."
    fi
}

install_sa

# Update perl modules
if [[ -n "${arg_update+x}" && $AUTOCPAN -ne 0 ]]; then
    cpanm App::cpanoutdated
    for i in $(cpan-outdated -p); do
      if [ "$i" == "Mail::SpamAssassin" ]; then
        # Check for spamassassin rpm and notify user
        if [[ -n $($RPM -qa | grep spamassassin) ]]; then
          echo "Spamassassin detected installed via rpm.  To update spamassassin use your package manager."
          timewait 1
        else
          install_sa "update"
        fi
      else
        cpanm --force --no-interactive $i
      fi
    done
fi

# will pause if a perl module was missing
timewait $PMODWAIT

# selinux
if [ $SELMODE -eq 1 ]; then
    OLDTHING='SELINUX=enforcing';
    NEWTHING='SELINUX=permissive';
        
    if [ -f '/etc/selinux/config' ]; then
        perl -pi -e 's/'$OLDTHING'/'$NEWTHING'/;' /etc/selinux/config
        setenforce 0
    else
        clear
        echo;
        echo "WARNING: I was unable to find the SELinux configuration file to set";
        echo "the permissive mode. You will need to find the file and set this item";
        echo "manually. Press <return> to continue.";
        read foobar
    fi
fi

# Freshclam
freshclam 2>/dev/null

# make sure in starting directory
cd "$THISCURRPMDIR"

clear
# echo;
# echo "Installing the MailScanner RPM ... ";

echo;
echo "Preparing MailScanner ..."

# allow supplementary groups
CAVOLD='^#AllowSupplementaryGroups.*';
CAVNEW='AllowSupplementaryGroups yes';
if [ -f '/etc/clamd.conf' ]; then
    sed -i "s/${CAVOLD}/${CAVNEW}/g" /etc/clamd.conf
fi

# check for common users and add to the mtagroup
if id -u clam >/dev/null 2>&1; then
    usermod -a -G mtagroup clam >/dev/null 2>&1
fi

if id -u clamav >/dev/null 2>&1; then
    usermod -a -G mtagroup clamav >/dev/null 2>&1
fi

if id -u clamscan >/dev/null 2>&1; then
    usermod -a -G mtagroup clamscan >/dev/null 2>&1
fi

if id -u vscan >/dev/null 2>&1; then
    usermod -a -G mtagroup vscan >/dev/null 2>&1
fi

if id -u sophosav >/dev/null 2>&1; then
    usermod -a -G mtagroup sophosav >/dev/null 2>&1
fi

if id -u postfix >/dev/null 2>&1; then
    usermod -a -G mtagroup postfix >/dev/null 2>&1
    chown postfix /var/spool/MailScanner/milterin >/dev/null 2>&1
    chown postfix /var/spool/MailScanner/milterout >/dev/null 2>&1
fi

if id -u mail >/dev/null 2>&1; then
    usermod -a -G mtagroup mail >/dev/null 2>&1
fi

if id -u avast >/dev/null 2>&1; then
    usermod -a -G mtagroup avast >/dev/null 2>&1
fi

# create symlink for spamasassin
if [ -d '/etc/mail/spamassassin' -a ! -L '/etc/mail/spamassassin/MailScanner.cf' -a -f '/etc/MailScanner/spamassassin.conf' -a ! -f '/etc/mail/spamassassin/MailScanner.cf' ]; then
    ln -s /etc/MailScanner/spamassassin.conf /etc/mail/spamassassin/MailScanner.cf 
fi

# fix the clamav wrapper if the user does not exist
if [ -d '/etc/clamav' ]; then

    DISTROCAVUSER='ClamUser="clamav"';
    DISTROCAVGRP='ClamGroup="clamav"';

    # check for common users and add to the mtagroup
    if id -u clam >/dev/null 2>&1; then
        CAVUSR='ClamUser="clam"';
    fi

    if id -u clamav >/dev/null 2>&1; then
        CAVUSR='ClamUser="clamav"';
    fi

    if id -u clamscan >/dev/null 2>&1; then
        CAVUSR='ClamUser="clamscan"';
    fi

    if id -u vscan >/dev/null 2>&1; then
        CAVUSR='ClamUser="vscan"';
    fi

    if getent group clamav >/dev/null 2>&1; then
        CAVGRP='ClamGroup="clamav"';
    fi

    if getent group clam >/dev/null 2>&1; then
        CAVGRP='ClamGroup="clam"';
    fi

    if getent group clamscan >/dev/null 2>&1; then
        CAVGRP='ClamGroup="clamscan"';
    fi

    if [ -f '/usr/lib/MailScanner/wrapper/clamav-wrapper' ]; then
        sed -i "s/${DISTROCAVUSER}/${CAVUSR}/g" /usr/lib/MailScanner/wrapper/clamav-wrapper
        sed -i "s/${DISTROCAVGRP}/${CAVGRP}/g" /usr/lib/MailScanner/wrapper/clamav-wrapper
    fi

    # fix old style clamav Monitors if preset in old mailscanner.conf
    CAVOLD='^Monitors for ClamAV Updates.*';
    CAVNEW='Monitors for ClamAV Updates = \/usr\/local\/share\/clamav\/\*\.cld \/usr\/local\/share\/clamav\/\*\.cvd \/var\/lib\/clamav\/\*\.inc\/\* \/var\/lib\/clamav\/\*\.\?db \/var\/lib\/clamav\/\*\.cvd';
    if [ -f '/etc/MailScanner/MailScanner.conf' ]; then
        sed -i "s/${CAVOLD}/${CAVNEW}/g" /etc/MailScanner/MailScanner.conf
    fi

fi


# create ramdisk
if [ $RAMDISK -eq 1 ]; then
    if [ -d '/var/spool/MailScanner/incoming' ]; then
        echo "Creating the ramdisk ...";
        echo;
        DISK="/var/spool/MailScanner/incoming";
        FSTYPE=$(df -P -T ${DISK}|tail -n +2 | awk '{print $2}')

        if [ $FSTYPE != tmpfs ]; then
            mount -t tmpfs -o size=${RAMDISKSIZE}M tmpfs ${DISK}
            echo "tmpfs ${DISK} tmpfs rw,size=${RAMDISKSIZE}M 0 0" >> /etc/fstab
            echo "Enabling ramdisk sync ...";
            if [ -f '/etc/MailScanner/defaults' ]; then
                OLD="^ramdisk_sync=0";
                NEW="ramdisk_sync=1";
                sed -i "s/${OLD}/${NEW}/g" /etc/MailScanner/defaults
            fi
        else
            echo "${DISK} is already a RAMDISK!"; echo;
        fi
    fi
fi
    
/usr/sbin/ms-update-phishing >/dev/null 2>&1

# fix the clamav wrapper if the user does not exist
if [ -f '/etc/freshclam.conf' ]; then
    if id -u clam >/dev/null 2>&1; then
        #clam is being used instead of clamav
        OLDCAVUSR='ClamUser="clamav"';
        NEWCAVUSR='ClamUser="clam"'

        if [ -f '/usr/lib/MailScanner/wrapper/clamav-wrapper' ]; then
            perl -pi -e 's/'$OLDCAVUSR'/'$NEWCAVUSR'/;' /usr/lib/MailScanner/wrapper/clamav-wrapper
        fi
    fi
fi

ldconfig

if [[ -n "${arg_update+x}" ]]; then
    echo;
    echo '----------------------------------------------------------';
    echo 'Configuration and module update complete'; 
    echo;
    echo 'See http://www.mailscanner.info for more information and  '
    echo 'support via the MailScanner mailing list.'
    echo;
    echo;
    echo To finish updating MailScanner, review the following files:
    echo
    echo /etc/MailScanner/defaults
    echo /etc/MailScanner/MailScanner.conf
    echo
    echo Restart MailScanner
    echo
    echo    --SysV Init--
    echo    service mailscanner restart
    echo
    echo    --Systemd--
    echo    systemctl restart mailscanner.service
    echo
    echo Restart Sendmail for Mailscanner \(if in use\)
    echo
    echo    --SysV Init--
    echo    service ms-sendmail restart
    echo
    echo    --Systemd--
    echo    systemctl restart ms-sendmail.service
    echo
    echo Restart MSMilter \(if in use\) 
    echo
    echo    --SysV Init--
    echo    service msmilter restart
    echo
    echo    --Systemd--
    echo    systemctl restart msmilter.service
    echo
else
    echo;
    echo '----------------------------------------------------------';
    echo 'Initial configuration and module installation complete'; 
    echo;
    echo 'See http://www.mailscanner.info for more information and  '
    echo 'support via the MailScanner mailing list.'
    echo;
    echo;
    echo To finish configuring MailScanner, edit the following files:
    echo
    echo /etc/MailScanner/defaults
    echo /etc/MailScanner/MailScanner.conf
    echo
    echo To activate MailScanner run the following commands:
    echo
    echo    --SysV Init--
    echo    chkconfig mailscanner on
    echo    service mailscanner start
    echo
    echo    --Systemd--
    echo    systemctl enable mailscanner.service
    echo    systemctl start mailscanner.service
    echo
    echo To activate Sendmail for Mailscanner \(if in use\) run the following commands:
    echo
    echo    --SysV Init--
    echo    chkconfig sendmail off
    echo    chkconfig sm-client off
    echo    chkconfig ms-sendmail on
    echo    service ms-sendmail start
    echo
    echo    --Systemd--
    echo    systemctl disable sendmail.service
    echo    systemctl disable sm-client.service
    echo    systemctl enable ms-sendmail.service
    echo    systemctl start ms-sendmail.service
    echo
    echo To activate MSMilter for Mailscanner \(if in use\) run the following commands:
    echo
    echo    --SysV Init--
    echo    chkconfig msmilter on
    echo    service msmilter start
    echo
    echo    --Systemd--
    echo    systemctl enable msmilter.service
    echo    systemctl start msmilter.service
    echo
fi

) 2>&1 | tee -a /var/log/mailscanner-configuration.log
