xref: /freebsd/usr.sbin/bsdconfig/timezone/share/zones.subr (revision f8ea072a542112d5e0e74a2d6ecf75d967c3054c)
1ab2043b8SDevin Teskeif [ ! "$_TIMEZONE_ZONES_SUBR" ]; then _TIMEZONE_ZONES_SUBR=1
2ab2043b8SDevin Teske#
3ab2043b8SDevin Teske# Copyright (c) 2011-2012 Devin Teske
4*f8ea072aSDevin Teske# All rights reserved.
5ab2043b8SDevin Teske#
6ab2043b8SDevin Teske# Redistribution and use in source and binary forms, with or without
7ab2043b8SDevin Teske# modification, are permitted provided that the following conditions
8ab2043b8SDevin Teske# are met:
9ab2043b8SDevin Teske# 1. Redistributions of source code must retain the above copyright
10ab2043b8SDevin Teske#    notice, this list of conditions and the following disclaimer.
11ab2043b8SDevin Teske# 2. Redistributions in binary form must reproduce the above copyright
12ab2043b8SDevin Teske#    notice, this list of conditions and the following disclaimer in the
13ab2043b8SDevin Teske#    documentation and/or other materials provided with the distribution.
14ab2043b8SDevin Teske#
15ab2043b8SDevin Teske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16ab2043b8SDevin Teske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE
17ab2043b8SDevin Teske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ab2043b8SDevin Teske# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19ab2043b8SDevin Teske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20ab2043b8SDevin Teske# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21ab2043b8SDevin Teske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22ab2043b8SDevin Teske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23ab2043b8SDevin Teske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24ab2043b8SDevin Teske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25ab2043b8SDevin Teske# SUCH DAMAGE.
26ab2043b8SDevin Teske#
27ab2043b8SDevin Teske# $FreeBSD$
28ab2043b8SDevin Teske#
29ab2043b8SDevin Teske############################################################ INCLUDES
30ab2043b8SDevin Teske
31ab2043b8SDevin TeskeBSDCFG_SHARE="/usr/share/bsdconfig"
32ab2043b8SDevin Teske. $BSDCFG_SHARE/common.subr || exit 1
3356961fd7SDevin Teskef_dprintf "%s: loading includes..." timezone/zones.subr
34ab2043b8SDevin Teskef_include $BSDCFG_SHARE/dialog.subr
35ab2043b8SDevin Teskef_include $BSDCFG_SHARE/timezone/continents.subr
36ab2043b8SDevin Teske
37ab2043b8SDevin TeskeBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="090.timezone"
38ab2043b8SDevin Teskef_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
39ab2043b8SDevin Teske
40ab2043b8SDevin Teske############################################################ CONFIGURATION
41ab2043b8SDevin Teske
42ab2043b8SDevin Teske#
43ab2043b8SDevin Teske# Standard pathnames
44ab2043b8SDevin Teske#
45ab2043b8SDevin Teske_PATH_ZONETAB="/usr/share/zoneinfo/zone.tab"
46ab2043b8SDevin Teske_PATH_ZONEINFO="/usr/share/zoneinfo"
47ab2043b8SDevin Teske_PATH_LOCALTIME="/etc/localtime"
48ab2043b8SDevin Teske_PATH_DB="/var/db/zoneinfo"
49ab2043b8SDevin Teske
50ab2043b8SDevin Teske#
51ab2043b8SDevin Teske# Export required i18n messages for awk(1) ENVIRON visibility
52ab2043b8SDevin Teske#
53ab2043b8SDevin Teskeexport msg_conflicting_zone_definition
54ab2043b8SDevin Teskeexport msg_country_code_invalid
55ab2043b8SDevin Teskeexport msg_country_code_unknown
56ab2043b8SDevin Teskeexport msg_invalid_country_code
57ab2043b8SDevin Teskeexport msg_invalid_format
58ab2043b8SDevin Teskeexport msg_invalid_region
59ab2043b8SDevin Teskeexport msg_invalid_zone_name
60ab2043b8SDevin Teskeexport msg_zone_multiply_defined
61ab2043b8SDevin Teskeexport msg_zone_must_have_description
62ab2043b8SDevin Teske
63ab2043b8SDevin Teske############################################################ FUNCTIONS
64ab2043b8SDevin Teske
65ab2043b8SDevin Teske# f_read_zones
66ab2043b8SDevin Teske#
67ab2043b8SDevin Teske# Read the zone descriptions database in _PATH_ZONETAB:
68ab2043b8SDevin Teske# 	/usr/share/zoneinfo/zone.tab on all OSes
69ab2043b8SDevin Teske#
70ab2043b8SDevin Teske# The format of this file (on all OSes) is:
71ab2043b8SDevin Teske# 	code	coordinates	TZ	comments
72ab2043b8SDevin Teske#
73ab2043b8SDevin Teske# With each of the following elements (described below) being separated by a
74ab2043b8SDevin Teske# single tab character:
75ab2043b8SDevin Teske#
76ab2043b8SDevin Teske# 	code
77ab2043b8SDevin Teske# 		The ISO 3166 2-character country code.
78ab2043b8SDevin Teske# 	coordinates
79ab2043b8SDevin Teske# 		Latitude and logitude of the zone's principal location in ISO
80ab2043b8SDevin Teske# 		6709 sign-degrees-minutes-seconds format, either +-DDMM+-DDDMM
81ab2043b8SDevin Teske# 		or +-DDMMSS+-DDDMMSS, first latitude (+ is north), then long-
82ab2043b8SDevin Teske# 		itude (+ is east).
83ab2043b8SDevin Teske# 	TZ
84ab2043b8SDevin Teske# 		Zone name used in value of TZ environment variable.
85ab2043b8SDevin Teske# 	comments
86ab2043b8SDevin Teske# 		Comments; present if and only if the country has multiple rows.
87ab2043b8SDevin Teske#
88ab2043b8SDevin Teske# Required variables [from continents.subr]:
89ab2043b8SDevin Teske#
90ab2043b8SDevin Teske# 	CONTINENTS
91ab2043b8SDevin Teske# 		Space-separated list of continents.
92ab2043b8SDevin Teske# 	continent_*_name
93ab2043b8SDevin Teske# 		Directory element in _PATH_ZONEINFO for the continent
94ab2043b8SDevin Teske# 		represented by *.
95ab2043b8SDevin Teske#
96ab2043b8SDevin Teske# Required variables [created by f_read_iso3166_table from iso3166.subr]:
97ab2043b8SDevin Teske#
98ab2043b8SDevin Teske# 	country_CODE_name
99ab2043b8SDevin Teske# 		Country name of the country represented by CODE, the 2-
100ab2043b8SDevin Teske# 		character country code.
101ab2043b8SDevin Teske#
102ab2043b8SDevin Teske# Variables created by this function:
103ab2043b8SDevin Teske#
104ab2043b8SDevin Teske# 	country_CODE_nzones
105ab2043b8SDevin Teske# 		Either set to `-1' to indicate that the 2-character country
106ab2043b8SDevin Teske# 		code has only a single zone associated with it (and therefore
107ab2043b8SDevin Teske# 		you should query the `country_CODE_*' environment variables),
108ab2043b8SDevin Teske# 		or set to `0' or higher to indicate how many zones are assoc-
109ab2043b8SDevin Teske# 		iated with the given country code. When multiple zones are
110ab2043b8SDevin Teske# 		configured for a single code, you should instead query the
111ab2043b8SDevin Teske# 		`country_CODE_*_N' environment variables (e.g., `echo
112ab2043b8SDevin Teske# 		$country_AQ_descr_1' prints the description of the first
113ab2043b8SDevin Teske# 		timezone in Antarctica).
114ab2043b8SDevin Teske# 	country_CODE_filename
115ab2043b8SDevin Teske# 		The ``filename'' portion of the TZ value that appears after the
116ab2043b8SDevin Teske# 		`/' (e.g., `Hong_Kong' from `Asia/Hong_Kong' or `Isle_of_Man'
117ab2043b8SDevin Teske# 		from `Europe/Isle_of_Man').
118ab2043b8SDevin Teske# 	country_CODE_cont
119ab2043b8SDevin Teske# 		The ``continent'' portion of the TZ value that appears before
120ab2043b8SDevin Teske# 		the `/' (e.g., `Asia' from `Asia/Hong_Kong' or `Europe' from
121ab2043b8SDevin Teske# 		`Europe/Isle_of_Man').
122ab2043b8SDevin Teske# 	country_CODE_descr
123ab2043b8SDevin Teske# 		The comments associated with the ISO 3166 code entry (if any).
124ab2043b8SDevin Teske#
125ab2043b8SDevin Teske# 	NOTE: CODE is the 2-character country code.
126ab2043b8SDevin Teske#
127ab2043b8SDevin Teske# This function is a two-parter. Below is the awk(1) portion of the function,
128ab2043b8SDevin Teske# afterward is the sh(1) function which utilizes the below awk script.
129ab2043b8SDevin Teske#
130ab2043b8SDevin Teskef_read_zones_awk='
131ab2043b8SDevin Teske# Variables that should be defined on the invocation line:
132ab2043b8SDevin Teske# 	-v progname="progname"
133ab2043b8SDevin Teske#
134ab2043b8SDevin TeskeBEGIN {
135ab2043b8SDevin Teske	lineno = 0
136ab2043b8SDevin Teske	failed = 0
137ab2043b8SDevin Teske
138ab2043b8SDevin Teske	#
139ab2043b8SDevin Teske	# Initialize continents array/map (name => id)
140ab2043b8SDevin Teske	#
141ab2043b8SDevin Teske	split(ENVIRON["CONTINENTS"], array, /[[:space:]]+/)
142ab2043b8SDevin Teske	for (item in array)
143ab2043b8SDevin Teske	{
144ab2043b8SDevin Teske		cont = array[item]
145ab2043b8SDevin Teske		if (!cont) continue
146ab2043b8SDevin Teske		name = ENVIRON["continent_" cont "_name"]
147ab2043b8SDevin Teske		continents[name] = cont
148ab2043b8SDevin Teske	}
149ab2043b8SDevin Teske}
150ab2043b8SDevin Teskefunction die(fmt, argc, argv)
151ab2043b8SDevin Teske{
152ab2043b8SDevin Teske	printf "f_die 1 \"%%s: %s\" \"%s\"", fmt, progname
153ab2043b8SDevin Teske	for (n = 1; n <= argc; n++)
154ab2043b8SDevin Teske		printf " \"%s\"", argv[n]
155ab2043b8SDevin Teske	print ""
156ab2043b8SDevin Teske	failed++
157ab2043b8SDevin Teske	exit 1
158ab2043b8SDevin Teske}
159ab2043b8SDevin Teskefunction find_continent(name)
160ab2043b8SDevin Teske{
161ab2043b8SDevin Teske	return continents[name]
162ab2043b8SDevin Teske}
163ab2043b8SDevin Teskefunction add_zone_to_country(lineno, tlc, descr, file, cont)
164ab2043b8SDevin Teske{
165ab2043b8SDevin Teske	#
166ab2043b8SDevin Teske	# Validate the two-character country code
167ab2043b8SDevin Teske	#
168ab2043b8SDevin Teske	if (!match(tlc, /^[A-Z][A-Z]$/))
169ab2043b8SDevin Teske	{
170ab2043b8SDevin Teske		argv[1] = FILENAME
171ab2043b8SDevin Teske		argv[2] = lineno
172ab2043b8SDevin Teske		argv[3] = tlc
173ab2043b8SDevin Teske		die(ENVRION["msg_country_code_invalid"], 3, argv)
174ab2043b8SDevin Teske	}
175ab2043b8SDevin Teske	if (!ENVIRON["country_" tlc "_name"])
176ab2043b8SDevin Teske	{
177ab2043b8SDevin Teske		argv[1] = FILENAME
178ab2043b8SDevin Teske		argv[2] = lineno
179ab2043b8SDevin Teske		argv[3] = tlc
180ab2043b8SDevin Teske		die(ENVIRON["msg_country_code_unknown"], 3, argv)
181ab2043b8SDevin Teske	}
182ab2043b8SDevin Teske
183ab2043b8SDevin Teske	#
184ab2043b8SDevin Teske	# Add Zone to an array that we will parse at the end
185ab2043b8SDevin Teske	#
186ab2043b8SDevin Teske	if (length(descr) > 0)
187ab2043b8SDevin Teske	{
188ab2043b8SDevin Teske		if (country_nzones[tlc] < 0)
189ab2043b8SDevin Teske		{
190ab2043b8SDevin Teske			argv[1] = FILENAME
191ab2043b8SDevin Teske			argv[2] = lineno
192ab2043b8SDevin Teske			die(ENVIRON["msg_conflicting_zone_definition"], 2, argv)
193ab2043b8SDevin Teske		}
194ab2043b8SDevin Teske
195ab2043b8SDevin Teske		n = ++country_nzones[tlc]
196ab2043b8SDevin Teske		country_cont[tlc,n] = cont
197ab2043b8SDevin Teske		country_filename[tlc,n] = file
198ab2043b8SDevin Teske		country_descr[tlc,n] = descr
199ab2043b8SDevin Teske	}
200ab2043b8SDevin Teske	else
201ab2043b8SDevin Teske	{
202ab2043b8SDevin Teske		if (country_nzones[tlc] > 0)
203ab2043b8SDevin Teske		{
204ab2043b8SDevin Teske			argv[1] = FILENAME
205ab2043b8SDevin Teske			argv[2] = lineno
206ab2043b8SDevin Teske			die(ENVIRON["msg_zone_must_have_description"], 2, argv)
207ab2043b8SDevin Teske		}
208ab2043b8SDevin Teske		if (country_nzones[tlc] < 0)
209ab2043b8SDevin Teske		{
210ab2043b8SDevin Teske			argv[1] = FILENAME
211ab2043b8SDevin Teske			argv[2] = lineno
212ab2043b8SDevin Teske			die(ENVIRON["msg_zone_multiply_defined"], 2, argv)
213ab2043b8SDevin Teske		}
214ab2043b8SDevin Teske
215ab2043b8SDevin Teske		country_nzones[tlc] = -1
216ab2043b8SDevin Teske		country_cont[tlc] = cont
217ab2043b8SDevin Teske		country_filename[tlc] = file
218ab2043b8SDevin Teske	}
219ab2043b8SDevin Teske}
220ab2043b8SDevin Teskefunction print_country_code(tlc)
221ab2043b8SDevin Teske{
222ab2043b8SDevin Teske	nz = country_nzones[tlc]
223ab2043b8SDevin Teske
224ab2043b8SDevin Teske	printf "country_%s_nzones=%d\n", tlc, nz
225ab2043b8SDevin Teske	printf "export country_%s_nzones\n", tlc
226ab2043b8SDevin Teske
227ab2043b8SDevin Teske	if (nz < 0)
228ab2043b8SDevin Teske	{
229ab2043b8SDevin Teske		printf "country_%s_cont=\"%s\"\n", tlc, country_cont[tlc]
230ab2043b8SDevin Teske		printf "export country_%s_cont\n", tlc
231ab2043b8SDevin Teske		printf "country_%s_filename=\"%s\"\n",
232ab2043b8SDevin Teske		       tlc, country_filename[tlc]
233ab2043b8SDevin Teske	}
234ab2043b8SDevin Teske	else
235ab2043b8SDevin Teske	{
236ab2043b8SDevin Teske		n = 0
237ab2043b8SDevin Teske		while ( ++n <= nz )
238ab2043b8SDevin Teske		{
239ab2043b8SDevin Teske			printf "country_%s_cont_%d=\"%s\"\n",
240ab2043b8SDevin Teske			       tlc, n, country_cont[tlc,n]
241ab2043b8SDevin Teske			printf "export country_%s_cont_%d\n", tlc, n
242ab2043b8SDevin Teske			printf "country_%s_filename_%d=\"%s\"\n",
243ab2043b8SDevin Teske			       tlc, n, country_filename[tlc,n]
244ab2043b8SDevin Teske			printf "country_%s_descr_%d=\"%s\"\n",
245ab2043b8SDevin Teske			       tlc, n, country_descr[tlc,n]
246ab2043b8SDevin Teske		}
247ab2043b8SDevin Teske	}
248ab2043b8SDevin Teske}
249ab2043b8SDevin Teske/^#/ {
250ab2043b8SDevin Teske	lineno++
251ab2043b8SDevin Teske	next
252ab2043b8SDevin Teske}
253ab2043b8SDevin Teske!/^#/ {
254ab2043b8SDevin Teske	lineno++
255ab2043b8SDevin Teske
256ab2043b8SDevin Teske	#
257ab2043b8SDevin Teske	# Split the current record (on TAB) into an array
258ab2043b8SDevin Teske	#
259ab2043b8SDevin Teske	if (split($0, line, /\t/) < 2)
260ab2043b8SDevin Teske	{
261ab2043b8SDevin Teske		argv[1] = FILENAME
262ab2043b8SDevin Teske		argv[2] = lineno
263ab2043b8SDevin Teske		die(ENVIRON["msg_invalid_format"], 2, argv)
264ab2043b8SDevin Teske	}
265ab2043b8SDevin Teske
266ab2043b8SDevin Teske	# Get the ISO3166-1 (Alpha 1) 2-letter country code
267ab2043b8SDevin Teske	tlc = line[1]
268ab2043b8SDevin Teske
269ab2043b8SDevin Teske	#
270ab2043b8SDevin Teske	# Validate the two-character country code
271ab2043b8SDevin Teske	#
272ab2043b8SDevin Teske	if (length(tlc) != 2)
273ab2043b8SDevin Teske	{
274ab2043b8SDevin Teske		argv[1] = FILENAME
275ab2043b8SDevin Teske		argv[2] = lineno
276ab2043b8SDevin Teske		argv[3] = tlc
277ab2043b8SDevin Teske		die(ENVIRON["msg_invalid_country_code"], 3, argv)
278ab2043b8SDevin Teske	}
279ab2043b8SDevin Teske
280ab2043b8SDevin Teske	# Get the TZ field
281ab2043b8SDevin Teske	tz = line[3]
282ab2043b8SDevin Teske
283ab2043b8SDevin Teske	#
284ab2043b8SDevin Teske	# Validate the TZ field
285ab2043b8SDevin Teske	#
286ab2043b8SDevin Teske	if (!match(tz, "/"))
287ab2043b8SDevin Teske	{
288ab2043b8SDevin Teske		argv[1] = FILENAME
289ab2043b8SDevin Teske		argv[2] = lineno
290ab2043b8SDevin Teske		argv[3] = tz
291ab2043b8SDevin Teske		die(ENVIRON["msg_invalid_zone_name"], 3, argv)
292ab2043b8SDevin Teske	}
293ab2043b8SDevin Teske
294ab2043b8SDevin Teske	#
295ab2043b8SDevin Teske	# Get the continent portion of the TZ field
296ab2043b8SDevin Teske	#
297ab2043b8SDevin Teske	contbuf = tz
298ab2043b8SDevin Teske	sub("/.*$", "", contbuf)
299ab2043b8SDevin Teske
300ab2043b8SDevin Teske	#
301ab2043b8SDevin Teske	# Validate the continent
302ab2043b8SDevin Teske	#
303ab2043b8SDevin Teske	cont = find_continent(contbuf)
304ab2043b8SDevin Teske	if (!cont)
305ab2043b8SDevin Teske	{
306ab2043b8SDevin Teske		argv[1] = FILENAME
307ab2043b8SDevin Teske		argv[2] = lineno
308ab2043b8SDevin Teske		argv[3] = contbuf
309ab2043b8SDevin Teske		die(ENVIRON["msg_invalid_region"], 3, argv)
310ab2043b8SDevin Teske	}
311ab2043b8SDevin Teske
312ab2043b8SDevin Teske	#
313ab2043b8SDevin Teske	# Get the filename portion of the TZ field
314ab2043b8SDevin Teske	#
315ab2043b8SDevin Teske	filename = tz
316ab2043b8SDevin Teske	sub("^[^/]*/", "", filename)
317ab2043b8SDevin Teske
318ab2043b8SDevin Teske	#
319ab2043b8SDevin Teske	# Calculate the substr start-position of the comment
320ab2043b8SDevin Teske	#
321ab2043b8SDevin Teske	descr_start = 0
322ab2043b8SDevin Teske	n = 4
323ab2043b8SDevin Teske	while (--n)
324ab2043b8SDevin Teske		descr_start += length(line[n]) + 1
325ab2043b8SDevin Teske
326ab2043b8SDevin Teske	# Get the comment field
327ab2043b8SDevin Teske	descr = substr($0, descr_start + 1)
328ab2043b8SDevin Teske
329ab2043b8SDevin Teske	add_zone_to_country(lineno, tlc, descr, filename, cont)
330ab2043b8SDevin Teske}
331ab2043b8SDevin TeskeEND {
332ab2043b8SDevin Teske	if (failed) exit failed
333ab2043b8SDevin Teske	for (tlc in country_nzones)
334ab2043b8SDevin Teske		print_country_code(tlc)
335ab2043b8SDevin Teske}
336ab2043b8SDevin Teske'
337ab2043b8SDevin Teskef_read_zones()
338ab2043b8SDevin Teske{
339ab2043b8SDevin Teske	eval $( awk -v progname="$pgm"   \
340ab2043b8SDevin Teske	            "$f_read_zones_awk"  \
341ab2043b8SDevin Teske	            "$_PATH_ZONETAB"     )
342ab2043b8SDevin Teske}
343ab2043b8SDevin Teske
344ab2043b8SDevin Teske# f_install_zoneinfo_file $filename
345ab2043b8SDevin Teske#
346ab2043b8SDevin Teske# Installs a zone file to _PATH_LOCALTIME.
347ab2043b8SDevin Teske#
348ab2043b8SDevin Teskef_install_zoneinfo_file()
349ab2043b8SDevin Teske{
350ab2043b8SDevin Teske	local zoneinfo_file="$1"
35174036c4dSDevin Teske	local copymode title msg err height width
352ab2043b8SDevin Teske
353ab2043b8SDevin Teske	if [ -L "$_PATH_LOCALTIME" ]; then
354ab2043b8SDevin Teske		copymode=
355ab2043b8SDevin Teske	elif [ ! -e "$_PATH_LOCALTIME" ]; then
356ab2043b8SDevin Teske		# Nothing there yet...
357ab2043b8SDevin Teske		copymode=1
358ab2043b8SDevin Teske	else
359ab2043b8SDevin Teske		copymode=1
360ab2043b8SDevin Teske	fi
361ab2043b8SDevin Teske
362ab2043b8SDevin Teske	if [ "$VERBOSE" ]; then
363ab2043b8SDevin Teske		if [ ! "$zoneinfo_file" ]; then
364ab2043b8SDevin Teske			msg=$( printf "$msg_removing_file" "$_PATH_LOCALTIME" )
365ab2043b8SDevin Teske		elif [ "$copymode" ]; then
366ab2043b8SDevin Teske			msg=$( printf "$msg_copying_file" \
367ab2043b8SDevin Teske			              "$zoneinfo_file" "$_PATH_LOCALTIME" )
368ab2043b8SDevin Teske		else
369ab2043b8SDevin Teske			msg=$( printf "$msg_creating_symlink" \
370ab2043b8SDevin Teske			              "$_PATH_LOCALTIME" "$zoneinfo_file" )
371ab2043b8SDevin Teske		fi
372ab2043b8SDevin Teske		if [ "$USEDIALOG" ]; then
373ab2043b8SDevin Teske			f_dialog_title "$msg_info"
374b4dc08d4SDevin Teske			f_dialog_msgbox "$msg"
375ab2043b8SDevin Teske			f_dialog_title_restore
376ab2043b8SDevin Teske		else
377ab2043b8SDevin Teske			printf "%s\n" "$msg"
378ab2043b8SDevin Teske		fi
379ab2043b8SDevin Teske	fi
380ab2043b8SDevin Teske
3819cd8fcc6SDevin Teske	[ "$REALLYDOIT" ] || return $SUCCESS
3829cd8fcc6SDevin Teske
383ab2043b8SDevin Teske	if [ ! "$zoneinfo_file" ]; then
384ab2043b8SDevin Teske		err=$( rm -f "$_PATH_LOCALTIME" 2>&1 )
385ab2043b8SDevin Teske		if [ "$err" ]; then
386ab2043b8SDevin Teske			if [ "$USEDIALOG" ]; then
387b4dc08d4SDevin Teske				f_dialog_title "$msg_error"
388b4dc08d4SDevin Teske				f_dialog_msgbox "$err"
389b4dc08d4SDevin Teske				f_dialog_title_restore
390ab2043b8SDevin Teske			else
391ab2043b8SDevin Teske				f_err "%s\n" "$err"
392ab2043b8SDevin Teske			fi
393ab2043b8SDevin Teske			return $FAILURE
394ab2043b8SDevin Teske		fi
395ab2043b8SDevin Teske
396ab2043b8SDevin Teske		err=$( rm -f "$_PATH_DB" 2>&1 )
397ab2043b8SDevin Teske		if [ "$err" ]; then
398ab2043b8SDevin Teske			if [ "$USEDIALOG" ]; then
399b4dc08d4SDevin Teske				f_dialog_title "$msg_error"
400b4dc08d4SDevin Teske				f_dialog_msgbox "$err"
401b4dc08d4SDevin Teske				f_dialog_title_restore
402ab2043b8SDevin Teske			else
403ab2043b8SDevin Teske				f_err "%s\n" "$err"
404ab2043b8SDevin Teske			fi
405ab2043b8SDevin Teske			return $FAILURE
406ab2043b8SDevin Teske		fi
407ab2043b8SDevin Teske
408ab2043b8SDevin Teske		if [ "$VERBOSE" ]; then
4099cd8fcc6SDevin Teske			msg=$( printf "$msg_removed_file" "$_PATH_LOCALTIME" )
410ab2043b8SDevin Teske			if [ "$USEDIALOG" ]; then
411b4dc08d4SDevin Teske				f_dialog_title "$msg_done"
412b4dc08d4SDevin Teske				f_dialog_msgbox "$msg"
413b4dc08d4SDevin Teske				f_dialog_title_restore
414ab2043b8SDevin Teske			else
415ab2043b8SDevin Teske				printf "%s\n" "$msg"
416ab2043b8SDevin Teske			fi
417ab2043b8SDevin Teske		fi
418ab2043b8SDevin Teske
419ab2043b8SDevin Teske		return $SUCCESS
420ab2043b8SDevin Teske
421ab2043b8SDevin Teske	fi # ! zoneinfo_file
422ab2043b8SDevin Teske
423ab2043b8SDevin Teske	if [ "$copymode" ]; then
424ab2043b8SDevin Teske
425ab2043b8SDevin Teske		err=$( rm -f "$_PATH_LOCALTIME" 2>&1 )
426ab2043b8SDevin Teske		if [ "$err" ]; then
427ab2043b8SDevin Teske			if [ "$USEDIALOG" ]; then
428b4dc08d4SDevin Teske				f_dialog_title "$msg_error"
429b4dc08d4SDevin Teske				f_dialog_msgbox "$err"
430b4dc08d4SDevin Teske				f_dialog_title_restore
431ab2043b8SDevin Teske			else
432ab2043b8SDevin Teske				f_err "%s\n" "$err"
433ab2043b8SDevin Teske			fi
434ab2043b8SDevin Teske			return $FAILURE
435ab2043b8SDevin Teske		fi
436ab2043b8SDevin Teske
437ab2043b8SDevin Teske		err=$( umask 222 && : 2>&1 > "$_PATH_LOCALTIME" )
438ab2043b8SDevin Teske		if [ "$err" ]; then
439ab2043b8SDevin Teske			if [ "$USEDIALOG" ]; then
440b4dc08d4SDevin Teske				f_dialog_title "$msg_error"
441b4dc08d4SDevin Teske				f_dialog_msgbox "$err"
442b4dc08d4SDevin Teske				f_dialog_title_restore
443ab2043b8SDevin Teske			else
444ab2043b8SDevin Teske				f_err "%s\n" "$err"
445ab2043b8SDevin Teske			fi
446ab2043b8SDevin Teske			return $FAILURE
447ab2043b8SDevin Teske		fi
448ab2043b8SDevin Teske
449ab2043b8SDevin Teske		err=$( cat "$zoneinfo_file" 2>&1 > "$_PATH_LOCALTIME" )
450ab2043b8SDevin Teske		if [ "$err" ]; then
451ab2043b8SDevin Teske			if [ "$USEDIALOG" ]; then
452b4dc08d4SDevin Teske				f_dialog_title "$msg_error"
453b4dc08d4SDevin Teske				f_dialog_msgbox "$err"
454b4dc08d4SDevin Teske				f_dialog_title_restore
455ab2043b8SDevin Teske			else
456ab2043b8SDevin Teske				f_err "%s\n" "$err"
457ab2043b8SDevin Teske			fi
458ab2043b8SDevin Teske			return $FAILURE
459ab2043b8SDevin Teske		fi
460ab2043b8SDevin Teske
461ab2043b8SDevin Teske	else # ! copymode
462ab2043b8SDevin Teske
463ab2043b8SDevin Teske		err=$( ( :< "$zoneinfo_file" ) 2>&1 )
464ab2043b8SDevin Teske		if [ "$err" ]; then
465ab2043b8SDevin Teske			if [ "$USEDIALOG" ]; then
466b4dc08d4SDevin Teske				f_dialog_title "$msg_error"
467b4dc08d4SDevin Teske				f_dialog_msgbox "$err"
468b4dc08d4SDevin Teske				f_dialog_title_restore
469ab2043b8SDevin Teske			else
470ab2043b8SDevin Teske				f_err "%s\n" "$err"
471ab2043b8SDevin Teske			fi
472ab2043b8SDevin Teske			return $FAILURE
473ab2043b8SDevin Teske		fi
474ab2043b8SDevin Teske
475ab2043b8SDevin Teske		err=$( rm -f "$_PATH_LOCALTIME" 2>&1 )
476ab2043b8SDevin Teske		if [ "$err" ]; then
477ab2043b8SDevin Teske			if [ "$USEDIALOG" ]; then
478b4dc08d4SDevin Teske				f_dialog_title "$msg_error"
479b4dc08d4SDevin Teske				f_dialog_msgbox "$err"
480b4dc08d4SDevin Teske				f_dialog_title_restore
481ab2043b8SDevin Teske			else
482ab2043b8SDevin Teske				f_err "%s\n" "$err"
483ab2043b8SDevin Teske			fi
484ab2043b8SDevin Teske			return $FAILURE
485ab2043b8SDevin Teske		fi
486ab2043b8SDevin Teske
487ab2043b8SDevin Teske		err=$( ln -s "$zoneinfo_file" "$_PATH_LOCALTIME" 2>&1 )
488ab2043b8SDevin Teske		if [ "$err" ]; then
489ab2043b8SDevin Teske			if [ "$USEDIALOG" ]; then
490b4dc08d4SDevin Teske				f_dialog_title "$msg_error"
491b4dc08d4SDevin Teske				f_dialog_msgbox "$err"
492b4dc08d4SDevin Teske				f_dialog_title_restore
493ab2043b8SDevin Teske			else
494ab2043b8SDevin Teske				f_err "%s\n" "$err"
495ab2043b8SDevin Teske			fi
496ab2043b8SDevin Teske			return $FAILURE
497ab2043b8SDevin Teske		fi
498ab2043b8SDevin Teske
499ab2043b8SDevin Teske	fi # copymode
500ab2043b8SDevin Teske
501ab2043b8SDevin Teske	if [ "$VERBOSE" ]; then
502ab2043b8SDevin Teske		if [ "$copymode" ]; then
503ab2043b8SDevin Teske			msg=$( printf "$msg_copied_timezone_file" \
5049cd8fcc6SDevin Teske			              "$zoneinfo_file" "$_PATH_LOCALTIME" )
505ab2043b8SDevin Teske		else
506ab2043b8SDevin Teske			msg=$( printf "$msg_created_symlink" \
5079cd8fcc6SDevin Teske			              "$_PATH_LOCALTIME" "$zoneinfo_file" )
508ab2043b8SDevin Teske		fi
509ab2043b8SDevin Teske		if [ "$USEDIALOG" ]; then
510b4dc08d4SDevin Teske			f_dialog_title "$msg_done"
511b4dc08d4SDevin Teske			f_dialog_msgbox "$msg"
512b4dc08d4SDevin Teske			f_dialog_title_restore
513ab2043b8SDevin Teske		else
514ab2043b8SDevin Teske			printf "%s\n" "$msg"
515ab2043b8SDevin Teske		fi
516ab2043b8SDevin Teske	fi
517ab2043b8SDevin Teske
518ab2043b8SDevin Teske	return $SUCCESS
519ab2043b8SDevin Teske}
520ab2043b8SDevin Teske
521ab2043b8SDevin Teske# f_install_zoneinfo $zoneinfo
522ab2043b8SDevin Teske#
523ab2043b8SDevin Teske# Install a zoneinfo file relative to _PATH_ZONEINFO. The given $zoneinfo
524ab2043b8SDevin Teske# will be written to _PATH_DB (usable later with the `-r' flag).
525ab2043b8SDevin Teske#
526ab2043b8SDevin Teskef_install_zoneinfo()
527ab2043b8SDevin Teske{
528ab2043b8SDevin Teske	local zoneinfo="$1"
529ab2043b8SDevin Teske	local rv
530ab2043b8SDevin Teske
531ab2043b8SDevin Teske	f_install_zoneinfo_file "$_PATH_ZONEINFO/$zoneinfo"
532ab2043b8SDevin Teske	rv=$?
533ab2043b8SDevin Teske
534ab2043b8SDevin Teske	# Save knowledge for later
535ab2043b8SDevin Teske	if [ "$REALLYDOIT" -a $rv -eq $SUCCESS ]; then
536437f6520SDevin Teske		if true 2> /dev/null > "$_PATH_DB"; then
537ab2043b8SDevin Teske			cat <<-EOF > "$_PATH_DB"
538ab2043b8SDevin Teske			$zoneinfo
539ab2043b8SDevin Teske			EOF
540ab2043b8SDevin Teske		fi
541ab2043b8SDevin Teske	fi
542ab2043b8SDevin Teske
543ab2043b8SDevin Teske	return $rv
544ab2043b8SDevin Teske}
545ab2043b8SDevin Teske
546ab2043b8SDevin Teske# f_confirm_zone $filename
547ab2043b8SDevin Teske#
548ab2043b8SDevin Teske# Prompt the user to confirm the new timezone data. The first (and only)
549ab2043b8SDevin Teske# argument should be the pathname to the zoneinfo file, either absolute or
550ab2043b8SDevin Teske# relative to `/usr/share/zoneinfo' (e.g., "America/Los_Angeles").
551ab2043b8SDevin Teske#
552ab2043b8SDevin Teske# The return status is 0 if "Yes" is chosen, 1 if "No", and 255 if Esc is
553ab2043b8SDevin Teske# pressed (see dialog(1) for additional details).
554ab2043b8SDevin Teske#
555ab2043b8SDevin Teskef_confirm_zone()
556ab2043b8SDevin Teske{
557ab2043b8SDevin Teske	local filename="$1"
558ab2043b8SDevin Teske	f_dialog_title "$msg_confirmation"
559ab2043b8SDevin Teske	local title="$DIALOG_TITLE" btitle="$DIALOG_BACKTITLE"
560ab2043b8SDevin Teske	f_dialog_title_restore
561ab2043b8SDevin Teske	local tm_zone="$( TZ="$filename" date +%Z )"
562ab2043b8SDevin Teske	local prompt="$( printf "$msg_look_reasonable" "$tm_zone" )"
563ab2043b8SDevin Teske	local height=5 width=72
564ab2043b8SDevin Teske
565ab2043b8SDevin Teske	if [ "$USE_XDIALOG" ]; then
566ab2043b8SDevin Teske		height=$(( $height + 4 ))
567ab2043b8SDevin Teske		$DIALOG \
568ab2043b8SDevin Teske			--title "$title"       \
569ab2043b8SDevin Teske			--backtitle "$btitle"  \
570ab2043b8SDevin Teske			--ok-label "$msg_yes" \
571ab2043b8SDevin Teske			--cancel-label "$msg_no"   \
572ab2043b8SDevin Teske			--yesno "$prompt" $height $width
573ab2043b8SDevin Teske	else
574ab2043b8SDevin Teske		$DIALOG \
575ab2043b8SDevin Teske			--title "$title"       \
576ab2043b8SDevin Teske			--backtitle "$btitle"  \
577ab2043b8SDevin Teske			--yes-label "$msg_yes" \
578ab2043b8SDevin Teske			--no-label "$msg_no"   \
579ab2043b8SDevin Teske			--yesno "$prompt" $height $width
580ab2043b8SDevin Teske	fi
581ab2043b8SDevin Teske}
582ab2043b8SDevin Teske
583ab2043b8SDevin Teske# f_set_zone_utc
584ab2043b8SDevin Teske#
585ab2043b8SDevin Teske# Resets to the UTC timezone.
586ab2043b8SDevin Teske#
587ab2043b8SDevin Teskef_set_zone_utc()
588ab2043b8SDevin Teske{
589ab2043b8SDevin Teske	f_confirm_zone "" || return $FAILURE
590ab2043b8SDevin Teske	f_install_zoneinfo_file ""
591ab2043b8SDevin Teske}
592ab2043b8SDevin Teske
59356961fd7SDevin Teske############################################################ MAIN
59456961fd7SDevin Teske
59556961fd7SDevin Teskef_dprintf "%s: Successfully loaded." timezone/zones.subr
59656961fd7SDevin Teske
597ab2043b8SDevin Teskefi # ! $_TIMEZONE_ZONES_SUBR
598