about summary refs log tree commit diff
path: root/timezone/zic.c
diff options
context:
space:
mode:
Diffstat (limited to 'timezone/zic.c')
-rw-r--r--timezone/zic.c89
1 files changed, 52 insertions, 37 deletions
diff --git a/timezone/zic.c b/timezone/zic.c
index 9bb8662e55..d855475f9f 100644
--- a/timezone/zic.c
+++ b/timezone/zic.c
@@ -1,4 +1,10 @@
-static char	elsieid[] = "@(#)zic.c	7.116";
+static char	elsieid[] = "@(#)zic.c	7.118";
+
+/*
+** Regardless of the type of time_t, we do our work using this type.
+*/
+
+typedef int	zic_t;
 
 #include "private.h"
 #include "locale.h"
@@ -50,7 +56,7 @@ struct rule {
 	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 */
+	zic_t		r_temp;		/* used in outzone */
 };
 
 /*
@@ -76,7 +82,7 @@ struct zone {
 	int		z_nrules;
 
 	struct rule	z_untilrule;
-	time_t		z_untiltime;
+	zic_t		z_untiltime;
 };
 
 extern int	getopt P((int argc, char * const argv[],
@@ -85,10 +91,10 @@ extern int	link P((const char * fromname, const char * toname));
 extern char *	optarg;
 extern int	optind;
 
-static void	addtt P((time_t starttime, int type));
+static void	addtt P((zic_t starttime, int type));
 static int	addtype P((long gmtoff, const char * abbr, int isdst,
 				int ttisstd, int ttisgmt));
-static void	leapadd P((time_t t, int positive, int rolling, int count));
+static void	leapadd P((zic_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));
@@ -121,13 +127,13 @@ 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 zic_t	rpytime P((const struct rule * rp, int wantedy));
 static void	rulesub P((struct rule * rp,
 			const char * loyearp, const char * hiyearp,
 			const char * typep, const char * monthp,
 			const char * dayp, const char * timep));
 static void	setboundaries P((void));
-static time_t	tadd P((time_t t1, long t2));
+static zic_t	tadd P((zic_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));
@@ -141,10 +147,10 @@ static int		errors;
 static const char *	filename;
 static int		leapcnt;
 static int		linenum;
-static time_t		max_time;
+static zic_t		max_time;
 static int		max_year;
 static int		max_year_representable;
-static time_t		min_time;
+static zic_t		min_time;
 static int		min_year;
 static int		min_year_representable;
 static int		noise;
@@ -334,7 +340,7 @@ static const int	len_years[2] = {
 };
 
 static struct attype {
-	time_t		at;
+	zic_t		at;
 	unsigned char	type;
 }			attypes[TZ_MAX_TIMES];
 static long		gmtoffs[TZ_MAX_TYPES];
@@ -343,7 +349,7 @@ 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 zic_t		trans[TZ_MAX_LEAPS];
 static long		corr[TZ_MAX_LEAPS];
 static char		roll[TZ_MAX_LEAPS];
 
@@ -629,7 +635,7 @@ const char * const	tofile;
 		        register char * symlinkcontents = NULL;
 		        while ((s = strchr(s+1, '/')) != NULL)
 			        symlinkcontents = ecatalloc(symlinkcontents, "../");
-			symlinkcontents = ecatalloc(symlinkcontents, fromname);
+			symlinkcontents = ecatalloc(symlinkcontents, fromfile);
 
 			result = unlink(toname);
 			if (result != 0 && errno != ENOENT) {
@@ -676,25 +682,36 @@ warning(_("hard link failed, symbolic link used"));
 */
 
 #define MAX_BITS_IN_FILE	32
-#define TIME_T_BITS_IN_FILE	((TYPE_BIT(time_t) < MAX_BITS_IN_FILE) ? TYPE_BIT(time_t) : MAX_BITS_IN_FILE)
+#define TIME_T_BITS_IN_FILE	((TYPE_BIT(zic_t) < MAX_BITS_IN_FILE) ? \
+					TYPE_BIT(zic_t) : MAX_BITS_IN_FILE)
 
 static void
 setboundaries P((void))
 {
-	if (TYPE_SIGNED(time_t)) {
-		min_time = ~ (time_t) 0;
-		min_time <<= TIME_T_BITS_IN_FILE - 1;
-		max_time = ~ (time_t) 0 - min_time;
+	register int	i;
+
+	if (TYPE_SIGNED(zic_t)) {
+		min_time = -1;
+		for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i)
+			min_time *= 2;
+		max_time = -(min_time + 1);
 		if (sflag)
 			min_time = 0;
 	} else {
 		min_time = 0;
 		max_time = 2 - sflag;
-		max_time <<= TIME_T_BITS_IN_FILE - 1;
+		for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i)
+			max_time *= 2;
 		--max_time;
 	}
-	min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year;
-	max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year;
+	{
+		time_t	t;
+
+		t = (time_t) min_time;
+		min_year = TM_YEAR_BASE + gmtime(&t)->tm_year;
+		t = (time_t) max_time;
+		max_year = TM_YEAR_BASE + gmtime(&t)->tm_year;
+	}
 	min_year_representable = min_year;
 	max_year_representable = max_year;
 }
@@ -1120,7 +1137,7 @@ const int		nfields;
 	register int			i, j;
 	int				year, month, day;
 	long				dayoff, tod;
-	time_t				t;
+	zic_t				t;
 
 	if (nfields != LEAP_FIELDS) {
 		error(_("wrong number of fields on Leap line"));
@@ -1164,7 +1181,7 @@ const int		nfields;
 			return;
 	}
 	dayoff = oadd(dayoff, eitol(day - 1));
-	if (dayoff < 0 && !TYPE_SIGNED(time_t)) {
+	if (dayoff < 0 && !TYPE_SIGNED(zic_t)) {
 		error(_("time before zero"));
 		return;
 	}
@@ -1176,7 +1193,7 @@ const int		nfields;
 		error(_("time too large"));
 		return;
 	}
-	t = (time_t) dayoff * SECSPERDAY;
+	t = (zic_t) dayoff * SECSPERDAY;
 	tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE);
 	cp = fields[LP_CORR];
 	{
@@ -1438,7 +1455,7 @@ const char * const	name;
 	register int		i, j;
 	static char *		fullname;
 	static struct tzhead	tzh;
-	time_t			ats[TZ_MAX_TIMES];
+	zic_t			ats[TZ_MAX_TIMES];
 	unsigned char		types[TZ_MAX_TIMES];
 
 	/*
@@ -1603,7 +1620,7 @@ const int			zonecount;
 	register struct rule *		rp;
 	register int			i, j;
 	register int			usestart, useuntil;
-	register time_t			starttime, untiltime;
+	register zic_t			starttime, untiltime;
 	register long			gmtoff;
 	register long			stdoff;
 	register int			year;
@@ -1672,7 +1689,7 @@ const int			zonecount;
 			}
 			for ( ; ; ) {
 				register int	k;
-				register time_t	jtime, ktime;
+				register zic_t	jtime, ktime;
 				register long	offset;
 				char		buf[BUFSIZ];
 
@@ -1784,7 +1801,7 @@ error(_("can't determine time zone abbreviation to use just after until time"));
 
 static void
 addtt(starttime, type)
-const time_t	starttime;
+const zic_t	starttime;
 int		type;
 {
 	if (starttime <= min_time ||
@@ -1868,7 +1885,7 @@ const int		ttisgmt;
 
 static void
 leapadd(t, positive, rolling, count)
-const time_t	t;
+const zic_t	t;
 const int	positive;
 const int	rolling;
 int		count;
@@ -2056,12 +2073,12 @@ const long	t2;
 	return t;
 }
 
-static time_t
+static zic_t
 tadd(t1, t2)
-const time_t	t1;
+const zic_t	t1;
 const long	t2;
 {
-	register time_t	t;
+	register zic_t	t;
 
 	if (t1 == max_time && t2 > 0)
 		return max_time;
@@ -2080,14 +2097,14 @@ const long	t2;
 ** 1970, 00:00 LOCAL time - in that year that the rule refers to.
 */
 
-static time_t
+static zic_t
 rpytime(rp, wantedy)
 register const struct rule * const	rp;
 register const int			wantedy;
 {
 	register int	y, m, i;
 	register long	dayoff;			/* with a nod to Margaret O. */
-	register time_t	t;
+	register zic_t	t;
 
 	if (wantedy == INT_MIN)
 		return min_time;
@@ -2154,15 +2171,13 @@ register const int			wantedy;
 				warning(_("rule goes past start/end of month--will not work with pre-2004 versions of zic"));
 		}
 	}
-	if (dayoff < 0 && !TYPE_SIGNED(time_t))
+	if (dayoff < 0 && !TYPE_SIGNED(zic_t))
 		return min_time;
 	if (dayoff < min_time / SECSPERDAY)
 		return min_time;
 	if (dayoff > max_time / SECSPERDAY)
 		return max_time;
-	t = (time_t) dayoff * SECSPERDAY;
-	if (t > 0 && max_time - t < rp->r_tod)
-		return max_time;
+	t = (zic_t) dayoff * SECSPERDAY;
 	return tadd(t, rp->r_tod);
 }