home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -websites- / amidoom / bin.lha / bin / tzselect < prev   
Text File  |  1997-12-29  |  7KB  |  290 lines

  1. #! /bin/ksh
  2. # Ask the user about the time zone, and output the resulting TZ value to stdout.
  3. # Interact with the user via stderr and stdin.
  4.  
  5. # Contributed by Paul Eggert <eggert@twinsun.com>.
  6.  
  7. # Porting notes:
  8. #
  9. # This script requires several features of the Korn shell.
  10. # If your host lacks the Korn shell,
  11. # you can use either of the following free programs instead:
  12. #
  13. #    Bourne-Again shell (bash)
  14. #    <URL:ftp://ftp.gnu.ai.mit.edu/pub/gnu/>
  15. #
  16. #    Public domain ksh
  17. #    <URL:ftp://ftp.cs.mun.ca/pub/pdksh/pdksh.tar.gz>
  18. #
  19. # This script also uses several features of modern awk programs.
  20. # If your host lacks awk, or has an old awk that does not conform to Posix.2,
  21. # you can use either of the following free programs instead:
  22. #
  23. #    GNU awk (gawk)
  24. #    <URL:ftp://ftp.gnu.ai.mit.edu/pub/gnu/>
  25. #
  26. #    mawk
  27. #    <URL:ftp://ftp.whidbey.net/pub/brennan/>
  28.  
  29.  
  30. # Specify default values for environment variables if they are unset.
  31. : ${AWK=gawk}
  32. : ${TZDIR=/gg/etc/zoneinfo}
  33.  
  34. # Check for awk Posix compliance.
  35. ($AWK -v x=y 'BEGIN { exit 123 }') </dev/null >/dev/null 2>&1
  36. [ $? = 123 ] || {
  37.     echo >&2 "$0: Sorry, your \`$AWK' program is not Posix compatible."
  38.     exit 1
  39. }
  40.  
  41. # Make sure the tables are readable.
  42. TZ_COUNTRY_TABLE=$TZDIR/iso3166.tab
  43. TZ_ZONE_TABLE=$TZDIR/zone.tab
  44. for f in $TZ_COUNTRY_TABLE $TZ_ZONE_TABLE
  45. do
  46.     <$f || {
  47.         echo >&2 "$0: time zone files are not set up correctly"
  48.         exit 1
  49.     }
  50. done
  51.  
  52. newline='
  53. '
  54. IFS=$newline
  55.  
  56.  
  57. # Work around a bug in bash 1.14.7 and earlier, where $PS3 is sent to stdout.
  58. case $(echo 1 | (select x in x; do break; done) 2>/dev/null) in
  59. ?*) PS3=
  60. esac
  61.  
  62.  
  63. # Begin the main loop.  We come back here if the user wants to retry.
  64. while
  65.  
  66.     echo >&2 'Please identify a location' \
  67.         'so that time zone rules can be set correctly.'
  68.  
  69.     continent=
  70.     country=
  71.     region=
  72.  
  73.  
  74.     # Ask the user for continent or ocean.
  75.  
  76.     echo >&2 'Please select a continent or ocean.'
  77.  
  78.     select continent in \
  79.         Africa \
  80.         Americas \
  81.         Antarctica \
  82.         'Arctic Ocean' \
  83.         Asia \
  84.         'Atlantic Ocean' \
  85.         Australia \
  86.         Europe \
  87.         'Indian Ocean' \
  88.         'Pacific Ocean' \
  89.         'none - I want to specify the time zone using the Posix TZ format.'
  90.     do
  91.         case $continent in
  92.         '')
  93.         echo >&2 'Please enter a number in range.';;
  94.         ?*)
  95.         case $continent in
  96.         Americas) continent=America;;
  97.         *' '*) continent=$(expr "$continent" : '\([^ ]*\)')
  98.         esac
  99.         break
  100.         esac
  101.     done
  102.     case $continent in
  103.     '')
  104.         exit 1;;
  105.     none)
  106.         # Ask the user for a Posix TZ string.  Check that it conforms.
  107.         while
  108.             echo >&2 'Please enter the desired value' \
  109.                 'of the TZ environment variable.'
  110.             echo >&2 'For example, GST-10 is a zone named GST' \
  111.                 'that is 10 hours ahead (east) of UTC.'
  112.             read TZ
  113.             $AWK -v TZ="$TZ" 'BEGIN {
  114.                 tzname = "[^-+,0-9][^-+,0-9][^-+,0-9]+"
  115.                 time = "[0-2]?[0-9](:[0-5][0-9](:[0-5][0-9])?)?"
  116.                 offset = "[-+]?" time
  117.                 date = "(J?[0-9]+|M[0-9]+\.[0-9]+\.[0-9]+)"
  118.                 datetime = "," date "(/" time ")?"
  119.                 tzpattern = "^(:.*|" tzname offset "(" tzname \
  120.                   "(" offset ")?(" datetime datetime ")?)?)$"
  121.                 if (TZ ~ tzpattern) exit 1
  122.                 exit 0
  123.             }'
  124.         do
  125.             echo >&2 "\`$TZ' is not a conforming" \
  126.                 'Posix time zone string.'
  127.         done
  128.         TZ_for_date=$TZ;;
  129.     *)
  130.         # Get list of names of countries in the continent or ocean.
  131.         countries=$($AWK -F'\t' \
  132.             -v continent="$continent" \
  133.             -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
  134.         '
  135.             /^#/ { next }
  136.             $3 ~ ("^" continent "/") {
  137.                 if (!cc_seen[$1]++) cc_list[++ccs] = $1
  138.             }
  139.             END {
  140.                 while (getline <TZ_COUNTRY_TABLE) {
  141.                     if ($0 !~ /^#/) cc_name[$1] = $2
  142.                 }
  143.                 for (i = 1; i <= ccs; i++) {
  144.                     country = cc_list[i]
  145.                     if (cc_name[country]) {
  146.                       country = cc_name[country]
  147.                     }
  148.                     print country
  149.                 }
  150.             }
  151.         ' <$TZ_ZONE_TABLE | sort -f)
  152.  
  153.  
  154.         # If there's more than one country, ask the user which one.
  155.         case $countries in
  156.         *"$newline"*)
  157.             echo >&2 'Please select a country.'
  158.             select country in $countries
  159.             do
  160.                 case $country in
  161.                 '') echo >&2 'Please enter a number in range.';;
  162.                 ?*) break
  163.                 esac
  164.             done
  165.  
  166.             case $country in
  167.             '') exit 1
  168.             esac;;
  169.         *)
  170.             country=$countries
  171.         esac
  172.  
  173.  
  174.         # Get list of names of time zone rule regions in the country.
  175.         regions=$($AWK -F'\t' \
  176.             -v country="$country" \
  177.             -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
  178.         '
  179.             BEGIN {
  180.                 cc = country
  181.                 while (getline <TZ_COUNTRY_TABLE) {
  182.                     if ($0 !~ /^#/  &&  country == $2) {
  183.                         cc = $1
  184.                         break
  185.                     }
  186.                 }
  187.             }
  188.             $1 == cc { print $4 }
  189.         ' <$TZ_ZONE_TABLE)
  190.  
  191.  
  192.         # If there's more than one region, ask the user which one.
  193.         case $regions in
  194.         *"$newline"*)
  195.             echo >&2 'Please select one of the following' \
  196.                 'time zone regions.'
  197.             select region in $regions
  198.             do
  199.                 case $region in
  200.                 '') echo >&2 'Please enter a number in range.';;
  201.                 ?*) break
  202.                 esac
  203.             done
  204.             case $region in
  205.             '') exit 1
  206.             esac;;
  207.         *)
  208.             region=$regions
  209.         esac
  210.  
  211.         # Determine TZ from country and region.
  212.         TZ=$($AWK -F'\t' \
  213.             -v country="$country" \
  214.             -v region="$region" \
  215.             -v TZ_COUNTRY_TABLE="$TZ_COUNTRY_TABLE" \
  216.         '
  217.             BEGIN {
  218.                 cc = country
  219.                 while (getline <TZ_COUNTRY_TABLE) {
  220.                     if ($0 !~ /^#/  &&  country == $2) {
  221.                         cc = $1
  222.                         break
  223.                     }
  224.                 }
  225.             }
  226.             $1 == cc && $4 == region { print $3 }
  227.         ' <$TZ_ZONE_TABLE)
  228.  
  229.         # Make sure the corresponding zoneinfo file exists.
  230.         TZ_for_date=$TZDIR/$TZ
  231.         <$TZ_for_date || {
  232.             echo >&2 "$0: time zone files are not set up correctly"
  233.             exit 1
  234.         }
  235.     esac
  236.  
  237.  
  238.     # Use the proposed TZ to output the current date relative to UTC.
  239.     # Loop until they agree in seconds.
  240.     # Give up after 8 unsuccessful tries.
  241.  
  242.     extra_info=
  243.     for i in 1 2 3 4 5 6 7 8
  244.     do
  245.         TZdate=$(LANG=C TZ="$TZ_for_date" /gg/bin/date)
  246.         UTdate=$(LANG=C TZ=UTC0 /gg/bin/date)
  247.         TZsec=$(expr "$TZdate" : '.*:\([0-5][0-9]\)')
  248.         UTsec=$(expr "$UTdate" : '.*:\([0-5][0-9]\)')
  249.         case $TZsec in
  250.         $UTsec)
  251.             extra_info="
  252. Local time is now:    $TZdate.
  253. Universal Time is now:    $UTdate."
  254.             break
  255.         esac
  256.     done
  257.  
  258.  
  259.     # Output TZ info and ask the user to confirm.
  260.  
  261.     echo >&2 ""
  262.     echo >&2 "The following information has been given:"
  263.     echo >&2 ""
  264.     case $country+$region in
  265.     ?*+?*)    echo >&2 "    $country$newline    $region";;
  266.     ?*+)    echo >&2 "    $country";;
  267.     +)    echo >&2 "    TZ='$TZ'"
  268.     esac
  269.     echo >&2 ""
  270.     echo >&2 "Therefore TZ='$TZ' will be used.$extra_info"
  271.     echo >&2 "Is the above information OK?"
  272.  
  273.     ok=
  274.     select ok in Yes No
  275.     do
  276.         case $ok in
  277.         '') echo >&2 'Please enter 1 for Yes, or 2 for No.';;
  278.         ?*) break
  279.         esac
  280.     done
  281.     case $ok in
  282.     '') exit 1;;
  283.     Yes) break
  284.     esac
  285. do :
  286. done
  287.  
  288. # Output the answer.
  289. echo "$TZ"
  290.