﻿# Compilation Params
	COMPILED="YES";
	# Set Language to english
	export LANG=en_US.UTF-8
# Setup URL Params
	SETUPPATH="http://install.Somnode.net/scripts";
	MIRROR="http://mirror.Somnode.net/download";
	BETASETUPPATH="http://install.Somnode.net/scripts_beta";
	BETAMIRROR="http://mirror.Somnode.net/download";
	INSTALLDIR="/usr/local/Somnode/";
    BasePath="/usr/local/Somnode";
# Wowza Streaming Engine Params
	WowzaVersion="4.9.6+3";
	WowzaDownloadURLx64="${MIRROR}/WowzaStreamingEngine-4.9.6+3-linux-x64-installer.run";
	WowzaUpdateURL="${MIRROR}/WowzaStreamingEngine-Update-4.9.6+3.zip";
	WowzaUpgradeURL="${WowzaUpdateURL}";
	WowzaUpgradeFilename=$(printf -- "%s" "${WowzaUpgradeURL##*/}")
    WowzaUpgradeFilenameNoExtension=$(echo ${WowzaUpgradeFilename} | sed -e 's/\.zip//g')
    WowzaSkipJavaUpdate=0
    # Flussonic
    FlussonicVersion="25.05";
    # NginxRtmp
    NginxRtmpVersion="nginx-1.16.0-rtmp-1.2.9-20210705";
# Shoutcast Download
	SHOUTCAST_FILENAME="SHOUTCAST_FILES_20220407.zip";
	SHOUTCAST_DOWNLOAD="${MIRROR}/${SHOUTCAST_FILENAME}";
	GEOIP_FILENAME="GeoIP.zip"; # Add version numbers to this when updated
# Somnode Params
	MCPInstallDir=/usr/local/Somnode/htdocs;
	MCPInstallPort=2020;
	if [[ -f /usr/local/Somnode/Somnode.port ]]; then MCPInstallPort=`cat /usr/local/Somnode/Somnode.port`; fi
	# If port has not been configured, and Somnode is already installed, then we use exsting port 2000
	if [[ ! -f /usr/local/Somnode/Somnode.port ]] && [[ -f /usr/local/Somnode/htdocs/database.php ]]; then MCPInstallPort=2000; fi
	MCPInstallChownUser="Somnode";
	MCPInstallChownGroup="Somnode";
	PHPBINARY=/usr/local/Somnode/php/bin/php;
	PHPCONF=/usr/local/Somnode/php/php.ini;
	PHPEXTDIR=/usr/local/Somnode/php/lib/php/extensions/;
# Development Environment Variables
	InstallSkipSomnode="n";
	InstallSkipFFMPEG="n";
	InstallSkipIcecast="n";
# Number of make jobs / # of cpu cores
numberOfCores=`grep -c ^processor /proc/cpuinfo`;
makeJobCount=1;
if [ "${numberOfCores}" -ge 8 ]; then
	makeJobCount=6;
elif [ "${numberOfCores}" -ge 4 ]; then
makeJobCount=3
elif [ "${numberOfCores}" -gt 2 ]; then
makeJobCount=2
fi
# Memory - Round down
systemTotalMemory=`grep MemTotal /proc/meminfo | awk '{print int(($2/1000/1000)+0.5)}'`
# Set ulimit so it's applied to everything using this file
ulimit -n 1024000;
export DEBIAN_FRONTEND=noninteractive # Make sure noninteractive mode enabled for DEBIAN
function ver() { printf "%d%03d%03d%03d" $(echo "$1" | tr '.' ' '); }
function lowercase(){
echo "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
}
# DETECT OPERATING SYSTEM
DISTRO="UNKNOWN";
DISTROBASE="UNKNOWN";
function DetectOS(){
  OS=`lowercase \`uname\``
  if [ "${OS}" = "linux" ]; then
    if [ -f /etc/redhat-release ] ; then
      DISTRO='Centos'
      Centos="Centos"
      DISTROBASE="Centos";
    elif [ `grep -c "debian" /etc/os-release` -gt 0 ] || [ -f /etc/debian_version ]; then
      if [[ `which lsb_release` == "" ]]; then apt -y install lsb-release; fi
      DISTRO=`lsb_release -is` # Returns Debian or Ubuntu
      DISTROBASE="Debian";
    fi
  fi
}
	DISTROVERSION="UNSUPPORTED";
	function DetectOSMajor(){
		DetectOS
		case $DISTRO in
			'Centos')
				DISTROVERSION=`cat /etc/redhat-release | grep -oE '[0-9]+\.[0-9]+' | cut -d"." -f1`;
        if [[ "${DISTROVERSION}" == "" ]]; then DISTROVERSION=`rpm --eval '%{centos_ver}'`; fi
			;;
			'Debian')
				DISTROVERSION=`lsb_release -sr`
			;;
			'Ubuntu')
				DISTROVERSION=`lsb_release -sr`
			;;
		esac
	}
	OSSupported="no";
	function IsOSSupported(){
		DetectOS
		DetectOSMajor
		case $DISTRO in
			'Centos')
				if [ "${DISTROVERSION}" == 7 ]; then
					OSSupported="no";
				fi
				if [ "${DISTROVERSION}" == 8 ]; then
					OSSupported="no";
				fi
				if [ "${DISTROVERSION}" == 9 ]; then
					OSSupported="yes";
				fi
				if [ "${DISTROVERSION}" == 10 ]; then
					OSSupported="yes";
				fi
			;;
			'Debian')
				if [ "${DISTROVERSION}" == 11 ]; then
					OSSupported="yes";
				fi
				if [ "${DISTROVERSION}" == 12 ]; then
					OSSupported="yes";
				fi
				if [ "${DISTROVERSION}" == 13 ]; then
					OSSupported="yes";
				fi
			;;
			'Ubuntu')
				if [[ "${DISTROVERSION}" =~ 18.04 ]] || [[ "${DISTROVERSION}" =~ 20.04 ]] ; then
					OSSupported="no";
				fi
				if [[ "${DISTROVERSION}" =~ 22.04 ]] || [[ "${DISTROVERSION}" =~ 24.04 ]]; then
					OSSupported="yes";
				fi
			;;
		esac
	}
	function ListSupportedOS(){
			echo " > CentOS Stream 9"
			echo " > CentOS Stream 10"
			echo " > AlmaLinux 9"
			echo " > AlmaLinux 10"
			echo " > Debian 11"
			echo " > Debian 12"
			echo " > Debian 13"
			echo " > Ubuntu 22.04 LTS"
			echo " > Ubuntu 24.04 LTS"
	}
	# GET Somnode VERSION
	function SomnodeVersion(){
        if [ ! -z "${CustomVersion}" ]; then
            echo "${CustomVersion}";
            return;
        fi
		if [ "${1}" == "" ]; then
			echo `wget -qO- "https://www.Somnode.net/mcp-updates/latest.php?release=${SomnodeRelease}&latest=true"`;
		else
			echo `wget -qO- "https://www.Somnode.net/mcp-updates/latest.php?release=${1}&latest=true"`;
		fi
	}
	# Check License Key
	function SomnodeCheckLicense(){
		VALIDUPGRADES=`wget https://www.Somnode.net/portal/validateupgrade.php?license=${1} --no-check-certificate -qO-`;
		if [ "${VALIDUPGRADES}" == "Invalid License" ]; then
			DisplayBanner
			echo ""
      echo "Please enter your Somnode License Key:";
      read SomnodeLicense
      SomnodeCheckLicense ${SomnodeLicense}
			return;
		fi
    # Force LTS version only for expired support and upgrades
    if [[ "${VALIDUPGRADES}" == "Your perpetual support & upgrades package is expired." ]]; then
      setReleaseBranch lts
      return;
    fi
		if [ "${VALIDUPGRADES}" != "UpgradeAvailable" ]; then
			DisplayBanner
			echo "";
			echo "License Error: ${VALIDUPGRADES}";
			echo "Contact accounts for more information: https://www.Somnode.net/portal/submitticket.php"
			echo ""
      echo "Please enter your Somnode License Key:";
      read SomnodeLicense
      SomnodeCheckLicense ${SomnodeLicense}
		fi
	}
	# HEADER
	function DisplayHeader(){
		clear;
		echo ""
		echo "-----------------------------------------------------------"
		echo ""
		echo " ${1}";
		echo ""
		echo "-----------------------------------------------------------"
		echo "";
	}
	function DisplayLine(){
		echo "-----------------------------------------------------------";
	}
	function DisplayBanner(){
		if [ "${isSilent}" != "1" ]; then
			clear;
		fi
		echo "       __  __          _ _        ____ ____  "
		echo "      |  \/  | ___  __| (_) __ _ / ___|  _ \ "
		echo "      | |\/| |/ _ \/ _\` | |/ _\` | |   | |_) |"
		echo "      | |  | |  __/ (_| | | (_| | |___|  __/ "
		echo "      |_|  |_|\___|\__,_|_|\__,_|\____|_|    "
		echo ""
		echo "      ___ _   _ ____ _____  _    _     _     "
		echo "     |_ _| \\ | / ___|_   _|/ \\  | |   | |    "
		echo "      | ||  \\| \\___ \\ | | / _ \\ | |   | |    "
		echo "      | || |\\  |___) || |/ ___ \\| |___| |___ "
		echo "     |___|_| \\_|____/ |_/_/   \\_\\_____|_____|"
		echo ""
		echo ""
		echo ""
	}
	function SignalAbortInstall(){
		echo "SIGNAL: ABORT INSTALLATION";
		return 1;
	}
	function SignalCompletedInstall(){
		echo "SIGNAL: COMPLETED INSTALLATION";
	}
function LoadResource {
	echo "Loading resource ${SETUPPATH}/resources/${1} ..."
	if [[ "${2}" == "" ]]; then
	    wget -q ${SETUPPATH}/resources/${1};
	else
	    wget -q -O ${2} ${SETUPPATH}/resources/${1};
        if [[ ! -f ${2} ]]; then
            echo "Failed downloading resource ${2}";
        fi
	fi
}
# PluginConfig Flussonic enable|disable
function PluginConfig {
    cd ${BasePath}/htdocs/;
    LoadResource manage_plugin.php.txt
    mv manage_plugin.php.txt manage_plugin.php
    ${PHPBINARY} manage_plugin.php $1 $2;
    rm -f /usr/local/Somnode/htdocs/manage_plugin.php;
}
function VersionSet {
	# $1 = package
	# $2 = version
	if [ ! -d ${BasePath}/versions/ ]; then
	    mkdir ${BasePath}/versions/;
	fi;
	echo $2 > ${BasePath}/versions/${1}
}
function VersionCheck {
	# $1 = package
	echo `cat ${BasePath}/versions/${1}`
}
function ReplaceString {
	sed -i "s/${2}/${3}/g" ${1}
}
function SetInstallDir {
	if [ ! -d /root/Somnode_install ]; then
		mkdir /root/Somnode_install;
	fi
	cd /root/Somnode_install;
}
function CheckDebugMode {
	if [ ${isDebug} -eq 1 ]; then echo "(DEBUG) Press return to continue";read CONFIRM; fi
}
function AutoSSLAutoInstall {
    MCPSS "Installing AutoSSL";
    # Stop any httpd/apache2/nginx before checking ports
    mkdir -p /root/Somnode_install/autossl/;
    mkdir -p ${BasePath}/certbot/;
    LoadResource autossl/pre.sh /root/Somnode_install/pre.sh;
    LoadResource autossl/post.sh /root/Somnode_install/post.sh;
    chmod +x /root/Somnode_install/autossl/*.sh;
    if ! test `which lsof`; then
      yum -y install lsof;
    fi
    # Check and run any hooks
    echo "Running AutoSSL pre hooks";
    /root/Somnode_install/pre.sh;
    if [[ -f ${BasePath}/hooks/autossl_pre.sh ]]; then
        ${BasePath}/hooks/autossl_pre.sh;
    fi
    nginxParentPid=`cat ${BasePath}/nginx/run/nginx.pid 2>/dev/null`;
    if [[ "${nginxParentPid}" -eq "" ]]; then
      CheckPorts="lsof -Pni :80 | grep 'LISTEN'";
    else
      nginxChildPids=`pgrep -P ${nginxParentPid} | tr '\n' '|' | sed 's/.$//'`
      CheckPorts="lsof -Pni :80 | grep 'LISTEN' | grep -Ev '${nginxParentPid}|${nginxChildPids}'";
    fi
    echo "Checking ports ... ";
    if [[ `eval ${CheckPorts} -c` -ne 0 ]]; then
        echo "Port 80 in use, unable to install AutoSSL";
        return
    fi
    # Run the post hooks again, because LetsEncryptInstall is going to run these hooks again
	  echo "Running AutoSSL post hooks";
	  /root/Somnode_install/post.sh;
    if [[ -f ${BasePath}/hooks/autossl_post.sh ]]; then
        ${BasePath}/hooks/autossl_post.sh;
    fi
    echo "Running LetsEncryptInstall";
    LetsEncryptInstall
}
function LetsEncryptEnable {
	skipPortCheck=`echo "${params[@]}" | grep -c 'skip-port-check'`;
	DisplayHeader "Let's Encrypt SSL Certificate Installation";
	if [ ${skipPortCheck} -eq 0 ]; then
        # Stop any httpd/apache2/nginx before running
        if [[ ! -d ${BasePath}/certbot ]]; then mkdir ${BasePath}/certbot; fi
        LoadResource autossl/pre.sh /root/Somnode_install/pre.sh;
        chmod +x /root/Somnode_install/pre.sh;
        /root/Somnode_install/pre.sh;
		# Check available ports, excluding our nginx process
    nginxParentPid=`cat ${BasePath}/nginx/run/nginx.pid 2>/dev/null`;
    if [[ "${nginxParentPid}" -eq "" ]]; then
      CheckPorts="lsof -Pni :80 | grep 'LISTEN' | grep -Ev '${nginxParentPid}'";
    else
      nginxChildPids=`pgrep -P ${nginxParentPid} | tr '\n' '|' | sed 's/.$//'`
      CheckPorts="lsof -Pni :80 | grep 'LISTEN' | grep -Ev '${nginxParentPid}|${nginxChildPids}'";
    fi
    if [[ `eval ${CheckPorts} -c` -ne 0 ]]; then
          echo "Setup has detected the following processes using port 80";
          echo "";
          echo "In order to validate your domain for a free Lets Encrypt SSL certificate";
          echo "you must first stop any process that is using port 80 on your server.";
          echo "";
          eval ${CheckPorts};
          echo "";
          echo "[Press return to continue]";
          exit;
      fi
	fi
	DisplayHeader "Lets Encrypt Certificate Installation"
	## Retrieve Domain Name from application
	GetDomain
	if [ "${DOMAIN}" == "" ]; then
		echo "Please enter the domain name to install on: [www.yourdomain.com]";
		read DOMAIN;
        while true
        do
            DOMAIN=`echo ${DOMAIN} | grep -P '(?=^.{5,254}$)(^(?:[a-zA-Z0-9_\-]{1,63}\.?)+\.(?:[a-z]{2,})$)'`;
            if [ ! "${DOMAIN}" == "" ]; then
                break;
            fi
            echo "";
            echo "Invalid domain, please enter a valid domain or sub-domain name:";
            read DOMAIN;
        done
	    echo "${DOMAIN}" > ${BasePath}/Somnode.domain
	fi
    LetsEncryptUpdatePanelURL="y";
    LetsEncryptInstall
	# Rerun Flussonic Config
	if [ -d /opt/flussonic ]; then
		RemoteScript ${SETUPPATH}/flussonic config;
	fi
    # Run the post hooks again, because LetsEncryptInstall is going to run these hooks again
	echo "Running AutoSSL post hooks";
    if [[ -f ${BasePath}/hooks/autossl_post.sh ]]; then
        ${BasePath}/hooks/autossl_post.sh;
    fi
	echo "Complete";
	${BasePath}/service restart;
	echo "";
}
function GetDomain {
	if [ "${DOMAIN}" == "" ]; then
        INSTALLED=`${BasePath}/php/bin/php -r 'require("/usr/local/Somnode/htdocs/database.php"); echo isset($db_host)?"Y":"N";'`
        if [ "${INSTALLED}" == "Y" ]; then
            DOMAIN=`${BasePath}/php/bin/php -r 'require("/usr/local/Somnode/htdocs/database.php"); echo $setting["panel_url"];' | awk -F/ '{print $3}'  | awk -F: '{print $1}'`
        else
            DOMAIN=`cat ${BasePath}/Somnode.domain`;
        fi
        DOMAIN=`echo ${DOMAIN} | awk '{print tolower($0)}'`
        echo "${DOMAIN}" > ${BasePath}/Somnode.domain
	fi
}
function LetsEncryptInstall {
  DetectOS
  DetectOSMajor
    # Check and run any hooks
    echo "Running AutoSSL pre hooks";
    if [[ -f ${BasePath}/hooks/autossl_pre.sh ]]; then
        ${BasePath}/hooks/autossl_pre.sh;
    fi
	## Retrieve Domain Name
	GetDomain
	if [ "${DOMAIN}" == "" ]; then
	    echo "Unable to determine domain name, exiting.";
	    return;
	fi
	echo "Installing certbot ..";
	if [ ! -d ${BasePath}/certbot/ ]; then mkdir ${BasePath}/certbot; fi
	cd ${BasePath}/certbot/;
  if ! test `which snap`; then
    if [[ "${DISTRO}" == "Centos" ]]; then
      yum -y remove certbot;
      yum -y install snapd;
      systemctl enable --now snapd.socket
    else
      apt-get install snapd -V -y --force-yes;
      apt-get remove certbot -V -y --force-yes;
    fi
  fi
  systemctl restart snapd;
  ldconfig;
  if [[ "${DISTRO}" == "Debian" ]] && [[ ! `snap list core 2>/dev/null` ]]; then
    snap install core;
    snap refresh core;
  fi
  if [[ ! -L /snap ]] && [[ ! -d /snap ]]; then ln -s /var/lib/snapd/snap /snap; fi
  if ! test `which certbot`; then snap install --classic certbot; fi
  if [[ -L /snap/bin/certbot ]]; then
    if [[ ! -L /snap/bin/certbot ]]; then ln -s /snap/bin/certbot /usr/bin/certbot; fi
    if [[ -L ${BasePath}/certbot/certbot ]] || [[ -f ${BasePath}/certbot/certbot ]]; then rm -f certbot; fi
    ln -s /snap/bin/certbot ${BasePath}/certbot/certbot;
  elif [[ "${DISTRO}" == "Centos" ]]; then
    yum -y install certbot;
    if [[ -L ${BasePath}/certbot/certbot ]] || [[ -f ${BasePath}/certbot/certbot ]]; then rm -f certbot; fi
    ln -s /usr/bin/certbot ${BasePath}/certbot/certbot;
  fi
  sudo chmod 0755 ${BasePath}/certbot;
	sudo chown -R Somnode:Somnode ${BasePath}/certbot;
	if [ -d ${BasePath}/letsencrypt.disabled/ ]; then mv ${BasePath}/letsencrypt.disabled/ ${BasePath}/letsencrypt/; fi
    # Create Pre and Post hook scripts
    AutoSSLCreateHooks;
    # Check and allow firewall rule
    if [[ -f /bin/firewall-cmd ]] && [[ `firewall-cmd --state 2>&1` == "running" ]]; then
        firewall-cmd --add-port=80/tcp --permanent
        firewall-cmd --reload
    fi
    # Attempt installation
    ./certbot certonly \
    --register-unsafely-without-email -d ${DOMAIN} \
    --agree-tos --standalone \
    --preferred-challenges http-01 \
    --config-dir ${BasePath}/letsencrypt \
    --non-interactive \
    --keep-until-expiring \
    --agree-tos \
    --pre-hook=${BasePath}/certbot/pre.sh \
    --post-hook=${BasePath}/certbot/post.sh \
    --deploy-hook ${BasePath}/certbot/deploy_wrapper.sh;
    RETVAL=($?);
	if [[ ${RETVAL} -ne 0 ]] || [[ ! -f "${BasePath}/letsencrypt/live/${DOMAIN}/cert.pem" ]]; then
	  echo "";
		echo "ERROR: AutoSSL Installation has failed";
		return 1;
	fi
	# Update Panel URL
	if [[ "${LetsEncryptUpdatePanelURL}" == "y" ]]; then
        cd ${BasePath}/htdocs/
        DBPREFIX=`${BasePath}/php/bin/php -r 'require "database.php"; echo $db_prefix;'`
        MYSQLCONNECTION="sudo -u Somnode ${BasePath}/mysql/bin/mysql --protocol=SOCKET --socket=${BasePath}/mysql/data/mysql.sock --user=root Somnode";
        echo "UPDATE ${DBPREFIX}settings SET value = REPLACE(value, 'http:','https:') WHERE setting = 'panel_url';" | ${MYSQLCONNECTION};
        cd /root/Somnode_install;
	fi
  echo "Configuring Web Service";
	AutoSSLConfigWeb
	echo "Configuring Cron";
	AutoSSLInstallCronjob
	chown Somnode:Somnode -R ${BasePath}/letsencrypt
}
function AutoSSLCreateHooks {
    if [[ -f /usr/local/Somnode/WowzaStreamingEngine.sh ]]; then
        rm -f /usr/local/Somnode/WowzaStreamingEngine.sh;
    fi
    if [[ -d /usr/local/WowzaStreamingEngine/ ]]; then
        wget ${SETUPPATH}/wowzastreamingengine -O /usr/local/Somnode/WowzaStreamingEngine.sh;
        chown Somnode:Somnode /usr/local/Somnode/WowzaStreamingEngine.sh;
        chmod +x /usr/local/Somnode/WowzaStreamingEngine.sh;
    fi
    # Create Pre-Hook to stop nginx
    CBPATH=/usr/local/Somnode/certbot/;
    LoadResource autossl/pre.sh ${CBPATH}/pre.sh
    LoadResource autossl/post.sh ${CBPATH}/post.sh
    LoadResource autossl/deploy.sh ${CBPATH}/deploy.sh
    LoadResource autossl/deploy_wrapper.sh ${CBPATH}/deploy_wrapper.sh
    chmod +x ${CBPATH}/*.sh;
}
function AutoSSLConfigWeb {
	DOMAIN=`cat ${BasePath}/Somnode.domain`;
	if [ -f ${BasePath}/letsencrypt/live/${DOMAIN}/fullchain.pem ]; then
	  echo "Reapplying autossl configurations"
		rm -f ${BasePath}/nginx/fullchain.pem;
		rm -f ${BasePath}/nginx/server.pem;
		rm -f ${BasePath}/nginx/server.key;
		rm -f ${BasePath}/icecast2/icecast.cert;
		ln -s ${BasePath}/letsencrypt/live/${DOMAIN}/fullchain.pem ${BasePath}/nginx/fullchain.pem;
		ln -s ${BasePath}/letsencrypt/live/${DOMAIN}/cert.pem ${BasePath}/nginx/server.pem;
		ln -s ${BasePath}/letsencrypt/live/${DOMAIN}/privkey.pem ${BasePath}/nginx/server.key;
		if [[ ! -d ${BasePath}/content/certs/ ]]; then mkdir ${BasePath}/content/certs/; fi
		chown Somnode:Somnode ${BasePath}/content/certs/;
		if [[ -f ${BasePath}/content/certs/${DOMAIN}.crt ]]; then rm -f ${BasePath}/content/certs/${DOMAIN}.crt; fi
		if [[ -f ${BasePath}/content/certs/${DOMAIN}.key ]]; then rm -f ${BasePath}/content/certs/${DOMAIN}.key; fi
		ln -s ${BasePath}/letsencrypt/live/${DOMAIN}/fullchain.pem ${BasePath}/content/certs/${DOMAIN}.crt;
		ln -s ${BasePath}/letsencrypt/live/${DOMAIN}/privkey.pem ${BasePath}/content/certs/${DOMAIN}.key;
		cat ${BasePath}/nginx/server.key > ${BasePath}/icecast2/icecast.cert;
		cat ${BasePath}/nginx/fullchain.pem >> ${BasePath}/icecast2/icecast.cert;
		echo "" > ${BasePath}/nginx/conf.d/ssl.conf;
		echo "ssl on;" >> ${BasePath}/nginx/conf.d/ssl.conf
		echo "ssl_certificate ${BasePath}/nginx/fullchain.pem;" >> ${BasePath}/nginx/conf.d/ssl.conf;
		echo "ssl_certificate_key ${BasePath}/nginx/server.key;" >> ${BasePath}/nginx/conf.d/ssl.conf;
		echo "ssl_session_cache shared:le_nginx_SSL:1m;" >> ${BasePath}/nginx/conf.d/ssl.conf;
		echo "ssl_session_timeout 1440m;" >> ${BasePath}/nginx/conf.d/ssl.conf;
		echo "error_page 497 =307 https://${DOMAIN}:\$server_port\$request_uri;" >> ${BasePath}/nginx/conf.d/ssl.conf;
		# ProFTPD SSL
		if [[ ! -d ${BasePath}/proftpd/etc.d/ ]]; then mkdir -p ${BasePath}/proftpd/etc.d/; fi
    if [[ -f ${BasePath}/proftpd/etc.d/20_ssl.conf ]]; then rm -f ${BasePath}/proftpd/etc.d/20_ssl.conf; fi
    LoadResource proftpd.ssl.conf.txt
    mv proftpd.ssl.conf.txt ${BasePath}/proftpd/etc.d/20_ssl.conf;
    chmod 700 -R ${BasePath}/proftpd/etc.d/20_ssl.conf;
		# Auto Re-Configure Flussonic SSL
		if [ -d /opt/flussonic ] && [ ! -f /etc/flussonic/flussonic.crt ]; then
			RemoteScript ${SETUPPATH}/flussonic config;
		fi
	else
	  echo "AutoSSL not detected."
	fi
}
function AutoSSLInstallCronjob {
	CRON="0 0 * * * root DOMAIN=`cat ${BasePath}/Somnode.domain` && ${BasePath}/certbot/certbot --standalone --config-dir ${BasePath}/letsencrypt renew --non-interactive --pre-hook=${BasePath}/certbot/pre.sh --post-hook=${BasePath}/certbot/post.sh --deploy-hook ${BasePath}/certbot/deploy_wrapper.sh >>/usr/local/Somnode/log/autossl/autossl.log 2>&1;";
  if ! grep -R "${CRON}" /etc/crontab > /dev/null
  then
    sed -i '/\/usr\/local\/Somnode\/certbot\/certbot/d' /etc/crontab;
    echo "${CRON}" >> /etc/crontab
  fi
}
function AutoSSLCheckCron {
  CRON="0 0 * * * root DOMAIN=`cat ${BasePath}/Somnode.domain` && ${BasePath}/certbot/certbot --standalone --config-dir ${BasePath}/letsencrypt renew --non-interactive --pre-hook=${BasePath}/certbot/pre.sh --post-hook=${BasePath}/certbot/post.sh --deploy-hook ${BasePath}/certbot/deploy_wrapper.sh >>/usr/local/Somnode/log/autossl/autossl.log 2>&1;";
	if ! grep -R "${CRON}" /etc/crontab > /dev/null
	then
	    AutoSSLCreateHooks
		  AutoSSLInstallCronjob
	fi
}
function AutoSSLHealthCheck {
  if [[ ! -d ${BasePath}/letsencrypt ]]; then
    return;
  fi
  # If certbot path does not exist, lets try to install the latest and best method of certbot
  if [[ ! -f ${BasePath}/certbot/certbot ]] && [[ -f ${BasePath}/certbot/certbot-auto ]]; then
	  AutoSSLAutoInstall
	fi
  AutoSSLCheckCron
}
function LetsEncryptDisable {
	echo "Disabling Lets Encrypt ...";
	echo "" > ${BasePath}/nginx/conf.d/ssl.conf;
	rm -f ${BasePath}/proftpd/etc.d/20_ssl.conf;
	mv ${BasePath}/letsencrypt/ ${BasePath}/letsencrypt.disabled/;
	# Configure WSE
	if [[ -d /usr/local/WowzaStreamingEngine ]]; then
        LoadResource wseConfig.php.txt
        mv wseConfig.php.txt wseConfig.php
        ${PHPBINARY} wseConfig.php disableAutoSSL
    fi
    # Uninstall Icecast
    mv /usr/local/Somnode/icecast2/icecast.cert /usr/local/Somnode/icecast2/icecast.cert.backup;
	# Update Panel URL
	cd ${BasePath}/htdocs/
	DBPREFIX=`${BasePath}/php/bin/php -r 'require "database.php"; echo $db_prefix;'`
	MYSQLCONNECTION="sudo -u Somnode ${BasePath}/mysql/bin/mysql --protocol=SOCKET --socket=${BasePath}/mysql/data/mysql.sock --user=root Somnode";
	echo "UPDATE ${DBPREFIX}settings SET value = REPLACE(value, 'https:','http:') WHERE setting = 'panel_url';" | ${MYSQLCONNECTION};
	cd /root/Somnode_install;
	${BasePath}/service restart;
	echo "Complete.";
}
function RemoteScript {
	URL=$1;
	FILENAME=$(basename -- "${URL}");
	mkdir -p /root/Somnode_install;
	if [ -f /root/Somnode_install/${FILENAME} ]; then rm -f /root/Somnode_install/${FILENAME}; fi
	wget ${URL} -O /root/Somnode_install/${FILENAME};
	chmod +x /root/Somnode_install/${FILENAME};
	echo "Running /root/Somnode_install/${FILENAME};";
	/root/Somnode_install/${FILENAME} ${2} ${3};
}
function TrimText() {
	echo $1 | awk '{ gsub(/^[ \t]+|[ \t]+$/, ""); print }'
}
function ProgressBar() {
	Title=$1
	Percentage=`[ -n "${2}" ] && echo $2 || echo 0`
	Divisible=4;
	Progress=$((Percentage / Divisible))
	Current=0;
	Max=50;
	echo -ne " ${Title}";
	for x in {1..35} ; do
		if [ "${x}" -gt "${#Title}" ]; then
	        echo -ne " ";
	    fi
	done ;
	echo -ne " [";
	for x in {1..25} ; do
		if [ "${x}" -le "${Progress}" ]; then
	        echo -ne "#";
	    else
	        echo -ne " ";
	    fi
	done ;
	echo -ne "] ${Percentage}%";
	echo "";
}
function DetermineProgress(){
	Progress='';unset Progress;array='';unset array;Logfile='';unset Logfile;
	Logfile=$1
	if [ ! -f "${Logfile}" ]; then echo "0"; return; fi
	Progression=`awk '/MCPSP/ {a=$0} END{print a}' ${Logfile}`;
	IFS=':' read -r -a array <<< "${Progression}";
	Progress="${array[1]}";
	if [ -z "${Progress}" ]; then echo "0"; return; fi
	if [ "${Progress}" -gt "0" ]; then
		echo ${Progress};
	else
		echo "0";
	fi
}
function DetermineStatus(){
	Logfile=$1
	if [ ! -f "${Logfile}" ]; then echo "0"; return; fi
	StatusMSG=`awk '/MCPSS/ {a=$0} END{print a}' ${Logfile}`;
	IFS=':' read -r -a array <<< "${StatusMSG}";
	StatusMSG="${array[1]}";
	if [ -n "${StatusMSG}" ]; then
		echo ${StatusMSG};
	else
		echo "";
	fi
}
function DetermineSleep(){
	Logfile=$1
	SleepTime=$2
	if [ ! -f "${Logfile}" ]; then echo "0"; return; fi
	MCPSetSleep=`awk '/MCPSetSleep/ {a=$0} END{print a}' ${Logfile}`;
	IFS=':' read -r -a array <<< "${MCPSetSleep}";
	NewSleepTime="${array[1]}";
	if [ -n "${NewSleepTime}" ]; then
		echo ${NewSleepTime};
		return;
	fi
	echo "${SleepTime}";
}
function GetStatus(){
	if [ -f /root/Somnode_install/status/${1} ]; then
			echo `cat /root/Somnode_install/status/${1} 2>/dev/null`;
		else
			echo 0;
	fi
}
function GetSlowInstallStatus(){
	echo `cat /root/.mcpslowinstall 2>/dev/null`;
}
export StatusMessage='';
function RenderInstallStatusScreen(){
	ShowRemaining=$1
	if [ "${ShowRemaining}" == "" ]; then ShowRemaining=1; fi
	StatusInstallPrerequisites=`GetStatus StatusInstallPrerequisites`;
	StatusInstallFFMPEG=`GetStatus StatusInstallFFMPEG`;
	StatusInstallWebService=`GetStatus StatusInstallWebService`;
	StatusInstallIcecast=`GetStatus StatusInstallIcecast`;
	StatusInstallLiquidSoap=`GetStatus StatusInstallLiquidSoap`;
	StatusInstallSomnode=`GetStatus StatusInstallSomnode`;
	StatusInstallWowza=`GetStatus StatusInstallWowza`;
	StatusInstallFlussonic=`GetStatus StatusInstallFlussonic`;
	StatusInstallNginxRtmp=`GetStatus StatusInstallNginxRtmp`;
	clear;
	DisplayHeader "Somnode Software Installation";
	ProgressBar "Installing Prerequisites" "${StatusInstallPrerequisites}";
	ProgressBar "Installing FFMPEG" ${StatusInstallFFMPEG};
	ProgressBar "Installing Web Service" ${StatusInstallWebService};
	ProgressBar "Installing Icecast" ${StatusInstallIcecast};
	ProgressBar "Installing LiquidSoap" ${StatusInstallLiquidSoap};
	ProgressBar "Installing Somnode" ${StatusInstallSomnode};
	if [ "${InstallWSE}" == "y" ]; then
		ProgressBar "Installing Wowza Streaming Engine" ${StatusInstallWowza};
	fi
	if [ "${InstallFlu}" == "y" ]; then
		ProgressBar "Installing Flussonic" ${StatusInstallFlussonic};
	fi
	if [ "${InstallNginxRtmp}" == "y" ]; then
		ProgressBar "Installing Somnode Video" ${StatusInstallNginxRtmp};
	fi
	echo "";
	if [ -n "${StatusMessage}" ]; then
		echo " Current Status: ${StatusMessage}";
	fi
	echo "";
	echo " % Please Wait %";
}
function RenderUpdateStatusScreen(){
	ShowRemaining=$1
	if [ "${ShowRemaining}" == "" ]; then ShowRemaining=1; fi
	StatusUpdatePrerequisites=`GetStatus StatusUpdatePrerequisites`;
	StatusUpdateFFMPEG=`GetStatus StatusUpdateFFMPEG`;
	StatusUpdateBackup=`GetStatus StatusUpdateBackup`;
	StatusUpdatePreupgradeScript=`GetStatus StatusUpdatePreupgradeScript`;
	StatusUpdateWeb=`GetStatus StatusUpdateWeb`;
	StatusUpdateWowza=`GetStatus StatusUpdateWowza`;
	StatusUpdateFlussonic=`GetStatus StatusUpdateFlussonic`;
	StatusUpdateNginxRtmp=`GetStatus StatusUpdateNginxRtmp`;
	StatusUpdateIcecast=`GetStatus StatusUpdateIcecast`;
	StatusUpdateLiquidSoap=`GetStatus StatusUpdateLiquidSoap`;
	StatusUpdateSomnode=`GetStatus StatusUpdateSomnode`;
	clear;
	if [ "${MCPVERSION}" == "" ]; then
		DisplayHeader "Somnode Software Upgrade";
	else
		DisplayHeader "Somnode Software Upgrade to ${SomnodeRelease} ${MCPVERSION}";
	fi
	ProgressBar "Backup Somnode" "${StatusUpdateBackup}";
	ProgressBar "Prerequisites" "${StatusUpdatePrerequisites}";
	ProgressBar "FFMPEG" "${StatusUpdateFFMPEG}";
	ProgressBar "Web Services" ${StatusUpdateWeb};
	if [ -d /usr/local/WowzaStreamingEngine ]; then
		ProgressBar "Wowza Streaming Engine" ${StatusUpdateWowza};
	fi
	if [ -f /etc/flussonic/flussonic.conf ]; then
		ProgressBar "Flussonic Media Server" ${StatusUpdateFlussonic};
	fi
	if [ -d /usr/local/Somnode/nginx-rtmp/ ]; then
		ProgressBar "Somnode Video" ${StatusUpdateNginxRtmp};
	fi
	ProgressBar "Icecast" ${StatusUpdateIcecast};
	ProgressBar "LiquidSoap" ${StatusUpdateLiquidSoap};
	ProgressBar "Somnode" ${StatusUpdateSomnode};
	echo "";
	if [ -n "${StatusMessage}" ]; then
		echo " Current Status: ${StatusMessage}";
	fi
	echo "";
	echo " % Please Wait %";
}
function UpdateInstallStatusScreen(){
	InstallOrUpdate=$1
	StatusVariable=$2
	LogFile=$3
	SleepTime=$4
	if [ "${SleepTime}" == "" ]; then SleepTime=5; fi
	StatusMessage="";
	LogFileSize=0;
	LastLogFileSize=0;
	FileLastUpdated=0;
	InstallStatusTimeout=450;
	if [ -f /root/.mcpslowinstall ]; then InstallStatusTimeout=1200; fi
	mkdir -p /root/Somnode_install/status/;
	# SILENT INSTALLATION SUPPORT
	isSilent=`cat /root/Somnode_install/isSilent 2>/dev/null`;
	while true
	do
		Status=`DetermineProgress ${LogFile}`;
		echo ${Status} > /root/Somnode_install/status/${StatusVariable}
		StatusMessage=`DetermineStatus ${LogFile}`
		SleepTime=`DetermineSleep ${LogFile} ${SleepTime}`;
		LogFileSize=`stat -c%s "$LogFile" 2>/dev/null || echo 0`
		if [[ "${isSilent}" == "1" ]]; then
			if [ -f "${LogFile}" ]; then
				if [ "${LogFileSize}" -gt "${LastLogFileSize}" ]; then
					tail -c +$((LastLogFileSize+1)) "${LogFile}"
				fi
			fi
		else
			if [ "${InstallOrUpdate}" == "Install" ]; then
				RenderInstallStatusScreen
			else
				RenderUpdateStatusScreen
			fi
		fi
		if grep -q 'MCPSP:100' "${LogFile}" 2>/dev/null; then
			echo "100" > /root/Somnode_install/status/${StatusVariable}
			break;
		fi
		if grep -q 'SIGNAL: COMPLETED INSTALLATION' "${LogFile}" 2>/dev/null; then
			echo "100" > /root/Somnode_install/status/${StatusVariable}
			break;
		fi
		if grep -q 'SIGNAL: ABORT INSTALLATION' "${LogFile}" 2>/dev/null; then
			rm -f ${BasePath}/htdocs/.maintenance;
			echo ""
			echo "Installation Failed.";
			echo "-------------------------------";
			tail -15 ${LogFile};
			echo "-------------------------------";
			echo "";
			echo "Please check the log file for more information:";
			echo ${LogFile};
			exit;
		fi
		# Make sure install is not stalled
		FileLastUpdated=$((FileLastUpdated+SleepTime));
		if [ "${LogFileSize}" -gt "${LastLogFileSize}" ]; then
			FileLastUpdated=0;
		fi
		LastLineProcessing="$(tail -n 1 -- "$LogFile" | grep -Eic '(installed|processing|gathering)')"
		if [[ "${FileLastUpdated}" -gt "${InstallStatusTimeout}" ]] && [[ $LastLineProcessing -lt 0 ]]; then
			rm -f ${BasePath}/htdocs/.maintenance;
			echo ""
			echo "Installation Failed.";
			echo "-------------------------------";
			tail -15 ${LogFile};
			echo "-------------------------------";
			echo "";
			echo "Please check log file for more information:";
			echo ${LogFile};
			exit;
		fi
		LastLogFileSize=${LogFileSize}
		sleep ${SleepTime};
	done
	return 0;
}
ShowMcpProgress="1";
function MCPSP(){
	if [[ "${ShowMcpProgress}" == "0" ]]; then return; fi
	echo "MCPSP:${1}";
}
function MCPSS(){
	if [[ "${ShowMcpProgress}" == "0" ]]; then echo $1; return; fi
	echo "MCPSS:${1}";
}
function MCPSetSleepTime(){
	if [[ "${ShowMcpProgress}" == "0" ]]; then return; fi
	echo "MCPSetSleep:${1}";
}
function GetEnvironmentSetup(){
# Environment Variables
	DetectOS;
	DetectOSMajor;
	IsOSSupported;
	KERNEL=`uname -r`
	MACH=`uname -m`
	ARCH=$(getconf LONG_BIT)
	SomnodeRelease="stable"
	isBeta=`cat /root/Somnode_install/isBeta 2>/dev/null`;
	isLatest=`cat /root/Somnode_install/isLatest 2>/dev/null`;
	isStable=`cat /root/Somnode_install/isStable 2>/dev/null`;
	isLts=`cat /root/Somnode_install/isLts 2>/dev/null`;
	isSilent=`cat /root/Somnode_install/isSilent 2>/dev/null`;
	if [ -f ${BasePath}/versions/release_branch ]; then
		SomnodeRelease=`cat ${BasePath}/versions/release_branch &`;
	fi
    # Set BETA Setup and mirror if isBeta
	if [[ "${isBeta}" == "1" ]] || [[ "${SomnodeRelease}" == "beta" ]]; then
		SETUPPATH=`echo ${BETASETUPPATH}`;
		MIRROR=`echo ${BETAMIRROR}`;
	fi
	# Command line override
	if [ "${isBeta}" == "1" ]; then
		SomnodeRelease="beta"
	fi
	if [ "${isStable}" == "1" ]; then
		SomnodeRelease="stable"
	fi
	if [ "${isLatest}" == "1" ]; then
		SomnodeRelease="latest"
	fi
	if [ "${isLts}" == "1" ]; then
		SomnodeRelease="lts"
	fi
	MCPVERSION=`SomnodeVersion`;
}
function version_gt() { test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"; }
function setReleaseBranch() {
    echo "Set release branch to ${1}";
	SomnodeRelease=${1};
	rm -f /root/Somnode_install/isStable /root/Somnode_install/isBeta /root/Somnode_install/isLatest /root/Somnode_install/isLts;
	echo "1" > /root/Somnode_install/is${SomnodeRelease^};
	GetEnvironmentSetup
}
function Output(){
    text=$1
    color=$2
    if [[ "${color}" == "" ]]; then
        color="black";
        return;
    fi
    ansiColor='\033[0m'; # Set default
    case $color in
        'red')
            ansiColor='\033[0;31m';
        ;;
        'green')
            ansiColor='\033[0;32m';
        ;;
        'blue')
            ansiColor='\033[01;34m';
        ;;
        'black'|'default')
            ansiColor='\033[0m';
        ;;
    esac
    echo -e "${ansiColor}${text}\033[0m"
}
function DebianInstallPackages(){
  # Attempt single line install, then fallback to individual package installs
  export DEBIAN_FRONTEND=noninteractive
  echo "Building apt install package list"
  for i in $1
    do
       if [ -z "$(apt-cache madison $i 2>/dev/null)" ]; then
         echo " > Package $i not available on repo."
       else
         echo " > Add package $i to the install list"
       packages="$packages $i"
       fi
   done
  echo "Installing $packages" #you could comment this.
  if ! apt-get install --ignore-missing -V -y --force-yes $packages; then
    for i in $packages; do apt-get -o DPkg::Options::="--force-confdef" install --ignore-missing -V -y --force-yes $i; done
  fi
}
	function ImportCentova(){
	    clear;
	    echo "Running params: $@"
      CentovaImportLimit=0;
      CentovaImportAccounts="";
      for i in "$@"; do
        case $i in
          '--single')
              CentovaImportSingle=1;
              shift
              ;;
          '--no-restart')
              CentovaNoRestart=1;
              shift
              ;;
          '--icecast-kh')
              CentovaIcecastKH=1;
              shift
              ;;
          '--force-ices-liquidsoap')
              ForceIcesLiquidsoap=1;
              shift
              ;;
          '--preserve-ip-address')
              PreserveIpAddress=1;
              shift
              ;;
          --limit=*)
              CentovaImportLimit="${i#*=}"
              shift
              ;;
          --accounts=*)
              CentovaImportAccounts="${i#*=}"
              shift
              ;;
          esac
        done
        echo "Downloading import script ..."
        if [[ -f /usr/local/Somnode/htdocs/system/importers/centovacast.php ]]; then rm -f /usr/local/Somnode/htdocs/system/importers/centovacast.php; fi
        LoadResource importers/centovacast.php.txt;
        mkdir -p /usr/local/Somnode/htdocs/system/importers/;
        mv centovacast.php.txt /usr/local/Somnode/htdocs/system/importers/centovacast.php
        # Automatically retrieve database connection details from /usr/local/centovacast/etc/centovacast.conf
        echo "Fetch centovacast configuration"
        source <(grep 'DB_\|LOCALE' /usr/local/centovacast/etc/centovacast.conf)
        # Set DB_PASS separately
        DB_HOST=`awk -F "=" '/^DB_HOST/ {gsub(/[ \t]/, "", $2); print $2}' /usr/local/centovacast/etc/centovacast.conf`
        DB_USER=`awk -F "=" '/^DB_USER/ {gsub(/[ \t]/, "", $2); print $2}' /usr/local/centovacast/etc/centovacast.conf`
        DB_PASS=`awk -F "=" '/^DB_PASS/ {gsub(/[ \t]/, "", $2); print $2}' /usr/local/centovacast/etc/centovacast.conf`
        DB_NAME=`awk -F "=" '/^DB_NAME/ {gsub(/[ \t]/, "", $2); print $2}' /usr/local/centovacast/etc/centovacast.conf`
        echo "Running import script"
        cd /usr/local/Somnode/htdocs/system/importers/;
        /usr/local/Somnode/php/bin/php /usr/local/Somnode/htdocs/system/importers/centovacast.php \
        --DB_HOST=${DB_HOST} \
        --DB_USER=${DB_USER} \
        --DB_PASS=${DB_PASS} \
        --DB_NAME=${DB_NAME} \
        --LOCALE=${LOCALE} \
        --NO-RESTART=${CentovaNoRestart} \
        --SINGLE=${CentovaImportSingle} \
        --ICECAST-KH=${CentovaIcecastKH} \
        --FORCE-ICES-LIQUIDSOAP=${ForceIcesLiquidsoap} \
        --PRESERVE-IP-ADDRESS=${PreserveIpAddress} \
        --LIMIT=${CentovaImportLimit} \
        --ACCOUNTS=${CentovaImportAccounts}
       # Update Permissions
       echo "Updating permissions"
       chown Somnode:Somnode -R /usr/local/Somnode/content/*;
       # Apply FTP Configurations
       echo "Creating ftp accounts";
       /root/init --reset-ftp >/dev/null 2>&1;
       echo "Migration is completed"
    }
    function EnableCentovaPort(){
        echo "Enabling port 2199 in Somnode ...";
        # Add centova.conf nginx configuration to conf.d
        LoadResource centova_port.conf;
        mv centova_port.conf ${BasePath}/nginx/conf.d/centova_port.http
        ${BasePath}/nginx/sbin/nginx -s reload;
        echo "Complete";
    }
	echo "Launching centova_import.sh";
	GetEnvironmentSetup;
	# Paramaters
	for params; do
		# Check action in params
		case ${params} in
				'migrate')
					ImportCentova $@
					echo
					exit $RETVAL
					shift
					;;
				'enable-port')
					EnableCentovaPort
					echo
					exit $RETVAL
					shift
					;;
		esac
	  let i=i+1
	done

