1 /*
2 
3 Functions related to time:
4 
5 1) rfc (string) time to unix-time
6 2) unix-time to rfc (string) time
7 3) current time to rfc (string) time for the "Date:" header
8 
9 */
10 
11 /****************************************************************
12  *	This program is free software; you can redistribute it and/or modify
13  *	it under the terms of the GNU General Public License as published by
14  *	the Free Software Foundation; either version 2, or (at your option)
15  *	any later version.
16  *
17  *	This program is distributed in the hope that it will be useful,
18  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *	GNU General Public License for more details.
21  *
22  *	You should have received a copy of the GNU General Public License
23  *	along with this program; if not, write to the Free Software
24  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  *
26  ****************************************************************/
27 
28 #include <linux/time.h>
29 #include <linux/kernel.h>
30 #include <linux/slab.h>
31 #include <linux/ctype.h>
32 
33 
34 #include "times.h"
35 #include "prototypes.h"
36 static char *dayName[7] = {
37 	"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
38 };
39 
40 static char *monthName[12] = {
41 	"Jan", "Feb", "Mar", "Apr", "May", "Jun",
42 	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
43 };
44 
45 
46 char CurrentTime[64];
47 int  CurrentTime_i;
48 
49 
50 static char itoa_h[60]={'0','0','0','0','0','0','0','0','0','0',
51 		 '1','1','1','1','1','1','1','1','1','1',
52 		 '2','2','2','2','2','2','2','2','2','2',
53 		 '3','3','3','3','3','3','3','3','3','3',
54 		 '4','4','4','4','4','4','4','4','4','4',
55 		 '5','5','5','5','5','5','5','5','5','5'};
56 
57 static char itoa_l[60]={'0','1','2','3','4','5','6','7','8','9',
58 		 '0','1','2','3','4','5','6','7','8','9',
59 		 '0','1','2','3','4','5','6','7','8','9',
60 		 '0','1','2','3','4','5','6','7','8','9',
61 		 '0','1','2','3','4','5','6','7','8','9',
62 		 '0','1','2','3','4','5','6','7','8','9'};
time_Unix2RFC(const time_t Zulu,char * Buffer)63 void time_Unix2RFC(const time_t Zulu,char *Buffer)
64 {
65 	int Y=0,M=0,D=0;
66 	int H=0,Min=0,S=0,WD=0;
67 	int I,I2;
68 	time_t rest;
69 
70 
71 
72 	I=0;
73 	while (I<KHTTPD_NUMYEARS)
74 	{
75 		if (TimeDays[I][0]>Zulu)
76 		   break;
77 		I++;
78 	}
79 
80 	Y=--I;
81 	if (I<0)
82 	{
83 		Y=0;
84 		goto BuildYear;
85 	}
86 	I2=0;
87 	while (I2<=12)
88 	{
89 		if (TimeDays[I][I2]>Zulu)
90 		   break;
91 		I2++;
92 	}
93 
94 	M=I2-1;
95 
96 	rest=Zulu - TimeDays[Y][M];
97 	WD=WeekDays[Y][M];
98 	D=rest/86400;
99 	rest=rest%86400;
100 	WD+=D;
101 	WD=WD%7;
102 	H=rest/3600;
103 	rest=rest%3600;
104 	Min=rest/60;
105 	rest=rest%60;
106 	S=rest;
107 
108 BuildYear:
109 	Y+=KHTTPD_YEAROFFSET;
110 
111 
112 	/* Format:  Day, 01 Mon 1999 01:01:01 GMT */
113 
114 /*
115 	We want to do
116 
117 	sprintf( Buffer, "%s, %02i %s %04i %02i:%02i:%02i GMT",
118 		dayName[ WD ], D+1, monthName[ M ], Y,
119 		H, Min, S
120 	);
121 
122 	but this is very expensive. Since the string is fixed length,
123 	it is filled manually.
124 */
125 	Buffer[0]=dayName[WD][0];
126 	Buffer[1]=dayName[WD][1];
127 	Buffer[2]=dayName[WD][2];
128 	Buffer[3]=',';
129 	Buffer[4]=' ';
130 	Buffer[5]=itoa_h[D+1];
131 	Buffer[6]=itoa_l[D+1];
132 	Buffer[7]=' ';
133 	Buffer[8]=monthName[M][0];
134 	Buffer[9]=monthName[M][1];
135 	Buffer[10]=monthName[M][2];
136 	Buffer[11]=' ';
137 	Buffer[12]=itoa_l[Y/1000];
138 	Buffer[13]=itoa_l[(Y/100)%10];
139 	Buffer[14]=itoa_l[(Y/10)%10];
140 	Buffer[15]=itoa_l[Y%10];
141 	Buffer[16]=' ';
142 	Buffer[17]=itoa_h[H];
143 	Buffer[18]=itoa_l[H];
144 	Buffer[19]=':';
145 	Buffer[20]=itoa_h[Min];
146 	Buffer[21]=itoa_l[Min];
147 	Buffer[22]=':';
148 	Buffer[23]=itoa_h[S];
149 	Buffer[24]=itoa_l[S];
150 	Buffer[25]=' ';
151 	Buffer[26]='G';
152 	Buffer[27]='M';
153 	Buffer[28]='T';
154 	Buffer[29]=0;
155 
156 
157 
158 
159 }
160 
UpdateCurrentDate(void)161 void UpdateCurrentDate(void)
162 {
163    struct timeval tv;
164 
165    do_gettimeofday(&tv);
166    if (CurrentTime_i!=tv.tv_sec)
167 	   time_Unix2RFC(tv.tv_sec,CurrentTime);
168 
169    CurrentTime_i = tv.tv_sec;
170 }
171 
172 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};
173 
174 #define is_digit(c)	((c) >= '0' && (c) <= '9')
175 
skip_atoi(char ** s)176 __inline static int skip_atoi(char **s)
177 {
178 	int i=0;
179 
180 	while (is_digit(**s))
181 		i = i*10 + *((*s)++) - '0';
182 	return i;
183 }
184 
mimeTime_to_UnixTime(char * Q)185 time_t mimeTime_to_UnixTime(char *Q)
186 {
187 	int Y,M,D,H,Min,S;
188 	unsigned int Hash;
189 	time_t Temp;
190 	char *s,**s2;
191 
192 	s=Q;
193 	s2=&s;
194 
195 	if (strlen(s)<30) return 0;
196 	if (s[3]!=',') return 0;
197 	if (s[19]!=':') return 0;
198 
199 	s+=5; /* Skip day of week */
200 	D = skip_atoi(s2);  /*  Day of month */
201 	s++;
202 	Hash = (unsigned char)s[0]+(unsigned char)s[2];
203 	Hash = (Hash<<1) + (unsigned char)s[1];
204 	Hash = (Hash&63)>>1;
205 	M = MonthHash[Hash];
206 	s+=4;
207 	Y = skip_atoi(s2); /* Year */
208 	s++;
209 	H = skip_atoi(s2); /* Hour */
210 	s++;
211 	Min = skip_atoi(s2); /* Minutes */
212 	s++;
213 	S = skip_atoi(s2); /* Seconds */
214 	s++;
215 	if ((s[0]!='G')||(s[1]!='M')||(s[2]!='T'))
216 	{
217   		return 0; /* No GMT */
218   	}
219 
220 	if (Y<KHTTPD_YEAROFFSET) Y = KHTTPD_YEAROFFSET;
221 	if (Y>KHTTPD_YEAROFFSET+9) Y = KHTTPD_YEAROFFSET+9;
222 
223 	Temp = 	TimeDays[Y-KHTTPD_YEAROFFSET][M];
224 	Temp += D*86400+H*3600+Min*60+S;
225 
226 	return Temp;
227 }
228