]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - usr.sbin/bsdconfig/timezone/timezone
MFC: r274394, r274399, r307802
[FreeBSD/stable/10.git] / usr.sbin / bsdconfig / timezone / timezone
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
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
42
43 BSDCFG_LIBE="/usr/libexec/bsdconfig" APP_DIR="090.timezone"
44 f_include_lang $BSDCFG_LIBE/$APP_DIR/include/messages.subr
45
46 f_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 #
62 REALLYDOIT=1
63 REINSTALL=
64 USEDIALOG=1
65 SKIPUTC= # See MAIN
66 VERBOSE=
67 TZ_OR_FAIL=
68 CHROOTENV=
69
70 #
71 # Dummy vars (populated dynamically)
72 #
73 COUNTRIES= # 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 #
81 dialog_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 #
131 while 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
142 done
143 shift $(( $OPTIND - 1 ))
144
145 #
146 # Initialize
147 #
148 f_dialog_title "$msg_time_zone"
149 f_dialog_backtitle "${ipgm:+bsdconfig }$pgm"
150 f_mustberoot_init
151
152 #
153 # Process `-C chroot_directory' command-line argument
154 #
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"
162 fi
163
164 #
165 # Process `-r' command-line option
166 #
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"
172         [ "$zoneinfo" ] ||
173                 f_die 1 "$msg_unable_to_determine_name_from_db" "$_PATH_DB"
174         f_install_zoneinfo "$zoneinfo"
175         exit $?
176 fi
177
178 #
179 # If the arguments on the command-line do not specify a file,
180 # then interpret it as a zoneinfo name
181 #
182 if [ $# -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
192 fi
193
194 #
195 # Process the UTC option
196 #
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"
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
241 fi
242
243 #
244 # Process optional default zone argument
245 #
246 if [ $# -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
265 fi
266
267 #
268 # Override the user-supplied umask
269 #
270 umask 022
271
272 #
273 # Read databases and perform initialization
274 #
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
279
280 #
281 # Launch application main menu
282 #
283 defaultctry=
284 defaultzone=
285 NEED_CONTINENT=1
286 NEED_COUNTRY=1
287 while :; 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
453 done
454
455 ################################################################################
456 # END
457 ################################################################################