Blame timezone/tzselect.ksh

Packit Service 82fcde
#!/bin/bash
Packit Service 82fcde
Packit Service 82fcde
PKGVERSION='(tzcode) '
Packit Service 82fcde
TZVERSION=see_Makefile
Packit Service 82fcde
REPORT_BUGS_TO=tz@iana.org
Packit Service 82fcde
Packit Service 82fcde
# Ask the user about the time zone, and output the resulting TZ value to stdout.
Packit Service 82fcde
# Interact with the user via stderr and stdin.
Packit Service 82fcde
Packit Service 82fcde
# Contributed by Paul Eggert.  This file is in the public domain.
Packit Service 82fcde
Packit Service 82fcde
# Porting notes:
Packit Service 82fcde
#
Packit Service 82fcde
# This script requires a Posix-like shell and prefers the extension of a
Packit Service 82fcde
# 'select' statement.  The 'select' statement was introduced in the
Packit Service 82fcde
# Korn shell and is available in Bash and other shell implementations.
Packit Service 82fcde
# If your host lacks both Bash and the Korn shell, you can get their
Packit Service 82fcde
# source from one of these locations:
Packit Service 82fcde
#
Packit Service 82fcde
#	Bash <http://www.gnu.org/software/bash/bash.html>
Packit Service 82fcde
#	Korn Shell <http://www.kornshell.com/>
Packit Service 82fcde
#	Public Domain Korn Shell <http://www.cs.mun.ca/~michael/pdksh/>
Packit Service 82fcde
#
Packit Service 82fcde
# For portability to Solaris 9 /bin/sh this script avoids some POSIX
Packit Service 82fcde
# features and common extensions, such as $(...) (which works sometimes
Packit Service 82fcde
# but not others), $((...)), and $10.
Packit Service 82fcde
#
Packit Service 82fcde
# This script also uses several features of modern awk programs.
Packit Service 82fcde
# If your host lacks awk, or has an old awk that does not conform to Posix,
Packit Service 82fcde
# you can use either of the following free programs instead:
Packit Service 82fcde
#
Packit Service 82fcde
#	Gawk (GNU awk) <http://www.gnu.org/software/gawk/>
Packit Service 82fcde
#	mawk <http://invisible-island.net/mawk/>
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
# Specify default values for environment variables if they are unset.
Packit Service 82fcde
: ${AWK=awk}
Packit Service 82fcde
: ${TZDIR=`pwd`}
Packit Service 82fcde
Packit Service 82fcde
# Output one argument as-is to standard output.
Packit Service 82fcde
# Safer than 'echo', which can mishandle '\' or leading '-'.
Packit Service 82fcde
say() {
Packit Service 82fcde
    printf '%s\n' "$1"
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
# Check for awk Posix compliance.
Packit Service 82fcde
($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1
Packit Service 82fcde
[ $? = 123 ] || {
Packit Service 82fcde
	say >&2 "$0: Sorry, your '$AWK' program is not Posix compatible."
Packit Service 82fcde
	exit 1
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
coord=
Packit Service 82fcde
location_limit=10
Packit Service 82fcde
zonetabtype=zone1970
Packit Service 82fcde
Packit Service 82fcde
usage="Usage: tzselect [--version] [--help] [-c COORD] [-n LIMIT]
Packit Service 82fcde
Select a time zone interactively.
Packit Service 82fcde
Packit Service 82fcde
Options:
Packit Service 82fcde
Packit Service 82fcde
  -c COORD
Packit Service 82fcde
    Instead of asking for continent and then country and then city,
Packit Service 82fcde
    ask for selection from time zones whose largest cities
Packit Service 82fcde
    are closest to the location with geographical coordinates COORD.
Packit Service 82fcde
    COORD should use ISO 6709 notation, for example, '-c +4852+00220'
Packit Service 82fcde
    for Paris (in degrees and minutes, North and East), or
Packit Service 82fcde
    '-c -35-058' for Buenos Aires (in degrees, South and West).
Packit Service 82fcde
Packit Service 82fcde
  -n LIMIT
Packit Service 82fcde
    Display at most LIMIT locations when -c is used (default $location_limit).
Packit Service 82fcde
Packit Service 82fcde
  --version
Packit Service 82fcde
    Output version information.
Packit Service 82fcde
Packit Service 82fcde
  --help
Packit Service 82fcde
    Output this help.
Packit Service 82fcde
Packit Service 82fcde
Report bugs to $REPORT_BUGS_TO."
Packit Service 82fcde
Packit Service 82fcde
# Ask the user to select from the function's arguments,
Packit Service 82fcde
# and assign the selected argument to the variable 'select_result'.
Packit Service 82fcde
# Exit on EOF or I/O error.  Use the shell's 'select' builtin if available,
Packit Service 82fcde
# falling back on a less-nice but portable substitute otherwise.
Packit Service 82fcde
if
Packit Service 82fcde
  case $BASH_VERSION in
Packit Service 82fcde
  ?*) : ;;
Packit Service 82fcde
  '')
Packit Service 82fcde
    # '; exit' should be redundant, but Dash doesn't properly fail without it.
Packit Service 82fcde
    (eval 'set --; select x; do break; done; exit') </dev/null 2>/dev/null
Packit Service 82fcde
  esac
Packit Service 82fcde
then
Packit Service 82fcde
  # Do this inside 'eval', as otherwise the shell might exit when parsing it
Packit Service 82fcde
  # even though it is never executed.
Packit Service 82fcde
  eval '
Packit Service 82fcde
    doselect() {
Packit Service 82fcde
      select select_result
Packit Service 82fcde
      do
Packit Service 82fcde
	case $select_result in
Packit Service 82fcde
	"") echo >&2 "Please enter a number in range." ;;
Packit Service 82fcde
	?*) break
Packit Service 82fcde
	esac
Packit Service 82fcde
      done || exit
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
    # Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout.
Packit Service 82fcde
    case $BASH_VERSION in
Packit Service 82fcde
    [01].*)
Packit Service 82fcde
      case `echo 1 | (select x in x; do break; done) 2>/dev/null` in
Packit Service 82fcde
      ?*) PS3=
Packit Service 82fcde
      esac
Packit Service 82fcde
    esac
Packit Service 82fcde
  '
Packit Service 82fcde
else
Packit Service 82fcde
  doselect() {
Packit Service 82fcde
    # Field width of the prompt numbers.
Packit Service 82fcde
    select_width=`expr $# : '.*'`
Packit Service 82fcde
Packit Service 82fcde
    select_i=
Packit Service 82fcde
Packit Service 82fcde
    while :
Packit Service 82fcde
    do
Packit Service 82fcde
      case $select_i in
Packit Service 82fcde
      '')
Packit Service 82fcde
	select_i=0
Packit Service 82fcde
	for select_word
Packit Service 82fcde
	do
Packit Service 82fcde
	  select_i=`expr $select_i + 1`
Packit Service 82fcde
	  printf >&2 "%${select_width}d) %s\\n" $select_i "$select_word"
Packit Service 82fcde
	done ;;
Packit Service 82fcde
      *[!0-9]*)
Packit Service 82fcde
	echo >&2 'Please enter a number in range.' ;;
Packit Service 82fcde
      *)
Packit Service 82fcde
	if test 1 -le $select_i && test $select_i -le $#; then
Packit Service 82fcde
	  shift `expr $select_i - 1`
Packit Service 82fcde
	  select_result=$1
Packit Service 82fcde
	  break
Packit Service 82fcde
	fi
Packit Service 82fcde
	echo >&2 'Please enter a number in range.'
Packit Service 82fcde
      esac
Packit Service 82fcde
Packit Service 82fcde
      # Prompt and read input.
Packit Service 82fcde
      printf >&2 %s "${PS3-#? }"
Packit Service 82fcde
      read select_i || exit
Packit Service 82fcde
    done
Packit Service 82fcde
  }
Packit Service 82fcde
fi
Packit Service 82fcde
Packit Service 82fcde
while getopts c:n:t:-: opt
Packit Service 82fcde
do
Packit Service 82fcde
    case $opt$OPTARG in
Packit Service 82fcde
    c*)
Packit Service 82fcde
	coord=$OPTARG ;;
Packit Service 82fcde
    n*)
Packit Service 82fcde
	location_limit=$OPTARG ;;
Packit Service 82fcde
    t*) # Undocumented option, used for developer testing.
Packit Service 82fcde
	zonetabtype=$OPTARG ;;
Packit Service 82fcde
    -help)
Packit Service 82fcde
	exec echo "$usage" ;;
Packit Service 82fcde
    -version)
Packit Service 82fcde
	exec echo "tzselect $PKGVERSION$TZVERSION" ;;
Packit Service 82fcde
    -*)
Packit Service 82fcde
	say >&2 "$0: -$opt$OPTARG: unknown option; try '$0 --help'"; exit 1 ;;
Packit Service 82fcde
    *)
Packit Service 82fcde
	say >&2 "$0: try '$0 --help'"; exit 1 ;;
Packit Service 82fcde
    esac
Packit Service 82fcde
done
Packit Service 82fcde
Packit Service 82fcde
shift `expr $OPTIND - 1`
Packit Service 82fcde
case $# in
Packit Service 82fcde
0) ;;
Packit Service 82fcde
*) say >&2 "$0: $1: unknown argument"; exit 1 ;;
Packit Service 82fcde
esac
Packit Service 82fcde
Packit Service 82fcde
# Make sure the tables are readable.
Packit Service 82fcde
TZ_COUNTRY_TABLE=$TZDIR/iso3166.tab
Packit Service 82fcde
TZ_ZONE_TABLE=$TZDIR/$zonetabtype.tab
Packit Service 82fcde
for f in $TZ_COUNTRY_TABLE $TZ_ZONE_TABLE
Packit Service 82fcde
do
Packit Service 82fcde
	<"$f" || {
Packit Service 82fcde
		say >&2 "$0: time zone files are not set up correctly"
Packit Service 82fcde
		exit 1
Packit Service 82fcde
	}
Packit Service 82fcde
done
Packit Service 82fcde
Packit Service 82fcde
# If the current locale does not support UTF-8, convert data to current
Packit Service 82fcde
# locale's format if possible, as the shell aligns columns better that way.
Packit Service 82fcde
# Check the UTF-8 of U+12345 CUNEIFORM SIGN URU TIMES KI.
Packit Service 82fcde
! $AWK 'BEGIN { u12345 = "\360\222\215\205"; exit length(u12345) != 1 }' &&
Packit Service 82fcde
    { tmp=`(mktemp -d) 2>/dev/null` || {
Packit Service 82fcde
	tmp=${TMPDIR-/tmp}/tzselect.$$ &&
Packit Service 82fcde
	(umask 77 && mkdir -- "$tmp")
Packit Service 82fcde
    };} &&
Packit Service 82fcde
    trap 'status=$?; rm -fr -- "$tmp"; exit $status' 0 HUP INT PIPE TERM &&
Packit Service 82fcde
    (iconv -f UTF-8 -t //TRANSLIT <"$TZ_COUNTRY_TABLE" >$tmp/iso3166.tab) \
Packit Service 82fcde
        2>/dev/null &&
Packit Service 82fcde
    TZ_COUNTRY_TABLE=$tmp/iso3166.tab &&
Packit Service 82fcde
    iconv -f UTF-8 -t //TRANSLIT <"$TZ_ZONE_TABLE" >$tmp/$zonetabtype.tab &&
Packit Service 82fcde
    TZ_ZONE_TABLE=$tmp/$zonetabtype.tab
Packit Service 82fcde
Packit Service 82fcde
newline='
Packit Service 82fcde
'
Packit Service 82fcde
IFS=$newline
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
# Awk script to read a time zone table and output the same table,
Packit Service 82fcde
# with each column preceded by its distance from 'here'.
Packit Service 82fcde
output_distances='
Packit Service 82fcde
  BEGIN {
Packit Service 82fcde
    FS = "\t"
Packit Service 82fcde
    while (getline 
Packit Service 82fcde
      if ($0 ~ /^[^#]/)
Packit Service 82fcde
        country[$1] = $2
Packit Service 82fcde
    country["US"] = "US" # Otherwise the strings get too long.
Packit Service 82fcde
  }
Packit Service 82fcde
  function abs(x) {
Packit Service 82fcde
    return x < 0 ? -x : x;
Packit Service 82fcde
  }
Packit Service 82fcde
  function min(x, y) {
Packit Service 82fcde
    return x < y ? x : y;
Packit Service 82fcde
  }
Packit Service 82fcde
  function convert_coord(coord, deg, minute, ilen, sign, sec) {
Packit Service 82fcde
    if (coord ~ /^[-+]?[0-9]?[0-9][0-9][0-9][0-9][0-9][0-9]([^0-9]|$)/) {
Packit Service 82fcde
      degminsec = coord
Packit Service 82fcde
      intdeg = degminsec < 0 ? -int(-degminsec / 10000) : int(degminsec / 10000)
Packit Service 82fcde
      minsec = degminsec - intdeg * 10000
Packit Service 82fcde
      intmin = minsec < 0 ? -int(-minsec / 100) : int(minsec / 100)
Packit Service 82fcde
      sec = minsec - intmin * 100
Packit Service 82fcde
      deg = (intdeg * 3600 + intmin * 60 + sec) / 3600
Packit Service 82fcde
    } else if (coord ~ /^[-+]?[0-9]?[0-9][0-9][0-9][0-9]([^0-9]|$)/) {
Packit Service 82fcde
      degmin = coord
Packit Service 82fcde
      intdeg = degmin < 0 ? -int(-degmin / 100) : int(degmin / 100)
Packit Service 82fcde
      minute = degmin - intdeg * 100
Packit Service 82fcde
      deg = (intdeg * 60 + minute) / 60
Packit Service 82fcde
    } else
Packit Service 82fcde
      deg = coord
Packit Service 82fcde
    return deg * 0.017453292519943296
Packit Service 82fcde
  }
Packit Service 82fcde
  function convert_latitude(coord) {
Packit Service 82fcde
    match(coord, /..*[-+]/)
Packit Service 82fcde
    return convert_coord(substr(coord, 1, RLENGTH - 1))
Packit Service 82fcde
  }
Packit Service 82fcde
  function convert_longitude(coord) {
Packit Service 82fcde
    match(coord, /..*[-+]/)
Packit Service 82fcde
    return convert_coord(substr(coord, RLENGTH))
Packit Service 82fcde
  }
Packit Service 82fcde
  # Great-circle distance between points with given latitude and longitude.
Packit Service 82fcde
  # Inputs and output are in radians.  This uses the great-circle special
Packit Service 82fcde
  # case of the Vicenty formula for distances on ellipsoids.
Packit Service 82fcde
  function gcdist(lat1, long1, lat2, long2, dlong, x, y, num, denom) {
Packit Service 82fcde
    dlong = long2 - long1
Packit Service 82fcde
    x = cos(lat2) * sin(dlong)
Packit Service 82fcde
    y = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlong)
Packit Service 82fcde
    num = sqrt(x * x + y * y)
Packit Service 82fcde
    denom = sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(dlong)
Packit Service 82fcde
    return atan2(num, denom)
Packit Service 82fcde
  }
Packit Service 82fcde
  # Parallel distance between points with given latitude and longitude.
Packit Service 82fcde
  # This is the product of the longitude difference and the cosine
Packit Service 82fcde
  # of the latitude of the point that is further from the equator.
Packit Service 82fcde
  # I.e., it considers longitudes to be further apart if they are
Packit Service 82fcde
  # nearer the equator.
Packit Service 82fcde
  function pardist(lat1, long1, lat2, long2) {
Packit Service 82fcde
    return abs(long1 - long2) * min(cos(lat1), cos(lat2))
Packit Service 82fcde
  }
Packit Service 82fcde
  # The distance function is the sum of the great-circle distance and
Packit Service 82fcde
  # the parallel distance.  It could be weighted.
Packit Service 82fcde
  function dist(lat1, long1, lat2, long2) {
Packit Service 82fcde
    return gcdist(lat1, long1, lat2, long2) + pardist(lat1, long1, lat2, long2)
Packit Service 82fcde
  }
Packit Service 82fcde
  BEGIN {
Packit Service 82fcde
    coord_lat = convert_latitude(coord)
Packit Service 82fcde
    coord_long = convert_longitude(coord)
Packit Service 82fcde
  }
Packit Service 82fcde
  /^[^#]/ {
Packit Service 82fcde
    here_lat = convert_latitude($2)
Packit Service 82fcde
    here_long = convert_longitude($2)
Packit Service 82fcde
    line = $1 "\t" $2 "\t" $3
Packit Service 82fcde
    sep = "\t"
Packit Service 82fcde
    ncc = split($1, cc, /,/)
Packit Service 82fcde
    for (i = 1; i <= ncc; i++) {
Packit Service 82fcde
      line = line sep country[cc[i]]
Packit Service 82fcde
      sep = ", "
Packit Service 82fcde
    }
Packit Service 82fcde
    if (NF == 4)
Packit Service 82fcde
      line = line " - " $4
Packit Service 82fcde
    printf "%g\t%s\n", dist(coord_lat, coord_long, here_lat, here_long), line
Packit Service 82fcde
  }
Packit Service 82fcde
'
Packit Service 82fcde
Packit Service 82fcde
# Begin the main loop.  We come back here if the user wants to retry.
Packit Service 82fcde
while
Packit Service 82fcde
Packit Service 82fcde
	echo >&2 'Please identify a location' \
Packit Service 82fcde
		'so that time zone rules can be set correctly.'
Packit Service 82fcde
Packit Service 82fcde
	continent=
Packit Service 82fcde
	country=
Packit Service 82fcde
	region=
Packit Service 82fcde
Packit Service 82fcde
	case $coord in
Packit Service 82fcde
	?*)
Packit Service 82fcde
		continent=coord;;
Packit Service 82fcde
	'')
Packit Service 82fcde
Packit Service 82fcde
	# Ask the user for continent or ocean.
Packit Service 82fcde
Packit Service 82fcde
	echo >&2 'Please select a continent, ocean, "coord", or "TZ".'
Packit Service 82fcde
Packit Service 82fcde
        quoted_continents=`
Packit Service 82fcde
	  $AWK '
Packit Service 82fcde
	    BEGIN { FS = "\t" }
Packit Service 82fcde
	    /^[^#]/ {
Packit Service 82fcde
              entry = substr($3, 1, index($3, "/") - 1)
Packit Service 82fcde
              if (entry == "America")
Packit Service 82fcde
		entry = entry "s"
Packit Service 82fcde
              if (entry ~ /^(Arctic|Atlantic|Indian|Pacific)$/)
Packit Service 82fcde
		entry = entry " Ocean"
Packit Service 82fcde
              printf "'\''%s'\''\n", entry
Packit Service 82fcde
            }
Packit Service 82fcde
          ' <"$TZ_ZONE_TABLE" |
Packit Service 82fcde
	  sort -u |
Packit Service 82fcde
	  tr '\n' ' '
Packit Service 82fcde
	  echo ''
Packit Service 82fcde
	`
Packit Service 82fcde
Packit Service 82fcde
	eval '
Packit Service 82fcde
	    doselect '"$quoted_continents"' \
Packit Service 82fcde
		"coord - I want to use geographical coordinates." \
Packit Service 82fcde
		"TZ - I want to specify the time zone using the Posix TZ format."
Packit Service 82fcde
	    continent=$select_result
Packit Service 82fcde
	    case $continent in
Packit Service 82fcde
	    Americas) continent=America;;
Packit Service 82fcde
	    *" "*) continent=`expr "$continent" : '\''\([^ ]*\)'\''`
Packit Service 82fcde
	    esac
Packit Service 82fcde
	'
Packit Service 82fcde
	esac
Packit Service 82fcde
Packit Service 82fcde
	case $continent in
Packit Service 82fcde
	TZ)
Packit Service 82fcde
		# Ask the user for a Posix TZ string.  Check that it conforms.
Packit Service 82fcde
		while
Packit Service 82fcde
			echo >&2 'Please enter the desired value' \
Packit Service 82fcde
				'of the TZ environment variable.'
Packit Service 82fcde
			echo >&2 'For example, GST-10 is a zone named GST' \
Packit Service 82fcde
				'that is 10 hours ahead (east) of UTC.'
Packit Service 82fcde
			read TZ
Packit Service 82fcde
			$AWK -v TZ="$TZ" 'BEGIN {
Packit Service 82fcde
				tzname = "(<[[:alnum:]+-]{3,}>|[[:alpha:]]{3,})"
Packit Service 82fcde
				time = "(2[0-4]|[0-1]?[0-9])" \
Packit Service 82fcde
				  "(:[0-5][0-9](:[0-5][0-9])?)?"
Packit Service 82fcde
				offset = "[-+]?" time
Packit Service 82fcde
				mdate = "M([1-9]|1[0-2])\\.[1-5]\\.[0-6]"
Packit Service 82fcde
				jdate = "((J[1-9]|[0-9]|J?[1-9][0-9]" \
Packit Service 82fcde
				  "|J?[1-2][0-9][0-9])|J?3[0-5][0-9]|J?36[0-5])"
Packit Service 82fcde
				datetime = ",(" mdate "|" jdate ")(/" time ")?"
Packit Service 82fcde
				tzpattern = "^(:.*|" tzname offset "(" tzname \
Packit Service 82fcde
				  "(" offset ")?(" datetime datetime ")?)?)$"
Packit Service 82fcde
				if (TZ ~ tzpattern) exit 1
Packit Service 82fcde
				exit 0
Packit Service 82fcde
			}'
Packit Service 82fcde
		do
Packit Service 82fcde
		    say >&2 "'$TZ' is not a conforming Posix time zone string."
Packit Service 82fcde
		done
Packit Service 82fcde
		TZ_for_date=$TZ;;
Packit Service 82fcde
	*)
Packit Service 82fcde
		case $continent in
Packit Service 82fcde
		coord)
Packit Service 82fcde
		    case $coord in
Packit Service 82fcde
		    '')
Packit Service 82fcde
			echo >&2 'Please enter coordinates' \
Packit Service 82fcde
				'in ISO 6709 notation.'
Packit Service 82fcde
			echo >&2 'For example, +4042-07403 stands for'
Packit Service 82fcde
			echo >&2 '40 degrees 42 minutes north,' \
Packit Service 82fcde
				'74 degrees 3 minutes west.'
Packit Service 82fcde
			read coord;;
Packit Service 82fcde
		    esac
Packit Service 82fcde
		    distance_table=`$AWK \
Packit Service 82fcde
			    -v coord="$coord" \
Packit Service 82fcde
			    -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
Packit Service 82fcde
			    "$output_distances" <"$TZ_ZONE_TABLE" |
Packit Service 82fcde
		      sort -n |
Packit Service 82fcde
		      sed "${location_limit}q"
Packit Service 82fcde
		    `
Packit Service 82fcde
		    regions=`say "$distance_table" | $AWK '
Packit Service 82fcde
		      BEGIN { FS = "\t" }
Packit Service 82fcde
		      { print $NF }
Packit Service 82fcde
		    '`
Packit Service 82fcde
		    echo >&2 'Please select one of the following' \
Packit Service 82fcde
			    'time zone regions,'
Packit Service 82fcde
		    echo >&2 'listed roughly in increasing order' \
Packit Service 82fcde
			    "of distance from $coord".
Packit Service 82fcde
		    doselect $regions
Packit Service 82fcde
		    region=$select_result
Packit Service 82fcde
		    TZ=`say "$distance_table" | $AWK -v region="$region" '
Packit Service 82fcde
		      BEGIN { FS="\t" }
Packit Service 82fcde
		      $NF == region { print $4 }
Packit Service 82fcde
		    '`
Packit Service 82fcde
		    ;;
Packit Service 82fcde
		*)
Packit Service 82fcde
		# Get list of names of countries in the continent or ocean.
Packit Service 82fcde
		countries=`$AWK \
Packit Service 82fcde
			-v continent="$continent" \
Packit Service 82fcde
			-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
Packit Service 82fcde
		'
Packit Service 82fcde
			BEGIN { FS = "\t" }
Packit Service 82fcde
			/^#/ { next }
Packit Service 82fcde
			$3 ~ ("^" continent "/") {
Packit Service 82fcde
			    ncc = split($1, cc, /,/)
Packit Service 82fcde
			    for (i = 1; i <= ncc; i++)
Packit Service 82fcde
				if (!cc_seen[cc[i]]++) cc_list[++ccs] = cc[i]
Packit Service 82fcde
			}
Packit Service 82fcde
			END {
Packit Service 82fcde
				while (getline 
Packit Service 82fcde
					if ($0 !~ /^#/) cc_name[$1] = $2
Packit Service 82fcde
				}
Packit Service 82fcde
				for (i = 1; i <= ccs; i++) {
Packit Service 82fcde
					country = cc_list[i]
Packit Service 82fcde
					if (cc_name[country]) {
Packit Service 82fcde
					  country = cc_name[country]
Packit Service 82fcde
					}
Packit Service 82fcde
					print country
Packit Service 82fcde
				}
Packit Service 82fcde
			}
Packit Service 82fcde
		' <"$TZ_ZONE_TABLE" | sort -f`
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
		# If there's more than one country, ask the user which one.
Packit Service 82fcde
		case $countries in
Packit Service 82fcde
		*"$newline"*)
Packit Service 82fcde
			echo >&2 'Please select a country' \
Packit Service 82fcde
				'whose clocks agree with yours.'
Packit Service 82fcde
			doselect $countries
Packit Service 82fcde
			country=$select_result;;
Packit Service 82fcde
		*)
Packit Service 82fcde
			country=$countries
Packit Service 82fcde
		esac
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
		# Get list of names of time zone rule regions in the country.
Packit Service 82fcde
		regions=`$AWK \
Packit Service 82fcde
			-v country="$country" \
Packit Service 82fcde
			-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
Packit Service 82fcde
		'
Packit Service 82fcde
			BEGIN {
Packit Service 82fcde
				FS = "\t"
Packit Service 82fcde
				cc = country
Packit Service 82fcde
				while (getline 
Packit Service 82fcde
					if ($0 !~ /^#/  &&  country == $2) {
Packit Service 82fcde
						cc = $1
Packit Service 82fcde
						break
Packit Service 82fcde
					}
Packit Service 82fcde
				}
Packit Service 82fcde
			}
Packit Service 82fcde
			/^#/ { next }
Packit Service 82fcde
			$1 ~ cc { print $4 }
Packit Service 82fcde
		' <"$TZ_ZONE_TABLE"`
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
		# If there's more than one region, ask the user which one.
Packit Service 82fcde
		case $regions in
Packit Service 82fcde
		*"$newline"*)
Packit Service 82fcde
			echo >&2 'Please select one of the following' \
Packit Service 82fcde
				'time zone regions.'
Packit Service 82fcde
			doselect $regions
Packit Service 82fcde
			region=$select_result;;
Packit Service 82fcde
		*)
Packit Service 82fcde
			region=$regions
Packit Service 82fcde
		esac
Packit Service 82fcde
Packit Service 82fcde
		# Determine TZ from country and region.
Packit Service 82fcde
		TZ=`$AWK \
Packit Service 82fcde
			-v country="$country" \
Packit Service 82fcde
			-v region="$region" \
Packit Service 82fcde
			-v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
Packit Service 82fcde
		'
Packit Service 82fcde
			BEGIN {
Packit Service 82fcde
				FS = "\t"
Packit Service 82fcde
				cc = country
Packit Service 82fcde
				while (getline 
Packit Service 82fcde
					if ($0 !~ /^#/  &&  country == $2) {
Packit Service 82fcde
						cc = $1
Packit Service 82fcde
						break
Packit Service 82fcde
					}
Packit Service 82fcde
				}
Packit Service 82fcde
			}
Packit Service 82fcde
			/^#/ { next }
Packit Service 82fcde
			$1 ~ cc && $4 == region { print $3 }
Packit Service 82fcde
		' <"$TZ_ZONE_TABLE"`
Packit Service 82fcde
		esac
Packit Service 82fcde
Packit Service 82fcde
		# Make sure the corresponding zoneinfo file exists.
Packit Service 82fcde
		TZ_for_date=$TZDIR/$TZ
Packit Service 82fcde
		<"$TZ_for_date" || {
Packit Service 82fcde
			say >&2 "$0: time zone files are not set up correctly"
Packit Service 82fcde
			exit 1
Packit Service 82fcde
		}
Packit Service 82fcde
	esac
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
	# Use the proposed TZ to output the current date relative to UTC.
Packit Service 82fcde
	# Loop until they agree in seconds.
Packit Service 82fcde
	# Give up after 8 unsuccessful tries.
Packit Service 82fcde
Packit Service 82fcde
	extra_info=
Packit Service 82fcde
	for i in 1 2 3 4 5 6 7 8
Packit Service 82fcde
	do
Packit Service 82fcde
		TZdate=`LANG=C TZ="$TZ_for_date" date`
Packit Service 82fcde
		UTdate=`LANG=C TZ=UTC0 date`
Packit Service 82fcde
		TZsec=`expr "$TZdate" : '.*:\([0-5][0-9]\)'`
Packit Service 82fcde
		UTsec=`expr "$UTdate" : '.*:\([0-5][0-9]\)'`
Packit Service 82fcde
		case $TZsec in
Packit Service 82fcde
		$UTsec)
Packit Service 82fcde
			extra_info="
Packit Service 82fcde
Selected time is now:	$TZdate.
Packit Service 82fcde
Universal Time is now:	$UTdate."
Packit Service 82fcde
			break
Packit Service 82fcde
		esac
Packit Service 82fcde
	done
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
	# Output TZ info and ask the user to confirm.
Packit Service 82fcde
Packit Service 82fcde
	echo >&2 ""
Packit Service 82fcde
	echo >&2 "The following information has been given:"
Packit Service 82fcde
	echo >&2 ""
Packit Service 82fcde
	case $country%$region%$coord in
Packit Service 82fcde
	?*%?*%)	say >&2 "	$country$newline	$region";;
Packit Service 82fcde
	?*%%)	say >&2 "	$country";;
Packit Service 82fcde
	%?*%?*) say >&2 "	coord $coord$newline	$region";;
Packit Service 82fcde
	%%?*)	say >&2 "	coord $coord";;
Packit Service 82fcde
	*)	say >&2 "	TZ='$TZ'"
Packit Service 82fcde
	esac
Packit Service 82fcde
	say >&2 ""
Packit Service 82fcde
	say >&2 "Therefore TZ='$TZ' will be used.$extra_info"
Packit Service 82fcde
	say >&2 "Is the above information OK?"
Packit Service 82fcde
Packit Service 82fcde
	doselect Yes No
Packit Service 82fcde
	ok=$select_result
Packit Service 82fcde
	case $ok in
Packit Service 82fcde
	Yes) break
Packit Service 82fcde
	esac
Packit Service 82fcde
do coord=
Packit Service 82fcde
done
Packit Service 82fcde
Packit Service 82fcde
case $SHELL in
Packit Service 82fcde
*csh) file=.login line="setenv TZ '$TZ'";;
Packit Service 82fcde
*) file=.profile line="TZ='$TZ'; export TZ"
Packit Service 82fcde
esac
Packit Service 82fcde
Packit Service 82fcde
test -t 1 && say >&2 "
Packit Service 82fcde
You can make this change permanent for yourself by appending the line
Packit Service 82fcde
	$line
Packit Service 82fcde
to the file '$file' in your home directory; then log out and log in again.
Packit Service 82fcde
Packit Service 82fcde
Here is that TZ value again, this time on standard output so that you
Packit Service 82fcde
can use the $0 command in shell scripts:"
Packit Service 82fcde
Packit Service 82fcde
say "$TZ"