#!/bin/bash
#
# dhclient-tz-exithook.sh
# Version 1.01 elear
#
# Copyright (c) 2007, Cisco Systems, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# - Neither the name of Cisco Systems, Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# the following script is used to set the timezone based on the new
# dhcp timezone option defined currently in the IETF document
# draft-ietf-dhc-timezone-option-04.txt.
# this code is intended for use with ISC's dhclient. it is to be called
# either as, or by, dhclient-exit-hooks
#
# As this is test code, in order for it to be called two changes
# must be made to /etc/dhclient.conf. First, dhclient.conf must be
# aware of the tzName option. The IANA has assigned tzName option
# code 101. You may need to add this to your configuration file.
#
# option tzName code 101 = text;
#
# Next, add tzName to the list of options in the "request" statement.
# For example:
#
# request subnet-mask, broadcast-address, time-offset, routers,
# domain-name, domain-name-servers, host-name, tzName;
#
#
# And of course make sure that your dhcp server is transmitting timezone
# information for option 101. For IOS this can be done as follows:
#
# option 101 ascii "Europe/Berlin"
#
timefile=/etc/localtime
oldfile=$timefile.old
tmpfile=$timefile.$$
# function to clean up just in case we are interrupted or something
# bad happens.
restore_file () {
if [ ! -f $timefile ]; then
$DEBUG mv $tmpfile $timefile
fi
$DEBUG rm $tmpfile
exit
}
#set DEBUG to "echo" to see what would happen.
if [ x$DEBUG = x ]; then
DEBUG=
fi
# if something has already gone wrong we're not doing a thing.
if [ x$exit_status != x0 ]; then
exit $exit_status
fi
# if we don't have a new timezone, then we have nothing to change, so
# goodbye.
if [ x$new_tzName = x ]; then
exit 0
fi
# if the timezone doesn't exist, goodbye.
if [ ! -e $timefile ]; then
exit 0
fi
# find zoneinfo. use the first one.
ftz=0
for a in /usr/share/zoneinfo /usr/lib/zoneinfo /var/share/zoneinfo /var/zoneinfo; do
if [ -d $a -a $ftz = 0 ]; then
zoneinfo=$a
ftz=1
fi
done
# no zoneinfo found. goodbye.
if [ x$zoneinfo = x ]; then
exit 0
fi
# timezone not found. goodbye.
if [ ! -f $zoneinfo/$new_tzName ]; then
exit 0
fi
# if we're here we can actually do something useful.
# first, link a copy of the existing timefile.
$DEBUG ln $timefile $tmpfile
if [ $? != 0 ]; then
echo "unable to create temporary file"
exit -1
fi
# in case of interrupt, cleanup.
trap restore_file SIGINT SIGSEGV SIGQUIT SIGTERM
# we destroy old backup files in this process. if we cannot and the
# file exists then something went wrong.
if [ -e $oldfile ]; then
$DEBUG rm $oldfile
if [ $? != 0 ]; then
echo "$0: failed to remove $oldfile"
rm -f $tmpfile
exit -1
fi
fi
# sensitive part happens here:
#
$DEBUG mv $timefile $oldfile
if [ $? != 0 ]; then
echo "$0: failed to move old $timefile file out of the way"
rm $tmpfile
exit -1
fi
$DEBUG ln $zoneinfo/$new_tzName $timefile
# we don't complain just yet- a hard link could fail because
# we're on two different file systems. Go for a soft link.
#
if [ $? != 0 ]; then
$DEBUG ln -s $zoneinfo/$new_tzName $timefile
fi
if [ $? != 0 ]; then # failed to softlink. now we're getting nervous.
echo "$0: unable to establish new timezone. Attempting to revert."
$DEBUG ln $tmpfile $timefile
fi
if [ $? != 0 ]; then # we're absolutely hosed
echo "$0: unable to link or softlink timezone file, and unable to restore old file - giving up!"
exit -1
fi
$DEBUG rm $tmpfile
exit $?