1#!/bin/bash
2#
3# dhclient-tz-exithook.sh
4# Version 1.01 elear
5#
6# Copyright (c) 2007, Cisco Systems, Inc.
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions
11# are met:
12#
13#    - Redistributions of source code must retain the above copyright
14#      notice, this list of conditions and the following disclaimer.
15#
16#    - Redistributions in binary form must reproduce the above copyright
17#      notice, this list of conditions and the following disclaimer in
18#      the documentation and/or other materials provided with the
19#      distribution.
20#
21#    - Neither the name of Cisco Systems, Inc. nor the names of its
22#      contributors may be used to endorse or promote products derived
23#      from this software without specific prior written permission.
24#
25#    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26#    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27#    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28#    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29#    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30#    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31#    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
32#    GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33#    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34#    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35#    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36#    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37#
38# the following script is used to set the timezone based on the new
39# dhcp timezone option defined currently in the IETF document
40# draft-ietf-dhc-timezone-option-04.txt.
41
42# this code is intended for use with ISC's dhclient.  it is to be called
43# either as, or by, dhclient-exit-hooks
44#
45# As this is test code, in order for it to be called two changes
46# must be made to /etc/dhclient.conf.  First, dhclient.conf must be
47# aware of the tzName option.  The IANA has assigned tzName option
48# code 101.  You may need to add this to your configuration file.
49#
50#  option tzName code 101 = text;
51#
52# Next, add tzName to the list of options in the "request" statement.
53# For example:
54#
55# request subnet-mask, broadcast-address, time-offset, routers,
56#         domain-name, domain-name-servers, host-name, tzName;
57#
58#
59# And of course make sure that your dhcp server is transmitting timezone
60# information for option 101.  For IOS this can be done as follows:
61#
62#    option 101 ascii "Europe/Berlin"
63#
64
65timefile=/etc/localtime
66oldfile=$timefile.old
67tmpfile=$timefile.$$
68
69# function to clean up just in case we are interrupted or something
70# bad happens.
71restore_file () {
72
73  if [ ! -f $timefile ]; then
74     $DEBUG mv $tmpfile $timefile
75  fi
76  $DEBUG rm $tmpfile
77  exit
78}
79
80
81#set DEBUG to "echo" to see what would happen.
82if [ x$DEBUG = x ]; then
83   DEBUG=
84fi
85
86# if something has already gone wrong we're not doing a thing.
87if [ x$exit_status != x0 ]; then
88   exit $exit_status
89fi
90
91
92# if we don't have a new timezone, then we have nothing to change, so
93# goodbye.
94if [ x$new_tzName = x ]; then
95   exit 0
96fi
97
98# if the timezone doesn't exist, goodbye.
99if [ ! -e $timefile ]; then
100   exit 0
101fi
102
103# find zoneinfo. use the first one.
104ftz=0
105for a in /usr/share/zoneinfo /usr/lib/zoneinfo /var/share/zoneinfo /var/zoneinfo; do
106  if [ -d $a -a $ftz = 0 ]; then
107    zoneinfo=$a
108    ftz=1
109  fi
110done
111
112# no zoneinfo found.  goodbye.
113if [ x$zoneinfo = x ]; then
114   exit 0
115fi
116
117# timezone not found.  goodbye.
118if [ ! -f $zoneinfo/$new_tzName ]; then
119   exit 0
120fi
121
122# if we're here we can actually do something useful.
123# first, link a copy of the existing timefile.
124
125$DEBUG ln $timefile $tmpfile
126
127if [ $? != 0 ]; then
128  echo "unable to create temporary file"
129  exit -1
130fi
131
132# in case of interrupt, cleanup.
133trap restore_file SIGINT SIGSEGV SIGQUIT SIGTERM
134
135# we destroy old backup files in this process.  if we cannot and the
136# file exists then something went wrong.
137if [ -e $oldfile ]; then
138  $DEBUG rm $oldfile
139  if [ $? != 0 ]; then
140     echo "$0: failed to remove $oldfile"
141     rm -f $tmpfile
142     exit -1
143  fi
144fi
145
146# sensitive part happens here:
147#
148$DEBUG mv $timefile $oldfile
149
150  if [ $? != 0 ]; then
151     echo "$0: failed to move old $timefile file out of the way"
152     rm $tmpfile
153     exit -1
154  fi
155
156$DEBUG ln $zoneinfo/$new_tzName $timefile
157
158# we don't complain just yet- a hard link could fail because
159# we're on two different file systems.  Go for a soft link.
160#
161
162if [ $? != 0 ]; then
163  $DEBUG ln -s $zoneinfo/$new_tzName $timefile
164fi
165
166if [ $? != 0 ]; then       # failed to softlink.  now we're getting nervous.
167  echo "$0: unable to establish new timezone.  Attempting to revert."
168  $DEBUG ln $tmpfile $timefile
169fi
170
171
172if [ $? != 0 ]; then       # we're absolutely hosed
173  echo "$0: unable to link or softlink timezone file, and unable to restore old file - giving up!"
174  exit -1
175fi
176
177$DEBUG rm $tmpfile
178
179exit $?
180