zones.subr revision 243476
1101099Srwatsonif [ ! "$_TIMEZONE_ZONES_SUBR" ]; then _TIMEZONE_ZONES_SUBR=1
2126097Srwatson#
3140628Srwatson# Copyright (c) 2011-2012 Devin Teske
4101099Srwatson# All Rights Reserved.
5101099Srwatson#
6101099Srwatson# Redistribution and use in source and binary forms, with or without
7101099Srwatson# modification, are permitted provided that the following conditions
8140628Srwatson# are met:
9140628Srwatson# 1. Redistributions of source code must retain the above copyright
10140628Srwatson#    notice, this list of conditions and the following disclaimer.
11140628Srwatson# 2. Redistributions in binary form must reproduce the above copyright
12101099Srwatson#    notice, this list of conditions and the following disclaimer in the
13101099Srwatson#    documentation and/or other materials provided with the distribution.
14101099Srwatson#
15101099Srwatson# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16101099Srwatson# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, THE
17101099Srwatson# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18101099Srwatson# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19101099Srwatson# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20101099Srwatson# DAMAGES (INLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21101099Srwatson# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22101099Srwatson# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23101099Srwatson# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24101099Srwatson# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25101099Srwatson# SUCH DAMAGE.
26101099Srwatson#
27101099Srwatson# $FreeBSD: head/usr.sbin/bsdconfig/timezone/share/zones.subr 243476 2012-11-24 07:02:31Z dteske $
28101099Srwatson#
29101099Srwatson############################################################ INCLUDES
30101099Srwatson
31101099SrwatsonBSDCFG_SHARE="/usr/share/bsdconfig"
32101099Srwatson. $BSDCFG_SHARE/common.subr || exit 1
33101099Srwatsonf_include $BSDCFG_SHARE/dialog.subr
34101099Srwatsonf_include $BSDCFG_SHARE/timezone/continents.subr
35101099Srwatson
36101099SrwatsonBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="090.timezone"
37101099Srwatsonf_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
38101099Srwatson
39101099Srwatson############################################################ CONFIGURATION
40101099Srwatson
41101099Srwatson#
42101099Srwatson# Standard pathnames
43101099Srwatson#
44101099Srwatson_PATH_ZONETAB="/usr/share/zoneinfo/zone.tab"
45101099Srwatson_PATH_ZONEINFO="/usr/share/zoneinfo"
46105988Srwatson_PATH_LOCALTIME="/etc/localtime"
47101099Srwatson_PATH_DB="/var/db/zoneinfo"
48101099Srwatson
49103183Sbde#
50145076Scsjp# Export required i18n messages for awk(1) ENVIRON visibility
51101099Srwatson#
52101099Srwatsonexport msg_conflicting_zone_definition
53115497Srwatsonexport msg_country_code_invalid
54101099Srwatsonexport msg_country_code_unknown
55101099Srwatsonexport msg_invalid_country_code
56101099Srwatsonexport msg_invalid_format
57105696Srwatsonexport msg_invalid_region
58101099Srwatsonexport msg_invalid_zone_name
59101099Srwatsonexport msg_zone_multiply_defined
60101099Srwatsonexport msg_zone_must_have_description
61101099Srwatson
62101099Srwatson############################################################ FUNCTIONS
63101099Srwatson
64140628Srwatson# f_read_zones
65140628Srwatson#
66140628Srwatson# Read the zone descriptions database in _PATH_ZONETAB:
67101099Srwatson# 	/usr/share/zoneinfo/zone.tab on all OSes
68145855Srwatson#
69145855Srwatson# The format of this file (on all OSes) is:
70101099Srwatson# 	code	coordinates	TZ	comments
71101099Srwatson#
72101099Srwatson# With each of the following elements (described below) being separated by a
73101099Srwatson# single tab character:
74101099Srwatson#
75101099Srwatson# 	code
76101099Srwatson# 		The ISO 3166 2-character country code.
77101099Srwatson# 	coordinates
78122875Srwatson# 		Latitude and logitude of the zone's principal location in ISO
79101099Srwatson# 		6709 sign-degrees-minutes-seconds format, either +-DDMM+-DDDMM
80101099Srwatson# 		or +-DDMMSS+-DDDMMSS, first latitude (+ is north), then long-
81122879Srwatson# 		itude (+ is east).
82101099Srwatson# 	TZ
83101099Srwatson# 		Zone name used in value of TZ environment variable.
84101099Srwatson# 	comments
85101099Srwatson# 		Comments; present if and only if the country has multiple rows.
86101099Srwatson#
87101099Srwatson# Required variables [from continents.subr]:
88101099Srwatson#
89101099Srwatson# 	CONTINENTS
90101099Srwatson# 		Space-separated list of continents.
91101099Srwatson# 	continent_*_name
92101099Srwatson# 		Directory element in _PATH_ZONEINFO for the continent
93105988Srwatson# 		represented by *.
94105988Srwatson#
95105988Srwatson# Required variables [created by f_read_iso3166_table from iso3166.subr]:
96105988Srwatson#
97107731Srwatson# 	country_CODE_name
98101099Srwatson# 		Country name of the country represented by CODE, the 2-
99101099Srwatson# 		character country code.
100102980Srwatson#
101101099Srwatson# Variables created by this function:
102101099Srwatson#
103101099Srwatson# 	country_CODE_nzones
104101099Srwatson# 		Either set to `-1' to indicate that the 2-character country
105101099Srwatson# 		code has only a single zone associated with it (and therefore
106101099Srwatson# 		you should query the `country_CODE_*' environment variables),
107101099Srwatson# 		or set to `0' or higher to indicate how many zones are assoc-
108101099Srwatson# 		iated with the given country code. When multiple zones are
109101099Srwatson# 		configured for a single code, you should instead query the
110101099Srwatson# 		`country_CODE_*_N' environment variables (e.g., `echo
111101099Srwatson# 		$country_AQ_descr_1' prints the description of the first
112101099Srwatson# 		timezone in Antarctica).
113101099Srwatson# 	country_CODE_filename
114101099Srwatson# 		The ``filename'' portion of the TZ value that appears after the
115101099Srwatson# 		`/' (e.g., `Hong_Kong' from `Asia/Hong_Kong' or `Isle_of_Man'
116101099Srwatson# 		from `Europe/Isle_of_Man').
117105643Srwatson# 	country_CODE_cont
118105643Srwatson# 		The ``continent'' portion of the TZ value that appears before
119105643Srwatson# 		the `/' (e.g., `Asia' from `Asia/Hong_Kong' or `Europe' from
120105643Srwatson# 		`Europe/Isle_of_Man').
121105606Srwatson# 	country_CODE_descr
122105606Srwatson# 		The comments associated with the ISO 3166 code entry (if any).
123105606Srwatson#
124105606Srwatson# 	NOTE: CODE is the 2-character country code.
125105606Srwatson# 	
126105637Srwatson# This function is a two-parter. Below is the awk(1) portion of the function,
127101099Srwatson# afterward is the sh(1) function which utilizes the below awk script.
128105637Srwatson#
129105637Srwatsonf_read_zones_awk='
130101099Srwatson# Variables that should be defined on the invocation line:
131101099Srwatson# 	-v progname="progname"
132101099Srwatson#
133132781SkanBEGIN {
134101099Srwatson	lineno = 0
135122879Srwatson	failed = 0
136101099Srwatson
137105643Srwatson	#
138105643Srwatson	# Initialize continents array/map (name => id)
139105643Srwatson	#
140105643Srwatson	split(ENVIRON["CONTINENTS"], array, /[[:space:]]+/)
141105643Srwatson	for (item in array)
142105643Srwatson	{
143105643Srwatson		cont = array[item]
144105643Srwatson		if (!cont) continue
145105643Srwatson		name = ENVIRON["continent_" cont "_name"]
146105643Srwatson		continents[name] = cont
147101099Srwatson	}
148104514Srwatson}
149101099Srwatsonfunction die(fmt, argc, argv)
150101099Srwatson{
151122879Srwatson	printf "f_die 1 \"%%s: %s\" \"%s\"", fmt, progname
152101099Srwatson	for (n = 1; n <= argc; n++)
153101099Srwatson		printf " \"%s\"", argv[n]
154101099Srwatson	print ""
155101099Srwatson	failed++
156101099Srwatson	exit 1
157101099Srwatson}
158101099Srwatsonfunction find_continent(name)
159122879Srwatson{
160101099Srwatson	return continents[name]
161101099Srwatson}
162101099Srwatsonfunction add_zone_to_country(lineno, tlc, descr, file, cont)
163101099Srwatson{
164101099Srwatson	#
165105634Srwatson	# Validate the two-character country code
166105634Srwatson	#
167105634Srwatson	if (!match(tlc, /^[A-Z][A-Z]$/))
168105634Srwatson	{
169105634Srwatson		argv[1] = FILENAME
170105634Srwatson		argv[2] = lineno
171105634Srwatson		argv[3] = tlc
172105634Srwatson		die(ENVRION["msg_country_code_invalid"], 3, argv)
173105634Srwatson	}
174101099Srwatson	if (!ENVIRON["country_" tlc "_name"])
175101099Srwatson	{
176101099Srwatson		argv[1] = FILENAME
177105643Srwatson		argv[2] = lineno
178101099Srwatson		argv[3] = tlc
179105736Srwatson		die(ENVIRON["msg_country_code_unknown"], 3, argv)
180101099Srwatson	}
181101099Srwatson
182101099Srwatson	#
183101099Srwatson	# Add Zone to an array that we will parse at the end
184101099Srwatson	#
185101099Srwatson	if (length(descr) > 0)
186101099Srwatson	{
187101099Srwatson		if (country_nzones[tlc] < 0)
188101099Srwatson		{
189101099Srwatson			argv[1] = FILENAME
190101099Srwatson			argv[2] = lineno
191101099Srwatson			die(ENVIRON["msg_conflicting_zone_definition"], 2, argv)
192101099Srwatson		}
193101099Srwatson
194101099Srwatson		n = ++country_nzones[tlc]
195101099Srwatson		country_cont[tlc,n] = cont
196101099Srwatson		country_filename[tlc,n] = file
197101099Srwatson		country_descr[tlc,n] = descr
198101099Srwatson	}
199101099Srwatson	else
200101099Srwatson	{
201101099Srwatson		if (country_nzones[tlc] > 0)
202101099Srwatson		{
203101099Srwatson			argv[1] = FILENAME
204101099Srwatson			argv[2] = lineno
205101099Srwatson			die(ENVIRON["msg_zone_must_have_description"], 2, argv)
206101099Srwatson		}
207101099Srwatson		if (country_nzones[tlc] < 0)
208105643Srwatson		{
209105643Srwatson			argv[1] = FILENAME
210105643Srwatson			argv[2] = lineno
211105643Srwatson			die(ENVIRON["msg_zone_multiply_defined"], 2, argv)
212105643Srwatson		}
213101099Srwatson
214101099Srwatson		country_nzones[tlc] = -1
215101099Srwatson		country_cont[tlc] = cont
216101099Srwatson		country_filename[tlc] = file
217101099Srwatson	}
218101099Srwatson}
219101099Srwatsonfunction print_country_code(tlc)
220101099Srwatson{
221101099Srwatson	nz = country_nzones[tlc]
222101099Srwatson
223101099Srwatson	printf "country_%s_nzones=%d\n", tlc, nz
224101099Srwatson	printf "export country_%s_nzones\n", tlc
225101099Srwatson
226101099Srwatson	if (nz < 0)
227105988Srwatson	{
228105988Srwatson		printf "country_%s_cont=\"%s\"\n", tlc, country_cont[tlc]
229105988Srwatson		printf "export country_%s_cont\n", tlc
230105988Srwatson		printf "country_%s_filename=\"%s\"\n",
231132232Srwatson		       tlc, country_filename[tlc]
232132232Srwatson	}
233132232Srwatson	else
234105988Srwatson	{
235105988Srwatson		n = 0
236105988Srwatson		while ( ++n <= nz )
237105988Srwatson		{
238105988Srwatson			printf "country_%s_cont_%d=\"%s\"\n",
239105988Srwatson			       tlc, n, country_cont[tlc,n]
240101099Srwatson			printf "export country_%s_cont_%d\n", tlc, n
241101099Srwatson			printf "country_%s_filename_%d=\"%s\"\n",
242101099Srwatson			       tlc, n, country_filename[tlc,n]
243101099Srwatson			printf "country_%s_descr_%d=\"%s\"\n",
244101099Srwatson			       tlc, n, country_descr[tlc,n]
245101099Srwatson		}
246101099Srwatson	}
247101099Srwatson}
248101099Srwatson/^#/ {
249101099Srwatson	lineno++
250136774Srwatson	next
251136774Srwatson}
252101099Srwatson!/^#/ {
253101099Srwatson	lineno++
254132232Srwatson
255132232Srwatson	#
256103750Srwatson	# Split the current record (on TAB) into an array
257132232Srwatson	#
258101099Srwatson	if (split($0, line, /\t/) < 2)
259101099Srwatson	{
260132232Srwatson		argv[1] = FILENAME
261132232Srwatson		argv[2] = lineno
262101099Srwatson		die(ENVIRON["msg_invalid_format"], 2, argv)
263101099Srwatson	}
264101099Srwatson
265101099Srwatson	# Get the ISO3166-1 (Alpha 1) 2-letter country code
266101099Srwatson	tlc = line[1]
267101099Srwatson
268132232Srwatson	#
269101099Srwatson	# Validate the two-character country code
270132232Srwatson	#
271132232Srwatson	if (length(tlc) != 2)
272132232Srwatson	{
273132232Srwatson		argv[1] = FILENAME
274101099Srwatson		argv[2] = lineno
275132232Srwatson		argv[3] = tlc
276101099Srwatson		die(ENVIRON["msg_invalid_country_code"], 3, argv)
277101099Srwatson	}
278101099Srwatson
279101099Srwatson	# Get the TZ field
280101099Srwatson	tz = line[3]
281101099Srwatson
282101099Srwatson	#
283101099Srwatson	# Validate the TZ field
284101099Srwatson	#
285101099Srwatson	if (!match(tz, "/"))
286101099Srwatson	{
287101099Srwatson		argv[1] = FILENAME
288101099Srwatson		argv[2] = lineno
289101099Srwatson		argv[3] = tz
290132232Srwatson		die(ENVIRON["msg_invalid_zone_name"], 3, argv)
291101099Srwatson	}
292101099Srwatson
293132232Srwatson	#
294132232Srwatson	# Get the continent portion of the TZ field
295132232Srwatson	#
296132232Srwatson	contbuf = tz
297101099Srwatson	sub("/.*$", "", contbuf)
298132232Srwatson
299101099Srwatson	#
300101099Srwatson	# Validate the continent
301101099Srwatson	#
302105634Srwatson	cont = find_continent(contbuf)
303105634Srwatson	if (!cont)
304105634Srwatson	{
305132232Srwatson		argv[1] = FILENAME
306132232Srwatson		argv[2] = lineno
307105634Srwatson		argv[3] = contbuf
308105634Srwatson		die(ENVIRON["msg_invalid_region"], 3, argv)
309105634Srwatson	}
310105634Srwatson
311105634Srwatson	#
312105634Srwatson	# Get the filename portion of the TZ field
313105637Srwatson	#
314105634Srwatson	filename = tz
315105634Srwatson	sub("^[^/]*/", "", filename)
316105634Srwatson
317105634Srwatson	#
318105634Srwatson	# Calculate the substr start-position of the comment
319105634Srwatson	#
320106090Srwatson	descr_start = 0
321105634Srwatson	n = 4
322105634Srwatson	while (--n)
323105634Srwatson		descr_start += length(line[n]) + 1
324105634Srwatson
325106090Srwatson	# Get the comment field
326105634Srwatson	descr = substr($0, descr_start + 1)
327132232Srwatson
328132232Srwatson	add_zone_to_country(lineno, tlc, descr, filename, cont)
329105634Srwatson}
330105634SrwatsonEND {
331105634Srwatson	if (failed) exit failed
332105634Srwatson	for (tlc in country_nzones)
333105634Srwatson		print_country_code(tlc)
334105634Srwatson}
335105634Srwatson'
336105634Srwatsonf_read_zones()
337105634Srwatson{
338105634Srwatson	eval $( awk -v progname="$pgm"   \
339105634Srwatson	            "$f_read_zones_awk"  \
340105634Srwatson	            "$_PATH_ZONETAB"     )
341105634Srwatson}
342105634Srwatson
343105634Srwatson# f_install_zoneinfo_file $filename
344105634Srwatson#
345106091Srwatson# Installs a zone file to _PATH_LOCALTIME.
346132232Srwatson#
347105988Srwatsonf_install_zoneinfo_file()
348105988Srwatson{
349132232Srwatson	local zoneinfo_file="$1"
350132232Srwatson	local copymode title msg err size
351105988Srwatson
352132232Srwatson	if [ -L "$_PATH_LOCALTIME" ]; then
353105988Srwatson		copymode=
354105988Srwatson	elif [ ! -e "$_PATH_LOCALTIME" ]; then
355105634Srwatson		# Nothing there yet...
356101099Srwatson		copymode=1
357101099Srwatson	else
358101099Srwatson		copymode=1
359132232Srwatson	fi
360132232Srwatson
361101099Srwatson	if [ "$VERBOSE" ]; then
362101099Srwatson		if [ ! "$zoneinfo_file" ]; then
363101099Srwatson			msg=$( printf "$msg_removing_file" "$_PATH_LOCALTIME" )
364101099Srwatson		elif [ "$copymode" ]; then
365101099Srwatson			msg=$( printf "$msg_copying_file" \
366101099Srwatson			              "$zoneinfo_file" "$_PATH_LOCALTIME" )
367132232Srwatson		else
368105643Srwatson			msg=$( printf "$msg_creating_symlink" \
369132232Srwatson			              "$_PATH_LOCALTIME" "$zoneinfo_file" )
370101099Srwatson		fi
371101099Srwatson		if [ "$USEDIALOG" ]; then
372101099Srwatson			f_dialog_title "$msg_info"
373101099Srwatson			title="$DIALOG_TITLE"
374101099Srwatson			btitle="$DIALOG_BACKTITLE"
375101099Srwatson			f_dialog_title_restore
376101099Srwatson			size=$( f_dialog_buttonbox_size "$title" \
377132232Srwatson			        	"$btitle" "$msg" )
378101099Srwatson			eval $DIALOG \
379101099Srwatson				--title \"\$title\"      \
380101099Srwatson				--backtitle \"\$btitle\" \
381101099Srwatson				--ok-label \"\$msg_ok\"  \
382101099Srwatson				--msgbox \"\$msg\" $size
383101099Srwatson		else
384101099Srwatson			printf "%s\n" "$msg"
385101099Srwatson		fi
386101099Srwatson	fi
387101099Srwatson
388101099Srwatson	if [ "$REALLYDOIT" ]; then
389105643Srwatson		f_dialog_title "$msg_error"
390105643Srwatson		title="$DIALOG_TITLE"
391105643Srwatson		btitle="$DIALOG_BACKTITLE"
392101099Srwatson		f_dialog_title_restore
393101099Srwatson
394101099Srwatson		if [ ! "$zoneinfo_file" ]; then
395101099Srwatson
396101099Srwatson			err=$( rm -f "$_PATH_LOCALTIME" 2>&1 )
397101099Srwatson			if [ "$err" ]; then
398101099Srwatson				if [ "$USEDIALOG" ]; then
399101099Srwatson					size=$( f_dialog_buttonbox_size \
400101099Srwatson					        	"$title"  \
401101099Srwatson					        	"$btitle" \
402101099Srwatson					        	"$err" )
403101099Srwatson					eval $DIALOG \
404101099Srwatson						--title \"\$title\"      \
405101099Srwatson						--backtitle \"\$btitle\" \
406105643Srwatson						--ok-label \"\$msg_ok\"  \
407105643Srwatson						--msgbox \"\$err\" $size
408105643Srwatson				else
409101099Srwatson					f_err "%s\n" "$err"
410101099Srwatson				fi
411101099Srwatson				return $FAILURE
412101099Srwatson			fi
413101099Srwatson
414101099Srwatson			err=$( rm -f "$_PATH_DB" 2>&1 )
415101099Srwatson			if [ "$err" ]; then
416101099Srwatson				if [ "$USEDIALOG" ]; then
417101099Srwatson					size=$( f_dialog_buttonbox_size \
418101099Srwatson					        	"$title"  \
419101099Srwatson					        	"$btitle" \
420101099Srwatson					        	"$err" )
421101099Srwatson					eval $DIALOG \
422101099Srwatson						--title \"\$title\"      \
423101099Srwatson						--backtitle \"\$btitle\" \
424101099Srwatson						--ok-label \"\$msg_ok\"  \
425101099Srwatson						--msgbox \"\$err\" $size
426101099Srwatson				else
427101099Srwatson					f_err "%s\n" "$err"
428101099Srwatson				fi
429105643Srwatson				return $FAILURE
430105643Srwatson			fi
431101099Srwatson
432101099Srwatson			if [ "$VERBOSE" ]; then
433101099Srwatson				title="$msg_done"
434101099Srwatson				msg=$( printf "$msg_removed_file" \
435105643Srwatson				              "$_PATH_LOCALTIME" )
436105643Srwatson				if [ "$USEDIALOG" ]; then
437105643Srwatson					size=$( f_dialog_buttonbox_size \
438105643Srwatson					        	"$title"  \
439101099Srwatson					        	"$btitle" \
440101099Srwatson					        	"$msg" )
441105643Srwatson					eval $DIALOG \
442105643Srwatson						--title \"\$title\"      \
443105643Srwatson						--backtitle \"\$btitle\" \
444105643Srwatson						--ok-label \"\$msg_ok\"  \
445101099Srwatson						--msgbox \"\$msg\" $size
446101099Srwatson				else
447101099Srwatson					printf "%s\n" "$msg"
448101099Srwatson				fi
449132232Srwatson			fi
450105643Srwatson
451101099Srwatson			return $SUCCESS
452101099Srwatson
453132232Srwatson		fi # ! zoneinfo_file
454132232Srwatson
455105643Srwatson		if [ "$copymode" ]; then
456132232Srwatson
457132232Srwatson			err=$( rm -f "$_PATH_LOCALTIME" 2>&1 )
458132232Srwatson			if [ "$err" ]; then
459101099Srwatson				if [ "$USEDIALOG" ]; then
460101099Srwatson					size=$( f_dialog_buttonbox_size \
461101099Srwatson					        	"$title"  \
462101099Srwatson					        	"$btitle" \
463101099Srwatson					        	"$err" )
464105643Srwatson					eval $DIALOG \
465101099Srwatson						--title \"\$title\"     \
466101099Srwatson						--backtitle \"\$btitle\" \
467101099Srwatson						--ok-label \"\$msg_ok\"  \
468101099Srwatson						--msgbox \"\$err\" $size
469101099Srwatson				else
470101099Srwatson					f_err "%s\n" "$err"
471101099Srwatson				fi
472101099Srwatson				return $FAILURE
473101099Srwatson			fi
474132232Srwatson
475101099Srwatson			err=$( umask 222 && : 2>&1 > "$_PATH_LOCALTIME" )
476101099Srwatson			if [ "$err" ]; then
477132232Srwatson				if [ "$USEDIALOG" ]; then
478132232Srwatson					size=$( f_dialog_buttonbox_size \
479101099Srwatson					        	"$title"  \
480132232Srwatson					        	"$btitle" \
481132232Srwatson					        	"$err" )
482101099Srwatson					eval $DIALOG \
483101099Srwatson						--title \"\$title\"      \
484105656Srwatson						--backtitle \"\$btitle\" \
485105656Srwatson						--ok-label \"\$msg_ok\"  \
486105656Srwatson						--msgbox \"\$err\" $size
487105656Srwatson				else
488132232Srwatson					f_err "%s\n" "$err"
489132232Srwatson				fi
490105656Srwatson				return $FAILURE
491105656Srwatson			fi
492105656Srwatson
493105656Srwatson			err=$( cat "$zoneinfo_file" 2>&1 > "$_PATH_LOCALTIME" )
494101099Srwatson			if [ "$err" ]; then
495101099Srwatson				if [ "$USEDIALOG" ]; then
496101099Srwatson					size=$( f_dialog_buttonbox_size \
497101099Srwatson					        	"$title"  \
498101099Srwatson					        	"$btitle" \
499101099Srwatson					        	"$err" )
500101099Srwatson					eval $DIALOG \
501122879Srwatson						--title \"\$title\"      \
502122879Srwatson						--backtitle \"\$btitle\" \
503101099Srwatson						--ok-label \"\$msg_ok\"  \
504101099Srwatson						--msgbox \"\$err\" $size
505101099Srwatson				else
506101099Srwatson					f_err "%s\n" "$err"
507101099Srwatson				fi
508101099Srwatson				return $FAILURE
509104514Srwatson			fi
510101099Srwatson
511101099Srwatson		else # ! copymode
512132781Skan
513101099Srwatson			err=$( ( :< "$zoneinfo_file" ) 2>&1 )
514101099Srwatson			if [ "$err" ]; then
515101099Srwatson				if [ "$USEDIALOG" ]; then
516104514Srwatson					size=$( f_dialog_buttonbox_size \
517101099Srwatson					        	"$title"  \
518101099Srwatson					        	"$btitle" \
519132781Skan					        	"$err" )
520101099Srwatson					eval $DIALOG \
521101099Srwatson						--title \"\$title\"      \
522101099Srwatson						--backtitle \"\$btitle\" \
523101099Srwatson						--ok-label \"\$msg_ok\"  \
524101099Srwatson						--msgbox \"\$err\" $size
525101099Srwatson				else
526101099Srwatson					f_err "%s\n" "$err"
527104514Srwatson				fi
528101099Srwatson				return $FAILURE
529101099Srwatson			fi
530101099Srwatson
531132781Skan			err=$( rm -f "$_PATH_LOCALTIME" 2>&1 )
532101099Srwatson			if [ "$err" ]; then
533101099Srwatson				if [ "$USEDIALOG" ]; then
534105696Srwatson					size=$( f_dialog_buttonbox_size \
535115497Srwatson					        	"$title"  \
536115497Srwatson					        	"$btitle" \
537115497Srwatson					        	"$err" )
538105696Srwatson					eval $DIALOG \
539115497Srwatson						--title \"\$title\"      \
540115497Srwatson						--backtitle \"\$btitle\" \
541105696Srwatson						--ok-label \"\$msg_ok\"  \
542115497Srwatson						--msgbox \"\$err\" $size
543105696Srwatson				else
544105696Srwatson					f_err "%s\n" "$err"
545105696Srwatson				fi
546115497Srwatson				return $FAILURE
547105696Srwatson			fi
548105696Srwatson
549115497Srwatson			err=$( ln -s "$zoneinfo_file" "$_PATH_LOCALTIME" 2>&1 )
550105696Srwatson			if [ "$err" ]; then
551105696Srwatson				if [ "$USEDIALOG" ]; then
552115497Srwatson					size=$( f_dialog_buttonbox_size \
553105696Srwatson					        	"$title"  \
554105696Srwatson					        	"$btitle" \
555115497Srwatson					        	"$err" )
556115497Srwatson					eval $DIALOG \
557115497Srwatson						--title \"\$title\"      \
558115497Srwatson						--backtitle \"\$btitle\" \
559115497Srwatson						--ok-label \"\$msg_ok\"  \
560115497Srwatson						--msgbox \"\$err\" $size
561115497Srwatson				else
562115497Srwatson					f_err "%s\n" "$err"
563115497Srwatson				fi
564115497Srwatson				return $FAILURE
565115497Srwatson			fi
566115497Srwatson
567115497Srwatson		fi # copymode
568115497Srwatson
569115497Srwatson		if [ "$VERBOSE" ]; then
570115497Srwatson			title="$msg_done"
571115497Srwatson			if [ "$copymode" ]; then
572105696Srwatson				msg=$( printf "$msg_copied_timezone_file" \
573115497Srwatson				              "$zoneinfo_file" \
574105696Srwatson				              "$_PATH_LOCALTIME" )
575105696Srwatson			else
576105696Srwatson				msg=$( printf "$msg_created_symlink" \
577105696Srwatson				              "$_PATH_LOCALTIME" \
578105696Srwatson				              "$zoneinfo_file" )
579105696Srwatson			fi
580105696Srwatson			if [ "$USEDIALOG" ]; then
581115497Srwatson				size=$( f_dialog_buttonbox_size \
582116701Srwatson				        	"$title" "$btitle" "$msg" )
583116701Srwatson				eval $DIALOG \
584116701Srwatson					--title \"\$title\"      \
585116701Srwatson					--backtitle \"\$btitle\" \
586116701Srwatson					--ok-label \"\$msg_ok\"  \
587115497Srwatson					--msgbox \"\$msg\" $size
588101099Srwatson			else
589116701Srwatson				printf "%s\n" "$msg"
590101099Srwatson			fi
591105696Srwatson		fi
592132232Srwatson
593132232Srwatson	fi # REALLYDOIT
594115497Srwatson
595105696Srwatson	return $SUCCESS
596105696Srwatson}
597105696Srwatson
598105696Srwatson# f_install_zoneinfo $zoneinfo
599116701Srwatson#
600105696Srwatson# Install a zoneinfo file relative to _PATH_ZONEINFO. The given $zoneinfo
601105696Srwatson# will be written to _PATH_DB (usable later with the `-r' flag).
602116701Srwatson#
603115497Srwatsonf_install_zoneinfo()
604105696Srwatson{
605105696Srwatson	local zoneinfo="$1"
606116701Srwatson	local rv
607105696Srwatson
608105696Srwatson	f_install_zoneinfo_file "$_PATH_ZONEINFO/$zoneinfo"
609116701Srwatson	rv=$?
610115497Srwatson
611105696Srwatson	# Save knowledge for later
612105696Srwatson	if [ "$REALLYDOIT" -a $rv -eq $SUCCESS ]; then
613116701Srwatson		if true 2> /dev/null > "$_PATH_DB"; then
614105696Srwatson			cat <<-EOF > "$_PATH_DB"
615105696Srwatson			$zoneinfo
616105696Srwatson			EOF
617105696Srwatson		fi
618105696Srwatson	fi
619105696Srwatson
620105696Srwatson	return $rv
621105696Srwatson}
622116701Srwatson
623105696Srwatson# f_confirm_zone $filename
624101099Srwatson#
625101099Srwatson# Prompt the user to confirm the new timezone data. The first (and only)
626105696Srwatson# argument should be the pathname to the zoneinfo file, either absolute or
627105696Srwatson# relative to `/usr/share/zoneinfo' (e.g., "America/Los_Angeles").
628105696Srwatson#
629105696Srwatson# The return status is 0 if "Yes" is chosen, 1 if "No", and 255 if Esc is
630105696Srwatson# pressed (see dialog(1) for additional details).
631101099Srwatson# 
632116701Srwatsonf_confirm_zone()
633105696Srwatson{
634105696Srwatson	local filename="$1"
635105696Srwatson	f_dialog_title "$msg_confirmation"
636105696Srwatson	local title="$DIALOG_TITLE" btitle="$DIALOG_BACKTITLE"
637101099Srwatson	f_dialog_title_restore
638115395Srwatson	local tm_zone="$( TZ="$filename" date +%Z )"
639115395Srwatson	local prompt="$( printf "$msg_look_reasonable" "$tm_zone" )"
640105696Srwatson	local height=5 width=72
641105696Srwatson
642105696Srwatson	if [ "$USE_XDIALOG" ]; then
643105696Srwatson		height=$(( $height + 4 ))
644105696Srwatson		$DIALOG \
645105696Srwatson			--title "$title"       \
646105696Srwatson			--backtitle "$btitle"  \
647105696Srwatson			--ok-label "$msg_yes" \
648105696Srwatson			--cancel-label "$msg_no"   \
649105696Srwatson			--yesno "$prompt" $height $width
650105696Srwatson	else
651105696Srwatson		$DIALOG \
652105696Srwatson			--title "$title"       \
653105696Srwatson			--backtitle "$btitle"  \
654115395Srwatson			--yes-label "$msg_yes" \
655105696Srwatson			--no-label "$msg_no"   \
656115395Srwatson			--yesno "$prompt" $height $width
657115395Srwatson	fi
658115395Srwatson}
659115395Srwatson
660115395Srwatson# f_set_zone_utc
661115395Srwatson#
662105696Srwatson# Resets to the UTC timezone.
663115395Srwatson#
664115395Srwatsonf_set_zone_utc()
665115395Srwatson{
666105696Srwatson	f_confirm_zone "" || return $FAILURE
667115395Srwatson	f_install_zoneinfo_file ""
668115395Srwatson}
669115395Srwatson
670115395Srwatsonfi # ! $_TIMEZONE_ZONES_SUBR
671115395Srwatson