about summary refs log tree commit diff
path: root/time/zic.c
diff options
context:
space:
mode:
Diffstat (limited to 'time/zic.c')
-rw-r--r--time/zic.c155
1 files changed, 96 insertions, 59 deletions
diff --git a/time/zic.c b/time/zic.c
index 73ea46821e..fc1a16bff9 100644
--- a/time/zic.c
+++ b/time/zic.c
@@ -1,11 +1,14 @@
 #ifndef lint
 #ifndef NOID
-static char	elsieid[] = "@(#)zic.c	7.28";
+static char	elsieid[] = "@(#)zic.c	7.50";
 #endif /* !defined NOID */
 #endif /* !defined lint */
 
 #include "private.h"
 #include "tzfile.h"
+#ifdef unix
+#include "sys/stat.h"			/* for umask manifest constants */
+#endif /* defined unix */
 
 struct rule {
 	const char *	r_filename;
@@ -25,7 +28,7 @@ struct rule {
 	long		r_tod;		/* time from midnight */
 	int		r_todisstd;	/* above is standard time if TRUE */
 					/* or wall clock time if FALSE */
-	int		r_todisuniv;	/* above is universal time if TRUE */
+	int		r_todisgmt;	/* above is GMT if TRUE */
 					/* or local time if FALSE */
 	long		r_stdoff;	/* offset from standard time */
 	const char *	r_abbrvar;	/* variable part of abbreviation */
@@ -60,8 +63,8 @@ struct zone {
 	time_t		z_untiltime;
 };
 
-extern int	emkdir P((const char * name, int mode));
-extern int	getopt P((int argc, char * argv[], const char * options));
+extern int	getopt P((int argc, char * const argv[],
+			const char * options));
 extern char *	icatalloc P((char * old, const char * new));
 extern char *	icpyalloc P((const char * string));
 extern void	ifree P((char * p));
@@ -74,13 +77,15 @@ 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));
+				int ttisstd, int ttisgmt));
 static void	leapadd P((time_t t, int positive, int rolling, int count));
 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	doabbr P((char * abbr, const char * format,
+			const char * letters, int isdst));
 static void	eat P((const char * name, int num));
 static void	eats P((const char * name, int num,
 			const char * rname, int rnum));
@@ -105,7 +110,7 @@ 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 genericptr_T leftp, const genericptr_T rightp));
+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,
 			const char * loyearp, const char * hiyearp,
@@ -321,6 +326,7 @@ static long		gmtoffs[TZ_MAX_TYPES];
 static char		isdsts[TZ_MAX_TYPES];
 static unsigned char	abbrinds[TZ_MAX_TYPES];
 static char		ttisstds[TZ_MAX_TYPES];
+static char		ttisgmts[TZ_MAX_TYPES];
 static char		chars[TZ_MAX_CHARS];
 static time_t		trans[TZ_MAX_LEAPS];
 static long		corr[TZ_MAX_LEAPS];
@@ -377,7 +383,7 @@ const char * const	string;
 {
 	/*
 	** Match the format of "cc" to allow sh users to
-	** 	zic ... 2>&1 | error -t "*" -v
+	**	zic ... 2>&1 | error -t "*" -v
 	** on BSD systems.
 	*/
 	(void) fprintf(stderr, "\"%s\", line %d: %s",
@@ -392,8 +398,8 @@ const char * const	string;
 static void
 usage P((void))
 {
-	(void) fprintf(stderr,
-"%s: usage is %s [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d directory ] \n\
+	(void) fprintf(stderr, "%s: usage is %s \
+[ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] [ -d directory ]\n\
 \t[ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n",
 		progname, progname);
 	(void) exit(EXIT_FAILURE);
@@ -411,11 +417,12 @@ main(argc, argv)
 int	argc;
 char *	argv[];
 {
-	register int	i, j;
+	register int	i;
+	register int	j;
 	register int	c;
 
 #ifdef unix
-	(void) umask(umask(022) | 022);
+	(void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH));
 #endif /* defined unix */
 	progname = argv[0];
 	while ((c = getopt(argc, argv, "d:l:p:L:vsy:")) != EOF)
@@ -601,7 +608,7 @@ const char * const	name;
 
 	myname = ecpyalloc(name);
 	myname = ecatalloc(myname, "/.");
-	accres = access(myname, 0);
+	accres = access(myname, F_OK);
 	ifree(myname);
 	return accres == 0;
 }
@@ -616,11 +623,11 @@ const char * const	name;
 
 static int
 rcomp(cp1, cp2)
-const genericptr_T	cp1;
-const genericptr_T	cp2;
+const void *	cp1;
+const void *	cp2;
 {
-	return strcmp(((struct rule *) cp1)->r_name,
-		((struct rule *) cp2)->r_name);
+	return strcmp(((const struct rule *) cp1)->r_name,
+		((const struct rule *) cp2)->r_name);
 }
 
 static void
@@ -632,9 +639,8 @@ associate P((void))
 	register int		i;
 
 	if (nrules != 0)
-		(void) qsort((genericptr_T) rules,
-			(qsort_size_T) nrules,
-			(qsort_size_T) sizeof *rules, rcomp);
+		(void) qsort((void *) rules, (size_t) nrules,
+			(size_t) sizeof *rules, rcomp);
 	for (i = 0; i < nzones; ++i) {
 		zp = &zones[i];
 		zp->z_rules = NULL;
@@ -767,7 +773,7 @@ const char *	name;
 
 /*
 ** Convert a string of one of the forms
-**	h	-h 	hh:mm	-hh:mm	hh:mm:ss	-hh:mm:ss
+**	h	-h	hh:mm	-hh:mm	hh:mm:ss	-hh:mm:ss
 ** into a number of seconds.
 ** A null string maps to zero.
 ** Call error with errstring and return zero on errors.
@@ -956,7 +962,8 @@ const int		iscont;
 			zones[nzones - 1].z_untiltime > min_time &&
 			zones[nzones - 1].z_untiltime < max_time &&
 			zones[nzones - 1].z_untiltime >= z.z_untiltime) {
-error("Zone continuation line end time is not after end time of previous line");
+				error("Zone continuation line end time is not \
+after end time of previous line");
 				return FALSE;
 		}
 	}
@@ -1115,25 +1122,25 @@ const char * const		timep;
 	}
 	rp->r_month = lp->l_value;
 	rp->r_todisstd = FALSE;
-	rp->r_todisuniv = FALSE;
+	rp->r_todisgmt = FALSE;
 	dp = ecpyalloc(timep);
 	if (*dp != '\0') {
 		ep = dp + strlen(dp) - 1;
 		switch (lowerit(*ep)) {
 			case 's':	/* Standard */
 				rp->r_todisstd = TRUE;
-				rp->r_todisuniv = FALSE;
+				rp->r_todisgmt = FALSE;
 				*ep = '\0';
 				break;
 			case 'w':	/* Wall */
 				rp->r_todisstd = FALSE;
-				rp->r_todisuniv = FALSE;
+				rp->r_todisgmt = FALSE;
 				*ep = '\0';
 			case 'g':	/* Greenwich */
 			case 'u':	/* Universal */
 			case 'z':	/* Zulu */
 				rp->r_todisstd = TRUE;
-				rp->r_todisuniv = TRUE;
+				rp->r_todisgmt = TRUE;
 				*ep = '\0';
 				break;
 		}
@@ -1144,7 +1151,8 @@ const char * const		timep;
 	** Year work.
 	*/
 	cp = loyearp;
-	if ((lp = byword(cp, begin_years)) != NULL) switch ((int) lp->l_value) {
+	lp = byword(cp, begin_years);
+	if (lp != NULL) switch ((int) lp->l_value) {
 		case YR_MINIMUM:
 			rp->r_loyear = min_int;
 			break;
@@ -1260,9 +1268,7 @@ FILE * const	fp;
 	char	buf[4];
 
 	convert(val, buf);
-	(void) fwrite((genericptr_T) buf,
-		(fwrite_size_T) sizeof buf,
-		(fwrite_size_T) 1, fp);
+	(void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
 }
 
 static void
@@ -1286,14 +1292,22 @@ const char * const	name;
 			(void) exit(EXIT_FAILURE);
 		}
 	}
+	convert(eitol(typecnt), tzh.tzh_ttisgmtcnt);
 	convert(eitol(typecnt), tzh.tzh_ttisstdcnt);
 	convert(eitol(leapcnt), tzh.tzh_leapcnt);
 	convert(eitol(timecnt), tzh.tzh_timecnt);
 	convert(eitol(typecnt), tzh.tzh_typecnt);
 	convert(eitol(charcnt), tzh.tzh_charcnt);
-	(void) fwrite((genericptr_T) &tzh,
-		(fwrite_size_T) sizeof tzh,
-		(fwrite_size_T) 1, fp);
+#define DO(field)	(void) fwrite((void *) tzh.field, \
+		(size_t) sizeof tzh.field, (size_t) 1, fp)
+	DO(tzh_reserved);
+	DO(tzh_ttisgmtcnt);
+	DO(tzh_ttisstdcnt);
+	DO(tzh_leapcnt);
+	DO(tzh_timecnt);
+	DO(tzh_typecnt);
+	DO(tzh_charcnt);
+#undef DO
 	for (i = 0; i < timecnt; ++i) {
 		j = leapcnt;
 		while (--j >= 0)
@@ -1304,18 +1318,16 @@ const char * const	name;
 		puttzcode((long) ats[i], fp);
 	}
 	if (timecnt > 0)
-		(void) fwrite((genericptr_T) types,
-			(fwrite_size_T) sizeof types[0],
-			(fwrite_size_T) timecnt, fp);
+		(void) fwrite((void *) types, (size_t) sizeof types[0],
+			(size_t) timecnt, fp);
 	for (i = 0; i < typecnt; ++i) {
 		puttzcode((long) gmtoffs[i], fp);
 		(void) putc(isdsts[i], fp);
 		(void) putc(abbrinds[i], fp);
 	}
 	if (charcnt != 0)
-		(void) fwrite((genericptr_T) chars,
-			(fwrite_size_T) sizeof chars[0],
-			(fwrite_size_T) charcnt, fp);
+		(void) fwrite((void *) chars, (size_t) sizeof chars[0],
+			(size_t) charcnt, fp);
 	for (i = 0; i < leapcnt; ++i) {
 		if (roll[i]) {
 			if (timecnt == 0 || trans[i] < ats[0]) {
@@ -1337,6 +1349,8 @@ const char * const	name;
 	}
 	for (i = 0; i < typecnt; ++i)
 		(void) putc(ttisstds[i], fp);
+	for (i = 0; i < typecnt; ++i)
+		(void) putc(ttisgmts[i], fp);
 	if (ferror(fp) || fclose(fp)) {
 		(void) fprintf(stderr, "%s: Write error on ", progname);
 		(void) perror(fullname);
@@ -1345,6 +1359,25 @@ const char * const	name;
 }
 
 static void
+doabbr(abbr, format, letters, isdst)
+char * const		abbr;
+const char * const	format;
+const char * const	letters;
+const int		isdst;
+{
+	if (strchr(format, '/') == NULL) {
+		if (letters == NULL)
+			(void) strcpy(abbr, format);
+		else	(void) sprintf(abbr, format, letters);
+	} else if (isdst)
+		(void) strcpy(abbr, strchr(format, '/') + 1);
+	else {
+		(void) strcpy(abbr, format);
+		*strchr(abbr, '/') = '\0';
+	}
+}
+
+static void
 outzone(zpfirst, zonecount)
 const struct zone * const	zpfirst;
 const int			zonecount;
@@ -1360,6 +1393,7 @@ const int			zonecount;
 	register long			startoff;
 	register int			startisdst;
 	register int			startttisstd;
+	register int			startttisgmt;
 	register int			type;
 	char				startbuf[BUFSIZ];
 
@@ -1381,9 +1415,7 @@ const int			zonecount;
 	** for noting the need to unconditionally initialize startttisstd.
 	*/
 	startttisstd = FALSE;
-#ifdef lint
-	starttime = 0;
-#endif /* defined lint */
+	startttisgmt = FALSE;
 	for (i = 0; i < zonecount; ++i) {
 		zp = &zpfirst[i];
 		usestart = i > 0 && (zp - 1)->z_untiltime > min_time;
@@ -1395,9 +1427,11 @@ const int			zonecount;
 		startisdst = -1;
 		if (zp->z_nrules == 0) {
 			stdoff = zp->z_stdoff;
-			(void) strcpy(startbuf, zp->z_format);
+			doabbr(startbuf, zp->z_format,
+				(char *) NULL, stdoff != 0);
 			type = addtype(oadd(zp->z_gmtoff, stdoff),
-				startbuf, stdoff != 0, startttisstd);
+				startbuf, stdoff != 0, startttisstd,
+				startttisgmt);
 			if (usestart)
 				addtt(starttime, type);
 			else if (stdoff != 0)
@@ -1433,7 +1467,7 @@ const int			zonecount;
 					** stdoff values.
 					*/
 					untiltime = zp->z_untiltime;
-					if (!zp->z_untilrule.r_todisuniv)
+					if (!zp->z_untilrule.r_todisgmt)
 						untiltime = tadd(untiltime,
 							-gmtoff);
 					if (!zp->z_untilrule.r_todisstd)
@@ -1445,16 +1479,13 @@ const int			zonecount;
 				** that takes effect earliest in the year.
 				*/
 				k = -1;
-#ifdef lint
-				ktime = 0;
-#endif /* defined lint */
 				for (j = 0; j < zp->z_nrules; ++j) {
 					rp = &zp->z_rules[j];
 					if (!rp->r_todo)
 						continue;
 					eats(zp->z_filename, zp->z_linenum,
 						rp->r_filename, rp->r_linenum);
-					offset = rp->r_todisuniv ? 0 : gmtoff;
+					offset = rp->r_todisgmt ? 0 : gmtoff;
 					if (!rp->r_todisstd)
 						offset = oadd(offset, stdoff);
 					jtime = rp->r_temp;
@@ -1478,8 +1509,9 @@ const int			zonecount;
 					stdoff = rp->r_stdoff;
 					startoff = oadd(zp->z_gmtoff,
 						rp->r_stdoff);
-					(void) sprintf(startbuf, zp->z_format,
-						rp->r_abbrvar);
+					doabbr(startbuf, zp->z_format,
+						rp->r_abbrvar,
+						rp->r_stdoff != 0);
 					startisdst = rp->r_stdoff != 0;
 					continue;
 				    }
@@ -1496,19 +1528,20 @@ const int			zonecount;
 						startoff = oadd(startoff,
 							zp->z_gmtoff);
 						(void) strcpy(startbuf,
-							&chars[abbrinds[type]]);
+						    &chars[abbrinds[type]]);
 					}
 					if (startisdst >= 0)
-addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd));
+addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd,
+	startttisgmt));
 				    }
 				}
 				eats(zp->z_filename, zp->z_linenum,
 					rp->r_filename, rp->r_linenum);
-				(void) sprintf(buf, zp->z_format,
-					rp->r_abbrvar);
+				doabbr(buf, zp->z_format, rp->r_abbrvar,
+					rp->r_stdoff != 0);
 				offset = oadd(zp->z_gmtoff, rp->r_stdoff);
 				type = addtype(offset, buf, rp->r_stdoff != 0,
-					rp->r_todisstd);
+					rp->r_todisstd, rp->r_todisgmt);
 				addtt(ktime, type);
 				stdoff = rp->r_stdoff;
 			}
@@ -1519,6 +1552,7 @@ addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd));
 		if (useuntil) {
 			starttime = tadd(zp->z_untiltime, -gmtoff);
 			startttisstd = zp->z_untilrule.r_todisstd;
+			startttisgmt = zp->z_untilrule.r_todisgmt;
 			if (!startttisstd)
 				starttime = tadd(starttime, -stdoff);
 		}
@@ -1545,11 +1579,12 @@ const int	type;
 }
 
 static int
-addtype(gmtoff, abbr, isdst, ttisstd)
+addtype(gmtoff, abbr, isdst, ttisstd, ttisgmt)
 const long		gmtoff;
 const char * const	abbr;
 const int		isdst;
 const int		ttisstd;
+const int		ttisgmt;
 {
 	register int	i, j;
 
@@ -1560,7 +1595,8 @@ const int		ttisstd;
 	for (i = 0; i < typecnt; ++i) {
 		if (gmtoff == gmtoffs[i] && isdst == isdsts[i] &&
 			strcmp(abbr, &chars[abbrinds[i]]) == 0 &&
-			ttisstd == ttisstds[i])
+			ttisstd == ttisstds[i] &&
+			ttisgmt == ttisgmts[i])
 				return i;
 	}
 	/*
@@ -1574,6 +1610,7 @@ const int		ttisstd;
 	gmtoffs[i] = gmtoff;
 	isdsts[i] = isdst;
 	ttisstds[i] = ttisstd;
+	ttisgmts[i] = ttisgmt;
 
 	for (j = 0; j < charcnt; ++j)
 		if (strcmp(&chars[j], abbr) == 0)
@@ -1908,7 +1945,7 @@ char * const	argname;
 		*cp = '\0';
 #ifndef unix
 		/*
-		** MS-DOS drive specifier?
+		** DOS drive specifier?
 		*/
 		if (strlen(name) == 2 && isascii(name[0]) &&
 			isalpha(name[0]) && name[1] == ':') {
@@ -1920,7 +1957,7 @@ char * const	argname;
 			/*
 			** It doesn't seem to exist, so we try to create it.
 			*/
-			if (emkdir(name, 0755) != 0) {
+			if (mkdir(name, 0755) != 0) {
 				(void) fprintf(stderr,
 					"%s: Can't create directory ",
 					progname);