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