]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - usr.sbin/bsdconfig/timezone/timezone
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / usr.sbin / bsdconfig / timezone / timezone
1 #!/bin/sh
2 #-
3 # Copyright (c) 2011-2013 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 ipgm=$( f_index_menusel_keyword $BSDCFG_LIBE/$APP_DIR/INDEX "$pgm" )
47 [ $? -eq $SUCCESS -a "$ipgm" ] && pgm="$ipgm"
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=
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 # Incorporate rc-file if it exists
123 [ -f "$HOME/.bsdconfigrc" ] && f_include "$HOME/.bsdconfigrc"
124
125 #
126 # Process command-line arguments
127 #
128 while getopts C:ehnrsv$GETOPTS_STDARGS flag; do
129         case "$flag" in
130         C) CHROOTENV="$OPTARG" ;;
131         e) TZ_OR_FAIL=1 ;;
132         n) REALLYDOIT= ;;
133         r) REINSTALL=1
134            USEDIALOG= ;;
135         s) SKIPUTC=1 ;;
136         v) VERBOSE=1 ;;
137         h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;;
138         esac
139 done
140 shift $(( $OPTIND - 1 ))
141
142 #
143 # Initialize
144 #
145 f_dialog_title "$msg_time_zone"
146 f_dialog_backtitle "${ipgm:+bsdconfig }$pgm"
147 f_mustberoot_init
148
149 #
150 # Process `-C chroot_directory' command-line argument
151 #
152 if [ "$CHROOTENV" ]; then
153         _PATH_ZONETAB="$CHROOTENV$_PATH_ZONETAB"
154         _PATH_ISO3166="$CHROOTENV$_PATH_ISO3166"
155         _PATH_ZONEINFO="$CHROOTENV$_PATH_ZONEINFO"
156         _PATH_LOCALTIME="$CHROOTENV$_PATH_LOCALTIME"
157         _PATH_DB="$CHROOTENV$_PATH_DB"
158         _PATH_WALL_CMOS_CLOCK="$CHROOTENV$_PATH_WALL_CMOS_CLOCK"
159 fi
160
161 #
162 # Process `-r' command-line option
163 #
164 if [ "$REINSTALL" ]; then
165         [ -f "$_PATH_DB" -a -r "$_PATH_DB" ] ||
166                 f_die 1 "$msg_cannot_open_for_reading" "$_PATH_DB"
167         zoneinfo=$( cat "$_PATH_DB" ) ||
168                 f_die 1 "$msg_error_reading" "$_PATH_DB"
169         [ "$zoneinfo" ] ||
170                 f_die 1 "$msg_unable_to_determine_name_from_db" "$_PATH_DB"
171         f_install_zoneinfo "$zoneinfo"
172         exit $?
173 fi
174
175 #
176 # If the arguments on the command-line do not specify a file,
177 # then interpret it as a zoneinfo name
178 #
179 if [ $# -ge 1 ]; then
180         zoneinfo="$1"
181
182         if [ ! -f "$zoneinfo" ]; then
183                 USEDIALOG=
184                 f_install_zoneinfo "$zoneinfo"
185                 exit $?
186         fi
187
188         # FALLTHROUGH
189 fi
190
191 #
192 # Process the UTC option
193 #
194 if [ "$_PATH_WALL_CMOS_CLOCK" -a ! "$SKIPUTC" ]; then
195         f_dialog_title "$msg_select_local_or_utc"
196         title="$DIALOG_TITLE"
197         btitle="$DIALOG_BACKTITLE"
198         f_dialog_title_restore
199         msg="$msg_is_machine_clock_utc"
200
201         if [ "$USE_XDIALOG" ]; then
202                 defaultno="default-no"
203                 height=10 width=77
204         else
205                 defaultno="defaultno"
206                 height=7 width=73
207         fi
208
209         if [ "$USE_XDIALOG" ]; then
210                 $DIALOG \
211                         --title "$title"         \
212                         --backtitle "$btitle"    \
213                         --$defaultno             \
214                         --ok-label "$msg_yes"    \
215                         --cancel-label "$msg_no" \
216                         --yesno "$msg" $height $width
217                 result=$?
218         else
219                 $DIALOG \
220                         --title "$title"       \
221                         --backtitle "$btitle"  \
222                         --$defaultno           \
223                         --yes-label "$msg_yes" \
224                         --no-label "$msg_no"   \
225                         --yesno "$msg" $height $width
226                 result=$?
227         fi
228
229         if [ $result -eq $DIALOG_OK ]; then
230                 # User chose YES
231                 [ "$REALLYDOIT" ] &&
232                         f_quietly rm -f "$_PATH_WALL_CMOS_CLOCK"
233         else
234                 # User chose NO, pressed ESC (or Ctrl-C), or closed box
235                 [ "$REALLYDOIT" ] &&
236                         ( umask 222 && :> "$_PATH_WALL_CMOS_CLOCK" )
237         fi
238 fi
239
240 #
241 # Process optional default zone argument
242 #
243 if [ $# -ge 1 ]; then
244         default="$1"
245
246         f_dialog_title "$msg_default_zone_provided"
247         msg=$( printf "\n$msg_use_default_zone" "$default" )
248         hline=
249         f_dialog_yesno "$msg" "$hline"
250         result=$?
251         f_dialog_title_restore
252
253         if [ $result -eq $DIALOG_OK ]; then
254                 # User chose YES
255                 f_install_zoneinfo_file "$default"
256                 result=$?
257                 [ ! "$USE_XDIALOG" ] && f_dialog_clear
258                 exit $result
259         fi
260
261         [ ! "$USE_XDIALOG" ] && f_dialog_clear
262 fi
263
264 #
265 # Override the user-supplied umask
266 #
267 umask 022
268
269 #
270 # Read databases and perform initialization
271 #
272 f_read_iso3166_table # creates $COUNTRIES and $country_*_name
273 f_read_zones         # creates $country_*_{descr,cont,filename}
274 f_sort_countries     # sorts the countries listed for each continent
275 f_make_menus         # creates $continent_menu_list and $continent_*_menu_list
276
277 #
278 # Launch application main menu
279 #
280 defaultctry=""
281 defaultzone=""
282 NEED_CONTINENT=1
283 NEED_COUNTRY=1
284 while :; do
285         if [ "$NEED_CONTINENT" ]; then
286                 dialog_menu_main # prompt the user to select a continent/ocean
287                 retval=$?
288                 f_dialog_menutag_fetch mtag
289
290                 if [ $retval -ne $DIALOG_OK ]; then
291                         [ "$TZ_OR_FAIL" ] && f_die
292                         exit $SUCCESS
293                 fi
294
295                 NEED_CONTINENT=
296
297                 continent=$( eval f_dialog_menutag2item \"\$mtag\" \
298                                         $continent_menu_list )
299                 cont=$( f_find_continent "$continent" )
300                 cont_title=$( f_continent $cont title )
301                 nitems=$( f_continent $cont nitems )
302                 isocean=$( f_OCEANP $cont )
303         fi
304
305         if [ "$NEED_COUNTRY" ]; then
306                 if [ "$cont_title" = "$continent_utc_title" ]; then
307                         if f_set_zone_utc; then
308                                 break
309                         else
310                                 NEED_CONTINENT=1
311                                 continue
312                         fi
313                 fi
314
315                 #
316                 # Short cut -- if there's only one country, don't post a menu.
317                 #
318                 if [ $nitems -eq 1 ]; then
319                         tag=1
320                 else
321                         #
322                         # It's amazing how much good grammar really matters...
323                         #
324                         if [ ! "$isocean" ]; then
325                                 title=$( printf "$msg_country_title" \
326                                                 "$cont_title" )
327                                 f_dialog_title "$title"
328                                 title="$DIALOG_TITLE"
329                                 btitle="$DIALOG_BACKTITLE"
330                                 f_dialog_title_restore
331                                 prompt="$msg_select_country"
332                         else
333                                 title=$( printf "$msg_island_and_group_title" \
334                                                 "$cont_title" )
335                                 f_dialog_title "$title"
336                                 title="$DIALOG_TITLE"
337                                 btitle="$DIALOG_BACKTITLE"
338                                 f_dialog_title_restore
339                                 prompt="$msg_select_island_or_group"
340                         fi
341
342                         #
343                         # Calculate size of menu
344                         #
345                         menu_list=$( f_continent $cont menu_list )
346                         eval f_dialog_menu_size height width rows \
347                                                 \"\$title\"  \
348                                                 \"\$btitle\" \
349                                                 \"\$prompt\" \
350                                                 \"\"         \
351                                                 $menu_list
352
353                         #
354                         # Launch the country selection menu
355                         #
356                         tag=$( eval $DIALOG \
357                                 --title \"\$title\"              \
358                                 --backtitle \"\$btitle\"         \
359                                 --ok-label \"\$msg_ok\"          \
360                                 --cancel-label \"\$msg_cancel\"  \
361                                 --default-item \"\$defaultctry\" \
362                                 --menu \"\$prompt\"              \
363                                 $height $width $rows             \
364                                 $menu_list                       \
365                                 2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
366                         )
367                         retval=$?
368                         f_dialog_data_sanitize tag
369                         defaultctry="$tag"
370
371                         if [ $retval -ne $DIALOG_OK ]; then
372                                 NEED_CONTINENT=1
373                                 continue # back to main menu
374                         fi
375                 fi
376
377                 # Get the country code from the user's selection 
378                 tlc=$( f_continent $cont tlc_$tag )
379
380                 NEED_COUNTRY=
381         fi
382
383         #
384         # If the selection has only one zone (nzones == -1),
385         # just set it.
386         #
387         nzones=$( f_country $tlc nzones )
388         if [ $nzones -lt 0 ]; then
389                 real_cont=$( f_country $tlc cont )
390                 real_continent=$( f_continent $real_cont name )
391                 name=$( f_country $tlc name )
392                 filename=$( f_country $tlc filename )
393
394                 if ! f_confirm_zone "$real_continent/$filename"; then
395                         [ $nitems -eq 1 ] && NEED_CONTINENT=1
396                         NEED_COUNTRY=1
397                         continue
398                 fi
399         else
400                 title=$( printf "$msg_country_time_zones" \
401                                 "$( f_country $tlc name )" )
402                 f_dialog_title "$title"
403                 title="$DIALOG_TITLE"
404                 btitle="$DIALOG_BACKTITLE"
405                 f_dialog_title_restore
406                 prompt="$msg_select_zone"
407                 menu_list=$( f_country $tlc menu_list )
408                 eval f_dialog_menu_size height width rows \
409                         \"\$title\"  \"\$btitle\" \"\$prompt\" \"\" $menu_list
410
411                 #
412                 # Launch the zone selection menu
413                 # NOTE: This is as deep as we go
414                 #
415                 n=$( eval $DIALOG \
416                         --title \"\$title\"              \
417                         --backtitle \"\$btitle\"         \
418                         --ok-label \"\$msg_ok\"          \
419                         --cancel-label \"\$msg_cancel\"  \
420                         --default-item \"\$defaultzone\" \
421                         --menu \"\$prompt\"              \
422                         $height $width $rows             \
423                         $menu_list                       \
424                         2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
425                 )
426                 retval=$?
427                 f_dialog_data_sanitize n
428                 defaultzone="$n"
429
430                 if [ $retval -ne $DIALOG_OK ]; then
431                         [ $nitems -eq 1 ] && NEED_CONTINENT=1
432                         NEED_COUNTRY=1
433                         continue
434                 fi
435
436                 real_cont=$( f_country $tlc cont_$n )
437                 real_continent=$( f_continent $real_cont name )
438                 name=$( f_country $tlc name )
439                 filename=$( f_country $tlc filename_$n )
440
441                 f_confirm_zone "$real_continent/$filename" || continue
442         fi
443
444         [ $retval -eq $DIALOG_OK ] || continue # back to main menu
445
446         if ! f_install_zoneinfo "$real_continent/$filename"; then
447                 [ $nzones -lt 0 ] && NEED_COUNTRY=1
448         else
449                 break
450         fi
451 done
452
453 ################################################################################
454 # END
455 ################################################################################