File: tzsetup

package info (click to toggle)
base-config 2.53.10.3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 2,072 kB
  • ctags: 36
  • sloc: sh: 1,755; makefile: 101; perl: 48
file content (353 lines) | stat: -rwxr-xr-x 9,500 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
#! /bin/sh
# TODO: replace tzconfig with this program
set -e

. /usr/share/debconf/confmodule

TEXTDOMAIN=base-config
export TEXTDOMAIN

NEWLINE="
"
TAB="	"

# The ZONEMAPPING file is used to map between the mangled
# choices and the raw timezones.
ZONEMAPPING=$(tempfile)

NONINTERACTIVE=""

# Given a country code, returns a debconf choices list describing the zones
# in that country.
mangle_zones_in_country () {
	code="$1"
	cat < /dev/null > "$ZONEMAPPING" # truncate
	# Get a list of the time zones for their country,
	# and use it as the choices list in the debconf
	# question.
	OLDIFS="$IFS"
	IFS="$NEWLINE"
	RET=""
	for line in $(grep -i "^$code$TAB" /usr/share/zoneinfo/zone.tab); do
		zone=$(echo "$line" | cut -d "$TAB" -f 3)
		comment=$(echo "$line" | cut -d "$TAB" -f 4 | sed "s/, /; /g")
		# Mangle the time zone for display.
		if [ -z "$comment" ]; then
			choice="$zone"
		else
			choice="$zone ($comment)"
		fi
		# This gettext is freaky, since the text is
		# completly dynamic. To construct the po file entries
		# for this, extract all the time zones and comments 
		# from zone.tab and mangle the same way it's done above.
		choice=$(gettext "$choice")
		echo "$choice$TAB$zone" >> "$ZONEMAPPING"
		if [ -z "$RET" ]; then
			RET="$choice"
		else
			RET="$RET, $choice"
		fi
	done
	IFS="$OLDIFS"
	echo "$RET"
}

# Given a country code, returns a good default timezone for that country,
# in the same form used by the other functions. Should be called after
# mangle_zones_in_country
default_for_country () {
	code="$1"
	
	case "$code" in
	AU)
		best="Australia/Sydney"
	;;
	*)
		# Default to first listed. (Which happens to be correct for
		# most of them.)
		best=$(grep -i "^$code$TAB" /usr/share/zoneinfo/zone.tab |
			head -n 1 | cut -d "$TAB" -f 3)
	;;
	esac

	# Get mangled form.
	grep "$TAB$best\$" "$ZONEMAPPING" | cut -d "$TAB" -f 1
}

# Given a choice from the list constructed by mangle_zones_in_country,
# returns the time zone.
demangle_zone () {
	CHOICE="$1"

	# Map from a possibly translated choice back the the C version.
	zone=$(grep "^$CHOICE$TAB" "$ZONEMAPPING" | cut -d "$TAB" -f 2)
	if [ -z "$zone" ]; then
		echo "$0 internal error: cannot find \"$CHOICE\" in $ZONEMAPPING" >&2
		exit 1
	fi
	echo "$zone"
}

while getopts "gUc:yN" o; do
	case $o in
	g) ASKUTC=1 ;;
	y) CHANGE=1 ;;
	c) COUNTRY=$OPTARG ;;
	U) NOTUTC=1 ;;
	N) NONINTERACTIVE=1 ;;
	*) exit 1   ;;
	esac
done

# s390 arch has no hwclock support; if there is no hwclock just diaable
# that code path in general
if [ ! -e /sbin/hwclock ]; then
	ASKUTC=""
fi

# Set up debconf.
db_capb backup
db_settitle tzconfig/title

# Feed current timezone in to question.
if [ -f /etc/timezone ]; then
	db_subst tzconfig/change_timezone timezone `cat /etc/timezone`
elif [ -L /etc/localtime ]; then
	db_subst tzconfig/change_timezone timezone \
		$(readlink /etc/localtime | sed 's%^/usr/share/zoneinfo/%%')	
fi

# Let's use a state machine to let the user jump back to earlier questions.
STATE=1
LASTSTATE=7
while [ "$STATE" -le $LASTSTATE ]; do
	case "$STATE" in
	1)
		if [ "$ASKUTC" ]; then
			if [ ! "$NOTUTC" ]; then
				# Source rcS to get the current setting,
				# and use that to control the default.
				if [ -e /etc/default/rcS ]; then
					. /etc/default/rcS || true
				fi
				if [ "$UTC" = yes ]; then
					db_set tzconfig/gmt true
				else
					db_set tzconfig/gmt false
				fi
			else
				db_fget tzconfig/gmt seen
				if [ "$RET" = false ] || [ ! "$NONINTERACTIVE" ]; then
					db_set tzconfig/gmt false
				fi
			fi

			# The awk removes info about drift from the 
			# hwclock output.
			db_subst tzconfig/gmt hwtime $(hwclock --show --localtime | awk '{NF-=2; print $0}')
			db_input high tzconfig/gmt || true
		fi
	;;
	2)
		db_fset tzconfig/gmt seen false
	
		if [ ! "$CHANGE" ]; then
			# Show current time zone and ask if it should be changed.
			db_input high tzconfig/change_timezone || true
		fi
	;;
	3)
		db_fset tzconfig/change_timezone seen false
	
		# Jump to end if the user doesn't want the time zone changed.
		db_get tzconfig/change_timezone
		if [ "$RET" = false ] && [ ! "$CHANGE" ]; then
			STATE=$(($LASTSTATE - 2))
		elif [ -n "$COUNTRY" ]; then
			# See if there is a special question for this
			# country.
			COUNTRY=$(echo "$COUNTRY" | tr a-z A-Z)
			if db_get tzconfig/choose_country_zone/$COUNTRY; then
				COUNTRY_ZONE_Q=tzconfig/choose_country_zone/$COUNTRY
				case "$COUNTRY" in
				CA)
					COUNTRY_ZONE_PREFIX=Canada
				;;
				US)
					COUNTRY_ZONE_PREFIX=US
				;;
				BR)
					COUNTRY_ZONE_PREFIX=Brazil
				;;
				esac
			else
				zone_choices=$(mangle_zones_in_country "$COUNTRY")
				if [ -n "$zone_choices" ]; then
					# Always subst into this, it is
					# used below to get the zone, no
					# matter which style of question is
					# displayed.
					db_subst tzconfig/choose_country_zone_multiple \
						choices "$zone_choices"
					db_fget tzconfig/choose_country_zone_multiple seen 
					if [ "$RET" = false ] || [ ! "$NONINTERACTIVE" ]; then
						db_set tzconfig/choose_country_zone_multiple \
							$(default_for_country "$COUNTRY")
					fi
					if echo "$zone_choices" | grep -q ", "; then
						COUNTRY_ZONE_Q=tzconfig/choose_country_zone_multiple
					else
						COUNTRY_ZONE_Q=tzconfig/choose_country_zone_single
						db_subst $COUNTRY_ZONE_Q zone "$zone_choices"
					fi
				fi
			fi
			if [ -n "$COUNTRY_ZONE_Q" ]; then
				db_input high $COUNTRY_ZONE_Q || true
			fi
		fi
	;;
	4)
		if [ -n "$COUNTRY_ZONE_Q" ]; then
			db_fset $COUNTRY_ZONE_Q seen false
			db_get $COUNTRY_ZONE_Q
			if [ "$COUNTRY_ZONE_Q" = tzconfig/choose_country_zone_single ]; then
				if [ "$RET" = "true" ]; then
					SKIP_DRILLDOWN=1
				else
					SKIP_DRILLDOWN=0
				fi
			elif [ "$RET" = other ]; then
				SKIP_DRILLDOWN=0
			else
				SKIP_DRILLDOWN=1
			fi
		else
			SKIP_DRILLDOWN=0
		fi
		
		if [ "$SKIP_DRILLDOWN" = 0 ]; then
			# Show top level divisions (mainly by continent).
			db_input high tzconfig/geographic_area || true
		fi
	;;
	5)
		if [ "$SKIP_DRILLDOWN" = 0 ]; then
			db_fset tzconfig/geographic_area seen false
			
			# Prompt with a list of zones in the selected area.
			# Suckily, we have to map some of the values that were
			# prompted with to the directory names themselves.
			db_get tzconfig/geographic_area
			DIR="$RET"
			case "$DIR" in
			"Atlantic Ocean")		DIR=Atlantic	;;
			"Indian Ocean")			DIR=Indian	;;
			"Pacific Ocean")		DIR=Pacific	;;
			"System V style time zones")	DIR=SystemV	;;
			"None of the above")		DIR=Etc		;;
			esac
			if [ ! -d /usr/share/zoneinfo/$DIR ]; then
				echo "$0 internal error: /usr/share/zoneinfo/$DIR does not exist" >&2
				exit 1
			fi

			# Instantiate zone selection question for area, and
			# populate with available choices.
			db_register tzconfig/select_zone tzconfig/select_zone/$DIR || true
			db_subst tzconfig/select_zone/$DIR choices \
				$(find /usr/share/zoneinfo/$DIR -type f -printf "%f, \n" | \
				  sort | xargs echo | sed 's/,$//')

			db_input high tzconfig/select_zone/$DIR || true
		fi
	;;
	6)
		if [ "$SKIP_DRILLDOWN" = 1 ]; then
			if db_get tzconfig/choose_country_zone/$COUNTRY; then
				timezone="$COUNTRY_ZONE_PREFIX/$RET"
			else
				db_get tzconfig/choose_country_zone_multiple
				timezone=$(demangle_zone "$RET")
			fi
		else
			db_fset tzconfig/select_zone/$DIR seen false
			db_get tzconfig/select_zone/$DIR || true
			timezone="$DIR/$RET"
		fi

		if [ "$timezone" = "/" ] || [ "$timezone" = "" ]; then
			# Skipped timezone selection stage.
			timezone=$(cat /etc/timezone)
		fi

		# Set time zone.
		db_get tzconfig/change_timezone
		if [ "$RET" = true ] || [ "$CHANGE" ]; then
			echo $timezone > /etc/timezone 
			rm -f /etc/localtime && \
				ln -sf /usr/share/zoneinfo/$timezone /etc/localtime
		fi
		
		if [ "$ASKUTC" ]; then
			# Set gmt or not. Only change the file if the value
			# changed. This must only be done after the time zone
			# file is set up.
			db_get tzconfig/gmt
			if [ "$RET" = true ] && [ "$UTC" != yes ]; then
				sed -e 's:^UTC="no":UTC="yes":' -e 's:^UTC=no:UTC=yes:' \
					/etc/default/rcS > /etc/default/rcS.new
				CHANGEUTC=1
			elif [ "$RET" = false ] && [ "$UTC" != no ]; then
				sed -e 's:^UTC="yes":UTC="no":' -e 's:^UTC=yes:UTC=no:' \
					/etc/default/rcS > /etc/default/rcS.new
				CHANGEUTC=1
			fi
			if [ "$CHANGEUTC" ]; then
				mv -f /etc/default/rcS.new /etc/default/rcS
				/etc/init.d/hwclock.sh start >/dev/null </dev/null
			fi
		fi
		
		db_get tzconfig/change_timezone
		if [ "$RET" = true ] || [ "$CHANGE" ]; then
			# Display a final message giving the selected zone
			# and showing the time in that zone (and UTC for
			# comparison) and asking if it looks ok.
			utdate=$(LANG=C LC_ALL=C date -u)
			tzdate=$(LANG=C LC_ALL=C date -d "$utdate")
			db_subst tzconfig/verify_choices timezone "$timezone"
			db_subst tzconfig/verify_choices tzdate "$tzdate"
			db_subst tzconfig/verify_choices utdate $utdate
			db_set tzconfig/verify_choices true
			db_input low tzconfig/verify_choices || true
		fi
	;;
	7)
		db_get tzconfig/change_timezone
		if [ "$RET" = true ] || [ "$CHANGE" ]; then
			db_fset tzconfig/verify_choices seen false
			# Get the result of that last question, and if it
			# is false, loop back to start.
			db_get tzconfig/verify_choices
			if [ "$RET" = false ]; then
				STATE=0
			fi
		fi
	;;
	esac

	if db_go; then
		STATE=$(($STATE + 1))
	else
		STATE=$(($STATE - 1))
	fi

	if [ "$STATE" = 0 ]; then
		# propigate back up out
		exit 30
	fi
done

rm -f "$ZONEMAPPING"