⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tzset.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1987 Regents of the University of California. * All rights reserved.  The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */#ifndef lintstatic	char	*sccsid = "@(#)tzset.c	4.1	(ULTRIX)	7/3/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1989 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ *			Modification History * * 005	Jon Reeves, 16-Jan-1990 *	Fix handling of DST with negative offset, mktime w/o rules * * 004	Jon Reeves, 20-Nov-1989 *	Added missing set of timezone/daylight; added _last_tz_set * * 003	Ken Lesniak, 03-Nov-1989 *	Conditionalized for X/Open * * 002	Ken Lesniak, 17-Jul-1989 *	Moved tz_is_set flag here from ctime.c and set flag in tzset() * * 001	Ken Lesniak, 11-Apr-1989 *	Moved here from ctime.c. *	Added support for POSIX 1003.1 compliancy. * *	Based on Berkeley ctime.c 1.2 ************************************************************************/#undef	_POSIX_SOURCE /* namespace protection is deadly to this file */#include <sys/param.h>#include <sys/time.h>#include <tzfile.h>#include <string.h>#include <stdlib.h>#include "tzs.h"#ifndef TRUE#define TRUE		1#define FALSE		0#endifstruct state		_tzs;int			_tz_is_set = FALSE;char			_last_tz_set[LAST_TZ_LEN]='\0';/* * For both system V and X/Open, the variables timezone and daylight * are defined as macros. This is because for X/Open, the names * must not be in the ANSI/POSIX name space. There is a special assembler * module with duplicate definitions for the names for those users * that really want to use them. */#ifdef SYSTEM_FIVE/* Ideally, the initial values of these should be unimportant, because *//* a program should call tzset() first before accessing them. But, *//* since they have always initialized this way, I'm sure there are *//* programs that exploit that fact. */#define TIMEZONE timezone#define DAYLIGHT daylighttime_t			TIMEZONE = 5*60*60;int			DAYLIGHT = 1;char			*tzname[2] = {"EST", "EDT"};#else /* SYSTEM_FIVE */#ifdef _XOPEN_SOURCE#define TIMEZONE __timezone#define DAYLIGHT __daylighttime_t			TIMEZONE;int			DAYLIGHT;#endif /* _XOPEN_SOURCE */char			*tzname[2] = {"GMT", "GMT"};#endif /* SYSTEM_FIVE */static longdetzcode(codep)char *	codep;{	register long	result;	register int	i;	result = 0;	for (i = 0; i < 4; ++i)		result = (result << 8) | (codep[i] & 0xff);	return result;}/* * Attempt to load time conversion information from a tzfile formatted file. */statictzload(name)register char *	name;{	register int	i;	register int	fid;	int		charcnt;	int		typecnt;	if (name == 0 && (name = TZDEFAULT) == 0)		return -1;	{		register char *	p;		register int	doaccess;		char		fullname[MAXPATHLEN];		doaccess = name[0] == '/';		if (!doaccess) {			if ((p = TZDIR) == 0)				return -1;			if ((strlen(p) + strlen(name) + 1) >= sizeof fullname)				return -1;			(void) strcpy(fullname, p);			(void) strcat(fullname, "/");			(void) strcat(fullname, name);			/*			** Set doaccess if '.' (as in "../") shows up in name.			*/			while (*name != '\0')				if (*name++ == '.')					doaccess = TRUE;			name = fullname;		}		if (doaccess && access(name, 4) != 0)			return -1;		if ((fid = open(name, 0)) == -1)			return -1;	}	{		register char *			p;		register struct tzhead *	tzhp;		char				buf[sizeof _tzs];		i = read(fid, buf, sizeof buf);		if (close(fid) != 0 || i < sizeof *tzhp)			return -1;		tzhp = (struct tzhead *) buf;		_tzs.timecnt = (int) detzcode(tzhp->tzh_timecnt);		typecnt = (int) detzcode(tzhp->tzh_typecnt);		charcnt = (int) detzcode(tzhp->tzh_charcnt);		if (_tzs.timecnt > TZ_MAX_TIMES ||			typecnt == 0 ||			typecnt > TZ_MAX_TYPES ||			charcnt > TZ_MAX_CHARS)				return -1;		if (i < sizeof *tzhp +			_tzs.timecnt * (4 + sizeof (char)) +			typecnt * (4 + 2 * sizeof (char)) +			charcnt * sizeof (char))				return -1;		p = buf + sizeof *tzhp;		for (i = 0; i < _tzs.timecnt; ++i) {			_tzs.ats[i] = detzcode(p);			p += 4;		}		for (i = 0; i < _tzs.timecnt; ++i)			_tzs.types[i] = (unsigned char) *p++;		for (i = 0; i < typecnt; ++i) {			register struct ttinfo *	ttisp;			ttisp = &_tzs.ttis[i];			ttisp->tt_gmtoff = detzcode(p);			p += 4;			ttisp->tt_isdst = (unsigned char) *p++;			ttisp->tt_abbrind = (unsigned char) *p++;		}		for (i = 0; i < charcnt; ++i)			_tzs.chars[i] = *p++;		_tzs.chars[i] = '\0';	/* ensure '\0' at end */	}	/*	** Check that all the local time type indices are valid.	*/	for (i = 0; i < _tzs.timecnt; ++i)		if (_tzs.types[i] >= typecnt)			return -1;	/*	** Check that all abbreviation indices are valid.	*/	for (i = 0; i < typecnt; ++i)		if (_tzs.ttis[i].tt_abbrind >= charcnt)			return -1;	/*	** Set tzname elements to initial values.	*/	tzname[0] = tzname[1] = _tzs.chars;#if defined(SYSTEM_FIVE) || defined(_XOPEN_SOURCE)	TIMEZONE = -_tzs.ttis[0].tt_gmtoff;	DAYLIGHT = 0;#endif	for (i = 1; i < typecnt; ++i) {		register struct ttinfo *	ttisp;		ttisp = &_tzs.ttis[i];		if (ttisp->tt_isdst) {			tzname[1] = &_tzs.chars[ttisp->tt_abbrind];#if defined(SYSTEM_FIVE) || defined(_XOPEN_SOURCE)			DAYLIGHT = 1;#endif		} else {			tzname[0] = &_tzs.chars[ttisp->tt_abbrind];#if defined(SYSTEM_FIVE) || defined(_XOPEN_SOURCE)			TIMEZONE = -ttisp->tt_gmtoff;#endif		}	}	return 0;}/* * Set time conversion information based on GMT. */statictzsetgmt(){	_tzs.timecnt = 0;	_tzs.ttis[0].tt_gmtoff = 0;	_tzs.ttis[0].tt_isdst = 0;	_tzs.ttis[0].tt_abbrind = 0;	tzname[0] = tzname[1] = strcpy(_tzs.chars, "GMT");#if defined(SYSTEM_FIVE) || defined(_XOPEN_SOURCE)	TIMEZONE = 0;	DAYLIGHT = 0;#endif}/* * The following tables are used for setting the time conversion * information in a manner which is backwards compatible with older * versions of BSD and System V ctime.c. * * Please, DO NOT FIX THE TABLES. They may be wrong, but the must match * the behavior of the old routines. * * Now, they are only used if the tzfile formatted files cannot be * accessed, as is the case if the program is run on a system which * has not yet been upgraded. */struct dstab {				/* describe change to and from dst */	int	dayyr;			/* year being described */	int	daylb;			/* begin: first Sunday after change */	int	dayle;			/* end: first Sunday after chagne */};struct dayrule {	int		dst_type;	/* number obtained from system */	int		dst_hrs;	/* hours to add when dst on */	struct	dstab *	dst_rules;	/* one of the above */	enum {STH, NTH}	dst_hemi;	/* southern, northern hemisphere */};static struct dstab usdaytab[] = {	0,	96,	303,	/* all other years: beg Apr - end Oct */	1974,	5,	333,	/* 1974: Jan 6 - last Sun. in Nov */	1975,	58,	303,	/* 1975: Last Sun. in Feb - last Sun in Oct */	1976,	119,	303,	/* 1976: end Apr - end Oct */	1977,	119,	303,	/* 1977: end Apr - end Oct */	1978,	119,	303,	/* 1978: end Apr - end Oct */	1979,	119,	303,	/* 1979: end Apr - end Oct */	1980,	119,	303,	/* 1980: end Apr - end Oct */	1981,	119,	303,	/* 1981: end Apr - end Oct */	1982,	119,	303,	/* 1982: end Apr - end Oct */	1983,	119,	303,	/* 1983: end Apr - end Oct */	1984,	119,	303,	/* 1984: end Apr - end Oct */	1985,	119,	303,	/* 1985: end Apr - end Oct */	1986,	119,	303,	/* 1986: end Apr - end Oct */};#ifdef SYSTEM_FIVEstatic struct dayrule dayrules[] ={	DST_USA,	1,	usdaytab,	NTH,	-1};#elsestatic struct dstab ausdaytab[] = {	0,	65,	303,	/* others: -> Mar 7, Oct 31 -> */	1970,	0,	400,	/* 1970: no daylight saving at all */	1971,	0,	303,	/* 1971: daylight saving from Oct 31 */	1972,	58,	303,	/* 1972: Jan 1 -> Feb 27 & Oct 31 -> dec 31 */};/* * The European tables ... based on hearsay * Believed correct for: *	WE:	Great Britain, Ireland, Portugal *	ME:	Belgium, Luxembourg, Netherlands, Denmark, Norway, *		Austria, Poland, Czechoslovakia, Sweden, Switzerland, *		DDR, DBR, France, Spain, Hungary, Italy, Jugoslavia * Eastern European dst is unknown, we'll make it ME until someone speaks up. *	EE:	Bulgaria, Finland, Greece, Rumania, Turkey, Western Russia */static struct dstab wedaytab[] = {	0,	86,	303,	/* others: end March - end Oct */	1983,	86,	303,	/* 1983: end March - end Oct */	1984,	86,	303,	/* 1984: end March - end Oct */	1985,	86,	303,	/* 1985: end March - end Oct */};static struct dstab medaytab[] = {	0,	86,	272,	/* others: saving end March - end Sep */	1983,	86,	272,	/* 1983: end March - end Sep */	1984,	86,	272,	/* 1984: end March - end Sep */	1985,	86,	272,	/* 1985: end March - end Sep */};static struct dayrule dayrules[] = {	DST_USA,	1,	usdaytab,	NTH,	DST_AUST,	1,	ausdaytab,	STH,	DST_WET,	1,	wedaytab,	NTH,	DST_MET,	1,	medaytab,	NTH,	DST_EET,	1,	medaytab,	NTH,	-1,};#endif/* * This routine sets the time conversion information in a way which produces * compatible behavior of localtime() with older versions. */statictzset_compat(dr, sw, std, dst)struct dayrule *dr;int sw;		/* seconds west of gmt */char *std;	/* standard time zone name */char *dst;	/* daylight savings time zone name */{	register int	tc;	register time_t	ytt;	register int	tday;	register int	wday;	int		y;	int		ly;	struct dstab	*dp, *dp0, *dpyr;	int		i;	int		chars;	int		type;	_tzs.timecnt = 0;	/* Copy "std" designation */	tzname[0] = tzname[1] = _tzs.chars;	chars = 0;	while (_tzs.chars[chars++] = *std++)		;	/* Fill in the time type information */	_tzs.ttis[0].tt_gmtoff = -sw;	_tzs.ttis[0].tt_isdst = 0;	_tzs.ttis[0].tt_abbrind = 0;	/* If "dst" is specified, create the transtion time table */	if (dr->dst_type >= 0) {		/* Fill in the time type information */		_tzs.ttis[1].tt_gmtoff = (dr->dst_hrs * SECS_PER_HOUR) - sw;		_tzs.ttis[1].tt_abbrind = chars;		_tzs.ttis[1].tt_isdst = 1;		/* Copy the "dst" designation */		tzname[1] += chars;		while (_tzs.chars[chars++] = *dst++)			;		/* Now for every year that is representable by a time_t */		/* value, create a pair of transition times. One for the */		/* start and one for the end of summer time. The transition */		/* times are used by localtime() in determining whether */		/* standard or summer time is in effect. */		/* The following *_year symbols, represent the minimum */		/* and maximum whole years representable by the time_t */		/* type. These definitions assume that time_t is a */		/* signed long */#define t_min_year (time_t)0x8017e880 /* Minimum year in time_t format */#define min_year 1902		/* Minimum year */#define max_year 2037		/* Maximum year */#define feb28_day0 (31 + 28 - 1) /* Julian day (0 based) of Feb 28th */		tc = 0;		ytt = t_min_year;		dp0 = dr->dst_rules;		dpyr = dp0 + 1;		/* Create a pair of transition times for each year */		for (y = min_year; y < max_year; y++) {			ly = isleap(y);			/* Point to the begin and end days for this year */			dp = (y == dpyr->dayyr ? dpyr++ : dp0);			tday = dp->daylb;			for (i = 0; i < 2; i++) {				/* Compute the transition time */				if (ly && tday >= feb28_day0)					tday++;				wday = ((ytt / SECS_PER_DAY)					+ EPOCH_WDAY + tday)					% DAYS_PER_WEEK;				if (wday < 0)					wday += DAYS_PER_WEEK;				tday -= wday;				/* Store the transition time and type index */				type = i;				if (dr->dst_hemi != STH)				    type ^= 1;				_tzs.ats[tc] = ytt					+ (tday * SECS_PER_DAY)					+ (2 * SECS_PER_HOUR)					- _tzs.ttis[type ^ 1].tt_gmtoff;				_tzs.types[tc] = type;				tc++;				tday = dp->dayle;			};			ytt += DAYS_PER_NYEAR * SECS_PER_DAY;			if (ly)				ytt += SECS_PER_DAY;		};		_tzs.timecnt = tc;	};			}/* * Set the time conversion information based on the kernel's idea * of local time. Changes to and from daylight savings time are * handled in a backwards compatible fashion. */statictzsetkernel(){	time_t		sw;	/* seconds west */	register struct dayrule *dr;	struct timeval	tv;	struct timezone	tz;	char		*_tztab();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -