2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. 2N/A#
define CCLEN 2 /* country code length */ 2N/A#
define GMT_MAX (
12*
60*
60)
/* The maximum GMT offset */ 2N/A#
define GMT_MIN (-
13*
60*
60)
/* The minimum GMT offset */ 2N/A#
define GMT0_FMT "GMT0" /* backwards compatibility name */ 2N/A#
define TZ_FMT "TZ=%s\n" /* format TZ entry init file */ 2N/A#
define TZ_FMT_Q "TZ=\"%s\"\n" /* format quoted TZ entry init file */ 2N/A/* Internal Declarations */ 2N/A * returns a list of continents. 2N/A char *
lp;
/* line pointer */ 2N/A /* open continents file */ 2N/A /* fopen() sets errno */ 2N/A /* read and count continents */ 2N/A /*CONSTANTCONDITION*/ 2N/A /* fgets() sets errno */ 2N/A /* Get continent name */ 2N/A /* create continent struct */ 2N/A /* Get continent description */ 2N/A /* Get localized continent description */ 2N/A * get_tz_countries() finds the list of countries from the zone_sun.tab 2N/A * file, for the input continent, and retrieves the country 2N/A * names from the country.tab file. It also retrieves the localized 2N/A * country names. The returned list of countries is sorted by the 2N/A * countries' localized name fields. 2N/A /* fopen() sets errno */ 2N/A /* fopen() sets errno */ 2N/A /* read timezones to match continents, and get countries */ 2N/A /*CONSTANTCONDITION*/ 2N/A /* fgets() error - errno set */ 2N/A * If country matches previously *matched* country, skip 2N/A * entry, since zone.tab is alphabetized by country code 2N/A * (It should be a *matched* country, because the same country 2N/A * can be in different continents.) 2N/A /* Get country code */ 2N/A /* Check country code cache; skip if already found */ 2N/A /* Get coordinates */ 2N/A /* Get timezone name (Skip timezone description) */ 2N/A /* If continents match, allocate a country struct */ 2N/A /* Copy and save country code (len already checked) */ 2N/A /* Create linked list */ 2N/A /* Get country name from country.tab; get localized country name */ 2N/A /* Read country list, match country codes to process entry */ 2N/A /*CONSTANTCONDITION*/ 2N/A /* fgets() sets errno */ 2N/A /* Match country codes */ 2N/A /* Get country description, and localized desc. */ 2N/A /* Skip to country description */ 2N/A lp +=
len;
/* lp points to country desc. */ 2N/A /* Get localized country description */ 2N/A /* Not found - should not happen */ 2N/A /* done with countries list */ 2N/A /* Now sort the list by ctry_display_desc field */ 2N/A * First copy list to a static array for qsort() to use. 2N/A * Use the cnt_next field to point back to original structure. 2N/A /* Next, call qsort() using strcoll() to order */ 2N/A (
int (*)(
const void *,
const void *))
compar);
2N/A /* Rearrange the country list according to qsort order */ 2N/A /* Last, free the static buffer */ 2N/A /* free the linked list */ 2N/A * get_timezones_by_country() finds the list of timezones from the 2N/A /* Read through zone.tab until countries match */ 2N/A /*CONSTANTCONDITION*/ 2N/A /* fgets() sets errno */ 2N/A * Find country entries, or detect if no country matches. 2N/A /* Get coordinates */ 2N/A /* Get Olson timezone name */ 2N/A /* Get Solaris compatible timezone name */ 2N/A /* No timezone description */ 2N/A /* Get timezone description */ 2N/A * Check tz name lengths. This check assumes the 2N/A * tz_oname and tz_name fields are the same size. 2N/A * (since tz_name may be written with lp_otz, if 2N/A /* Create timezone struct */ 2N/A * Copy the timezone names - use the Solaris 2N/A * compatible timezone name if one exists, 2N/A * otherwise use the current Olson timezone 2N/A /* If name has numeric digits, prefix ':' */ 2N/A /* Process timezone description, if one exists */ 2N/A /* Get localized country description */ 2N/A /* Get coordinate information */ 2N/A /* Store timezone struct in a linked list */ 2N/A * if we've already found timezone entries for 2N/A * the input country, then we've found all of 2N/A * the desired timezone entries (since we will 2N/A * be past that country's section in 2N/A * conv_gmt() returns a GMT-offset style timezone 2N/A * If flag = 0, return Quoted POSIX timezone like: <GMT+8>+8 2N/A * If flag = 1, return zoneinfo timezone like: :Etc/GMT+8 2N/A /* make hour positive for snprintf() */ 2N/A /* make hour positive for snprintf() */ 2N/A/* Regular expression for POSIX GMT-offset timezone */ 2N/A * Regular expression for quoted POSIX timezone. 2N/A/* Avoid alphabetic ranges (eg, a-z) due to effect of LC_COLLATE */ 2N/A#
define _ALPHA "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 2N/A#
define _NUM "0123456789" /* for safe */ 2N/A/* Regular expression for unquoted POSIX timezone */ 2N/A/* Regular expression for POSIX timezone */ 2N/A#
define _DATEJ "J(([0-2]?[0-9]?[0-9])|3[0-5][0-9]|36[0-5])" 2N/A#
define _DATEn "(([0-2]?[0-9]?[0-9])|3[0-5][0-9]|36[0-5])" 2N/A#
define _DATEM "M([0-9]|10|11|12)\\.[1-5]\\.[0-6]" 2N/A#
define _HH "(([0-1]?[0-9])|20|21|22|23|24)" 2N/A * isvalid_tz() checks if timezone is a valid POSIX or zoneinfo 2N/A * timezone, depending on the value of flag. For flag = _VTZ_INSTALL, 2N/A * isvalid_tz() behaves according to the behavior of Solaris Install 2N/A * were validated. isvalid_tz() has a special check for GMT+-* timezones 2N/A * isvalid_tz() returns 1 if a valid timezone is detected. 2N/A /* First check if timezone is a valid POSIX timezone */ 2N/A * Special check for POSIX GMT timezone. 2N/A * If no match, check for zoneinfo timezone below 2N/A /* Valid GMT timezone */ 2N/A /* Check for generic POSIX timezone */ 2N/A /* Valid POSIX timezone */ 2N/A /* Invalid POSIX timezone */ 2N/A /* Check for generic POSIX timezone */ 2N/A /* Valid POSIX timezone */ 2N/A * Check for valid zoneinfo timezone - 2N/A * open zoneinfo file and check for magic number 2N/A /* skip prepended ':' if one exists */ 2N/A /* Construct full zoneinfo pathname */ 2N/A /* Valid zoneinfo timezone */ 2N/A /* Either reached EOF with no TZ= entry, or got fgets() error */ 2N/A /* No "TZ=" entry found */ 2N/A * timezone SMF service based on input. 2N/A * Returns 0 on success or -1 on failure. 2N/A * If root is '/', then set the tz in SMF service 2N/A * If it is alternate root, then set 2N/A * Generate temporary file name to use. We make sure it's in the same 2N/A * directory as the db we're processing so that we can use rename to 2N/A * do the replace later. Otherwise we run the risk of being on the 2N/A * wrong filesystem and having rename() fail for that reason. 2N/A /* Preserve permissions of current file if it exists */ 2N/A * no "TZ=" entry found in the init file. 2N/A * Function to traverse a symlink path to find the real file at the end of 2N/A * ENOENT or EINVAL is the normal exit case of the above loop. 2N/A *
path =
'\0';
/* set path to null str */ 2N/A *p =
'\0';
/* zap it */ 2N/A * get_coord() fills in the tz_coord structure of the tz_timezone 2N/A * struct. It returns 0 on success, or -1 on error. 2N/A * The format of p_coord is: 2N/A * Latitude and longitude of the zone's principal location 2N/A * in ISO 6709 sign-degrees-minutes-seconds format, 2N/A * either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS, 2N/A * first latitude (+ is north), then longitude (+ is east). 2N/A /* Figure out which format to use */ 2N/A /* "+-DDMM+-DDDMM" */ 2N/A /* "+-DDMMSS+-DDDMMSS" */ 2N/A * First time through, get values for latitude; 2N/A * second time through, get values for longitude. 2N/A for (i = 0; i <
2; i++) {
2N/A /* Set up pointers */ 2N/A /* Get DD latitude, or DDD longitude */ 2N/A while (*
cp && ((*
cp ==
' ') || (*
cp ==
'\t'))) {
2N/A * skipline() checks if the line begins with a comment 2N/A * comment character anywhere in the line, or if the 2N/A * line is only whitespace. 2N/A * skipline() also checks if the line read is too long to 2N/A * fit in the buffer. 2N/A * skipline() returns 1 if the line can be skipped, -1 if 2N/A * the line read is too long, and 0 if the line should not be skipped. 2N/A * strip_quotes -- strip double (") or single (') quotes 2N/A * Compare function used by get_tz_countries() - uses strcoll() 2N/A * for locale-sensitive comparison for the localized country names.