Print this page
XXX Remove nawk(1)
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/zic/tzselect.ksh
+++ new/usr/src/cmd/zic/tzselect.ksh
1 1 #! /usr/bin/ksh
2 2 #
3 3 # Copyright 2005 Sun Microsystems, Inc. All rights reserved.
4 4 # Use is subject to license terms.
5 5 #
6 6 # ident "%Z%%M% %I% %E% SMI"
7 7 #
8 8 # '@(#)tzselect.ksh 1.8'
9 9
10 10 # Ask the user about the time zone, and output the resulting TZ value to stdout.
11 11 # Interact with the user via stderr and stdin.
12 12
13 13 # Contributed by Paul Eggert
14 14
15 15 # Porting notes:
16 16 #
17 17 # This script requires several features of the Korn shell.
18 18 # If your host lacks the Korn shell,
19 19 # you can use either of the following free programs instead:
20 20 #
21 21 # <a href=ftp://ftp.gnu.org/pub/gnu/>
22 22 # Bourne-Again shell (bash)
23 23 # </a>
24 24 #
25 25 # <a href=ftp://ftp.cs.mun.ca/pub/pdksh/pdksh.tar.gz>
26 26 # Public domain ksh
27 27 # </a>
28 28 #
29 29 # This script also uses several features of modern awk programs.
30 30 # If your host lacks awk, or has an old awk that does not conform to POSIX.2,
↓ open down ↓ |
30 lines elided |
↑ open up ↑ |
31 31 # you can use either of the following free programs instead:
32 32 #
33 33 # <a href=ftp://ftp.gnu.org/pub/gnu/>
34 34 # GNU awk (gawk)
35 35 # </a>
36 36 #
37 37 # <a href=ftp://ftp.whidbey.net/pub/brennan/>
38 38 # mawk
39 39 # </a>
40 40
41 -AWK=/usr/bin/nawk
41 +AWK=/usr/xpg4/bin/awk
42 42 GREP=/usr/bin/grep
43 43 EXPR=/usr/bin/expr
44 44 LOCALE=/usr/bin/locale
45 45 SORT=/usr/bin/sort
46 46 PRINTF=/usr/bin/printf
47 47 DATE=/usr/bin/date
48 48 GETTEXT=/usr/bin/gettext
49 49
50 50 TZDIR=/usr/share/lib/zoneinfo
51 51
52 52 # Messages
53 53 ERR_NO_SETUP="%s: time zone files are not set up correctly"
54 54 INFO_LOCATION="Please identify a location so that time zone rules \
55 55 can be set correctly."
56 56 INFO_SELECT_CONT="Please select a continent or ocean."
57 57 INFO_POSIX="none - I want to specify the time zone using the POSIX \
58 58 TZ format."
59 59 WARN_ENTER_NUM="Please enter a number in range."
60 60 INFO_ENTER_POSIX="Please enter the desired value of the TZ environment \
61 61 variable."
62 62 INFO_POSIX_EX="For example, GST-10 is a zone named GST that is 10 hours \
63 63 ahead (east) of UTC."
64 64 ERR_INV_POSIX="\`%s\' is not a conforming POSIX time zone string."
65 65 INFO_SELECT_CNTRY="Please select a country or region."
66 66 INFO_SELECT_TZ="Please select one of the following time zone regions."
67 67 INFO_EXTRA1="Local time is now: %s"
68 68 INFO_EXTRA2="Universal Time is now: %s"
69 69 INFO_INFO="The following information has been given:"
70 70 INFO_TZ="Therefore TZ='%s' will be used."
71 71 INFO_OK="Is the above information OK?"
72 72 INFO_YES="Yes"
73 73 INFO_NO="No"
74 74 WARN_ENTER_YORN="Please enter 1 for Yes, or 2 for No."
75 75 INFO_FINE="Here is the TZ value again, this time on standard output:"
76 76
77 77 # I18n support
78 78 TEXTDOMAINDIR=/usr/lib/locale; export TEXTDOMAINDIR
79 79 TEXTDOMAIN=SUNW_OST_OSCMD; export TEXTDOMAIN
80 80 DOMAIN2=SUNW_OST_ZONEINFO
81 81
82 82 # Make sure the tables are readable.
83 83 TZ_COUNTRY_TABLE=$TZDIR/tab/country.tab
84 84 TZ_ZONE_TABLE=$TZDIR/tab/zone_sun.tab
85 85 for f in $TZ_COUNTRY_TABLE $TZ_ZONE_TABLE
86 86 do
87 87 <$f || {
88 88 $PRINTF >&2 "`$GETTEXT "$ERR_NO_SETUP"`\n" $0
89 89 exit 1
90 90 }
91 91 done
92 92
93 93 newline='
94 94 '
95 95 IFS=$newline
96 96
97 97 # For C locale, don't need to call gettext(1)
98 98 loc_messages=`$LOCALE | $GREP LC_MESSAGES | $AWK -F"=" '{print $2}`
99 99 if [ "$loc_messages" = "\"C\"" -o "$loc_messages" = "C" ]; then
100 100 is_C=1
101 101 else
102 102 is_C=0
103 103 fi
104 104
105 105 iafrica=`$GETTEXT $DOMAIN2 Africa`
106 106 iamerica=`$GETTEXT $DOMAIN2 Americas`
107 107 iantarctica=`$GETTEXT $DOMAIN2 Antarctica`
108 108 iarcticocean=`$GETTEXT $DOMAIN2 "Arctic Ocean"`
109 109 iasia=`$GETTEXT $DOMAIN2 Asia`
110 110 iatlanticocean=`$GETTEXT $DOMAIN2 "Atlantic Ocean"`
111 111 iaustralia=`$GETTEXT $DOMAIN2 Australia`
112 112 ieurope=`$GETTEXT $DOMAIN2 Europe`
113 113 ipacificocean=`$GETTEXT $DOMAIN2 "Pacific Ocean"`
114 114 iindianocean=`$GETTEXT $DOMAIN2 "Indian Ocean"`
115 115 none=`$GETTEXT "$INFO_POSIX"`
116 116
117 117 # Begin the main loop. We come back here if the user wants to retry.
118 118 while
119 119 $PRINTF >&2 "`$GETTEXT "$INFO_LOCATION"`\n"
120 120
121 121 continent=
122 122 country=
123 123 region=
124 124
125 125 # Ask the user for continent or ocean.
126 126 $PRINTF >&2 "`$GETTEXT "$INFO_SELECT_CONT"`\n"
127 127
128 128 select continent in \
129 129 $iafrica \
130 130 $iamerica \
131 131 $iantarctica \
132 132 $iarcticocean \
133 133 $iasia \
134 134 $iatlanticocean \
135 135 $iaustralia \
136 136 $ieurope \
137 137 $iindianocean \
138 138 $ipacificocean \
139 139 $none
140 140
141 141 do
142 142 case $continent in
143 143 '')
144 144 $PRINTF >&2 "`$GETTEXT "$WARN_ENTER_NUM"`\n";;
145 145
146 146 ?*)
147 147 case $continent in
148 148 $iafrica) continent=Africa;;
149 149 $iamerica) continent=America;;
150 150 $iantarctica) continent=Antarctica;;
151 151 $iarcticocean) continent=Arctic;;
152 152 $iasia) continent=Asia;;
153 153 $iatlanticocean) continent=Atlantic;;
154 154 $iaustralia) continent=Australia;;
155 155 $ieurope) continent=Europe;;
156 156 $iindianocean) continent=Indian;;
157 157 $ipacificocean) continent=Pacific;;
158 158 $none) continent=none;;
159 159 esac
160 160 break
161 161 esac
162 162 done
163 163 case $continent in
164 164 '')
165 165 exit 1;;
166 166 none)
167 167 # Ask the user for a POSIX TZ string. Check that it conforms.
168 168 while
169 169 $PRINTF >&2 "`$GETTEXT "$INFO_ENTER_POSIX"`\n"
170 170 $PRINTF >&2 "`$GETTEXT "$INFO_POSIX_EX"`\n"
171 171
172 172 read TZ
173 173 env LC_ALL=C $AWK -v TZ="$TZ" 'BEGIN {
174 174 tzname = "[^-+,0-9][^-+,0-9][^-+,0-9]+"
175 175 time = "[0-2]?[0-9](:[0-5][0-9](:[0-5][0-9])?)?"
176 176 offset = "[-+]?" time
177 177 date = "(J?[0-9]+|M[0-9]+\.[0-9]+\.[0-9]+)"
178 178 datetime = "," date "(/" time ")?"
179 179 tzpattern = "^(:.*|" tzname offset "(" tzname \
180 180 "(" offset ")?(" datetime datetime ")?)?)$"
181 181 if (TZ ~ tzpattern) exit 1
182 182 exit 0
183 183 }'
184 184 do
185 185 $PRINTF >&2 "`$GETTEXT "$ERR_INV_POSIX"`\n" $TZ
186 186
187 187 done
188 188 TZ_for_date=$TZ;;
189 189 *)
190 190 # Get list of names of countries in the continent or ocean.
191 191 countries=$($AWK -F'\t' \
192 192 -v continent="$continent" \
193 193 -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
194 194 '
195 195 /^#/ { next }
196 196 $3 ~ ("^" continent "/") {
197 197 if (!cc_seen[$1]++) cc_list[++ccs] = $1
198 198 }
199 199 END {
200 200 while (getline <TZ_COUNTRY_TABLE) {
201 201 if ($0 !~ /^#/) cc_name[$1] = $2
202 202 }
203 203 for (i = 1; i <= ccs; i++) {
204 204 country = cc_list[i]
205 205 if (cc_name[country]) {
206 206 country = cc_name[country]
207 207 }
208 208 print country
209 209 }
210 210 }
211 211 ' <$TZ_ZONE_TABLE | $SORT -f)
212 212
213 213 # i18n country names
214 214 c=0
215 215 set -A icountry
216 216 for country in $countries
217 217 do
218 218 if [ $is_C -eq 1 ]; then
219 219 icountry[c]=$country
220 220 else
221 221 icountry[c]=`${GETTEXT} ${DOMAIN2} $country`
222 222 fi
223 223 ocountry[c]="$country"
224 224 c=$(( $c + 1 ))
225 225 done
226 226 maxnum=$c
227 227
228 228 # If there's more than one country, ask the user which one.
229 229 case $countries in
230 230 *"$newline"*)
231 231 $PRINTF >&2 "`$GETTEXT "$INFO_SELECT_CNTRY"`\n"
232 232 select xcountry in ${icountry[*]}
233 233 do
234 234 case $xcountry in
235 235 '')
236 236 $PRINTF >&2 "`$GETTEXT "$WARN_ENTER_NUM"`\n"
237 237 ;;
238 238 ?*) c=0
239 239 while true; do
240 240 if [ "$xcountry" = "${icountry[$c]}" ];
241 241 then
242 242 country="${ocountry[$c]}"
243 243 break
244 244 fi
245 245 if [ $c -lt $maxnum ]; then
246 246 c=$(( $c + 1 ))
247 247 else
248 248 break
249 249 fi
250 250 done
251 251 break
252 252 esac
253 253 done
254 254
255 255 case $xcountry in
256 256 '') exit 1
257 257 esac;;
258 258 *)
259 259 country=$countries
260 260 xcountry=$countries
261 261 esac
262 262
263 263
264 264 # Get list of names of time zone rule regions in the country.
265 265 regions=$($AWK -F'\t' \
266 266 -v country="$country" \
267 267 -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
268 268 '
269 269 BEGIN {
270 270 cc = country
271 271 while (getline <TZ_COUNTRY_TABLE) {
272 272 if ($0 !~ /^#/ && country == $2) {
273 273 cc = $1
274 274 break
275 275 }
276 276 }
277 277 }
278 278 $1 == cc { print $5 }
279 279 ' <$TZ_ZONE_TABLE)
280 280
281 281 # I18n region names
282 282 c=0
283 283 set -A iregion
284 284 for region in $regions
285 285 do
286 286 if [ $is_C -eq 1 ]; then
287 287 iregion[c]=$region
288 288 else
289 289 iregion[c]=`${GETTEXT} ${DOMAIN2} $region`
290 290 fi
291 291 oregion[c]="$region"
292 292 c=$(( $c + 1 ))
293 293 done
294 294 maxnum=$c
295 295
296 296 # If there's more than one region, ask the user which one.
297 297 case $regions in
298 298 *"$newline"*)
299 299 $PRINTF >&2 "`$GETTEXT "$INFO_SELECT_TZ"`\n"
300 300
301 301 select xregion in ${iregion[*]}
302 302 do
303 303 case $xregion in
304 304 '')
305 305 $PRINTF >&2 "`$GETTEXT "$WARN_ENTER_NUM"`\n"
306 306 ;;
307 307 ?*) c=0
308 308 while true; do
309 309 if [ "$xregion" = "${iregion[$c]}" ];
310 310 then
311 311 region="${oregion[$c]}"
312 312 break
313 313 fi
314 314 if [ $c -lt $maxnum ]; then
315 315 c=$(( $c + 1 ))
316 316 else
317 317 break
318 318 fi
319 319 done
320 320 break
321 321 esac
322 322 done
323 323
324 324 case $region in
325 325 '') exit 1
326 326 esac;;
327 327 *)
328 328 region=$regions
329 329 xregion=$regions
330 330 esac
331 331
332 332 # Determine TZ from country and region.
333 333 TZ=$($AWK -F'\t' \
334 334 -v country="$country" \
335 335 -v region="$region" \
336 336 -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
337 337 '
338 338 BEGIN {
339 339 cc = country
340 340 while (getline <TZ_COUNTRY_TABLE) {
341 341 if ($0 !~ /^#/ && country == $2) {
342 342 cc = $1
343 343 break
344 344 }
345 345 }
346 346 }
347 347
348 348 $1 == cc && $5 == region {
349 349 # Check if tzname mapped to
350 350 # backward compatible tzname
351 351 if ($4 == "-") {
352 352 print $3
353 353 } else {
354 354 print $4
355 355 }
356 356 }
357 357 ' <$TZ_ZONE_TABLE)
358 358
359 359 # Make sure the corresponding zoneinfo file exists.
360 360 TZ_for_date=$TZDIR/$TZ
361 361 <$TZ_for_date || {
362 362 $PRINTF >&2 "`$GETTEXT "$ERR_NO_SETUP"`\n" $0
363 363 exit 1
364 364 }
365 365 # Absolute path TZ's not supported
366 366 TZ_for_date=$TZ
367 367 esac
368 368
369 369
370 370 # Use the proposed TZ to output the current date relative to UTC.
371 371 # Loop until they agree in seconds.
372 372 # Give up after 8 unsuccessful tries.
373 373
374 374 extra_info1=
375 375 extra_info2=
376 376 for i in 1 2 3 4 5 6 7 8
377 377 do
378 378 TZdate=$(LANG=C TZ="$TZ_for_date" $DATE)
379 379 UTdate=$(LANG=C TZ=UTC0 $DATE)
380 380 TZsec=$($EXPR "$TZdate" : '.*:\([0-5][0-9]\)')
381 381 UTsec=$($EXPR "$UTdate" : '.*:\([0-5][0-9]\)')
382 382 case $TZsec in
383 383 $UTsec)
384 384 extra_info1=$($PRINTF "`$GETTEXT "$INFO_EXTRA1"`" \
385 385 "$TZdate")
386 386 extra_info2=$($PRINTF "`$GETTEXT "$INFO_EXTRA2"`" \
387 387 "$UTdate")
388 388 break
389 389 esac
390 390 done
391 391
392 392
393 393 # Output TZ info and ask the user to confirm.
394 394
395 395 $PRINTF >&2 "\n"
396 396 $PRINTF >&2 "`$GETTEXT "$INFO_INFO"`\n"
397 397 $PRINTF >&2 "\n"
398 398
399 399 case $country+$region in
400 400 ?*+?*) $PRINTF >&2 " $xcountry$newline $xregion\n";;
401 401 ?*+) $PRINTF >&2 " $xcountry\n";;
402 402 +) $PRINTF >&2 " TZ='$TZ'\n"
403 403 esac
404 404 $PRINTF >&2 "\n"
405 405 $PRINTF >&2 "`$GETTEXT "$INFO_TZ"`\n" "$TZ"
406 406 $PRINTF >&2 "$extra_info1\n"
407 407 $PRINTF >&2 "$extra_info2\n"
408 408 $PRINTF >&2 "`$GETTEXT "$INFO_OK"`\n"
409 409
410 410 ok=
411 411 # select ok in Yes No
412 412 Yes="`$GETTEXT "$INFO_YES"`"
413 413 No="`$GETTEXT "$INFO_NO"`"
414 414 select ok in $Yes $No
415 415 do
416 416 case $ok in
417 417 '')
418 418 $PRINTF >&2 "`$GETTEXT "$WARN_ENTER_YORN"`\n"
419 419 ;;
420 420 ?*) break
421 421 esac
422 422 done
423 423 case $ok in
424 424 '') exit 1;;
425 425 $Yes) break
426 426 esac
427 427 do :
428 428 done
429 429
430 430 $PRINTF >&2 "`$GETTEXT "$INFO_FINE"`\n"
431 431
432 432 $PRINTF "%s\n" "$TZ"
↓ open down ↓ |
381 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX