Sophie

Sophie

distrib > Scientific%20Linux > 5x > i386 > by-pkgid > 351d529f9beeb4e5d936a6d5e3e7813a > files > 2454

kernel-2.6.18-128.29.1.el5.src.rpm

From: Jason Baron <jbaron@redhat.com>
Subject: [RHEL5 patch] fix tux overflow
Date: Fri, 23 Mar 2007 10:51:40 -0400 (EDT)
Bugzilla: 231561
Message-Id: <Pine.LNX.4.64.0703231049580.2638@dhcp83-20.boston.redhat.com>
Changelog: [tux] date overflow fix



fixes bz #231561

thanks,

-jason


--- linux-2.6.18.noarch/net/tux/times.c.bak	2007-03-22 16:59:01.000000000 -0400
+++ linux-2.6.18.noarch/net/tux/times.c	2007-03-22 16:59:15.000000000 -0400
@@ -30,8 +30,11 @@
 #include <linux/slab.h>
 #include <linux/ctype.h>
 
-
-#include "times.h"
+#define EPOCH_YEAR	1970
+#define DAY		(24 * 60 * 60)
+#define YEAR		(365 * DAY)
+#define LEAP_YEAR	(YEAR + DAY)
+#define FOUR_CYCLE	(3 * YEAR + LEAP_YEAR)
 
 char *dayName[7] = {
 	"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
@@ -42,6 +45,33 @@ static char *monthName[12] = {
 	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
 };
 
+unsigned int month_table[2][12] = {
+        { 31 * DAY,
+	  (31 + 28) * DAY,
+	  (31 + 28 + 31) * DAY,
+	  (31 + 28 + 31 + 30) * DAY,
+	  (31 + 28 + 31 + 30 + 31) * DAY,
+	  (31 + 28 + 31 + 30 + 31 + 30) * DAY,
+	  (31 + 28 + 31 + 30 + 31 + 30 + 31) * DAY,
+	  (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31) * DAY,
+	  (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30) * DAY,
+	  (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31) * DAY,
+	  (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30) * DAY,
+	  (31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31) * DAY },
+        { 31 * DAY,
+	  (31 + 29) * DAY,
+	  (31 + 29 + 31) * DAY,
+	  (31 + 29 + 31 + 30) * DAY,
+	  (31 + 29 + 31 + 30 + 31) * DAY,
+	  (31 + 29 + 31 + 30 + 31 + 30) * DAY,
+	  (31 + 29 + 31 + 30 + 31 + 30 + 31) * DAY,
+	  (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31) * DAY,
+	  (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30) * DAY,
+	  (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31) * DAY,
+	  (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30) * DAY,
+	  (31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31) * DAY },
+};
+
 char itoa_h[60]={'0','0','0','0','0','0','0','0','0','0',
 		 '1','1','1','1','1','1','1','1','1','1',
 		 '2','2','2','2','2','2','2','2','2','2',
@@ -58,119 +88,56 @@ char itoa_l[60]={'0','1','2','3','4','5'
 
 int time_unix2ls(time_t zulu, char *buf)
 {
-	int Y=0,M=0,D=0;
-	int H=0,Min=0,S=0,WD=0;
-	int I,I2;
-	time_t rest, delta;
+	unsigned int i, year, month, day, hour, minute, leap_year, cycles, *mtp;
+	unsigned long offset;
+	time_t delta;
 
-	if (zulu > xtime.tv_sec)
+	if ((unsigned long)zulu > (unsigned long)xtime.tv_sec)
 		zulu = xtime.tv_sec;
 
-	I=0;
-	while (I<TUX_NUMYEARS) {
-		if (TimeDays[I][0]>zulu)
-		   break;
-		I++;
-	}
-
-	Y=--I;
-	if (I<0) {
-		Y=0;
-		goto BuildYear;
-	}
-	I2=0;
-	while (I2<=12) {
-		if (TimeDays[I][I2]>zulu)
-		   break;
-		I2++;
-	}
-
-	M=I2-1;
-
-	rest=zulu - TimeDays[Y][M];
-	WD=WeekDays[Y][M];
-	D=rest/86400;
-	rest=rest%86400;
-	WD+=D;
-	WD=WD%7;
-	H=rest/3600;
-	rest=rest%3600;
-	Min=rest/60;
-	rest=rest%60;
-	S=rest;
+	offset = (unsigned long)zulu;
 
-BuildYear:
-	Y+=TUX_YEAROFFSET;
+	/* calculate the year */
+	offset += YEAR + LEAP_YEAR;
+	year = EPOCH_YEAR - 2;
+	cycles = offset / FOUR_CYCLE;
+	offset -= cycles * FOUR_CYCLE;
+	year += 4 * cycles;
+	if (offset >= LEAP_YEAR) {
+		offset -= LEAP_YEAR;
+		i = offset / YEAR;
+		offset -= i * YEAR;
+		year += i + 1;
+		leap_year = 0;
+	} else
+		leap_year = 1;
 
+	/* next we calculate the month */
+	mtp = &month_table[leap_year][0];
+	for (i = 0; i < 11; i++, mtp++) {
+		if (offset < *mtp)
+			break;
+	}
+	month = i;
+	if (month != 0)
+		offset -= *(mtp - 1);
+
+	/* finally, calculate day, hour, minute */
+	day = offset / DAY;
+	offset -= day * DAY;
+	hour = offset / 3600;
+	offset -= hour * 3600;
+	minute = offset / 60;
 
 	/* Format:  Day, 01 Mon 1999 01:01:01 GMT */
-
 	delta = xtime.tv_sec - zulu;
-	if (delta > 6*30*24*60)
+	if (delta > YEAR / 2)
 		//               "May 23   2000"
-		return sprintf( buf, "%s %02i  %04i", monthName[M], D+1, Y);
+		return sprintf( buf, "%s %02i  %04i", monthName[month], day + 1, year);
 	else
 		//                "May 23 10:14"
 		return sprintf( buf, "%s %02i %02i:%02i",
-			monthName[M], D+1, H, Min);
-}
-
-static int MonthHash[32] =
-	{0,0,7,0,0,0,0,0,0,0,0,3,0,0,0,2,6,0,5,0,9,8,4,0,0,11,1,10,0,0,0,0};
-
-#define is_digit(c)	((c) >= '0' && (c) <= '9')
-
-static inline int skip_atoi(char **s)
-{
-	int i=0;
-
-	while (is_digit(**s))
-		i = i*10 + *((*s)++) - '0';
-	return i;
-}
-
-time_t mimetime_to_unixtime(char *Q)
-{
-	int Y,M,D,H,Min,S;
-	unsigned int Hash;
-	time_t Temp;
-	char *s,**s2;
-
-	s=Q;
-	s2=&s;
-
-	if (strlen(s)<30) return 0;
-	if (s[3]!=',') return 0;
-	if (s[19]!=':') return 0;
-
-	s+=5; /* Skip day of week */
-	D = skip_atoi(s2);  /*  Day of month */
-	s++;
-	Hash = (char)s[0]+(char)s[2];
-	Hash = (Hash<<1) + (char)s[1];
-	Hash = (Hash&63)>>1;
-	M = MonthHash[Hash];
-	s+=4;
-	Y = skip_atoi(s2); /* Year */
-	s++;
-	H = skip_atoi(s2); /* Hour */
-	s++;
-	Min = skip_atoi(s2); /* Minutes */
-	s++;
-	S = skip_atoi(s2); /* Seconds */
-	s++;
-	if ((s[0]!='G')||(s[1]!='M')||(s[2]!='T'))
-	{
-		return 0; /* No GMT */
-	}
-
-	if (Y<TUX_YEAROFFSET) Y = TUX_YEAROFFSET;
-	if (Y>TUX_YEAROFFSET+9) Y = TUX_YEAROFFSET+9;
-
-	Temp = TimeDays[Y-TUX_YEAROFFSET][M];
-	Temp += D*86400+H*3600+Min*60+S;
-
-	return Temp;
+			monthName[month], day + 1, hour, minute);
 }
 
 // writes the full http date, corresponding to time_t received
--- linux-2.6.18.noarch/net/tux/times.h.bak	2007-03-22 16:59:01.000000000 -0400
+++ linux-2.6.18.noarch/net/tux/times.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-static time_t TimeDays[10][13] = {
- { 852073200,	854751600,	857170800,	859849200,	862441200,	865119600,	867711600,	870390000,	873068400,	875660400,	878338800,	880930800,	883609200 } ,
- { 883609200,	886287600,	888706800,	891385200,	893977200,	896655600,	899247600,	901926000,	904604400,	907196400,	909874800,	912466800,	915145200 } ,
- { 915145200,	917823600,	920242800,	922921200,	925513200,	928191600,	930783600,	933462000,	936140400,	938732400,	941410800,	944002800,	946681200 } ,
- { 946681200,	949359600,	951865200,	954543600,	957135600,	959814000,	962406000,	965084400,	967762800,	970354800,	973033200,	975625200,	978303600 } ,
- { 978303600,	980982000,	983401200,	986079600,	988671600,	991350000,	993942000,	996620400,	999298800,	1001890800,	1004569200,	1007161200,	1009839600 } ,
- { 1009839600,	1012518000,	1014937200,	1017615600,	1020207600,	1022886000,	1025478000,	1028156400,	1030834800,	1033426800,	1036105200,	1038697200,	1041375600 } ,
- { 1041375600,	1044054000,	1046473200,	1049151600,	1051743600,	1054422000,	1057014000,	1059692400,	1062370800,	1064962800,	1067641200,	1070233200,	1072911600 } ,
- { 1072911600,	1075590000,	1078095600,	1080774000,	1083366000,	1086044400,	1088636400,	1091314800,	1093993200,	1096585200,	1099263600,	1101855600,	1104534000 } ,
- { 1104534000,	1107212400,	1109631600,	1112310000,	1114902000,	1117580400,	1120172400,	1122850800,	1125529200,	1128121200,	1130799600,	1133391600,	1136070000 } ,
- { 1136070000,	1138748400,	1141167600,	1143846000,	1146438000,	1149116400,	1151708400,	1154386800,	1157065200,	1159657200,	1162335600,	1164927600,	1167606000 }
-};
-static int WeekDays[10][13] = {
- { 3,	6,	6,	2,	4,	0,	2,	5,	1,	3,	6,	1,	4 } ,
- { 4,	0,	0,	3,	5,	1,	3,	6,	2,	4,	0,	2,	5 } ,
- { 5,	1,	1,	4,	6,	2,	4,	0,	3,	5,	1,	3,	6 } ,
- { 6,	2,	3,	6,	1,	4,	6,	2,	5,	0,	3,	5,	1 } ,
- { 1,	4,	4,	0,	2,	5,	0,	3,	6,	1,	4,	6,	2 } ,
- { 2,	5,	5,	1,	3,	6,	1,	4,	0,	2,	5,	0,	3 } ,
- { 3,	6,	6,	2,	4,	0,	2,	5,	1,	3,	6,	1,	4 } ,
- { 4,	0,	1,	4,	6,	2,	4,	0,	3,	5,	1,	3,	6 } ,
- { 6,	2,	2,	5,	0,	3,	5,	1,	4,	6,	2,	4,	0 } ,
- { 0,	3,	3,	6,	1,	4,	6,	2,	5,	0,	3,	5,	1 }
-};
-#define TUX_YEAROFFSET   1997
-#define TUX_NUMYEARS     10