#!/bin/sh

############
# CHANGELOG
#===========
# 2015/03/24    crqms00151045   mingju lia
#               avoid POODLE attack: prevent using SSLv2 and SSLv3
#
# 2014/09/22    crqms00121003   mingju lai
#               OTBETA SUNRISE vhe frozen in resurrection after upgrade
#
# 2013/02/22    CRMS00418041    Ziming Xu
#               VHE does not change after reset mac address
#
# 2013/02/08    crms00417047    Zimingxu
#               Confusion about the style of dmurl update
#
# 2013/01/24    PR261951        Jerry ZHOU
#               Reduce time of unavailability during boot time
# 
# 2013/01/15     Ting He
#				Modify inappropriate error log for PR411913
#
# 2013/01/21    PR341502        Ziming Xu <Ziming.b.Xu@alcatel-lucent.com>
#               Reduce Reboot Frequency
#
# 2012/12/14    PR412060        Ziming Xu <Ziming.b.Xu@alcatel-lucent.com>
#               DM URL update using ssh
#
# 2012/08/23    CRMS00392052    Ziming Xu
#               Enhancement for CTL download and installation
#
# 2012/04/27    CRMS00370056    Ziming Xu
#               VHE should not use DM survival mode if server is reachable
#   
# 2012/04/24    CRMS00370729
#               VHE will go into step 3 login screen even if user want to modify parameter in MMI instep 2
#   
# 2012/03/16    CRMS00366844    Ziming Xu
#               Authentication URL is incorrect in DAD feature
# 2011/12/15    CRMS00351686    Michel SULYAN
#               Use new parseUrl() function from /etc/functions to parse URLs
# 2012/03/16    CRMS00366845    Ziming Xu
#               Generate incorrect MD5 password in DAD feature
# 2012/01/30    CRMS00358058    Jason ZHANG
#               VHE don't work after being upgraded to 01.002.0 and could not upgrade
#
# 2011/12/07    PR262041        Jerry ZHOU
#               Device auto discovery new feature
#               1. add function get_authen_url
#               2. add function authen_send
#               3. add return 'ERR_AUTH_REQ' for 401 in function 'download'
#               4. add process for 'ERR_AUTH_REQ' in function 'download_parse'
#               5. change options of curl command in function 'download':
#                  a. Use '--write-out' option to get curl http response code
#                  b. remove '-D ' option, no config-file header dump 
#                  c. add '--silent' and '--output /dev/null' option
#
# 2011/12/06    PR262041       Qianjun Zhang
#               add a function for send event to dbus
#               add a pipefile for appli_ptf to write and dmconfig to read logname and passwd
# 2011/11/09    CRMS00331041    Jerry ZHOU
#               Current 'status' settings may be lost if they are updated during DM config files treatment
#
# 2011/09/07    CRMS00335652    Xiaodong YANG
#               shell error reported on unlock version when user delete all the dm config files under /config/dm directory
#
# 2011/08/30    CRMS00333277    Claire Dechriste
#               add a popup and reboot if http error code 60 and ctl is not updated on server
#
# 2011/08/11    CRMS00329513    Xiaodong YANG
#               Alpha OXE: 3 VHE doesn't upgrade from 01.26.5 to 01.027.2
#
# 2011/08/11    CRMS00329694    Thanh lam NGUYEN
#               OXO : My IC Phone upgrade mechanism not working - sipdata file retrieval failure
#
# 2011/06/07    CRMS00315134    Xiaodong YANG
#               Https fallback not working during polling if ENETCFG_SIP_FILE is a full url
#
# 2011/05/30    CRMS00312748    Thanh lam NGUYEN
#               Fix multiple instance of either the daemon or the init script
#
# 2011/03/18    CRMS00302064    Claire Dechriste
#               Management of CTL update
#
# 2011/02/25    CRMS00296816    Thanh lam NGUYEN
#               Fix the sending of end of parsing.
#
# 2011/02/24    CRMS00292666    Thanh lam NGUYEN
#               Always start the polling thread so the SIP NOTIFY can wake it up.
#               When no polling is programmed, just set the frequency of the parsing to 1 every 136 years.
#
# 2011/02/24    CRMS00296547    Thanh lam NGUYEN
#               Add a loop before exiting to wait for the reboot that is ongoing by the settings manager.
#
# 2011/02/14    CRMS00293946    Michel Sulyan
#               add default scripts for post treatment (*.deferred_always)
#
# 2011/01/31    CRMS00290892    Thanh lam NGUYEN
#               Follow http redirect to retrieve configuration files
#
# 2011/01/19    CRMS00288108    Thanh lam NGUYEN
#               Add post-parsing treatment.
#
# 2011/01/14    CRMS00286717    Thanh lam NGUYEN
#               Log and display successful download of configuration files.
#
# 2011/01/11    CRMS00286432    Thanh lam NGUYEN
#               Fix cases when reboot could occures while in settings manager.
#
# 2011/01/10    CRMS00285309    Thanh lam NGUYEN
#               fix http fallback file path.
#
# 2011/01/07    CRMS00282780    Claire Dechriste
#               Management of empty CTL_FILE
#
# 2011/01/07    CRMS00282812    Claire Dechriste
#               add a call to displaypopup when the CTL changes on the server
#
# 2010/12/23    CRMS00282384    Thanh lam NGUYEN
#               No http fallback in "secured" mode.
#
# 2010/12/22    CRMS00280704    Thanh lam NGUYEN
#               Fix the "]] missing" error
#
# 2010/12/14    CRMS00280492    Thanh lam NGUYEN
#               Fix CTL file checking (checking the wrong file)
#
# 2010/12/07    CRMS00275985    Thanh lam NGUYEN
#               Parse all the files from the one that have been modified.
#
# 2010/12/06    CRMS00278662    Thanh lam NGUYEN
#               Forget PROXY information on ERR_DNS
#
# 2010/12/06    CRMS00278660    Thanh lam NGUYEN
#               Fix the use of the proxy protocol
#
# 2010/12/01    CRMS00276076    Thanh lam NGUYEN
#               Fix download file checksum creation
#
# 2010/11/30    CRMS00273516    Thanh lam NGUYEN
#               Add the check of the hash before installing the ctl.
#
# 2010/11/29    CRMS00272826    Thanh lam NGUYEN
#               Fix save_DM calls
#               Fix in save_DM the parsing of the variable name and variable value
#
# 2010/11/23    CRMS00275977    Claire Dechriste
#               Fix hash test when certificate customer is used
#
# 2010/10/22    CRMS00268816    Thanh lam NGUYEN
#               Fix hash test.
#
# 2010/10/22    CRMS00268714    Thanh lam NGUYEN
#               Add display of the error on screen in step 3.
#
# 2010/10/22    CRMS00267939    Thanh lam NGUYEN
#               Fix behavior to not reboot when polling parameter change.
#
# 2010/10/14    CRMS00263036    Thanh lam NGUYEN
#               fix "dm proxies" never cleaned when the 1st file coudl not be retrieved
#
# 2010/09/20    CRMS00260316    Thanh lam NGUYEN
#               Add option to "curl_args" to disable the check of the Common Name in the server certificate.
#
# 2010/09/08    CRMS00257438    Thanh lam NGUYEN
#               Fix http fallback in static mode
#
# 2010/08/25    CRMS00243881    Thanh lam NGUYEN
#               Fix DM & DM_BACKUP swap
#
# 2010/08/18    CRMS00253769    Thanh lam NGUYEN
#               Fix server comparison
#
# 2010/08/04    CRMS00244210    Thanh lam NGUYEN
#               Add a pop-up for the missing files
#
# 2010/07/30    CRMS00246998    Thanh lam NGUYEN
#               Save also the protocol
#
# 2010/07/22    CRMS00247489    Thanh lam NGUYEN
#               Fix for CTL infinite loop
#
# 2010/07/01    CRMS00239649    Thanh lam NGUYEN
#               Fix file name for xmlparse
#
# 2010/06/21    CRMS00239649    Thanh lam NGUYEN
#               New policy:
#                   On step 2, cleanup if no cfg file found, no reboot du to platform modification,
#                       remove parsed files on checksum changed of the 1st file only.
#                   On step 5, reboot accepted for platform modification, no files are removed.
#
# 2010/06/11    CRMS00229474    Thanh lam NGUYEN
#               Add signaling to the application manager when the parsing is done
#
# 2010/06/10    CRMS00228029    Thanh lam NGUYEN
#               Fix SIGHUP trapping
#
# 2010/06/07    _XML_SURVI      Thanh lam NGUYEN
#               When using the private parser, should not enter survivability mode
#
# 2010/05/31    INVENTORY_FILE  Thanh lam NGUYEN
#               Modification to take into account the inventory file
#
# 2010/05/06    DEMO_MODE       Thanh lam NGUYEN
#               Modification to take into account the demo mode
#
# 2010/05/05    CRMS00228732    Thanh lam NGUYEN
#               Update all configuration files after parsing
#
# 2010/05/04    CRMS00228734    Thanh lam NGUYEN
#               Make the 4 attempts only for the 1st file.
#
# 2010/04/22    _CTL_INSTALL    Thanh lam NGUYEN
#               Add use of private parser in case of xml parsing problem.
#
# 2010/03/25    CRMS00221778    Thanh lam NGUYEN
#               Add use of private parser in case of xml parsing problem.
#
# 2010/03/16    Thanh lam NGUYEN
#               Add retrieval of ssl informations
#
# 2010/03/11    CRMS00217278    Thanh lam NGUYEN
#               Add a log to the console on a failure to download a file
#
# 2010/02/19    CRMS00152511    Thanh lam NGUYEN
#               Content reorganisation
#               Change the download mechanism to comply with 3AK_29000_0204_DTZZA
#
# 2010/02/04    crms00213012    Thanh lam NGUYEN
#               fix
################################
# CRMS00312748
#### Read function library
####=======================
#### This has to be done very early in order to find the macros....
# root directory, the equivalent of "/"
ROOT=${ROOT:-}
source $ROOT/etc/functions
# CRMS00312748 END

################################
# CONFIGURATION CONST & VAR
####################################################################
#### Debug consts & vars
# CRMS00312748
attr="$esc[43;30m"
errorattr="$esc[31;40m"
default=$default # to restore colors
alias set_debug_on='if [[ "${-//x}" == "$-" ]]; then exec 0<&- 1>${ROOT}/dev/console 2>&1; set -x; fi'
alias set_debug_off='if [[ "${-//x}" != "$-" ]]; then set +x; exec 0<&- 1>&- 2>&-; fi'
scriptname=dmconfig
# hack for defPS4, ENTER_FUNCTION & RETURN macros
FUNCTION=$scriptname; _function="$FUNCTION(""$*"")"; read <${ROOT}/proc/self/stat PS4_PREFIX - 2>/dev/null; PS4_TPLT="$esc[$((${PS4_PREFIX##*|}%6+31))m+(\$PS4_PREFIX)\$FUNCTION:$esc[0m "; PS4=$PS4_TPLT
IN_DEBUG && set_debug_on
xtrace="${-//[^x]}"

#### Script consts & vars
## consts
##--------
servicelaunch=$ROOT/etc/init.d/$scriptname
# CRMS00292666
DISABLED_SLEEPTIME=294967295
# CRMS00292666 END
getPID
pidfile=$ROOT/var/run/dmconfig.pid
rcfile=$ROOT/etc/dmconfigrc
norebootflag=$ROOT/etc/.noreboot
#CRMS00247489
nocleanflag=$ROOT/tmp/dmconfig.noclean
xmlparse=$ROOT/bin/xmlparse
xmlparseArgs="all=1"

#PR262041
AppPtfDmPipeFile=$ROOT/tmp/appliptf_pipe_dmconfig
#PR262041 END

# CRMS00312748 END
# DNS SRV parameters
SERVICE=_DMICTOUCH
TRANSPORT=_TCP
# CRMS00288108
POSTPARSINGDIR=$ROOT/var/run/dmconfig
# CRMS00288108 END
# PR262041 
#CRMS00366844
authen_path=/DM/dm_authent
#CRMS00366844 END
# PR262041 END
## errors
##--------
OK=0
ERR_MISC=1
ERR_DNS=2
ERR_NODM=3
ERR_NOBKP=4
ERR_MISS=5
ERR_BADCFG=6
ERR_SSL=7
ERR_SWAP=8
ERR_DISK=9
ERR_TMOUT=10
# CRMS00312748
ERR_TRAP=133
ERR_USR1=138
# CRMS00312748 END
XMLPARSE=13
ERR_NEVER=14
ERR_CKSUM=15
# CRMS00302064
ERR_CTL=16
# PR262041
ERR_AUTH_REQ=17
AUTH_RETRY=19
AUTH_FAILED=20
# PR262041 END
# CRMS00418041 zimingxu+
stepfile=/tmp/step
# CRMS00418041 zimingxu-
## flags
# PR341502 zimingxu+
polling_thread_flag=/tmp/.dmconfig.polling
UPDT_FLAG=/tmp/.update_flag
update_defer_flag=/tmp/.update_defer_flag
mutex_param=mtx_param                        
mutex_context=ctx_upgdparam                                                  
mutex_check=0
# PR341502 zimingxu-
# CRMS00418041 zimingxu+
stepfile=/tmp/step
# CRMS00418041 zimingxu-
##-------
force=0
noclean=0
[[ -f $norebootflag ]] && noreboot=1 || noreboot=${NOREBOOT:-0}
nofallback=0
## vars
##------
# CRMS00312748
polling_restart=0
usr1=
# CRMS00312748 END
# PER ATTEMPT PARAMS
timeout=
retry=

# RETRY PARAMS
maxdownloadretry=
delaydownloadretry=

# SSL PARAMS
insecure=$(getICTinfo PKI STATUS DM 2>/dev/null)
ca_default=$(getICTinfo PKI CA DM 2>/dev/null)
cert_default=$(getICTinfo PKI CERT DM 2>/dev/null)
key_default=$(getICTinfo PKI CERT_PKEY DM)
# CRMS00302064
ctl_update=0
# CRMS00282384
if [[ "$insecure" == "SECURED" ]]; then
    nofallback=1
fi
# CRMS00282384 END


# MISC
# if the server and backup were swapped
swap=0
# The list of files to retrieve (can have variables from the system config in the filename)
# E.g. "${ENETCFG_DM_URL}/filename" is a valid filename
filelist_template=
# The list of missing mandatory files. Updated by download_parse()
MISSING=""
# The RETURN value 'RET' is used when several steps are needed to complete the task.
# Each task RETURN a 'ret' and depending on 'ret', 'RET' is updated.
# Primary ret value
RET=0
# Secondary ret value
ret=0
urlfromfile=0
survival=0
# CRMS00239649
thread=0
# CRMS00239649 END
####################################################################

# CRMS00312748
trap ": \"${attr}$esc[7mUSR1 received.${default}\"" USR1
# CRMS00312748 END

################################
# HELPER FUNCTION
####################################################################
# CRMS00312748
handler_exit() {
    local FUNCTION=handler_exit attr="$esc[30;43m" default="$esc[0m"
    ENTER_FUNCTION
    local pid
    read 2>/dev/null <$pidfile pid
    if [[ "${pid:-1}" == "$PID" ]]; then
        rm $pidfile
    fi
    RETURN 0
}
trap handler_exit 0
## create pid file if it does not exists or no process is associated
if ! read 2>/dev/null <$pidfile pid || [[ ! -d /proc/$pid ]]; then
    echo "$PID" > $pidfile
fi

handler_usr2()
{
    local FUNCTION=handler_usr2 attr="$esc[30;42m" default="$esc[0m"
    ENTER_FUNCTION
    exit
    RETURN 0
}
trap handler_usr2 USR2
# CRMS00312748 END

dowait()
{
    local FUNCTION=dowait
    ENTER_FUNCTION
    local RET=0 nostderr=0
    while [[ "${1##--}" != "$1" ]]; do
        case "$1" in
            --nostderr) nostderr=1
            ;;
        esac
        shift
    done
    dowaitcmd="$1" shift
# CRMS00290892
    : "${attr}==> $dowaitcmd ""$@""${default}"
    if [[ $nostderr -eq 1 ]]; then
        $dowaitcmd 2>/dev/null "$@" &
    else
        $dowaitcmd "$@" &
    fi
# CRMS00290892 END
    dowaitpid=$!
# CRMS00312748
    echo $dowaitpid > /var/run/dowait.pid
# CRMS00312748 END
    wait $dowaitpid
    RET=$?
    [[ -d /proc/$dowaitpid ]] && kill $dowaitpid
    dowaitpid=0
# CRMS00312748
    rm /var/run/dowait.pid
# CRMS00312748 END

    RETURN $RET
}

do_reboot()
# ARG:
#   $1  Reboot reason
#   $2  Optional, reboot delay
#
# RETURN VALUE:
#   This function never returns
{
    local FUNCTION=do_reboot
    ENTER_FUNCTION
    local msg="Rebooting..." \
          delay="" \
          step="" \
          cr=$'\n'

    # Parse arguments
    while [[ $# -gt 0 ]]; do
        case "$1" in
            --step=*) step=${1##*=};;
            --delay=*) delay=${1##*=};;
            *) msg="$1";;
        esac
        shift
    done

    echoerror "$msg"
    displaymsg "$msg"
    if [[ ! -f $sanityflag ]]; then
        ( attr="$esc[31m"; default="$esc[0m"; display "$msg${cr}REBOOTING IN 10 SECONDS." )
# CRMS00286432
        reboot --waitSettings ${delay:+--delay=$delay} ${step:+--step=$step} --owner dmconfig --reason "$msg"
# CRMS00286432 END
    else
        # only if in debug (sanityflag)
        ( attr="$esc[31m"; display "$msg${cr}SHOULD REBOOT IN 10 SECONDS" )
        sleep 10
    fi
    exit $ERR_MISC

    # Should never arrive here
    RETURN $ERR_NEVER
}
####################################################################
################################
# POLLING THREAD
####################################################################
# CRMS00312748
polling_thread_exit()
#--------------------
# Exit function for the polling thread
# INPUT:    none
# RETVAL:   0       Success
{
    local FUNCTION=polling_thread_exit attr="$esc[30;43m" default="$esc[0m"
    ENTER_FUNCTION

    if [[ "$dowaitpid" -ne 0 ]]; then
        echo "===== $PID: killing $dowaitcmd ($dowaitpid) ====="
        kill $dowaitpid
        dowaitpid=0
    fi
# PR341502 zimingxu+
    [[ $mutex_check -eq 1 ]] && { mutex_unlock $mutex_param $mutex_context; mutex_delete_context $mutex_context; }
# PR341502 zimingxu-
    handler_exit "$@"
    RETURN 0
}

polling_thread_usr1()
# Handler of the usr1 signal for the polling thread.
# On usr1 signal, set the usr1 variable
# INPUT:    none
# RETVAL:   0       Success
{
    local FUNCTION=polling_thread_usr1 attr="$esc[30;41m" default="$esc[0m"
    ENTER_FUNCTION

    : "${attr}SIGUSR1 received${default}"
    usr1=1
    RETURN 0
}

polling_thread_trap()
#--------------------
# Handler of the trap signal for the polling thread.
# On trap signal, toggle the xtrace & redirection of stdout/stderr to the console
# INPUT:    none
# RETVAL:   0       Success
{
    local FUNCTION=polling_thread_trap
    ENTER_FUNCTION

    echo "===== $PID: toggling debug =====" >/dev/console
    [[ "$dowaitpid" -ne 0 ]] && kill $dowaitpid
    dowaitpid=0
    if [[ -n "$xtrace" ]]; then
        set_debug_off
    else
        set_debug_on
    fi
    xtrace="${-//[^x]}"
    RETURN 0
}
# CRMS00312748 END

polling_thread_main()
#--------------------
# Main of the polling thread
# INPUT:    none
# RETVAL:   none
{
    local FUNCTION=polling_thread_main
    ENTER_FUNCTION
# PR341502 zimingxu+
# CRMS00292666
    local RET=0 tmp sleeptime update=false
# CRMS00292666 END
# PR341502 zimingxu-

# CRMS00239649
    thread=1
# CRMS00239649 END
# CRMS00228029
    #### Make the redirection of stdout/stderr depending on the xtrace flag
# CRMS00312748
    getPID
    polling_thread_pid=$PID
    PS4_PREFIX=$polling_thread_pid
    defPS4
# CRMS00312748 END
    if [[ -n "$xtrace" ]]; then
        set_debug_on
    fi
# CRMS00228029 END
    # To prevent HUP from the session
    trap "" HUP
    #### Set signal interface
    # On any exit, execute polling_thread_exit
# CRMS00312748
    trap 0
    trap polling_thread_exit 0
    # Other signal handling
    trap handler_usr2 USR2
    trap polling_thread_usr1 USR1
    trap polling_thread_trap TRAP

    # cleaning up any previous dowait
    read 2>/dev/null </var/run/dowait.pid tmp
    [[ -d /proc/${tmp:-0} ]] && kill $tmp && rm /var/run/dowait.pid
    usr1=$polling_restart
    [[ $usr1 -eq 1 ]] && readCurrentConfig

    # create the flag used by init script to restart the polling_thread
# PR341502 zimingxu+
    touch $polling_thread_flag
# PR341502 zimingxu-
    #### main polling loop
    while :; do
        if [[ $usr1 -eq 0 ]]; then
# CRMS00312748 END
# CRMS00292666
            if [[ "$ADMCFG_CFGFILE_POLLING_ENABLE" == "true" ]]; then
                sleeptime=$ADMCFG_CFGFILE_POLLING_TIMEOUT
            else
                sleeptime=$DISABLED_SLEEPTIME
            fi
            #### Sleep the timeout
            dowait sleep $sleeptime
# CRMS00292666 END
        fi

# CRMS00312748
        usr1=0
# CRMS00312748 END

#CRMS00315134
#nofallback is set to 0 for polling if necessary
        if [[ "$insecure" == "SECURED" ]]; then
            nofallback=1
        else
            nofallback=0
        fi
#CRMS00315134 END

# CRMS00335652
# CRMS00329513
        survival=$(CLISettings get current ENETCFG_DM_SURVIVABILITY_MODE  2>/dev/null) 	    
# CRMS00329513 END
# CRMS00335652 END

        #### Check and parse the config files
       
# PR341502 zimingxu+
        if [ -e "$UPDT_FLAG" ]; then
            rm -rf $UPDT_FLAG
            update=true
            unset "ENETCFG_DM ENETCFG_DM_PORT ENETCFG_DM_PROTOCOL ENETCFG_DM_CONFIG_PATH ENETCFG_DM_BACKUP \
                   ENETCFG_DM_BACKUP_PORT ENETCFG_DM_BACKUP_PROTOCOL ENETCFG_DM_BACKUP_CONFIG_PATH ENETCFG_DM_PROXY \
                   ENETCFG_DM_PROXY_PORT ENETCFG_DM_PROXY_PROTOCOL ENETCFG_DM_PROXY_CONFIG_PATH ENETCFG_DM_PROXY_BACKUP \
                   ENETCFG_DM_PROXY_BACKUP_PORT ENETCFG_DM_PROXY_BACKUP_PROTOCOL ENETCFG_DM_PROXY_BACKUP_CONFIG_PATH"
            readConfig
            select_DM
            RET=$?
            if [ "$RET" == 0 ]; then
                download_parse "$maxdownloadretry" "$filelist_template"
                RET=$?
            fi
        else
            readConfig
            download_parse "$maxdownloadretry" "$filelist_template"
            RET=$?
        fi
# PR341502 zimingxu-

        case "$RET" in
            $ERR_BADCFG) : "${attr}The saved configuration is bad.${default}"
# PR341502 zimingxu+
                msg="DM ERROR: unable to download configuration file. POSSIBLE REASON: bad saved configuration or file not found."
# PR341502 zimingxu-
                # clear the locally saved info
                save_DM "LOCAL" "ENETCFG_DM_PROTOCOL=" "ENETCFG_DM=" "ENETCFG_DM_PORT=" "ENETCFG_DM_CONFIG_PATH=" \
                                "ENETCFG_DM_BACKUP_PROTOCOL=" "ENETCFG_DM_BACKUP=" "ENETCFG_DM_BACKUP_PORT=" \
                                "ENETCFG_DM_BACKUP_CONFIG_PATH="
# CRMS00392052 zimingx+
                $servicelaunch reparse
# CRMS00392052 zimingx-
                # reboot
# CRMS00370629
                do_reboot "Bad configuration files, cleaning and rebooting"
# CRMS00370629 END
                RETURN $ERR_NEVER
            ;;
            $ERR_TRAP) : "${attr}SIGTRAP was received, service it${default}"
                polling_thread_trap
            ;;
# PR341502 zimingxu+
            $ERR_NODM) : "${attr}No DM/PROXY !!!${default}"
                msg="DM ERROR: No DM/PROXY found. POPOSAL: check/correct configurations!"
                : "${attr}Cleaning up any stored DM/DM PROXY information${default}"
                save_DM "LOCAL" "ENETCFG_DM_PROTOCOL=" "ENETCFG_DM=" "ENETCFG_DM_PORT=" "ENETCFG_DM_CONFIG_PATH=" \
                                "ENETCFG_DM_BACKUP_PROTOCOL=" "ENETCFG_DM_BACKUP=" "ENETCFG_DM_BACKUP_PORT=" \
                                "ENETCFG_DM_BACKUP_CONFIG_PATH=" "ENETCFG_DM_PROXY_PROTOCOL=" "ENETCFG_DM_PROXY=" \
                                "ENETCFG_DM_PROXY_PORT=" "ENETCFG_DM_PROXY_CONFIG_PATH=" \
                                "ENETCFG_DM_PROXY_BACKUP_PROTOCOL=" "ENETCFG_DM_PROXY_BACKUP=" \
                                "ENETCFG_DM_PROXY_BACKUP_PORT=" "ENETCFG_DM_PROXY_BACKUP_CONFIG_PATH="
                do_reboot "$msg"
                RETURN $ERR_NEVER
            ;;
            $OK) : "${attr}Download or update succeed${default}"
                if [[ "$update" == true ]] || [[ "$polling_restart" -eq 1 ]]; then
                    mutex_create_context $mutex_context      
                    mutex_check=1                                                 
                    mutex_lock $mutex_param $mutex_context
                    updateSystemConfiguration
                    mutex_unlock $mutex_param $mutex_context
                    update=false
                    polling_restart=0
                fi
            ;;
            *) : "${attr}Other error handle${default}"
                if [[ -n "$MISSING" ]]; then
                    : "${attr}There are missing files.${default}"
                    msg="DM ERROR: could not retrieve following file"
                    #treatMissingFilesOutput
                    if [[ "${MISSING%, *}" != "${MISSING}" ]]; then
                        # Several files, update missing and msg to manage several files
                        MISSING="${MISSING%, *} and${MISSING##*,}"
                        msg="${msg}s"
                    fi
                    msg="$msg $MISSING"$'\n'
                    echoerror "$msg"
                    displaymsg "$msg" & wait $!
                    displaypopup "$msg" & wait $!
                fi
                do_reboot "$msg"
                RETURN $ERR_NEVER
            ;;
# PR341502 zimingxu-
        esac
    done
    RETURN $RET
}

####################################################################

################################
# FUNCTION IMPLEMENTATION
####################################################################
help()
#-----
# Display the help message
# INPUT:    none
# RETVAL:   0       Success
{
    local FUNCTION=help
    ENTER_FUNCTION

    echo ""
    echo "Syntax:\t${0##*/} [-h|--help][-c|--config <config_file>][--cacert <cacert_path>][--cert <cert_path>][--key <priv_key>][--timeout <timeout>][--skip_identical][[--maxdownloadretry <max_retry>][--retry <retry>][--url <URL>][--dest <dest>][file optional|mandatory [file optional|mandatory] ....]"
    echo        "\t${0##*/} clean|get <url>"
# CRMS00312748
    echo        "\t${0##*/} --polling_restart"
# CRMS00312748 END
    echo ""
    echo "Retrieve from the <url> a list of files that are defined in the config file or on the command line"
    echo "If skip_identical is set, only files that are different are processed."
    echo "Parameters:"
    echo "    <config_file>	the configuration file to use (default /etc/dmconfig.rc)."
    echo "    <cacert_path>	the full path to the CA cert."
    echo "    <cert_path>	the full path to the client certificat that will be send to the DM server."
    echo "    <priv_key>	private key for the client certificat."
    echo "    <timeout>		is the connection-timeout in second."
    echo "    <retry>		the number of retry to do before giving up."
    echo "    <URL>		is the URL to retrieve from the server."
    echo "    <dest>		is the directory where the retrieved files will be stored."
    echo ""
    echo "NOTE: the certificates are used only when the URL starts with 'https://'."
    echo "NOTE: no <space> are allowed in the different filenames."
    RETURN 0
}

process_cmdline()
#----------------
# Process the command line
# INPUT:    $@      Command line
# RETVAL:   0       Success
#           other   Failure
{
    local FUNCTION=process_cmdline
    ENTER_FUNCTION

    while [[ -n "${1:-}" ]]; do
        : "${attr}\$1=$1        remaining args: [${*#$1}]${default}"
        case "$1" in
            --debug) : "${attr}debug${default}"
                attr="$esc[30;42m" default="$esc[0m"
                set -vx
                debug=1
            ;;
            -h|--help) : "${attr}help${default}"
                help
                RET=0 exit $RET
            ;;
            -c|--config) : "${attr}config${default}"
                shift
                config_file=$1
            ;;
            --cacert) : "${attr}cacert${default}"
                shift
                cmdl_ca=$1
            ;;
            --cert) : "${attr}cert${default}"
                shift
                cmdl_cert=$1
            ;;
            --key) : "${attr}key${default}"
                shift
                cmdl_key=$1
            ;;
            --retry) : "${attr}retry${default}"
                shift
                cmdl_retry=$1
            ;;
            --maxdownloadretry) : "${attr}maxdownloadretry${default}"
                shift
                cmdl_maxdownloadretry=$1
            ;;
            --force) : "${attr}force${default}"
                force=1
            ;;
            --timeout) : "${attr}timeout${default}"
                shift
                cmdl_timeout=$1
            ;;
            --url) : "${attr}url${default}"
                shift
                cmdl_url=$1
            ;;
            --dest) : "${attr}dest${default}"
                shift
                cmdl_downloaddir=$1
            ;;
            --noclean) : "${attr}noclean${default}"
                noclean=1
            ;;
            --nopoll) : "${attr}nopoll${default}"
                nopoll=1
            ;;
# CRMS00312748
            --polling_restart): "${attr}polling_restart${default}"
                polling_restart=1
            ;;
# PR341502 zimingxu+
# CRMS00392052 zimingx+
            start|stop|restart|reload|hup|update|debug|condrestart|reparse|clean|setforce|force|check) : "${attr}$1, go to $servicelaunch${default}"
# CRMS00392052 zimingx-
# PR341502 zimingxu-
                handler_exit
                trap 0
                exec $servicelaunch "$@"
            ;;
# CRMS00312748 END
            *) : "${attr}append to filelist${default}"
                cmdl_filelist="${cmdl_filelist+$cmdl_filelist }$1"
            ;;
        esac
        shift
    done
    RETURN 0
}


# PR262041
notify_event2dbus()                                                             
{                                                                               
  local FUNCTION=notify_event2dbus attr="$esc[30;41m" default="$esc[0m"
  ENTER_FUNCTION                                                       
  local ictfile=/usr/bin/ICTApplication/ICTCliGateLite                         
  ret=0                                                                
                                                                       
  while [[ $# -gt 0 ]]; do                                             
        : "${attr}notify_event2dbus send event :$1${default}"            
        if [[ -x ${ictfile} ]]; then                                   
            eval "${ictfile} --event $1"                     
            if [[ $? -ne 0 ]]; then                                             
                echoerror "eval not return a good value $1!"    
                ret=1                                        
                break                                                           
            fi                                               
        else
            ret=1
            echoerror "ICTGliGateLite is not exist now!"    
            break
        fi                                                   
        shift                                                                
  done         
  RETURN $ret                                                
}   
# PR262041 END


get_config()
#-----------
# Read the system configuration and set the required vars
# INPUT:    $@          command line arguments
# RETVAL:   0           Success
#           ERR_DNS     DNS error
#           ERR_NODM    No DM found
#           other       Failure
{
    local FUNCTION=get_config
    ENTER_FUNCTION
    local ERR=0 \
          ret attr default oldattr do_cmdline=0

    ## Process command line
    ##----------------------
#PR261951 jerryzh+
    if [[ ! -z "$@" ]]; then
        process_cmdline "$@"
        do_cmdline=1
    fi
#PR261951 jerryzh-
    oldattr="$attr" attr="$esc[44;30m" default="$esc[0m"
    ## Read system configuration
    ##---------------------------
    [[ -n "$xtrace" ]] && set_debug_off
# PR341502 zimingxu+
    readConfig
# PR341502 zimingxu-
    [[ -n "$xtrace" ]] && set_debug_on

    ## Read dmconfig configuration file
    ##----------------------------------
    : "${attr}Read rc file${default}"
    [[ -f "${config_file:=$rcfile}" ]] && source $config_file

    attr="$oldattr" default="$esc[0m"
    ## Overwrite using command lines
    ##-------------------------------
#PR261951 jerryzh+
    if [[ $do_cmdline -eq 1 ]]; then
        : "${attr}Overwrite with command line${default}"
        retry=${cmdl_retry:-$retry}
        maxdownloadretry=${cmdl_maxdownloadretry:-$maxdownloadretry}
        timeout=${cmdl_timeout:-$timeout}
        url=${cmdl_url:-$url}
        downloaddir=${cmdl_downloaddir:-$downloaddir}
        filelist=${cmdl_filelist:-$filelist}
        ca=${cmdl_ca:-$ca}
        cert=${cmdl_cert:-$cert}
        key=${cmdl_key:-$key}
    fi
#PR261951 jerryzh-

    [[ -z "$ca" ]] && ca=$ca_default
    [[ -z "$cert" ]] && cert=$cert_default
    [[ -z "$key" ]] && key=$key_default

    ## Resolve the variables, clean "filelist" and remove trailing '/' from url and downloaddir
    ##------------------------------------------------------------------------------------------
    eval "url=\"${url%%/}\" downloaddir=\"${downloaddir%%/}\" cacert=\"$cacert\" cert=\"$cert\" key=\"$key\""
    downloaddir=${downloaddir##/}
    unset filelist_template
    push filelist_template ${filelist//[^[:graph:]]/ }
    unset filelist

    ## Validate parameters
    ##---------------------
    : "${attr}Check parameters${default}"
    # destination dir
    if [[ ! -d /$downloaddir ]]; then
        mkdir -p /$downloaddir
        if [[ $? -ne 0 ]]; then
            echoerror "/$downloaddir cannot be created"
            ERR=1
        fi
    fi
    [[ -d /tmp/$downloaddir ]] && rm -rf /tmp/$downloaddir
    if [[ ! -d /tmp/$downloaddir ]]; then
        mkdir -p /tmp/$downloaddir
        if [[ $? -ne 0 ]]; then
            echoerror "/tmp/$downloaddir cannot be created"
            ERR=1
        fi
    fi
    # delay download retry
    [[ $delaydownloadretry -lt 15 ]] && delaydownloadretry=15

    ## Select the DM
    ##---------------
    select_DM || ERR=$?
    attr="$oldattr" default=$default ## the setting of default is to nullify the attribute in xtrace mode
    RETURN $ERR
}

comp_server()
#------------
# Compare 2 serveurs values
# INPUT:    $1      1st server IP/FQDN
#           $2      2nd server IP/FQDN
# OUTPUT:   none
# RETVAL:   0       identical
#           1       not identical
#           ERR_DNS DNS error
{
    local FUNCTION=comp_server
    ENTER_FUNCTION
    local server1="$1" server2="$2" \
          ret=0 \
          isip1 isip2 tmp1 tmp2

    server1=$(echo "${server1//[^[:graph:]]}"| tr [:upper:] [:lower:])
    server2=$(echo "${server2//[^[:graph:]]}"| tr [:upper:] [:lower:])
    [[ "${server1//[[:blank:]]}" == "${server2//[[:blank:]]}" ]] && { RETURN 0; }
    # server1 and server2 are not identical in their IP/FQDN
    is_ip "$server1"; isip1=$?
# CRMS0000253769 
    if [[ $isip1 -ne 0 ]]; then
        # server1 is not an ip
        if [[ -n "${server1//[[:blank:]]}" ]]; then
            server1=$({ nslookup "$server1" 2>/dev/null; echo "EXIT_AWK $?"; } | awk '/^Name:/{found=1}found==0{next}/Address.*:/{print $3}/^AWK_EXIT/{exit $2}')
            [[ $? -ne 0 ]] && { RETURN $ERR_DNS; }
        fi
    fi
# CRMS0000253769 END
    is_ip "$server2"; isip2=$?
# CRMS0000253769 
    if [[ $isip2 -ne 0 ]]; then
        # server2 is not an ip
        if [[ -n "${server2//[[:blank:]]}" ]]; then
            server2=$({ nslookup "$server2" 2>/dev/null; echo "EXIT_AWK $?"; } | awk '/^Name:/{found=1}found==0{next}/Address.*:/{print $3}/^AWK_EXIT/{exit $2}')
            [[ $? -ne 0 ]] && { RETURN $ERR_DNS; }
        fi
    fi
# CRMS0000253769 END
    # Now server1  and server2 are IP(s)
    ret=1
# CRMS0000253769 
    for tmp1 in ${server1//[^[:graph:]]/ }; do
        for tmp2 in ${server2//[^[:graph:]]/ }; do
            [[ "$tmp1" == "$tmp2" ]] && ret=0
        done
    done
# CRMS0000253769 END

    RETURN $ret
}

check_DM()
#---------
# Check to see if DM information are the same from previous DHCP
# INPUT:    none
# OUTPUT:   none
# RETVAL:   0       identical
#           1       not identical
#           ERR_DNS DNS error
{
    local FUNCTION=check_DM
    ENTER_FUNCTION
    local ret=0 \
          dhcp_domain dnssrv IFS \
          saved_dm saved_dm_backup \
          dhcp_dm dhcp_dm_backup

    case "$ENETCFG_DHCP_MODE" in
        [Ss]tatic) : "${attr}DHCP in static mode${default}"
            # nothing to do
            ret=1
        ;;
        *) : "${attr}DHCP in dynamic mode${default}"
        ;;
    esac
    [[ $ret -ne 0 ]] && { RETURN $ret; }

    : "${attr}Get saved values${default}"
    ## Get the save value
    saved_dm=$(CLISettings get LOCAL ENETCFG_DM --nodefault 2>/dev/null)
    saved_dm_backup=$(CLISettings get LOCAL ENETCFG_DM_BACKUP --nodefault 2>/dev/null)
    : "${attr}saved_dm=$saved_dm${default}"
    : "${attr}saved_dm_backup=$saved_dm_backup${default}"

    ## Find the correct DM & BACKUP
    ##------------------------------
    dhcp_domain=$(CLISettings get DHCP ENETCFG_DOMAIN --nodefault 2>/dev/null)
    if [[ ! -z "$dhcp_domain" ]]; then
        # DNS SRV to resolve the DM into FQDN
        : "${attr}DNS SRV query${default}"
        dnssrv=$(srvquery $SERVICE.$TRANSPORT.${dhcp_domain})
        if [[ $? -ne 0 ]]; then
            # An error occures, could not resolve the DNS SRV
            echoerror "Could not resolve the service."
            ret=$DNS_ERROR
            RETURN $ret
        fi
        if [[ "${dnssrv//[^[:graph:]]}" != "" ]]; then
            ## DNS SRV response found
            : "${attr}DNS SRV answer not empty, use it${default}"
            # overwrite the ENETCFG_DM & ENETCFG_DM_BACKUP
            dnssrv="$dnssrv"$'\n'" "
            IFS=$'\n'; i=dm
            for line in $dnssrv; do
                unset IFS
                [[ -z "${line//[^[:graph:]]}" ]] && set "" || set $line
                case "$i" in
                    dm) : "${attr}setting dm${default}"
                        ENETCFG_DM=$1 ENETCFG_DM_PORT=$2
                        i=backup
                    ;;
                    backup) : "${attr}setting backup${default}"
                        ENETCFG_DM_BACKUP=$1 ENETCFG_DM_BACKUP_PORT=$2
                        i=done
                    ;;
                    *) : "${attr}Nohthing to do${default}"
                esac
            done
# CRMS00272826
            save_DM "DHCP" "ENETCFG_DM=\"$ENETCFG_DM\"" \
                           "ENETCFG_DM_PORT=\"$ENETCFG_DM_PORT\"" \
                           "ENETCFG_DM_CONFIG_PATH=\"$ENETCFG_DM_CONFIG_PATH\"" \
                           "ENETCFG_DM_BACKUP=\"$ENETCFG_DM_BACKUP\"" \
                           "ENETCFG_DM_BACKUP_PORT=\"$ENETCFG_DM_BACKUP_PORT\"" \
                           "ENETCFG_DM_BACKUP_CONFIG_PATH=\"$ENETCFG_DM_BACKUP_CONFIG_PATH\""
# CRMS00272826 END
            updateCurrentConfig enet.cfg
        else
            : "${attr}DNS SRV empty !!!${default}"
        fi
    fi
    dhcp_dm=$(CLISettings get DHCP ENETCFG_DM --nodefault 2>/dev/null)
    dhcp_dm_backup=$(CLISettings get DHCP ENETCFG_DM_BACKUP --nodefault 2>/dev/null)
    ## Compare the version
    comp_server "$dhcp_dm" "$saved_dm" || ret=$?
    [[ $ret -eq 0 ]] && comp_server "$dhcp_dm_backup" "$saved_dm_backup" || ret=$?
    RETURN $ret
}

get_DM()
#-------
# Get from the DM the requested settings
# INPUT:    $1      CONFIG_LOCATION
#           $...    settings to save in "var=value" format
# OUTPUT:   none
# RETVAL:   0       Success
{
    local FUNCTION=get_DM
    ENTER_FUNCTION
    local dir=$1 \
          cmd= \
          var

    shift
    while [[ $# -ne 0 ]]; do
        var=$1
        cmd="${cmd:+$cmd; }$var=\"$(CLISettings get $dir $var)\""
        shift
    done
    : "${attr}cmd:"$'\n'"${cmd:-nothing}${default}"
    [[ ! -z "$cmd" ]] && eval $cmd
    RETURN 0
}

save_DM()
#--------
# Saved the DM and its BACKUP into the local settings without post hook
# INPUT:    $1      CONFIG_LOCATION
#           $2...$n Long options which start with "--", default option "--nopost"
#           $m...   Settings to save in "var=value" format, m=n+1
# OUTPUT:   none
# RETVAL:   0       Success
{
    local FUNCTION=save_DM
    ENTER_FUNCTION
# PR341502 zimingxu+
    local dir=$1 \
          cmd= \
          var value options=--nopost
# PR341502 zimingxu-

    shift
# PR341502 zimingxu+
    # Get possible options
    while [ "${1:0:2}" == "--" ]; do
        options="$options${options:+ }$1"
        shift
    done
# PR341502 zimingxu-

    while [[ $# -ne 0 ]]; do
        # format VAR=value not respected
        : "check <var>=<value> format"
# CRMS00272826
        [[ "${1//=}" == "$1" ]] && shift && continue
        var="${1%%=*}"
        value="${1#$var=}"
        # the following line is to strip the leading and trailing '"'
        eval "value=$value" >/dev/null 2>&1
# CRMS00272826 END
        case "$value" in
            "")
# PR341502 zimingxu+
               cmd="${cmd:+$cmd; }CLISettings unset \"$dir\" $var $options" 
# PR341502 zimingxu-
            ;;
            *)
# PR341502 zimingxu+
               cmd="${cmd:+$cmd; }[[ \"$(CLISettings get DEFAULT $var)\" != \"$value\" ]] && CLISettings set \"$dir\" $var \"$value\" $options || CLISettings unset \"$dir\" $var $options"
# PR341502 zimingxu-
            ;;
        esac
        shift
    done
    eval $cmd
    RETURN 0
}

# PR412060 zimingxu+
get_dm_params()
#---------------
# Get DM relative parameters(proto, server, path, port) including backup ones
{
        local FUNCTION=get_dm_params
        ENTER_FUNCTION

        ## retrieve the local setting for ENETCFG_DM_URL
        ENETCFG_DM_URL=$(CLISettings get LOCAL ENETCFG_DM_URL 2>/dev/null)
        ## break it into params
# CRMS00351686
        parseUrl "$ENETCFG_DM_URL"
        download_proto="$parseUrl_proto"
        download_server="$parseUrl_server"
        download_path="$parseUrl_path"
        download_port="$parseUrl_port"
        ## retrieve the local setting for ENETCFG_DM_BACKUP_URL
# CRMS00351686 END
        ENETCFG_DM_BACKUP_URL=$(CLISettings get LOCAL ENETCFG_DM_BACKUP_URL 2>/dev/null)
        ## break it into params
# CRMS00351686
        parseUrl "$ENETCFG_DM_BACKUP_URL"
        download_backup_proto="$parseUrl_proto"
        download_backup_server="$parseUrl_server"
        download_backup_path="$parseUrl_path"
        download_backup_port="$parseUrl_port"
# CRMS00351686 END

        return 0
}

validate_params()
#-----------------
# Validate dm parameters and dm backup parameters
{
        local FUNCTION=validate_params
        ENTER_FUNCTION

        # Check the parameter and handle them
        if [[ ! -z "$download_server" ]]; then
                [[ ! -z "$download_proto" ]] && download_proto=$(echo "$download_proto" | tr [[:upper:]] [[:lower:]])
                download_server=$(echo "$download_server" | tr [[:upper:]] [[:lower:]])
                [[ -z "$download_path" ]] && download_path=${default_path}
                download_path=${download_path##/}
        else
                download_proto=
                download_port=
                download_path=
        fi

        # Check the backup parameters and handle them
        if [[ ! -z "$download_backup_server" ]]; then
                [[ ! -z "$download_backup_proto" ]] && download_backup_proto=$(echo "$download_backup_proto" | tr [[:upper:]] [[:lower:]])
                download_backup_server=$(echo "$download_backup_server" | tr [[:upper:]] [[:lower:]])
                [[ -z "$download_backup_path" ]] && download_backup_path=$default_path
                download_backup_path=${download_backup_path##/}
        else
                download_backup_proto=
                download_backup_port=
                download_backup_path=
        fi

        return 0
}

try_local_url()
#--------------
# Try local DM URL if DM is not configured in DHCP server in DHCP mode
{
        local FUNCTION=try_local_url
        ENTER_FUNCTION
        local ret=0

        get_dm_params

        # If download server is empty, swap it
        [ -z "$download_server" ] && { swap_server; swap=0; }

        validate_params

        [[ -z "$download_server" ]] && ret=$ERR_NODM

        return $ret
}
# PR412060 zimingxu-

select_DM()
#----------
# Select either the DM or the Proxy and the corresponding backup.
# INPUT:    none
# OUTPUT:   download_proto  The download protocole "http", "https" or "file"
#           download_server The server to use
#           download_port   The port to use
#           download_path   The path to the file on the server
#           download_backup_proto  The download protocole "http", "https" or "file"
#           download_backup_server The server to use
#           download_backup_port   The port to use
#           download_backup_path   The path to the file on the server
# RETVAL:   0           Success
#           ERR_DNS     DNS error
#           ERR_NODM    No DM found
{
    local FUNCTION=select_DM
    ENTER_FUNCTION
    local ret=0 \
          default_path server backup

    ## reset the swap status
    # !!! Have to reset because we could have gone from DM,DM_BACKUP to PROXY,PROXY_BACKUP
    swap=0
    if [[ ! -z "$cmdl_url" ]]; then
        ## A download URL has been given on the command line use it
        : "${attr}Using command line url.${default}"
        select_DM_nofallback=1
# CRMS00351686
        parseUrl "$url"
        download_proto="$parseUrl_proto"
        download_server="$parseUrl_server"
        download_path="$parseUrl_path"
        download_port="$parseUrl_port"
# CRMS00351686 END
        [[ -z "$download_server" ]] && ret=$ERR_NODM
        download_backup_server=
    else
        : "${attr}Getting DM info from configuration.${default}"
        select_DM_nofallback=0
        default_path=$ENETCFG_DM_CONFIG_PATH;
        case "${ENETCFG_DHCP_MODE}" in
            Static) : "${attr}Static mode${default}"
# CRMS00257438
                select_DM_nofallback=1
# CRMS00257438 END
# CRMS00278660
                get_DM "LOCAL" "ENETCFG_DM_PROXY_PROTOCOL" \
                               "ENETCFG_DM_PROXY" \
                               "ENETCFG_DM_PROXY_PORT" \
                               "ENETCFG_DM_PROXY_CONFIG_PATH" \
                               "ENETCFG_DM_PROXY_BACKUP_PROTOCOL" \
                               "ENETCFG_DM_PROXY_BACKUP" \
                               "ENETCFG_DM_PROXY_BACKUP_PORT" \
                               "ENETCFG_DM_PROXY_BACKUP_CONFIG_PATH"
# CRMS00278660 END
# PR412060 zimingxu+
                [[ -e "$NVDM_ROOT/enet.cfg" ]] && eval "$(awk '/ENETCFG_DM_PROXY/ { printf("%s ", $0) }' $NVDM_ROOT/enet.cfg 2>/dev/null)"
# PR412060 zimingxu-
                if [[ -z "$ENETCFG_DM_PROXY" ]]; then
                    : "${attr}Static mode, NO PROXY${default}"
                    ## NO PROXY defined
# PR412060 zimingxu+
                    get_dm_params
# PR412060 zimingxu-
                else
                    : "${attr}Static mode, PROXY${default}"
                    ## PROXY found, use it
                    server=DM_PROXY
                    backup=DM_PROXY_BACKUP
                fi
            ;;
            *) : "${attr}Dynamic mode${default}"
                ## get the default path (set by the DHCP)
                check_DM
                ret=$?
                case "$ret" in
                    ERR_DNS) : "${attr}DNS ERROR${default}"
                        RETURN $ret
                    ;;
                    0) : "${attr}identical${default}"
                        if [[ ! -z "${ENETCFG_DM_PROXY}" ]] || [[ ! -z "${ENETCFG_DM_PROXY_BACKUP}" ]]; then
                            : "${attr}using proxy settings.${default}"
                            ## Use the proxy and backup proxy settings
                            server=DM_PROXY
                            backup=DM_PROXY_BACKUP
                        else
                            : "${attr}using DM settings.${default}"
                            ## No proxy, use DM & DM_BACKUP
                            server=DM
                            backup=DM_BACKUP
                        fi
                    ;;
                    1) : "${attr}not identical${default}"
                        ret=0
                        ## Use the DM and DM backup settings
                        server=DM
                        backup=DM_BACKUP
                    ;;
                    *) : "${attr}Unknown error${default}"
                        RETURN $ret
                    ;;
                esac
            ;;
        esac
        if [[ -n "$server" ]]; then
            eval "
                unset download_server download_proto download_port download_path
                download_server=\${ENETCFG_${server}};
                if [[ ! -z \"\$download_server\" ]]; then
                    download_proto=\${ENETCFG_${server}_PROTOCOL}
                    download_port=\${ENETCFG_${server}_PORT}
                    download_path=\${ENETCFG_${server}_CONFIG_PATH}
                    [[ -z \"\$download_path\" ]] && download_path=\$default_path
                fi
                unset download_backup_server download_backup_proto download_backup_port download_backup_path
                download_backup_server=\${ENETCFG_${backup}}
                if [[ ! -z \"\$download_backup_server\" ]]; then
                    download_backup_proto=\${ENETCFG_${backup}_PROTOCOL}
                    download_backup_port=\${ENETCFG_${backup}_PORT}
                    download_backup_path=\${ENETCFG_${backup}_CONFIG_PATH}
                    [[ -z \"\$download_backup_path\" ]] && download_backup_path=\$default_path
                fi
            "
        fi
        ## check that at least the DM server is not empty !!!
        if [[ -z "$download_server" ]]; then
            # download server is empty !!! Try to swap it
            swap_server
            ret=$?
            # reset swappiness
            swap=0
        fi
        if [[ $ret -ne 0 ]] && [[ ! -z "$url" ]]; then
            ## A download URL has been define in the rc file, and we did not get another one, use it
            : "${attr}No DM from the configuration.${default}"
            : "${attr}Using default download url.${default}"
            select_DM_nofallback=1
# CRMS00351686
            parseUrl "$url"
            download_proto="$parseUrl_proto"
            download_server="$parseUrl_server"
            download_path="$parseUrl_path"
            download_port="$parseUrl_port"
# CRMS00351686 END
            download_backup_server=
        fi
    fi

# PR412060 zimingxu+
    validate_params

    if [ -z "$download_server" ]
    then
        [ "${ENETCFG_DHCP_MODE}" == "Static" ] && ret=$ERR_NODM || { try_local_url; ret=$?; }
    fi
# PR412060 zimingxu-

    : "${attr}DM: ${download_proto:+$download_proto://}$download_server${download_port:+:$download_port}${download_path:+/$download_path}${default}"
    : "${attr}BACKUP: ${download_backup_proto:+$download_backup_proto://}$download_backup_server${download_backup_port:+:$download_backup_port}${download_backup_path:+/$download_backup_path}${default}"
    RETURN  $ret
}

get_server_param()
#-----------------
# Get the server parameters
# INPUT:    $1                      The file to download
# OUTPUT:   download_url            The url where the file can be found
#           download_backup_url     The backup url where the file can be bound
# RETVAL:   0       Success
#           other   Failure
{
    local FUNCTION=get_server_param
    ENTER_FUNCTION
    local in_file="$1" in_path \
          proto server port path file

    if [[ -z "$in_file" ]]; then
        in_file="${download_url}" in_file=${in_file#*://}$download_file in_file="/${in_file#*/}"
        in_path=${in_file%/*} in_path=${in_path##/}
        if [[ "$in_path" == "$download_path" ]]  || [[ "$in_path" == "$download_backup_path" ]]; then
            in_file=${in_file##*/}
        fi
    fi
    if [[ "${in_file#*://}" == "$in_file" ]]; then
        : "${attr}No server information in: $in_file${default}"
        : "${attr}using selected DM${default}"
        # select_DM_nofallback has been positionned by get_config that has been run
# CRMS00282384
        [[ $nofallback -eq 0 ]] && nofallback=${select_DM_nofallback}
# CRMS00282384 END
        urlfromfile=0
        ## the file is taken from the function argument
        path=${in_file%/*} file=${in_file##*/} path=${path#$file}
        proto=$download_proto
        server=$download_server
        port=$download_port
        backup_proto=$download_backup_proto
        backup_server=$download_backup_server
        backup_port=$download_backup_port
        if [[ -z "$path" ]]; then
            path=$download_path
            backup_path=$download_backup_path
        else
            path="$path/"
            backup_path=$path
        fi
    else
        : "${attr}getting server information from: $in_file${default}"
        nofallback=1
        urlfromfile=1
        ## the file has a complete URI
        ##-----------------------------
        # Break the URI into the parameters
        proto=${in_file%://*}
        server=${in_file#$proto://} server=${server%%/*}
        file=${in_file#$proto://$server}
        port=${server#*:} server=${server%:${port}}
        [[ "$port" == "$server" ]] && port=
        path=${file%/*} file=${file##*/} path=${path#$file}
# CRMS00280704
        [[ -n "$path" ]] && path="${path%/}/"
# CRMS00280704 END
        # format the different parameters
        proto=$(echo "$proto" | tr [[:upper:]] [[:lower:]])
        server=$(echo "$server" | tr [[:upper:]] [[:lower:]])
        ## No backup in this case
        ##------------------------
        backup_proto=
        backup_server=
        backup_port=
        backup_path=
    fi
    download_file=$file
    # last formatting of the params
    # proto
    # server
    # port
    # path
    [[ ! -z "$server" ]] && download_url="${proto:+$proto://}${server:+$server}${port:+:$port}${path:+/${path##/}}" || download_url=
    [[ ! -z "$backup_server" ]] && download_backup_url="${backup_proto:+$backup_proto://}${backup_server:+$backup_server}${backup_port:+:$backup_port}${backup_path:+/${backup_path##/}}" || download_backup_url=
    ## check if the ENETCFG_DM_URL has to end with '/'
    case "$download_url" in
        ""|*/) :
        ;;
        *\?*) : "${attr}The download url contains an URI parameters, do nothing${default}"
        ;;
        *) : "${attr}The download url contains no URI parameters, add a '/'${default}"
            download_url="$download_url/"
        ;;
    esac
    case "$download_backup_url" in
        ""|*/) :
        ;;
        *\?*) : "${attr}The backup download url contains an URI parameters, do nothing${default}"
        ;;
        *) : "${attr}The backup download url contains no URI parameters, add a '/'${default}"
            download_backup_url="$download_backup_url/"
        ;;
    esac
    : "${attr}download_url: $download_url${default}"
    : "${attr}download_backup_url: $download_backup_url${default}"
    RETURN 0
}

swap_server()
#------------
# Swap the download server and its backup
# INPUT:    none
# OUTPUT:   download_proto  The download protocole "http", "https" or "file"
#           download_server The server to use
#           download_port   The port to use
#           download_path   The path to the file on the server
#           download_backup_proto  The download protocole "http", "https" or "file"
#           download_backup_server The server to use
#           download_backup_port   The port to use
#           download_backup_path   The path to the file on the server
# RETVAL:   0           Success
#           ERR_NOBKP   The backup was empty, nothing done
{
    local FUNCTION=swap_server
    ENTER_FUNCTION
    local ret tmp_proto tmp_server tmp_port tmp_path tmp_download_url

    : "${attr}Current swap state: $swap${default}"
    [[ $swap -eq 1 ]] && { RETURN $ERR_SWAP; }
    if [[ $urlfromfile -eq 0 ]] && [[ ! -z "${download_backup_server}" ]]; then
        swap=1
        tmp_proto=$download_proto
        tmp_server=$download_server
        tmp_port=$download_port
        tmp_path=$download_path
        tmp_download_url=$download_url
        download_proto=$download_backup_proto
        download_server=$download_backup_server
        download_port=$download_backup_port
        download_path=$download_backup_path
        download_url=$download_backup_url
        download_backup_proto=$tmp_proto
        download_backup_server=$tmp_server
        download_backup_port=$tmp_port
        download_backup_path=$tmp_path
        download_backup_url=$tmp_download_url
        ret=0
    else
        ret=$ERR_NOBKP
    fi
    RETURN $ret
}

download()
#---------
# Download the "download_file"
# INPUT:    $1      retry number
#           $2      max number of retry
#           $3      download_url
#           $4      download_backup_url
#           $5      file
# CRMS00285309
#           $6      original_file
# CRMS00285309 END
# OUTPUT:   none
# RETVAL:   0       Success
#           ERR_BADCFG
#           ERR_DISK
#           ERR_DNS
#           ERR_NOBKP
#           ERR_NODM
#           ERR_SSL
#           ERR_TMOUT
{
    local FUNCTION=download
    ENTER_FUNCTION
# CRMS00285309
# CRMS00290892
    local retry=$1 maxretry=$2 url=$3 backup_url=$4 file=$5 original_file="$6" \
          ret=0 \
          httpCode= \
          curl_args="-f -L" phonemodel="" domisc=0
# CRMS00290892 END
# CRMS00285309 END

    ## update curl options
    ##---------------------
# CRMS00290892
    case "${url%://*}" in
        file|http) : "${attr}http/file protocol${default}"
        ;;
        https) : "${attr}https protocol${default}"
# crqms00151045 
            curl_args="${curl_args:+$curl_args }--tlsv1"
# crqms00151045 END
            [[ -n "$cert" ]] && curl_args="${curl_args:+$curl_args }--cert $cert"
            [[ -n "$key" ]] && curl_args="${curl_args:+$curl_args }--key $key"
# CRMS00302064
            if [[ "$insecure" == "INSECURED" ]] || [[ $ctl_update == 1 ]]; then
                echo "Next download will be done in insecure mode"
# CRMS00302064 END
                curl_args="${curl_args:+$curl_args }--insecure"
            else
# CRMS00260316
                curl_args="${curl_args:+$curl_args }--cacert $ca --disable-ssl-cn-check"
# CRMS00260316 END
            fi
        ;;
        *) : "${attr}Unsupported proto: $download_proto${default}"
            echoerror "unsupported protocol ($download_proto)"
            ret=1
        ;;
    esac
# CRMS00290892 END
    : "${attr}ret=$ret${default}"
    [[ $ret -ne 0 ]] && { RETURN $ret; }
    ## download the file
    ##-------------------
    : "${attr}download_proto=$download_proto${default}"
    case "$download_proto" in
        file) : "${attr}file${default}"
            cp /$download_path$download_file /tmp/$downloaddir$download_file
            ret=0
            # fake a successful httpCode
            httpCode=200
        ;;
        http*) : "${attr}http(s)${default}"
            # pass the PHONE_MODEL as argument
            # phonemodel is used as a tmp var before being set
# CRMS00243881
            phonemodel=$url$download_file
# CRMS00243881 END
            if [[ "${phonemodel//\?}" == "$phonemodel" ]]; then
                # '?' not found in the URI
                phonemodel="?PHONE_MODEL=$PHONE_MODEL"
            else
                # '?' found in the URI
                phonemodel="&PHONE_MODEL=$PHONE_MODEL"
            fi
            # recreate the download url
# CRMS00290892
# CRMS00243881
# PR262041 
            if IN_DEBUG; then
                httpCode=$(dowait curl -v\
                    $curl_args \
                    --write-out %{http_code} \
                    ${timeout+--connect-timeout $timeout} \
                    ${retry+--retry $retry}\
                    -o /tmp/$downloaddir/$download_file \
                    $url$download_file$phonemodel)
            else
                httpCode=$(dowait --nostderr curl \
                    $curl_args \
                    --write-out %{http_code} \
                    ${timeout+--connect-timeout $timeout} \
                    ${retry+--retry $retry}\
                    -o /tmp/$downloaddir/$download_file \
                    --silent --output /dev/null \
                    $url$download_file$phonemodel)
            fi
# PR262041 END
# CRMS00243881 END
# CRMS00290892 END
            ret=$?
        ;;
    esac

    if [[ $ret -ne 0 ]] || [[ "${httpCode#2}" == "$httpCode" ]] ; then
        echoerror "Retrieving $url$download_file$phonemodel"
        if [[ $ret -eq 0 ]]; then
            echoerror "curl ret: $ret & http code: $httpCode"
        else
            echoerror "curl ret: $ret"
        fi
# CRMS00268714
        [[ $thread -eq 0 ]] && displaymsg "$scriptname: curl ret: $ret & http code: $httpCode"
# CRMS00268714 END
    else
# CRMS00312748
# CRMS00286717
        echolog "($PID)SUCCESS" "Retrieving $url$download_file$phonemodel"
        if [[ $ret -eq 0 ]]; then
            echolog "($PID)SUCCESS" "curl ret: $ret & http code: $httpCode"
        else
            echolog "($PID)SUCCESS" "curl ret: $ret"
        fi
        [[ $thread -eq 0 ]] && displaymsg "$scriptname: curl ret: $ret & http code: $httpCode"
# CRMS00286717 END
# CRMS00312748 END
    fi

    ## update err depending on the effective download
    ##------------------------------------------------
    : "${attr}update return code on effective download${default}"
    case "$ret" in
        0) : "${attr}A content has been retrieved${default}"
            case "$httpCode" in
                2[[:digit:]][[:digit:]]) : "${attr}HTTP Success${default}"
                    ret=0
                ;;
# PR262041
                401) : "${attr}(401)authentication need${default}"
                    ret=$ERR_AUTH_REQ
                ;;
# PR262041 END
                [45][[:digit:]][[:digit:]]|404) : "${attr}(4xx)bad configuration${default}"
                    ret=$ERR_BADCFG
                    rm /tmp/$downloaddir/$download_file >/dev/null 2>&1
                ;;
            esac
        ;;
        6) : "${attr}DNS Error${default}"
            ret=$ERR_DNS
        ;;
        7) : "${attr}Failed to connect to host${default}"
            # no http/https server
            if [[ $nofallback -eq 0 ]] && [[ "$download_proto" == "https" ]]; then
                : "${attr}Falling back to http and retry${default}"
                # update the proto and recreate the urls
                download_proto=http
# CRMS00285309
                get_server_param "$original_file"
# CRMS00243881
                download "$retry" "$maxretry" "$download_url" "$download_backup_url" "$file" "$original_file"
# CRMS00243881 END
# CRMS00285309 END
                ret=$?
            else
                : "${attr}Falling back not allowed, swapping servers and retry${default}"
                if swap_server; then
# CRMS00285309
                    download "$retry" "$maxretry" "$download_url" "$download_backup_url" "$file" "$original_file"
# CRMS00285309 END
                    ret=$?
                else
                    ret=$ERR_NODM
                fi
            fi
        ;;
# PR262041 
        22) :  
            case "$httpCode" in
                401) : "${attr}(401)authentication need${default}"
                    ret=$ERR_AUTH_REQ
                ;;
                *) : "${attr}(curl)bad configuration${default}"
            ret=$ERR_BADCFG
            rm /tmp/$downloaddir/$download_file >/dev/null 2>&1
        ;;
            esac
        ;;
# PR262041 END
        23) : "${attr}Local disk error${default}"
            ret=$ERR_DISK
            rm /tmp/$downloaddir/$download_file >/dev/null 2>&1
        ;;
        28) : "${attr}Timeout${default}"
# CRMS00243881
            if swap_server; then
# CRMS00285309
                download "$retry" "$maxretry" "$download_url" "$download_backup_url" "$file" "$original_file"
# CRMS00285309 END
                ret=$?
            else
                ret=$ERR_TMOUT
            fi
# CRMS00243881 END
        ;;
        35) : "${attr}SSL connect error (handshake failed)${default}"
            # https server present but connection failed
# CRMS00243881
            if swap_server; then
# CRMS00285309
                download "$retry" "$maxretry" "$download_url" "$download_backup_url" "$file" "$original_file"
# CRMS00285309 END
                ret=$?
            else
                ret=$ERR_CTL
            fi
# CRMS00243881 END
        ;;
        51) : "${attr}remote SSL certificate signature not OK${default}"
            if swap_server; then
# CRMS00285309
                download "$retry" "$maxretry" "$download_url" "$download_backup_url" "$file" "$original_file"
# CRMS00285309 END
                ret=$?
            else
                ret=$ERR_SSL
            fi
        ;;
        52) : "${attr}The server didn't reply anything${default}"
            if swap_server; then
# CRMS00285309
                download "$retry" "$maxretry" "$download_url" "$download_backup_url" "$file" "$original_file"
# CRMS00285309 END
                ret=$?
            else
                ret=$ERR_NODM
            fi
        ;;
        58) : "${attr}Local certificat problem${default}"
            ret=$ERR_SSL
        ;;
        60) : "${attr}Invalid remote certificat${default}"
# CRMS00302064
            ret=$ERR_CTL
        ;;
        66) : "${attr}Problem with SSL engine${default}"
            ret=$ERR_SSL
        ;;
        77) : "${attr}Problem reading SSL CA cert${default}"
            ret=$ERR_SSL
        ;;
        133) : "${attr}SIGTRAP received during curl${default}"
            if [[ $thread -eq 1 ]]; then
                domisc=0
                ret=$ERR_TRAP
            else
                domisc=1
            fi
        ;;
        138) : "${attr}SIGUSR1 received during curl${default}"
            if [[ $thread -eq 1 ]]; then
                domisc=0
                ret=$ERR_USR1
            else
                domisc=1
            fi
        ;;
        *) : "${attr}Misc error${default}"
            domisc=1
        ;;
    esac
    if [[ $domisc -eq 1 ]]; then
        echo "${attr}Misc error($ret)${default}" >/dev/console
        if swap_server; then
# CRMS00285309
            download "$retry" "$maxretry" "$download_url" "$download_backup_url" "$file" "$original_file"
# CRMS00285309 END
            ret=$?
        else
            ret=$ERR_NODM
        fi
    fi
    RETURN $ret
}

# _CTL_INSTALL
install_CTL()
#------------
# Do the check of the CTL
# INPUT:    $1      path to the config file 
#           $2      config file
# OUPUT:    none
# RETVAL:   0
#           ERR_CKSUM   wrong checksum
#           other       cf download()
{
    local FUNCTION=install_CTL
    ENTER_FUNCTION
    local filepath=$1 \
          filename=$2 \
          local_hash \
          ret=$ERR_MISC \
          msg

    removeTrailing "/" filepath
    removeLeading "/" filename
    ## read the info from the xml file
    ##---------------------------------
    eval "$(xmlparse $filepath/$filename platform=1 DmCtlSigningMacaddr DmCtlFile DmCtlHash)"
    ## hash identical, do do nothing
    ##-------------------------------
    local_hash="$(CLISettings get DM CTL_HASH)"

# CRMS00268816
# CRMS00275977    
#    [[ "${CTL_HASH:-NO HASH!!!}" == "$local_hash" ]] && { RETURN 0; }
#    if [[ "${CTL_HASH}" == "$local_hash" ]] && ( [[ "$insecure" == "INSECURED" ]] && [[ -n "$CTL_HASH" ]] || [[ "$insecure" != "INSECURED" ]] ); then
#    	return 0
#    fi

    if [[ "$insecure" == "SECURED" ]]; then
    #secured mode: CTL or customer certificate installed
        # same HASH found, CTL already installed, exit with OK
        if [[ "${CTL_HASH}" == "$local_hash" ]]; then
            #CRMS00333277
            if [[ $ctl_update == 1 ]]; then
                msg="Check CTL file/parameters on the DM server."
                echoerror "$msg"
                displaymsg "$msg"
                displaypopup "$msg"
                do_reboot "Check CTL file/parameters on the DM server."
                RETURN $ERR_NEVER
            fi
            #CRMS00333277 END
            #CRMS00302064
            # clean the flag to avoid to keep the insecure dwl mode
            ctl_update=0
            ret=$OK
            RETURN $ret
        fi
        if  [[ -z "${CTL_HASH//[[:blank:]]}" ]] && [[ -n "$local_hash" ]]; then
            # received DM HASH is empty, local hash exists: notify an error, but don't reset
            msg="Received CTL hash is empty but not the local one."
            #CRMS00302064
            # clean the flag to avoid to keep the insecure dwl mode
            ctl_update=0
            echoerror "$msg"
            displaymsg "$msg"
# CRMS00280492
            displaypopup "$msg"
            ret=$ERR_CKSUM
# CRMS00280492 END
            RETURN $ret
        fi
        # HASH are different and DM CTL_HASH non empty, download and test the hash validity
    else
        # no CTL_HASH in DM config file => no CTL on DM server, exit
        if [[ -z "${CTL_HASH//[[:blank:]]}" ]]; then
            do_reboot "No hash given for the CTL."
            RETURN $ERR_NEVER
        fi
        # else CTL_HASH is present, try to download the CTL
    fi
# CRMS00275977 END  

    : "${attr}Downloading and installing the CTL${default}"
# CRMS00268816 END

# CRMS00282780
 # no CTL_FILE in DM config file => must warn the admin
    if [[ -z "${CTL_FILE//[[:blank:]]}" ]]; then
        msg="CTL_FILE is empty: cannot download the CTL"
        echoerror "$msg"
        displaymsg "$msg"
        displaypopup "$msg"
        do_reboot --delay=10 "CTL_FILE empty"
        RETURN $ERR_NEVER
    fi
# CRMS00282780 END

 # CRMS00282812
    displaypopup -t 4 -l information "New CTL found"
    sleep 2
# CRMS00282812 END

    ## download the CTL
    ##------------------
    get_server_param "$CTL_FILE"
# CRMS00285309
    download 1 1 "$download_url" "$download_backup_url" "$download_file" "$CTL_FILE"
# CRMS00285309 END
    ret=$?
    if [[ $ret -ne 0 ]]; then
# CRMS00282780
        msg="Could not download the CTL"
        echoerror "$msg"
        displaymsg "$msg"
        displaypopup "$msg"
# CRMS00282780 END
        do_reboot --delay=10 "Could not download the CTL: $download_url/$download_file"
        RETURN $ERR_NEVER
    fi

    #CRMS00302064
    # clean the flag to avoid to keep the insecure dwl mode
    ctl_update=0

# CRMS00273516
    ## do the verification of the CTL_HASH
    ##-------------------------------------
# CRMS00280492
    set -- $(openssl md5 "/tmp/$downloaddir/$download_file")
# CRMS00280492 END
    local_hash=$2
    if [[ "$local_hash" != "$CTL_HASH" ]]; then
        msg="Received CTL checksum is incorrect."
        echoerror "$msg"
        displaymsg "$msg"
# CRMS00280492
        displaypopup "$msg"
# CRMS00280492 END
#CRMS00333277
        do_reboot --delay=10 "Received CTL checksum is incorrect"
        ret=$ERR_NEVER
#CRMS00333277 END
        RETURN $ret
    fi
# CRMS00273516 END

# CRMS00282780
 # no CTL_SIGNING_MACADDR in DM config file => must warn the admin
    if [[ -z "${CTL_SIGNING_MACADDR//[[:blank:]]}" ]]; then
        msg="CTL_SIGNING_MACADDR is empty: cannot verify the CTL"
        echoerror "$msg"
        displaymsg "$msg"
        displaypopup "$msg"
        do_reboot --delay=10 "CTL_SIGNING_MACADDR empty"
        RETURN $ERR_NEVER
    fi
# CRMS00282780 END

    ## install the CTL into the phone set
    ##------------------------------------
    installCTL "-m $CTL_SIGNING_MACADDR" -x "/tmp/$downloaddir/$download_file"
    ret=$?
    if [[ $ret != 0 ]]; then
# CRMS00282780
        displaymsg "Installation of the CTL failed"
        displaypopup "Installation of the CTL failed"
# CRMS00282780 END
        do_reboot --delay=10 "Installation of the CTL failed."
        RETURN $ERR_NEVER
    fi

    ## Memorize CTL hash 
    ##-------------------
    CLISettings set dm CTL_HASH $CTL_HASH

    #CRMS00247489
    touch $nocleanflag

    display "Restart with the new CTL"
    eval exec "$(popall cmdline)"
    ( attr="$esc[31m"; default="$esc[0m"; display "SHOULD NEVER ARRIVE HERE." )
    gotoInfiniteLoop
}
# _CTL_INSTALL END

# PR262041
get_authen_url()
#-----------------
# Get the server parameters
# INPUT:    $1                    device_key
#           $2                    md5_pass
#           $3                    mac
# OUTPUT:   authen_url            The url where the authentication message will be sent
#
# RETVAL:   OK       Success
#           other    Failure
{
    local FUNCTION=get_authen_url
    ENTER_FUNCTION
    local protol=$download_proto \
          server=$download_server \
          port=$download_port \
          path=$authen_path \
          device_key=$1 \
          md5_pass=$2 \
          mac=$3 \
          ret=$OK

    ## check if "device_key" and "md5_pass" contain char '?' and '&'
    ##-------------------------------------------------------------
    device_key=${device_key//"?"/"\?"}
    device_key=${device_key//"&"/"\&"}
#CRMS00366845   
    md5_pass=`printf $md5_pass | openssl md5 | awk '{print $1}'`
#CRMS00366845 END
    
    ## compose the authentication url
    ##--------------------------------
    if [[ ! -z "$server" ]]; then
        authen_url="${protol:+$protol://}${server:+$server}${port:+:$port}${path:+/${path##/}}?DEVICE_KEY=$device_key&MD5_PASS=$md5_pass&MAC=$mac" 
    else
        authen_url=
    fi

    if [[ -z $authen_url ]]; then
        ret=$ERR_MISC
    else
        echo "authen_url: $authen_url"
    fi

    RETURN $ret
}

authen_send()
#---------------
# Send authentication message to DM server
# INPUT:    $1      authen_url
# OUTPUT:   
# RETVAL:   OK              Success
#           AUTH_RETRY      authentication retry
#           AUTH_FAILED     authentication failed 
{
    local FUNCTION=authen_send
    ENTER_FUNCTION
    local url=$1 \
          httpCode= \
          curl_args="-f -L" \
          ret=$OK
    
    case "${url%://*}" in
        http) : "${attr}http protocol${default}"
        ;;
        https) : "${attr}https protocol${default}"
            curl_args="${curl_args:+$curl_args }--tlsv1"
            [[ -n "$cert" ]] && curl_args="${curl_args:+$curl_args }--cert $cert"
            [[ -n "$key" ]] && curl_args="${curl_args:+$curl_args }--key $key"
            
            if [[ "$insecure" == "INSECURED" ]] || [[ $ctl_update == 1 ]]; then
                echo "authentication will be done in insecure mode"
                curl_args="${curl_args:+$curl_args }--insecure"
            else
                curl_args="${curl_args:+$curl_args }--cacert $ca --disable-ssl-cn-check"
            fi
        ;;
        *) : "${attr}Unsupported proto: $download_proto${default}"
            echoerror "unsupported protocol ($download_proto)"
            ret=$AUTH_FAILED
        ;;
    esac

    : "${attr}ret=$ret${default}"
    if [[ $ret -ne $OK ]]; then                                                 
        RETURN $ret                                                             
    fi    

    if IN_DEBUG; then
        httpCode=$(dowait curl -v\
        $curl_args \
        --write-out %{http_code} \
        ${timeout+--connect-timeout $timeout} \
        ${retry+--retry $retry} \
        $url)
    else
        httpCode=$(dowait --nostderr curl \
        $curl_args \
        --write-out %{http_code} \
        ${timeout+--connect-timeout $timeout} \
        ${retry+--retry $retry} \
        --silent --output /dev/null \
        $url)
    fi
    
    ret=$?

    ## check the curl return
    ##----------------------
    : "${attr}check authentication result${default}"
    case "$ret" in
        0) : "${attr}A content has been retrieved${default}"
            case "$httpCode" in
                2[[:digit:]][[:digit:]]) : "${attr}Authentication Success${default}"
                    ret=$OK
                ;;
                401) : "${attr}(401)authentication retry need${default}"
                    ret=$AUTH_RETRY
                ;;
                *) : "${attr}($httpCode)authentication failed${default}"
                    ret=$AUTH_FAILED
                ;;
            esac
        ;;
        22) : "${attr}Curl return 22${default}"
            case "$httpCode" in
                401) : "${attr}(401)authentication retry need${default}"
                    ret=$AUTH_RETRY
                ;;
                *) : "${attr}($httpCode)authentication failed${default}"
                    ret=$AUTH_FAILED
                ;;
            esac
        ;;
 
        *) : "${attr}($httpCode)authentication failed${default}"
            ret=$AUTH_FAILED
        ;;
    esac

    : "${attr}ret: $ret ${default}"
    RETURN $ret
}
# PR262041 END

# CRMS00358058
# CRMS00335652
# CRMS00329513
updateSystemConfiguration()
#----------------------------------
# update system configuration if not in survivability mode
# INPUT:    none
# OUPUT:    none
# RETVAL:   0

{
    local FUNCTION=updateSystemConfiguration
    ENTER_FUNCTION

    # update current enet.cfg
# CRMS00358058 END
    # CRMS00246998
        ENETCFG_DM_PROTOCOL="$download_proto"
        ENETCFG_DM="$download_server"
        ENETCFG_DM_PORT="$download_port"
        ENETCFG_DM_CONFIG_PATH="/$download_path"
        ENETCFG_DM_BACKUP_PROTOCOL="$download_backup_proto"
        ENETCFG_DM_BACKUP="$download_backup_server"
        ENETCFG_DM_BACKUP_PORT="$download_backup_port"
    # CRMS00246998 END
        updateCurrentConfig enet.cfg --noread
    # CRMS0000253769
        if [[ "$download_path" == "$download_backup_path" ]]; then
            ENETCFG_DM_BACKUP_CONFIG_PATH=
        fi
    # CRMS00272826
        save_DM "LOCAL" "ENETCFG_DM_PROTOCOL=\"$ENETCFG_DM_PROTOCOL\"" \
                        "ENETCFG_DM=\"$ENETCFG_DM\"" \
                        "ENETCFG_DM_PORT=\"$ENETCFG_DM_PORT\"" \
                        "ENETCFG_DM_CONFIG_PATH=\"$ENETCFG_DM_CONFIG_PATH\"" \
                        "ENETCFG_DM_BACKUP_PROTOCOL=\"$ENETCFG_DM_BACKUP_PROTOCOL\"" \
                        "ENETCFG_DM_BACKUP=\"$ENETCFG_DM_BACKUP\"" \
                        "ENETCFG_DM_BACKUP_PORT=\"$ENETCFG_DM_BACKUP_PORT\"" \
                        "ENETCFG_DM_BACKUP_CONFIG_PATH=\"$ENETCFG_DM_BACKUP_CONFIG_PATH\""
    # CRMS00272826 END
    # CRMS0000253769 END
    
    RETURN 0
}
# CRMS00329513 END
# CRMS00335652 END

# crqms00121003
gen_check_pin_and_run()
#---------------
{
    tmp_check_file=/tmp/check_pin_input.sh
    echo "#!/bin/sh" > ${tmp_check_file}
    echo "sleep 300" >> ${tmp_check_file}
    echo "if [ -e ${AppPtfDmPipeFile} ]" >> ${tmp_check_file}
    echo "then" >> ${tmp_check_file}
    echo "  rm -f ${AppPtfDmPipeFile}" >> ${tmp_check_file}
    echo "  reboot" >> ${tmp_check_file}
    echo "fi" >> ${tmp_check_file}
    echo 'rm -f $0' >> ${tmp_check_file}
    chmod +x ${tmp_check_file}
    ${tmp_check_file} &
}
# crqms00121003 END

download_parse()
#---------------
# Download and Parse if need be the files
# INPUT:    $1      max number of retry
#           $2...   files to check
# OUTPUT:   MISSING A string containing the missing files
# RETVAL:   0           Success
#           XMLPARSE    private XML parser used
#           ERR_DNS     DNS Error
#           other       Failure
{
    local FUNCTION=download_parse
    ENTER_FUNCTION
    local maxretry=$1; shift
# CRMS00296816
# CRMS00275985
    local TORETRIEVE="$@" \
          RET \
          curl_args \
          _maxretry \
          delay \
          dlretry \
          file_template \
          filenumber=0 \
          item \
          option file \
          ret \
          todl \
          cmd \
          diff \
          device_key \
          md5pass \
          pipestring \
          mac \
          authen_ok= \
          parsed
# CRMS00275985 END
# CRMS00296816 END

# CRMS00288108
    ## cleanup the post-parsing directory
    ##------------------------------------
    rm -rf $POSTPARSINGDIR >/dev/null 2>&1
    mkdir -m 0755 $POSTPARSINGDIR
# CRMS00293946
    # run always these scripts
    cp -s /usr/lib/lib_settings/*.deferred_always $POSTPARSINGDIR >/dev/null 2>&1
# CRMS00293946 END
# CRMS00288108 END
    ## try to retrieve each item
    ##---------------------------
    todl=$TORETRIEVE
# CRMS00275985
    diff=0
# CRMS00275985 END
# CRMS00296816
    parsed=0
# CRMS00296816 END


    while [[ -n "$todl" ]]; do
        ## get the one item and its option
        ##---------------------------------
        : "${attr}Get file and option${default}"
        file_template="" file="" option=""
        while [ -z "$file" -o -z "$option" ] && pop item todl; do
            : "${attr}item: $item${default}"
            case "$item" in
                M|mandatory*) : "${attr}mandatory field${default}"
                [[ -n "${option:-}" ]] && break
                option=M
                ;;
                O|optional*) : "${attr}optional field${default}"
                [[ -n "${option:-}" ]] && break
                option=O
                ;;
                *) : "${attr}filename field${default}"
                [[ -n "${file_template:-}" ]] && break
                file_template=$item
                # resolve the variables from the file_template to get the filename
                eval "file=$file_template"
                ;;
            esac
        done
        option=${option:-M}
        : "${attr}FILE_TEMPLATE: $file_template${default}"
        : "${attr}FILE: $file${default}"
        : "${attr}OPTION: $option${default}"
        if [[ -z "${cmdl_filelist}" ]]; then
            ## update filenumber
            ##-------------------
# CRMS00213012
            filenumber=$((filenumber+1))
# CRMS00213012 END
            case "$filenumber" in
                2) : "${attr}Second configuration file, reevaluate the server${default}"
                select_DM
# PR341502 zimingxu+
                RET=$?
                [[ "$RET" != "$OK" ]] && { RETURN $RET; }
# PR341502 zimingxu-
                ;;
            esac
        fi
        ## check the resulting filename and option
        ##-----------------------------------------
        : "${attr}Check file and option${default}"
        if [[ -z "${file_template}" ]]; then
            ## empty template
            continue
        fi
        if [[ -n "$file_template" ]] && [[ -z "$file" ]]; then
            ## the template resolved into nothing
            case "$option" in
                O|Optional*) : "${attr} optional file, skip it.${default}"
                ;;
                M|mandatory*) : "${attr} mandatory file, mark it as missing.${default}"
                    if [[ "${MISSING//$file_template}" == "$MISSING" ]]; then
                        MISSING="${MISSING:+$MISSING, }$file_template"
                    fi
                ;;
            esac
            continue
        fi
# CRMS00228734
        ## if the 1st file has failed, mark all the following as missing
        ##---------------------------------------------------------------
         if [[ $filenumber -gt 1 ]] && [[ $dlretry -eq $maxretry ]]; then
             if [[ "${MISSING//$file_template}" == "$MISSING" ]]; then
                 MISSING="${MISSING:+$MISSING, }$file_template"
             fi
             continue
         fi
# CRMS00228734 END
        ## get the server proto, port and path from which to download
        ##------------------------------------------------------------
        get_server_param "$file"
        ## try to download up to maxretry
        ##--------------------------------
# CRMS00228734
        ## max attempts for the 1st file only, and 1 for the others
        ##----------------------------------------------------------
        dlretry=0
        if [[ $filenumber -eq 1 ]]; then
            _maxretry=$maxretry
        else
            _maxretry=1
        fi
# CRMS00228734 END
        while [[ $dlretry -lt $_maxretry ]]; do
            if [[ $swap -ne 0 ]]; then
                # Dm & BACKUP have been swapped, reswap them to have the original order
                swap=0
                swap_server
                swap=0
            fi
            ## do the sleep if it is not the 1st attempt
            ##-------------------------------------------
            if [[ $dlretry -ne 0 ]]; then
                if IN_DEBUG; then
                    delay=5
                    : "${attr}${attr:=}-- (IN_DEBUG) sleeping for $delay seconds${default}"
                else
                    delay=$((delaydownloadretry-15+RANDOM%30))
                    : "${attr}${attr:=}-- sleeping for $delay seconds${default}"
                fi
# CRMS00312748
                sleep $delay & wait $!; kill $! 2>/dev/null
# CRMS00312748 END
            fi
            ## download the file
            ##-------------------
# CRMS00285309
# CRMS00243881
            download "$dlretry" "$_maxretry" "$download_url" "$download_backup_url" "$download_file" "$file"
# CRMS00243881 END
# CRMS00285309 END
            ret=$?
            if [[ $ret -eq 0 ]] || [[ $ret -eq $ERR_TRAP ]] || [[ $ret -eq $ERR_USR1 ]]; then
                break
            fi
# CRMS00302064
            ## Curl error code 60: untrusted server certificat
            ##------------------------------------------------
            if [[ $filenumber -eq 1 ]] && [[ $ret -eq $ERR_CTL ]]; then
                # Force CTL update (insecure mode) at next download of mac config file
                ctl_update=1
                # do not increment dlretry to avoid the 30s delay
            else
                ## start next retry
                ##------------------
                dlretry=$((dlretry+1))
            fi
# CRMS00302064 END

# PR262041
            ## DM server need authenticate login information
            ##-----------------------------------------------
            if [[ $filenumber -eq 1 ]] && [[ $ret -eq $ERR_AUTH_REQ ]]; then
                ## start authentication process
                ##----------------------------------------
# CRMS00418041 zimingxu+
                if [[ "$(cat $stepfile 2>/dev/null)" -ge 5 ]]; then
                    authen_ok=$AUTH_FAILED
                else
                    authen_ok=$AUTH_RETRY
                fi
# CRMS00418041 zimingxu-
                while [[ $authen_ok -eq $AUTH_RETRY ]]; do
                    mkfifo ${AppPtfDmPipeFile} -m 0666 >/dev/null 2>&1
                    device_key=
                    md5pass=
                    while [[ -z $device_key ]] || [[ -z $md5pass ]]; do
                            #CRMS 00370729
                            [[ -n "$xtrace" ]] && set_debug_off
                            while [[ -f /tmp/lockinit ]] || [[ -f /.lockinit ]];do
                                usleep 100000
                            done
                            [[ -n "$xtrace" ]] && set_debug_on
                            #CRMS 00370729 END
                            notify_event2dbus DMLoginRequest
                            while  [[ ! -e  ${AppPtfDmPipeFile} ]];do
                               : "${attr}${attr:=}-- pipe file is not created,we wait"
                                sleep 2
                            done
                            gen_check_pin_and_run # crqms00121003
                            pipestring=`cat ${AppPtfDmPipeFile}` 
                            device_key=`echo $pipestring|awk '{print $1}'`
                            md5pass=`echo $pipestring|awk '{print $2}'` 
                           : "${attr}${attr:=}-- device_key is  $device_key md5pass is ${md5pass}"
                    done
                
                    rm -f ${AppPtfDmPipeFile}
                    ## get mac address
                    ##---------------------------------------
                    mac=$(mac)
                    mac=${mac//":"/}

                    ## get authen_url
                    ##---------------------------------------
                    get_authen_url $device_key $md5pass $mac

                    ## send authentication message to DM server
                    ##-----------------------------------------
                    : "${attr}send authentication to DM server${default}"
                    authen_send $authen_url
                    authen_ok=$?
        done

                ## server response [2xx|4xx] besides 401, stop retry authentication
                ##-----------------------------------------------------------
                if [[ $authen_ok -eq $AUTH_FAILED ]]; then
                    echo "authenticated failed, stop retry"
# CRMS00370056
                    ret=$ERR_BADCFG
                    dlretry=$_maxretry 
                    rm /tmp/$downloaddir/$download_file >/dev/null 2>&1
# CRMS00370056 END
                    break
                else
                    echo "authenticated OK, start download config file"
                    ## reset 'dlretry' to avoid the 30s delay
                    dlretry=0
                fi                 
            fi
# PR262041 END           
        done

        ## Post download
        ##---------------
        : "${attr}=============${default}"
        : "${attr}Post download${default}"
        : "${attr}=============${default}"
        if [[ $ret -eq 0 ]]; then
            : "${attr}SUCCESSFULLY DOWNLOAD FILE${default}"
            : "${attr}--------------------------${default}"
# _CTL_INSTALL
            : "${attr}install CTL ?${default}"
            if [[ "$download_proto" == "https" ]] \
               && [[ "$CTL_ACTIVATE_CA_DEPLOYMENT" == "false" ]] \
               && [[ -z "$cmdl_filelist" ]] \
               && [[ $filenumber -eq 1 ]]
            then
                : "${attr}yes${default}"
# CRMS00329694
# CRMS00312748
# CRMS00272826
                install_CTL "/tmp/$downloaddir" "$download_file" 
# CRMS00272826 END
# CRMS00312748 END
# CRMS00329694 END
                [[ $ret -ne 0 ]] && { RETURN $ret; }
            else
                : "${attr}no${default}"
            fi
# _CTL_INSTALL END
            ## compute file checksum
            ##-----------------------
            : "${attr}Calc the checksum${default}"
# CRMS00312748
            ( cd /tmp/$downloaddir; openssl md5 $download_file > .cksum.$download_file ) & wait $!; kill $! 2>/dev/null
            ## compare checksums
            ##-------------------
            : "${attr}Compare the checksums${default}"
            diff /tmp/$downloaddir/.cksum.$download_file /$downloaddir/.cksum.$download_file >/dev/null 2>&1 & wait $!; ret=$?; kill $! 2>/dev/null
            if [[ $ret -eq 0 ]]; then
# CRMS00312748 END
# CRMS00275985
                if [[ $diff -eq 0 ]]; then
                    : "${attr}No difference since 1st file${default}"
                    diff=0
                else
                    : "${attr}previous config file has been changed, forcing the parsing${default}"
                    diff=2
                fi
# CRMS00275985 END
            else
                : "${attr}Files are different${default}"
                diff=1
            fi
            if [ $force -eq 1 ]; then
                : "${attr}Forcing difference${default}"
                diff=1
            fi
# CRMS00275985
            if [ $diff -gt 0 ]; then
# CRMS00275985 END
                ## A new file has been retrieved
                ##-------------------------------
# CRMS00239649
                # on the first file and not in polling thread, do a clean
# CRMS00275985
                if [[ $filenumber -eq 1 ]] && [[ $thread -eq 0 ]] && [[ $diff -eq 1 ]]; then
# CRMS00275985 END
                    : "${attr}Cleaning...${default}"
# CRMS00312748
                     $servicelaunch clean & wait $!; kill $! 2>/dev/null
# CRMS00312748 END
                else
                    : "${attr}No cleaning done${default}"
                fi
# CRMS00239649 END

# CRMS00275985
                case "$diff" in
                    1) : "${attr}Differences due to this file${default}"
# CRMS00276076
                        : "${attr}Remove the checksum and recreate it only if the parsing is ok${default}"
                        rm /$downloaddir/.cksum.$download_file >/dev/null 2>&1
# CRMS00276076 END
                        # Copy it to its final destination
                        : "${attr}Copy the new downloaded file to its final destination${default}"
                        cp -a /tmp/$downloaddir/.cksum.$download_file /$downloaddir/.cksum.$download_file.new
                        cp -a /tmp/$downloaddir/$download_file /$downloaddir/$download_file.new
                        mv /$downloaddir/$download_file.new /$downloaddir/$download_file
                    ;;
                    2) : "${attr}Differences due to earlier configuration file${default}"
                        mv /$downloaddir/.cksum.$download_file /$downloaddir/.cksum.$download_file.new
                    ;;
                esac
# CRMS00275985 END

# CRMS00239649
                ## parse the file
                ##----------------
                : "${attr}Parse the configuration file${default}"
                dowait send_infra --wait settingfile "/$downloaddir/$download_file"
                ret=$?
# CRMS00276076
                if [[ $ret -eq 0 ]]; then
                    : "${attr}Parsing ok, recreate the checksum file.${default}"
# CRMS00296816
                    parsed=1
# CRMS00296816 END
                    mv /$downloaddir/.cksum.$download_file.new /$downloaddir/.cksum.$download_file
                    touch /$downloaddir/.cksum.$download_file /$downloaddir/$download_file
                fi
# CRMS00276076 END
# CRMS00221778
                if [[ -z "${cmdl_filelist}" ]]; then
                    if [[ $ret -ne 0 ]] && [[ $do_xmlparse -eq 1 ]]; then
# CRMS00239649
                        : "${attr}Using private parser for $download_file${default}"
                        echoerror "Could not contact infra (ret: $ret), using private parser"
# CRMS00239649 END
                        ret=$XMLPARSE
# CRMS00239649
                        eval "$($xmlparse /$downloaddir/$download_file all=1 platform=1)"
# CRMS00239649 END
                        cmd=":"
# CRMS00239649
                        for i in $(xmlparse /$downloaddir/$download_file list=1 platform=1|awk '{print $1}'); do
# CRMS00239649 END
                            cmd="$cmd; CLISettings set DM $i \"\$$i\""
                        done
                        : "${attr}cmd=[$cmd]${default}"
                        eval "$cmd"
                    fi
                fi
# CRMS00221778 END
                if [[ $ret -eq 0 ]] || [[ $ret -eq $XMLPARSE ]]; then
# CRMS00228732
                    oldattr="$attr" attr="$esc[42;30m" default="$default"
# CRMS00331041
                    cd $NVDM_ROOT; updateCurrentConfig *.cfg --source=$NVDM_ROOT; cd - >/dev/null 2>&1
# CRMS00331041 END
                    attr="$oldattr" default="$default"
# CRMS00228732 END
                else
                    : "${attr}Error while parsing $download_file${default}"
                fi
# CRMS00239649 END
                if [[ $ret -eq 0 ]] || [[ $do_xmlparse -eq 1 ]]; then
# PR341502 zimingxu+
                    [[ -e "$NVDM_ROOT/enet.cfg" ]] && save_DM "LOCAL" $(awk '/ENETCFG_DM_PROXY/ { printf("%s ", $0) }' "$NVDM_ROOT/enet.cfg" 2>/dev/null)
# PR341502 zimingxu+
                fi
            fi
        elif [[ $ret -ne $ERR_TRAP ]] && [[ $ret -ne $ERR_USR1 ]]; then
            : "${attr}FAILED TO DOWNLOAD FILE${default}"
            : "${attr}-----------------------${default}"
# CRMS00228734
            ## Failed to download a config file
            ##----------------------------------
            if [[ $filenumber -gt 1 ]]; then
                if [[ -f "/$downloaddir/$download_file" ]]; then
# CRMS00276076
                    : "${attr}Remove the checksum and recreate it only if the parsing is ok${default}"
                    rm /$downloaddir/.cksum.$download_file
# CRMS00276076 END
                    ## Parse the local copy
                    ##----------------------
                    : "${attr}Parse local copy of $download_file${default}"
                    dowait send_infra --wait settingfile /$downloaddir/$download_file
                    ret=$?
# CRMS00276076
                    if [[ $ret -eq 0 ]]; then
                        : "${attr}Parsing ok, reacreate the checksum file.${default}"
                        mv /$downloaddir/.cksum.$download_file.new /$downloaddir/.cksum.$download_file
                        touch /$downloaddir/.cksum.$download_file /$downloaddir/$download_file
                    fi
# CRMS00276076 END
                    if [[ -z "${cmdl_filelist}" ]]; then
                        if [[ $ret -ne 0 ]] && [[ $do_xmlparse -eq 1 ]]; then
# CRMS00239649
                            : "${attr}Using private parser for $download_file${default}"
# CRMS00239649 END
                            ret=$XMLPARSE
# CRMS00239649
                            eval "$($xmlparse /$downloaddir/$download_file all=1 platform=1)"
# CRMS00239649 END
                            cmd=":"
# CRMS00239649
                            for i in $(xmlparse /$downloaddir/$download_file list=1 platform=1|awk '{print $1}'); do
# CRMS00239649 END
                                cmd="$cmd; CLISettings set DM $i \"\$$i\""
                            done
                            : "${attr}cmd=[$cmd]${default}"
                            eval "$cmd"
# CRMS00228732
# CRMS00331041
                            cd $NVDM_ROOT; updateCurrentConfig *.cfg --source=$NVDM_ROOT; cd - >/dev/null 2>&1
# CRMS00331041 END
# CRMS00228732 END
                        fi
                    fi
                    if [[ $ret -ne 0 ]]; then
                        : "${attr}Error while parsing $download_file${default}"
# CRMS00228732
                    else
# CRMS00331041
                        cd $NVDM_ROOT; updateCurrentConfig *.cfg --source=$NVDM_ROOT; cd - >/dev/null 2>&1
# CRMS00331041 END
# CRMS00228732 END
                    fi
                else
                    ## THIS SHOULD NEVER HAPPEN !!!
                    ##------------------------------
                    : "${attr}Local copy of $download_file does not exists${default}"
# PR411913 tingh
                    ( attr="$esc[31m"; default="$esc[0m"; display "LOCAL COPY OF $download_file NOT FOUND.\n" )
# PR411913 tingh END
# CRMS00392052 zimingx+
                    $servicelaunch reparse
# CRMS00392052 zimingx-
# PR411913 tingh
                    do_reboot "LOCAL COPY OF $download_file NOT FOUND."
# PR411913 tingh END                
                    RETURN $ERR_NEVER
                fi
            fi
# CRMS00228734 END
            # remember the file for next retry
            if [[ "$option" == "M" ]]; then
                : "${attr}Missing mandatory file${default}"
                if [[ "${MISSING//$download_url$download_file}" == "$MISSING" ]]; then
                    MISSING="${MISSING:+$MISSING, }$download_url$download_file"
                fi
            fi
        else
            break
        fi
    done

    if [[ $ret -ne $ERR_USR1 ]] && [[ $ret -ne $ERR_TRAP ]]; then
# CRMS00296816
        if [[ $parsed -eq 1 ]]; then
# CRMS00288108

# CRMS00335652
# CRMS00329513            
            if [[ "$survival" == "true" ]]; then
                # update current enet.cfg 
                updateSystemConfiguration
                CLISettings set CURRENT ENETCFG_DM_SURVIVABILITY_MODE "false" 
            fi
# CRMS00329513 end
# CRMS00335652 end

            : "${attr}Post parsing script${default}"
            for file in $POSTPARSINGDIR/*; do
# CRMS00312748
                { /bin/sh -e $file >&2 ; } & wait $!
# CRMS00312748 END
            done
# CRMS00288108 END
# CRMS00229474
            : "${attr}Signal the end of config file download and parsing${default}"
# CRMS00312748
            dowait send_infra dm_end_of_parsing >/dev/null 2>&1
# CRMS00312748 END
# CRMS00296547
            ret=$?
            if [[ $ret -eq 1 ]]; then
                : "${attr}A REBOOT HAS BEEN TRIGGERED${default}"
                if [[ $thread -eq 0 ]]; then
                    : "${attr}NOT IN THREAD => INFINITE LOOP${default}"
                    display "Waiting for reboot"
                    gotoInfiniteLoop
                else
                    : "${attr}IN THREAD => DO NOTHING${default}"
                fi
                ret=0
            fi
# CRMS00296547 END
# PR341502 zimingxu+
            [[ -e "$update_defer_flag" ]] && { rm -rf "$update_defer_flag"; $servicelaunch update & }
# PR341502 zimingxu-
# CRMS00229474 END
        fi
# CRMS00296816 END
    fi

    : "${attr}ret: $ret${default}"
    : "${attr}MISSING: $MISSING${default}"
    RETURN $ret
}

enterDmSurvivalMode()
#--------------------
# Entering DmSurvival mode
# INPUT:    $1      reboot reason
# OUPUT:    none
# RETVAL:   0       Success
#           other   A problem occurs
{
    local FUNCTION=enterDmSurvivalMode
    ENTER_FUNCTION
    local reason="$1" ret=0 attr cfg

    ## Get existing config files
    cfg="$(ls $NVDM_ROOT/*.cfg 2>/dev/null)" cfg=${cfg//[^[:graph:]]/ }
    : "${attr}Existing config files: ${cfg}${default}"
    ## Check that at least enet.cfg is in it
# DEMO_MODE
    if [[ "${cfg//enet.cfg}" == "$cfg" ]] && [[ "$DEMO_MODE" != "true" ]]; then
# DEMO_MODE END
        : "${attr}Enet.cfg not found${default}"
        ret=1
    fi
    if [[ $ret -ne 0 ]]; then
        ## Enet.cfg not found, rebooting
# PR341502 zimingxu+
        if [[ $noreboot -eq 0 ]]; then
            echoerror "DM survival mode not available, rebooting..."
# PR341502 zimingxu-
            [[ -z "${reason//[[:blank:]]}" ]] && reason="Can not enter DM survivability"
            do_reboot --step 5 --delay=10 "$reason"
            RETURN $ERR_NEVER
        fi
    else
# INVENTORY_FILE
        CLISettings set CURRENT ENETCFG_DM_SURVIVABILITY_MODE "true" 
# INVENTORY_FILE END
        echoerror "Entering DM survival mode"
        survival=1
    fi
    RETURN $ret
}

#crms00452052 tingh++
treatMissingFilesOutput()
#--------------------
#Remove ${} character from output message
# INPUT:    $1      MISSING  a string contains the missing files
# OUPUT:    MISSING  a string contains the missing files, ${} removed
# RETVAL:   0       Success
#           other   A problem occurs
{
    local FUNCTION=treatMissingFilesOutput                           
    ENTER_FUNCTION                                                   
    local missing_files file_numbers i=1 j file_name ret=0           
                                                                                
    file_numbers=`echo "$MISSING" | awk -F, '{print NF}'`            
    while [[ $i -le $file_numbers ]];do                              
        file_name=`echo $MISSING | awk -F, -v j=$i '{print $j}'`                
        i=`expr $i + 1`                                                         
        file_name=${file_name##*\$\{}                                
        file_name=${file_name%\}*}                                              
        if [ -z $missing_files ];then                                
                missing_files=$file_name                             
                else                                                            
                missing_files=${missing_files}", "${file_name}             
        fi                                                      
    done                                                                   
                                                                
    MISSING="$missing_files"                                    
    RETURN $ret      
}

####################################################################

push cmdline /usr/sbin/dmconfig "$@"
################################
# MAIN
####################################################################
#### Define debug attributes
####=========================
: "${attr}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~${default}"
: "${attr}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~${default}"
: "${attr}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~${default}"

#### Get the config
####================
get_config "$@"
RET=$?

# CRMS00312748
if [[ $polling_restart -eq 0 ]]; then
# CRMS00312748 END
    #### Do the 1st check
    ####==================
    # DEMO_MODE
    if [[ "$DEMO_MODE" == "true" ]]; then
        : "${attr}DEMO MODE, TRY TO DOWNLOAD ONLY ONCE${default}"
        maxdownloadretry=1
    fi
    # DEMO_MODE END
    if [[ $RET -eq 0 ]]; then
# CRMS00239649
        #CRMS00247489
        if [[ ! -f $nocleanflag ]] && [[ -z "${cmdl_filelist}" ]] && [[ ! -f $NVDM_ROOT/enet.cfg ]]; then
            : "${attr}cleaning if at least enet.cfg not found in $NVDM_ROOT and no list given or command line${default}"
# CRMS00392052 zimingx+
            $servicelaunch reparse
# CRMS00392052 zimingx-
        fi
# CRMS00239649 END
        do_xmlparse=1
        download_parse "$maxdownloadretry" "$filelist_template"
        RET=$?
        do_xmlparse=0
    fi

    survivalMsg=""
    msg=""
    # CRMS00278662
    forgetPROXY=0
    # CRMS00278662 END
    case "$RET" in
        $ERR_DNS) : "${attr}DNS ERROR DETECTED !!!${default}"
# CRMS0000244210
            survivalMsg="Could not contact the DNS."
            msg="$survivalMsg"
# CRMS0000244210 END
# CRMS00278662
            # In case of ERR_DNS we need to forget the information in case PROXY is set in the config file with a FQDN and no DNS
            # is available.
            forgetPROXY=1
# CRMS00278662 END
        ;;
# CRMS00263036
        $ERR_NODM) : "${attr}Unable to contact the configured DM/PROXY !!!${default}"
# CRMS0000244210
# PR341502 zimingxu+
            survivalMsg="DM ERROR: No DM/PROXY found. PROPOSAL: check/correct configurations!"
# PR341502 zimingxu-
            msg="$survivalMsg"
# CRMS0000244210 END
# CRMS00278662
            forgetPROXY=1
# CRMS00278662 END
        ;;
# CRMS00263036 END
        $ERR_BADCFG) : "${attr}The saved configuration is bad.${default}"
# CRMS0000244210
# PR341502 zimingxu+
            survivalMsg="DM ERROR: unable to download configuration file. POSSIBLE REASON: bad saved configuration or file not found."
# PR341502 zimingxu-
            msg="$survivalMsg"
# CRMS0000244210 END
            # clear the locally saved info
            save_DM "LOCAL" "ENETCFG_DM_PROTOCOL=" "ENETCFG_DM=" "ENETCFG_DM_PORT=" "ENETCFG_DM_CONFIG_PATH=" \
                            "ENETCFG_DM_BACKUP_PROTOCOL=" "ENETCFG_DM_BACKUP=" "ENETCFG_DM_BACKUP_PORT=" "ENETCFG_DM_BACKUP_CONFIG_PATH=" \
                            "ENETCFG_DM_PROXY_PROTOCOL=" "ENETCFG_DM_PROXY=" "ENETCFG_DM_PROXY_PORT=" "ENETCFG_DM_PROXY_CONFIG_PATH=" \
                            "ENETCFG_DM_PROXY_BACKUP_PROTOCOL=" "ENETCFG_DM_PROXY_BACKUP=" "ENETCFG_DM_PROXY_BACKUP_PORT=" "ENETCFG_DM_PROXY_BACKUP_CONFIG_PATH="
# CRMS00392052 zimingx+
            $servicelaunch reparse
# CRMS00392052 zimingx-
        ;;
# _XML_SURVI
        $XMLPARSE) : "${attr}Private xml parser has been used.${default}"
            ## Should behave as if everything was good
            RET=0
        ;;
# _XML_SURVI END
    esac

    if [[ $forgetPROXY -ne 0 ]]; then
            : "${attr}Cleaning up any stored DM/DM PROXY information${default}"
            save_DM "LOCAL" "ENETCFG_DM_PROTOCOL=" "ENETCFG_DM=" "ENETCFG_DM_PORT=" "ENETCFG_DM_CONFIG_PATH=" \
                            "ENETCFG_DM_BACKUP_PROTOCOL=" "ENETCFG_DM_BACKUP=" "ENETCFG_DM_BACKUP_PORT=" "ENETCFG_DM_BACKUP_CONFIG_PATH=" \
                            "ENETCFG_DM_PROXY_PROTOCOL=" "ENETCFG_DM_PROXY=" "ENETCFG_DM_PROXY_PORT=" "ENETCFG_DM_PROXY_CONFIG_PATH=" \
                            "ENETCFG_DM_PROXY_BACKUP_PROTOCOL=" "ENETCFG_DM_PROXY_BACKUP=" "ENETCFG_DM_PROXY_BACKUP_PORT=" "ENETCFG_DM_PROXY_BACKUP_CONFIG_PATH="
    fi
# CRMS00278662
    unset forgetPROXY
# CRMS00278662 END

    if [[ -n "$msg" ]]; then
        echoerror "$msg"
# CRMS00312748
        displaymsg "$msg" & wait $!
        displaypopup "$msg" & wait $!
# CRMS00312748 END
    fi
    if [[ -n "$MISSING" ]]; then
        : "${attr}There are missing files.${default}"
        msg="Could not retrieve the following file"
        #treatMissingFilesOutput
        if [[ "${MISSING%, *}" != "${MISSING}" ]]; then
            # Several files, update missing and msg to manage several files
            MISSING="${MISSING%, *} and${MISSING##*,}"
            msg="${msg}s"
        fi
        msg="$msg: $MISSING"$'\n'
        echoerror "$msg"
# CRMS00312748
        displaymsg "$msg" & wait $!
        displaypopup "$msg" & wait $!
# CRMS00312748 END
    fi

    if [[ $RET -ne 0 ]]; then
# CRMS0000244210
        enterDmSurvivalMode "${survivalMsg:-Error while downloading configuration files}"
# CRMS0000244210 END
        RET=$?
    fi

    #### Do not continue on error
    ####==========================
    [[ $RET -ne 0 ]] && exit $RET

    if [[ $survival -eq 0 ]]; then
        # NOT IN SURVIVAL MODE
        #### Update system configuration
        ####=============================
        : "${attr}update enet.cfg${default}"
        # update current enet.cfg.cfg
# CRMS00335652
        updateSystemConfiguration
# # CRMS00335652 END
    fi
# CRMS00312748
fi
# CRMS00312748 END

#### Start the polling thread
####==========================
# CRMS0029266
if [[ ${nopoll:-0} -eq 0 ]] ; then
# CRMS00292666 END
# CRMS00312748
    read 2>/dev/null <$pidfile pid
    if [[ ! -d /proc/$pid ]] || [[ "$pid" == "$PID" ]]; then
        # No polling thread is running, start it
        : "${attr}starting polling thread${default}"
        set_debug_off
        { polling_thread_main 0<&- 1>&- 2>&- & echo "$!" > $pidfile; } 0<&- 1>&- 2>&- &
        [[ -n "$xtrace" ]] && set_debug_on
        while read 2>/dev/null <$pidfile pid && [[ "$pid" == "$PID" ]]; do nopoll=$((nopoll+1)); done
        echolog "$PID" "polling thread $pid started."
    else
        echoerror "Polling thread already running ($pid)"
    fi
fi
# CRMS00312748 END

exit $RET
####################################################################
# vim:ts=8:sw=4:expandtab:nocin:foldenable:fdm=marker:fmr=@BEGIN\ FOLD@,@END\ FOLD@
