1#!/bin/sh 2#- 3# Copyright (c) 2011-2015 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 (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 25# SUCH DAMAGE. 26# 27# 28############################################################ INCLUDES 29 30BSDCFG_SHARE="/usr/share/bsdconfig" 31. $BSDCFG_SHARE/common.subr || exit 1 32f_dprintf "%s: loading includes..." "$0" 33f_include $BSDCFG_SHARE/dialog.subr 34f_include $BSDCFG_SHARE/mustberoot.subr 35f_include $BSDCFG_SHARE/strings.subr 36f_include $BSDCFG_SHARE/timezone/continents.subr 37f_include $BSDCFG_SHARE/timezone/countries.subr 38f_include $BSDCFG_SHARE/timezone/iso3166.subr 39f_include $BSDCFG_SHARE/timezone/menus.subr 40f_include $BSDCFG_SHARE/timezone/zones.subr 41 42BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="090.timezone" 43f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr 44 45f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm && 46 pgm="${ipgm:-$pgm}" 47 48############################################################ CONFIGURATION 49 50# 51# Standard pathnames 52# 53_PATH_DB="/var/db/zoneinfo" 54_PATH_WALL_CMOS_CLOCK="/etc/wall_cmos_clock" 55 56############################################################ GLOBALS 57 58# 59# Options 60# 61REALLYDOIT=1 62REINSTALL= 63USEDIALOG=1 64SKIPUTC= # See MAIN 65VERBOSE= 66TZ_OR_FAIL= 67CHROOTENV= 68 69# 70# Dummy vars (populated dynamically) 71# 72COUNTRIES= # list of 2-character country codes created by f_read_iso3166_table 73 74############################################################ FUNCTIONS 75 76# dialog_menu_main 77# 78# Display the dialog(1)-based application main menu. 79# 80dialog_menu_main() 81{ 82 local title="$DIALOG_TITLE" 83 local btitle="$DIALOG_BACKTITLE" 84 local prompt="$msg_select_region" 85 local defaultitem= # Calculated below 86 local hline= 87 88 local height width rows 89 eval f_dialog_menu_size height width rows \ 90 \"\$title\" \ 91 \"\$btitle\" \ 92 \"\$prompt\" \ 93 \"\$hline\" \ 94 $continent_menu_list 95 96 # Obtain default-item from previously stored selection 97 f_dialog_default_fetch defaultitem 98 99 local menu_choice 100 menu_choice=$( eval $DIALOG \ 101 --title \"\$title\" \ 102 --backtitle \"\$btitle\" \ 103 --hline \"\$hline\" \ 104 --ok-label \"\$msg_ok\" \ 105 --cancel-label \"\$msg_cancel\" \ 106 --default-item \"\$defaultitem\" \ 107 --menu \"\$prompt\" \ 108 $height $width $rows \ 109 $continent_menu_list \ 110 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 111 ) 112 local retval=$? 113 f_dialog_data_sanitize menu_choice 114 f_dialog_menutag_store "$menu_choice" 115 f_dialog_default_store "$menu_choice" 116 return $retval 117} 118 119############################################################ MAIN 120 121# Skip initial question regarding UTC v. Wall-Clock time if run in VM 122[ "$( sysctl -n kern.vm_guest 2> /dev/null )" = "none" ] || SKIPUTC=1 123 124# Incorporate rc-file if it exists 125[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc" 126 127# 128# Process command-line arguments 129# 130while getopts C:ehnrsv$GETOPTS_STDARGS flag; do 131 case "$flag" in 132 C) CHROOTENV="$OPTARG" ;; 133 e) TZ_OR_FAIL=1 ;; 134 n) REALLYDOIT= ;; 135 r) REINSTALL=1 136 USEDIALOG= ;; 137 s) SKIPUTC=1 ;; 138 v) VERBOSE=1 ;; 139 h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;; 140 esac 141done 142shift $(( $OPTIND - 1 )) 143 144# 145# Initialize 146# 147f_dialog_title "$msg_time_zone" 148f_dialog_backtitle "${ipgm:+bsdconfig }$pgm" 149f_mustberoot_init 150 151# 152# Process `-C chroot_directory' command-line argument 153# 154if [ "$CHROOTENV" ]; then 155 _PATH_ZONETAB="$CHROOTENV$_PATH_ZONETAB" 156 _PATH_ISO3166="$CHROOTENV$_PATH_ISO3166" 157 _PATH_ZONEINFO="$CHROOTENV$_PATH_ZONEINFO" 158 _PATH_LOCALTIME="$CHROOTENV$_PATH_LOCALTIME" 159 _PATH_DB="$CHROOTENV$_PATH_DB" 160 _PATH_WALL_CMOS_CLOCK="$CHROOTENV$_PATH_WALL_CMOS_CLOCK" 161fi 162 163# 164# Process `-r' command-line option 165# 166if [ "$REINSTALL" ]; then 167 [ -f "$_PATH_DB" -a -r "$_PATH_DB" ] || 168 f_die 1 "$msg_cannot_open_for_reading" "$_PATH_DB" 169 f_eval_catch -dk zoneinfo "$0" cat 'cat "%s"' "$_PATH_DB" || 170 f_die 1 "$msg_error_reading" "$_PATH_DB" 171 [ "$zoneinfo" ] || 172 f_die 1 "$msg_unable_to_determine_name_from_db" "$_PATH_DB" 173 f_install_zoneinfo "$zoneinfo" 174 exit $? 175fi 176 177# 178# If the arguments on the command-line do not specify a file, 179# then interpret it as a zoneinfo name 180# 181if [ $# -ge 1 ]; then 182 zoneinfo="$1" 183 184 if [ ! -f "$zoneinfo" ]; then 185 USEDIALOG= 186 f_install_zoneinfo "$zoneinfo" 187 exit $? 188 fi 189 190 # FALLTHROUGH 191fi 192 193# 194# Process the UTC option 195# 196if [ "$_PATH_WALL_CMOS_CLOCK" -a ! "$SKIPUTC" ]; then 197 f_dialog_title "$msg_select_local_or_utc" 198 title="$DIALOG_TITLE" 199 btitle="$DIALOG_BACKTITLE" 200 f_dialog_title_restore 201 msg="$msg_is_machine_clock_utc" 202 203 if [ "$USE_XDIALOG" ]; then 204 defaultno="default-no" 205 height=10 width=77 206 else 207 defaultno="defaultno" 208 height=7 width=73 209 fi 210 211 if [ "$USE_XDIALOG" ]; then 212 $DIALOG \ 213 --title "$title" \ 214 --backtitle "$btitle" \ 215 --$defaultno \ 216 --ok-label "$msg_yes" \ 217 --cancel-label "$msg_no" \ 218 --yesno "$msg" $height $width 219 result=$? 220 else 221 $DIALOG \ 222 --title "$title" \ 223 --backtitle "$btitle" \ 224 --$defaultno \ 225 --yes-label "$msg_yes" \ 226 --no-label "$msg_no" \ 227 --yesno "$msg" $height $width 228 result=$? 229 fi 230 231 if [ $result -eq $DIALOG_OK ]; then 232 # User chose YES 233 [ "$REALLYDOIT" ] && 234 f_quietly rm -f "$_PATH_WALL_CMOS_CLOCK" 235 else 236 # User chose NO, pressed ESC (or Ctrl-C), or closed box 237 [ "$REALLYDOIT" ] && 238 ( umask 222 && :> "$_PATH_WALL_CMOS_CLOCK" ) 239 fi 240fi 241 242# 243# Process optional default zone argument 244# 245if [ $# -ge 1 ]; then 246 default="$1" 247 248 f_dialog_title "$msg_default_zone_provided" 249 f_sprintf msg "\n$msg_use_default_zone" "$default" 250 hline= 251 f_dialog_yesno "$msg" "$hline" 252 result=$? 253 f_dialog_title_restore 254 255 if [ $result -eq $DIALOG_OK ]; then 256 # User chose YES 257 f_install_zoneinfo_file "$default" 258 result=$? 259 [ ! "$USE_XDIALOG" ] && f_dialog_clear 260 exit $result 261 fi 262 263 [ ! "$USE_XDIALOG" ] && f_dialog_clear 264fi 265 266# 267# Override the user-supplied umask 268# 269umask 022 270 271# 272# Read databases and perform initialization 273# 274f_read_iso3166_table # creates $COUNTRIES and $country_*_name 275f_read_zones # creates $country_*_{descr,cont,filename} 276f_sort_countries # sorts the countries listed for each continent 277f_make_menus # creates $continent_menu_list and $continent_*_menu_list 278 279# 280# Launch application main menu 281# 282defaultctry= 283defaultzone= 284NEED_CONTINENT=1 285NEED_COUNTRY=1 286while :; do 287 if [ "$NEED_CONTINENT" ]; then 288 dialog_menu_main # prompt the user to select a continent/ocean 289 retval=$? 290 f_dialog_menutag_fetch mtag 291 292 if [ $retval -ne $DIALOG_OK ]; then 293 [ "$TZ_OR_FAIL" ] && f_die 294 exit $SUCCESS 295 fi 296 297 NEED_CONTINENT= 298 299 continent=$( eval f_dialog_menutag2item \"\$mtag\" \ 300 $continent_menu_list ) 301 f_find_continent "$continent" cont 302 f_continent $cont title cont_title 303 f_continent $cont nitems nitems 304 f_OCEANP $cont isocean 305 fi 306 307 if [ "$NEED_COUNTRY" ]; then 308 if [ "$cont_title" = "$continent_utc_title" ]; then 309 if f_set_zone_utc; then 310 break 311 else 312 NEED_CONTINENT=1 313 continue 314 fi 315 fi 316 317 # 318 # Short cut -- if there's only one country, don't post a menu. 319 # 320 if [ $nitems -eq 1 ]; then 321 tag=1 322 else 323 # 324 # It's amazing how much good grammar really matters... 325 # 326 if [ ! "$isocean" ]; then 327 f_sprintf title "$msg_country_title" \ 328 "$cont_title" 329 f_dialog_title "$title" 330 title="$DIALOG_TITLE" 331 btitle="$DIALOG_BACKTITLE" 332 f_dialog_title_restore 333 prompt="$msg_select_country" 334 else 335 f_sprintf title "$msg_island_and_group_title" \ 336 "$cont_title" 337 f_dialog_title "$title" 338 title="$DIALOG_TITLE" 339 btitle="$DIALOG_BACKTITLE" 340 f_dialog_title_restore 341 prompt="$msg_select_island_or_group" 342 fi 343 344 # 345 # Calculate size of menu 346 # 347 f_continent $cont menu_list menu_list 348 eval f_dialog_menu_size height width rows \ 349 \"\$title\" \ 350 \"\$btitle\" \ 351 \"\$prompt\" \ 352 \"\" \ 353 $menu_list 354 355 # 356 # Launch the country selection menu 357 # 358 tag=$( eval $DIALOG \ 359 --title \"\$title\" \ 360 --backtitle \"\$btitle\" \ 361 --ok-label \"\$msg_ok\" \ 362 --cancel-label \"\$msg_cancel\" \ 363 --default-item \"\$defaultctry\" \ 364 --menu \"\$prompt\" \ 365 $height $width $rows \ 366 $menu_list \ 367 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 368 ) 369 retval=$? 370 f_dialog_data_sanitize tag 371 defaultctry="$tag" 372 373 if [ $retval -ne $DIALOG_OK ]; then 374 NEED_CONTINENT=1 375 continue # back to main menu 376 fi 377 fi 378 379 # Get the country code from the user's selection 380 f_continent $cont tlc_$tag tlc 381 382 NEED_COUNTRY= 383 fi 384 385 # 386 # If the selection has only one zone (nzones == -1), 387 # just set it. 388 # 389 f_country $tlc nzones nzones 390 if [ $nzones -lt 0 ]; then 391 f_country $tlc cont real_cont 392 f_continent $real_cont name real_continent 393 f_country $tlc name name 394 f_country $tlc filename filename 395 396 if ! f_confirm_zone "$real_continent/$filename"; then 397 [ $nitems -eq 1 ] && NEED_CONTINENT=1 398 NEED_COUNTRY=1 399 continue 400 fi 401 else 402 f_country $tlc name name 403 f_sprintf title "$msg_country_time_zones" "$name" 404 f_dialog_title "$title" 405 title="$DIALOG_TITLE" btitle="$DIALOG_BACKTITLE" 406 f_dialog_title_restore 407 prompt="$msg_select_zone" 408 f_country $tlc menu_list menu_list 409 eval f_dialog_menu_size height width rows \ 410 \"\$title\" \"\$btitle\" \"\$prompt\" \"\" $menu_list 411 412 # 413 # Launch the zone selection menu 414 # NOTE: This is as deep as we go 415 # 416 n=$( eval $DIALOG \ 417 --title \"\$title\" \ 418 --backtitle \"\$btitle\" \ 419 --ok-label \"\$msg_ok\" \ 420 --cancel-label \"\$msg_cancel\" \ 421 --default-item \"\$defaultzone\" \ 422 --menu \"\$prompt\" \ 423 $height $width $rows \ 424 $menu_list \ 425 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 426 ) 427 retval=$? 428 f_dialog_data_sanitize n 429 defaultzone="$n" 430 431 if [ $retval -ne $DIALOG_OK ]; then 432 [ $nitems -eq 1 ] && NEED_CONTINENT=1 433 NEED_COUNTRY=1 434 continue 435 fi 436 437 f_country $tlc cont_$n real_cont 438 f_continent $real_cont name real_continent 439 f_country $tlc name name 440 f_country $tlc filename_$n filename 441 442 f_confirm_zone "$real_continent/$filename" || continue 443 fi 444 445 [ $retval -eq $DIALOG_OK ] || continue # back to main menu 446 447 if ! f_install_zoneinfo "$real_continent/$filename"; then 448 [ $nzones -lt 0 ] && NEED_COUNTRY=1 449 else 450 break 451 fi 452done 453 454################################################################################ 455# END 456################################################################################ 457