����JFIF��� ( %"1"%)+...383,7(-.- 404 Not Found
Sh3ll
OdayForums


Server : Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.4.20
System : Linux st2.domain.com 3.10.0-1127.10.1.el7.x86_64 #1 SMP Wed Jun 3 14:28:03 UTC 2020 x86_64
User : apache ( 48)
PHP Version : 7.4.20
Disable Function : NONE
Directory :  /usr/local/FlashphonerWebCallServer/bin/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //usr/local/FlashphonerWebCallServer/bin/webcallserver
#!/bin/bash
#
# Startup script for Flashphoner WebCallServer
#
# chkconfig: - 80 20
# description: Flashphoner WebCallServer provides WEB to SIP gateway services
#
#### BEGIN INIT INFO
# Provides:          WebCallServer
# Required-Start:    $time $local_fs $remote_fs $network
# Required-Stop:     $time $local_fs $remote_fs
# Default-Start:     3 4 5
# Default-Stop:      S 0 1 2 6
# Short-Description: WebCallServer Init Script
# Description:       WebCallServer Init Script
### END INIT INFO

# Import functions from init.d
FUNCTIONS_EXIST=false
if [ -f /etc/rc.d/init.d/functions ] ; then
  . /etc/rc.d/init.d/functions
  FUNCTIONS_EXIST=true
fi
if [ -f /etc/init.d/functions ] ; then
  . /etc/init.d/functions
  FUNCTIONS_EXIST=true
fi

if ! $FUNCTIONS_EXIST ; then
  failure() {
    return 0
  }
  success() {
    return 0
  }
fi



# Global variables configuration

# Declare global variables
function declareGlobals() {
  PRODUCT=FlashphonerWebCallServer
  WCS_HOME="/usr/local/$PRODUCT"
  FLASHPHONER_USER="flashphoner"
}

# Get product name
function getProduct() {
  echo "$PRODUCT"
}

# Get WCS home directory
function getHome() {
  echo "$WCS_HOME"
}

# Get WCS user name
function getUser() {
  echo "$FLASHPHONER_USER"
}

# Get flashphoner.properties config
function getWCSConfig() {
  echo "$(getHome)/conf/flashphoner.properties"
}

# Get database.yml config
function getDatabaseYml() {
  echo "$(getHome)/conf/database.yml"
}



# Environment variables configuration

# Configure environment variables
function setUpEvironment() {
  local envConfig="$(getHome)/bin/setenv.sh"

  # Clean Java options to prevent dubbinng while re-initializing #WCS-3034
  WCS_JAVA_OPTS=""
  WCS_SERVER_OPTS=""
  [ -r "$envConfig" ] && . "$envConfig"
}

# Get Java options
function getJavaOpts() {
  echo "$WCS_JAVA_OPTS"
}

# Get server options
function getServerOpts() {
  echo "$WCS_SERVER_OPTS"
}

# Get library path
function getLdLibraryPath() {
  echo "$LD_LIBRARY_PATH"
}

# Get Java executable
function getJavaExec() {
  local javaExec=$_EXECJAVA

  if [[ "$javaExec" == "" ]]; then
    javaExec=`which java`
  fi
  echo "$javaExec"
}

# Get non root mode setting
function getNonRoot() {
  echo "$WCS_NON_ROOT"
}

# Check root mode to use in conditions
function isRootMode() {
  if [ "$(getNonRoot)" == "false" ]; then
    true; return
  else
    false; return
  fi
}

# Check non root mode to use in conditions
function isNonRootMode() {
  if [ "$(getNonRoot)" == "true" ]; then
    true; return
  else
    false; return
  fi
}

# Get PID file name depending on root mode
function getPidFile() {
  local pidFile="FlashphonerMainWebCallServer.pid"
  local pidPath=""

  if isRootMode; then
    pidPath="/var/run"
  else
    pidPath="$(getHome)/bin"
  fi
  echo "$pidPath/$pidFile"
}

# Get lock file name depending on root mode
function getLockFile() {
  local lockFile="$(getProduct)"
  local lockPath=""
 
  if isRootMode; then
    lockPath="/var/run"
    [ -w "/var/lock/subsys" ] && lockPath=/var/lock/subsys
  else
    lockPath="$(getHome)/bin"
  fi
  echo "$lockPath/$lockFile"
}

# Get file descriptors limit
function getFDLimit() {
  local fdLimit=$WCS_FD_LIMIT

  if [[ "$fdLimit" == "" ]]; then
    fdLimit=20000
  fi
  echo "$fdLimit"
}

# Get startup log file name
function getStartupLogFile() {
  local startupLogFile=$WCS_STARTUP_LOG
 
  if [[ "$startupLogFile" == "" ]]; then
    startupLogFile=$(getHome)/logs/startup.log
  fi
  echo "$startupLogFile"
}

# Get enterprise builds URL
function getEnterpriseUrl() {
  echo "$ENTERPRISE_URL"
}

# Get login to download enterprise builds
function getEnterpriseLogin() {
  echo "$ENTERPRISE_LOGIN"
}

# Get password to download enterprise builds
function getEnterprisePasswd() {
  echo "$ENTERPRISE_PASSWD"
}


# Logging functions

# Declare logging variables
function declareLog() {
  local logFile=$1

  DEBUG=${DEBUG:-false}
  DEFAULT_LOG=${DEFAULT_LOG:-}

  setDefaultLogFile $logFile
}

# Check if debug log enabled
function isDebugEnabled() {
  if [[ ! -z $DEBUG ]]; then
    $DEBUG; return
  else
    false; return
  fi
}

# Enable debug logging
function enableDebug() {
  DEBUG=true
}

# Disable debug logging
function disableDebug() {
  DEBUG=false
}

# Get default log file
function getDefaultLogFile() {
  echo "$DEFAULT_LOG"
}

# Set default log file
function setDefaultLogFile() {
  local logFile=$1

  [[ -z $logFile ]] && return 1
  if checkLogPath $logFile; then
    DEFAULT_LOG=$logFile
  fi
}

# # Check if log file path exists and make the dir if needed
function checkLogPath() {
  local logFile=$1
  local result=0

  [[ -z $logFile ]] && return 1
  logPath=$(dirname "$logFile")
  if [[ ! -d $logPath ]]; then
    mkdir -p $logPath
    result=$?
  fi
  return $result
}

# Form log timestamp
function logDate() {
  local dateToLog=`echo "[$(date '+%Y-%m-%d %H:%M:%S')]"`
 
  echo "$dateToLog"
}

# Write to a log file
function writeLog() {
  local level=$1
  local message=$2
  local logFile=$3
  local owner=$(getCurrentUser)
  local logPath=""
  local callerFuncName=""

  [[ -z $logFile ]] && logFile=$(getDefaultLogFile)
  if [[ "$level" == "" || "$message" == "" || "$logFile" == "" ]]; then
    return 1
  fi
  if [[ -f $logFile ]]; then
    owner=$(ls -l $logFile | awk '{print $3}');
  else
    checkLogPath $logFile
    [[ $? -ne 0 ]] && return 1
  fi
  # Determine caller function name
  for callerFuncName in ${FUNCNAME[@]}; do
    if [[ "$callerFuncName" == "${FUNCNAME[0]}" || "$callerFuncName" =~ ^log ]]; then
      continue
    else
      break
    fi
  done
  if [[ $owner != $(getCurrentUser) ]]; then
    # The log file is owned by someone else, try to sudo to it
    sudo -u $owner echo -e "$(logDate) $level: $message" >> $logFile
  else
    echo -e "$(logDate) $level $callerFuncName - $message" >> $logFile
  fi
 }

# Write INFO level message
function logInfo() {
  local message=$1
  local logFile=$2

  writeLog "INFO" "$message" "$logFile"
}

# Write WARN level message
function logWarn() {
  local message=$1
  local logFile=$2

  writeLog "WARN" "$message" "$logFile"
}

# Write ERROR level message
function logError() {
  local message=$1
  local logFile=$2

  writeLog "ERROR" "$message" "$logFile"
}

# Write DEBUG level message
function logDebug() {
  local message=$1
  local logFile=$2

  if isDebugEnabled; then
    writeLog "DEBUG" "$message" "$logFile"
  fi
}


# Various helper functions

# Check if user exists in system
function isUser() {
  local user=$1
  
  if [[ -z $user ]]; then
    user=$(getUser)
  fi
  if [[ "$(getent passwd $1)" =~ "^$1" ]]; then
    true; return
  else
    false; return
  fi
}

# Get current user running script
function getCurrentUser() {
  echo "$(whoami)"
}

# Get daemon type
function getDaemonType() {
  local daemonType=`ps --no-headers -o comm 1`
  echo "$daemonType"
} 

# Check if service is running
function isService() {
  # Check service only if systemd used #WCS-3034
  if [[ $(getDaemonType) != 'systemd' ]]; then
    false; return
  fi
  if systemctl is-active --quiet webcallserver.service; then
    true; return
  else
    false; return
  fi
}

# Check if the script is running from root
function isScriptRunningFromRoot() {
  if [[ "$(getCurrentUser)" == "root" ]]; then
    true; return
  else
    false; return
  fi
}

# Set file system item owner to user
function setOwner() {
  local user=$1
  local object=$2
  if [[ "$user" == "" || "$object" == "" ]]; then
    return 1
  fi
  if isScriptRunningFromRoot; then
    chown -R $user $object
  fi
}

# Get Java version
function getJavaVersion() {
  local jdkVersion=`java -version 2>&1`
  local javaFullVersion=`echo $jdkVersion | head -1 | cut -d" " -f 3 | tr -d \"`
  local javaMajor=`echo $javaFullVersion | cut -d \. -f 1`
  local javaMinor=0
  local javaVersion=0

  if [[ $javaMajor -eq 1 ]]; then
    javaMinor=`echo $java_ver | cut -d \. -f 2`
    if [[ $javaMinor -ge 8  ]]; then
      javaVersion=$javaMinor
    fi
  elif [[ $javaMajor -ge 8 ]]; then
    javaVersion=$javaMajor
  fi
  logDebug "Java version $javaVersion"
  echo "$javaVersion"
}

# Get user running the process by pid
function getUserByPid() {
  local pid=$1
  local user=`ps -o uname= -p "$pid"`
 
  logDebug "Process $pid running as user $user"
  echo "$user"
}


# Amazon cloud operations

# Declare Amazon cloud constants
function declareCloudConstants_Amazon() {
  METADATA_URL_AMAZON=${METADATA_URL_AMAZON:-"http://169.254.169.254/latest/meta-data"}
}

# Detect a cloud
function isCloud_Amazon() {
  declareCloudConstants_Amazon
  
  local kernel=$(uname -r | grep amzn)
  local os=$(cat /etc/issue | grep -e "Amazon\|AMI")
  local metadata=$(curl --max-time 1 --insecure -s -i -o /dev/null -w '%{http_code}' $METADATA_URL_AMAZON/ | grep 200)

  if [[ $kernel || $os || $metadata == "200" ]]; then
    true; return
  else
    false; return
  fi
}

# Get cloud public IP
function getPublicIp_Amazon() {
  local publicIp=$(curl -s -f $METADATA_URL_AMAZON/public-ipv4)

  if [[ $? -ne 0 ]]; then
    publicIp=""
  fi
 
  logDebug "Public ip detecting using command 'curl -s -f $METADATA_URL_AMAZON/public-ipv4'"

  echo "$publicIp"
}

# Get cloud public IP
function getPrivateIp_Amazon() {
  local privateIp=$(curl -s -f $METADATA_URL_AMAZON/local-ipv4)
 
  if [[ $? -ne 0 ]]; then
    privateIp=""
  fi
 
  logDebug "Private ip detecting using command 'curl -s -f $METADATA_URL_AMAZON/local-ipv4'"

  echo "$privateIp"
}

# Set admin password to instanse id
function setAdminPasswd_Amazon() {
  local instanceId=""

  if [ ! -d "$(getHome)/logs/server_logs" ]; then
    if grep "admin:" "$(getDatabaseYml)" > /dev/null 2>&1; then
      # Set InstanceId as admin password
      instanceId=$(echo -n $(wget -q -O - $METADATA_URL_AMAZON/instance-id) | md5sum | cut -f1 -d"-" | tr -d " ")
      sed -i -e "/admin:/s/password:\ [0-9A-Za-z]*,/password:\ $instanceId,/" "$(getDatabaseYml)"
    fi
  fi
}


# Google cloud operations

# Declare Amazon cloud constants
function declareCloudConstants_Google() {
  METADATA_URL_GOOGLE=${METADATA_URL_GOOGLE:-"http://metadata.google.internal/computeMetadata/v1/instance"}
  HEADER_GOOGLE=${HEADER_GOOGLE:-'-H Metadata-Flavor:Google'}
}

# Detect a cloud
function isCloud_Google() {
  declareCloudConstants_Google
  
  local metadata=$(curl --insecure -s -i -o /dev/null -w '%{http_code}' $HEADER_GOOGLE $METADATA_URL_GOOGLE/ | grep 200)

  if [[ $metadata == "200" ]]; then
    true; return
  else
    false; return
  fi
}

# Get cloud public IP
function getPublicIp_Google() {
  local publicIp=$(curl -s -f $HEADER_GOOGLE $METADATA_URL_GOOGLE/network-interfaces/0/access-configs/0/external-ip)

  if [[ $? -ne 0 ]]; then
    publicIp=""
  fi
 
  logDebug "Public ip detecting using command 'curl -s -f $HEADER_GOOGLE $METADATA_URL_GOOGLE/network-interfaces/0/access-configs/0/external-ip'"

  echo "$publicIp"
}

# Get cloud public IP
function getPrivateIp_Google() {
  local privateIp=$(curl -s -f $HEADER_GOOGLE $METADATA_URL_GOOGLE/network-interfaces/0/ip)
 
  if [[ $? -ne 0 ]]; then
    privateIp=""
  fi
 
  logDebug "Public ip detecting using command 'curl -s -f $HEADER_GOOGLE $METADATA_URL_GOOGLE/network-interfaces/0/ip'"

  echo "$privateIp"
}

# Set admin password to instanse id
function setAdminPasswd_Google() {
  return 0
}


# Abstarct cloud checking functions

# Declare clouds list
function declareClouds() {
  CLOUDS=(
    "Amazon"
    "Google"
  )
  CLOUD=""
}

# Get clouds list
function getClouds() {
  echo "${CLOUDS[@]}"
}

# Add cloud to list
function addCloud() {
  CLOUDS+=($1)
}

# Get current cloud name
function getCurrentCloud() {
  echo "$CLOUD"
}

# Set current cloud name
function setCurrentCloud() {
  local currentCloud=$1
  
  if [[ ! -z $currentCloud ]]; then
    CLOUD=$currentCloud
  fi
}

# Check if certain cloud detector function exists
function isCloudFunc() {
  local func=$1

  if [[ "$(declare -fF $func)" ]]; then
    true; return
  else
    false; return
  fi  
}

# Update settings to work behind NAT
function updateSettings() {
  local cloud=$1
  local wcsConfig=$(getWCSConfig)  

  if ! grep "client_mode" $wcsConfig > /dev/null ; then
    echo -e "\nclient_mode=false" >> $wcsConfig
  fi
  if ! grep "rtc_ice_add_local_component" $wcsConfig > /dev/null ; then
    echo -e "\nrtc_ice_add_local_component=true" >> $wcsConfig
  fi
  isCloudFunc updateSettings_$cloud && updateSettings_$cloud
}

# Helper function to update IP settings
function updateIpSettings() {
  local privateIp=$1
  local publicIp=$2

  # Use function from IP module to write IPs to the config
  writeIps $privateIp $publicIp
}

# Update IP addresses if allowed
function updateIps() {
  local privateIp=$1
  local publicIp=$2
  local wcsConfig=$(getWCSConfig)
  local holdIpSettings="hold_ip_settings"
  local holdIpValue=""
 
  holdIpValue=$(cat $wcsConfig | grep "$holdIpSettings" | cut -d"=" -f2)
  if [[ $holdIpValue == "true" ]]; then
    return 0
  fi
  logDebug "Cloud IPs detected: ip=$publicIp ip_local=$privateIp"
  if [[ "$publicIp" != "" && "$privateIp" != "" ]]; then
    updateIpSettings $privateIp $publicIp
  elif [[ "$privateIp" != "" ]]; then
    updateIpSettings $privateIp $privateIp
  else
    sed -i -e "s/^\(ip[ \t]*=\|ip_local[ \t]*=\|cdn_ip[ \t]*=\).*\$/\1/" $wcsConfig
  fi
}

# Check a cloud
function checkCloud() {
  local cloud=$1
  local publicIp=""
  local privateIp=""

  if isCloud_$cloud; then
    isCloudFunc getPublicIp_$cloud && publicIp=$(getPublicIp_$cloud)
    isCloudFunc getPrivateIp_$cloud && privateIp=$(getPrivateIp_$cloud)
    updateIps $privateIp $publicIp
    updateSettings $cloud
    isCloudFunc setAdminPasswd_$cloud && setAdminPasswd_$cloud
    true; return
  else
    false; return
  fi
}

# Main cloud detection function: check clouds until the first match
function checkClouds() {
  local cloud=""
 
  declareClouds

  for cloud in $(getClouds); do
    if checkCloud $cloud; then
      setCurrentCloud $cloud
      logInfo "Cloud environment detected like $cloud" $(getStartupLogFile)
      break
    fi 
  done
}

# Cloud env detection checker to allow non-cloud specific operations
function isNotInCloud() {
  local currentCloud="$(getCurrentCloud)"
  
  if [[ -z $currentCloud ]]; then
    true; return
  else
    false; return
  fi
}


# Directories management functions

# Make a dir if not exists and set owner if needed
function makeDir() {
  local dirName=$1

  [ -z $dirName ] && return 1
  [ ! -d "$dirName" ] && mkdir -p $dirName
  [ isDirActionRequired ] && setOwner $(getUser) $dirName
}

# Set access rights to default dirs (and make then if not exist)
function setAccessRightsToDirs() {
  local defaultDirs=(
    logs
    hls
    records
    media
    snapshots
    report
    metrics
  )
  local dirName=""
  for dir in ${defaultDirs[@]}; do
    makeDir $(getHome)/$dir
  done
}

# Helper function to check if access rights action required
function isDirActionRequired() {
  if [[ isUser && isScriptRunningFromRoot ]]; then
    true; return
  else
    false; return
  fi
}



# Licence checking function 
function checkLicense() {
  local licenseFile="$(getHome)/conf/flashphoner.license"
  if [ ! -f "$licenseFile" ]; then
    echo ""
    echo "ERROR: Missing license file: (${licenseFile})"
    echo "You must activate license."
    echo "Execute the following commands to do it:"
    echo ""
    echo "cd $WCS_APP_HOME/bin"
    echo "./activation.sh"
    echo ""
    return 1
  fi
  $(getJavaExec) -Dcom.flashphoner.fms.AppHome="$(getHome)" -cp "$(getHome)/lib/*" com.flashphoner.server.license.ExpiredUpdates
  if [ "$?" -eq "1" ]; then
    exit 1;
  fi
}


# Server state checking functions

# Check if server is running
function isServerRunning() {
  pidFile=$(getPidFile)
  lockFile=$(getLockFile)
  if [[ -f $pidFile && -f $lockFile && -d /proc/$(cat $pidFile) ]]; then
    logDebug "Server is running, pid $(cat $pidFile)"
    true; return
  else
    logDebug "Server is not running"
    false; return
  fi 
}

# Check local status
function localStatus() {
  if isServerRunning; then
    echo "$(getProduct) started"
  elif [[ -f $(getLockFile) ]]; then
    echo "$(getProduct) not running but subsys locked"
  else
    echo "$(getProduct) not running"
  fi
  return 0
}



# WCS starting functions

# Declare startup global variables
function declareStart() {
  SERVER_PID={$SERVER_PID:-}
}

# Get server pid
function getServerPid() {
  echo "$SERVER_PID"
}

# Set server pid
function setServerPid() {
  local pid=$1

  if [[ ! -z $pid ]]; then
    SERVER_PID=$pid
  fi
}

# Check Java optiions before start
function checkJavaOptions() {
  local startupLog=$(getStartupLogFile)

  logInfo "Checking JVM options" $startupLog
  $(getJavaExec) -version $(getJavaOpts) >> $startupLog 2>> $startupLog
  return $?
}

# Form WCS running options
function getRunOptions() {
  local wcsRunOptions="$(getJavaOpts) -Dcom.flashphoner.fms.AppHome=$(getHome) -Djava.library.path=$(getHome)/lib/so:$(getHome)/lib -DWCS_NON_ROOT=$(getNonRoot) $(getServerOpts)"
 
  echo "$wcsRunOptions"
}

# Start WCS sudoing to default user
function startWithSudo() {
  local standalone=$1
  local user=$(getUser)
  local pid=""
  local parent=""

  if [[ "$standalone" == "standalone" ]]; then
    sudo -u $user env LD_LIBRARY_PATH=$(getLdLibraryPath) $(getJavaExec) $(getRunOptions) -cp "$(getHome)/lib/*" com.flashphoner.server.Server
  else
    logInfo "Starting $(getProduct) as user $user"
    sudo -u $user env LD_LIBRARY_PATH=$(getLdLibraryPath) $(getJavaExec) $(getRunOptions) -cp "$(getHome)/lib/*" com.flashphoner.server.Server > /dev/null 2>&1 &
  fi
  # Get sudo command pid
  parent=$!
  sleep 1
  # Get main process pid
  pid=$(ps -o pid= --ppid $parent)
 
  setServerPid "$pid"
}

# Start WCS as current user
function startAsCurrentUser() {
  local standalone=$1
  local pid=""

  if [[ "$standalone" == "standalone" ]]; then
    $(getJavaExec) $(getRunOptions) -cp "$(getHome)/lib/*" com.flashphoner.server.Server
  else
    logInfo "Starting $(getProduct)"
    $(getJavaExec) $(getRunOptions) -cp "$(getHome)/lib/*" com.flashphoner.server.Server > /dev/null 2>&1 &
  fi
  pid=$!

  setServerPid "$pid"
}

# Start WCS depending on user and mode
function startServer() {
  local standalone=$1
  local nonRootUser=$(getUser)
  local currentUser=$(getCurrentUser)
  local startAsCurrent=true
  local pid=""
 
  if isScriptRunningFromRoot; then
    # When runing from root, always start as root
    startAsCurrent=true
  elif isRootMode; then
    # When running as non root fail if server is in root mode
    logError "$(getProduct) cannot be started from user $nonRootUser, please switch WCS_NON_ROOT in setenv.sh to true!" $(getStartupLogFile)
    echo ""
    return 1
  elif [[ $nonRootUser == $currentUser ]]; then
    # When running as predefined user in non root mode, start as predefined user
    startAsCurrent=true
  else
    # When running as other non root user in non root mode, start sudoing to predefined user
    startAsCurrent=false
  fi

  logDebug "startAsCurrent=$startAsCurrent, standalone=$standalone, startup options=$(getRunOptions)"
  if $startAsCurrent; then
    startAsCurrentUser $standalone
  else
    startWithSudo $standalone
  fi
}

# Tweak hosts file for hostname if needed
function tweakHostsFile() {
  if [[ ! `getent hosts \`hostname\`` ]]; then
    echo "127.0.0.1		$(hostname)" >> /etc/hosts
  fi	
}

# Make symlink to records folder
function makeRecordsSymlink() {
  local recordsSymlink="$(getHome)/client/records"

  if [[ ! -L $recordsSymlink && -d $(getHome)/records ]]; then
    ln -sf $(getHome)/records $recordsSymlink
  fi
}

# Main startup function
function start() {
  local standalone=$1
  local msgAlreadyRunning="$(getProduct) is already running"
  local msgIpAddressesFail="$(getProduct) can't start due to incorrect Java options"
  local msgJavaOptionsFail="$(getProduct) can't start due to incorrect Java options"
  local msgCantStart="$(getProduct) can't start"
  local msgStart="$(getProduct) startup"
  local pid=""

  declareStart

  #Check if server is already running
  if isServerRunning; then
    logInfo $msgAlreadyRunning $(getStartupLogFile)
    echo $"$msgAlreadyRunning"
    return 0
  fi

  # Check license (and dont't go futher if updates expired
  checkLicense
 
  # If we have enough permissions
  if isScriptRunningFromRoot; then
    # Tweak hosts file
    tweakHostsFile
    # set open file descriptors limit
    ulimit -n $(getFDLimit)
  fi

  # Check cloud environment
  checkClouds

  # If we are not in cloud, check and detect IP addresses if they are not set
  if isNotInCloud; then
    setIp
    # Do not start if setIp failed
    [[ $? -ne 0 ]] && failure "$msgIpAddressesFail" && return 1
  fi

  echo -n $"$(getProduct): starting"
 
  # Set default foders access permissions if we starting from root
  if isDirActionRequired; then
    setAccessRightsToDirs
  fi

  # Check Java options before start
  if ! checkJavaOptions; then
    logError "$msgJavaOptionsFail" $(getStartupLogFile)
    echo -e "$msgJavaOptionsFail"
    failure "$msgJavaOptionsFail"
    return 1  
  fi

  # Set signal trapper when starting in standalone mode
  if [[ "$standalone" == "standalone" ]]; then
    trap 'echo -e "\n######### Stop standalone mode #########\n"; exit 0' 2
    echo -e "\n######### Start standalone mode #########\n"
  fi

  # Start with user choosing logic
  startServer $standalone
  pid=$(getServerPid)
 
  # Fail if no pid returned
  if [[ "$pid" == "" ]]; then
    failure "$msgCantStart"
    return 1
  fi
 
  # Check if process is started
  sleep 1
  if [[ `ps -p $pid | grep -c $pid` == '0' ]]; then
    failure "$msgCantStart"
    return 1
  fi

  # Save pid to file if not exists yet    
  if [[ ! -f $(getPidFile) ]]; then
    echo $pid > $(getPidFile)
  fi
  success "$msgStart"
  echo
  touch $(getLockFile)

  # Clean up obsolete GC logs
  rm -rf $(getHome)/logs/*.0
 
  # Make symlink to records folder
  makeRecordsSymlink

  # Set permissions to all logs created if starting first time as root
  sleep 1
  if isDirActionRequired; then
    setOwner $(getUser) "$(getHome)/logs"
    [ isNonRootMode ] && setOwner $(getUser) "$(getLockFile)"
    [ isNonRootMode ] && setOwner $(getUser) "$(getPidFile)"
  fi
 
  return 0
}


# WCS stopping functions

# Stop WCS process
function stop() { 
  local msgStopping="$(getProduct): stopping"
  local msgStopped="$(getProduct) stopped"
  local msgNotRunning="$(getProduct): not running"
  local msgShutdown="$(getProduct): shutdown"
  local pid=""
  local userRunFrom=""
  local stopped=false
 
  if isServerRunning; then
    echo -e $"$msgStopping"
    read pid < $(getPidFile)
    userRunFrom=$(getUserByPid $pid)
    kill -15 $pid
    rm -f $(getPidFile)
    rm -f $(getLockFile)
    stopped=true
    logInfo "$msgStopped" $(getStartupLogFile)
    # Set access right to dirs if the stopped instance was run from non prefdefined user
    if [[ $userRunFrom != $(getUser) && isDirActionRequired ]]; then
      setAccessRightsToDirs
    fi
  else
    echo -n $"msgNotRunning"
  fi

  if $stopped; then
    success "msgShutdown"
  fi
  echo
  return 0
}


# IP configuration functions

# Declare IP variables
function declareIp() {
  CONST_IP_UNDEFINED="undefined"
  IP_EXTERNAL=${IP_EXTERNAL:-$CONST_IP_UNDEFINED}
  IP_LOCAL=${IP_LOCAL:-$CONST_IP_UNDEFINED}
  LOCAL_IP_COUNT=${LOCAL_IP_COUNT:-0}
}

# Get external IP value
function getExternalIp() {
  echo "$IP_EXTERNAL"
}

# Set external IP value
function setExternalIp() {
  local externalIp=$1

  if [[ ! -z $externalIp ]]; then
    IP_EXTERNAL=$externalIp
  fi
}

# Get internal IP value
function getInternalIp() {
  echo "$IP_INTERNAL"
}

# Set external IP value
function setInternalIp() {
  local internalIp=$1

  if [[ ! -z $internalIp ]]; then
    IP_INTERNAL=$internalIp
  fi
}

# Get local IP count
function getLocalIpCount() {
  echo "$LOCAL_IP_COUNT"
}

# Set local IP count
function setLocalIpCount() {
  local localIpCount=$1

  if [[ ! -z $localIpCount ]]; then
    LOCAL_IP_COUNT=$localIpCount
  fi
}

# Check if address is empty or undefined
function isEmptyOrUndef() {
  local ip=$1

  if [[ -z $ip || "$ip" == "$CONST_IP_UNDEFINED" ]]; then
    true; return
  else
    false; return
  fi
}

# Count local interfaces
function countLocalIfaces() {
  local localIpCount=0
  local i

  for i in $(hostname -I); do
    ((localIpCount++))
  done
  setLocalIpCount $localIpCount
}

# Find local IP in hostname generated list
function findLocalIp() {
  local ip=$1
  local localIp=$CONST_IP_UNDEFINED
  local i

  for i in $(hostname -I) ; do
    if [[ "$ip" == "$i" ]]; then		
      localIp=$ip
    fi
  done
  
  echo "$localIp"
}

# Get external IP from public detector site with error code checking
function getIpByUrl() {
  local url=$1
  local httpResponse=""
  local httpBody=""
  local httpStatus=400

  if [[ -z $url ]]; then
    echo ""
    return 1
  fi
  httpResponse=`/usr/bin/curl -s -w "HTTPSTATUS:%{http_code}" $url`
  httpBody=$(echo "$httpResponse" | sed -E 's/HTTPSTATUS\:[0-9]{3}$//')
  httpStatus=$(echo "$httpResponse" | tr -d '\n' | sed -E 's/.*HTTPSTATUS:([0-9]{3})$/\1/')

  if [[ $httpStatus -eq 200 ]]; then
    echo "$httpBody"
    return 0
  fi
  echo ""
  return 1
}

# Detect external IP
function detectExternalIp() {
  local extIp1="$(getIpByUrl https://api.ipify.org)"
  local extIp2="$(getIpByUrl ipinfo.io/ip)"
  local extIp=$CONST_IP_UNDEFINED

  if [[ $extIp1 != '' ]]; then
    extIp=$extIp1
  elif [[ $extIp2 != '' ]]; then
    extIp=$extIp2
  fi

  echo "$extIp"
}

# Get IPs from hostname list
function getIpsFromHostname() {
  local localIp=$(getInternalIp)
  local externalIp=$(getExternalIp)

  logDebug "localIp=$localIp, externalIp=$externalIp"
  if isEmptyOrUndef $localIp; then
   localIp=$(hostname -I | tr -d '[:space:]')
  fi	
  if isEmptyOrUndef $externalIp; then
   setExternalIp $localIp
  fi    
  setInternalIp $localIp
}

# Ask user for IPs
function askUserForIps() {
  local localIp=$(getInternalIp)
  local externalIp=$(getExternalIp)
  local addr=""

  if [[ "$localIp" == "$CONST_IP_UNDEFINED" ]];then
    read -p "What is your server LAN IP? " addr
  else 	
    read -p "We have found $(getLocalIpCount) IPs, what should be used for WCS: $(hostname -I)? " addr
  fi  
  logDebug "User choose address $addr"
  if isEmptyOrUndef $externalIp; then
   setExternalIp $addr
  fi    
  setInternalIp $addr
}

# Try to configure IPs manually or semi-manually
function configureIps() {
  local localIpCount=$(getLocalIpCount)

  logDebug "Configuring IP: localIpCount=$localIpCount"
  if [[ $localIpCount -eq 1 ]]; then
    getIpsFromHostname
  else
    askUserForIps
  fi
}

# Ask user to confirm the server is in private network
function askUserForLan() {
  local extIp=$1

  echo -e "We have found these IP on your server\n"
  echo -e "External IP\t\tLocal IPs" 
  echo -e "$extIp\t\t$(hostname -I)\n"
  read -p "Is your server located in your LAN [yes/no] ? " confirm
  if [[ $confirm = n* ]]; then
    logDebug "extIp=$extIp"
    [[ $extIp != "$CONST_IP_UNDEFINED" ]] && setExternalIp $extIp
  fi	
  configureIps
  echo -e "Thanks. We have configured:\n"
  echo -e "ip = $(getExternalIp)"
  echo -e "ip_local = $(getInternalIp)"  	
  echo -e "\n"
  read -p "Press any key to continue..."
}

# Main IP detection function
function detectIps {
  local interactive=$1
  local extIp="$(detectExternalIp)"
  local localIp="$(findLocalIp $extIp)"

  logDebug "Detecting IP: extIp=$extIp, localIp=$localIp"
  if [[ "$extIp" == "$localIp" && "$extIp" != "$CONST_IP_UNDEFINED" ]]; then
    setExternalIp $extIp
    setInternalIp $localIp
  elif [[ ! -z $interactive ]]; then
    # Ask user in intercative mode only, if set-ip command is used
    askUserForLan $extIp
  fi
}	

# Check if IPs are not configured in settings
function isIpsEmpty() {
  local privateIp=""
  local publicIp=""
  local wcsConfig=$(getWCSConfig)

  publicIp=`sed -n -e "s/^ip[ \t]*=[ \t]*\(.*\)/\1/p" $wcsConfig`
  privateIp=`sed -n -e "s/^ip_local[ \t]*=[ \t]*\(.*\)/\1/p" $wcsConfig`
  if [[ -z $publicIp || -z $privateIp ]]; then
    true; return
  else
    false; return
  fi
}

# Helper function to write IP settings
function writeIp() {
  local setting=$1
  local value=$2
  local wcsConfig="$(getWCSConfig)"

  [[ -z $setting || -z $value ]] && return 1

  if [[ "$(grep -e "^$setting[ \t]*=" $wcsConfig)" != "" ]]; then
    logDebug "There is $setting setting, replacing $setting=$value"
    sed -i -e "s/^\($setting[ \t]*=\).*\$/\1$value/" $wcsConfig
  else
    logDebug "No $setting setting, adding $setting=$value"
    echo -e "\n$setting=$value" >> $wcsConfig
  fi
  return 0
}

# Write IPs to config file
function writeIps() {
  local privateIp=$1
  local publicIp=$2
  local wcsConfig="$(getWCSConfig)"
  local result=1

  if isEmptyOrUndef "$publicIp" || isEmptyOrUndef "$privateIp"; then
    # Do not write undefined addresses
    return 1
  fi
  if writeIp "ip" "$publicIp" && writeIp "ip_local" "$privateIp"; then
    result=0
    sed -i -e "s/^\(cdn_ip[ \t]*=\).*\$/\1$privateIp/" $wcsConfig
  fi
  return $result
}

# IP configuration main function
function setIp() {
  local override=$1
  local confirm="no"
  local result=0
  local msgFail="Cannot detect IP addresses automatically, please edit flashphoner.properties file to set them manually or run 'webcallserver set-ip' command"
  local msgSuccess="IP addresses are set"
  local msgAskRestart="$msgSuccess, please restart WCS to apply"

  declareIp
  countLocalIfaces
  
  if isIpsEmpty; then
    confirm="yes"
  elif [[ "$override" == "override" ]]; then
    read -p "IP adresses are already set, re-configure them [yes/no] ? " confirm
  fi
  if [[ $confirm = y* ]]; then
    detectIps $override
    writeIps "$(getInternalIp)" "$(getExternalIp)"
    result=$?
  else
    # Cancelled or no need to change IPs, just return
    return 0
  fi
  if [[ $result -eq 0 ]]; then
    [[ "$override" == "override" ]] && echo "$msgAskRestart"
    logInfo "$msgSuccess" $(getStartupLogFile)
  else
    logError "$msgFail" $(getStartupLogFile)
    echo "$msgFail"
  fi
  return $result
}


# WCS update functions

# Declare update globals
function declareUpdate() {
  SITE=${SITE:-flashphoner.com}
  LOCAL_VERSION=${LOCAL_VERSION:-}
  REMOTE_VERSION=${REMOTE_VERSION:-}
  UPDATE_LOG_FILE=${UPDATE_LOG_FILE:-"/tmp/wcs_update.log"}
  UPDATE_FULL_URL=${UPDATE_FULL_URL:-}
  UPDATE_LOGIN=${UPDATE_LOGIN:-}
  UPDATE_PASSWD=${UPDATE_PASSWD:-}
  START_AS_SERVICE=${START_AS_SERVICE:-false}
  setLocalVersion
  setRemoteVersion
}

# Get site domain name
function getSite() {
  echo "$SITE"
}

# Get site URL
function getSiteUrl() {
  echo "https://$SITE"
}

# Check if site available
function isSiteUp() {
  ping -c1 -W1 -q $(getSite) &>/dev/null
  if [[ $? -eq 0 ]]; then
    true; return
  else
    false; return
  fi
}

# Get local version
function getLocalVersion() {
  echo "$LOCAL_VERSION"
}

# Get major local version
function getMajorVersion() {
  local localVersion=$(getLocalVersion)
  
  echo "${localVersion:0:3}"
}


# Set local version
function setLocalVersion() {
  local localVersionFile="$(getHome)/conf/WCS.version"
  local localVersion=""

  if [[ -z $LOCAL_VERSION ]]; then
    localVersion=`cat $localVersionFile | cut -f1 -d-`
    LOCAL_VERSION=$localVersion
  fi
}

# Get remote version
function getRemoteVersion() {
  echo "$REMOTE_VERSION"
}

# Set remote version
function setRemoteVersion() {
  local remoteVersion=$1
  local remoteVersionFile="$(getSiteUrl)/downloads/builds/WCS/$(getMajorVersion)/currentVersion"

  if [[ -z $remoteVersion ]]; then
    [[ -z $REMOTE_VERSION && isSiteUp ]] && REMOTE_VERSION=`curl -s --connect-timeout 5 -m 5 $remoteVersionFile`
  else
    # Set to predefined build
    REMOTE_VERSION=$remoteVersion
  fi
}

# Get update log file name
function getUpdateLog() {
  echo "$UPDATE_LOG_FILE"
}

# Get full url to download build
function getFullUpdateUrl() {
  echo "$UPDATE_FULL_URL"
}

# Set full url to download build
function setFullUpdateUrl() {
  local fullUrl=$1

  if [[ ! -z $fullUrl ]]; then
    UPDATE_FULL_URL=$fullUrl
  fi
}

# Get login to download build
function getLogin() {
  echo "$UPDATE_LOGIN"
}

# Set login to download build
function setLogin() {
  local credentials=$1

  if [[ ! -z $credentials ]]; then
    UPDATE_LOGIN=$credentials
  fi
}

# Get passwd to download build
function getPasswd() {
  echo "$UPDATE_PASSWD"
}

# Set passwd to download build
function setPasswd() {
  local credentials=$1

  if [[ ! -z $credentials ]]; then
    UPDATE_PASSWD=$credentials
  fi
}

# Get start as service status
function getRunService() {
  $START_AS_SERVICE; return
}

# Set start as service status
function setRunService() {
  START_AS_SERVICE=$1
}

# Stop server carefully before update
function stopBeforeUpdate() {
 logDebug "Stopping before update"
 if isService; then
  # We should carefully stop service before updating #WCS-3024
  systemctl stop webcallserver
  setRunService true
 else
  stop
 fi
}

# Start server carefully after update
function startAfterUpdate() {
 logDebug "Starting after update"
 if getRunService; then
  # We should carefully start service after updating #WCS-3024
  systemctl restart webcallserver
 else
  # Re-init environment to update PID and lock file paths #WCS-3024
  setUpEvironment
  start
 fi
}

# Ask user to stop server if running
function tryToStopServer() {
  local arg=""
  local confirm=""

  # Stop if @yes" is passed in commandline
  for arg in "$@"; do
    if [[ $arg == "yes" ]]; then
      stopBeforeUpdate
      return 0
    fi
  done
  # Ask user to stop
  echo ">>> You have to stop $(getProduct) before update."
  read -p ">>> Stop now [yes/no] ? " confirm
  if [[ $confirm = y* ]]; then
    stopBeforeUpdate
  else
    echo "  Abort updating"
    return 1
  fi  

  return 0
}

# Execute download command
function executeDownloadCommand() {
  local url=$1
  local login=$2
  local passwd=$3

  logDebug "Downloading $url"
  wget $login $passwd --timeout=10 --no-check-certificate $url -O wcs5-server.tar.gz -o $(getUpdateLog)
}

# Execute build extstance check command
function executeCheckCommand() {
  local url=$1
  local login=$2
  local passwd=$3

  logDebug "Checking $url"
  wget $login $passwd --timeout=5 --tries=1 --waitretry=0 --no-check-certificate -S --spider $url 2>&1 | grep 'HTTP/1.1 200 OK' > /dev/nul 2>&1
}

# Prepare enterprise download URL and credentials
function prepareEnterpriseDownload() {
  local build=$1
  local url=""
  local majorVersion=$(getMajorVersion)
  local enterpriseUrl=$(getEnterpriseUrl)
  local enterpriseLogin=$(getEnterpriseLogin)
  local enterprisePasswd=$(getEnterprisePasswd)

  if [[ "$enterpriseUrl" != "" ]]; then
    setRemoteVersion $majorVersion.$build-enterprise
    url=`echo $enterpriseUrl | sed s/build-enterprise/$build-enterprise/`
    setFullUpdateUrl $url
    setLogin "--user=$(echo $enterpriseLogin | base64 --decode)"
    setPasswd "--password=$(echo $enterprisePasswd | base64 --decode)"
  else
    echo ">>> You have no access to enterprise builds"
  fi
}

# Prepare certain build doenload URL
function prepareBuildDownload() {
  local build=$1
  local enterprise=$2
  local url=""
  local majorVersion=$(getMajorVersion)

  if [[ "$enterprise" == "enterprise" ]]; then
    prepareEnterpriseDownload $build
  else
    setRemoteVersion $majorVersion.$build
    url=$(getSiteUrl)/downloads/builds/WCS/$majorVersion/FlashphonerWebCallServer-$majorVersion.$build.tar.gz
    setFullUpdateUrl $url
  fi
}

# Check if there is update
function checkUpdate() {
  local localVersion=""
  local remoteVersion=""

  declareUpdate

  if ! isSiteUp; then
    echo ">>> $(getSiteUrl) is not available, cannot check new version"
    return 1;
  fi
  localVersion=$(getLocalVersion)
  remoteVersion=$(getRemoteVersion)
  logDebug "Checking for update: local $localVersion, remote $remoteVersion"
  if [[ $remoteVersion == "" ]]; then
   echo ">>> Remote version is not available, cannot check new version"
   return 1
  elif [[ $localVersion < $remoteVersion ]]; then
   echo ">>> New version available: $remoteVersion"
   echo ">>> Your version: $localVersion"
  else
   echo ">>> You have latest version: $localVersion"
  fi

  return 0
}

# Main update function
function update() {
  local restart=false

  declareUpdate

  if ! isScriptRunningFromRoot; then
    echo ">>> You must be root to update, try to use sudo"
    return 1
  fi
  if ! isSiteUp; then
    echo ">>> $(getSiteUrl) is not available, cannot update"
    return 1
  fi

  if [ "$1" -eq "$1" ] 2>/dev/null; then
    # A build number is set as first parameter, get download command for it
    prepareBuildDownload "$@"
  else
    # Check for a new version
    checkUpdate
    # Return if there is no updates
    [ $? -ne 0 ] && return 1
    setFullUpdateUrl $(getSiteUrl)/download-wcs5.2-server.tar.gz
  fi

  if [[ -z $(getFullUpdateUrl) ]]; then
    echo ">>> Cannot build download URL, abort update"
    return 1
  fi

  # Check if build is available to download
  if executeCheckCommand $(getFullUpdateUrl) $(getLogin) $(getPasswd); then
    echo ">>> Version $(getRemoteVersion) is available, try to update"
  else
    echo ">>> Version $(getRemoteVersion) is not available"
    return 1
  fi

  # Check if server is running
  if isServerRunning; then
    restart=true
    tryToStopServer $@
    # Return if server is not stopped
    [ $? -ne 0 ] && return 1
  fi

  echo ">>> Updating $(getProduct)"
  cd /tmp
  echo ">>> Downloading $(getRemoteVersion) build"
  executeDownloadCommand $(getFullUpdateUrl) $(getLogin) $(getPasswd)
  if [ $? -eq 0 ]; then
    mkdir -p /tmp/wcs_latest && rm -rf /tmp/wcs_latest/* && tar xzf wcs5-server.tar.gz -C /tmp/wcs_latest --strip-components 1
    cd /tmp/wcs_latest
    chmod +x install.sh
    /bin/bash ./install.sh -silent 
    cd /tmp
    rm -rf /tmp/wcs_latest /tmp/wcs5-server.tar.gz
    echo -e ">>> $(getProduct) updated to $(getRemoteVersion)\n"
  else
    echo ">>> Error during downloading tar, please, check $(getUpdateLog)"
    return 1
  fi  
  # Restart server only if it was running before update #WCS-3034
  if $restart; then
    echo -e ">>> Starting $(getProduct)\n"
    startAfterUpdate
  fi

  return 0
}


# Main module

# Usage displaying
function usage() {
  echo "Usage: $(basename $0) [OPTIONS]"
  echo -e "  start [standalone]\t\t\tstart WCS (add standalone to display stdout for debugging purposes)"
  echo -e "  stop\t\t\t\t\tstop WCS"
  echo -e "  restart\t\t\t\trestart WCS"
  echo -e "  status\t\t\t\tdisplay WCS status"
  echo -e "  check_update\t\t\t\tcheck if WCS update available"
  echo -e "  update [<build> [enterprise]] [yes]\tupdate WCS (add build number to update to this build)"
  echo -e "  set-ip\t\t\t\tdetect and set IP parameters"
  return 1
}

# Main script function
function main() {
  local action=""
  local standalone=""
  local build=""
  local enterprise=""
  local forceUpdate=""

  declareGlobals
  setUpEvironment
  declareLog $(getStartupLogFile)

  # Parse command line arguments
  action=$1
  shift
  while [[ $# -gt 0 ]]; do
    case $1 in
      standalone)
        [[ "$action" == "start" ]] && standalone=$1
        shift
        ;;
      --debug)
        enableDebug
        shift
        ;;
      [0-9]*)
        [[ "$action" == "update" ]] && build=$1
        shift
        ;;
      enterprise)
        [[ "$action" == "update" ]] && enterprise=$1
        shift
        ;;
      yes)
        [[ "$action" == "update" ]] && forceUpdate=$1
        shift
        ;;
      *)
        usage
        return 1
        ;;
    esac
  done

  # Do the action
  case $action in
    start)
      start $standalone
      ;;
    stop)
      stop
      ;;
    status)
      localstatus
      ;;
    restart)
      stop
      start
      ;;
    check_update)
      checkUpdate
      ;;
    update)
      update $build $enterprise $forceUpdate
      ;;
    set-ip)
      setIp override
      ;;
    *)
      usage
      ;;
  esac
}

main "$@"

exit $?



ZeroDay Forums Mini