1*276da39aSCy Schubert#!/bin/bash 2*276da39aSCy Schubert 3*276da39aSCy Schubert# Copyright (C) 2014 Timothe Litt litt at acm dot org 4*276da39aSCy Schubert 5*276da39aSCy Schubert# This script may be freely copied, used and modified providing that 6*276da39aSCy Schubert# this notice and the copyright statement are included in all copies 7*276da39aSCy Schubert# and derivative works. No warranty is offered, and use is entirely at 8*276da39aSCy Schubert# your own risk. Bugfixes and improvements would be appreciated by the 9*276da39aSCy Schubert# author. 10*276da39aSCy Schubert 11*276da39aSCy SchubertVERSION="1.003" 12*276da39aSCy Schubert 13*276da39aSCy Schubert# leap-seconds file manager/updater 14*276da39aSCy Schubert 15*276da39aSCy Schubert# Depends on: 16*276da39aSCy Schubert# wget sed, tr, shasum, logger 17*276da39aSCy Schubert 18*276da39aSCy Schubert# ########## Default configuration ########## 19*276da39aSCy Schubert# 20*276da39aSCy Schubert# Where to get the file 21*276da39aSCy SchubertLEAPSRC="ftp://time.nist.gov/pub/leap-seconds.list" 22*276da39aSCy Schubert 23*276da39aSCy Schubert# How many times to try to download new file 24*276da39aSCy SchubertMAXTRIES=6 25*276da39aSCy SchubertINTERVAL=10 26*276da39aSCy Schubert 27*276da39aSCy Schubert# Where to find ntp config file 28*276da39aSCy SchubertNTPCONF=/etc/ntp.conf 29*276da39aSCy Schubert 30*276da39aSCy Schubert# How long before expiration to get updated file 31*276da39aSCy SchubertPREFETCH="60 days" 32*276da39aSCy Schubert 33*276da39aSCy Schubert# How to restart NTP - older NTP: service ntpd? try-restart | condrestart 34*276da39aSCy Schubert# Recent NTP checks for new file daily, so there's nothing to do 35*276da39aSCy SchubertRESTART= 36*276da39aSCy Schubert 37*276da39aSCy Schubert# Where to put temporary copy before it's validated 38*276da39aSCy SchubertTMPFILE="/tmp/leap-seconds.$$.tmp" 39*276da39aSCy Schubert 40*276da39aSCy Schubert# Syslog facility 41*276da39aSCy SchubertLOGFAC=daemon 42*276da39aSCy Schubert# ########################################### 43*276da39aSCy Schubert 44*276da39aSCy Schubert# Places to look for commands. Allows for CRON having path to 45*276da39aSCy Schubert# old utilities on embedded systems 46*276da39aSCy Schubert 47*276da39aSCy SchubertPATHLIST="/opt/sbin:/opt/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:" 48*276da39aSCy Schubert 49*276da39aSCy SchubertREQUIREDCMDS=" wget logger tr sed shasum" 50*276da39aSCy Schubert 51*276da39aSCy SchubertSELF="`basename $0`" 52*276da39aSCy Schubert 53*276da39aSCy Schubertfunction displayHelp { 54*276da39aSCy Schubert cat <<EOF 55*276da39aSCy SchubertUsage: $SELF [options] [leapfile] 56*276da39aSCy Schubert 57*276da39aSCy SchubertVerifies and if necessary, updates leap-second definition file 58*276da39aSCy Schubert 59*276da39aSCy SchubertAll arguments are optional: Default (or current value) shown: 60*276da39aSCy Schubert -s Specify the URL of the master copy to download 61*276da39aSCy Schubert $LEAPSRC 62*276da39aSCy Schubert -4 Use only IPv4 63*276da39aSCy Schubert -6 Use only IPv6 64*276da39aSCy Schubert -p 4|6 65*276da39aSCy Schubert Prefer IPv4 or IPv6 (as specified) addresses, but use either 66*276da39aSCy Schubert -d Specify the filename on the local system 67*276da39aSCy Schubert $LEAPFILE 68*276da39aSCy Schubert -e Specify how long before expiration the file is to be refreshed 69*276da39aSCy Schubert Units are required, e.g. "-e 60 days" Note that larger values 70*276da39aSCy Schubert imply more frequent refreshes. 71*276da39aSCy Schubert "$PREFETCH" 72*276da39aSCy Schubert -f Specify location of ntp.conf (used to make sure leapfile directive is 73*276da39aSCy Schubert present and to default leapfile) 74*276da39aSCy Schubert $NTPCONF 75*276da39aSCy Schubert -F Force update even if current file is OK and not close to expiring. 76*276da39aSCy Schubert -c Command to restart NTP after installing a new file 77*276da39aSCy Schubert <none> - ntpd checks file daily 78*276da39aSCy Schubert -r Specify number of times to retry on get failure 79*276da39aSCy Schubert $MAXTRIES 80*276da39aSCy Schubert -i Specify number of minutes between retries 81*276da39aSCy Schubert $INTERVAL 82*276da39aSCy Schubert -l Use syslog for output (Implied if CRONJOB is set) 83*276da39aSCy Schubert -L Don't use syslog for output 84*276da39aSCy Schubert -P Specify the syslog facility for logging 85*276da39aSCy Schubert $LOGFAC 86*276da39aSCy Schubert -t Name of temporary file used in validation 87*276da39aSCy Schubert $TMPFILE 88*276da39aSCy Schubert -q Only report errors to stdout 89*276da39aSCy Schubert -v Verbose output 90*276da39aSCy Schubert -z Specify path for utilities 91*276da39aSCy Schubert $PATHLIST 92*276da39aSCy Schubert -Z Only use system path 93*276da39aSCy Schubert 94*276da39aSCy Schubert$SELF will validate the file currently on the local system 95*276da39aSCy Schubert 96*276da39aSCy SchubertOrdinarily, the file is found using the "leapfile" directive in $NTPCONF. 97*276da39aSCy SchubertHowever, an alternate location can be specified on the command line. 98*276da39aSCy Schubert 99*276da39aSCy SchubertIf the file does not exist, is not valid, has expired, or is expiring soon, 100*276da39aSCy Schuberta new copy will be downloaded. If the new copy validates, it is installed and 101*276da39aSCy SchubertNTP is (optionally) restarted. 102*276da39aSCy Schubert 103*276da39aSCy SchubertIf the current file is acceptable, no download or restart occurs. 104*276da39aSCy Schubert 105*276da39aSCy Schubert-c can also be used to invoke another script to perform administrative 106*276da39aSCy Schubertfunctions, e.g. to copy the file to other local systems. 107*276da39aSCy Schubert 108*276da39aSCy SchubertThis can be run as a cron job. As the file is rarely updated, and leap 109*276da39aSCy Schubertseconds are announced at least one month in advance (usually longer), it 110*276da39aSCy Schubertneed not be run more frequently than about once every three weeks. 111*276da39aSCy Schubert 112*276da39aSCy SchubertFor cron-friendly behavior, define CRONJOB=1 in the crontab. 113*276da39aSCy Schubert 114*276da39aSCy SchubertThis script depends on$REQUIREDCMDS 115*276da39aSCy Schubert 116*276da39aSCy SchubertVersion $VERSION 117*276da39aSCy SchubertEOF 118*276da39aSCy Schubert return 0 119*276da39aSCy Schubert} 120*276da39aSCy Schubert 121*276da39aSCy Schubert# Default: Use syslog for logging if running under cron 122*276da39aSCy Schubert 123*276da39aSCy SchubertSYSLOG="$CRONJOB" 124*276da39aSCy Schubert 125*276da39aSCy Schubertif [ "$1" = "--help" ]; then 126*276da39aSCy Schubert displayHelp 127*276da39aSCy Schubert exit 0 128*276da39aSCy Schubertfi 129*276da39aSCy Schubert 130*276da39aSCy Schubert# Parse options 131*276da39aSCy Schubert 132*276da39aSCy Schubertwhile getopts 46p:P:s:e:f:Fc:r:i:lLt:hqvz:Z opt; do 133*276da39aSCy Schubert case $opt in 134*276da39aSCy Schubert 4) 135*276da39aSCy Schubert PROTO="-4" 136*276da39aSCy Schubert ;; 137*276da39aSCy Schubert 6) 138*276da39aSCy Schubert PROTO="-6" 139*276da39aSCy Schubert ;; 140*276da39aSCy Schubert p) 141*276da39aSCy Schubert if [ "$OPTARG" = '4' -o "$OPTARG" = '6' ]; then 142*276da39aSCy Schubert PREFER="--prefer-family=IPv$OPTARG" 143*276da39aSCy Schubert else 144*276da39aSCy Schubert echo "Invalid -p $OPTARG" >&2 145*276da39aSCy Schubert exit 1; 146*276da39aSCy Schubert fi 147*276da39aSCy Schubert ;; 148*276da39aSCy Schubert P) 149*276da39aSCy Schubert LOGFAC="$OPTARG" 150*276da39aSCy Schubert ;; 151*276da39aSCy Schubert s) 152*276da39aSCy Schubert LEAPSRC="$OPTARG" 153*276da39aSCy Schubert ;; 154*276da39aSCy Schubert e) 155*276da39aSCy Schubert PREFETCH="$OPTARG" 156*276da39aSCy Schubert ;; 157*276da39aSCy Schubert f) 158*276da39aSCy Schubert NTPCONF="$OPTARG" 159*276da39aSCy Schubert ;; 160*276da39aSCy Schubert F) 161*276da39aSCy Schubert FORCE="Y" 162*276da39aSCy Schubert ;; 163*276da39aSCy Schubert c) 164*276da39aSCy Schubert RESTART="$OPTARG" 165*276da39aSCy Schubert ;; 166*276da39aSCy Schubert r) 167*276da39aSCy Schubert MAXTRIES="$OPTARG" 168*276da39aSCy Schubert ;; 169*276da39aSCy Schubert i) 170*276da39aSCy Schubert INTERVAL="$OPTARG" 171*276da39aSCy Schubert ;; 172*276da39aSCy Schubert t) 173*276da39aSCy Schubert TMPFILE="$OPTARG" 174*276da39aSCy Schubert ;; 175*276da39aSCy Schubert l) 176*276da39aSCy Schubert SYSLOG="y" 177*276da39aSCy Schubert ;; 178*276da39aSCy Schubert L) 179*276da39aSCy Schubert SYSLOG= 180*276da39aSCy Schubert ;; 181*276da39aSCy Schubert h) 182*276da39aSCy Schubert displayHelp 183*276da39aSCy Schubert exit 0 184*276da39aSCy Schubert ;; 185*276da39aSCy Schubert q) 186*276da39aSCy Schubert QUIET="Y" 187*276da39aSCy Schubert ;; 188*276da39aSCy Schubert v) 189*276da39aSCy Schubert VERBOSE="Y" 190*276da39aSCy Schubert ;; 191*276da39aSCy Schubert z) 192*276da39aSCy Schubert PATHLIST="$OPTARG:" 193*276da39aSCy Schubert ;; 194*276da39aSCy Schubert Z) 195*276da39aSCy Schubert PATHLIST= 196*276da39aSCy Schubert ;; 197*276da39aSCy Schubert *) 198*276da39aSCy Schubert echo "$SELF -h for usage" >&2 199*276da39aSCy Schubert exit 1 200*276da39aSCy Schubert ;; 201*276da39aSCy Schubert esac 202*276da39aSCy Schubertdone 203*276da39aSCy Schubertshift $((OPTIND-1)) 204*276da39aSCy Schubert 205*276da39aSCy Schubertexport PATH="$PATHLIST$PATH" 206*276da39aSCy Schubert 207*276da39aSCy Schubert# Add to path to deal with embedded systems 208*276da39aSCy Schubert# 209*276da39aSCy Schubertfor P in $REQUIREDCMDS ; do 210*276da39aSCy Schubert if >/dev/null 2>&1 which "$P" ; then 211*276da39aSCy Schubert continue 212*276da39aSCy Schubert fi 213*276da39aSCy Schubert [ "$P" = "logger" ] && continue 214*276da39aSCy Schubert echo "FATAL: missing $P command, please install" 215*276da39aSCy Schubert exit 1 216*276da39aSCy Schubertdone 217*276da39aSCy Schubert 218*276da39aSCy Schubert# Handle logging 219*276da39aSCy Schubert 220*276da39aSCy Schubertif ! LOGGER="`2>/dev/null which logger`" ; then 221*276da39aSCy Schubert LOGGER= 222*276da39aSCy Schubertfi 223*276da39aSCy Schubert 224*276da39aSCy Schubertfunction log { 225*276da39aSCy Schubert # "priority" "message" 226*276da39aSCy Schubert # 227*276da39aSCy Schubert # Stdout unless syslog specified or logger isn't available 228*276da39aSCy Schubert # 229*276da39aSCy Schubert if [ -z "$SYSLOG" -o -z "$LOGGER" ]; then 230*276da39aSCy Schubert if [ -n "$QUIET" -a \( "$1" = "info" -o "$1" = "notice" -o "$1" = "debug" \) ]; then 231*276da39aSCy Schubert return 0 232*276da39aSCy Schubert fi 233*276da39aSCy Schubert echo "`echo \"$1\" | tr a-z A-Z`: $2" 234*276da39aSCy Schubert return 0 235*276da39aSCy Schubert fi 236*276da39aSCy Schubert 237*276da39aSCy Schubert # Also log to stdout if cron job && notice or higher 238*276da39aSCy Schubert local S 239*276da39aSCy Schubert if [ -n "$CRONJOB" -a \( "$1" != "info" \) -a \( "$1" != "debug" \) ] || [ -n "$VERBOSE" ]; then 240*276da39aSCy Schubert S="-s" 241*276da39aSCy Schubert fi 242*276da39aSCy Schubert $LOGGER $S -t "$SELF[$$]" -p "$LOGFAC.$1" "$2" 243*276da39aSCy Schubert} 244*276da39aSCy Schubert 245*276da39aSCy Schubert# Verify interval 246*276da39aSCy SchubertINTERVAL=$(( $INTERVAL *1 )) 247*276da39aSCy Schubert 248*276da39aSCy Schubert# Validate a leap-seconds file checksum 249*276da39aSCy Schubert# 250*276da39aSCy Schubert# File format: (full description in files) 251*276da39aSCy Schubert# # marks comments, except: 252*276da39aSCy Schubert# #$ number : the NTP date of the last update 253*276da39aSCy Schubert# #@ number : the NTP date that the file expires 254*276da39aSCy Schubert# Date (seconds since 1900) leaps : leaps is the # of seconds to add for times >= Date 255*276da39aSCy Schubert# Date lines have comments. 256*276da39aSCy Schubert# #h hex hex hex hex hex is the SHA-1 checksum of the data & dates, excluding whitespace w/o leading zeroes 257*276da39aSCy Schubert 258*276da39aSCy Schubertfunction verifySHA { 259*276da39aSCy Schubert 260*276da39aSCy Schubert if [ ! -f "$1" ]; then 261*276da39aSCy Schubert return 1 262*276da39aSCy Schubert fi 263*276da39aSCy Schubert 264*276da39aSCy Schubert # Remove comments, except those that are markers for last update, expires and hash 265*276da39aSCy Schubert 266*276da39aSCy Schubert local RAW="`sed $1 -e'/^\\([0-9]\\|#[\$@h]\)/!d' -e'/^#[\$@h]/!s/#.*\$//g'`" 267*276da39aSCy Schubert 268*276da39aSCy Schubert # Extract just the data, removing all whitespace 269*276da39aSCy Schubert 270*276da39aSCy Schubert local DATA="`echo \"$RAW\" | sed -e'/^#h/d' -e's/^#[\$@]//g' | tr -d '[:space:]'`" 271*276da39aSCy Schubert 272*276da39aSCy Schubert # Compute the SHA hash of the data, removing the marker and filename 273*276da39aSCy Schubert # Computed in binary mode, which shouldn't matter since whitespace has been removed 274*276da39aSCy Schubert # shasum comes in several flavors; a portable one is available in Perl (with Digest::SHA) 275*276da39aSCy Schubert 276*276da39aSCy Schubert local DSHA="`echo -n \"$DATA\" | shasum | sed -e's/[? *].*$//'`" 277*276da39aSCy Schubert 278*276da39aSCy Schubert # Extract the file's hash. Restore any leading zeroes in hash segments. 279*276da39aSCy Schubert 280*276da39aSCy Schubert # The sed [] includes a tab (\t) and space; #h is followed by a tab and space 281*276da39aSCy Schubert local FSHA="`echo \"$RAW\" | sed -e'/^#h/!d' -e's/^#h//' -e's/[ ] */ 0x/g'`" 282*276da39aSCy Schubert FSHA=`printf '%08x%08x%08x%08x%08x' $FSHA` 283*276da39aSCy Schubert 284*276da39aSCy Schubert if [ -n "$FSHA" -a \( "$FSHA" = "$DSHA" \) ]; then 285*276da39aSCy Schubert if [ -n "$2" ]; then 286*276da39aSCy Schubert log "info" "Checksum of $1 validated" 287*276da39aSCy Schubert fi 288*276da39aSCy Schubert else 289*276da39aSCy Schubert log "error" "Checksum of $1 is invalid:" 290*276da39aSCy Schubert [ -z "$FSHA" ] && FSHA="(no checksum record found in file)" 291*276da39aSCy Schubert log "error" "EXPECTED: $FSHA" 292*276da39aSCy Schubert log "error" "COMPUTED: $DSHA" 293*276da39aSCy Schubert return 1 294*276da39aSCy Schubert fi 295*276da39aSCy Schubert 296*276da39aSCy Schubert # Check the expiration date, converting NTP epoch to Unix epoch used by date 297*276da39aSCy Schubert 298*276da39aSCy Schubert EXPIRES="`echo \"$RAW\" | sed -e'/^#@/!d' -e's/^#@//' | tr -d '[:space:]'`" 299*276da39aSCy Schubert EXPIRES="$(($EXPIRES - 2208988800 ))" 300*276da39aSCy Schubert 301*276da39aSCy Schubert if [ $EXPIRES -lt `date -u +%s` ]; then 302*276da39aSCy Schubert log "notice" "File expired on `date -u -d \"Jan 1, 1970 00:00:00 +0000 + $EXPIRES seconds\"`" 303*276da39aSCy Schubert return 2 304*276da39aSCy Schubert fi 305*276da39aSCy Schubert 306*276da39aSCy Schubert} 307*276da39aSCy Schubert 308*276da39aSCy Schubert# Verify ntp.conf 309*276da39aSCy Schubert 310*276da39aSCy Schubertif ! [ -f "$NTPCONF" ]; then 311*276da39aSCy Schubert log "critical" "Missing ntp configuration $NTPCONF" 312*276da39aSCy Schubert exit 1 313*276da39aSCy Schubertfi 314*276da39aSCy Schubert 315*276da39aSCy Schubert# Parse ntp.conf for leapfile directive 316*276da39aSCy Schubert 317*276da39aSCy SchubertLEAPFILE="`sed $NTPCONF -e'/^ *leapfile *.*$/!d' -e's/^ *leapfile *//'`" 318*276da39aSCy Schubertif [ -z "$LEAPFILE" ]; then 319*276da39aSCy Schubert log "error" "$NTPCONF does not specify a leapfile" 320*276da39aSCy Schubertfi 321*276da39aSCy Schubert 322*276da39aSCy Schubert# Allow placing the file someplace else - testing 323*276da39aSCy Schubert 324*276da39aSCy Schubertif [ -n "$1" ]; then 325*276da39aSCy Schubert if [ "$1" != "$LEAPFILE" ]; then 326*276da39aSCy Schubert log "notice" "Requested install to $1, but $NTPCONF specifies $LEAPFILE" 327*276da39aSCy Schubert fi 328*276da39aSCy Schubert LEAPFILE="$1" 329*276da39aSCy Schubertfi 330*276da39aSCy Schubert 331*276da39aSCy Schubert# Verify the current file 332*276da39aSCy Schubert# If it is missing, doesn't validate or expired 333*276da39aSCy Schubert# Or is expiring soon 334*276da39aSCy Schubert# Download a new one 335*276da39aSCy Schubert 336*276da39aSCy Schubertif [ -n "$FORCE" ] || ! verifySHA $LEAPFILE "$VERBOSE" || [ $EXPIRES -lt `date -d "NOW + $PREFETCH" +%s` ] ; then 337*276da39aSCy Schubert TRY=0 338*276da39aSCy Schubert while true; do 339*276da39aSCy Schubert TRY=$(( $TRY + 1 )) 340*276da39aSCy Schubert if [ -n "$VERBOSE" ]; then 341*276da39aSCy Schubert log "info" "Attempting download from $LEAPSRC, try $TRY.." 342*276da39aSCy Schubert fi 343*276da39aSCy Schubert if wget $PROTO $PREFER -o ${TMPFILE}.log $LEAPSRC -O $TMPFILE ; then 344*276da39aSCy Schubert log "info" "Download of $LEAPSRC succeeded" 345*276da39aSCy Schubert if [ -n "$VERBOSE" ]; then 346*276da39aSCy Schubert cat ${TMPFILE}.log 347*276da39aSCy Schubert fi 348*276da39aSCy Schubert 349*276da39aSCy Schubert if ! verifySHA $TMPFILE "$VERBOSE" ; then 350*276da39aSCy Schubert # There is no point in retrying, as the file on the server is almost 351*276da39aSCy Schubert # certainly corrupt. 352*276da39aSCy Schubert 353*276da39aSCy Schubert log "warning" "Downloaded file $TMPFILE rejected -- saved for diagnosis" 354*276da39aSCy Schubert cat ${TMPFILE}.log 355*276da39aSCy Schubert rm -f ${TMPFILE}.log 356*276da39aSCy Schubert exit 1 357*276da39aSCy Schubert fi 358*276da39aSCy Schubert rm -f ${TMPFILE}.log 359*276da39aSCy Schubert 360*276da39aSCy Schubert # Set correct permissions on temporary file 361*276da39aSCy Schubert 362*276da39aSCy Schubert REFFILE="$LEAPFILE" 363*276da39aSCy Schubert if [ ! -f $LEAPFILE ]; then 364*276da39aSCy Schubert log "notice" "$LEAPFILE was missing, creating new copy - check permissions" 365*276da39aSCy Schubert touch $LEAPFILE 366*276da39aSCy Schubert # Can't copy permissions from old file, copy from NTPCONF instead 367*276da39aSCy Schubert REFFILE="$NTPCONF" 368*276da39aSCy Schubert fi 369*276da39aSCy Schubert chmod --reference $REFFILE $TMPFILE 370*276da39aSCy Schubert chown --reference $REFFILE $TMPFILE 371*276da39aSCy Schubert ( which selinuxenabled && selinuxenabled && which chcon ) >/dev/null 2>&1 372*276da39aSCy Schubert if [ $? == 0 ] ; then 373*276da39aSCy Schubert chcon --reference $REFFILE $TMPFILE 374*276da39aSCy Schubert fi 375*276da39aSCy Schubert 376*276da39aSCy Schubert # Replace current file with validated new one 377*276da39aSCy Schubert 378*276da39aSCy Schubert if mv -f $TMPFILE $LEAPFILE ; then 379*276da39aSCy Schubert log "notice" "Installed new $LEAPFILE from $LEAPSRC" 380*276da39aSCy Schubert else 381*276da39aSCy Schubert log "error" "Install $TMPFILE => $LEAPFILE failed -- saved for diagnosis" 382*276da39aSCy Schubert exit 1 383*276da39aSCy Schubert fi 384*276da39aSCy Schubert 385*276da39aSCy Schubert # Restart NTP (or whatever else is specified) 386*276da39aSCy Schubert 387*276da39aSCy Schubert if [ -n "$RESTART" ]; then 388*276da39aSCy Schubert if [ -n "$VERBOSE" ]; then 389*276da39aSCy Schubert log "info" "Attempting restart action: $RESTART" 390*276da39aSCy Schubert fi 391*276da39aSCy Schubert R="$( 2>&1 $RESTART )" 392*276da39aSCy Schubert if [ $? -eq 0 ]; then 393*276da39aSCy Schubert log "notice" "Restart action succeeded" 394*276da39aSCy Schubert if [ -n "$VERBOSE" -a -n "$R" ]; then 395*276da39aSCy Schubert log "info" "$R" 396*276da39aSCy Schubert fi 397*276da39aSCy Schubert else 398*276da39aSCy Schubert log "error" "Restart action failed" 399*276da39aSCy Schubert if [ -n "$R" ]; then 400*276da39aSCy Schubert log "error" "$R" 401*276da39aSCy Schubert fi 402*276da39aSCy Schubert exit 2 403*276da39aSCy Schubert fi 404*276da39aSCy Schubert fi 405*276da39aSCy Schubert exit 0 406*276da39aSCy Schubert fi 407*276da39aSCy Schubert 408*276da39aSCy Schubert # Failed to download. See about trying again 409*276da39aSCy Schubert 410*276da39aSCy Schubert rm -f $TMPFILE 411*276da39aSCy Schubert if [ $TRY -ge $MAXTRIES ]; then 412*276da39aSCy Schubert break; 413*276da39aSCy Schubert fi 414*276da39aSCy Schubert if [ -n "$VERBOSE" ]; then 415*276da39aSCy Schubert cat ${TMPFILE}.log 416*276da39aSCy Schubert log "info" "Waiting $INTERVAL minutes before retrying..." 417*276da39aSCy Schubert fi 418*276da39aSCy Schubert sleep $(( $INTERVAL * 60)) 419*276da39aSCy Schubert done 420*276da39aSCy Schubert 421*276da39aSCy Schubert # Failed and out of retries 422*276da39aSCy Schubert 423*276da39aSCy Schubert log "warning" "Download from $LEAPSRC failed after $TRY attempts" 424*276da39aSCy Schubert if [ -f ${TMPFILE}.log ]; then 425*276da39aSCy Schubert cat ${TMPFILE}.log 426*276da39aSCy Schubert rm -f ${TMPFILE}.log $TMPFILE 427*276da39aSCy Schubert fi 428*276da39aSCy Schubert exit 1 429*276da39aSCy Schubertfi 430*276da39aSCy Schubertlog "info" "Not time to replace $LEAPFILE" 431*276da39aSCy Schubert 432*276da39aSCy Schubertexit 0 433*276da39aSCy Schubert 434*276da39aSCy Schubert# EOF