1238438Sdteske#!/bin/sh 2238438Sdteske#- 3278489Sdteske# Copyright (c) 2011-2015 Devin Teske 4252980Sdteske# All rights reserved. 5238438Sdteske# 6238438Sdteske# Redistribution and use in source and binary forms, with or without 7238438Sdteske# modification, are permitted provided that the following conditions 8238438Sdteske# are met: 9238438Sdteske# 1. Redistributions of source code must retain the above copyright 10238438Sdteske# notice, this list of conditions and the following disclaimer. 11238438Sdteske# 2. Redistributions in binary form must reproduce the above copyright 12238438Sdteske# notice, this list of conditions and the following disclaimer in the 13238438Sdteske# documentation and/or other materials provided with the distribution. 14238438Sdteske# 15238438Sdteske# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16252987Sdteske# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17238438Sdteske# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18238438Sdteske# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19238438Sdteske# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20252987Sdteske# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21238438Sdteske# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22238438Sdteske# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23238438Sdteske# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24238438Sdteske# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25238438Sdteske# SUCH DAMAGE. 26238438Sdteske# 27238438Sdteske# $FreeBSD$ 28238438Sdteske# 29238438Sdteske############################################################ INCLUDES 30238438Sdteske 31240684SdteskeBSDCFG_SHARE="/usr/share/bsdconfig" 32240684Sdteske. $BSDCFG_SHARE/common.subr || exit 1 33244675Sdteskef_dprintf "%s: loading includes..." "$0" 34240684Sdteskef_include $BSDCFG_SHARE/dialog.subr 35240684Sdteskef_include $BSDCFG_SHARE/mustberoot.subr 36240684Sdteskef_include $BSDCFG_SHARE/strings.subr 37240684Sdteskef_include $BSDCFG_SHARE/timezone/continents.subr 38240684Sdteskef_include $BSDCFG_SHARE/timezone/countries.subr 39240684Sdteskef_include $BSDCFG_SHARE/timezone/iso3166.subr 40240684Sdteskef_include $BSDCFG_SHARE/timezone/menus.subr 41240684Sdteskef_include $BSDCFG_SHARE/timezone/zones.subr 42238438Sdteske 43240684SdteskeBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="090.timezone" 44238438Sdteskef_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr 45238438Sdteske 46259054Sdteskef_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ipgm && 47259054Sdteske pgm="${ipgm:-$pgm}" 48238438Sdteske 49238438Sdteske############################################################ CONFIGURATION 50238438Sdteske 51238438Sdteske# 52238438Sdteske# Standard pathnames 53238438Sdteske# 54238438Sdteske_PATH_DB="/var/db/zoneinfo" 55238438Sdteske_PATH_WALL_CMOS_CLOCK="/etc/wall_cmos_clock" 56238438Sdteske 57238438Sdteske############################################################ GLOBALS 58238438Sdteske 59238438Sdteske# 60238438Sdteske# Options 61238438Sdteske# 62238438SdteskeREALLYDOIT=1 63238438SdteskeREINSTALL= 64238438SdteskeUSEDIALOG=1 65274394SdteskeSKIPUTC= # See MAIN 66238438SdteskeVERBOSE= 67238438SdteskeTZ_OR_FAIL= 68238438SdteskeCHROOTENV= 69238438Sdteske 70238438Sdteske# 71238438Sdteske# Dummy vars (populated dynamically) 72238438Sdteske# 73238438SdteskeCOUNTRIES= # list of 2-character country codes created by f_read_iso3166_table 74238438Sdteske 75238438Sdteske############################################################ FUNCTIONS 76238438Sdteske 77238438Sdteske# dialog_menu_main 78238438Sdteske# 79238438Sdteske# Display the dialog(1)-based application main menu. 80238438Sdteske# 81238438Sdteskedialog_menu_main() 82238438Sdteske{ 83238438Sdteske local title="$DIALOG_TITLE" 84238438Sdteske local btitle="$DIALOG_BACKTITLE" 85238438Sdteske local prompt="$msg_select_region" 86251244Sdteske local defaultitem= # Calculated below 87251264Sdteske local hline= 88238438Sdteske 89251190Sdteske local height width rows 90251190Sdteske eval f_dialog_menu_size height width rows \ 91251190Sdteske \"\$title\" \ 92251190Sdteske \"\$btitle\" \ 93251190Sdteske \"\$prompt\" \ 94251264Sdteske \"\$hline\" \ 95251190Sdteske $continent_menu_list 96238438Sdteske 97251244Sdteske # Obtain default-item from previously stored selection 98251244Sdteske f_dialog_default_fetch defaultitem 99251244Sdteske 100251236Sdteske local menu_choice 101251236Sdteske menu_choice=$( eval $DIALOG \ 102251244Sdteske --title \"\$title\" \ 103251244Sdteske --backtitle \"\$btitle\" \ 104251264Sdteske --hline \"\$hline\" \ 105251244Sdteske --ok-label \"\$msg_ok\" \ 106251244Sdteske --cancel-label \"\$msg_cancel\" \ 107251244Sdteske --default-item \"\$defaultitem\" \ 108251244Sdteske --menu \"\$prompt\" \ 109251244Sdteske $height $width $rows \ 110251244Sdteske $continent_menu_list \ 111240768Sdteske 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 112240768Sdteske ) 113240768Sdteske local retval=$? 114251236Sdteske f_dialog_data_sanitize menu_choice 115251236Sdteske f_dialog_menutag_store "$menu_choice" 116251244Sdteske f_dialog_default_store "$menu_choice" 117240768Sdteske return $retval 118238438Sdteske} 119238438Sdteske 120238438Sdteske############################################################ MAIN 121238438Sdteske 122274394Sdteske# Skip initial question regarding UTC v. Wall-Clock time if run in VM 123274394Sdteske[ "$( sysctl -n kern.vm_guest 2> /dev/null )" = "none" ] || SKIPUTC=1 124274394Sdteske 125238438Sdteske# Incorporate rc-file if it exists 126238438Sdteske[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc" 127238438Sdteske 128238438Sdteske# 129238438Sdteske# Process command-line arguments 130238438Sdteske# 131250633Sdteskewhile getopts C:ehnrsv$GETOPTS_STDARGS flag; do 132238438Sdteske case "$flag" in 133252178Sdteske C) CHROOTENV="$OPTARG" ;; 134252178Sdteske e) TZ_OR_FAIL=1 ;; 135252178Sdteske n) REALLYDOIT= ;; 136238438Sdteske r) REINSTALL=1 137252178Sdteske USEDIALOG= ;; 138252178Sdteske s) SKIPUTC=1 ;; 139252178Sdteske v) VERBOSE=1 ;; 140252178Sdteske h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;; 141238438Sdteske esac 142238438Sdteskedone 143238438Sdteskeshift $(( $OPTIND - 1 )) 144238438Sdteske 145238438Sdteske# 146238438Sdteske# Initialize 147238438Sdteske# 148238438Sdteskef_dialog_title "$msg_time_zone" 149238438Sdteskef_dialog_backtitle "${ipgm:+bsdconfig }$pgm" 150238438Sdteskef_mustberoot_init 151238438Sdteske 152238438Sdteske# 153238438Sdteske# Process `-C chroot_directory' command-line argument 154238438Sdteske# 155238438Sdteskeif [ "$CHROOTENV" ]; then 156238438Sdteske _PATH_ZONETAB="$CHROOTENV$_PATH_ZONETAB" 157238438Sdteske _PATH_ISO3166="$CHROOTENV$_PATH_ISO3166" 158238438Sdteske _PATH_ZONEINFO="$CHROOTENV$_PATH_ZONEINFO" 159238438Sdteske _PATH_LOCALTIME="$CHROOTENV$_PATH_LOCALTIME" 160238438Sdteske _PATH_DB="$CHROOTENV$_PATH_DB" 161238438Sdteske _PATH_WALL_CMOS_CLOCK="$CHROOTENV$_PATH_WALL_CMOS_CLOCK" 162238438Sdteskefi 163238438Sdteske 164238438Sdteske# 165238438Sdteske# Process `-r' command-line option 166238438Sdteske# 167238438Sdteskeif [ "$REINSTALL" ]; then 168238438Sdteske [ -f "$_PATH_DB" -a -r "$_PATH_DB" ] || 169238438Sdteske f_die 1 "$msg_cannot_open_for_reading" "$_PATH_DB" 170259054Sdteske f_eval_catch -dk zoneinfo "$0" cat 'cat "%s"' "$_PATH_DB" || 171238438Sdteske f_die 1 "$msg_error_reading" "$_PATH_DB" 172238438Sdteske [ "$zoneinfo" ] || 173238438Sdteske f_die 1 "$msg_unable_to_determine_name_from_db" "$_PATH_DB" 174238438Sdteske f_install_zoneinfo "$zoneinfo" 175238438Sdteske exit $? 176238438Sdteskefi 177238438Sdteske 178238438Sdteske# 179238438Sdteske# If the arguments on the command-line do not specify a file, 180238438Sdteske# then interpret it as a zoneinfo name 181238438Sdteske# 182238438Sdteskeif [ $# -ge 1 ]; then 183238438Sdteske zoneinfo="$1" 184238438Sdteske 185238438Sdteske if [ ! -f "$zoneinfo" ]; then 186238438Sdteske USEDIALOG= 187238438Sdteske f_install_zoneinfo "$zoneinfo" 188238438Sdteske exit $? 189238438Sdteske fi 190238438Sdteske 191238438Sdteske # FALLTHROUGH 192238438Sdteskefi 193238438Sdteske 194238438Sdteske# 195238438Sdteske# Process the UTC option 196238438Sdteske# 197238438Sdteskeif [ "$_PATH_WALL_CMOS_CLOCK" -a ! "$SKIPUTC" ]; then 198238438Sdteske f_dialog_title "$msg_select_local_or_utc" 199238438Sdteske title="$DIALOG_TITLE" 200238438Sdteske btitle="$DIALOG_BACKTITLE" 201238438Sdteske f_dialog_title_restore 202238438Sdteske msg="$msg_is_machine_clock_utc" 203238438Sdteske 204238438Sdteske if [ "$USE_XDIALOG" ]; then 205238438Sdteske defaultno="default-no" 206238438Sdteske height=10 width=77 207238438Sdteske else 208238438Sdteske defaultno="defaultno" 209238438Sdteske height=7 width=73 210238438Sdteske fi 211238438Sdteske 212238438Sdteske if [ "$USE_XDIALOG" ]; then 213238438Sdteske $DIALOG \ 214238438Sdteske --title "$title" \ 215238438Sdteske --backtitle "$btitle" \ 216238438Sdteske --$defaultno \ 217238438Sdteske --ok-label "$msg_yes" \ 218238438Sdteske --cancel-label "$msg_no" \ 219238438Sdteske --yesno "$msg" $height $width 220238438Sdteske result=$? 221238438Sdteske else 222238438Sdteske $DIALOG \ 223238438Sdteske --title "$title" \ 224238438Sdteske --backtitle "$btitle" \ 225238438Sdteske --$defaultno \ 226238438Sdteske --yes-label "$msg_yes" \ 227238438Sdteske --no-label "$msg_no" \ 228238438Sdteske --yesno "$msg" $height $width 229238438Sdteske result=$? 230238438Sdteske fi 231238438Sdteske 232256181Sdteske if [ $result -eq $DIALOG_OK ]; then 233238438Sdteske # User chose YES 234238438Sdteske [ "$REALLYDOIT" ] && 235238438Sdteske f_quietly rm -f "$_PATH_WALL_CMOS_CLOCK" 236238438Sdteske else 237238438Sdteske # User chose NO, pressed ESC (or Ctrl-C), or closed box 238238438Sdteske [ "$REALLYDOIT" ] && 239238438Sdteske ( umask 222 && :> "$_PATH_WALL_CMOS_CLOCK" ) 240238438Sdteske fi 241238438Sdteskefi 242238438Sdteske 243238438Sdteske# 244238438Sdteske# Process optional default zone argument 245238438Sdteske# 246238438Sdteskeif [ $# -ge 1 ]; then 247238438Sdteske default="$1" 248238438Sdteske 249238438Sdteske f_dialog_title "$msg_default_zone_provided" 250259054Sdteske f_sprintf msg "\n$msg_use_default_zone" "$default" 251251979Sdteske hline= 252251979Sdteske f_dialog_yesno "$msg" "$hline" 253251979Sdteske result=$? 254238438Sdteske f_dialog_title_restore 255238438Sdteske 256256181Sdteske if [ $result -eq $DIALOG_OK ]; then 257238438Sdteske # User chose YES 258238438Sdteske f_install_zoneinfo_file "$default" 259238438Sdteske result=$? 260238438Sdteske [ ! "$USE_XDIALOG" ] && f_dialog_clear 261238438Sdteske exit $result 262238438Sdteske fi 263238438Sdteske 264238438Sdteske [ ! "$USE_XDIALOG" ] && f_dialog_clear 265238438Sdteskefi 266238438Sdteske 267238438Sdteske# 268238438Sdteske# Override the user-supplied umask 269238438Sdteske# 270238438Sdteskeumask 022 271238438Sdteske 272238438Sdteske# 273238438Sdteske# Read databases and perform initialization 274238438Sdteske# 275238438Sdteskef_read_iso3166_table # creates $COUNTRIES and $country_*_name 276238438Sdteskef_read_zones # creates $country_*_{descr,cont,filename} 277238438Sdteskef_sort_countries # sorts the countries listed for each continent 278238438Sdteskef_make_menus # creates $continent_menu_list and $continent_*_menu_list 279238438Sdteske 280238438Sdteske# 281238438Sdteske# Launch application main menu 282238438Sdteske# 283278489Sdteskedefaultctry= 284278489Sdteskedefaultzone= 285238438SdteskeNEED_CONTINENT=1 286238438SdteskeNEED_COUNTRY=1 287238438Sdteskewhile :; do 288238438Sdteske if [ "$NEED_CONTINENT" ]; then 289238438Sdteske dialog_menu_main # prompt the user to select a continent/ocean 290238438Sdteske retval=$? 291251236Sdteske f_dialog_menutag_fetch mtag 292238438Sdteske 293256181Sdteske if [ $retval -ne $DIALOG_OK ]; then 294238438Sdteske [ "$TZ_OR_FAIL" ] && f_die 295238438Sdteske exit $SUCCESS 296238438Sdteske fi 297238438Sdteske 298238438Sdteske NEED_CONTINENT= 299238438Sdteske 300238438Sdteske continent=$( eval f_dialog_menutag2item \"\$mtag\" \ 301238438Sdteske $continent_menu_list ) 302278489Sdteske f_find_continent "$continent" cont 303278489Sdteske f_continent $cont title cont_title 304278489Sdteske f_continent $cont nitems nitems 305278489Sdteske f_OCEANP $cont isocean 306238438Sdteske fi 307238438Sdteske 308238438Sdteske if [ "$NEED_COUNTRY" ]; then 309238438Sdteske if [ "$cont_title" = "$continent_utc_title" ]; then 310238438Sdteske if f_set_zone_utc; then 311238438Sdteske break 312238438Sdteske else 313238438Sdteske NEED_CONTINENT=1 314238438Sdteske continue 315238438Sdteske fi 316238438Sdteske fi 317238438Sdteske 318238438Sdteske # 319238438Sdteske # Short cut -- if there's only one country, don't post a menu. 320238438Sdteske # 321238438Sdteske if [ $nitems -eq 1 ]; then 322238438Sdteske tag=1 323238438Sdteske else 324238438Sdteske # 325238438Sdteske # It's amazing how much good grammar really matters... 326238438Sdteske # 327238438Sdteske if [ ! "$isocean" ]; then 328259054Sdteske f_sprintf title "$msg_country_title" \ 329259054Sdteske "$cont_title" 330238438Sdteske f_dialog_title "$title" 331238438Sdteske title="$DIALOG_TITLE" 332238438Sdteske btitle="$DIALOG_BACKTITLE" 333238438Sdteske f_dialog_title_restore 334238438Sdteske prompt="$msg_select_country" 335238438Sdteske else 336259054Sdteske f_sprintf title "$msg_island_and_group_title" \ 337259054Sdteske "$cont_title" 338238438Sdteske f_dialog_title "$title" 339238438Sdteske title="$DIALOG_TITLE" 340238438Sdteske btitle="$DIALOG_BACKTITLE" 341238438Sdteske f_dialog_title_restore 342238438Sdteske prompt="$msg_select_island_or_group" 343238438Sdteske fi 344238438Sdteske 345238438Sdteske # 346238438Sdteske # Calculate size of menu 347238438Sdteske # 348278489Sdteske f_continent $cont menu_list menu_list 349251190Sdteske eval f_dialog_menu_size height width rows \ 350251190Sdteske \"\$title\" \ 351251190Sdteske \"\$btitle\" \ 352251190Sdteske \"\$prompt\" \ 353251190Sdteske \"\" \ 354251190Sdteske $menu_list 355238438Sdteske 356238438Sdteske # 357238438Sdteske # Launch the country selection menu 358238438Sdteske # 359251236Sdteske tag=$( eval $DIALOG \ 360249751Sdteske --title \"\$title\" \ 361249751Sdteske --backtitle \"\$btitle\" \ 362249751Sdteske --ok-label \"\$msg_ok\" \ 363249751Sdteske --cancel-label \"\$msg_cancel\" \ 364249751Sdteske --default-item \"\$defaultctry\" \ 365251190Sdteske --menu \"\$prompt\" \ 366251190Sdteske $height $width $rows \ 367249751Sdteske $menu_list \ 368240768Sdteske 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 369240768Sdteske ) 370238438Sdteske retval=$? 371251236Sdteske f_dialog_data_sanitize tag 372249751Sdteske defaultctry="$tag" 373238438Sdteske 374256181Sdteske if [ $retval -ne $DIALOG_OK ]; then 375238438Sdteske NEED_CONTINENT=1 376238438Sdteske continue # back to main menu 377238438Sdteske fi 378238438Sdteske fi 379238438Sdteske 380238438Sdteske # Get the country code from the user's selection 381278489Sdteske f_continent $cont tlc_$tag tlc 382238438Sdteske 383238438Sdteske NEED_COUNTRY= 384238438Sdteske fi 385238438Sdteske 386238438Sdteske # 387238438Sdteske # If the selection has only one zone (nzones == -1), 388238438Sdteske # just set it. 389238438Sdteske # 390278489Sdteske f_country $tlc nzones nzones 391238438Sdteske if [ $nzones -lt 0 ]; then 392278489Sdteske f_country $tlc cont real_cont 393278489Sdteske f_continent $real_cont name real_continent 394278489Sdteske f_country $tlc name name 395278489Sdteske f_country $tlc filename filename 396238438Sdteske 397238438Sdteske if ! f_confirm_zone "$real_continent/$filename"; then 398238438Sdteske [ $nitems -eq 1 ] && NEED_CONTINENT=1 399238438Sdteske NEED_COUNTRY=1 400238438Sdteske continue 401238438Sdteske fi 402238438Sdteske else 403278489Sdteske f_country $tlc name name 404278489Sdteske f_sprintf title "$msg_country_time_zones" "$name" 405238438Sdteske f_dialog_title "$title" 406259054Sdteske title="$DIALOG_TITLE" btitle="$DIALOG_BACKTITLE" 407238438Sdteske f_dialog_title_restore 408238438Sdteske prompt="$msg_select_zone" 409278489Sdteske f_country $tlc menu_list menu_list 410251190Sdteske eval f_dialog_menu_size height width rows \ 411251190Sdteske \"\$title\" \"\$btitle\" \"\$prompt\" \"\" $menu_list 412238438Sdteske 413238438Sdteske # 414238438Sdteske # Launch the zone selection menu 415238438Sdteske # NOTE: This is as deep as we go 416238438Sdteske # 417251236Sdteske n=$( eval $DIALOG \ 418249751Sdteske --title \"\$title\" \ 419249751Sdteske --backtitle \"\$btitle\" \ 420249751Sdteske --ok-label \"\$msg_ok\" \ 421249751Sdteske --cancel-label \"\$msg_cancel\" \ 422249751Sdteske --default-item \"\$defaultzone\" \ 423251190Sdteske --menu \"\$prompt\" \ 424251190Sdteske $height $width $rows \ 425249751Sdteske $menu_list \ 426240768Sdteske 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 427240768Sdteske ) 428238438Sdteske retval=$? 429251236Sdteske f_dialog_data_sanitize n 430249751Sdteske defaultzone="$n" 431238438Sdteske 432256181Sdteske if [ $retval -ne $DIALOG_OK ]; then 433238438Sdteske [ $nitems -eq 1 ] && NEED_CONTINENT=1 434238438Sdteske NEED_COUNTRY=1 435238438Sdteske continue 436238438Sdteske fi 437238438Sdteske 438278489Sdteske f_country $tlc cont_$n real_cont 439278489Sdteske f_continent $real_cont name real_continent 440278489Sdteske f_country $tlc name name 441278489Sdteske f_country $tlc filename_$n filename 442238438Sdteske 443238438Sdteske f_confirm_zone "$real_continent/$filename" || continue 444238438Sdteske fi 445238438Sdteske 446256181Sdteske [ $retval -eq $DIALOG_OK ] || continue # back to main menu 447238438Sdteske 448238438Sdteske if ! f_install_zoneinfo "$real_continent/$filename"; then 449238438Sdteske [ $nzones -lt 0 ] && NEED_COUNTRY=1 450238438Sdteske else 451238438Sdteske break 452238438Sdteske fi 453238438Sdteskedone 454238438Sdteske 455238438Sdteske################################################################################ 456238438Sdteske# END 457238438Sdteske################################################################################ 458