GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libc/time/localtime.c Lines: 0 847 0.0 %
Date: 2017-11-13 Branches: 0 706 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: localtime.c,v 1.59 2016/09/19 12:48:21 millert Exp $ */
2
/*
3
** This file is in the public domain, so clarified as of
4
** 1996-06-05 by Arthur David Olson.
5
*/
6
7
/*
8
** Leap second handling from Bradley White.
9
** POSIX-style TZ environment variable handling from Guy Harris.
10
*/
11
12
#include <ctype.h>
13
#include <errno.h>
14
#include <fcntl.h>
15
#include <float.h>	/* for FLT_MAX and DBL_MAX */
16
#include <stdint.h>
17
#include <stdlib.h>
18
#include <string.h>
19
#include <unistd.h>
20
21
#include "private.h"
22
#include "tzfile.h"
23
#include "thread_private.h"
24
25
#ifndef TZ_ABBR_MAX_LEN
26
#define TZ_ABBR_MAX_LEN	16
27
#endif /* !defined TZ_ABBR_MAX_LEN */
28
29
#ifndef TZ_ABBR_CHAR_SET
30
#define TZ_ABBR_CHAR_SET \
31
	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
32
#endif /* !defined TZ_ABBR_CHAR_SET */
33
34
#ifndef TZ_ABBR_ERR_CHAR
35
#define TZ_ABBR_ERR_CHAR	'_'
36
#endif /* !defined TZ_ABBR_ERR_CHAR */
37
38
#ifndef WILDABBR
39
/*
40
** Someone might make incorrect use of a time zone abbreviation:
41
**	1.	They might reference tzname[0] before calling tzset (explicitly
42
**		or implicitly).
43
**	2.	They might reference tzname[1] before calling tzset (explicitly
44
**		or implicitly).
45
**	3.	They might reference tzname[1] after setting to a time zone
46
**		in which Daylight Saving Time is never observed.
47
**	4.	They might reference tzname[0] after setting to a time zone
48
**		in which Standard Time is never observed.
49
**	5.	They might reference tm.TM_ZONE after calling offtime.
50
** What's best to do in the above cases is open to debate;
51
** for now, we just set things up so that in any of the five cases
52
** WILDABBR is used. Another possibility: initialize tzname[0] to the
53
** string "tzname[0] used before set", and similarly for the other cases.
54
** And another: initialize tzname[0] to "ERA", with an explanation in the
55
** manual page of what this "time zone abbreviation" means (doing this so
56
** that tzname[0] has the "normal" length of three characters).
57
*/
58
#define WILDABBR	"   "
59
#endif /* !defined WILDABBR */
60
61
static char		wildabbr[] = WILDABBR;
62
63
static const char	gmt[] = "GMT";
64
65
/*
66
** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
67
** We default to US rules as of 1999-08-17.
68
** POSIX 1003.1 section 8.1.1 says that the default DST rules are
69
** implementation dependent; for historical reasons, US rules are a
70
** common default.
71
*/
72
#ifndef TZDEFRULESTRING
73
#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
74
#endif /* !defined TZDEFDST */
75
76
struct ttinfo {				/* time type information */
77
	long		tt_gmtoff;	/* UTC offset in seconds */
78
	int		tt_isdst;	/* used to set tm_isdst */
79
	int		tt_abbrind;	/* abbreviation list index */
80
	int		tt_ttisstd;	/* TRUE if transition is std time */
81
	int		tt_ttisgmt;	/* TRUE if transition is UTC */
82
};
83
84
struct lsinfo {				/* leap second information */
85
	time_t		ls_trans;	/* transition time */
86
	long		ls_corr;	/* correction to apply */
87
};
88
89
#define BIGGEST(a, b)	(((a) > (b)) ? (a) : (b))
90
91
#ifdef TZNAME_MAX
92
#define MY_TZNAME_MAX	TZNAME_MAX
93
#endif /* defined TZNAME_MAX */
94
#ifndef TZNAME_MAX
95
#define MY_TZNAME_MAX	255
96
#endif /* !defined TZNAME_MAX */
97
98
struct state {
99
	int		leapcnt;
100
	int		timecnt;
101
	int		typecnt;
102
	int		charcnt;
103
	int		goback;
104
	int		goahead;
105
	time_t		ats[TZ_MAX_TIMES];
106
	unsigned char	types[TZ_MAX_TIMES];
107
	struct ttinfo	ttis[TZ_MAX_TYPES];
108
	char		chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt),
109
			    (2 * (MY_TZNAME_MAX + 1)))];
110
	struct lsinfo	lsis[TZ_MAX_LEAPS];
111
};
112
113
struct rule {
114
	int		r_type;		/* type of rule--see below */
115
	int		r_day;		/* day number of rule */
116
	int		r_week;		/* week number of rule */
117
	int		r_mon;		/* month number of rule */
118
	long		r_time;		/* transition time of rule */
119
};
120
121
#define JULIAN_DAY		0	/* Jn - Julian day */
122
#define DAY_OF_YEAR		1	/* n - day of year */
123
#define MONTH_NTH_DAY_OF_WEEK	2	/* Mm.n.d - month, week, day of week */
124
125
/*
126
** Prototypes for static functions.
127
*/
128
129
static long		detzcode(const char * codep);
130
static time_t		detzcode64(const char * codep);
131
static int		differ_by_repeat(time_t t1, time_t t0);
132
static const char *	getzname(const char * strp);
133
static const char *	getqzname(const char * strp, const int delim);
134
static const char *	getnum(const char * strp, int * nump, int min,
135
				int max);
136
static const char *	getsecs(const char * strp, long * secsp);
137
static const char *	getoffset(const char * strp, long * offsetp);
138
static const char *	getrule(const char * strp, struct rule * rulep);
139
static void		gmtload(struct state * sp);
140
static struct tm *	gmtsub(const time_t * timep, long offset,
141
				struct tm * tmp);
142
static struct tm *	localsub(const time_t * timep, long offset,
143
				struct tm * tmp);
144
static int		increment_overflow(int * number, int delta);
145
static int		leaps_thru_end_of(int y);
146
static int		long_increment_overflow(long * number, int delta);
147
static int		long_normalize_overflow(long * tensptr,
148
				int * unitsptr, int base);
149
static int		normalize_overflow(int * tensptr, int * unitsptr,
150
				int base);
151
static void		settzname(void);
152
static time_t		time1(struct tm * tmp,
153
				struct tm * (*funcp)(const time_t *,
154
				long, struct tm *),
155
				long offset);
156
static time_t		time2(struct tm *tmp,
157
				struct tm * (*funcp)(const time_t *,
158
				long, struct tm*),
159
				long offset, int * okayp);
160
static time_t		time2sub(struct tm *tmp,
161
				struct tm * (*funcp)(const time_t *,
162
				long, struct tm*),
163
				long offset, int * okayp, int do_norm_secs);
164
static struct tm *	timesub(const time_t * timep, long offset,
165
				const struct state * sp, struct tm * tmp);
166
static int		tmcomp(const struct tm * atmp,
167
				const struct tm * btmp);
168
static time_t		transtime(time_t janfirst, int year,
169
				const struct rule * rulep, long offset);
170
static int		typesequiv(const struct state * sp, int a, int b);
171
static int		tzload(const char * name, struct state * sp,
172
				int doextend);
173
static int		tzparse(const char * name, struct state * sp,
174
				int lastditch);
175
176
#ifdef STD_INSPIRED
177
struct tm	*offtime(const time_t *, long);
178
time_t		time2posix(time_t);
179
time_t		posix2time(time_t);
180
PROTO_DEPRECATED(offtime);
181
PROTO_DEPRECATED(time2posix);
182
PROTO_DEPRECATED(posix2time);
183
#endif
184
185
static struct state *	lclptr;
186
static struct state *	gmtptr;
187
188
189
#ifndef TZ_STRLEN_MAX
190
#define TZ_STRLEN_MAX 255
191
#endif /* !defined TZ_STRLEN_MAX */
192
193
static char		lcl_TZname[TZ_STRLEN_MAX + 1];
194
static int		lcl_is_set;
195
static int		gmt_is_set;
196
_THREAD_PRIVATE_MUTEX(lcl);
197
_THREAD_PRIVATE_MUTEX(gmt);
198
199
char *			tzname[2] = {
200
	wildabbr,
201
	wildabbr
202
};
203
#if 0
204
DEF_WEAK(tzname);
205
#endif
206
207
/*
208
** Section 4.12.3 of X3.159-1989 requires that
209
**	Except for the strftime function, these functions [asctime,
210
**	ctime, gmtime, localtime] return values in one of two static
211
**	objects: a broken-down time structure and an array of char.
212
** Thanks to Paul Eggert for noting this.
213
*/
214
215
static struct tm	tm;
216
217
#ifdef USG_COMPAT
218
long			timezone = 0;
219
int			daylight = 0;
220
#endif /* defined USG_COMPAT */
221
222
#ifdef ALTZONE
223
time_t			altzone = 0;
224
#endif /* defined ALTZONE */
225
226
static long
227
detzcode(const char *codep)
228
{
229
	long	result;
230
	int	i;
231
232
	result = (codep[0] & 0x80) ? ~0L : 0;
233
	for (i = 0; i < 4; ++i)
234
		result = (result << 8) | (codep[i] & 0xff);
235
	return result;
236
}
237
238
static time_t
239
detzcode64(const char *codep)
240
{
241
	time_t	result;
242
	int	i;
243
244
	result = (codep[0] & 0x80) ?  (~(int_fast64_t) 0) : 0;
245
	for (i = 0; i < 8; ++i)
246
		result = result * 256 + (codep[i] & 0xff);
247
	return result;
248
}
249
250
static void
251
settzname(void)
252
{
253
	struct state * const	sp = lclptr;
254
	int			i;
255
256
	tzname[0] = wildabbr;
257
	tzname[1] = wildabbr;
258
#ifdef USG_COMPAT
259
	daylight = 0;
260
	timezone = 0;
261
#endif /* defined USG_COMPAT */
262
#ifdef ALTZONE
263
	altzone = 0;
264
#endif /* defined ALTZONE */
265
	if (sp == NULL) {
266
		tzname[0] = tzname[1] = (char *)gmt;
267
		return;
268
	}
269
	/*
270
	** And to get the latest zone names into tzname. . .
271
	*/
272
	for (i = 0; i < sp->timecnt; ++i) {
273
		const struct ttinfo *ttisp = &sp->ttis[sp->types[i]];
274
275
		tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind];
276
#ifdef USG_COMPAT
277
		if (ttisp->tt_isdst)
278
			daylight = 1;
279
		if (!ttisp->tt_isdst)
280
			timezone = -(ttisp->tt_gmtoff);
281
#endif /* defined USG_COMPAT */
282
#ifdef ALTZONE
283
		if (ttisp->tt_isdst)
284
			altzone = -(ttisp->tt_gmtoff);
285
#endif /* defined ALTZONE */
286
	}
287
	/*
288
	** Finally, scrub the abbreviations.
289
	** First, replace bogus characters.
290
	*/
291
	for (i = 0; i < sp->charcnt; ++i) {
292
		if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
293
			sp->chars[i] = TZ_ABBR_ERR_CHAR;
294
	}
295
	/*
296
	** Second, truncate long abbreviations.
297
	*/
298
	for (i = 0; i < sp->typecnt; ++i) {
299
		const struct ttinfo *ttisp = &sp->ttis[i];
300
		char *cp = &sp->chars[ttisp->tt_abbrind];
301
302
		if (strlen(cp) > TZ_ABBR_MAX_LEN &&
303
		    strcmp(cp, GRANDPARENTED) != 0)
304
			*(cp + TZ_ABBR_MAX_LEN) = '\0';
305
	}
306
}
307
308
static int
309
differ_by_repeat(time_t t1, time_t t0)
310
{
311
	if (TYPE_BIT(time_t) - 1 < SECSPERREPEAT_BITS)
312
		return 0;
313
	return (int64_t)t1 - t0 == SECSPERREPEAT;
314
}
315
316
static int
317
tzload(const char *name, struct state *sp, int doextend)
318
{
319
	const char *		p;
320
	int			i;
321
	int			fid;
322
	int			stored;
323
	int			nread;
324
	typedef union {
325
		struct tzhead	tzhead;
326
		char		buf[2 * sizeof(struct tzhead) +
327
				    2 * sizeof *sp +
328
				    4 * TZ_MAX_TIMES];
329
	} u_t;
330
	u_t *			up;
331
	char			fullname[PATH_MAX];
332
333
	up = calloc(1, sizeof *up);
334
	if (up == NULL)
335
		return -1;
336
337
	sp->goback = sp->goahead = FALSE;
338
	if (name != NULL && issetugid() != 0) {
339
		if ((name[0] == ':' && (strchr(name, '/') || strstr(name, ".."))) ||
340
		    name[0] == '/' || strchr(name, '.'))
341
			name = NULL;
342
	}
343
	if (name == NULL && (name = TZDEFAULT) == NULL)
344
		goto oops;
345
346
	if (name[0] == ':')
347
		++name;
348
	if (name[0] != '/') {
349
		if ((p = TZDIR) == NULL)
350
			goto oops;
351
		if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)
352
			goto oops;
353
		strlcpy(fullname, p, sizeof fullname);
354
		strlcat(fullname, "/", sizeof fullname);
355
		strlcat(fullname, name, sizeof fullname);
356
		name = fullname;
357
	}
358
	if ((fid = open(name, O_RDONLY)) == -1)
359
		goto oops;
360
361
	nread = read(fid, up->buf, sizeof up->buf);
362
	if (close(fid) < 0 || nread <= 0)
363
		goto oops;
364
	for (stored = 4; stored <= 8; stored *= 2) {
365
		int		ttisstdcnt;
366
		int		ttisgmtcnt;
367
368
		ttisstdcnt = (int) detzcode(up->tzhead.tzh_ttisstdcnt);
369
		ttisgmtcnt = (int) detzcode(up->tzhead.tzh_ttisgmtcnt);
370
		sp->leapcnt = (int) detzcode(up->tzhead.tzh_leapcnt);
371
		sp->timecnt = (int) detzcode(up->tzhead.tzh_timecnt);
372
		sp->typecnt = (int) detzcode(up->tzhead.tzh_typecnt);
373
		sp->charcnt = (int) detzcode(up->tzhead.tzh_charcnt);
374
		p = up->tzhead.tzh_charcnt + sizeof up->tzhead.tzh_charcnt;
375
		if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS ||
376
		    sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES ||
377
		    sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES ||
378
		    sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS ||
379
		    (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
380
		    (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
381
			goto oops;
382
		if (nread - (p - up->buf) <
383
		    sp->timecnt * stored +		/* ats */
384
		    sp->timecnt +			/* types */
385
		    sp->typecnt * 6 +		/* ttinfos */
386
		    sp->charcnt +			/* chars */
387
		    sp->leapcnt * (stored + 4) +	/* lsinfos */
388
		    ttisstdcnt +			/* ttisstds */
389
		    ttisgmtcnt)			/* ttisgmts */
390
			goto oops;
391
		for (i = 0; i < sp->timecnt; ++i) {
392
			sp->ats[i] = (stored == 4) ?
393
			    detzcode(p) : detzcode64(p);
394
			p += stored;
395
		}
396
		for (i = 0; i < sp->timecnt; ++i) {
397
			sp->types[i] = (unsigned char) *p++;
398
			if (sp->types[i] >= sp->typecnt)
399
				goto oops;
400
		}
401
		for (i = 0; i < sp->typecnt; ++i) {
402
			struct ttinfo *	ttisp;
403
404
			ttisp = &sp->ttis[i];
405
			ttisp->tt_gmtoff = detzcode(p);
406
			p += 4;
407
			ttisp->tt_isdst = (unsigned char) *p++;
408
			if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1)
409
				goto oops;
410
			ttisp->tt_abbrind = (unsigned char) *p++;
411
			if (ttisp->tt_abbrind < 0 ||
412
			    ttisp->tt_abbrind > sp->charcnt)
413
				goto oops;
414
		}
415
		for (i = 0; i < sp->charcnt; ++i)
416
			sp->chars[i] = *p++;
417
		sp->chars[i] = '\0';	/* ensure '\0' at end */
418
		for (i = 0; i < sp->leapcnt; ++i) {
419
			struct lsinfo *	lsisp;
420
421
			lsisp = &sp->lsis[i];
422
			lsisp->ls_trans = (stored == 4) ?
423
			    detzcode(p) : detzcode64(p);
424
			p += stored;
425
			lsisp->ls_corr = detzcode(p);
426
			p += 4;
427
		}
428
		for (i = 0; i < sp->typecnt; ++i) {
429
			struct ttinfo *	ttisp;
430
431
			ttisp = &sp->ttis[i];
432
			if (ttisstdcnt == 0)
433
				ttisp->tt_ttisstd = FALSE;
434
			else {
435
				ttisp->tt_ttisstd = *p++;
436
				if (ttisp->tt_ttisstd != TRUE &&
437
				    ttisp->tt_ttisstd != FALSE)
438
					goto oops;
439
			}
440
		}
441
		for (i = 0; i < sp->typecnt; ++i) {
442
			struct ttinfo *	ttisp;
443
444
			ttisp = &sp->ttis[i];
445
			if (ttisgmtcnt == 0)
446
				ttisp->tt_ttisgmt = FALSE;
447
			else {
448
				ttisp->tt_ttisgmt = *p++;
449
				if (ttisp->tt_ttisgmt != TRUE &&
450
				    ttisp->tt_ttisgmt != FALSE)
451
					goto oops;
452
			}
453
		}
454
		/*
455
		** Out-of-sort ats should mean we're running on a
456
		** signed time_t system but using a data file with
457
		** unsigned values (or vice versa).
458
		*/
459
		for (i = 0; i < sp->timecnt - 2; ++i)
460
			if (sp->ats[i] > sp->ats[i + 1]) {
461
				++i;
462
				/*
463
				** Ignore the end (easy).
464
				*/
465
				sp->timecnt = i;
466
				break;
467
			}
468
		/*
469
		** If this is an old file, we're done.
470
		*/
471
		if (up->tzhead.tzh_version[0] == '\0')
472
			break;
473
		nread -= p - up->buf;
474
		for (i = 0; i < nread; ++i)
475
			up->buf[i] = p[i];
476
		/*
477
		** If this is a narrow integer time_t system, we're done.
478
		*/
479
		if (stored >= sizeof(time_t))
480
			break;
481
	}
482
	if (doextend && nread > 2 &&
483
	    up->buf[0] == '\n' && up->buf[nread - 1] == '\n' &&
484
	    sp->typecnt + 2 <= TZ_MAX_TYPES) {
485
		struct state	ts;
486
		int	result;
487
488
		up->buf[nread - 1] = '\0';
489
		result = tzparse(&up->buf[1], &ts, FALSE);
490
		if (result == 0 && ts.typecnt == 2 &&
491
		    sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
492
			for (i = 0; i < 2; ++i)
493
				ts.ttis[i].tt_abbrind +=
494
				    sp->charcnt;
495
			for (i = 0; i < ts.charcnt; ++i)
496
				sp->chars[sp->charcnt++] =
497
				    ts.chars[i];
498
			i = 0;
499
			while (i < ts.timecnt &&
500
			    ts.ats[i] <=
501
			    sp->ats[sp->timecnt - 1])
502
				++i;
503
			while (i < ts.timecnt &&
504
			    sp->timecnt < TZ_MAX_TIMES) {
505
				sp->ats[sp->timecnt] =
506
				    ts.ats[i];
507
				sp->types[sp->timecnt] =
508
				    sp->typecnt +
509
				    ts.types[i];
510
				++sp->timecnt;
511
				++i;
512
			}
513
			sp->ttis[sp->typecnt++] = ts.ttis[0];
514
			sp->ttis[sp->typecnt++] = ts.ttis[1];
515
		}
516
	}
517
	if (sp->timecnt > 1) {
518
		for (i = 1; i < sp->timecnt; ++i) {
519
			if (typesequiv(sp, sp->types[i], sp->types[0]) &&
520
			    differ_by_repeat(sp->ats[i], sp->ats[0])) {
521
				sp->goback = TRUE;
522
				break;
523
			}
524
		}
525
		for (i = sp->timecnt - 2; i >= 0; --i) {
526
			if (typesequiv(sp, sp->types[sp->timecnt - 1],
527
			    sp->types[i]) &&
528
			    differ_by_repeat(sp->ats[sp->timecnt - 1],
529
			    sp->ats[i])) {
530
				sp->goahead = TRUE;
531
				break;
532
			}
533
		}
534
	}
535
	free(up);
536
	return 0;
537
oops:
538
	free(up);
539
	return -1;
540
}
541
542
static int
543
typesequiv(const struct state *sp, int a, int b)
544
{
545
	int	result;
546
547
	if (sp == NULL ||
548
	    a < 0 || a >= sp->typecnt ||
549
	    b < 0 || b >= sp->typecnt)
550
		result = FALSE;
551
	else {
552
		const struct ttinfo *	ap = &sp->ttis[a];
553
		const struct ttinfo *	bp = &sp->ttis[b];
554
		result = ap->tt_gmtoff == bp->tt_gmtoff &&
555
		    ap->tt_isdst == bp->tt_isdst &&
556
		    ap->tt_ttisstd == bp->tt_ttisstd &&
557
		    ap->tt_ttisgmt == bp->tt_ttisgmt &&
558
		    strcmp(&sp->chars[ap->tt_abbrind],
559
		    &sp->chars[bp->tt_abbrind]) == 0;
560
	}
561
	return result;
562
}
563
564
static const int	mon_lengths[2][MONSPERYEAR] = {
565
	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
566
	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
567
};
568
569
static const int	year_lengths[2] = {
570
	DAYSPERNYEAR, DAYSPERLYEAR
571
};
572
573
/*
574
** Given a pointer into a time zone string, scan until a character that is not
575
** a valid character in a zone name is found. Return a pointer to that
576
** character.
577
*/
578
579
static const char *
580
getzname(const char *strp)
581
{
582
	char	c;
583
584
	while ((c = *strp) != '\0' && !isdigit((unsigned char)c) && c != ',' && c != '-' &&
585
	    c != '+')
586
		++strp;
587
	return strp;
588
}
589
590
/*
591
** Given a pointer into an extended time zone string, scan until the ending
592
** delimiter of the zone name is located. Return a pointer to the delimiter.
593
**
594
** As with getzname above, the legal character set is actually quite
595
** restricted, with other characters producing undefined results.
596
** We don't do any checking here; checking is done later in common-case code.
597
*/
598
599
static const char *
600
getqzname(const char *strp, const int delim)
601
{
602
	int	c;
603
604
	while ((c = *strp) != '\0' && c != delim)
605
		++strp;
606
	return strp;
607
}
608
609
/*
610
** Given a pointer into a time zone string, extract a number from that string.
611
** Check that the number is within a specified range; if it is not, return
612
** NULL.
613
** Otherwise, return a pointer to the first character not part of the number.
614
*/
615
616
static const char *
617
getnum(const char *strp, int *nump, int min, int max)
618
{
619
	char	c;
620
	int	num;
621
622
	if (strp == NULL || !isdigit((unsigned char)(c = *strp)))
623
		return NULL;
624
	num = 0;
625
	do {
626
		num = num * 10 + (c - '0');
627
		if (num > max)
628
			return NULL;	/* illegal value */
629
		c = *++strp;
630
	} while (isdigit((unsigned char)c));
631
	if (num < min)
632
		return NULL;		/* illegal value */
633
	*nump = num;
634
	return strp;
635
}
636
637
/*
638
** Given a pointer into a time zone string, extract a number of seconds,
639
** in hh[:mm[:ss]] form, from the string.
640
** If any error occurs, return NULL.
641
** Otherwise, return a pointer to the first character not part of the number
642
** of seconds.
643
*/
644
645
static const char *
646
getsecs(const char *strp, long *secsp)
647
{
648
	int	num;
649
650
	/*
651
	** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
652
	** "M10.4.6/26", which does not conform to Posix,
653
	** but which specifies the equivalent of
654
	** ``02:00 on the first Sunday on or after 23 Oct''.
655
	*/
656
	strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
657
	if (strp == NULL)
658
		return NULL;
659
	*secsp = num * (long) SECSPERHOUR;
660
	if (*strp == ':') {
661
		++strp;
662
		strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
663
		if (strp == NULL)
664
			return NULL;
665
		*secsp += num * SECSPERMIN;
666
		if (*strp == ':') {
667
			++strp;
668
			/* `SECSPERMIN' allows for leap seconds. */
669
			strp = getnum(strp, &num, 0, SECSPERMIN);
670
			if (strp == NULL)
671
				return NULL;
672
			*secsp += num;
673
		}
674
	}
675
	return strp;
676
}
677
678
/*
679
** Given a pointer into a time zone string, extract an offset, in
680
** [+-]hh[:mm[:ss]] form, from the string.
681
** If any error occurs, return NULL.
682
** Otherwise, return a pointer to the first character not part of the time.
683
*/
684
685
static const char *
686
getoffset(const char *strp, long *offsetp)
687
{
688
	int	neg = 0;
689
690
	if (*strp == '-') {
691
		neg = 1;
692
		++strp;
693
	} else if (*strp == '+')
694
		++strp;
695
	strp = getsecs(strp, offsetp);
696
	if (strp == NULL)
697
		return NULL;		/* illegal time */
698
	if (neg)
699
		*offsetp = -*offsetp;
700
	return strp;
701
}
702
703
/*
704
** Given a pointer into a time zone string, extract a rule in the form
705
** date[/time]. See POSIX section 8 for the format of "date" and "time".
706
** If a valid rule is not found, return NULL.
707
** Otherwise, return a pointer to the first character not part of the rule.
708
*/
709
710
static const char *
711
getrule(const char *strp, struct rule *rulep)
712
{
713
	if (*strp == 'J') {
714
		/*
715
		** Julian day.
716
		*/
717
		rulep->r_type = JULIAN_DAY;
718
		++strp;
719
		strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
720
	} else if (*strp == 'M') {
721
		/*
722
		** Month, week, day.
723
		*/
724
		rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
725
		++strp;
726
		strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
727
		if (strp == NULL)
728
			return NULL;
729
		if (*strp++ != '.')
730
			return NULL;
731
		strp = getnum(strp, &rulep->r_week, 1, 5);
732
		if (strp == NULL)
733
			return NULL;
734
		if (*strp++ != '.')
735
			return NULL;
736
		strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
737
	} else if (isdigit((unsigned char)*strp)) {
738
		/*
739
		** Day of year.
740
		*/
741
		rulep->r_type = DAY_OF_YEAR;
742
		strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
743
	} else
744
		return NULL;		/* invalid format */
745
	if (strp == NULL)
746
		return NULL;
747
	if (*strp == '/') {
748
		/*
749
		** Time specified.
750
		*/
751
		++strp;
752
		strp = getsecs(strp, &rulep->r_time);
753
	} else
754
		rulep->r_time = 2 * SECSPERHOUR;	/* default = 2:00:00 */
755
	return strp;
756
}
757
758
/*
759
** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
760
** year, a rule, and the offset from UTC at the time that rule takes effect,
761
** calculate the Epoch-relative time that rule takes effect.
762
*/
763
764
static time_t
765
transtime(time_t janfirst, int year, const struct rule *rulep, long offset)
766
{
767
	int	leapyear;
768
	time_t	value;
769
	int	i;
770
	int		d, m1, yy0, yy1, yy2, dow;
771
772
	value = 0;
773
	leapyear = isleap(year);
774
	switch (rulep->r_type) {
775
776
	case JULIAN_DAY:
777
		/*
778
		** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
779
		** years.
780
		** In non-leap years, or if the day number is 59 or less, just
781
		** add SECSPERDAY times the day number-1 to the time of
782
		** January 1, midnight, to get the day.
783
		*/
784
		value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
785
		if (leapyear && rulep->r_day >= 60)
786
			value += SECSPERDAY;
787
		break;
788
789
	case DAY_OF_YEAR:
790
		/*
791
		** n - day of year.
792
		** Just add SECSPERDAY times the day number to the time of
793
		** January 1, midnight, to get the day.
794
		*/
795
		value = janfirst + rulep->r_day * SECSPERDAY;
796
		break;
797
798
	case MONTH_NTH_DAY_OF_WEEK:
799
		/*
800
		** Mm.n.d - nth "dth day" of month m.
801
		*/
802
		value = janfirst;
803
		for (i = 0; i < rulep->r_mon - 1; ++i)
804
			value += mon_lengths[leapyear][i] * SECSPERDAY;
805
806
		/*
807
		** Use Zeller's Congruence to get day-of-week of first day of
808
		** month.
809
		*/
810
		m1 = (rulep->r_mon + 9) % 12 + 1;
811
		yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
812
		yy1 = yy0 / 100;
813
		yy2 = yy0 % 100;
814
		dow = ((26 * m1 - 2) / 10 +
815
		    1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
816
		if (dow < 0)
817
			dow += DAYSPERWEEK;
818
819
		/*
820
		** "dow" is the day-of-week of the first day of the month. Get
821
		** the day-of-month (zero-origin) of the first "dow" day of the
822
		** month.
823
		*/
824
		d = rulep->r_day - dow;
825
		if (d < 0)
826
			d += DAYSPERWEEK;
827
		for (i = 1; i < rulep->r_week; ++i) {
828
			if (d + DAYSPERWEEK >=
829
			    mon_lengths[leapyear][rulep->r_mon - 1])
830
				break;
831
			d += DAYSPERWEEK;
832
		}
833
834
		/*
835
		** "d" is the day-of-month (zero-origin) of the day we want.
836
		*/
837
		value += d * SECSPERDAY;
838
		break;
839
	}
840
841
	/*
842
	** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
843
	** question. To get the Epoch-relative time of the specified local
844
	** time on that day, add the transition time and the current offset
845
	** from UTC.
846
	*/
847
	return value + rulep->r_time + offset;
848
}
849
850
/*
851
** Given a POSIX section 8-style TZ string, fill in the rule tables as
852
** appropriate.
853
*/
854
855
static int
856
tzparse(const char *name, struct state *sp, int lastditch)
857
{
858
	const char *			stdname;
859
	const char *			dstname;
860
	size_t				stdlen;
861
	size_t				dstlen;
862
	long				stdoffset;
863
	long				dstoffset;
864
	time_t *		atp;
865
	unsigned char *	typep;
866
	char *			cp;
867
	int			load_result;
868
	static struct ttinfo		zttinfo;
869
870
	dstname = NULL;
871
	stdname = name;
872
	if (lastditch) {
873
		stdlen = strlen(name);	/* length of standard zone name */
874
		name += stdlen;
875
		if (stdlen >= sizeof sp->chars)
876
			stdlen = (sizeof sp->chars) - 1;
877
		stdoffset = 0;
878
	} else {
879
		if (*name == '<') {
880
			name++;
881
			stdname = name;
882
			name = getqzname(name, '>');
883
			if (*name != '>')
884
				return (-1);
885
			stdlen = name - stdname;
886
			name++;
887
		} else {
888
			name = getzname(name);
889
			stdlen = name - stdname;
890
		}
891
		if (*name == '\0')
892
			return -1;
893
		name = getoffset(name, &stdoffset);
894
		if (name == NULL)
895
			return -1;
896
	}
897
	load_result = tzload(TZDEFRULES, sp, FALSE);
898
	if (load_result != 0)
899
		sp->leapcnt = 0;		/* so, we're off a little */
900
	if (*name != '\0') {
901
		if (*name == '<') {
902
			dstname = ++name;
903
			name = getqzname(name, '>');
904
			if (*name != '>')
905
				return -1;
906
			dstlen = name - dstname;
907
			name++;
908
		} else {
909
			dstname = name;
910
			name = getzname(name);
911
			dstlen = name - dstname; /* length of DST zone name */
912
		}
913
		if (*name != '\0' && *name != ',' && *name != ';') {
914
			name = getoffset(name, &dstoffset);
915
			if (name == NULL)
916
				return -1;
917
		} else
918
			dstoffset = stdoffset - SECSPERHOUR;
919
		if (*name == '\0' && load_result != 0)
920
			name = TZDEFRULESTRING;
921
		if (*name == ',' || *name == ';') {
922
			struct rule	start;
923
			struct rule	end;
924
			int		year;
925
			time_t		janfirst;
926
			time_t		starttime;
927
			time_t		endtime;
928
929
			++name;
930
			if ((name = getrule(name, &start)) == NULL)
931
				return -1;
932
			if (*name++ != ',')
933
				return -1;
934
			if ((name = getrule(name, &end)) == NULL)
935
				return -1;
936
			if (*name != '\0')
937
				return -1;
938
			sp->typecnt = 2;	/* standard time and DST */
939
			/*
940
			** Two transitions per year, from EPOCH_YEAR forward.
941
			*/
942
			sp->ttis[0] = sp->ttis[1] = zttinfo;
943
			sp->ttis[0].tt_gmtoff = -dstoffset;
944
			sp->ttis[0].tt_isdst = 1;
945
			sp->ttis[0].tt_abbrind = stdlen + 1;
946
			sp->ttis[1].tt_gmtoff = -stdoffset;
947
			sp->ttis[1].tt_isdst = 0;
948
			sp->ttis[1].tt_abbrind = 0;
949
			atp = sp->ats;
950
			typep = sp->types;
951
			janfirst = 0;
952
			sp->timecnt = 0;
953
			for (year = EPOCH_YEAR;
954
			    sp->timecnt + 2 <= TZ_MAX_TIMES;
955
			    ++year) {
956
			    	time_t	newfirst;
957
958
				starttime = transtime(janfirst, year, &start,
959
				    stdoffset);
960
				endtime = transtime(janfirst, year, &end,
961
				    dstoffset);
962
				if (starttime > endtime) {
963
					*atp++ = endtime;
964
					*typep++ = 1;	/* DST ends */
965
					*atp++ = starttime;
966
					*typep++ = 0;	/* DST begins */
967
				} else {
968
					*atp++ = starttime;
969
					*typep++ = 0;	/* DST begins */
970
					*atp++ = endtime;
971
					*typep++ = 1;	/* DST ends */
972
				}
973
				sp->timecnt += 2;
974
				newfirst = janfirst;
975
				newfirst += year_lengths[isleap(year)] *
976
				    SECSPERDAY;
977
				if (newfirst <= janfirst)
978
					break;
979
				janfirst = newfirst;
980
			}
981
		} else {
982
			long	theirstdoffset;
983
			long	theirdstoffset;
984
			long	theiroffset;
985
			int	isdst;
986
			int	i;
987
			int	j;
988
989
			if (*name != '\0')
990
				return -1;
991
			/*
992
			** Initial values of theirstdoffset and theirdstoffset.
993
			*/
994
			theirstdoffset = 0;
995
			for (i = 0; i < sp->timecnt; ++i) {
996
				j = sp->types[i];
997
				if (!sp->ttis[j].tt_isdst) {
998
					theirstdoffset =
999
						-sp->ttis[j].tt_gmtoff;
1000
					break;
1001
				}
1002
			}
1003
			theirdstoffset = 0;
1004
			for (i = 0; i < sp->timecnt; ++i) {
1005
				j = sp->types[i];
1006
				if (sp->ttis[j].tt_isdst) {
1007
					theirdstoffset =
1008
						-sp->ttis[j].tt_gmtoff;
1009
					break;
1010
				}
1011
			}
1012
			/*
1013
			** Initially we're assumed to be in standard time.
1014
			*/
1015
			isdst = FALSE;
1016
			theiroffset = theirstdoffset;
1017
			/*
1018
			** Now juggle transition times and types
1019
			** tracking offsets as you do.
1020
			*/
1021
			for (i = 0; i < sp->timecnt; ++i) {
1022
				j = sp->types[i];
1023
				sp->types[i] = sp->ttis[j].tt_isdst;
1024
				if (sp->ttis[j].tt_ttisgmt) {
1025
					/* No adjustment to transition time */
1026
				} else {
1027
					/*
1028
					** If summer time is in effect, and the
1029
					** transition time was not specified as
1030
					** standard time, add the summer time
1031
					** offset to the transition time;
1032
					** otherwise, add the standard time
1033
					** offset to the transition time.
1034
					*/
1035
					/*
1036
					** Transitions from DST to DDST
1037
					** will effectively disappear since
1038
					** POSIX provides for only one DST
1039
					** offset.
1040
					*/
1041
					if (isdst && !sp->ttis[j].tt_ttisstd) {
1042
						sp->ats[i] += dstoffset -
1043
						    theirdstoffset;
1044
					} else {
1045
						sp->ats[i] += stdoffset -
1046
						    theirstdoffset;
1047
					}
1048
				}
1049
				theiroffset = -sp->ttis[j].tt_gmtoff;
1050
				if (sp->ttis[j].tt_isdst)
1051
					theirdstoffset = theiroffset;
1052
				else
1053
					theirstdoffset = theiroffset;
1054
			}
1055
			/*
1056
			** Finally, fill in ttis.
1057
			*/
1058
			sp->ttis[0] = sp->ttis[1] = zttinfo;
1059
			sp->ttis[0].tt_gmtoff = -stdoffset;
1060
			sp->ttis[0].tt_isdst = FALSE;
1061
			sp->ttis[0].tt_abbrind = 0;
1062
			sp->ttis[1].tt_gmtoff = -dstoffset;
1063
			sp->ttis[1].tt_isdst = TRUE;
1064
			sp->ttis[1].tt_abbrind = stdlen + 1;
1065
			sp->typecnt = 2;
1066
		}
1067
	} else {
1068
		dstlen = 0;
1069
		sp->typecnt = 1;		/* only standard time */
1070
		sp->timecnt = 0;
1071
		sp->ttis[0] = zttinfo;
1072
		sp->ttis[0].tt_gmtoff = -stdoffset;
1073
		sp->ttis[0].tt_isdst = 0;
1074
		sp->ttis[0].tt_abbrind = 0;
1075
	}
1076
	sp->charcnt = stdlen + 1;
1077
	if (dstlen != 0)
1078
		sp->charcnt += dstlen + 1;
1079
	if ((size_t) sp->charcnt > sizeof sp->chars)
1080
		return -1;
1081
	cp = sp->chars;
1082
	strlcpy(cp, stdname, stdlen + 1);
1083
	cp += stdlen + 1;
1084
	if (dstlen != 0) {
1085
		strlcpy(cp, dstname, dstlen + 1);
1086
	}
1087
	return 0;
1088
}
1089
1090
static void
1091
gmtload(struct state *sp)
1092
{
1093
	if (tzload(gmt, sp, TRUE) != 0)
1094
		(void) tzparse(gmt, sp, TRUE);
1095
}
1096
1097
static void
1098
tzsetwall_basic(void)
1099
{
1100
	if (lcl_is_set < 0)
1101
		return;
1102
	lcl_is_set = -1;
1103
1104
	if (lclptr == NULL) {
1105
		lclptr = calloc(1, sizeof *lclptr);
1106
		if (lclptr == NULL) {
1107
			settzname();	/* all we can do */
1108
			return;
1109
		}
1110
	}
1111
	if (tzload(NULL, lclptr, TRUE) != 0)
1112
		gmtload(lclptr);
1113
	settzname();
1114
}
1115
1116
#ifndef STD_INSPIRED
1117
/*
1118
** A non-static declaration of tzsetwall in a system header file
1119
** may cause a warning about this upcoming static declaration...
1120
*/
1121
static
1122
#endif /* !defined STD_INSPIRED */
1123
void
1124
tzsetwall(void)
1125
{
1126
	_THREAD_PRIVATE_MUTEX_LOCK(lcl);
1127
	tzsetwall_basic();
1128
	_THREAD_PRIVATE_MUTEX_UNLOCK(lcl);
1129
}
1130
1131
static void
1132
tzset_basic(void)
1133
{
1134
	const char *	name;
1135
1136
	name = getenv("TZ");
1137
	if (name == NULL) {
1138
		tzsetwall_basic();
1139
		return;
1140
	}
1141
1142
	if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
1143
		return;
1144
	lcl_is_set = strlen(name) < sizeof lcl_TZname;
1145
	if (lcl_is_set)
1146
		strlcpy(lcl_TZname, name, sizeof lcl_TZname);
1147
1148
	if (lclptr == NULL) {
1149
		lclptr = calloc(1, sizeof *lclptr);
1150
		if (lclptr == NULL) {
1151
			settzname();	/* all we can do */
1152
			return;
1153
		}
1154
	}
1155
	if (*name == '\0') {
1156
		/*
1157
		** User wants it fast rather than right.
1158
		*/
1159
		lclptr->leapcnt = 0;		/* so, we're off a little */
1160
		lclptr->timecnt = 0;
1161
		lclptr->typecnt = 0;
1162
		lclptr->ttis[0].tt_isdst = 0;
1163
		lclptr->ttis[0].tt_gmtoff = 0;
1164
		lclptr->ttis[0].tt_abbrind = 0;
1165
		strlcpy(lclptr->chars, gmt, sizeof lclptr->chars);
1166
	} else if (tzload(name, lclptr, TRUE) != 0) {
1167
		if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
1168
			gmtload(lclptr);
1169
	}
1170
	settzname();
1171
}
1172
1173
void
1174
tzset(void)
1175
{
1176
	_THREAD_PRIVATE_MUTEX_LOCK(lcl);
1177
	tzset_basic();
1178
	_THREAD_PRIVATE_MUTEX_UNLOCK(lcl);
1179
}
1180
DEF_WEAK(tzset);
1181
1182
/*
1183
** The easy way to behave "as if no library function calls" localtime
1184
** is to not call it--so we drop its guts into "localsub", which can be
1185
** freely called. (And no, the PANS doesn't require the above behavior--
1186
** but it *is* desirable.)
1187
**
1188
** The unused offset argument is for the benefit of mktime variants.
1189
*/
1190
1191
static struct tm *
1192
localsub(const time_t *timep, long offset, struct tm *tmp)
1193
{
1194
	struct state *		sp;
1195
	const struct ttinfo *	ttisp;
1196
	int			i;
1197
	struct tm *		result;
1198
	const time_t			t = *timep;
1199
1200
	sp = lclptr;
1201
	if (sp == NULL)
1202
		return gmtsub(timep, offset, tmp);
1203
	if ((sp->goback && t < sp->ats[0]) ||
1204
	    (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
1205
		time_t			newt = t;
1206
		time_t		seconds;
1207
		time_t		tcycles;
1208
		int_fast64_t	icycles;
1209
1210
		if (t < sp->ats[0])
1211
			seconds = sp->ats[0] - t;
1212
		else
1213
			seconds = t - sp->ats[sp->timecnt - 1];
1214
		--seconds;
1215
		tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
1216
		++tcycles;
1217
		icycles = tcycles;
1218
		if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
1219
			return NULL;
1220
		seconds = icycles;
1221
		seconds *= YEARSPERREPEAT;
1222
		seconds *= AVGSECSPERYEAR;
1223
		if (t < sp->ats[0])
1224
			newt += seconds;
1225
		else
1226
			newt -= seconds;
1227
		if (newt < sp->ats[0] ||
1228
		    newt > sp->ats[sp->timecnt - 1])
1229
			return NULL;	/* "cannot happen" */
1230
		result = localsub(&newt, offset, tmp);
1231
		if (result == tmp) {
1232
			time_t	newy;
1233
1234
			newy = tmp->tm_year;
1235
			if (t < sp->ats[0])
1236
				newy -= icycles * YEARSPERREPEAT;
1237
			else
1238
				newy += icycles * YEARSPERREPEAT;
1239
			tmp->tm_year = newy;
1240
			if (tmp->tm_year != newy)
1241
				return NULL;
1242
		}
1243
		return result;
1244
	}
1245
	if (sp->timecnt == 0 || t < sp->ats[0]) {
1246
		i = 0;
1247
		while (sp->ttis[i].tt_isdst) {
1248
			if (++i >= sp->typecnt) {
1249
				i = 0;
1250
				break;
1251
			}
1252
		}
1253
	} else {
1254
		int	lo = 1;
1255
		int	hi = sp->timecnt;
1256
1257
		while (lo < hi) {
1258
			int	mid = (lo + hi) >> 1;
1259
1260
			if (t < sp->ats[mid])
1261
				hi = mid;
1262
			else
1263
				lo = mid + 1;
1264
		}
1265
		i = (int) sp->types[lo - 1];
1266
	}
1267
	ttisp = &sp->ttis[i];
1268
	/*
1269
	** To get (wrong) behavior that's compatible with System V Release 2.0
1270
	** you'd replace the statement below with
1271
	**	t += ttisp->tt_gmtoff;
1272
	**	timesub(&t, 0L, sp, tmp);
1273
	*/
1274
	result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1275
	tmp->tm_isdst = ttisp->tt_isdst;
1276
	tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
1277
#ifdef TM_ZONE
1278
	tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
1279
#endif /* defined TM_ZONE */
1280
	return result;
1281
}
1282
1283
/*
1284
** Re-entrant version of localtime.
1285
*/
1286
1287
struct tm *
1288
localtime_r(const time_t *timep, struct tm *p_tm)
1289
{
1290
	_THREAD_PRIVATE_MUTEX_LOCK(lcl);
1291
	tzset_basic();
1292
	p_tm = localsub(timep, 0L, p_tm);
1293
	_THREAD_PRIVATE_MUTEX_UNLOCK(lcl);
1294
	return p_tm;
1295
}
1296
DEF_WEAK(localtime_r);
1297
1298
struct tm *
1299
localtime(const time_t *timep)
1300
{
1301
	_THREAD_PRIVATE_KEY(localtime);
1302
	struct tm * p_tm = (struct tm*)_THREAD_PRIVATE(localtime, tm, NULL);
1303
1304
	if (p_tm == NULL)
1305
		return NULL;
1306
	return localtime_r(timep, p_tm);
1307
}
1308
DEF_STRONG(localtime);
1309
1310
/*
1311
** gmtsub is to gmtime as localsub is to localtime.
1312
*/
1313
1314
static struct tm *
1315
gmtsub(const time_t *timep, long offset, struct tm *tmp)
1316
{
1317
	struct tm *	result;
1318
1319
	_THREAD_PRIVATE_MUTEX_LOCK(gmt);
1320
	if (!gmt_is_set) {
1321
		gmt_is_set = TRUE;
1322
		gmtptr = calloc(1, sizeof(*gmtptr));
1323
		if (gmtptr != NULL)
1324
			gmtload(gmtptr);
1325
	}
1326
	_THREAD_PRIVATE_MUTEX_UNLOCK(gmt);
1327
	result = timesub(timep, offset, gmtptr, tmp);
1328
#ifdef TM_ZONE
1329
	/*
1330
	** Could get fancy here and deliver something such as
1331
	** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero,
1332
	** but this is no time for a treasure hunt.
1333
	*/
1334
	if (offset != 0)
1335
		tmp->TM_ZONE = wildabbr;
1336
	else {
1337
		if (gmtptr == NULL)
1338
			tmp->TM_ZONE = (char *)gmt;
1339
		else
1340
			tmp->TM_ZONE = gmtptr->chars;
1341
	}
1342
#endif /* defined TM_ZONE */
1343
	return result;
1344
}
1345
1346
/*
1347
** Re-entrant version of gmtime.
1348
*/
1349
1350
struct tm *
1351
gmtime_r(const time_t *timep, struct tm *p_tm)
1352
{
1353
	return gmtsub(timep, 0L, p_tm);
1354
}
1355
DEF_WEAK(gmtime_r);
1356
1357
struct tm *
1358
gmtime(const time_t *timep)
1359
{
1360
	_THREAD_PRIVATE_KEY(gmtime);
1361
	struct tm * p_tm = (struct tm*) _THREAD_PRIVATE(gmtime, tm, NULL);
1362
1363
	if (p_tm == NULL)
1364
		return NULL;
1365
	return gmtime_r(timep, p_tm);
1366
1367
}
1368
DEF_WEAK(gmtime);
1369
1370
#ifdef STD_INSPIRED
1371
1372
struct tm *
1373
offtime(const time_t *timep, long offset)
1374
{
1375
	return gmtsub(timep, offset, &tm);
1376
}
1377
1378
#endif /* defined STD_INSPIRED */
1379
1380
/*
1381
** Return the number of leap years through the end of the given year
1382
** where, to make the math easy, the answer for year zero is defined as zero.
1383
*/
1384
1385
static int
1386
leaps_thru_end_of(int y)
1387
{
1388
	return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
1389
		-(leaps_thru_end_of(-(y + 1)) + 1);
1390
}
1391
1392
static struct tm *
1393
timesub(const time_t *timep, long offset, const struct state *sp, struct tm *tmp)
1394
{
1395
	const struct lsinfo *	lp;
1396
	time_t			tdays;
1397
	int			idays;	/* unsigned would be so 2003 */
1398
	long			rem;
1399
	int			y;
1400
	const int *		ip;
1401
	long			corr;
1402
	int			hit;
1403
	int			i;
1404
	long			seconds;
1405
1406
	corr = 0;
1407
	hit = 0;
1408
	i = (sp == NULL) ? 0 : sp->leapcnt;
1409
	while (--i >= 0) {
1410
		lp = &sp->lsis[i];
1411
		if (*timep >= lp->ls_trans) {
1412
			if (*timep == lp->ls_trans) {
1413
				hit = ((i == 0 && lp->ls_corr > 0) ||
1414
				    lp->ls_corr > sp->lsis[i - 1].ls_corr);
1415
				if (hit) {
1416
					while (i > 0 &&
1417
					    sp->lsis[i].ls_trans ==
1418
					    sp->lsis[i - 1].ls_trans + 1 &&
1419
					    sp->lsis[i].ls_corr ==
1420
					    sp->lsis[i - 1].ls_corr + 1) {
1421
						++hit;
1422
						--i;
1423
					}
1424
				}
1425
			}
1426
			corr = lp->ls_corr;
1427
			break;
1428
		}
1429
	}
1430
	y = EPOCH_YEAR;
1431
	tdays = *timep / SECSPERDAY;
1432
	rem = *timep - tdays * SECSPERDAY;
1433
	while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
1434
		int		newy;
1435
		time_t	tdelta;
1436
		int	idelta;
1437
		int	leapdays;
1438
1439
		tdelta = tdays / DAYSPERLYEAR;
1440
		idelta = tdelta;
1441
		if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
1442
			return NULL;
1443
		if (idelta == 0)
1444
			idelta = (tdays < 0) ? -1 : 1;
1445
		newy = y;
1446
		if (increment_overflow(&newy, idelta))
1447
			return NULL;
1448
		leapdays = leaps_thru_end_of(newy - 1) -
1449
			leaps_thru_end_of(y - 1);
1450
		tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
1451
		tdays -= leapdays;
1452
		y = newy;
1453
	}
1454
1455
	seconds = tdays * SECSPERDAY + 0.5;
1456
	tdays = seconds / SECSPERDAY;
1457
	rem += seconds - tdays * SECSPERDAY;
1458
1459
	/*
1460
	** Given the range, we can now fearlessly cast...
1461
	*/
1462
	idays = tdays;
1463
	rem += offset - corr;
1464
	while (rem < 0) {
1465
		rem += SECSPERDAY;
1466
		--idays;
1467
	}
1468
	while (rem >= SECSPERDAY) {
1469
		rem -= SECSPERDAY;
1470
		++idays;
1471
	}
1472
	while (idays < 0) {
1473
		if (increment_overflow(&y, -1))
1474
			return NULL;
1475
		idays += year_lengths[isleap(y)];
1476
	}
1477
	while (idays >= year_lengths[isleap(y)]) {
1478
		idays -= year_lengths[isleap(y)];
1479
		if (increment_overflow(&y, 1))
1480
			return NULL;
1481
	}
1482
	tmp->tm_year = y;
1483
	if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
1484
		return NULL;
1485
	tmp->tm_yday = idays;
1486
	/*
1487
	** The "extra" mods below avoid overflow problems.
1488
	*/
1489
	tmp->tm_wday = EPOCH_WDAY +
1490
	    ((y - EPOCH_YEAR) % DAYSPERWEEK) *
1491
	    (DAYSPERNYEAR % DAYSPERWEEK) +
1492
	    leaps_thru_end_of(y - 1) -
1493
	    leaps_thru_end_of(EPOCH_YEAR - 1) +
1494
	    idays;
1495
	tmp->tm_wday %= DAYSPERWEEK;
1496
	if (tmp->tm_wday < 0)
1497
		tmp->tm_wday += DAYSPERWEEK;
1498
	tmp->tm_hour = (int) (rem / SECSPERHOUR);
1499
	rem %= SECSPERHOUR;
1500
	tmp->tm_min = (int) (rem / SECSPERMIN);
1501
	/*
1502
	** A positive leap second requires a special
1503
	** representation. This uses "... ??:59:60" et seq.
1504
	*/
1505
	tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
1506
	ip = mon_lengths[isleap(y)];
1507
	for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
1508
		idays -= ip[tmp->tm_mon];
1509
	tmp->tm_mday = (int) (idays + 1);
1510
	tmp->tm_isdst = 0;
1511
#ifdef TM_GMTOFF
1512
	tmp->TM_GMTOFF = offset;
1513
#endif /* defined TM_GMTOFF */
1514
	return tmp;
1515
}
1516
1517
char *
1518
ctime(const time_t *timep)
1519
{
1520
/*
1521
** Section 4.12.3.2 of X3.159-1989 requires that
1522
**	The ctime function converts the calendar time pointed to by timer
1523
**	to local time in the form of a string. It is equivalent to
1524
**		asctime(localtime(timer))
1525
*/
1526
	return asctime(localtime(timep));
1527
}
1528
1529
char *
1530
ctime_r(const time_t *timep, char *buf)
1531
{
1532
	struct tm	mytm;
1533
1534
	return asctime_r(localtime_r(timep, &mytm), buf);
1535
}
1536
1537
/*
1538
** Adapted from code provided by Robert Elz, who writes:
1539
**	The "best" way to do mktime I think is based on an idea of Bob
1540
**	Kridle's (so its said...) from a long time ago.
1541
**	It does a binary search of the time_t space. Since time_t's are
1542
**	just 32 bits, its a max of 32 iterations (even at 64 bits it
1543
**	would still be very reasonable).
1544
*/
1545
1546
#ifndef WRONG
1547
#define WRONG	(-1)
1548
#endif /* !defined WRONG */
1549
1550
/*
1551
** Normalize logic courtesy Paul Eggert.
1552
*/
1553
1554
static int
1555
increment_overflow(int *ip, int j)
1556
{
1557
	int const	i = *ip;
1558
1559
	/*
1560
	** If i >= 0 there can only be overflow if i + j > INT_MAX
1561
	** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
1562
	** If i < 0 there can only be overflow if i + j < INT_MIN
1563
	** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
1564
	*/
1565
	if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i))
1566
		return TRUE;
1567
	*ip += j;
1568
	return FALSE;
1569
}
1570
1571
static int
1572
long_increment_overflow(long *lp, int m)
1573
{
1574
	long const	l = *lp;
1575
1576
	if ((l >= 0) ? (m > LONG_MAX - l) : (m < LONG_MIN - l))
1577
		return TRUE;
1578
	*lp += m;
1579
	return FALSE;
1580
}
1581
1582
static int
1583
normalize_overflow(int *tensptr, int *unitsptr, int base)
1584
{
1585
	int	tensdelta;
1586
1587
	tensdelta = (*unitsptr >= 0) ?
1588
	    (*unitsptr / base) :
1589
	    (-1 - (-1 - *unitsptr) / base);
1590
	*unitsptr -= tensdelta * base;
1591
	return increment_overflow(tensptr, tensdelta);
1592
}
1593
1594
static int
1595
long_normalize_overflow(long *tensptr, int *unitsptr, int base)
1596
{
1597
	int	tensdelta;
1598
1599
	tensdelta = (*unitsptr >= 0) ?
1600
	    (*unitsptr / base) :
1601
	    (-1 - (-1 - *unitsptr) / base);
1602
	*unitsptr -= tensdelta * base;
1603
	return long_increment_overflow(tensptr, tensdelta);
1604
}
1605
1606
static int
1607
tmcomp(const struct tm *atmp, const struct tm *btmp)
1608
{
1609
	int	result;
1610
1611
	if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
1612
	    (result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
1613
	    (result = (atmp->tm_mday - btmp->tm_mday)) == 0 &&
1614
	    (result = (atmp->tm_hour - btmp->tm_hour)) == 0 &&
1615
	    (result = (atmp->tm_min - btmp->tm_min)) == 0)
1616
		result = atmp->tm_sec - btmp->tm_sec;
1617
	return result;
1618
}
1619
1620
static time_t
1621
time2sub(struct tm *tmp, struct tm *(*funcp)(const time_t *, long, struct tm *),
1622
    long offset, int *okayp, int do_norm_secs)
1623
{
1624
	const struct state *	sp;
1625
	int			dir;
1626
	int			i, j;
1627
	int			saved_seconds;
1628
	long			li;
1629
	time_t			lo;
1630
	time_t			hi;
1631
	long			y;
1632
	time_t			newt;
1633
	time_t			t;
1634
	struct tm		yourtm, mytm;
1635
1636
	*okayp = FALSE;
1637
	yourtm = *tmp;
1638
	if (do_norm_secs) {
1639
		if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
1640
			SECSPERMIN))
1641
				return WRONG;
1642
	}
1643
	if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
1644
		return WRONG;
1645
	if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
1646
		return WRONG;
1647
	y = yourtm.tm_year;
1648
	if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR))
1649
		return WRONG;
1650
	/*
1651
	** Turn y into an actual year number for now.
1652
	** It is converted back to an offset from TM_YEAR_BASE later.
1653
	*/
1654
	if (long_increment_overflow(&y, TM_YEAR_BASE))
1655
		return WRONG;
1656
	while (yourtm.tm_mday <= 0) {
1657
		if (long_increment_overflow(&y, -1))
1658
			return WRONG;
1659
		li = y + (1 < yourtm.tm_mon);
1660
		yourtm.tm_mday += year_lengths[isleap(li)];
1661
	}
1662
	while (yourtm.tm_mday > DAYSPERLYEAR) {
1663
		li = y + (1 < yourtm.tm_mon);
1664
		yourtm.tm_mday -= year_lengths[isleap(li)];
1665
		if (long_increment_overflow(&y, 1))
1666
			return WRONG;
1667
	}
1668
	for ( ; ; ) {
1669
		i = mon_lengths[isleap(y)][yourtm.tm_mon];
1670
		if (yourtm.tm_mday <= i)
1671
			break;
1672
		yourtm.tm_mday -= i;
1673
		if (++yourtm.tm_mon >= MONSPERYEAR) {
1674
			yourtm.tm_mon = 0;
1675
			if (long_increment_overflow(&y, 1))
1676
				return WRONG;
1677
		}
1678
	}
1679
	if (long_increment_overflow(&y, -TM_YEAR_BASE))
1680
		return WRONG;
1681
	yourtm.tm_year = y;
1682
	if (yourtm.tm_year != y)
1683
		return WRONG;
1684
	if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
1685
		saved_seconds = 0;
1686
	else if (y + TM_YEAR_BASE < EPOCH_YEAR) {
1687
		/*
1688
		** We can't set tm_sec to 0, because that might push the
1689
		** time below the minimum representable time.
1690
		** Set tm_sec to 59 instead.
1691
		** This assumes that the minimum representable time is
1692
		** not in the same minute that a leap second was deleted from,
1693
		** which is a safer assumption than using 58 would be.
1694
		*/
1695
		if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
1696
			return WRONG;
1697
		saved_seconds = yourtm.tm_sec;
1698
		yourtm.tm_sec = SECSPERMIN - 1;
1699
	} else {
1700
		saved_seconds = yourtm.tm_sec;
1701
		yourtm.tm_sec = 0;
1702
	}
1703
	/*
1704
	** Do a binary search (this works whatever time_t's type is).
1705
	*/
1706
	lo = 1;
1707
	for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i)
1708
		lo *= 2;
1709
	hi = -(lo + 1);
1710
	for ( ; ; ) {
1711
		t = lo / 2 + hi / 2;
1712
		if (t < lo)
1713
			t = lo;
1714
		else if (t > hi)
1715
			t = hi;
1716
		if ((*funcp)(&t, offset, &mytm) == NULL) {
1717
			/*
1718
			** Assume that t is too extreme to be represented in
1719
			** a struct tm; arrange things so that it is less
1720
			** extreme on the next pass.
1721
			*/
1722
			dir = (t > 0) ? 1 : -1;
1723
		} else
1724
			dir = tmcomp(&mytm, &yourtm);
1725
		if (dir != 0) {
1726
			if (t == lo) {
1727
				++t;
1728
				if (t <= lo)
1729
					return WRONG;
1730
				++lo;
1731
			} else if (t == hi) {
1732
				--t;
1733
				if (t >= hi)
1734
					return WRONG;
1735
				--hi;
1736
			}
1737
			if (lo > hi)
1738
				return WRONG;
1739
			if (dir > 0)
1740
				hi = t;
1741
			else
1742
				lo = t;
1743
			continue;
1744
		}
1745
		if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst)
1746
			break;
1747
		/*
1748
		** Right time, wrong type.
1749
		** Hunt for right time, right type.
1750
		** It's okay to guess wrong since the guess
1751
		** gets checked.
1752
		*/
1753
		sp = (const struct state *)
1754
		    ((funcp == localsub) ? lclptr : gmtptr);
1755
		if (sp == NULL)
1756
			return WRONG;
1757
		for (i = sp->typecnt - 1; i >= 0; --i) {
1758
			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
1759
				continue;
1760
			for (j = sp->typecnt - 1; j >= 0; --j) {
1761
				if (sp->ttis[j].tt_isdst == yourtm.tm_isdst)
1762
					continue;
1763
				newt = t + sp->ttis[j].tt_gmtoff -
1764
					sp->ttis[i].tt_gmtoff;
1765
				if ((*funcp)(&newt, offset, &mytm) == NULL)
1766
					continue;
1767
				if (tmcomp(&mytm, &yourtm) != 0)
1768
					continue;
1769
				if (mytm.tm_isdst != yourtm.tm_isdst)
1770
					continue;
1771
				/*
1772
				** We have a match.
1773
				*/
1774
				t = newt;
1775
				goto label;
1776
			}
1777
		}
1778
		return WRONG;
1779
	}
1780
label:
1781
	newt = t + saved_seconds;
1782
	if ((newt < t) != (saved_seconds < 0))
1783
		return WRONG;
1784
	t = newt;
1785
	if ((*funcp)(&t, offset, tmp))
1786
		*okayp = TRUE;
1787
	return t;
1788
}
1789
1790
static time_t
1791
time2(struct tm *tmp, struct tm * (*funcp)(const time_t *, long, struct tm *),
1792
    long offset, int *okayp)
1793
{
1794
	time_t	t;
1795
1796
	/*
1797
	** First try without normalization of seconds
1798
	** (in case tm_sec contains a value associated with a leap second).
1799
	** If that fails, try with normalization of seconds.
1800
	*/
1801
	t = time2sub(tmp, funcp, offset, okayp, FALSE);
1802
	return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
1803
}
1804
1805
static time_t
1806
time1(struct tm *tmp, struct tm * (*funcp)(const time_t *, long, struct tm *),
1807
    long offset)
1808
{
1809
	time_t			t;
1810
	const struct state *	sp;
1811
	int			samei, otheri;
1812
	int			sameind, otherind;
1813
	int			i;
1814
	int			nseen;
1815
	int			seen[TZ_MAX_TYPES];
1816
	int			types[TZ_MAX_TYPES];
1817
	int			okay;
1818
1819
	if (tmp == NULL) {
1820
		errno = EINVAL;
1821
		return WRONG;
1822
	}
1823
	if (tmp->tm_isdst > 1)
1824
		tmp->tm_isdst = 1;
1825
	t = time2(tmp, funcp, offset, &okay);
1826
#ifdef PCTS
1827
	/*
1828
	** PCTS code courtesy Grant Sullivan.
1829
	*/
1830
	if (okay)
1831
		return t;
1832
	if (tmp->tm_isdst < 0)
1833
		tmp->tm_isdst = 0;	/* reset to std and try again */
1834
#endif /* defined PCTS */
1835
#ifndef PCTS
1836
	if (okay || tmp->tm_isdst < 0)
1837
		return t;
1838
#endif /* !defined PCTS */
1839
	/*
1840
	** We're supposed to assume that somebody took a time of one type
1841
	** and did some math on it that yielded a "struct tm" that's bad.
1842
	** We try to divine the type they started from and adjust to the
1843
	** type they need.
1844
	*/
1845
	sp = (const struct state *) ((funcp == localsub) ?  lclptr : gmtptr);
1846
	if (sp == NULL)
1847
		return WRONG;
1848
	for (i = 0; i < sp->typecnt; ++i)
1849
		seen[i] = FALSE;
1850
	nseen = 0;
1851
	for (i = sp->timecnt - 1; i >= 0; --i) {
1852
		if (!seen[sp->types[i]]) {
1853
			seen[sp->types[i]] = TRUE;
1854
			types[nseen++] = sp->types[i];
1855
		}
1856
	}
1857
	for (sameind = 0; sameind < nseen; ++sameind) {
1858
		samei = types[sameind];
1859
		if (sp->ttis[samei].tt_isdst != tmp->tm_isdst)
1860
			continue;
1861
		for (otherind = 0; otherind < nseen; ++otherind) {
1862
			otheri = types[otherind];
1863
			if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst)
1864
				continue;
1865
			tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
1866
			    sp->ttis[samei].tt_gmtoff;
1867
			tmp->tm_isdst = !tmp->tm_isdst;
1868
			t = time2(tmp, funcp, offset, &okay);
1869
			if (okay)
1870
				return t;
1871
			tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
1872
			    sp->ttis[samei].tt_gmtoff;
1873
			tmp->tm_isdst = !tmp->tm_isdst;
1874
		}
1875
	}
1876
	return WRONG;
1877
}
1878
1879
time_t
1880
mktime(struct tm *tmp)
1881
{
1882
	time_t ret;
1883
1884
	_THREAD_PRIVATE_MUTEX_LOCK(lcl);
1885
	tzset_basic();
1886
	ret = time1(tmp, localsub, 0L);
1887
	_THREAD_PRIVATE_MUTEX_UNLOCK(lcl);
1888
	return ret;
1889
}
1890
DEF_STRONG(mktime);
1891
1892
#ifdef STD_INSPIRED
1893
1894
time_t
1895
timelocal(struct tm *tmp)
1896
{
1897
	if (tmp != NULL)
1898
		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
1899
	return mktime(tmp);
1900
}
1901
1902
time_t
1903
timegm(struct tm *tmp)
1904
{
1905
	if (tmp != NULL)
1906
		tmp->tm_isdst = 0;
1907
	return time1(tmp, gmtsub, 0L);
1908
}
1909
1910
time_t
1911
timeoff(struct tm *tmp, long offset)
1912
{
1913
	if (tmp != NULL)
1914
		tmp->tm_isdst = 0;
1915
	return time1(tmp, gmtsub, offset);
1916
}
1917
1918
#endif /* defined STD_INSPIRED */
1919
1920
/*
1921
** XXX--is the below the right way to conditionalize??
1922
*/
1923
1924
#ifdef STD_INSPIRED
1925
1926
/*
1927
** IEEE Std 1003.1-1988 (POSIX) legislates that 536457599
1928
** shall correspond to "Wed Dec 31 23:59:59 UTC 1986", which
1929
** is not the case if we are accounting for leap seconds.
1930
** So, we provide the following conversion routines for use
1931
** when exchanging timestamps with POSIX conforming systems.
1932
*/
1933
1934
static long
1935
leapcorr(time_t *timep)
1936
{
1937
	struct state *		sp;
1938
	struct lsinfo *	lp;
1939
	int			i;
1940
1941
	sp = lclptr;
1942
	i = sp->leapcnt;
1943
	while (--i >= 0) {
1944
		lp = &sp->lsis[i];
1945
		if (*timep >= lp->ls_trans)
1946
			return lp->ls_corr;
1947
	}
1948
	return 0;
1949
}
1950
1951
time_t
1952
time2posix(time_t t)
1953
{
1954
	tzset();
1955
	return t - leapcorr(&t);
1956
}
1957
1958
time_t
1959
posix2time(time_t t)
1960
{
1961
	time_t	x;
1962
	time_t	y;
1963
1964
	tzset();
1965
	/*
1966
	** For a positive leap second hit, the result
1967
	** is not unique. For a negative leap second
1968
	** hit, the corresponding time doesn't exist,
1969
	** so we return an adjacent second.
1970
	*/
1971
	x = t + leapcorr(&t);
1972
	y = x - leapcorr(&x);
1973
	if (y < t) {
1974
		do {
1975
			x++;
1976
			y = x - leapcorr(&x);
1977
		} while (y < t);
1978
		if (t != y)
1979
			return x - 1;
1980
	} else if (y > t) {
1981
		do {
1982
			--x;
1983
			y = x - leapcorr(&x);
1984
		} while (y > t);
1985
		if (t != y)
1986
			return x + 1;
1987
	}
1988
	return x;
1989
}
1990
1991
#endif /* defined STD_INSPIRED */