timezone revision 243112
1238438Sdteske#!/bin/sh 2238438Sdteske#- 3238438Sdteske# Copyright (c) 2011-2012 Devin Teske 4238438Sdteske# 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 16238438Sdteske# 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 20238438Sdteske# DAMAGES (INLUDING, 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: head/usr.sbin/bsdconfig/timezone/timezone 243112 2012-11-16 00:59:11Z dteske $ 28238438Sdteske# 29238438Sdteske############################################################ INCLUDES 30238438Sdteske 31240684SdteskeBSDCFG_SHARE="/usr/share/bsdconfig" 32240684Sdteske. $BSDCFG_SHARE/common.subr || exit 1 33240684Sdteskef_include $BSDCFG_SHARE/dialog.subr 34240684Sdteskef_include $BSDCFG_SHARE/mustberoot.subr 35240684Sdteskef_include $BSDCFG_SHARE/strings.subr 36240684Sdteskef_include $BSDCFG_SHARE/timezone/continents.subr 37240684Sdteskef_include $BSDCFG_SHARE/timezone/countries.subr 38240684Sdteskef_include $BSDCFG_SHARE/timezone/iso3166.subr 39240684Sdteskef_include $BSDCFG_SHARE/timezone/menus.subr 40240684Sdteskef_include $BSDCFG_SHARE/timezone/zones.subr 41238438Sdteske 42240684SdteskeBSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="090.timezone" 43238438Sdteskef_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr 44238438Sdteske 45243112Sdteskeipgm=$( f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" ) 46238438Sdteske[ $? -eq $SUCCESS -a "$ipgm" ] && pgm="$ipgm" 47238438Sdteske 48238438Sdteske############################################################ CONFIGURATION 49238438Sdteske 50238438Sdteske# 51238438Sdteske# Standard pathnames 52238438Sdteske# 53238438Sdteske_PATH_DB="/var/db/zoneinfo" 54238438Sdteske_PATH_WALL_CMOS_CLOCK="/etc/wall_cmos_clock" 55238438Sdteske 56238438Sdteske############################################################ GLOBALS 57238438Sdteske 58238438Sdteske# 59238438Sdteske# Options 60238438Sdteske# 61238438SdteskeREALLYDOIT=1 62238438SdteskeREINSTALL= 63238438SdteskeUSEDIALOG=1 64238438SdteskeSKIPUTC= 65238438SdteskeVERBOSE= 66238438SdteskeTZ_OR_FAIL= 67238438SdteskeCHROOTENV= 68238438Sdteske 69238438Sdteske# 70238438Sdteske# Dummy vars (populated dynamically) 71238438Sdteske# 72238438SdteskeCOUNTRIES= # list of 2-character country codes created by f_read_iso3166_table 73238438Sdteske 74238438Sdteske############################################################ FUNCTIONS 75238438Sdteske 76238438Sdteske# dialog_menu_main 77238438Sdteske# 78238438Sdteske# Display the dialog(1)-based application main menu. 79238438Sdteske# 80238438Sdteskedialog_menu_main() 81238438Sdteske{ 82238438Sdteske local title="$DIALOG_TITLE" 83238438Sdteske local btitle="$DIALOG_BACKTITLE" 84238438Sdteske local prompt="$msg_select_region" 85238438Sdteske local size 86238438Sdteske 87238438Sdteske size=$( eval f_dialog_menu_size \ 88238438Sdteske \"\$title\" \ 89238438Sdteske \"\$btitle\" \ 90238438Sdteske \"\$prompt\" \ 91238438Sdteske \"\" \ 92238438Sdteske $continent_menu_list ) 93238438Sdteske 94240768Sdteske local dialog_menu 95240768Sdteske dialog_menu=$( eval $DIALOG \ 96238438Sdteske --title \"\$title\" \ 97238438Sdteske --backtitle \"\$btitle\" \ 98238438Sdteske --ok-label \"\$msg_ok\" \ 99238438Sdteske --cancel-label \"\$msg_cancel\" \ 100238438Sdteske --menu \"\$prompt\" $size \ 101238438Sdteske $continent_menu_list \ 102240768Sdteske 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 103240768Sdteske ) 104240768Sdteske local retval=$? 105240768Sdteske setvar DIALOG_MENU_$$ "$dialog_menu" 106240768Sdteske return $retval 107238438Sdteske} 108238438Sdteske 109238438Sdteske############################################################ MAIN 110238438Sdteske 111238438Sdteske# Incorporate rc-file if it exists 112238438Sdteske[ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc" 113238438Sdteske 114238438Sdteske# 115238438Sdteske# Process command-line arguments 116238438Sdteske# 117238438Sdteskewhile getopts C:ehnrsSvX flag; do 118238438Sdteske case "$flag" in 119238438Sdteske C) CHROOTENV="$OPTARG";; 120238438Sdteske e) TZ_OR_FAIL=1;; 121238438Sdteske n) REALLYDOIT=;; 122238438Sdteske r) REINSTALL=1 123238438Sdteske USEDIALOG=;; 124238438Sdteske s) SKIPUTC=1;; 125238438Sdteske v) VERBOSE=1;; 126238438Sdteske h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm";; 127238438Sdteske esac 128238438Sdteskedone 129238438Sdteskeshift $(( $OPTIND - 1 )) 130238438Sdteske 131238438Sdteske# 132238438Sdteske# Initialize 133238438Sdteske# 134238438Sdteskef_dialog_init 135238438Sdteskef_dialog_title "$msg_time_zone" 136238438Sdteskef_dialog_backtitle "${ipgm:+bsdconfig }$pgm" 137238438Sdteskef_mustberoot_init 138238438Sdteske 139238438Sdteske# 140238438Sdteske# Process `-C chroot_directory' command-line argument 141238438Sdteske# 142238438Sdteskeif [ "$CHROOTENV" ]; then 143238438Sdteske _PATH_ZONETAB="$CHROOTENV$_PATH_ZONETAB" 144238438Sdteske _PATH_ISO3166="$CHROOTENV$_PATH_ISO3166" 145238438Sdteske _PATH_ZONEINFO="$CHROOTENV$_PATH_ZONEINFO" 146238438Sdteske _PATH_LOCALTIME="$CHROOTENV$_PATH_LOCALTIME" 147238438Sdteske _PATH_DB="$CHROOTENV$_PATH_DB" 148238438Sdteske _PATH_WALL_CMOS_CLOCK="$CHROOTENV$_PATH_WALL_CMOS_CLOCK" 149238438Sdteskefi 150238438Sdteske 151238438Sdteske# 152238438Sdteske# Process `-r' command-line option 153238438Sdteske# 154238438Sdteskeif [ "$REINSTALL" ]; then 155238438Sdteske [ -f "$_PATH_DB" -a -r "$_PATH_DB" ] || 156238438Sdteske f_die 1 "$msg_cannot_open_for_reading" "$_PATH_DB" 157238438Sdteske zoneinfo=$( cat "$_PATH_DB" ) || 158238438Sdteske f_die 1 "$msg_error_reading" "$_PATH_DB" 159238438Sdteske [ "$zoneinfo" ] || 160238438Sdteske f_die 1 "$msg_unable_to_determine_name_from_db" "$_PATH_DB" 161238438Sdteske f_install_zoneinfo "$zoneinfo" 162238438Sdteske exit $? 163238438Sdteskefi 164238438Sdteske 165238438Sdteske# 166238438Sdteske# If the arguments on the command-line do not specify a file, 167238438Sdteske# then interpret it as a zoneinfo name 168238438Sdteske# 169238438Sdteskeif [ $# -ge 1 ]; then 170238438Sdteske zoneinfo="$1" 171238438Sdteske 172238438Sdteske if [ ! -f "$zoneinfo" ]; then 173238438Sdteske USEDIALOG= 174238438Sdteske f_install_zoneinfo "$zoneinfo" 175238438Sdteske exit $? 176238438Sdteske fi 177238438Sdteske 178238438Sdteske # FALLTHROUGH 179238438Sdteskefi 180238438Sdteske 181238438Sdteske# 182238438Sdteske# Process the UTC option 183238438Sdteske# 184238438Sdteskeif [ "$_PATH_WALL_CMOS_CLOCK" -a ! "$SKIPUTC" ]; then 185238438Sdteske f_dialog_title "$msg_select_local_or_utc" 186238438Sdteske title="$DIALOG_TITLE" 187238438Sdteske btitle="$DIALOG_BACKTITLE" 188238438Sdteske f_dialog_title_restore 189238438Sdteske msg="$msg_is_machine_clock_utc" 190238438Sdteske 191238438Sdteske if [ "$USE_XDIALOG" ]; then 192238438Sdteske defaultno="default-no" 193238438Sdteske height=10 width=77 194238438Sdteske else 195238438Sdteske defaultno="defaultno" 196238438Sdteske height=7 width=73 197238438Sdteske fi 198238438Sdteske 199238438Sdteske if [ "$USE_XDIALOG" ]; then 200238438Sdteske $DIALOG \ 201238438Sdteske --title "$title" \ 202238438Sdteske --backtitle "$btitle" \ 203238438Sdteske --$defaultno \ 204238438Sdteske --ok-label "$msg_yes" \ 205238438Sdteske --cancel-label "$msg_no" \ 206238438Sdteske --yesno "$msg" $height $width 207238438Sdteske result=$? 208238438Sdteske else 209238438Sdteske $DIALOG \ 210238438Sdteske --title "$title" \ 211238438Sdteske --backtitle "$btitle" \ 212238438Sdteske --$defaultno \ 213238438Sdteske --yes-label "$msg_yes" \ 214238438Sdteske --no-label "$msg_no" \ 215238438Sdteske --yesno "$msg" $height $width 216238438Sdteske result=$? 217238438Sdteske fi 218238438Sdteske 219238438Sdteske if [ $result -eq 0 ]; then 220238438Sdteske # User chose YES 221238438Sdteske [ "$REALLYDOIT" ] && 222238438Sdteske f_quietly rm -f "$_PATH_WALL_CMOS_CLOCK" 223238438Sdteske else 224238438Sdteske # User chose NO, pressed ESC (or Ctrl-C), or closed box 225238438Sdteske [ "$REALLYDOIT" ] && 226238438Sdteske ( umask 222 && :> "$_PATH_WALL_CMOS_CLOCK" ) 227238438Sdteske fi 228238438Sdteskefi 229238438Sdteske 230238438Sdteske# 231238438Sdteske# Process optional default zone argument 232238438Sdteske# 233238438Sdteskeif [ $# -ge 1 ]; then 234238438Sdteske default="$1" 235238438Sdteske 236238438Sdteske f_dialog_title "$msg_default_zone_provided" 237238438Sdteske title="$DIALOG_TITLE" 238238438Sdteske btitle="$DIALOG_BACKTITLE" 239238438Sdteske f_dialog_title_restore 240238438Sdteske msg=$( printf "\n$msg_use_default_zone" "$default" ) 241238438Sdteske size=$( f_dialog_buttonbox_size "$title" "$btitle" "$msg" ) 242238438Sdteske 243238438Sdteske if [ "$USE_XDIALOG" ]; then 244238438Sdteske eval $DIALOG \ 245238438Sdteske --title \"\$title\" \ 246238438Sdteske --backtitle \"\$btitle\" \ 247238438Sdteske --ok-label \"\$msg_yes\" \ 248238438Sdteske --cancel-label \"\$msg_no\" \ 249238438Sdteske --yesno \"\$msg\" $size 250238438Sdteske result=$? 251238438Sdteske else 252238438Sdteske eval $DIALOG \ 253238438Sdteske --title \"\$title\" \ 254238438Sdteske --backtitle \"\$btitle\" \ 255238438Sdteske --yes-label \"\$msg_yes\" \ 256238438Sdteske --no-label \"\$msg_no\" \ 257238438Sdteske --yesno \"\$msg\" $size 258238438Sdteske result=$? 259238438Sdteske fi 260238438Sdteske 261238438Sdteske if [ $result -eq 0 ]; then 262238438Sdteske # User chose YES 263238438Sdteske f_install_zoneinfo_file "$default" 264238438Sdteske result=$? 265238438Sdteske [ ! "$USE_XDIALOG" ] && f_dialog_clear 266238438Sdteske exit $result 267238438Sdteske fi 268238438Sdteske 269238438Sdteske [ ! "$USE_XDIALOG" ] && f_dialog_clear 270238438Sdteskefi 271238438Sdteske 272238438Sdteske# 273238438Sdteske# Override the user-supplied umask 274238438Sdteske# 275238438Sdteskeumask 022 276238438Sdteske 277238438Sdteske# 278238438Sdteske# Read databases and perform initialization 279238438Sdteske# 280238438Sdteskef_read_iso3166_table # creates $COUNTRIES and $country_*_name 281238438Sdteskef_read_zones # creates $country_*_{descr,cont,filename} 282238438Sdteskef_sort_countries # sorts the countries listed for each continent 283238438Sdteskef_make_menus # creates $continent_menu_list and $continent_*_menu_list 284238438Sdteske 285238438Sdteske# 286238438Sdteske# Launch application main menu 287238438Sdteske# 288238438SdteskeNEED_CONTINENT=1 289238438SdteskeNEED_COUNTRY=1 290238438Sdteskewhile :; do 291238438Sdteske if [ "$NEED_CONTINENT" ]; then 292238438Sdteske dialog_menu_main # prompt the user to select a continent/ocean 293238438Sdteske retval=$? 294238438Sdteske mtag=$( f_dialog_menutag ) 295238438Sdteske 296238438Sdteske if [ $retval -ne 0 ]; then 297238438Sdteske [ "$TZ_OR_FAIL" ] && f_die 298238438Sdteske exit $SUCCESS 299238438Sdteske fi 300238438Sdteske 301238438Sdteske NEED_CONTINENT= 302238438Sdteske 303238438Sdteske continent=$( eval f_dialog_menutag2item \"\$mtag\" \ 304238438Sdteske $continent_menu_list ) 305238438Sdteske cont=$( f_find_continent "$continent" ) 306238438Sdteske cont_title=$( f_continent $cont title ) 307238438Sdteske nitems=$( f_continent $cont nitems ) 308238438Sdteske isocean=$( f_OCEANP $cont ) 309238438Sdteske fi 310238438Sdteske 311238438Sdteske if [ "$NEED_COUNTRY" ]; then 312238438Sdteske if [ "$cont_title" = "$continent_utc_title" ]; then 313238438Sdteske if f_set_zone_utc; then 314238438Sdteske break 315238438Sdteske else 316238438Sdteske NEED_CONTINENT=1 317238438Sdteske continue 318238438Sdteske fi 319238438Sdteske fi 320238438Sdteske 321238438Sdteske # 322238438Sdteske # Short cut -- if there's only one country, don't post a menu. 323238438Sdteske # 324238438Sdteske if [ $nitems -eq 1 ]; then 325238438Sdteske tag=1 326238438Sdteske else 327238438Sdteske # 328238438Sdteske # It's amazing how much good grammar really matters... 329238438Sdteske # 330238438Sdteske if [ ! "$isocean" ]; then 331238438Sdteske title=$( printf "$msg_country_title" \ 332238438Sdteske "$cont_title" ) 333238438Sdteske f_dialog_title "$title" 334238438Sdteske title="$DIALOG_TITLE" 335238438Sdteske btitle="$DIALOG_BACKTITLE" 336238438Sdteske f_dialog_title_restore 337238438Sdteske prompt="$msg_select_country" 338238438Sdteske else 339238438Sdteske title=$( printf "$msg_island_and_group_title" \ 340238438Sdteske "$cont_title" ) 341238438Sdteske f_dialog_title "$title" 342238438Sdteske title="$DIALOG_TITLE" 343238438Sdteske btitle="$DIALOG_BACKTITLE" 344238438Sdteske f_dialog_title_restore 345238438Sdteske prompt="$msg_select_island_or_group" 346238438Sdteske fi 347238438Sdteske 348238438Sdteske # 349238438Sdteske # Calculate size of menu 350238438Sdteske # 351238438Sdteske menu_list=$( f_continent $cont menu_list ) 352238438Sdteske size=$( eval f_dialog_menu_size \ 353238438Sdteske \"\$title\" \ 354238438Sdteske \"\$btitle\" \ 355238438Sdteske \"\$prompt\" \ 356238438Sdteske \"\" \ 357238438Sdteske $menu_list ) 358238438Sdteske 359238438Sdteske # 360238438Sdteske # Launch the country selection menu 361238438Sdteske # 362240768Sdteske dialog_menu=$( eval $DIALOG \ 363238438Sdteske --title \"\$title\" \ 364238438Sdteske --backtitle \"\$btitle\" \ 365238438Sdteske --ok-label \"\$msg_ok\" \ 366238438Sdteske --cancel-label \"\$msg_cancel\" \ 367238438Sdteske --menu \"\$prompt\" $size \ 368238438Sdteske $menu_list \ 369240768Sdteske 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 370240768Sdteske ) 371238438Sdteske retval=$? 372240768Sdteske setvar DIALOG_MENU_$$ "$dialog_menu" 373238438Sdteske tag=$( f_dialog_menutag ) 374238438Sdteske 375238438Sdteske if [ $retval -ne 0 ]; then 376238438Sdteske NEED_CONTINENT=1 377238438Sdteske continue # back to main menu 378238438Sdteske fi 379238438Sdteske fi 380238438Sdteske 381238438Sdteske # Get the country code from the user's selection 382238438Sdteske tlc=$( f_continent $cont tlc_$tag ) 383238438Sdteske 384238438Sdteske NEED_COUNTRY= 385238438Sdteske fi 386238438Sdteske 387238438Sdteske # 388238438Sdteske # If the selection has only one zone (nzones == -1), 389238438Sdteske # just set it. 390238438Sdteske # 391238438Sdteske nzones=$( f_country $tlc nzones ) 392238438Sdteske if [ $nzones -lt 0 ]; then 393238438Sdteske real_cont=$( f_country $tlc cont ) 394238438Sdteske real_continent=$( f_continent $real_cont name ) 395238438Sdteske name=$( f_country $tlc name ) 396238438Sdteske filename=$( f_country $tlc filename ) 397238438Sdteske 398238438Sdteske if ! f_confirm_zone "$real_continent/$filename"; then 399238438Sdteske [ $nitems -eq 1 ] && NEED_CONTINENT=1 400238438Sdteske NEED_COUNTRY=1 401238438Sdteske continue 402238438Sdteske fi 403238438Sdteske else 404238438Sdteske title=$( printf "$msg_country_time_zones" \ 405238438Sdteske "$( f_country $tlc name )" ) 406238438Sdteske f_dialog_title "$title" 407238438Sdteske title="$DIALOG_TITLE" 408238438Sdteske btitle="$DIALOG_BACKTITLE" 409238438Sdteske f_dialog_title_restore 410238438Sdteske prompt="$msg_select_zone" 411238438Sdteske menu_list=$( f_country $tlc menu_list ) 412238438Sdteske size=$( eval f_dialog_menu_size \"\$title\" \"\$btitle\" \ 413238438Sdteske \"\$prompt\" \"\" $menu_list ) 414238438Sdteske 415238438Sdteske # 416238438Sdteske # Launch the zone selection menu 417238438Sdteske # NOTE: This is as deep as we go 418238438Sdteske # 419240768Sdteske dialog_menu=$( eval $DIALOG \ 420238438Sdteske --title \"\$title\" \ 421238438Sdteske --backtitle \"\$btitle\" \ 422238438Sdteske --ok-label \"\$msg_ok\" \ 423238438Sdteske --cancel-label \"\$msg_cancel\" \ 424238438Sdteske --menu \"\$prompt\" $size \ 425238438Sdteske $menu_list \ 426240768Sdteske 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD 427240768Sdteske ) 428238438Sdteske retval=$? 429240768Sdteske setvar DIALOG_MENU_$$ "$dialog_menu" 430238438Sdteske n=$( f_dialog_menutag ) 431238438Sdteske 432238438Sdteske if [ $retval -ne 0 ]; then 433238438Sdteske [ $nitems -eq 1 ] && NEED_CONTINENT=1 434238438Sdteske NEED_COUNTRY=1 435238438Sdteske continue 436238438Sdteske fi 437238438Sdteske 438238438Sdteske real_cont=$( f_country $tlc cont_$n ) 439238438Sdteske real_continent=$( f_continent $real_cont name ) 440238438Sdteske name=$( f_country $tlc name ) 441238438Sdteske filename=$( f_country $tlc filename_$n ) 442238438Sdteske 443238438Sdteske f_confirm_zone "$real_continent/$filename" || continue 444238438Sdteske fi 445238438Sdteske 446238438Sdteske [ $retval -eq 0 ] || 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