3 # Copyright (c) 2011-2015 Devin Teske
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
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.
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 (INCLUDING, 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
29 ############################################################ INCLUDES
31 BSDCFG_SHARE="/usr/share/bsdconfig"
32 . $BSDCFG_SHARE/common.subr || exit 1
33 f_dprintf "%s: loading includes..." "$0"
34 f_include $BSDCFG_SHARE/dialog.subr
35 f_include $BSDCFG_SHARE/mustberoot.subr
36 f_include $BSDCFG_SHARE/strings.subr
37 f_include $BSDCFG_SHARE/timezone/continents.subr
38 f_include $BSDCFG_SHARE/timezone/countries.subr
39 f_include $BSDCFG_SHARE/timezone/iso3166.subr
40 f_include $BSDCFG_SHARE/timezone/menus.subr
41 f_include $BSDCFG_SHARE/timezone/zones.subr
43 BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="090.timezone"
44 f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
46 f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm &&
49 ############################################################ CONFIGURATION
54 _PATH_DB="/var/db/zoneinfo"
55 _PATH_WALL_CMOS_CLOCK="/etc/wall_cmos_clock"
57 ############################################################ GLOBALS
71 # Dummy vars (populated dynamically)
73 COUNTRIES= # list of 2-character country codes created by f_read_iso3166_table
75 ############################################################ FUNCTIONS
79 # Display the dialog(1)-based application main menu.
83 local title="$DIALOG_TITLE"
84 local btitle="$DIALOG_BACKTITLE"
85 local prompt="$msg_select_region"
86 local defaultitem= # Calculated below
89 local height width rows
90 eval f_dialog_menu_size height width rows \
97 # Obtain default-item from previously stored selection
98 f_dialog_default_fetch defaultitem
101 menu_choice=$( eval $DIALOG \
102 --title \"\$title\" \
103 --backtitle \"\$btitle\" \
104 --hline \"\$hline\" \
105 --ok-label \"\$msg_ok\" \
106 --cancel-label \"\$msg_cancel\" \
107 --default-item \"\$defaultitem\" \
108 --menu \"\$prompt\" \
109 $height $width $rows \
110 $continent_menu_list \
111 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
114 f_dialog_data_sanitize menu_choice
115 f_dialog_menutag_store "$menu_choice"
116 f_dialog_default_store "$menu_choice"
120 ############################################################ MAIN
122 # Skip initial question regarding UTC v. Wall-Clock time if run in VM
123 [ "$( sysctl -n kern.vm_guest 2> /dev/null )" = "none" ] || SKIPUTC=1
125 # Incorporate rc-file if it exists
126 [ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc"
129 # Process command-line arguments
131 while getopts C:ehnrsv$GETOPTS_STDARGS flag; do
133 C) CHROOTENV="$OPTARG" ;;
140 h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;;
143 shift $(( $OPTIND - 1 ))
148 f_dialog_title "$msg_time_zone"
149 f_dialog_backtitle "${ipgm:+bsdconfig }$pgm"
153 # Process `-C chroot_directory' command-line argument
155 if [ "$CHROOTENV" ]; then
156 _PATH_ZONETAB="$CHROOTENV$_PATH_ZONETAB"
157 _PATH_ISO3166="$CHROOTENV$_PATH_ISO3166"
158 _PATH_ZONEINFO="$CHROOTENV$_PATH_ZONEINFO"
159 _PATH_LOCALTIME="$CHROOTENV$_PATH_LOCALTIME"
160 _PATH_DB="$CHROOTENV$_PATH_DB"
161 _PATH_WALL_CMOS_CLOCK="$CHROOTENV$_PATH_WALL_CMOS_CLOCK"
165 # Process `-r' command-line option
167 if [ "$REINSTALL" ]; then
168 [ -f "$_PATH_DB" -a -r "$_PATH_DB" ] ||
169 f_die 1 "$msg_cannot_open_for_reading" "$_PATH_DB"
170 f_eval_catch -dk zoneinfo "$0" cat 'cat "%s"' "$_PATH_DB" ||
171 f_die 1 "$msg_error_reading" "$_PATH_DB"
173 f_die 1 "$msg_unable_to_determine_name_from_db" "$_PATH_DB"
174 f_install_zoneinfo "$zoneinfo"
179 # If the arguments on the command-line do not specify a file,
180 # then interpret it as a zoneinfo name
182 if [ $# -ge 1 ]; then
185 if [ ! -f "$zoneinfo" ]; then
187 f_install_zoneinfo "$zoneinfo"
195 # Process the UTC option
197 if [ "$_PATH_WALL_CMOS_CLOCK" -a ! "$SKIPUTC" ]; then
198 f_dialog_title "$msg_select_local_or_utc"
199 title="$DIALOG_TITLE"
200 btitle="$DIALOG_BACKTITLE"
201 f_dialog_title_restore
202 msg="$msg_is_machine_clock_utc"
204 if [ "$USE_XDIALOG" ]; then
205 defaultno="default-no"
208 defaultno="defaultno"
212 if [ "$USE_XDIALOG" ]; then
215 --backtitle "$btitle" \
217 --ok-label "$msg_yes" \
218 --cancel-label "$msg_no" \
219 --yesno "$msg" $height $width
224 --backtitle "$btitle" \
226 --yes-label "$msg_yes" \
227 --no-label "$msg_no" \
228 --yesno "$msg" $height $width
232 if [ $result -eq $DIALOG_OK ]; then
235 f_quietly rm -f "$_PATH_WALL_CMOS_CLOCK"
237 # User chose NO, pressed ESC (or Ctrl-C), or closed box
239 ( umask 222 && :> "$_PATH_WALL_CMOS_CLOCK" )
244 # Process optional default zone argument
246 if [ $# -ge 1 ]; then
249 f_dialog_title "$msg_default_zone_provided"
250 f_sprintf msg "\n$msg_use_default_zone" "$default"
252 f_dialog_yesno "$msg" "$hline"
254 f_dialog_title_restore
256 if [ $result -eq $DIALOG_OK ]; then
258 f_install_zoneinfo_file "$default"
260 [ ! "$USE_XDIALOG" ] && f_dialog_clear
264 [ ! "$USE_XDIALOG" ] && f_dialog_clear
268 # Override the user-supplied umask
273 # Read databases and perform initialization
275 f_read_iso3166_table # creates $COUNTRIES and $country_*_name
276 f_read_zones # creates $country_*_{descr,cont,filename}
277 f_sort_countries # sorts the countries listed for each continent
278 f_make_menus # creates $continent_menu_list and $continent_*_menu_list
281 # Launch application main menu
288 if [ "$NEED_CONTINENT" ]; then
289 dialog_menu_main # prompt the user to select a continent/ocean
291 f_dialog_menutag_fetch mtag
293 if [ $retval -ne $DIALOG_OK ]; then
294 [ "$TZ_OR_FAIL" ] && f_die
300 continent=$( eval f_dialog_menutag2item \"\$mtag\" \
301 $continent_menu_list )
302 f_find_continent "$continent" cont
303 f_continent $cont title cont_title
304 f_continent $cont nitems nitems
305 f_OCEANP $cont isocean
308 if [ "$NEED_COUNTRY" ]; then
309 if [ "$cont_title" = "$continent_utc_title" ]; then
310 if f_set_zone_utc; then
319 # Short cut -- if there's only one country, don't post a menu.
321 if [ $nitems -eq 1 ]; then
325 # It's amazing how much good grammar really matters...
327 if [ ! "$isocean" ]; then
328 f_sprintf title "$msg_country_title" \
330 f_dialog_title "$title"
331 title="$DIALOG_TITLE"
332 btitle="$DIALOG_BACKTITLE"
333 f_dialog_title_restore
334 prompt="$msg_select_country"
336 f_sprintf title "$msg_island_and_group_title" \
338 f_dialog_title "$title"
339 title="$DIALOG_TITLE"
340 btitle="$DIALOG_BACKTITLE"
341 f_dialog_title_restore
342 prompt="$msg_select_island_or_group"
346 # Calculate size of menu
348 f_continent $cont menu_list menu_list
349 eval f_dialog_menu_size height width rows \
357 # Launch the country selection menu
359 tag=$( eval $DIALOG \
360 --title \"\$title\" \
361 --backtitle \"\$btitle\" \
362 --ok-label \"\$msg_ok\" \
363 --cancel-label \"\$msg_cancel\" \
364 --default-item \"\$defaultctry\" \
365 --menu \"\$prompt\" \
366 $height $width $rows \
368 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
371 f_dialog_data_sanitize tag
374 if [ $retval -ne $DIALOG_OK ]; then
376 continue # back to main menu
380 # Get the country code from the user's selection
381 f_continent $cont tlc_$tag tlc
387 # If the selection has only one zone (nzones == -1),
390 f_country $tlc nzones nzones
391 if [ $nzones -lt 0 ]; then
392 f_country $tlc cont real_cont
393 f_continent $real_cont name real_continent
394 f_country $tlc name name
395 f_country $tlc filename filename
397 if ! f_confirm_zone "$real_continent/$filename"; then
398 [ $nitems -eq 1 ] && NEED_CONTINENT=1
403 f_country $tlc name name
404 f_sprintf title "$msg_country_time_zones" "$name"
405 f_dialog_title "$title"
406 title="$DIALOG_TITLE" btitle="$DIALOG_BACKTITLE"
407 f_dialog_title_restore
408 prompt="$msg_select_zone"
409 f_country $tlc menu_list menu_list
410 eval f_dialog_menu_size height width rows \
411 \"\$title\" \"\$btitle\" \"\$prompt\" \"\" $menu_list
414 # Launch the zone selection menu
415 # NOTE: This is as deep as we go
418 --title \"\$title\" \
419 --backtitle \"\$btitle\" \
420 --ok-label \"\$msg_ok\" \
421 --cancel-label \"\$msg_cancel\" \
422 --default-item \"\$defaultzone\" \
423 --menu \"\$prompt\" \
424 $height $width $rows \
426 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
429 f_dialog_data_sanitize n
432 if [ $retval -ne $DIALOG_OK ]; then
433 [ $nitems -eq 1 ] && NEED_CONTINENT=1
438 f_country $tlc cont_$n real_cont
439 f_continent $real_cont name real_continent
440 f_country $tlc name name
441 f_country $tlc filename_$n filename
443 f_confirm_zone "$real_continent/$filename" || continue
446 [ $retval -eq $DIALOG_OK ] || continue # back to main menu
448 if ! f_install_zoneinfo "$real_continent/$filename"; then
449 [ $nzones -lt 0 ] && NEED_COUNTRY=1
455 ################################################################################
457 ################################################################################