usr/src/lib/libc/port/gen/localtime.c
author Jon Tibble <meths@btinternet.com>
Thu, 09 Dec 2010 22:32:39 +0100
changeset 13255 4afa820d78b9
parent 13249 abc9578d5a0e
child 13269 52325acbd90e
permissions -rw-r--r--
298 SPARC build fails in smt_pause.o 478 Build needs fixing for pkgdepend flag day Reviewed by: [email protected] Reviewed by: [email protected] Reviewed by: [email protected] Approved by: [email protected]
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
2923
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
     5
 * Common Development and Distribution License (the "License").
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
2923
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
    21
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
    23
 * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
    24
 */
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
    25
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
    26
/*
8563
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
    27
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
/*	Copyright (c) 1988 AT&T	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
/*	  All Rights Reserved  	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 * A part of this file comes from public domain source, so
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 * clarified as of June 5, 1996 by Arthur David Olson
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 * ([email protected]).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
 * localtime.c
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
 * This file contains routines to convert struct tm to time_t and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
 * back as well as adjust time values based on their timezone, which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
 * is a local offset from GMT (Greenwich Mean Time).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
 * Many timezones actually consist of more than one offset from GMT.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
 * The GMT offset that is considered the normal offset is referred
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
 * to as standard time.  The other offset is referred to as alternate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
 * time, but is better known as daylight savings time or summer time.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
 * The current timezone for an application is derived from the TZ
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
 * environment variable either as defined in the environment or in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
 * /etc/default/init.  As defined by IEEE 1003.1-1990 (POSIX), the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
 * TZ variable can either be:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
 *    :<characters>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
 * or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
 *    <std><offset1>[<dst>[<offset2>]][,<start>[/<time>],<end>[/<time>]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
 * <characters> is an implementation-defined string that somehow describes
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
 * a timezone.  The implementation-defined description of a timezone used
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
 * in Solaris is based on the public domain zoneinfo code available from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
 * elsie.nci.nih.gov and a timezone that is specified in this way is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
 * referred to as a zoneinfo timezone.  An example of this is ":US/Pacific".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
 * The precise definition of the second format can be found in POSIX,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
 * but, basically, <std> is the abbreviation for the timezone in standard
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
 * (not daylight savings time), <offset1> is the standard offset from GMT,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
 * <dst> is the abbreviation for the timezone in daylight savings time and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
 * <offset2> is the daylight savings time offset from GMT.  The remainder
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
 * specifies when daylight savings time begins and ends.  A timezone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
 * specified in this way is referred to as a POSIX timezone.  An example
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
 * of this is "PST7PDT".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
 * In Solaris, there is an extension to this.  If the timezone is not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
 * preceded by a ":" and it does not parse as a POSIX timezone, then it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
 * will be treated as a zoneinfo timezone.  Much usage of zoneinfo
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
 * timezones in Solaris is done without the leading ":".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
 * A zoneinfo timezone is a reference to a file that contains a set of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
 * rules that describe the timezone.  In Solaris, the file is in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
 * /usr/share/lib/zoneinfo.  The file is generated by zic(1M), based
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
 * on zoneinfo rules "source" files.  This is all described on the zic(1M)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
 * man page.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
 * Functions that are common to ctime(3C) and cftime(3C)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 2923
diff changeset
    91
#pragma weak _tzset = tzset
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 2923
diff changeset
    93
#include "lint.h"
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
#include "libc.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
#include "tsd.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
#include <stdarg.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
#include <mtlib.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
#include <ctype.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
#include <stdio.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
#include <limits.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
#include <time.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
#include <unistd.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
#include <stdlib.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
#include <string.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
#include <tzfile.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
#include <thread.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
#include <synch.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
#include <fcntl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
#include <errno.h>
2923
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
   112
#include <deflt.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
#include <sys/stat.h>
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   114
#include <sys/mman.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
2292
9d2338c070a5 6444194 64-bit localtime() transitions wrong past 2038 for POSIX timezones
robbin
parents: 1138
diff changeset
   116
/* JAN_01_1902 cast to (int) - negative number of seconds from 1970 */
9d2338c070a5 6444194 64-bit localtime() transitions wrong past 2038 for POSIX timezones
robbin
parents: 1138
diff changeset
   117
#define	JAN_01_1902		(int)0x8017E880
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
#define	LEN_TZDIR		(sizeof (TZDIR) - 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
#define	TIMEZONE		"/etc/default/init"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
#define	TZSTRING		"TZ="
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   121
#define	HASHTABLE		31
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
#define	LEAPS_THRU_END_OF(y)	((y) / 4 - (y) / 100 + (y) / 400)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
/* Days since 1/1/70 to 12/31/(1900 + Y - 1) */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
#define	DAYS_SINCE_70(Y) (YR((Y)-1L) - YR(70-1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
#define	YR(X) /* Calc # days since 0 A.D. X = curr. yr - 1900 */ \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
	((1900L + (X)) * 365L + (1900L + (X)) / 4L - \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
	(1900L + (X)) / 100L + ((1900L + (X)) - 1600L) / 400L)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
 * The following macros are replacements for detzcode(), which has
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
 * been in the public domain versions of the localtime.c code for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
 * a long time. The primatives supporting the CVTZCODE macro are
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
 * implemented differently for different endianness (ie. little
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
 * vs. big endian) out of necessity, to account for the different
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
 * byte ordering of the quantities being fetched.  Both versions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
 * are substantially faster than the detzcode() macro.  The big
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
 * endian version is approx. 6.8x faster than detzcode(), the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
 * little endian version is approximately 3x faster, due to the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
 * extra shifting requiring to change byte order.  The micro
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
 * benchmarks used to compare were based on the SUNWSpro SC6.1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
 * (and later) compilers.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
#if defined(__sparc) || defined(__sparcv9)  /* big endian */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
#define	GET_LONG(p) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
	    *(uint_t *)(p)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
#define	GET_SHORTS(p) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
	    *(ushort_t *)(p) << 16 |\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
	    *(ushort_t *)((p) + 2)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
#define	GET_CHARS(p) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
	    *(uchar_t *)(p) << 24 |\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
	    *(uchar_t *)((p) + 1) << 16 |\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
	    *(uchar_t *)((p) + 2) << 8  |\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
	    *(uchar_t *)((p) + 3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
#else /* little endian */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
#define	GET_BYTE(x) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
	    ((x) & 0xff)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
#define	SWAP_BYTES(x) ((\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
	    GET_BYTE(x) << 8) |\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
	    GET_BYTE((x) >> 8))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
#define	SWAP_WORDS(x) ((\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
	    SWAP_BYTES(x) << 16) |\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	    SWAP_BYTES((x) >> 16))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
#define	GET_LONG(p) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
	    SWAP_WORDS(*(uint_t *)(p))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
#define	GET_SHORTS(p) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
	    SWAP_BYTES(*(ushort_t *)(p)) << 16 |\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
	    SWAP_BYTES(*(ushort_t *)((p) + 2))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
#define	GET_CHARS(p) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
	    GET_BYTE(*(uchar_t *)(p)) << 24 |\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
	    GET_BYTE(*(uchar_t *)((p) + 1)) << 16 |\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
	    GET_BYTE(*(uchar_t *)((p) + 2)) << 8 |\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
	    GET_BYTE(*(uchar_t *)((p) + 3))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
#define	IF_ALIGNED(ptr, byte_alignment) \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
			!((uintptr_t)(ptr) & (byte_alignment - 1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
#define	CVTZCODE(p) (int)(\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
	    IF_ALIGNED(p, 4) ? GET_LONG(p) :\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
	    IF_ALIGNED(p, 2) ? GET_SHORTS(p) : GET_CHARS(p));\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
	    p += 4;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
#ifndef	FALSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
#define	FALSE	(0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
#ifndef	TRUE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
#define	TRUE	(1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
extern	mutex_t		_time_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
extern const int	__lyday_to_month[];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
extern const int	__yday_to_month[];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
extern const int	__mon_lengths[2][MONS_PER_YEAR];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
extern const int	__year_lengths[2];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
const char	_tz_gmt[4] = "GMT";	/* "GMT"  */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
const char	_tz_spaces[4] = "   ";	/* "   "  */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
static const char	_posix_gmt0[5] = "GMT0";	/* "GMT0" */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
typedef struct ttinfo {			/* Time type information */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
	long		tt_gmtoff;	/* GMT offset in seconds */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
	int		tt_isdst;	/* used to set tm_isdst */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
	int		tt_abbrind;	/* abbreviation list index */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
	int		tt_ttisstd;	/* TRUE if trans is std time */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
	int		tt_ttisgmt;	/* TRUE if transition is GMT */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
} ttinfo_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
typedef struct lsinfo {			/* Leap second information */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	time_t		ls_trans;	/* transition time */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	long		ls_corr;	/* correction to apply */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
} lsinfo_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
typedef struct previnfo {		/* Info about *prev* trans */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	ttinfo_t	*std;		/* Most recent std type */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
	ttinfo_t	*alt;		/* Most recent alt type */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
} prev_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
typedef enum {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
	MON_WEEK_DOW,		/* Mm.n.d - month, week, day of week */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
	JULIAN_DAY,		/* Jn - Julian day */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
	DAY_OF_YEAR		/* n - day of year */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
} posrule_type_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
typedef struct {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
	posrule_type_t	r_type;		/* type of rule */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	int		r_day;		/* day number of rule */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
	int		r_week;		/* week number of rule */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
	int		r_mon;		/* month number of rule */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
	long		r_time;		/* transition time of rule */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
} rule_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
typedef struct {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
	rule_t		*rules[2];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
	long		offset[2];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
	long long	rtime[2];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
} posix_daylight_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
 * Note: ZONERULES_INVALID used for global curr_zonerules variable, but not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
 * for zonerules field of state_t.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
typedef enum {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
	ZONERULES_INVALID, POSIX, POSIX_USA, ZONEINFO
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
} zone_rules_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
 * The following members are allocated from the libc-internal malloc:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
 *	zonename
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
 *	chars
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
typedef struct state {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
	const char	*zonename;		/* Timezone */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
	struct state	*next;			/* next state */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	zone_rules_t	zonerules;		/* Type of zone */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
	int		daylight;		/* daylight global */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
	long		default_timezone;	/* Def. timezone val */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
	long		default_altzone;	/* Def. altzone val */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
	const char	*default_tzname0;	/* Def tz..[0] val */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
	const char	*default_tzname1;	/* Def tz..[1] val  */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
	int		leapcnt;		/* # leap sec trans */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
	int		timecnt;		/* # transitions */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
	int		typecnt;		/* # zone types */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	int		charcnt;		/* # zone abbv. chars */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	char		*chars;			/* Zone abbv. chars */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
	size_t		charsbuf_size;		/* malloc'ed buflen */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
	prev_t		prev[TZ_MAX_TIMES];	/* Pv. trans info */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
	time_t		ats[TZ_MAX_TIMES];	/* Trans.  times */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
	uchar_t		types[TZ_MAX_TIMES];	/* Type indices */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
	ttinfo_t	ttis[TZ_MAX_TYPES];	/* Zone types */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	lsinfo_t	lsis[TZ_MAX_LEAPS];	/* Leap sec trans */
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   290
	int		last_ats_idx;		/* last ats index */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
	rule_t		start_rule;		/* For POSIX w/rules */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
	rule_t		end_rule;		/* For POSIX w/rules */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
} state_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   295
typedef struct tznmlist {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   296
	struct tznmlist *link;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   297
	char	name[1];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   298
} tznmlist_t;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   299
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   300
static const char	*systemTZ;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   301
static tznmlist_t	*systemTZrec;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
static const char	*namecache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   305
static state_t		*tzcache[HASHTABLE];
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   307
#define	TZNMC_SZ	43
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   308
static tznmlist_t	*tznmhash[TZNMC_SZ];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   309
static const char	*last_tzname[2];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   310
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   311
static state_t		*lclzonep;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
static struct tm	tm;		/* For non-reentrant use */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
static int		is_in_dst;	/* Set if t is in DST */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
static zone_rules_t	curr_zonerules = ZONERULES_INVALID;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
static int		cached_year;	/* mktime() perf. enhancement */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
static long long	cached_secs_since_1970;	/* mktime() perf. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
static int		year_is_cached = FALSE;	/* mktime() perf. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   320
#define	TZSYNC_FILE	"/var/run/tzsync"
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   321
static uint32_t		zoneinfo_seqno;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   322
static uint32_t		zoneinfo_seqno_init = 1;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   323
static uint32_t		*zoneinfo_seqadr = &zoneinfo_seqno_init;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   324
#define	RELOAD_INFO()	(zoneinfo_seqno != *zoneinfo_seqadr)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
#define	_2AM		(2 * SECS_PER_HOUR)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
#define	FIRSTWEEK	1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
#define	LASTWEEK	5
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
enum wks {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
	_1st_week = 1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
	_2nd_week,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	_3rd_week,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
	_4th_week,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
	_Last_week
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
enum dwk {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	Sun,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
	Mon,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
	Tue,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
	Wed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
	Thu,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
	Fri,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
	Sat
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
enum mth {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
	Jan = 1,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
	Feb,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
	Mar,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
	Apr,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
	May,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
	Jun,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
	Jul,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
	Aug,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
	Sep,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
	Oct,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
	Nov,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
	Dec
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
 * The following table defines standard USA DST transitions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
 * as they have been declared throughout history, disregarding
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
 * the legally sanctioned local variants.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
 * Note:  At some point, this table may be supplanted by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
 * more popular 'posixrules' logic.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
typedef struct {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
	int	s_year;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
	int	e_year;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
	rule_t	start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
	rule_t	end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
} __usa_rules_t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
static const __usa_rules_t	__usa_rules[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
	{
1138
3eec486d02fb PSARC/2005/386 Updates to zic and zdump
robbin
parents: 0
diff changeset
   380
		2007, 2037,
3eec486d02fb PSARC/2005/386 Updates to zic and zdump
robbin
parents: 0
diff changeset
   381
		{ MON_WEEK_DOW, Sun, _2nd_week, Mar, _2AM },
3eec486d02fb PSARC/2005/386 Updates to zic and zdump
robbin
parents: 0
diff changeset
   382
		{ MON_WEEK_DOW, Sun, _1st_week, Nov, _2AM },
3eec486d02fb PSARC/2005/386 Updates to zic and zdump
robbin
parents: 0
diff changeset
   383
	},
3eec486d02fb PSARC/2005/386 Updates to zic and zdump
robbin
parents: 0
diff changeset
   384
	{
3eec486d02fb PSARC/2005/386 Updates to zic and zdump
robbin
parents: 0
diff changeset
   385
		1987, 2006,
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
		{ MON_WEEK_DOW, Sun, _1st_week,  Apr, _2AM },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
		{ MON_WEEK_DOW, Sun, _Last_week, Oct, _2AM },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
	{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
		1976, 1986,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
		{ MON_WEEK_DOW, Sun, _Last_week, Apr, _2AM },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
		{ MON_WEEK_DOW, Sun, _Last_week, Oct, _2AM },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
	{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
		1975, 1975,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
		{ MON_WEEK_DOW, Sun, _Last_week, Feb, _2AM },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
		{ MON_WEEK_DOW, Sun, _Last_week, Oct, _2AM },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
	{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
		1974, 1974,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
		{ MON_WEEK_DOW, Sun, _1st_week,  Jan, _2AM },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
		{ MON_WEEK_DOW, Sun, _Last_week, Nov, _2AM },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
	 * The entry below combines two previously separate entries for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
	 * 1969-1973 and 1902-1968
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
	{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
		1902, 1973,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
		{ MON_WEEK_DOW, Sun, _Last_week, Apr, _2AM },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
		{ MON_WEEK_DOW, Sun, _Last_week, Oct, _2AM },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
#define	MAX_RULE_TABLE	(sizeof (__usa_rules) / sizeof (__usa_rules_t) - 1)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
 * Prototypes for static functions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
 */
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   420
static const char *getsystemTZ(void);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
static const char *getzname(const char *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
static const char *getnum(const char *, int *, int, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
static const char *getsecs(const char *, long *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
static const char *getoffset(const char *, long *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
static const char *getrule(const char *, rule_t *, int);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
static int	load_posixinfo(const char *, state_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
static int	load_zoneinfo(const char *, state_t *);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   428
static void	load_posix_transitions(state_t *, long, long, zone_rules_t);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   429
static void	adjust_posix_default(state_t *, long, long);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   430
static void	*ltzset_u(time_t);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
static struct tm *offtime_u(time_t, long, struct tm *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
static int	posix_check_dst(long long, state_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
static int	posix_daylight(long long *, int, posix_daylight_t *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
static void	set_zone_context(time_t);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   435
static void	reload_counter(void);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   436
static void	purge_zone_cache(void);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   437
static void	set_tzname(const char **);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
 * definition of difftime
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
 * This code assumes time_t is type long.  Note the difference of two
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
 * longs in absolute value is representable as an unsigned long.  So,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
 * compute the absolute value of the difference, cast the result to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
 * double and attach the sign back on.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
 * Note this code assumes 2's complement arithmetic.  The subtraction
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
 * operation may overflow when using signed operands, but when the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
 * result is cast to unsigned long, it yields the desired value
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
 * (ie, the absolute value of the difference).  The cast to unsigned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
 * long is done using pointers to avoid undefined behavior if casting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
 * a negative value to unsigned.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
double
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
difftime(time_t time1, time_t time0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
	if (time1 < time0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
		time0 -= time1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
		return (-(double)*(unsigned long *) &time0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
		time1 -= time0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
		return ((double)*(unsigned long *) &time1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
 * Accepts a time_t, returns a tm struct based on it, with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
 * no local timezone adjustment.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
 * This routine is the thread-safe variant of gmtime(), and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
 * requires that the call provide the address of their own tm
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
 * struct.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
 * Locking is not done here because set_zone_context()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
 * is not called, thus timezone, altzone, and tzname[] are not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
 * accessed, no memory is allocated, and no common dynamic
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
 * data is accessed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
 * See ctime(3C)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
struct tm *
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 2923
diff changeset
   482
gmtime_r(const time_t *timep, struct tm *p_tm)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
	return (offtime_u((time_t)*timep, 0L, p_tm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
 * Accepts a time_t, returns a tm struct based on it, with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
 * no local timezone adjustment.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
 * This function is explicitly NOT THREAD-SAFE.  The standards
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
 * indicate it should provide its results in its own statically
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
 * allocated tm struct that gets overwritten. The thread-safe
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
 * variant is gmtime_r().  We make it mostly thread-safe by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
 * allocating its buffer in thread-specific data.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
 * See ctime(3C)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
struct tm *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
gmtime(const time_t *timep)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
	struct tm *p_tm = tsdalloc(_T_STRUCT_TM, sizeof (struct tm), NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
	if (p_tm == NULL)	/* memory allocation failure */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
		p_tm = &tm;	/* use static buffer and hope for the best */
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 2923
diff changeset
   506
	return (gmtime_r(timep, p_tm));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
 * This is the hashing function, based on the input timezone name.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
get_hashid(const char *id)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
	unsigned char	c;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
	unsigned int	h;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   518
	h = *id++;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   519
	while ((c = *id++) != '\0')
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   520
		h += c;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
	return ((int)(h % HASHTABLE));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
 * find_zone() gets the hashid for zonename, then uses the hashid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
 * to search the hash table for the appropriate timezone entry.  If
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
 * the entry for zonename is found in the hash table, return a pointer
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   528
 * to the entry.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
static state_t *
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   531
find_zone(const char *zonename)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
	int	hashid;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   534
	state_t	*cur;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
	hashid = get_hashid(zonename);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
	cur = tzcache[hashid];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
	while (cur) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
		int	res;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
		res = strcmp(cur->zonename, zonename);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
		if (res == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
			return (cur);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
		} else if (res > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
		cur = cur->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   551
/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   552
 * Register new state in the cache.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   553
 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   554
static void
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   555
reg_zone(state_t *new)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   556
{
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   557
	int	hashid, res;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   558
	state_t	*cur, *prv;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   559
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   560
	hashid = get_hashid(new->zonename);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   561
	cur = tzcache[hashid];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   562
	prv = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   563
	while (cur != NULL) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   564
		res = strcmp(cur->zonename, new->zonename);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   565
		if (res == 0) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   566
			/* impossible, but just in case */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   567
			return;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   568
		} else if (res > 0) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   569
			break;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   570
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   571
		prv = cur;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   572
		cur = cur->next;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   573
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   574
	if (prv != NULL) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   575
		new->next = prv->next;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   576
		prv->next = new;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   577
	} else {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   578
		new->next = tzcache[hashid];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   579
		tzcache[hashid] = new;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   580
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   581
}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
 * Returns tm struct based on input time_t argument, correcting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
 * for the local timezone, producing documented side-effects
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
 * to extern global state, timezone, altzone, daylight and tzname[].
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
 * localtime_r() is the thread-safe variant of localtime().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
 * IMPLEMENTATION NOTE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
 *	Locking slows multithreaded access and is probably ultimately
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
 *	unnecessary here. The POSIX specification is a bit vague
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
 *	as to whether the extern variables set by tzset() need to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
 *	set as a result of a call to localtime_r()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
 *	Currently, the spec only mentions that tzname[] doesn't
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
 *	need to be set.  As soon as it becomes unequivocal
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
 *	that the external zone state doesn't need to be asserted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
 *	for this call, and it really doesn't make much sense
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
 *	to set common state from multi-threaded calls made to this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
 *	function, locking can be dispensed with here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
 *	local zone state would still need to be aquired for the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
 *	time in question in order for calculations elicited here
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
 *	to be correct, but that state wouldn't need to be shared,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
 *	thus no multi-threaded synchronization would be required.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
 *	It would be nice if POSIX would approve an ltzset_r()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
 *	function, but if not, it wouldn't stop us from making one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
 *	privately.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
 *	localtime_r() can now return NULL if overflow is detected.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
 *	offtime_u() is the function that detects overflow, and sets
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
 *	errno appropriately.  We unlock before the call to offtime_u(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
 *	so that lmutex_unlock() does not reassign errno.  The function
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
 *	offtime_u() is MT-safe and does not have to be locked.  Use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
 *	my_is_in_dst to reference local copy of is_in_dst outside locks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
 * See ctime(3C)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
struct tm *
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 2923
diff changeset
   623
localtime_r(const time_t *timep, struct tm *p_tm)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
	long	offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
	struct tm *rt;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   627
	void	*unused;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
	int	my_is_in_dst;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
	lmutex_lock(&_time_lock);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   631
	unused = ltzset_u(*timep);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
	if (lclzonep == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
		lmutex_unlock(&_time_lock);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   634
		if (unused != NULL)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   635
			free(unused);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
		return (offtime_u(*timep, 0L, p_tm));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
	my_is_in_dst = is_in_dst;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
	offset = (my_is_in_dst) ? -altzone : -timezone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
	lmutex_unlock(&_time_lock);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   641
	if (unused != NULL)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   642
		free(unused);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
	rt = offtime_u(*timep, offset, p_tm);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
	p_tm->tm_isdst = my_is_in_dst;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
	return (rt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
 * Accepts a time_t, returns a tm struct based on it, correcting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
 * for the local timezone.  Produces documented side-effects to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
 * extern global timezone state data.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
 * This function is explicitly NOT THREAD-SAFE.  The standards
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
 * indicate it should provide its results in its own statically
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
 * allocated tm struct that gets overwritten. The thread-safe
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
 * variant is localtime_r().  We make it mostly thread-safe by
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
 * allocating its buffer in thread-specific data.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
 * localtime() can now return NULL if overflow is detected.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
 * offtime_u() is the function that detects overflow, and sets
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
 * errno appropriately.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
 * See ctime(3C)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
struct tm *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
localtime(const time_t *timep)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
	struct tm *p_tm = tsdalloc(_T_STRUCT_TM, sizeof (struct tm), NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
	if (p_tm == NULL)	/* memory allocation failure */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
		p_tm = &tm;	/* use static buffer and hope for the best */
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 2923
diff changeset
   672
	return (localtime_r(timep, p_tm));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
 * This function takes a pointer to a tm struct and returns a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
 * normalized time_t, also inducing documented side-effects in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
 * extern global zone state variables.  (See mktime(3C)).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
 */
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   680
static time_t
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   681
mktime1(struct tm *tmptr, int usetz)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
	struct tm _tm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
	long long t;		/* must hold more than 32-bit time_t */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
	int	temp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
	int	mketimerrno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
	int	overflow;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   688
	void	*unused;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
	mketimerrno = errno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
	/* mktime leaves errno unchanged if no error is encountered */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
	/* Calculate time_t from tm arg.  tm may need to be normalized. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
	t = tmptr->tm_sec + SECSPERMIN * tmptr->tm_min +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
	    SECSPERHOUR * tmptr->tm_hour +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
	    SECSPERDAY * (tmptr->tm_mday - 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
	if (tmptr->tm_mon >= 12) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
		tmptr->tm_year += tmptr->tm_mon / 12;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
		tmptr->tm_mon %= 12;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
	} else if (tmptr->tm_mon < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
		temp = -tmptr->tm_mon;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
		tmptr->tm_mon = 0;	/* If tm_mon divides by 12. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
		tmptr->tm_year -= (temp / 12);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
		if (temp %= 12) {	/* Remainder... */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
			tmptr->tm_year--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
			tmptr->tm_mon = 12 - temp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   712
	lmutex_lock(&_time_lock);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   713
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
	/* Avoid numerous calculations embedded in macro if possible */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
	if (!year_is_cached || (cached_year != tmptr->tm_year))	 {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
		cached_year = tmptr->tm_year;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
		year_is_cached = TRUE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
		/* For boundry values of tm_year, typecasting required */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
		cached_secs_since_1970 =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
		    (long long)SECSPERDAY * DAYS_SINCE_70(cached_year);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
	t += cached_secs_since_1970;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
	if (isleap(tmptr->tm_year + TM_YEAR_BASE))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
		t += SECSPERDAY * __lyday_to_month[tmptr->tm_mon];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
		t += SECSPERDAY * __yday_to_month[tmptr->tm_mon];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   729
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   730
	if (usetz) {
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   731
		/*
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   732
		 * If called from mktime(), then we need to do the TZ
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   733
		 * related transformations.
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   734
		 */
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   735
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   736
		unused = ltzset_u((time_t)t);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   737
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   738
		/* Attempt to convert time to GMT based on tm_isdst setting */
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   739
		t += (tmptr->tm_isdst > 0) ? altzone : timezone;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
#ifdef _ILP32
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   742
		overflow = t > LONG_MAX || t < LONG_MIN ||
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   743
		    tmptr->tm_year < 1 || tmptr->tm_year > 138;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
#else
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   745
		overflow = t > LONG_MAX || t < LONG_MIN;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
#endif
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   747
		set_zone_context((time_t)t);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   748
		if (tmptr->tm_isdst < 0) {
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   749
			long dst_delta = timezone - altzone;
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   750
			switch (curr_zonerules) {
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   751
			case ZONEINFO:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
				if (is_in_dst) {
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   753
					t -= dst_delta;
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   754
					set_zone_context((time_t)t);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   755
					if (is_in_dst) {
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   756
						(void) offtime_u((time_t)t,
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   757
						    -altzone, &_tm);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   758
						_tm.tm_isdst = 1;
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   759
					} else {
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   760
						(void) offtime_u((time_t)t,
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   761
						    -timezone, &_tm);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   762
					}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
				} else {
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   764
					(void) offtime_u((time_t)t, -timezone,
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   765
					    &_tm);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
				}
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   767
				break;
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   768
			case POSIX_USA:
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   769
			case POSIX:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
				if (is_in_dst) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
					t -= dst_delta;
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   772
					set_zone_context((time_t)t);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   773
					if (is_in_dst) {
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   774
						(void) offtime_u((time_t)t,
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   775
						    -altzone, &_tm);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   776
						_tm.tm_isdst = 1;
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   777
					} else {
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   778
						(void) offtime_u((time_t)t,
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   779
						    -timezone, &_tm);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   780
					}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
				} else {
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   782
					/*
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   783
					 * check for ambiguous
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   784
					 * 'fallback' transition
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   785
					 */
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   786
					set_zone_context((time_t)t - dst_delta);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   787
					if (is_in_dst) {
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   788
						/* In fallback, force DST */
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   789
						t -= dst_delta;
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   790
						(void) offtime_u((time_t)t,
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   791
						    -altzone, &_tm);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   792
						_tm.tm_isdst = 1;
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   793
					} else {
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   794
						(void) offtime_u((time_t)t,
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   795
						    -timezone, &_tm);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   796
					}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
				}
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   798
				break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   800
			case ZONERULES_INVALID:
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   801
				(void) offtime_u((time_t)t, 0L, &_tm);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   802
				break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   804
			}
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   805
		} else if (is_in_dst) {
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   806
			(void) offtime_u((time_t)t, -altzone, &_tm);
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   807
			_tm.tm_isdst = 1;
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   808
		} else {
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   809
			(void) offtime_u((time_t)t, -timezone, &_tm);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
		}
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   811
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   812
	} else {	/* !usetz, i.e. using UTC */
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   813
		overflow = 0;
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   814
		/* Normalize the TM structure */
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   815
		(void) offtime_u((time_t)t, 0, &_tm);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
	if (overflow || t > LONG_MAX || t < LONG_MIN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
		mketimerrno = EOVERFLOW;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
		t = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
		*tmptr = _tm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
	lmutex_unlock(&_time_lock);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   826
	if (unused != NULL)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   827
		free(unused);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
	errno = mketimerrno;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
	return ((time_t)t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
13249
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   833
time_t
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   834
mktime(struct tm *tmptr)
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   835
{
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   836
	return (mktime1(tmptr, TRUE));
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   837
}
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   838
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   839
time_t
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   840
timegm(struct tm *tmptr)
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   841
{
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   842
	return (mktime1(tmptr, FALSE));
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   843
}
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   844
abc9578d5a0e 317 strptime needs %Z support
Garrett D'Amore <garrett@nexenta.com>
parents: 11115
diff changeset
   845
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
 * Sets extern global zone state variables based on the current
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
 * time.  Specifically, tzname[], timezone, altzone, and daylight
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
 * are updated.  See ctime(3C) manpage.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
void
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 2923
diff changeset
   852
tzset(void)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
{
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   854
	void	*unused;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	lmutex_lock(&_time_lock);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   857
	unused = ltzset_u(time(NULL));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
	lmutex_unlock(&_time_lock);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   859
	if (unused != NULL)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   860
		free(unused);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
_ltzset(time_t tim)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
{
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   866
	void	*unused;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
	lmutex_lock(&_time_lock);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   869
	unused = ltzset_u(tim);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
	lmutex_unlock(&_time_lock);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   871
	if (unused != NULL)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   872
		free(unused);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
 * Loads local zone information if TZ changed since last time zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
 * information was loaded, or if this is the first time thru.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
 * We already hold _time_lock; no further locking is required.
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   879
 * Return a memory block which can be free'd at safe place.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
 */
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   881
static void *
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   882
ltzset_u(time_t t)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
{
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   884
	const char	*zonename;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   885
	state_t		*entry, *new_entry;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   886
	const char	*newtzname[2];
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   888
	if (RELOAD_INFO()) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   889
		reload_counter();
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   890
		purge_zone_cache();
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   891
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   892
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   893
	if ((zonename = getsystemTZ()) == NULL || *zonename == '\0')
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
		zonename = _posix_gmt0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   896
	if (namecache != NULL && strcmp(namecache, zonename) == 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
		set_zone_context(t);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   898
		return (NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   901
	entry = find_zone(zonename);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
	if (entry == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
		/*
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   904
		 * We need to release _time_lock to call out malloc().
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   905
		 * We can release _time_lock as far as global variables
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   906
		 * can remain consistent. Here, we haven't touch any
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   907
		 * variables, so it's okay to release lock.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   908
		 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   909
		lmutex_unlock(&_time_lock);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   910
		new_entry = malloc(sizeof (state_t));
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   911
		lmutex_lock(&_time_lock);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   912
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   913
		/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   914
		 * check it again, since zone may have been loaded while
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   915
		 * time_lock was unlocked.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   916
		 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   917
		entry = find_zone(zonename);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   918
	} else {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   919
		new_entry = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   920
		goto out;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   921
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   922
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   923
	/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   924
	 * We are here because the 1st attemp failed.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   925
	 * new_entry points newly allocated entry. If it was NULL, it
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   926
	 * indicates that the memory allocation also failed.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   927
	 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   928
	if (entry == NULL) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   929
		/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   930
		 * 2nd attemp also failed.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
		 * No timezone entry found in hash table, so load it,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
		 * and create a new timezone entry.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
		char	*newzonename, *charsbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
		newzonename = libc_strdup(zonename);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
		daylight = 0;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   938
		entry = new_entry;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
		if (entry == NULL || newzonename == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
			/* something wrong happened. */
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   942
failed:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
			if (newzonename != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
				libc_free(newzonename);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   945
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   946
			/* Invalidate the current timezone */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   947
			curr_zonerules = ZONERULES_INVALID;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   948
			namecache = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   949
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
			timezone = altzone = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
			is_in_dst = 0;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   952
			newtzname[0] = (char *)_tz_gmt;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   953
			newtzname[1] = (char *)_tz_spaces;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   954
			set_tzname(newtzname);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   955
			return (entry);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   956
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   957
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   958
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   959
		 * Builds transition cache and sets up zone state data for zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   960
		 * specified in TZ, which can be specified as a POSIX zone or an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   961
		 * Olson zoneinfo file reference.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   962
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
		 * If local data cannot be parsed or loaded, the local zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
		 * tables are set up for GMT.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   965
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   966
		 * Unless a leading ':' is prepended to TZ, TZ is initially
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   967
		 * parsed as a POSIX zone;  failing that, it reverts to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   968
		 * a zoneinfo check.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
		 * However, if a ':' is prepended, the zone will *only* be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
		 * parsed as zoneinfo.  If any failure occurs parsing or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
		 * loading a zoneinfo TZ, GMT data is loaded for the local zone.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
		 * Example:  There is a zoneinfo file in the standard
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
		 * distribution called 'PST8PDT'.  The only way the user can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
		 * specify that file under Solaris is to set TZ to ":PST8PDT".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
		 * Otherwise the initial parse of PST8PDT as a POSIX zone will
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
		 * succeed and be used.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
		 */
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   979
		if ((charsbuf = libc_malloc(TZ_MAX_CHARS)) == NULL)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   980
			goto failed;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   982
		entry->zonerules = ZONERULES_INVALID;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
		entry->charsbuf_size = TZ_MAX_CHARS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
		entry->chars = charsbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
		entry->default_tzname0 = _tz_gmt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
		entry->default_tzname1 = _tz_spaces;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
		entry->zonename = newzonename;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
		if (*zonename == ':') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
			if (load_zoneinfo(zonename + 1, entry) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
				(void) load_posixinfo(_posix_gmt0, entry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
		} else if (load_posixinfo(zonename, entry) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
			if (load_zoneinfo(zonename, entry) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
				(void) load_posixinfo(_posix_gmt0, entry);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
		}
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   998
		entry->last_ats_idx = -1;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
   999
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
		 * The pre-allocated buffer is used; reset the free flag
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
		 * so the buffer won't be freed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
		 */
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1004
		reg_zone(entry);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1005
		new_entry = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1006
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1007
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1008
out:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1009
	curr_zonerules = entry->zonerules;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1010
	namecache = entry->zonename;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
	daylight = entry->daylight;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
	lclzonep = entry;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
	set_zone_context(t);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1015
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1016
	/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1017
	 * We shouldn't release lock beyond this point since lclzonep
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1018
	 * can refer to invalid address if cache is invalidated.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1019
	 * We defer the call to free till it can be done safely.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1020
	 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1021
	return (new_entry);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1023
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
 * Sets timezone, altzone, tzname[], extern globals, to represent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
 * disposition of t with respect to TZ; See ctime(3C). is_in_dst,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
 * internal global is also set.  daylight is set at zone load time.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
 * Issues:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
 *	In this function, any time_t not located in the cache is handled
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
 *	as a miss.  To build/update transition cache, load_zoneinfo()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
 *	must be called prior to this routine.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
 *	If POSIX zone, cache miss penalty is slightly degraded
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
 *	performance.  For zoneinfo, penalty is decreased is_in_dst
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
 *	accuracy.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
 *	POSIX, despite its chicken/egg problem, ie. not knowing DST
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
 *	until time known, and not knowing time until DST known, at
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
 *	least uses the same algorithm for 64-bit time as 32-bit.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
 *	The fact that zoneinfo files only contain transistions for 32-bit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
 *	time space is a well known problem, as yet unresolved.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
 *	Without an official standard for coping with out-of-range
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
 *	zoneinfo times,  assumptions must be made.  For now
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
 *	the assumption is:   If t exceeds 32-bit boundries and local zone
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
 *	is zoneinfo type, is_in_dst is set to to 0 for negative values
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
 *	of t, and set to the same DST state as the highest ordered
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
 * 	transition in cache for positive values of t.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
static void
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1053
set_zone_default_context(void)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1054
{
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1055
	const char	*newtzname[2];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1056
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1057
	/* Retrieve suitable defaults for this zone */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1058
	altzone = lclzonep->default_altzone;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1059
	timezone = lclzonep->default_timezone;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1060
	newtzname[0] = (char *)lclzonep->default_tzname0;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1061
	newtzname[1] = (char *)lclzonep->default_tzname1;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1062
	is_in_dst = 0;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1063
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1064
	set_tzname(newtzname);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1065
}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1066
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1067
static void
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
set_zone_context(time_t t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
	prev_t		*prevp;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1071
	int    		lo, hi, tidx, lidx;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1072
	ttinfo_t	*ttisp, *std, *alt;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1073
	const char	*newtzname[2];
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1074
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1075
	/* If state data not loaded or TZ busted, just use GMT */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1076
	if (lclzonep == NULL || curr_zonerules == ZONERULES_INVALID) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1077
		timezone = altzone = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1078
		daylight = is_in_dst = 0;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1079
		newtzname[0] = (char *)_tz_gmt;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1080
		newtzname[1] = (char *)_tz_spaces;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1081
		set_tzname(newtzname);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1082
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1083
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1084
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1085
	if (lclzonep->timecnt <= 0 || lclzonep->typecnt < 2) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
		/* Loaded zone incapable of transitioning. */
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1087
		set_zone_default_context();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
		return;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1089
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1090
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1091
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1092
	 * At least one alt. zone and one transistion exist. Locate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1093
	 * state for 't' quickly as possible.  Use defaults as necessary.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
	lo = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
	hi = lclzonep->timecnt - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
	if (t < lclzonep->ats[0] || t >= lclzonep->ats[hi]) {
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1099
		/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1100
		 * Date which is out of definition.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1101
		 * Calculate DST as best as possible
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1102
		 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
		if (lclzonep->zonerules == POSIX_USA ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1104
		    lclzonep->zonerules == POSIX) {
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1105
			/* Must invoke calculations to determine DST */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1106
			set_zone_default_context();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
			is_in_dst = (daylight) ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
			    posix_check_dst(t, lclzonep) : 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
		} else if (t < lclzonep->ats[0]) {   /* zoneinfo... */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
			/* t precedes 1st transition.  Use defaults */
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1112
			set_zone_default_context();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1113
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
		} else	{    /* zoneinfo */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
			/* t follows final transistion.  Use final */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
			tidx = hi;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
	} else {
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1119
		if ((lidx = lclzonep->last_ats_idx) != -1 &&
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1120
		    lidx != hi &&
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1121
		    t >= lclzonep->ats[lidx] &&
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1122
		    t < lclzonep->ats[lidx + 1]) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1123
			/* CACHE HIT. Nothing needs to be done */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1124
			tidx = lidx;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1125
		} else {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1126
			/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1127
			 * CACHE MISS.  Locate transition using binary search.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1128
			 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1129
			while (lo <= hi) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1130
				tidx = (lo + hi) / 2;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1131
				if (t == lclzonep->ats[tidx])
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1132
					break;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1133
				else if (t < lclzonep->ats[tidx])
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1134
					hi = tidx - 1;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1135
				else
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1136
					lo = tidx + 1;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1137
			}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1138
			if (lo > hi)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1139
				tidx = hi;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
	 * Set extern globals based on located transition and summary of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
	 * its previous state, which were cached when zone was loaded
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
	ttisp = &lclzonep->ttis[lclzonep->types[tidx]];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
	prevp = &lclzonep->prev[tidx];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
	if ((is_in_dst = ttisp->tt_isdst) == 0) { /* std. time */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
		timezone = -ttisp->tt_gmtoff;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1152
		newtzname[0] = &lclzonep->chars[ttisp->tt_abbrind];
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
		if ((alt = prevp->alt) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
			altzone = -alt->tt_gmtoff;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1155
			newtzname[1] = &lclzonep->chars[alt->tt_abbrind];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1156
		} else {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1157
			altzone = lclzonep->default_altzone;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1158
			newtzname[1] = (char *)lclzonep->default_tzname1;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
	} else { /* alt. time */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
		altzone = -ttisp->tt_gmtoff;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1162
		newtzname[1] = &lclzonep->chars[ttisp->tt_abbrind];
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
		if ((std = prevp->std) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
			timezone = -std->tt_gmtoff;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1165
			newtzname[0] = &lclzonep->chars[std->tt_abbrind];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1166
		} else {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1167
			timezone = lclzonep->default_timezone;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1168
			newtzname[0] = (char *)lclzonep->default_tzname0;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
	}
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1171
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1172
	lclzonep->last_ats_idx = tidx;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1173
	set_tzname(newtzname);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
 * This function takes a time_t and gmt offset and produces a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
 * tm struct based on specified time.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
 * The the following fields are calculated, based entirely
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
 * on the offset-adjusted value of t:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
 * tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
 * tm_yday. tm_wday.  (tm_isdst is ALWAYS set to 0).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
static struct tm *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
offtime_u(time_t t, long offset, struct tm *tmptr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
	long		days;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
	long		rem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
	long		y;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
	int		yleap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
	const int	*ip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
	days = t / SECSPERDAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
	rem = t % SECSPERDAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
	rem += offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
	while (rem < 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
		rem += SECSPERDAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
		--days;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
	while (rem >= SECSPERDAY) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
		rem -= SECSPERDAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
		++days;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
	tmptr->tm_hour = (int)(rem / SECSPERHOUR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1208
	rem = rem % SECSPERHOUR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
	tmptr->tm_min = (int)(rem / SECSPERMIN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
	tmptr->tm_sec = (int)(rem % SECSPERMIN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
	tmptr->tm_wday = (int)((EPOCH_WDAY + days) % DAYSPERWEEK);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
	if (tmptr->tm_wday < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
		tmptr->tm_wday += DAYSPERWEEK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
	y = EPOCH_YEAR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
	while (days < 0 || days >= (long)__year_lengths[yleap = isleap(y)]) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
		long newy;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
		newy = y + days / DAYSPERNYEAR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
		if (days < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
			--newy;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
		days -= ((long)newy - (long)y) * DAYSPERNYEAR +
8563
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  1223
		    LEAPS_THRU_END_OF(newy > 0 ? newy - 1L : newy) -
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  1224
		    LEAPS_THRU_END_OF(y > 0 ? y - 1L : y);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
		y = newy;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
	tmptr->tm_year = (int)(y - TM_YEAR_BASE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
	tmptr->tm_yday = (int)days;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
	ip = __mon_lengths[yleap];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
	for (tmptr->tm_mon = 0; days >=
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1231
	    (long)ip[tmptr->tm_mon]; ++(tmptr->tm_mon)) {
8563
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  1232
		days = days - (long)ip[tmptr->tm_mon];
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1233
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
	tmptr->tm_mday = (int)(days + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
	tmptr->tm_isdst = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
#ifdef _LP64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
	/* do as much as possible before checking for error. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
	if ((y > (long)INT_MAX + TM_YEAR_BASE) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
	    (y < (long)INT_MIN + TM_YEAR_BASE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
		errno = EOVERFLOW;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
	return (tmptr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
 * Check whether DST is set for time in question.  Only applies to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
 * POSIX timezones.  If explicit POSIX transition rules were provided
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
 * for the current zone, use those, otherwise use default USA POSIX
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
 * transitions.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
posix_check_dst(long long t, state_t *sp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
	struct tm	gmttm;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
	long long	jan01;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
	int		year, i, idx, ridx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
	posix_daylight_t	pdaylight;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
	(void) offtime_u(t, 0L, &gmttm);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
	year = gmttm.tm_year + 1900;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
	jan01 = t - ((gmttm.tm_yday * SECSPERDAY) +
8563
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  1266
	    (gmttm.tm_hour * SECSPERHOUR) +
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  1267
	    (gmttm.tm_min * SECSPERMIN) + gmttm.tm_sec);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
	 * If transition rules were provided for this zone,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
	 * use them, otherwise, default to USA daylight rules,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
	 * which are historically correct for the continental USA,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
	 * excluding local provisions.  (This logic may be replaced
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
	 * at some point in the future with "posixrules" to offer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
	 * more flexibility to the system administrator).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
	if (sp->zonerules == POSIX)	 {	/* POSIX rules */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
		pdaylight.rules[0] = &sp->start_rule;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
		pdaylight.rules[1] = &sp->end_rule;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
	} else { 			/* POSIX_USA: USA */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
		i = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
		while (year < __usa_rules[i].s_year && i < MAX_RULE_TABLE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
			i++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
		pdaylight.rules[0] = (rule_t *)&__usa_rules[i].start;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
		pdaylight.rules[1] = (rule_t *)&__usa_rules[i].end;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
	pdaylight.offset[0] = timezone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
	pdaylight.offset[1] = altzone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
	idx = posix_daylight(&jan01, year, &pdaylight);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
	ridx = !idx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
	 * Note:  t, rtime[0], and rtime[1] are all bounded within 'year'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
	 * beginning on 'jan01'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
	if (t >= pdaylight.rtime[idx] && t < pdaylight.rtime[ridx]) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
		return (ridx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
		return (idx);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
 * Given January 1, 00:00:00 GMT for a year as an Epoch-relative time,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
 * along with the integer year #, a posix_daylight_t that is composed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
 * of two rules, and two GMT offsets (timezone and altzone), calculate
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
 * the two Epoch-relative times the two rules take effect, and return
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
 * them in the two rtime fields of the posix_daylight_t structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
 * Also update janfirst by a year, by adding the appropriate number of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
 * seconds depending on whether the year is a leap year or not.  (We take
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
 * advantage that this routine knows the leap year status.)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
posix_daylight(long long *janfirst, int year, posix_daylight_t *pdaylightp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
	rule_t	*rulep;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
	long	offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
	int	idx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
	int	i, d, m1, yy0, yy1, yy2, dow;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
	long	leapyear;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
	long long	value;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
	static const int	__secs_year_lengths[2] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
		DAYS_PER_NYEAR * SECSPERDAY,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
		DAYS_PER_LYEAR * SECSPERDAY
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
	};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
	leapyear = isleap(year);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
	for (idx = 0; idx < 2; idx++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
		rulep = pdaylightp->rules[idx];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
		offset = pdaylightp->offset[idx];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
		switch (rulep->r_type) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
		case MON_WEEK_DOW:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
			 * Mm.n.d - nth "dth day" of month m.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
			value = *janfirst;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
			for (i = 0; i < rulep->r_mon - 1; ++i)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
				value += __mon_lengths[leapyear][i] *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
				    SECSPERDAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
			 * Use Zeller's Congruence to get day-of-week of first
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
			 * day of month.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
			m1 = (rulep->r_mon + 9) % 12 + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
			yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
			yy1 = yy0 / 100;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
			yy2 = yy0 % 100;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
			dow = ((26 * m1 - 2) / 10 +
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
			    1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
			if (dow < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
				dow += DAYSPERWEEK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
			 * Following heuristic increases accuracy of USA rules
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
			 * for negative years.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
			if (year < 1 && leapyear)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
				++dow;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
			 * "dow" is the day-of-week of the first day of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
			 * month.  Get the day-of-month, zero-origin, of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
			 * first "dow" day of the month.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
			d = rulep->r_day - dow;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
			if (d < 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
				d += DAYSPERWEEK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
			for (i = 1; i < rulep->r_week; ++i) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
				if (d + DAYSPERWEEK >=
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
				    __mon_lengths[leapyear][rulep->r_mon - 1])
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
				d += DAYSPERWEEK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
			 * "d" is the day-of-month, zero-origin, of the day
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
			 * we want.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
			value += d * SECSPERDAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
		case JULIAN_DAY:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
			 * Jn - Julian day, 1 == Jan 1, 60 == March 1 even
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
			 * in leap yrs.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
			value = *janfirst + (rulep->r_day - 1) * SECSPERDAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
			if (leapyear && rulep->r_day >= 60)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
				value += SECSPERDAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
		case DAY_OF_YEAR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
			 * n - day of year.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
			value = *janfirst + rulep->r_day * SECSPERDAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
		pdaylightp->rtime[idx] = value + rulep->r_time + offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
	*janfirst += __secs_year_lengths[leapyear];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
	return ((pdaylightp->rtime[0] > pdaylightp->rtime[1]) ? 1 : 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
 * Try to load zoneinfo file into internal transition tables using name
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
 * indicated in TZ, and do validity checks.  The format of zic(1M)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
 * compiled zoneinfo files isdescribed in tzfile.h
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
load_zoneinfo(const char *name, state_t *sp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
	char	*cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
	char	*cp2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
	int	i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
	long	cnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
	int	fid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
	int	ttisstdcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
	int	ttisgmtcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
	char	*fullname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
	size_t	namelen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
	char	*bufp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
	size_t	flen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
	prev_t	*prevp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
/* LINTED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
	struct	tzhead *tzhp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
	struct	stat64	stbuf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
	ttinfo_t	*most_recent_alt = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
	ttinfo_t	*most_recent_std = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
	ttinfo_t	*ttisp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
	if (name == NULL && (name = TZDEFAULT) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
	if ((name[0] == '/') || strstr(name, "../"))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
	 * We allocate fullname this way to avoid having
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
	 * a PATH_MAX size buffer in our stack frame.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
	namelen = LEN_TZDIR + 1 + strlen(name) + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
	if ((fullname = lmalloc(namelen)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
	(void) strcpy(fullname, TZDIR "/");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
	(void) strcpy(fullname + LEN_TZDIR + 1, name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
	if ((fid = open(fullname, O_RDONLY)) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
		lfree(fullname, namelen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
	lfree(fullname, namelen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
	if (fstat64(fid, &stbuf) == -1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
		(void) close(fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
	flen = (size_t)stbuf.st_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
	if (flen < sizeof (struct tzhead)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
		(void) close(fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
	 * It would be nice to use alloca() to allocate bufp but,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
	 * as above, we wish to avoid allocating a big buffer in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
	 * our stack frame, and also because alloca() gives us no
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
	 * opportunity to fail gracefully on allocation failure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
	cp = bufp = lmalloc(flen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
	if (bufp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
		(void) close(fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
	if ((cnt = read(fid, bufp, flen)) != flen) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
		lfree(bufp, flen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
		(void) close(fid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
	if (close(fid) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
		lfree(bufp, flen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
	cp += (sizeof (tzhp->tzh_magic)) + (sizeof (tzhp->tzh_reserved));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
/* LINTED: alignment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
	ttisstdcnt = CVTZCODE(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
/* LINTED: alignment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
	ttisgmtcnt = CVTZCODE(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
/* LINTED: alignment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
	sp->leapcnt = CVTZCODE(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
/* LINTED: alignment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
	sp->timecnt = CVTZCODE(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
/* LINTED: alignment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
	sp->typecnt = CVTZCODE(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
/* LINTED: alignment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
	sp->charcnt = CVTZCODE(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
	if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
	    sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
	    sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
	    sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
	    (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
	    (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
		lfree(bufp, flen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
	if (cnt - (cp - bufp) < (long)(sp->timecnt * 4 +	/* ats */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
	    sp->timecnt +			/* types */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
	    sp->typecnt * (4 + 2) +		/* ttinfos */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
	    sp->charcnt +			/* chars */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
	    sp->leapcnt * (4 + 4) +		/* lsinfos */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
	    ttisstdcnt +			/* ttisstds */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
	    ttisgmtcnt)) {			/* ttisgmts */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
		lfree(bufp, flen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
	for (i = 0; i < sp->timecnt; ++i) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
/* LINTED: alignment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
		sp->ats[i] = CVTZCODE(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1536
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1537
	 * Skip over types[] for now and load ttis[] so that when
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
	 * types[] are loaded we can check for transitions to STD & DST.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
	 * This allows us to shave cycles in ltzset_u(), including
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
	 * eliminating the need to check set 'daylight' later.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1541
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1543
	cp2 = (char *)((uintptr_t)cp + sp->timecnt);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
	for (i = 0; i < sp->typecnt; ++i) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
		ttisp = &sp->ttis[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
/* LINTED: alignment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
		ttisp->tt_gmtoff = CVTZCODE(cp2);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1549
		ttisp->tt_isdst = (uchar_t)*cp2++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1550
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1551
		if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1552
			lfree(bufp, flen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1553
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1554
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1555
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
		ttisp->tt_abbrind = (uchar_t)*cp2++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
		if (ttisp->tt_abbrind < 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
		    ttisp->tt_abbrind > sp->charcnt) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
			lfree(bufp, flen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
	 * Since ttis were loaded ahead of types, it is possible to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
	 * detect whether daylight is ever set for this zone now, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
	 * also preload other information to avoid repeated lookups later.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
	 * This logic facilitates keeping a running tab on the state of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
	 * std zone and alternate zone transitions such that timezone,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
	 * altzone and tzname[] can be determined quickly via an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
	 * index to any transition.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
	 * For transition #0 there are no previous transitions,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
	 * so prev->std and prev->alt will be null, but that's OK,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1575
	 * because null prev->std/prev->alt effectively
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
	 * indicates none existed prior.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
	prevp = &sp->prev[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
	for (i = 0; i < sp->timecnt; ++i) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
		sp->types[i] = (uchar_t)*cp++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
		ttisp = &sp->ttis[sp->types[i]];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
		prevp->std = most_recent_std;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
		prevp->alt = most_recent_alt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
		if (ttisp->tt_isdst == 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
			most_recent_alt = ttisp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
			most_recent_std = ttisp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
		if ((int)sp->types[i] >= sp->typecnt) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
			lfree(bufp, flen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
		++prevp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
	if (most_recent_alt == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
		sp->daylight = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
		sp->daylight = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
	 * Set pointer ahead to where it would have been if we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
	 * had read types[] and ttis[] in the same order they
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
	 * occurred in the file.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
	cp = cp2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
	for (i = 0; i < sp->charcnt; ++i)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
		sp->chars[i] = *cp++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
	sp->chars[i] = '\0';	/* ensure '\0' at end */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
	for (i = 0; i < sp->leapcnt; ++i) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
		struct lsinfo *lsisp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
		lsisp = &sp->lsis[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
/* LINTED: alignment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
		lsisp->ls_trans = CVTZCODE(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
/* LINTED: alignment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
		lsisp->ls_corr = CVTZCODE(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
	for (i = 0; i < sp->typecnt; ++i) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
		ttisp = &sp->ttis[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
		if (ttisstdcnt == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
			ttisp->tt_ttisstd = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
			ttisp->tt_ttisstd = *cp++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
			if (ttisp->tt_ttisstd != TRUE &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
			    ttisp->tt_ttisstd != FALSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
				lfree(bufp, flen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
				return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1642
	for (i = 0; i < sp->typecnt; ++i) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
		ttisp = &sp->ttis[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
		if (ttisgmtcnt == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
			ttisp->tt_ttisgmt = FALSE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
			ttisp->tt_ttisgmt = *cp++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
			if (ttisp->tt_ttisgmt != TRUE &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
			    ttisp->tt_ttisgmt != FALSE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
				lfree(bufp, flen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
				return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
	 * Other defaults set at beginning of this routine
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
	 * to cover case where zoneinfo file cannot be loaded
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
	sp->default_timezone = -sp->ttis[0].tt_gmtoff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
	sp->default_altzone  = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
	sp->default_tzname0  = &sp->chars[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
	sp->default_tzname1  = _tz_spaces;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
	lfree(bufp, flen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1667
	sp->zonerules = ZONEINFO;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1672
#ifdef	_TZ_DEBUG
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1673
static void
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1674
print_state(state_t *sp)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1675
{
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1676
	struct tm	tmp;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1677
	int	i, c;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1678
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1679
	(void) fprintf(stderr, "=========================================\n");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1680
	(void) fprintf(stderr, "zonename: \"%s\"\n", sp->zonename);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1681
	(void) fprintf(stderr, "next: 0x%p\n", (void *)sp->next);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1682
	(void) fprintf(stderr, "zonerules: %s\n",
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1683
	    sp->zonerules == ZONERULES_INVALID ? "ZONERULES_INVALID" :
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1684
	    sp->zonerules == POSIX ? "POSIX" :
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1685
	    sp->zonerules == POSIX_USA ? "POSIX_USA" :
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1686
	    sp->zonerules == ZONEINFO ? "ZONEINFO" : "UNKNOWN");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1687
	(void) fprintf(stderr, "daylight: %d\n", sp->daylight);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1688
	(void) fprintf(stderr, "default_timezone: %ld\n", sp->default_timezone);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1689
	(void) fprintf(stderr, "default_altzone: %ld\n", sp->default_altzone);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1690
	(void) fprintf(stderr, "default_tzname0: \"%s\"\n",
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1691
	    sp->default_tzname0);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1692
	(void) fprintf(stderr, "default_tzname1: \"%s\"\n",
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1693
	    sp->default_tzname1);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1694
	(void) fprintf(stderr, "leapcnt: %d\n", sp->leapcnt);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1695
	(void) fprintf(stderr, "timecnt: %d\n", sp->timecnt);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1696
	(void) fprintf(stderr, "typecnt: %d\n", sp->typecnt);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1697
	(void) fprintf(stderr, "charcnt: %d\n", sp->charcnt);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1698
	(void) fprintf(stderr, "chars: \"%s\"\n", sp->chars);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1699
	(void) fprintf(stderr, "charsbuf_size: %u\n", sp->charsbuf_size);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1700
	(void) fprintf(stderr, "prev: skipping...\n");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1701
	(void) fprintf(stderr, "ats = {\n");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1702
	for (c = 0, i = 0; i < sp->timecnt; i++) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1703
		char	buf[64];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1704
		size_t	len;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1705
		if (c != 0) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1706
			(void) fprintf(stderr, ", ");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1707
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1708
		(void) asctime_r(gmtime_r(&sp->ats[i], &tmp),
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1709
		    buf, sizeof (buf));
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1710
		len = strlen(buf);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1711
		buf[len-1] = '\0';
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1712
		(void) fprintf(stderr, "%s", buf);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1713
		if (c == 1) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1714
			(void) fprintf(stderr, "\n");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1715
			c = 0;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1716
		} else {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1717
			c++;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1718
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1719
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1720
	(void) fprintf(stderr, "}\n");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1721
	(void) fprintf(stderr, "types = {\n");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1722
	for (c = 0, i = 0; i < sp->timecnt; i++) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1723
		if (c == 0) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1724
			(void) fprintf(stderr, "\t");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1725
		} else {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1726
			(void) fprintf(stderr, ", ");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1727
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1728
		(void) fprintf(stderr, "%d", sp->types[i]);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1729
		if (c == 7) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1730
			(void) fprintf(stderr, "\n");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1731
			c = 0;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1732
		} else {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1733
			c++;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1734
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1735
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1736
	(void) fprintf(stderr, "}\n");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1737
	(void) fprintf(stderr, "ttis = {\n");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1738
	for (i = 0; i < sp->typecnt; i++) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1739
		(void) fprintf(stderr, "\t{\n");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1740
		(void) fprintf(stderr, "\t\ttt_gmtoff: %ld\n",
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1741
		    sp->ttis[i].tt_gmtoff);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1742
		(void) fprintf(stderr, "\t\ttt_ttisdst: %d\n",
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1743
		    sp->ttis[i].tt_isdst);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1744
		(void) fprintf(stderr, "\t\ttt_abbrind: %d\n",
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1745
		    sp->ttis[i].tt_abbrind);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1746
		(void) fprintf(stderr, "\t\ttt_tt_isstd: %d\n",
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1747
		    sp->ttis[i].tt_ttisstd);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1748
		(void) fprintf(stderr, "\t\ttt_ttisgmt: %d\n",
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1749
		    sp->ttis[i].tt_ttisgmt);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1750
		(void) fprintf(stderr, "\t}\n");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1751
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1752
	(void) fprintf(stderr, "}\n");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1753
}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1754
#endif
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1755
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
 * Given a POSIX section 8-style TZ string, fill in transition tables.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
 * Examples:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
 * TZ = PST8 or GMT0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
 *	Timecnt set to 0 and typecnt set to 1, reflecting std time only.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
 * TZ = PST8PDT or PST8PDT7
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
 *	Create transition times by applying USA transitions from
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
 *	Jan 1 of each year covering 1902-2038.  POSIX offsets
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
 *	as specified in the TZ are used to calculate the tt_gmtoff
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1768
 *	for each of the two zones.  If ommitted, DST defaults to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
 *	std. time minus one hour.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1770
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1771
 * TZ = <PST8>8PDT  or <PST8>8<PDT9>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1772
 *      Quoted transition.  The values in angled brackets are treated
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
 *      as zone name text, not parsed as offsets.  The offsets
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
 *      occuring following the zonename section.  In this way,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
 *      instead of PST being displayed for standard time, it could
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1776
 *      be displayed as PST8 to give an indication of the offset
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
 *      of that zone to GMT.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1778
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
 * TZ = GMT0BST, M3.5.0/1, M10.5.0/2   or  GMT0BST, J23953, J23989
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1780
 *	Create transition times based on the application new-year
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1781
 *	relative POSIX transitions, parsed from TZ, from Jan 1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1782
 *	for each year covering 1902-2038.  POSIX offsets specified
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1783
 *	in TZ are used to calculate tt_gmtoff for each of the two
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1784
 *	zones.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1785
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1786
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1787
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1788
load_posixinfo(const char *name, state_t *sp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1789
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1790
	const char	*stdname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1791
	const char	*dstname = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1792
	size_t		stdlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
	size_t		dstlen;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
	long		stdoff = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
	long		dstoff = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
	char		*cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
	int		i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
	ttinfo_t	*dst;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
	ttinfo_t	*std;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
	int		quoted;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
	zone_rules_t	zonetype;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1802
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
	zonetype = POSIX_USA;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
	stdname = name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
	if ((quoted = (*stdname == '<')) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
		++stdname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
	/* Parse/extract STD zone name, len and GMT offset */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
	if (*name != '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
		if ((name = getzname(name, quoted)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
		stdlen = name - stdname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
		if (*name == '>')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1816
			++name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
		if (*name == '\0' || stdlen < 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
			if ((name = getoffset(name, &stdoff)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
				return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
	/* If DST specified in TZ, extract DST zone details */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
	if (*name != '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
		dstname = name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
		if ((quoted = (*dstname == '<')) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
			++dstname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
		if ((name = getzname(name, quoted)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
		dstlen = name - dstname;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
		if (dstlen < 1)
8563
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  1835
			return (-1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
		if (*name == '>')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1837
			++name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
		if (*name != '\0' && *name != ',' && *name != ';') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
			if ((name = getoffset(name, &dstoff)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
				return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
			dstoff = stdoff - SECSPERHOUR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1845
		if (*name != ',' && *name != ';') {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1846
			/* no transtition specified; using default rule */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1847
			if (load_zoneinfo(TZDEFRULES, sp) == 0 &&
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1848
			    sp->daylight == 1) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1849
				/* loading TZDEFRULES zoneinfo succeeded */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1850
				adjust_posix_default(sp, stdoff, dstoff);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1851
			} else {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1852
				/* loading TZDEFRULES zoneinfo failed */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1853
				load_posix_transitions(sp, stdoff, dstoff,
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1854
				    zonetype);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1855
			}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1856
		} else {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1857
			/* extract POSIX transitions from TZ */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
			/* Backward compatibility using ';' separator */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
			int	compat_flag = (*name == ';');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
			++name;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
			if ((name = getrule(name, &sp->start_rule, compat_flag))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
			    == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
				return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
			if (*name++ != ',')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
				return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
			if ((name = getrule(name, &sp->end_rule, compat_flag))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1867
			    == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1868
				return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1869
			if (*name != '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1870
				return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1871
			zonetype = POSIX;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1872
			load_posix_transitions(sp, stdoff, dstoff, zonetype);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1873
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1874
		dst = &sp->ttis[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1875
		std = &sp->ttis[1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1876
	} else {  /* DST wasn't specified in POSIX TZ */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1877
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1878
		/*  Since we only have STD time, there are no transitions */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1879
		dstlen = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1880
		sp->daylight = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1881
		sp->typecnt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1882
		sp->timecnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1883
		std = &sp->ttis[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1884
		std->tt_gmtoff = -stdoff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1885
		std->tt_isdst = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1886
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1887
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1888
	/* Setup zone name character data for state table */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1889
	sp->charcnt = (int)(stdlen + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1890
	if (dstlen != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1891
		sp->charcnt += dstlen + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1892
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1893
	/* If bigger than zone name abbv. buffer, grow it */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1894
	if ((size_t)sp->charcnt > sp->charsbuf_size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1895
		if ((cp = libc_realloc(sp->chars, sp->charcnt)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1896
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1897
		sp->chars = cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1898
		sp->charsbuf_size = sp->charcnt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1899
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1900
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1901
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1902
	 * Copy zone name text null-terminatedly into state table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1903
	 * By doing the copy once during zone loading, setting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1904
	 * tzname[] subsequently merely involves setting pointer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1905
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1906
	 * If either or both std. or alt. zone name < 3 chars,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1907
	 * space pad the deficient name(s) to right.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1908
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1909
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1910
	std->tt_abbrind = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1911
	cp = sp->chars;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1912
	(void) strncpy(cp, stdname, stdlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1913
	while (stdlen < 3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1914
		cp[stdlen++] = ' ';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1915
	cp[stdlen] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1916
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1917
	i = (int)(stdlen + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1918
	if (dstlen != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1919
		dst->tt_abbrind = i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1920
		cp += i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1921
		(void) strncpy(cp, dstname, dstlen);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1922
		while (dstlen < 3)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1923
			cp[dstlen++] = ' ';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1924
		cp[dstlen] = '\0';
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1925
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1926
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1927
	/* Save default values */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1928
	if (sp->typecnt == 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1929
		sp->default_timezone = stdoff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1930
		sp->default_altzone = stdoff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1931
		sp->default_tzname0 = &sp->chars[0];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1932
		sp->default_tzname1 = _tz_spaces;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1933
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1934
		sp->default_timezone = -std->tt_gmtoff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1935
		sp->default_altzone = -dst->tt_gmtoff;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1936
		sp->default_tzname0 = &sp->chars[std->tt_abbrind];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
		sp->default_tzname1 = &sp->chars[dst->tt_abbrind];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1938
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1939
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1940
	sp->zonerules = zonetype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1941
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1942
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1943
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1944
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1945
/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1946
 * We loaded the TZDEFAULT which usually the one in US zones. We
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1947
 * adjust the GMT offset for the zone which has stdoff/dstoff
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1948
 * offset.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1949
 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1950
static void
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1951
adjust_posix_default(state_t *sp, long stdoff, long dstoff)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1952
{
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1953
	long	zone_stdoff = 0;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1954
	long	zone_dstoff = 0;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1955
	int	zone_stdoff_flag = 0;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1956
	int	zone_dstoff_flag = 0;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1957
	int	isdst;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1958
	int	i;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1959
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1960
	/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1961
	 * Initial values of zone_stdoff and zone_dstoff
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1962
	 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1963
	for (i = 0; (zone_stdoff_flag == 0 || zone_dstoff_flag == 0) &&
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1964
	    i < sp->timecnt; i++) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1965
		ttinfo_t	*zone;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1966
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1967
		zone = &sp->ttis[sp->types[i]];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1968
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1969
		if (zone_stdoff_flag == 0 && zone->tt_isdst == 0) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1970
			zone_stdoff = -zone->tt_gmtoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1971
			zone_stdoff_flag = 1;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1972
		} else if (zone_dstoff_flag == 0 && zone->tt_isdst != 0) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1973
			zone_dstoff = -zone->tt_gmtoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1974
			zone_dstoff_flag = 1;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1975
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1976
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1977
	if (zone_dstoff_flag == 0)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1978
		zone_dstoff = zone_stdoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1979
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1980
	/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1981
	 * Initially we're assumed to be in standard time.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1982
	 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1983
	isdst = 0;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1984
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1985
	for (i = 0; i < sp->timecnt; i++) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1986
		ttinfo_t	*zone;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1987
		int	next_isdst;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1988
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1989
		zone = &sp->ttis[sp->types[i]];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1990
		next_isdst = zone->tt_isdst;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1991
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1992
		sp->types[i] = next_isdst ? 0 : 1;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1993
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1994
		if (zone->tt_ttisgmt == 0) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1995
			/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1996
			 * If summer time is in effect, and the transition time
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1997
			 * was not specified as standard time, add the summer
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1998
			 * time offset to the transition time;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  1999
			 * otherwise, add the standard time offset to the
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2000
			 * transition time.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2001
			 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2002
			/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2003
			 * Transitions from DST to DDST will effectively
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2004
			 * disappear since POSIX provides for only one DST
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2005
			 * offset.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2006
			 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2007
			if (isdst != 0 && zone->tt_ttisstd == 0)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2008
				sp->ats[i] += dstoff - zone_dstoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2009
			else
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2010
				sp->ats[i] += stdoff - zone_stdoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2011
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2012
		if (next_isdst != 0)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2013
			zone_dstoff = -zone->tt_gmtoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2014
		else
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2015
			zone_stdoff = -zone->tt_gmtoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2016
		isdst = next_isdst;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2017
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2018
	/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2019
	 * Finally, fill in ttis.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2020
	 * ttisstd and ttisgmt need not be handled.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2021
	 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2022
	sp->ttis[0].tt_gmtoff = -dstoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2023
	sp->ttis[0].tt_isdst = 1;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2024
	sp->ttis[1].tt_gmtoff = -stdoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2025
	sp->ttis[1].tt_isdst = 0;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2026
	sp->typecnt = 2;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2027
	sp->daylight = 1;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2028
}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2029
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2030
/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2031
 *
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2032
 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2033
static void
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2034
load_posix_transitions(state_t *sp, long stdoff, long dstoff,
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2035
    zone_rules_t zonetype)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2036
{
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2037
	ttinfo_t	*std, *dst;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2038
	time_t	*tranp;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2039
	uchar_t	*typep;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2040
	prev_t	*prevp;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2041
	int	year;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2042
	int	i;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2043
	long long	janfirst;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2044
	posix_daylight_t	pdaylight;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2045
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2046
	/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2047
	 * We know STD and DST zones are specified with this timezone
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2048
	 * therefore the cache will be set up with 2 transitions per
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2049
	 * year transitioning to their respective std and dst zones.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2050
	 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2051
	sp->daylight = 1;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2052
	sp->typecnt = 2;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2053
	sp->timecnt = 272;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2054
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2055
	/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2056
	 * Insert zone data from POSIX TZ into state table
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2057
	 * The Olson public domain POSIX code sets up ttis[0] to be DST,
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2058
	 * as we are doing here.  It seems to be the correct behavior.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2059
	 * The US/Pacific zoneinfo file also lists DST as first type.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2060
	 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2061
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2062
	dst = &sp->ttis[0];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2063
	dst->tt_gmtoff = -dstoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2064
	dst->tt_isdst = 1;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2065
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2066
	std = &sp->ttis[1];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2067
	std->tt_gmtoff = -stdoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2068
	std->tt_isdst = 0;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2069
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2070
	sp->prev[0].std = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2071
	sp->prev[0].alt = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2072
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2073
	/* Create transition data based on POSIX TZ */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2074
	tranp = sp->ats;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2075
	prevp  = &sp->prev[1];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2076
	typep  = sp->types;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2077
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2078
	/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2079
	 * We only cache from 1902 to 2037 to avoid transistions
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2080
	 * that wrap at the 32-bit boundries, since 1901 and 2038
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2081
	 * are not full years in 32-bit time.  The rough edges
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2082
	 * will be handled as transition cache misses.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2083
	 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2084
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2085
	janfirst = JAN_01_1902;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2086
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2087
	pdaylight.rules[0] = &sp->start_rule;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2088
	pdaylight.rules[1] = &sp->end_rule;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2089
	pdaylight.offset[0] = stdoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2090
	pdaylight.offset[1] = dstoff;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2091
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2092
	for (i = MAX_RULE_TABLE; i >= 0; i--) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2093
		if (zonetype == POSIX_USA) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2094
			pdaylight.rules[0] = (rule_t *)&__usa_rules[i].start;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2095
			pdaylight.rules[1] = (rule_t *)&__usa_rules[i].end;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2096
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2097
		for (year = __usa_rules[i].s_year;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2098
		    year <= __usa_rules[i].e_year; year++) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2099
			int	idx, ridx;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2100
			idx = posix_daylight(&janfirst, year, &pdaylight);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2101
			ridx = !idx;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2102
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2103
			/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2104
			 * Two transitions per year. Since there are
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2105
			 * only two zone types for this POSIX zone,
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2106
			 * previous std and alt are always set to
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2107
			 * &ttis[0] and &ttis[1].
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2108
			 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2109
			*tranp++ = (time_t)pdaylight.rtime[idx];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2110
			*typep++ = idx;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2111
			prevp->std = std;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2112
			prevp->alt = dst;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2113
			++prevp;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2114
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2115
			*tranp++ = (time_t)pdaylight.rtime[ridx];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2116
			*typep++ = ridx;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2117
			prevp->std = std;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2118
			prevp->alt = dst;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2119
			++prevp;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2120
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2121
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2122
}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2123
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2124
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2125
 * Given a pointer into a time zone string, scan until a character that is not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2126
 * a valid character in a zone name is found.  Return ptr to that character.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2127
 * Return NULL if error (ie. non-printable character located in name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2128
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2129
static const char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2130
getzname(const char *strp, int quoted)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2131
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2132
	char	c;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2133
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2134
	if (quoted) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2135
		while ((c = *strp) != '\0' && c != '>' &&
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2136
		    isgraph((unsigned char)c)) {
8563
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  2137
			++strp;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2138
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2139
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2140
		while ((c = *strp) != '\0' && isgraph((unsigned char)c) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2141
		    !isdigit((unsigned char)c) && c != ',' && c != '-' &&
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2142
		    c != '+') {
8563
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  2143
			++strp;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2144
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2145
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2146
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2147
	/* Found an excessively invalid character.  Discredit whole name */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2148
	if (c != '\0' && !isgraph((unsigned char)c))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2149
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2150
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2151
	return (strp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2152
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2153
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2154
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2155
 * Given pointer into time zone string, extract first
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2156
 * number pointed to.  Validate number within range specified,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2157
 * Return ptr to first char following valid numeric sequence.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2158
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2159
static const char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2160
getnum(const char *strp, int *nump, int min, int max)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2161
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2162
	char	c;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2163
	int	num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2164
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2165
	if (strp == NULL || !isdigit((unsigned char)(c = *strp)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2166
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2167
	num = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2168
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2169
		num = num * 10 + (c - '0');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
		if (num > max)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2171
			return (NULL);	/* illegal value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2172
		c = *++strp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2173
	} while (isdigit((unsigned char)c));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2174
	if (num < min)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
		return (NULL);		/* illegal value */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2176
	*nump = num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2177
	return (strp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2178
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2179
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2180
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2181
 * Given a pointer into a time zone string, extract a number of seconds,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
 * in hh[:mm[:ss]] form, from the string.  If an error occurs, return NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
 * otherwise, return a pointer to the first character not part of the number
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
 * of seconds.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2185
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2186
static const char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2187
getsecs(const char *strp, long *secsp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2188
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2189
	int	num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2191
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2192
	 * `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2193
	 * "M10.4.6/26", which does not conform to Posix,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2194
	 * but which specifies the equivalent of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2195
	 * ``02:00 on the first Sunday on or after 23 Oct''.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2196
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2197
	strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2198
	if (strp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2199
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2200
	*secsp = num * (long)SECSPERHOUR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2201
	if (*strp == ':') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2202
		++strp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2203
		strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2204
		if (strp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2205
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2206
		*secsp += num * SECSPERMIN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2207
		if (*strp == ':') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2208
			++strp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2209
			/* `SECSPERMIN' allows for leap seconds.  */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2210
			strp = getnum(strp, &num, 0, SECSPERMIN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2211
			if (strp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2212
				return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2213
			*secsp += num;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2214
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2215
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2216
	return (strp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2217
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2218
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2219
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2220
 * Given a pointer into a time zone string, extract an offset, in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2221
 * [+-]hh[:mm[:ss]] form, from the string.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2222
 * If any error occurs, return NULL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2223
 * Otherwise, return a pointer to the first character not part of the time.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2224
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2225
static const char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2226
getoffset(const char *strp, long *offsetp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2227
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2228
	int	neg = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2229
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2230
	if (*strp == '-') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2231
		neg = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2232
		++strp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2233
	} else if (*strp == '+') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2234
		++strp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2235
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2236
	strp = getsecs(strp, offsetp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2237
	if (strp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2238
		return (NULL);		/* illegal time */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2239
	if (neg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2240
		*offsetp = -*offsetp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2241
	return (strp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2242
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2243
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2244
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2245
 * Given a pointer into a time zone string, extract a rule in the form
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2246
 * date[/time].  See POSIX section 8 for the format of "date" and "time".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2247
 * If a valid rule is not found, return NULL.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2248
 * Otherwise, return a pointer to the first character not part of the rule.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2249
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2250
 * If compat_flag is set, support old 1-based day of year values.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2251
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2252
static const char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2253
getrule(const char *strp, rule_t *rulep, int compat_flag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2254
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2255
	if (compat_flag == 0 && *strp == 'M') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2256
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2257
		 * Month, week, day.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2258
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2259
		rulep->r_type = MON_WEEK_DOW;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2260
		++strp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2261
		strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2262
		if (strp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2263
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2264
		if (*strp++ != '.')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2265
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2266
		strp = getnum(strp, &rulep->r_week, 1, 5);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2267
		if (strp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2268
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2269
		if (*strp++ != '.')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2270
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2271
		strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2272
	} else if (compat_flag == 0 && *strp == 'J') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2273
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2274
		 * Julian day.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2275
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2276
		rulep->r_type = JULIAN_DAY;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2277
		++strp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2278
		strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2279
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2280
	} else if (isdigit((unsigned char)*strp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2281
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2282
		 * Day of year.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2283
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2284
		rulep->r_type = DAY_OF_YEAR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2285
		if (compat_flag == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2286
			/* zero-based day of year */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2287
			strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2288
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2289
			/* one-based day of year */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2290
			strp = getnum(strp, &rulep->r_day, 1, DAYSPERLYEAR);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2291
			rulep->r_day--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2292
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2293
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2294
		return (NULL);		/* ZONERULES_INVALID format */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2295
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2296
	if (strp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2297
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2298
	if (*strp == '/') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2299
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2300
		 * Time specified.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2301
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2302
		++strp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2303
		strp = getsecs(strp, &rulep->r_time);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2304
	} else	{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2305
		rulep->r_time = 2 * SECSPERHOUR;	/* default = 2:00:00 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2306
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2307
	return (strp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2308
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2309
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2310
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2311
 * Returns default value for TZ as specified in /etc/default/init file, if
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2312
 * a default value for TZ is provided there.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2313
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2314
static char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2315
get_default_tz(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2316
{
2923
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2317
	char	*tz = NULL;
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2318
	uchar_t	*tzp, *tzq;
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2319
	int	flags;
8563
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  2320
	void	*defp;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2321
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2322
	assert_no_libc_locks_held();
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2323
8563
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  2324
	if ((defp = defopen_r(TIMEZONE)) != NULL) {
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  2325
		flags = defcntl_r(DC_GETFLAGS, 0, defp);
2923
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2326
		TURNON(flags, DC_STRIP_QUOTES);
8563
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  2327
		(void) defcntl_r(DC_SETFLAGS, flags, defp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2328
8563
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  2329
		if ((tzp = (uchar_t *)defread_r(TZSTRING, defp)) != NULL) {
2923
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2330
			while (isspace(*tzp))
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2331
				tzp++;
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2332
			tzq = tzp;
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2333
			while (!isspace(*tzq) &&
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2334
			    *tzq != ';' &&
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2335
			    *tzq != '#' &&
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2336
			    *tzq != '\0')
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2337
				tzq++;
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2338
			*tzq = '\0';
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2339
			if (*tzp != '\0')
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2340
				tz = libc_strdup((char *)tzp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2341
		}
2923
da82ab368162 PSARC 2006/561 libcmd must die
raf
parents: 2292
diff changeset
  2342
8563
3cefe121bbd2 6783069 libc must not use defread internally
Kenjiro Tsuji <Kenjiro.Tsuji@Sun.COM>
parents: 6812
diff changeset
  2343
		defclose_r(defp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2344
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2345
	return (tz);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2346
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2347
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2348
/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2349
 * Purge all cache'd state_t
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2350
 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2351
static void
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2352
purge_zone_cache(void)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2353
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2354
	int	hashid;
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2355
	state_t	*p, *n, *r;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2356
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2357
	/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2358
	 * Create a single list of caches which are detached
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2359
	 * from hash table.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2360
	 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2361
	r = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2362
	for (hashid = 0; hashid < HASHTABLE; hashid++) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2363
		for (p = tzcache[hashid]; p != NULL; p = n) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2364
			n = p->next;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2365
			p->next = r;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2366
			r = p;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2367
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2368
		tzcache[hashid] = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2369
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2370
	namecache = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2371
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2372
	/* last_tzname[] may point cache being freed */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2373
	last_tzname[0] = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2374
	last_tzname[1] = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2375
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2376
	/* We'll reload system TZ as well */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2377
	systemTZ = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2378
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2379
	/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2380
	 * Hash table has been cleared, and all elements are detached from
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2381
	 * the hash table. Now we are safe to release _time_lock.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2382
	 * We need to unlock _time_lock because we need to call out to
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2383
	 * free().
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2384
	 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2385
	lmutex_unlock(&_time_lock);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2386
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2387
	assert_no_libc_locks_held();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2388
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2389
	while (r != NULL) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2390
		n = r->next;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2391
		libc_free((char *)r->zonename);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2392
		libc_free((char *)r->chars);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2393
		free(r);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2394
		r = n;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2395
	}
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2396
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2397
	lmutex_lock(&_time_lock);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2398
}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2399
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2400
/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2401
 * When called first time, open the counter device and load
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2402
 * the initial value. If counter is updated, copy value to
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2403
 * private memory.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2404
 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2405
static void
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2406
reload_counter(void)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2407
{
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2408
	int	fd;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2409
	caddr_t	addr;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2410
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2411
	if (zoneinfo_seqadr != &zoneinfo_seqno_init) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2412
		zoneinfo_seqno = *zoneinfo_seqadr;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2413
		return;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2414
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2415
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2416
	if ((fd = open(TZSYNC_FILE, O_RDONLY)) < 0)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2417
		return;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2418
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2419
	addr = mmap(0, sizeof (uint32_t), PROT_READ, MAP_SHARED, fd, 0);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2420
	(void) close(fd);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2421
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2422
	if (addr == MAP_FAILED)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2423
		return;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2424
	/*LINTED*/
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2425
	zoneinfo_seqadr = (uint32_t *)addr;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2426
	zoneinfo_seqno = *zoneinfo_seqadr;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2427
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2428
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2429
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2430
 * getsystemTZ() returns the TZ value if it is set in the environment, or
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2431
 * it returns the system TZ;  if the systemTZ has not yet been set, or
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2432
 * cleared by tzreload, get_default_tz() is called to read the
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2433
 * /etc/default/init file to get the value.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2434
 */
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2435
static const char *
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2436
getsystemTZ()
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2437
{
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2438
	tznmlist_t *tzn;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2439
	char	*tz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2440
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2441
	tz = getenv("TZ");
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2442
	if (tz != NULL && *tz != '\0')
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2443
		return ((const char *)tz);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2444
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2445
	if (systemTZ != NULL)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2446
		return (systemTZ);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2447
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2448
	/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2449
	 * get_default_tz calls out stdio functions via defread.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2450
	 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2451
	lmutex_unlock(&_time_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2452
	tz = get_default_tz();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2453
	lmutex_lock(&_time_lock);
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2454
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2455
	if (tz == NULL) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2456
		/* no TZ entry in the file */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2457
		systemTZ = _posix_gmt0;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2458
		return (systemTZ);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2459
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2460
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2461
	/*
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2462
	 * look up timezone used previously. We will not free the
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2463
	 * old timezone name, because ltzset_u() can release _time_lock
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2464
	 * while it has references to systemTZ (via zonename). If we
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2465
	 * free the systemTZ, the reference via zonename can access
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2466
	 * invalid memory when systemTZ is reset.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2467
	 */
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2468
	for (tzn = systemTZrec; tzn != NULL; tzn = tzn->link) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2469
		if (strcmp(tz, tzn->name) == 0)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2470
			break;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2471
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2472
	if (tzn == NULL) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2473
		/* This is new timezone name */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2474
		tzn = lmalloc(sizeof (tznmlist_t *) + strlen(tz) + 1);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2475
		(void) strcpy(tzn->name, tz);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2476
		tzn->link = systemTZrec;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2477
		systemTZrec = tzn;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2478
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2479
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2480
	libc_free(tz);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2481
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2482
	return (systemTZ = tzn->name);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2483
}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2484
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2485
/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2486
 * tzname[] is the user visible string which applications may have
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2487
 * references. Even though TZ was changed, references to the old tzname
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2488
 * may continue to remain in the application, and those references need
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2489
 * to be valid. They were valid by our implementation because strings being
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2490
 * pointed by tzname were never be freed nor altered by the change of TZ.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2491
 * However, this will no longer be the case.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2492
 *
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2493
 * state_t is now freed when cache is purged. Therefore, reading string
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2494
 * from old tzname[] addr may end up with accessing a stale data(freed area).
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2495
 * To avoid this, we maintain a copy of all timezone name strings which will
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2496
 * never be freed, and tzname[] will point those copies.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2497
 *
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2498
 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2499
static int
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2500
set_one_tzname(const char *name, int idx)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2501
{
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2502
	const unsigned char *nm;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2503
	int	hashid, i;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2504
	char	*s;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2505
	tznmlist_t *tzn;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2506
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2507
	if (name == _tz_gmt || name == _tz_spaces) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2508
		tzname[idx] = (char *)name;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2509
		return (0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2510
	}
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2511
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2512
	nm = (const unsigned char *)name;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2513
	hashid = (nm[0] * 29 + nm[1] * 3) % TZNMC_SZ;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2514
	for (tzn = tznmhash[hashid]; tzn != NULL; tzn = tzn->link) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2515
		s = tzn->name;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2516
		/* do the strcmp() */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2517
		for (i = 0; s[i] == name[i]; i++) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2518
			if (s[i] == '\0') {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2519
				tzname[idx] = tzn->name;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2520
				return (0);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2521
			}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2522
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2523
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2524
	/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2525
	 * allocate new entry. This entry is never freed, so use lmalloc
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2526
	 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2527
	tzn = lmalloc(sizeof (tznmlist_t *) + strlen(name) + 1);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2528
	if (tzn == NULL)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2529
		return (1);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2530
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2531
	(void) strcpy(tzn->name, name);
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2532
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2533
	/* link it */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2534
	tzn->link = tznmhash[hashid];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2535
	tznmhash[hashid] = tzn;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2536
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2537
	tzname[idx] = tzn->name;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2538
	return (0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2539
}
11115
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2540
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2541
/*
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2542
 * Set tzname[] after testing parameter to see if we are setting
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2543
 * same zone name. If we got same address, it should be same zone
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2544
 * name as tzname[], unless cache have been purged.
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2545
 * Note, purge_zone_cache() resets last_tzname[].
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2546
 */
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2547
static void
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2548
set_tzname(const char **namep)
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2549
{
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2550
	if (namep[0] != last_tzname[0]) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2551
		if (set_one_tzname(namep[0], 0)) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2552
			tzname[0] = (char *)_tz_gmt;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2553
			last_tzname[0] = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2554
		} else {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2555
			last_tzname[0] = namep[0];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2556
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2557
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2558
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2559
	if (namep[1] != last_tzname[1]) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2560
		if (set_one_tzname(namep[1], 1)) {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2561
			tzname[1] = (char *)_tz_spaces;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2562
			last_tzname[1] = NULL;
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2563
		} else {
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2564
			last_tzname[1] = namep[1];
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2565
		}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2566
	}
bcfb2bb98fca PSARC/2009/516 Timezone cache renewal
Nobutomo Nakano <Nobutomo.Nakano@Sun.COM>
parents: 8563
diff changeset
  2567
}