1#!/bin/sh 2 3# Created on April 13, 2012 4# 5# Copyright (c) 2012, NETGEAR, Inc. 6# 350 East Plumeria, San Jose California, 95134, U.S.A. 7# All rights reserved. 8# 9# This software is the confidential and proprietary information of 10# NETGEAR, Inc. ("Confidential Information"). You shall not 11# disclose such Confidential Information and shall use it only in 12# accordance with the terms of the license agreement you entered into 13# with NETGEAR. 14 15# cp_installer for all devices 16# 17# usage: 18# cp_installer <server-url> <cp-install-dir> <path-to-eco.env> <certificate> 19# e.g. 20# ./cp_installer.sh http://updates.netgear.com/ecosystem/pkg-repo . . 21# ./cp_installer.sh https://updates.netgear.com/ecosystem/pkg-repo /media/nand . 22# ./cp_installer.sh https://updates.netgear.com/ecosystem/pkg-repo /media/nand . /etc/ca/CAs.txt 23# ./cp_installer.sh updates.netgear.com/ecosystem/pkg-repo /media/nand 24# 25# 26# This script file installs the Control Point package as 27# <cp-install-dir>/cp.d 28 29REPO_URL=${1} 30LOCAL_DIR=${2} 31CP_INSTALL_DIR=${LOCAL_DIR}/cp.d 32 33PATH_ECO_ENV=${3} 34if [ -z ${PATH_ECO_ENV} ] || [ ${PATH_ECO_ENV} = "." ]; then 35 PATH_ECO_ENV=$PWD 36else 37 # Check if PATH_ECO_ENV is an absolute path, get the first char 38 ABSOLUTE_PATH=`echo "${PATH_ECO_ENV}" | cut -c1` 39 if [ "${ABSOLUTE_PATH}" != "/" ]; then 40 PATH_ECO_ENV=${PWD}/${PATH_ECO_ENV} 41 fi 42fi 43 44CA_FILE=${4} 45HTTPS_FLAGS="" 46 47#. ./cp.d/cpinst/cp_dbg.sh 48cp_timing_debug() { 49 if [ -n "${TIMING_DEBUG}" ] && [ ${TIMING_DEBUG} -eq 1 ]; then 50 CURR_TIME=`uptime | cut -d " " -f2` 51 echo " ___ ${CURR_TIME} ___ ${1}" 52 fi 53 return 0 54} 55 56ENV_EXISTS=0 # eco.env file exists: 0=no, 1=yes 57# source the env file, if it's in the same directory 58# otherwise the caller must do it before calling this script 59if [ -r ${PATH_ECO_ENV}/eco.env ]; then 60 echo "sourcing ${PATH_ECO_ENV}/eco.env ..." 61 . ${PATH_ECO_ENV}/eco.env 62 ENV_EXISTS=1 63fi 64 65if [ "X${DEVICE_MODEL_NAME}" = "X" ]; then 66 echo "eco env var DEVICE_MODEL_NAME not defined. exiting ${0}" 67 exit 1 68fi 69echo "DEVICE_MODEL_NAME is $DEVICE_MODEL_NAME" 70TARGET_ID=${DEVICE_MODEL_NAME} 71 72if [ "X${FIRMWARE_VERSION}" = "X" ]; then 73 echo " -- eco env var FIRMWARE_VERSION not defined. exiting ${0}" 74 exit 1 75fi 76 77 78# wait_mount_nand() 79# wait for the nand partition $APPS_MOUNT_POINT 80# to be mounted in the system. 81# The environment variable APPS_MOUNT_POINT must be 82# defined and exported before this script is called. 83 84wait_mount_nand() 85{ 86 OUTFILE=/tmp/mtab.txt 87 MTABLE=/proc/mounts 88 NAND=$APPS_MOUNT_POINT 89 90 if [ "X${NAND}" = "X" ]; then 91 echo " -- eco env var APPS_MOUNT_POINT not defined. exiting ${0}" 92 exit 1 93 fi 94 95 echo "APPS_MOUNT_POINT is $NAND" 96 97 # let's put 60 seconds timeout 98 count=60 99 100 while [ $count -ne 0 ] ; 101 do 102 # dump mtab to file for pipe 103 awk '{ print $2 }' $MTABLE > $OUTFILE 104 105 while read MOUNT 106 do 107 if [ "$MOUNT" = "$NAND" ] 108 then 109 echo "$NAND mounted ok." 110 /bin/rm $OUTFILE 111 return 0 112 fi 113 done < $OUTFILE 114 sleep 1 115 echo "wait_mount, retry" 116 count=`expr $count - 1` 117 done 118 119 echo " -- ${0} timedout" 120 return 1 121} 122 123echo " -- ${0}, `uptime`" 124if [ -z ${INITIAL_WAIT} ]; then 125 if [ ${ENV_EXISTS} -eq 0 ]; then 126 # eco.env file does not exist, do not sleep 127 INITIAL_WAIT=0 128 else 129 INITIAL_WAIT=75 130 fi 131fi 132echo " -- ${0}, sleep INITIAL_WAIT=${INITIAL_WAIT} seconds" 133sleep ${INITIAL_WAIT} 134wait_mount_nand 135echo " -- ${0}, `uptime`" 136 137RESULT=${?} 138if [ ${RESULT} -ne 0 ]; then 139 echo " -- wait_mount_nand failed ... exiting ${0}" 140 exit ${RESULT} 141fi 142 143normalized_string="" 144normalize_version() 145{ 146 NUMSIZE=5 147 substring="" 148 normalized_string="" 149 150 startnum=-1 151 chars=`echo ${1} | awk -v ORS="" '{ gsub(/./,"&\n") ; print }'` 152 for char in $chars; do 153 case $char in 154 "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "0") 155 substring="${substring}${char}" 156 ;; 157 *) 158 if [ ${#substring} -gt 0 ]; then 159 pack_accum=${#substring} 160 while [ ${pack_accum} -lt ${NUMSIZE} ]; do 161 #pack_accum=$((${pack_accum}+1)) 162 pack_accum=`expr ${pack_accum} + 1` 163 normalized_string="${normalized_string}0" 164 done 165 normalized_string="${normalized_string}${substring}" 166 substring="" 167 fi 168 normalized_string="${normalized_string}${char}" 169 ;; 170 esac 171 done 172 173 if [ ${#substring} -gt 0 ]; then 174 pack_accum=${#substring} 175 while [ ${pack_accum} -lt ${NUMSIZE} ]; do 176 #pack_accum=$((${pack_accum}+1)) 177 pack_accum=`expr ${pack_accum} + 1` 178 normalized_string="${normalized_string}0" 179 done 180 normalized_string="${normalized_string}${substring}" 181 fi 182} 183 184 185# determine the best fit upgrade version 186UPDATE_FIRMWARE_VERSION="" 187TEMP_FILE=/tmp/tmp_pkglists 188 189 190get_https_flags() 191{ 192 # get the URL scheme (http or https) 193 SCHEME=`echo ${REPO_URL} | cut -d ':' -f1` 194 # if no scheme in the URL, prepend "https://" 195 if [ "${SCHEME}" != "http" ] && [ "${SCHEME}" != "https" ]; then 196 REPO_URL="https://${REPO_URL}" 197 SCHEME=https 198 fi 199 if [ "${SCHEME}" != "http" ]; then 200 if [ "${CA_FILE}" != "" ]; then 201 CERTIFICATE=${CA_FILE} 202 if [ "${CERTIFICATE}" = "" ]; then 203 CERTIFICATE=/etc/ca/CAs.txt 204 fi 205 fi 206 HTTPS_FLAGS="--secure-protocol=auto --ca-certificate=${CERTIFICATE}" 207 fi 208} 209 210 211check_update_server() 212{ 213 # each ping = sleep 10 sec (if internet is down), or 214 # = default deadline 20 sec + sleep 10 sec 215 # max no. of pings = 15 216 # max ping time = 150 sec (internet down), or 217 # = 450 sec (internet up) 218 # max wait time = initial wait (75 sec) + total ping 219 # = 225 sec (internet down), or 220 # = 525 sec (internet up) 221 SLEEP_TIME=10 222 ping_count=15 223 224 SERVER_NAME=`echo ${REPO_URL} | cut -d "/" -f3` 225 echo " -- checking server ${SERVER_NAME}" 226 while [ ${ping_count} -ne 0 ] ; 227 do 228 PING_STAT=`((ping -c1 updates.netgear.com) > /dev/null 2>&1) && echo "up" || echo "down"` 229 if [ ${PING_STAT} = "up" ]; then 230 return 0 231 fi 232 ping_count=`expr $ping_count - 1` 233 sleep $SLEEP_TIME 234 echo -n "#" 235 done 236 237 # Server is not reachable. 238 echo " -- Unable to ping server ${SERVER_NAME}" 239 return 1 240} 241 242 243validate_cp_pkg() 244{ 245 PACKAGE_DB=${CP_INSTALL_DIR}/"pkgdb" 246 PKG_LIST=${PACKAGE_DB}/"pkg_list" 247 248 if [ ! -f ${PKG_LIST} ]; then 249 echo " -- ${PKG_LIST} not found" 250 return 1 251 fi 252 # iterate through the packages in the pkg_list file 253 while read line; do 254 PKG_NAME=`echo ${line} | cut -d " " -f1` 255 PKG_STATE_FILE=${PACKAGE_DB}/${PKG_NAME}/"state" 256 if [ ! -f ${PKG_STATE_FILE} ]; then 257 echo " -- ${PKG_STATE_FILE} not found" 258 return 1 259 fi 260 PKG_STATE=`cat ${PKG_STATE_FILE}` 261 echo " -- ${PKG_STATE_FILE} = ${PKG_STATE}" 262 if [ ${PKG_STATE} != "validated" ]; then 263 return 1 264 fi 265 done < ${PKG_LIST} 266 # All packages validated OK 267 return 0 268} 269 270 271get_update_version() 272{ 273 check_update_server 274 # result: 0=up / 1=down 275 SERVER_STAT=${?} 276 CP_VALIDATE_RESULT=0 277 278 DONE=0 279 while [ $DONE -eq 0 ]; do 280 if [ -f ${TEMP_FILE} ]; then 281 rm -f ${TEMP_FILE} 282 fi 283 284 cp_timing_debug "${0} get_update_version wget ### > > >" 285 wget -4 ${HTTPS_FLAGS} ${REPO_URL}/${TARGET_ID} -T 30 --tries=1 -O ${TEMP_FILE} 286 cp_timing_debug "get_update_version wget < < < ###" 287 RESULT=${?} 288 if [ ${RESULT} -ne 0 ]; then 289 # If CP was downloaded before, but the server is down, 290 # then validate the existing CP package. 291 # The validation will need to be run once. 292 if [ -d ${CP_INSTALL_DIR}/cpinst ] && [ ${SERVER_STAT} -eq 1 ]; then 293 if [ ${CP_VALIDATE_RESULT} -eq 0 ]; then 294 validate_cp_pkg 295 CP_VALIDATE_RESULT=${?} 296 # result: 0=validated / 1=not 297 fi 298 if [ ${CP_VALIDATE_RESULT} -eq 0 ]; then 299 echo " -- update server offline, but a cp is present!" 300 return 1 301 fi 302 fi 303 echo " -- Unable to connect to package server. ... retrying in 1 minute ${0}" 304 sleep 60 305 else 306 DONE=1 307 fi 308 done 309 310 # always update cpinst if can contact the update server 311 if [ -d ./cpinst ]; then 312 rm -rf ./cpinst 313 fi 314 315 # get a normalized version of the firmware version 316 normalize_version ${FIRMWARE_VERSION} 317 normalized_firmware_version=${normalized_string} 318 normalized_update_version="" 319 320 for repo_dir in `grep "pkg_cont-" $TEMP_FILE | sed -e 's/.*href=\"//' -e 's/\/\">.*$//'`; do 321 # extract version 322 repo_version=`echo ${repo_dir} | sed -e 's/.*pkg_cont\-//'` 323 normalize_version ${repo_version} 324 normalized_repo_version=${normalized_string} 325 326 normalize_version `echo ${repo_version} | sed 's/-[^-]*$//'` 327 min_target_version=${normalized_string} 328 if [ ! "${min_target_version}" \> "${normalized_firmware_version}" ]; then 329 if [ -z "${UPDATE_FIRMWARE_VERSION}" -o ! "${normalized_repo_version}" \< "${normalized_update_version}" ]; then 330 UPDATE_FIRMWARE_VERSION=${repo_version} 331 normalized_update_version=${normalized_repo_version} 332 fi 333 fi 334 done 335 336 # clean up the temp file 337 if [ -f ${TEMP_FILE} ]; then 338 rm -f ${TEMP_FILE} 339 fi 340 341 echo "INSTALLED_FIRMWARE_VERSION = \"${FIRMWARE_VERSION}\"" 342 if [ -z "${UPDATE_FIRMWARE_VERSION}" ]; then 343 echo "no corresponding version, exiting ... !" 344 exit 1 345 fi 346 echo "UPDATE_FIRMWARE_VERSION = \"${UPDATE_FIRMWARE_VERSION}\"" 347 348 return 0 349} 350 351 352install_cpinst() 353{ 354 get_https_flags 355 get_update_version 356 RESULT=${?} 357 if [ $RESULT -ne 0 ]; then 358 echo " -- revert to installed cpinst!" 359 return 0 360 fi 361 362 # fetch the cp startup scripts from the repository 363 DONE=0 364 while [ $DONE -eq 0 ]; do 365 # delete partially downloaded file just in case 366 rm -f /tmp/cpinst.tar.gz 367 368 cp_timing_debug "${0} install_cpinst wget === > > >" 369 wget -4 ${HTTPS_FLAGS} ${REPO_URL}/${TARGET_ID}/pkg_cont-${UPDATE_FIRMWARE_VERSION}/packages/cpinst.tar.gz -O /tmp/cpinst.tar.gz 370 cp_timing_debug "install_cpinst wget < < < ===" 371 RESULT=${?} 372 if [ ${RESULT} -ne 0 ]; then 373 echo " -- Unable to connect to package server. ... retrying in 1 minute ${0}" 374 sleep 60 375 else 376 DONE=1 377 fi 378 done 379 380 tar -zxf /tmp/cpinst.tar.gz 381 rm -rf ./META-INF 382 rm -rf /tmp/cpinst.tar.gz 383} 384 385# call the core startup script 386if [ -d ${LOCAL_DIR} ]; then 387 if [ ! -d ${CP_INSTALL_DIR} ]; then 388 mkdir ${CP_INSTALL_DIR} 389 fi 390 cd ${CP_INSTALL_DIR} 391 392 install_cpinst 393 394 export HTTPS_FLAGS 395 396 if [ -x ./cpinst/cp_startup.sh ]; then 397 ./cpinst/cp_startup.sh ${TARGET_ID} ${FIRMWARE_VERSION} ${REPO_URL} ${PATH_ECO_ENV} 398 else 399 echo " -- startup script doesn't exist ... exiting ${0}" 400 exit 1 401 fi 402fi 403 404exit 0 405 406