cleanup
[linux-2.4.21-pre4.git] / net / khttpd / rfc_time.c
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'};
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
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
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
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 }