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