@@ -11,7 +11,7 @@ REPORT_BUGS_TO=tz@iana.org
11
11
12
12
# Porting notes:
13
13
#
14
- # This script requires a Posix-like shell with the extension of a
14
+ # This script requires a Posix-like shell and prefers the extension of a
15
15
# 'select' statement. The 'select' statement was introduced in the
16
16
# Korn shell and is available in Bash and other shell implementations.
17
17
# If your host lacks both Bash and the Korn shell, you can get their
@@ -21,6 +21,10 @@ REPORT_BUGS_TO=tz@iana.org
21
21
# Korn Shell <http://www.kornshell.com/>
22
22
# Public Domain Korn Shell <http://www.cs.mun.ca/~michael/pdksh/>
23
23
#
24
+ # For portability to Solaris 9 /bin/sh this script avoids some POSIX
25
+ # features and common extensions, such as $(...) (which works sometimes
26
+ # but not others), $((...)), and $10.
27
+ #
24
28
# This script also uses several features of modern awk programs.
25
29
# If your host lacks awk, or has an old awk that does not conform to Posix,
26
30
# you can use either of the following free programs instead:
@@ -31,7 +35,7 @@ REPORT_BUGS_TO=tz@iana.org
31
35
32
36
# Specify default values for environment variables if they are unset.
33
37
: ${AWK=awk}
34
- : ${TZDIR=$( pwd) }
38
+ : ${TZDIR=` pwd` }
35
39
36
40
# Check for awk Posix compliance.
37
41
($AWK -v x=y ' BEGIN { exit 123 }' ) < /dev/null > /dev/null 2>&1
@@ -67,6 +71,74 @@ Options:
67
71
68
72
Report bugs to $REPORT_BUGS_TO ."
69
73
74
+ # Ask the user to select from the function's arguments,
75
+ # and assign the selected argument to the variable 'select_result'.
76
+ # Exit on EOF or I/O error. Use the shell's 'select' builtin if available,
77
+ # falling back on a less-nice but portable substitute otherwise.
78
+ if
79
+ case $BASH_VERSION in
80
+ ?* ) : ;;
81
+ ' ' )
82
+ # '; exit' should be redundant, but Dash doesn't properly fail without it.
83
+ (eval ' set --; select x; do break; done; exit' ) 2> /dev/null
84
+ esac
85
+ then
86
+ # Do this inside 'eval', as otherwise the shell might exit when parsing it
87
+ # even though it is never executed.
88
+ eval '
89
+ doselect() {
90
+ select select_result
91
+ do
92
+ case $select_result in
93
+ "") echo >&2 "Please enter a number in range." ;;
94
+ ?*) break
95
+ esac
96
+ done || exit
97
+ }
98
+
99
+ # Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout.
100
+ case $BASH_VERSION in
101
+ [01].*)
102
+ case `echo 1 | (select x in x; do break; done) 2>/dev/null` in
103
+ ?*) PS3=
104
+ esac
105
+ esac
106
+ '
107
+ else
108
+ doselect () {
109
+ # Field width of the prompt numbers.
110
+ select_width=` expr $# : ' .*' `
111
+
112
+ select_i=
113
+
114
+ while :
115
+ do
116
+ case $select_i in
117
+ ' ' )
118
+ select_i=0
119
+ for select_word
120
+ do
121
+ select_i=` expr $select_i + 1`
122
+ printf " %${select_width} d) %s\\ n" $select_i " $select_word "
123
+ done ;;
124
+ * [!0-9]* )
125
+ echo >&2 ' Please enter a number in range.' ;;
126
+ * )
127
+ if test 1 -le $select_i && test $select_i -le $# ; then
128
+ shift ` expr $select_i - 1`
129
+ select_result=$1
130
+ break
131
+ fi
132
+ echo >&2 ' Please enter a number in range.'
133
+ esac
134
+
135
+ # Prompt and read input.
136
+ printf %s >&2 " ${PS3-# ? } "
137
+ read select_i || exit
138
+ done
139
+ }
140
+ fi
141
+
70
142
while getopts c:n:-: opt
71
143
do
72
144
case $opt$OPTARG in
85
157
esac
86
158
done
87
159
88
- shift $(( OPTIND- 1 ))
160
+ shift ` expr $ OPTIND - 1 `
89
161
case $# in
90
162
0) ;;
91
163
* ) echo >&2 " $0 : $1 : unknown argument" ; exit 1 ;;
@@ -107,11 +179,6 @@ newline='
107
179
IFS=$newline
108
180
109
181
110
- # Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout.
111
- case $( echo 1 | (select x in x; do break ; done) 2> /dev/null) in
112
- ?* ) PS3=
113
- esac
114
-
115
182
# Awk script to read a time zone table and output the same table,
116
183
# with each column preceded by its distance from 'here'.
117
184
output_distances='
@@ -191,7 +258,7 @@ while
191
258
192
259
echo >&2 ' Please select a continent, ocean, "coord", or "TZ".'
193
260
194
- quoted_continents=$(
261
+ quoted_continents=`
195
262
$AWK -F' \t' '
196
263
/^[^#]/ {
197
264
entry = substr($3, 1, index($3, "/") - 1)
@@ -205,30 +272,21 @@ while
205
272
sort -u |
206
273
tr ' \n' ' '
207
274
echo ' '
208
- )
275
+ `
209
276
210
277
eval '
211
- select continent in ' " $quoted_continents " ' \
278
+ doselect ' " $quoted_continents " ' \
212
279
"coord - I want to use geographical coordinates." \
213
280
"TZ - I want to specify the time zone using the Posix TZ format."
214
- do
215
- case $continent in
216
- "")
217
- echo >&2 "Please enter a number in range.";;
218
- ?*)
219
- case $continent in
220
- Americas) continent=America;;
221
- *" "*) continent=$(expr "$continent" : ' \' ' \([^ ]*\)' \' ' )
222
- esac
223
- break
224
- esac
225
- done
281
+ continent=$select_result
282
+ case $continent in
283
+ Americas) continent=America;;
284
+ *" "*) continent=`expr "$continent" : ' \' ' \([^ ]*\)' \' ' `
285
+ esac
226
286
'
227
287
esac
228
288
229
289
case $continent in
230
- ' ' )
231
- exit 1;;
232
290
TZ)
233
291
# Ask the user for a Posix TZ string. Check that it conforms.
234
292
while
@@ -265,36 +323,31 @@ while
265
323
' 74 degrees 3 minutes west.'
266
324
read coord;;
267
325
esac
268
- distance_table=$( $AWK \
326
+ distance_table=` $AWK \
269
327
-v coord=" $coord " \
270
328
-v TZ_COUNTRY_TABLE=" $TZ_COUNTRY_TABLE " \
271
329
" $output_distances " < $TZ_ZONE_TABLE |
272
330
sort -n |
273
331
sed " ${location_limit} q"
274
- )
275
- regions=$( echo " $distance_table " | $AWK '
332
+ `
333
+ regions=` echo " $distance_table " | $AWK '
276
334
BEGIN { FS = "\t" }
277
335
{ print $NF }
278
- ' )
336
+ ' `
279
337
echo >&2 ' Please select one of the following' \
280
338
' time zone regions,'
281
339
echo >&2 ' listed roughly in increasing order' \
282
340
" of distance from $coord " .
283
- select region in $regions
284
- do
285
- case $region in
286
- ' ' ) echo >&2 ' Please enter a number in range.' ;;
287
- ?* ) break ;;
288
- esac
289
- done
290
- TZ=$( echo " $distance_table " | $AWK -v region=" $region " '
341
+ doselect $regions
342
+ region=$select_result
343
+ TZ=` echo " $distance_table " | $AWK -v region=" $region " '
291
344
BEGIN { FS="\t" }
292
345
$NF == region { print $4 }
293
- ' )
346
+ ' `
294
347
;;
295
348
* )
296
349
# Get list of names of countries in the continent or ocean.
297
- countries=$( $AWK -F' \t' \
350
+ countries=` $AWK -F' \t' \
298
351
-v continent=" $continent " \
299
352
-v TZ_COUNTRY_TABLE=" $TZ_COUNTRY_TABLE " \
300
353
'
@@ -314,32 +367,23 @@ while
314
367
print country
315
368
}
316
369
}
317
- ' < $TZ_ZONE_TABLE | sort -f)
370
+ ' < $TZ_ZONE_TABLE | sort -f`
318
371
319
372
320
373
# If there's more than one country, ask the user which one.
321
374
case $countries in
322
375
* " $newline " * )
323
376
echo >&2 ' Please select a country' \
324
377
' whose clocks agree with yours.'
325
- select country in $countries
326
- do
327
- case $country in
328
- ' ' ) echo >&2 ' Please enter a number in range.' ;;
329
- ?* ) break
330
- esac
331
- done
332
-
333
- case $country in
334
- ' ' ) exit 1
335
- esac ;;
378
+ doselect $countries
379
+ country=$select_result ;;
336
380
* )
337
381
country=$countries
338
382
esac
339
383
340
384
341
385
# Get list of names of time zone rule regions in the country.
342
- regions=$( $AWK -F' \t' \
386
+ regions=` $AWK -F' \t' \
343
387
-v country=" $country " \
344
388
-v TZ_COUNTRY_TABLE=" $TZ_COUNTRY_TABLE " \
345
389
'
@@ -353,30 +397,22 @@ while
353
397
}
354
398
}
355
399
$1 == cc { print $4 }
356
- ' < $TZ_ZONE_TABLE )
400
+ ' < $TZ_ZONE_TABLE `
357
401
358
402
359
403
# If there's more than one region, ask the user which one.
360
404
case $regions in
361
405
* " $newline " * )
362
406
echo >&2 ' Please select one of the following' \
363
407
' time zone regions.'
364
- select region in $regions
365
- do
366
- case $region in
367
- ' ' ) echo >&2 ' Please enter a number in range.' ;;
368
- ?* ) break
369
- esac
370
- done
371
- case $region in
372
- ' ' ) exit 1
373
- esac ;;
408
+ doselect $regions
409
+ region=$select_result ;;
374
410
* )
375
411
region=$regions
376
412
esac
377
413
378
414
# Determine TZ from country and region.
379
- TZ=$( $AWK -F' \t' \
415
+ TZ=` $AWK -F' \t' \
380
416
-v country=" $country " \
381
417
-v region=" $region " \
382
418
-v TZ_COUNTRY_TABLE=" $TZ_COUNTRY_TABLE " \
@@ -391,7 +427,7 @@ while
391
427
}
392
428
}
393
429
$1 == cc && $4 == region { print $3 }
394
- ' < $TZ_ZONE_TABLE )
430
+ ' < $TZ_ZONE_TABLE `
395
431
esac
396
432
397
433
# Make sure the corresponding zoneinfo file exists.
@@ -410,10 +446,10 @@ while
410
446
extra_info=
411
447
for i in 1 2 3 4 5 6 7 8
412
448
do
413
- TZdate=$( LANG=C TZ=" $TZ_for_date " date)
414
- UTdate=$( LANG=C TZ=UTC0 date)
415
- TZsec=$( expr " $TZdate " : ' .*:\([0-5][0-9]\)' )
416
- UTsec=$( expr " $UTdate " : ' .*:\([0-5][0-9]\)' )
449
+ TZdate=` LANG=C TZ=" $TZ_for_date " date`
450
+ UTdate=` LANG=C TZ=UTC0 date`
451
+ TZsec=` expr " $TZdate " : ' .*:\([0-5][0-9]\)' `
452
+ UTsec=` expr " $UTdate " : ' .*:\([0-5][0-9]\)' `
417
453
case $TZsec in
418
454
$UTsec )
419
455
extra_info="
@@ -440,16 +476,9 @@ Universal Time is now: $UTdate."
440
476
echo >&2 " Therefore TZ='$TZ ' will be used.$extra_info "
441
477
echo >&2 " Is the above information OK?"
442
478
443
- ok=
444
- select ok in Yes No
445
- do
446
- case $ok in
447
- ' ' ) echo >&2 ' Please enter 1 for Yes, or 2 for No.' ;;
448
- ?* ) break
449
- esac
450
- done
479
+ doselect Yes No
480
+ ok=$select_result
451
481
case $ok in
452
- ' ' ) exit 1;;
453
482
Yes) break
454
483
esac
455
484
do coord=
0 commit comments