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

📄 zic.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/*- * Copyright (c) 1991, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Arthur David Olson of the National Cancer Institute. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)zic.c	8.1 (Berkeley) 7/19/93";#endif /* not lint */#ifdef notdefstatic char	elsieid[] = "@(#)zic.c	4.12";#endif#include <sys/types.h>#include <sys/cdefs.h>#include <sys/stat.h>#include <time.h>#include <tzfile.h>#include <stdio.h>#include <ctype.h>#include <string.h>#include <stdlib.h>#ifndef TRUE#define TRUE	1#define FALSE	0#endif /* !defined TRUE */struct rule {	const char *	r_filename;	int		r_linenum;	const char *	r_name;	int		r_loyear;	/* for example, 1986 */	int		r_hiyear;	/* for example, 1986 */	const char *	r_yrtype;	int		r_month;	/* 0..11 */	int		r_dycode;	/* see below */	int		r_dayofmonth;	int		r_wday;	long		r_tod;		/* time from midnight */	int		r_todisstd;	/* above is standard time if TRUE */					/* or wall clock time if FALSE */	long		r_stdoff;	/* offset from standard time */	const char *	r_abbrvar;	/* variable part of abbreviation */	int		r_todo;		/* a rule to do (used in outzone) */	time_t		r_temp;		/* used in outzone */};/***	r_dycode		r_dayofmonth	r_wday*/#define DC_DOM		0	/* 1..31 */	/* unused */#define DC_DOWGEQ	1	/* 1..31 */	/* 0..6 (Sun..Sat) */#define DC_DOWLEQ	2	/* 1..31 */	/* 0..6 (Sun..Sat) */struct zone {	const char *	z_filename;	int		z_linenum;	const char *	z_name;	long		z_gmtoff;	const char *	z_rule;	const char *	z_format;	long		z_stdoff;	struct rule *	z_rules;	int		z_nrules;	struct rule	z_untilrule;	time_t		z_untiltime;};extern char *	icatalloc __P((char * old, const char * new));extern char *	icpyalloc __P((const char * string));extern void	ifree __P((char * p));extern char *	imalloc __P((int n));extern char *	irealloc __P((char * old, int n));extern int	link __P((const char * fromname, const char * toname));extern char *	optarg;extern int	optind;extern void	perror __P((const char * string));extern char *	scheck __P((const char * string, const char * format));static void	addtt __P((time_t starttime, int type));static int	addtype		    __P((long gmtoff, const char * abbr, int isdst,		    int ttisstd));static void	addleap __P((time_t t, int positive, int rolling));static void	adjleap __P((void));static void	associate __P((void));static int	ciequal __P((const char * ap, const char * bp));static void	convert __P((long val, char * buf));static void	dolink __P((const char * fromfile, const char * tofile));static void	eat __P((const char * name, int num));static void	eats __P((const char * name, int num,		    const char * rname, int rnum));static long	eitol __P((int i));static void	error __P((const char * message));static char **	getfields __P((char * buf));static long	gethms __P((char * string, const char * errstrng,		    int signable));static void	infile __P((const char * filename));static void	inleap __P((char ** fields, int nfields));static void	inlink __P((char ** fields, int nfields));static void	inrule __P((char ** fields, int nfields));static int	inzcont __P((char ** fields, int nfields));static int	inzone __P((char ** fields, int nfields));static int	inzsub __P((char ** fields, int nfields, int iscont));static int	itsabbr __P((const char * abbr, const char * word));static int	itsdir __P((const char * name));static int	lowerit __P((int c));static char *	memcheck __P((char * tocheck));static int	mkdirs __P((char * filename));static void	newabbr __P((const char * abbr));static long	oadd __P((long t1, long t2));static void	outzone __P((const struct zone * zp, int ntzones));static void	puttzcode __P((long code, FILE * fp));static int	rcomp __P((const void *leftp, const void *rightp));static time_t	rpytime __P((const struct rule * rp, int wantedy));static void	rulesub __P((struct rule * rp, char * loyearp, char * hiyearp,		char * typep, char * monthp, char * dayp, char * timep));static void	setboundaries __P((void));static time_t	tadd __P((time_t t1, long t2));static void	usage __P((void));static void	writezone __P((const char * name));static int	yearistype __P((int year, const char * type));static int		charcnt;static int		errors;static const char *	filename;static int		leapcnt;static int		linenum;static time_t		max_time;static int		max_year;static time_t		min_time;static int		min_year;static int		noise;static const char *	rfilename;static int		rlinenum;static const char *	progname;static int		timecnt;static int		typecnt;static int		tt_signed;/*** Line codes.*/#define LC_RULE		0#define LC_ZONE		1#define LC_LINK		2#define LC_LEAP		3/*** Which fields are which on a Zone line.*/#define ZF_NAME		1#define ZF_GMTOFF	2#define ZF_RULE		3#define ZF_FORMAT	4#define ZF_TILYEAR	5#define ZF_TILMONTH	6#define ZF_TILDAY	7#define ZF_TILTIME	8#define ZONE_MINFIELDS	5#define ZONE_MAXFIELDS	9/*** Which fields are which on a Zone continuation line.*/#define ZFC_GMTOFF	0#define ZFC_RULE	1#define ZFC_FORMAT	2#define ZFC_TILYEAR	3#define ZFC_TILMONTH	4#define ZFC_TILDAY	5#define ZFC_TILTIME	6#define ZONEC_MINFIELDS	3#define ZONEC_MAXFIELDS	7/*** Which files are which on a Rule line.*/#define RF_NAME		1#define RF_LOYEAR	2#define RF_HIYEAR	3#define RF_COMMAND	4#define RF_MONTH	5#define RF_DAY		6#define RF_TOD		7#define RF_STDOFF	8#define RF_ABBRVAR	9#define RULE_FIELDS	10/*** Which fields are which on a Link line.*/#define LF_FROM		1#define LF_TO		2#define LINK_FIELDS	3/*** Which fields are which on a Leap line.*/#define LP_YEAR		1#define LP_MONTH	2#define LP_DAY		3#define LP_TIME		4#define LP_CORR		5#define LP_ROLL		6#define LEAP_FIELDS	7/*** Year synonyms.*/#define YR_MINIMUM	0#define YR_MAXIMUM	1#define YR_ONLY		2static struct rule *	rules;static int		nrules;	/* number of rules */static struct zone *	zones;static int		nzones;	/* number of zones */struct link {	const char *	l_filename;	int		l_linenum;	const char *	l_from;	const char *	l_to;};static struct link *	links;static int		nlinks;struct lookup {	const char *	l_word;	const int	l_value;};static struct lookup const *	byword __P((const char * string,					const struct lookup * lp));static struct lookup const	line_codes[] = {	"Rule",		LC_RULE,	"Zone",		LC_ZONE,	"Link",		LC_LINK,	"Leap",		LC_LEAP,	NULL,		0};static struct lookup const	mon_names[] = {	"January",	TM_JANUARY,	"February",	TM_FEBRUARY,	"March",	TM_MARCH,	"April",	TM_APRIL,	"May",		TM_MAY,	"June",		TM_JUNE,	"July",		TM_JULY,	"August",	TM_AUGUST,	"September",	TM_SEPTEMBER,	"October",	TM_OCTOBER,	"November",	TM_NOVEMBER,	"December",	TM_DECEMBER,	NULL,		0};static struct lookup const	wday_names[] = {	"Sunday",	TM_SUNDAY,	"Monday",	TM_MONDAY,	"Tuesday",	TM_TUESDAY,	"Wednesday",	TM_WEDNESDAY,	"Thursday",	TM_THURSDAY,	"Friday",	TM_FRIDAY,	"Saturday",	TM_SATURDAY,	NULL,		0};static struct lookup const	lasts[] = {	"last-Sunday",		TM_SUNDAY,	"last-Monday",		TM_MONDAY,	"last-Tuesday",		TM_TUESDAY,	"last-Wednesday",	TM_WEDNESDAY,	"last-Thursday",	TM_THURSDAY,	"last-Friday",		TM_FRIDAY,	"last-Saturday",	TM_SATURDAY,	NULL,			0};static struct lookup const	begin_years[] = {	"minimum",		YR_MINIMUM,	"maximum",		YR_MAXIMUM,	NULL,			0};static struct lookup const	end_years[] = {	"minimum",		YR_MINIMUM,	"maximum",		YR_MAXIMUM,	"only",			YR_ONLY,	NULL,			0};static struct lookup const	leap_types[] = {	"Rolling",		TRUE,	"Stationary",		FALSE,	NULL,			0};static const int	len_months[2][MONSPERYEAR] = {	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,	31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};static const int	len_years[2] = {	DAYSPERNYEAR, DAYSPERLYEAR};static time_t		ats[TZ_MAX_TIMES];static unsigned char	types[TZ_MAX_TIMES];static long		gmtoffs[TZ_MAX_TYPES];static char		isdsts[TZ_MAX_TYPES];static char		abbrinds[TZ_MAX_TYPES];static char		ttisstds[TZ_MAX_TYPES];static char		chars[TZ_MAX_CHARS];static time_t		trans[TZ_MAX_LEAPS];static long		corr[TZ_MAX_LEAPS];static char		roll[TZ_MAX_LEAPS];/*** Memory allocation.*/static char *memcheck(ptr)char * const	ptr;{	if (ptr == NULL) {		(void) perror(progname);		(void) exit(EXIT_FAILURE);	}	return ptr;}#define emalloc(size)		memcheck(imalloc(size))#define erealloc(ptr, size)	memcheck(irealloc(ptr, size))#define ecpyalloc(ptr)		memcheck(icpyalloc(ptr))#define ecatalloc(oldp, newp)	memcheck(icatalloc(oldp, newp))/*** Error handling.*/static voideats(name, num, rname, rnum)const char * const	name;const int		num;const char * const	rname;const int		rnum;{	filename = name;	linenum = num;	rfilename = rname;	rlinenum = rnum;}static voideat(name, num)const char * const	name;const int		num;{	eats(name, num, (char *) NULL, -1);}static voiderror(string)const char * const	string;{	/*	** Match the format of "cc" to allow sh users to	** 	zic ... 2>&1 | error -t "*" -v	** on BSD systems.	*/	(void) fprintf(stderr, "\"%s\", line %d: %s",		filename, linenum, string);	if (rfilename != NULL)		(void) fprintf(stderr, " (rule from \"%s\", line %d)",			rfilename, rlinenum);	(void) fprintf(stderr, "\n");	++errors;}static voidusage(){	(void) fprintf(stderr,"%s: usage is %s [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d directory ]\n\\t[ -L leapseconds ] [ filename ... ]\n",		progname, progname);	(void) exit(EXIT_FAILURE);}static const char *	psxrules = NULL;static const char *	lcltime = NULL;static const char *	directory = NULL;static const char *	leapsec = NULL;static int		sflag = FALSE;intmain(argc, argv)int	argc;char *	argv[];{	register int	i, j;	register int	c;	(void) umask(umask(022) | 022);	progname = argv[0];	while ((c = getopt(argc, argv, "d:l:p:L:vs")) != EOF)		switch (c) {			default:				usage();			case 'd':				if (directory == NULL)					directory = optarg;				else {					(void) fprintf(stderr,"%s: More than one -d option specified\n",						progname);					(void) exit(EXIT_FAILURE);				}				break;			case 'l':				if (lcltime == NULL)					lcltime = optarg;				else {					(void) fprintf(stderr,"%s: More than one -l option specified\n",						progname);					(void) exit(EXIT_FAILURE);				}				break;			case 'p':				if (psxrules == NULL)					psxrules = optarg;				else {					(void) fprintf(stderr,"%s: More than one -p option specified\n",						progname);					(void) exit(EXIT_FAILURE);				}				break;			case 'L':				if (leapsec == NULL)					leapsec = optarg;				else {					(void) fprintf(stderr,"%s: More than one -L option specified\n",						progname);					(void) exit(EXIT_FAILURE);				}				break;			case 'v':				noise = TRUE;				break;			case 's':				sflag = TRUE;				break;		}	if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)		usage();	/* usage message by request */	if (directory == NULL)		directory = TZDIR;	setboundaries();	if (optind < argc && leapsec != NULL) {		infile(leapsec);		adjleap();	}	zones = (struct zone *) emalloc(0);	rules = (struct rule *) emalloc(0);	links = (struct link *) emalloc(0);	for (i = optind; i < argc; ++i)		infile(argv[i]);	if (errors)		(void) exit(EXIT_FAILURE);	associate();	for (i = 0; i < nzones; i = j) {		/*		** Find the next non-continuation zone entry.		*/		for (j = i + 1; j < nzones && zones[j].z_name == NULL; ++j)			;		outzone(&zones[i], j - i);	}	/*	** Make links.	*/	for (i = 0; i < nlinks; ++i)		dolink(links[i].l_from, links[i].l_to);	if (lcltime != NULL)		dolink(lcltime, TZDEFAULT);	if (psxrules != NULL)		dolink(psxrules, TZDEFRULES);	return (errors == 0) ? EXIT_SUCCESS : EXIT_FAILURE;}static voiddolink(fromfile, tofile)const char * const	fromfile;const char * const	tofile;{	register char *	fromname;	register char *	toname;	fromname = ecpyalloc(directory);	fromname = ecatalloc(fromname, "/");	fromname = ecatalloc(fromname, fromfile);	toname = ecpyalloc(directory);	toname = ecatalloc(toname, "/");	toname = ecatalloc(toname, tofile);	/*	** We get to be careful here since	** there's a fair chance of root running us.	*/	if (!itsdir(toname))		(void) remove(toname);	if (link(fromname, toname) != 0) {		(void) fprintf(stderr, "%s: Can't link from %s to ",			progname, fromname);		(void) perror(toname);		(void) exit(EXIT_FAILURE);	}	ifree(fromname);	ifree(toname);}static voidsetboundaries(){	register time_t	bit;	for (bit = 1; bit > 0; bit <<= 1)		;	if (bit == 0) {		/* time_t is an unsigned type */		tt_signed = FALSE;		min_time = 0;		max_time = ~(time_t) 0;		if (sflag)			max_time >>= 1;	} else {		tt_signed = TRUE;		min_time = bit;		max_time = bit;		++max_time;		max_time = -max_time;		if (sflag)			min_time = 0;	}	min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year;	max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year;}static intitsdir(name)const char * const	name;{	struct stat	s;	return (stat(name, &s) == 0 && S_ISDIR(s.st_mode));}/*** Associate sets of rules with zones.*//*** Sort by rule name.*/static intrcomp(cp1, cp2)const void *	cp1;const void *	cp2;{	return strcmp(((struct rule *) cp1)->r_name,		((struct rule *) cp2)->r_name);

⌨️ 快捷键说明

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