/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <tzfile.h>
#include <fcntl.h>
#include <regex.h>
#include <errno.h>
#include <libintl.h>
#include <libzoneinfo.h>
#include <libscf.h>
/* Internal Declarations */
static char *skipwhite(char *);
static int skipline(char *);
static int trav_link(char **);
static void remove_component(char *);
static void strip_quotes(char *, char *);
static int _tz_match(const char *, const char *);
static char *_conv_gmt_zoneinfo(int);
static char *_conv_gmt_posix(int);
/*
* get_tz_continents() reads the continent.tab file, and
* returns a list of continents.
*/
int
{
/* open continents file */
/* fopen() sets errno */
return (-1);
}
/* read and count continents */
ncount = 0;
/*CONSTANTCONDITION*/
while (1) {
/* fgets() sets errno */
ncount = -1;
}
break;
}
/* Skip comments or blank/whitespace lines */
if (status == 1)
continue;
else {
ncount = -1;
break;
}
}
/* Get continent name */
ncount = -1;
break;
}
/* create continent struct */
if ((lcp = (struct tz_continent *)
ncount = -1;
break;
}
/* Get continent description */
(void) free_tz_continents(lcp);
ncount = -1;
break;
}
/* Get localized continent description */
(void) free_tz_continents(lcp);
ncount = -1;
break;
}
} else {
}
ncount++;
}
if (ncount == -1) {
(void) free_tz_continents(head);
}
if (sav_errno)
} else {
}
return (ncount);
}
/*
* get_tz_countries() finds the list of countries from the zone_sun.tab
* file, for the input continent, and retrieves the country
* names from the country.tab file. It also retrieves the localized
* country names. The returned list of countries is sorted by the
* countries' localized name fields.
*/
int
{
return (-1);
}
ccbuf[0] = '\0';
/* open zone_sun.tab and country.tab files */
/* fopen() sets errno */
return (-1);
}
/* fopen() sets errno */
return (-1);
}
/* read timezones to match continents, and get countries */
ncount = 0;
/*CONSTANTCONDITION*/
while (1) {
/* fgets() error - errno set */
ncount = -1;
}
break;
}
/* Skip comments or blank/whitespace lines */
if (status == 1)
continue;
else {
ncount = -1;
break;
}
}
/*
* If country matches previously *matched* country, skip
* entry, since zone.tab is alphabetized by country code
* (It should be a *matched* country, because the same country
* can be in different continents.)
*/
/* Get country code */
ncount = -1;
break;
}
/* Check country code cache; skip if already found */
continue;
}
/* Get coordinates */
COORD_FMTLEN1) &&
(len_coord != COORD_FMTLEN2)) {
ncount = -1;
break;
}
/* Get timezone name (Skip timezone description) */
ncount = -1;
break;
}
/* If continents match, allocate a country struct */
if ((cp = (struct tz_country *)
ncount = -1;
break;
}
/* Copy and save country code (len already checked) */
/* Create linked list */
} else {
};
ncount++;
}
} /* while */
if (ncount == -1)
goto error;
/* Get country name from country.tab; get localized country name */
/* Read country list, match country codes to process entry */
/*CONSTANTCONDITION*/
while (1) {
/* fgets() sets errno */
ncount = -1;
}
break;
}
/* Skip comments or blank/whitespace lines */
if (status == 1)
continue;
else {
ncount = -1;
break;
}
}
/* Match country codes */
ncount = -1;
break;
}
/* Get country description, and localized desc. */
/* Skip to country description */
ncount = -1;
break;
}
ncount = -1;
break;
}
/* Get localized country description */
ncount = -1;
break;
}
} else if (cmp > 0) {
/* Keep searching country.tab */
continue;
} else {
/* Not found - should not happen */
ncount = -1;
break;
}
/* done with countries list */
break;
} else {
}
} /* while */
/* Now sort the list by ctry_display_desc field */
if ((ncount != -1) &&
/*
* First copy list to a static array for qsort() to use.
* Use the cnt_next field to point back to original structure.
*/
for (i = 0; i < ncount; i++) {
}
/* Next, call qsort() using strcoll() to order */
(int (*)(const void *, const void *))compar);
/* Rearrange the country list according to qsort order */
for (i = 0; i < ncount; i++) {
}
/* Last, free the static buffer */
} else {
if (ncount != -1)
ncount = -1;
}
if (ncount == -1) {
/* free the linked list */
(void) free_tz_countries(head);
if (sav_errno)
} else {
}
return (ncount);
}
/*
* get_timezones_by_country() finds the list of timezones from the
* zone_sun.tab file, for the input country.
*/
int
struct tz_country *country)
{
/* open zone.tab file */
return (-1);
/* Read through zone.tab until countries match */
/*CONSTANTCONDITION*/
while (1) {
break;
} else {
/* fgets() sets errno */
ncount = -1;
break;
}
}
/* Skip comments or blank/whitespace lines */
if (status == 1)
continue;
else {
ncount = -1;
break;
}
}
/*
* Find country entries, or detect if no country matches.
*/
ncount = -1;
break;
}
match = 1;
/* Get coordinates */
COORD_FMTLEN1) &&
(len_coord != COORD_FMTLEN2)) {
ncount = -1;
break;
}
/* Get Olson timezone name */
/* Get Solaris compatible timezone name */
/* No timezone description */
len_tz--;
len_tzdesc = 0;
} else {
/* Get timezone description */
len_tz);
NEWLINE);
}
/*
* Check tz name lengths. This check assumes the
* tz_oname and tz_name fields are the same size.
* (since tz_name may be written with lp_otz, if
* lp_tz is "-".)
*/
ncount = -1;
break;
}
/* Create timezone struct */
if ((tp = (struct tz_timezone *)
NULL) {
ncount = -1;
break;
}
/*
* Copy the timezone names - use the Solaris
* compatible timezone name if one exists,
* otherwise use the current Olson timezone
* name.
*/
}
/* If name has numeric digits, prefix ':' */
ncount = -1;
break;
}
} else {
}
/* Process timezone description, if one exists */
== NULL) {
ncount = -1;
(void) free_timezones(tp);
break;
}
/* Get localized country description */
ncount = -1;
(void) free_timezones(tp);
break;
}
} else {
}
/* Get coordinate information */
ncount = -1;
(void) free_timezones(tp);
break;
}
/* Store timezone struct in a linked list */
} else {
}
ncount++;
} else {
if (match == 1) {
/*
* At this point, since zone_sun.tab is ordered,
* if we've already found timezone entries for
* the input country, then we've found all of
* the desired timezone entries (since we will
* be past that country's section in
* zone_sun.tab), and we are done.
*/
break;
}
}
}
/* Finish up */
if (ncount == -1) {
(void) free_timezones(head);
if (sav_errno)
} else {
}
return (ncount);
}
int
{
}
return (0);
}
int
{
}
return (0);
}
int
{
}
return (0);
}
/*
* conv_gmt() returns a GMT-offset style timezone
* If flag = 0, return Quoted POSIX timezone like: <GMT+8>+8
*/
char *
{
int hour;
char *cp;
return (NULL);
}
if (flag == 0) {
} else if (flag == 1) {
} else {
return (NULL);
}
return (cp);
}
static char *
{
char *cp;
char xsign;
if (hour == 0) {
return (NULL);
}
} else {
if (hour < 0) {
xsign = '-';
/* make hour positive for snprintf() */
} else {
xsign = '+';
}
return (NULL);
}
}
return (cp);
}
static char *
{
char *cp;
char xsign;
if (hour < 0) {
xsign = '-';
/* make hour positive for snprintf() */
} else {
xsign = '+';
}
return (NULL);
}
return (cp);
}
/* Regular expression for POSIX GMT-offset timezone */
/*
* Regular expression for quoted POSIX timezone.
*/
/* Avoid alphabetic ranges (eg, a-z) due to effect of LC_COLLATE */
/* Regular expression for unquoted POSIX timezone */
/* Regular expression for POSIX timezone */
/*
* isvalid_tz() checks if timezone is a valid POSIX or zoneinfo
* timezone, depending on the value of flag. For flag = _VTZ_INSTALL,
* isvalid_tz() behaves according to the behavior of Solaris Install
* were validated. isvalid_tz() has a special check for GMT+-* timezones
* no longer works.
*
* isvalid_tz() returns 1 if a valid timezone is detected.
*/
int
{
return (0);
}
/* First check if timezone is a valid POSIX timezone */
switch (flag) {
case _VTZ_INSTALL:
/*
* Special check for POSIX GMT timezone.
* If no match, check for zoneinfo timezone below
*/
/* Valid GMT timezone */
return (1);
}
break;
case _VTZ_POSIX:
/* Check for generic POSIX timezone */
/* Valid POSIX timezone */
return (1);
}
/* Invalid POSIX timezone */
return (0);
case _VTZ_ALL:
/* Check for generic POSIX timezone */
/* Valid POSIX timezone */
return (1);
}
break;
case _VTZ_ZONEINFO:
break;
default:
return (0);
}
/*
* Check for valid zoneinfo timezone -
* open zoneinfo file and check for magic number
*/
/* skip prepended ':' if one exists */
if (*timezone == ':') {
timezone++;
}
/* Construct full zoneinfo pathname */
/* too long */
return (0);
}
} else {
/* too long */
return (0);
}
}
return (0);
}
sizeof (struct tzhead)) {
return (0);
}
return (0);
}
return (0);
}
/* Valid zoneinfo timezone */
return (1);
}
int
{
int ret;
if (ret != 0) {
return (-1);
}
if (ret == 0) {
#ifdef DEBUG
#endif
return (0);
}
#ifdef DEBUG
#endif
return (-1);
}
char *
{
sizeof (fname)) {
return (NULL);
} else if (ret < 0) {
return (NULL);
}
return (NULL);
p = &buff[3];
*sp = '\0';
*sp = '\0';
}
strip_quotes(p, p);
}
return (NULL);
}
return (ptr);
}
}
/* Either reached EOF with no TZ= entry, or got fgets() error */
/* No "TZ=" entry found */
}
return (NULL);
}
/*
* timezone SMF service based on input.
*
* Returns 0 on success or -1 on failure.
*/
static int
{
scf_handle_t *h = NULL;
scf_handle_bind(h) != 0 ||
goto cleanup;
}
goto cleanup;
}
SCF_TYPE_ASTRING) == -1 ||
goto cleanup;
}
(smf_refresh_instance(SMF_TIMEZONE_FMRI) == 0)) {
err = 0;
}
if (h) {
(void) scf_handle_unbind(h);
}
return (err);
}
int
{
char *tdb;
const char *tzfmt;
return (-1);
/*
* If root is '/', then set the tz in SMF service
*/
if (root == "/")
return (set_smf_tz(tz));
/*
* If it is alternate root, then set
*/
} else {
}
sizeof (fname)) {
return (-1);
} else if (ret < 0) {
return (-1);
}
/*
* Generate temporary file name to use. We make sure it's in the same
* directory as the db we're processing so that we can use rename to
* do the replace later. Otherwise we run the risk of being on the
* wrong filesystem and having rename() fail for that reason.
*/
return (-1);
return (-1);
}
len = 1;
}
return (-1);
}
return (-1);
}
return (-1);
}
/* Preserve permissions of current file if it exists */
return (-1);
}
return (-1);
}
return (-1);
}
return (-1);
}
replaced = 1;
}
return (-1);
}
}
return (-1);
}
/*
* no "TZ=" entry found in the init file.
*/
if (!replaced &&
return (-1);
}
return (-1);
}
return (-1);
} else {
return (0);
}
}
/*
* Function to traverse a symlink path to find the real file at the end of
* the rainbow.
*/
int
{
char *tp;
if (newpath[0] != '/') {
return (-1);
}
return (-1);
}
}
/*
* ENOENT or EINVAL is the normal exit case of the above loop.
*/
return (0);
else
return (-1);
}
void
{
char *p;
if (p == NULL) {
} else {
*p = '\0'; /* zap it */
}
}
/*
* get_coord() fills in the tz_coord structure of the tz_timezone
* struct. It returns 0 on success, or -1 on error.
* The format of p_coord is:
*
* Latitude and longitude of the zone's principal location
* in ISO 6709 sign-degrees-minutes-seconds format,
* either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS,
* first latitude (+ is north), then longitude (+ is east).
*/
static int
{
/* Figure out which format to use */
if (len_coord == COORD_FMTLEN1) {
/* "+-DDMM+-DDDMM" */
} else if (len_coord == COORD_FMTLEN2) {
/* "+-DDMMSS+-DDDMMSS" */
} else {
/* error */
return (-1);
}
/*
* First time through, get values for latitude;
* second time through, get values for longitude.
*/
for (i = 0; i < 2; i++) {
/* Set up pointers */
if (i == 0) {
/* Do latitude */
} else {
/* Do longitude */
}
if (*p_coord == '+') {
*signp = 1;
} else if (*p_coord == '-') {
*signp = -1;
} else {
return (-1);
}
p_coord++;
/* Get DD latitude, or DDD longitude */
errno = 0;
return (-1);
errno = 0;
return (-1);
p_coord += COORD_MLEN;
if (fmt_flag == COORD_FMT2) {
errno = 0;
return (-1);
p_coord += COORD_SLEN;
} else {
*secp = 0;
}
}
return (0);
}
static char *
{
cp++;
}
return (cp);
}
/*
* skipline() checks if the line begins with a comment
* comment character anywhere in the line, or if the
* line is only whitespace.
* skipline() also checks if the line read is too long to
* fit in the buffer.
* skipline() returns 1 if the line can be skipped, -1 if
* the line read is too long, and 0 if the line should not be skipped.
*/
static int
{
return (-1);
return (1);
else
return (0);
}
/*
* strip_quotes -- strip double (") or single (') quotes
*/
static void
{
while (*from != '\0') {
} else {
strip_ptr++;
} else {
to++;
}
}
from++;
}
*strip_ptr = '\0';
} else {
*to = '\0';
}
}
/*
* Compare function used by get_tz_countries() - uses strcoll()
* for locale-sensitive comparison for the localized country names.
*/
static int
{
int ret;
return (ret);
}