1 9df487d7 2003-11-23 devnull #include <u.h>
2 9df487d7 2003-11-23 devnull #include <libc.h>
3 9df487d7 2003-11-23 devnull #include <httpd.h>
6 9df487d7 2003-11-23 devnull * print dates in the format
7 9df487d7 2003-11-23 devnull * Wkd, DD Mon YYYY HH:MM:SS GMT
8 9df487d7 2003-11-23 devnull * parse dates of formats
9 9df487d7 2003-11-23 devnull * Wkd, DD Mon YYYY HH:MM:SS GMT
10 9df487d7 2003-11-23 devnull * Weekday, DD-Mon-YY HH:MM:SS GMT
11 9df487d7 2003-11-23 devnull * Wkd Mon ( D|DD) HH:MM:SS YYYY
12 9df487d7 2003-11-23 devnull * plus anything similar
14 9df487d7 2003-11-23 devnull static char *
15 9df487d7 2003-11-23 devnull weekdayname[7] =
17 9df487d7 2003-11-23 devnull "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
19 9df487d7 2003-11-23 devnull static char *
20 9df487d7 2003-11-23 devnull wdayname[7] =
22 9df487d7 2003-11-23 devnull "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
25 9df487d7 2003-11-23 devnull static char *
26 9df487d7 2003-11-23 devnull monname[12] =
28 9df487d7 2003-11-23 devnull "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
31 9df487d7 2003-11-23 devnull static int dateindex(char*, char**, int);
33 9df487d7 2003-11-23 devnull static int
34 9df487d7 2003-11-23 devnull dtolower(int c)
36 9df487d7 2003-11-23 devnull if(c >= 'A' && c <= 'Z')
37 9df487d7 2003-11-23 devnull return c - 'A' + 'a';
38 9df487d7 2003-11-23 devnull return c;
41 9df487d7 2003-11-23 devnull static int
42 9df487d7 2003-11-23 devnull disalpha(int c)
44 9df487d7 2003-11-23 devnull return c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';
47 9df487d7 2003-11-23 devnull static int
48 9df487d7 2003-11-23 devnull disdig(int c)
50 9df487d7 2003-11-23 devnull return c >= '0' && c <= '9';
54 9df487d7 2003-11-23 devnull hdatefmt(Fmt *f)
59 9df487d7 2003-11-23 devnull t = va_arg(f->args, ulong);
60 9df487d7 2003-11-23 devnull tm = gmtime(t);
61 9df487d7 2003-11-23 devnull return fmtprint(f, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
62 9df487d7 2003-11-23 devnull wdayname[tm->wday], tm->mday, monname[tm->mon], tm->year+1900,
63 9df487d7 2003-11-23 devnull tm->hour, tm->min, tm->sec);
66 9df487d7 2003-11-23 devnull static char*
67 9df487d7 2003-11-23 devnull dateword(char *date, char *buf)
73 9df487d7 2003-11-23 devnull while(!disalpha(c = *date) && !disdig(c) && c)
75 9df487d7 2003-11-23 devnull while(disalpha(c = *date)){
76 9df487d7 2003-11-23 devnull if(p - buf < 30)
77 9df487d7 2003-11-23 devnull *p++ = dtolower(c);
81 9df487d7 2003-11-23 devnull return date;
84 9df487d7 2003-11-23 devnull static int
85 9df487d7 2003-11-23 devnull datenum(char **d)
87 9df487d7 2003-11-23 devnull char *date;
88 9df487d7 2003-11-23 devnull int c, n;
90 9df487d7 2003-11-23 devnull date = *d;
91 9df487d7 2003-11-23 devnull while(!disdig(c = *date) && c)
93 9df487d7 2003-11-23 devnull if(c == 0){
94 9df487d7 2003-11-23 devnull *d = date;
95 9df487d7 2003-11-23 devnull return -1;
98 9df487d7 2003-11-23 devnull while(disdig(c = *date)){
99 9df487d7 2003-11-23 devnull n = n * 10 + c - '0';
102 9df487d7 2003-11-23 devnull *d = date;
103 9df487d7 2003-11-23 devnull return n;
107 9df487d7 2003-11-23 devnull * parse a date and return the seconds since the epoch
108 9df487d7 2003-11-23 devnull * return 0 for a failure
111 9df487d7 2003-11-23 devnull hdate2sec(char *date)
114 9df487d7 2003-11-23 devnull char buf[32];
117 9df487d7 2003-11-23 devnull * Weekday|Wday
119 9df487d7 2003-11-23 devnull date = dateword(date, buf);
120 9df487d7 2003-11-23 devnull tm.wday = dateindex(buf, wdayname, 7);
121 9df487d7 2003-11-23 devnull if(tm.wday < 0)
122 9df487d7 2003-11-23 devnull tm.wday = dateindex(buf, weekdayname, 7);
123 9df487d7 2003-11-23 devnull if(tm.wday < 0)
124 9df487d7 2003-11-23 devnull return 0;
127 9df487d7 2003-11-23 devnull * check for the two major formats
129 9df487d7 2003-11-23 devnull date = dateword(date, buf);
130 9df487d7 2003-11-23 devnull tm.mon = dateindex(buf, monname, 12);
131 9df487d7 2003-11-23 devnull if(tm.mon >= 0){
135 9df487d7 2003-11-23 devnull tm.mday = datenum(&date);
136 9df487d7 2003-11-23 devnull if(tm.mday < 1 || tm.mday > 31)
137 9df487d7 2003-11-23 devnull return 0;
140 9df487d7 2003-11-23 devnull * HH:MM:SS
142 9df487d7 2003-11-23 devnull tm.hour = datenum(&date);
143 9df487d7 2003-11-23 devnull if(tm.hour < 0 || tm.hour >= 24)
144 9df487d7 2003-11-23 devnull return 0;
145 9df487d7 2003-11-23 devnull tm.min = datenum(&date);
146 9df487d7 2003-11-23 devnull if(tm.min < 0 || tm.min >= 60)
147 9df487d7 2003-11-23 devnull return 0;
148 9df487d7 2003-11-23 devnull tm.sec = datenum(&date);
149 9df487d7 2003-11-23 devnull if(tm.sec < 0 || tm.sec >= 60)
150 9df487d7 2003-11-23 devnull return 0;
155 9df487d7 2003-11-23 devnull tm.year = datenum(&date);
156 9df487d7 2003-11-23 devnull if(tm.year < 70 || tm.year > 99 && tm.year < 1970)
157 9df487d7 2003-11-23 devnull return 0;
158 9df487d7 2003-11-23 devnull if(tm.year >= 1970)
159 9df487d7 2003-11-23 devnull tm.year -= 1900;
162 9df487d7 2003-11-23 devnull * MM-Mon-(YY|YYYY)
164 9df487d7 2003-11-23 devnull tm.mday = datenum(&date);
165 9df487d7 2003-11-23 devnull if(tm.mday < 1 || tm.mday > 31)
166 9df487d7 2003-11-23 devnull return 0;
167 9df487d7 2003-11-23 devnull date = dateword(date, buf);
168 9df487d7 2003-11-23 devnull tm.mon = dateindex(buf, monname, 12);
169 9df487d7 2003-11-23 devnull if(tm.mon < 0 || tm.mon >= 12)
170 9df487d7 2003-11-23 devnull return 0;
171 9df487d7 2003-11-23 devnull tm.year = datenum(&date);
172 9df487d7 2003-11-23 devnull if(tm.year < 70 || tm.year > 99 && tm.year < 1970)
173 9df487d7 2003-11-23 devnull return 0;
174 9df487d7 2003-11-23 devnull if(tm.year >= 1970)
175 9df487d7 2003-11-23 devnull tm.year -= 1900;
178 9df487d7 2003-11-23 devnull * HH:MM:SS
180 9df487d7 2003-11-23 devnull tm.hour = datenum(&date);
181 9df487d7 2003-11-23 devnull if(tm.hour < 0 || tm.hour >= 24)
182 9df487d7 2003-11-23 devnull return 0;
183 9df487d7 2003-11-23 devnull tm.min = datenum(&date);
184 9df487d7 2003-11-23 devnull if(tm.min < 0 || tm.min >= 60)
185 9df487d7 2003-11-23 devnull return 0;
186 9df487d7 2003-11-23 devnull tm.sec = datenum(&date);
187 9df487d7 2003-11-23 devnull if(tm.sec < 0 || tm.sec >= 60)
188 9df487d7 2003-11-23 devnull return 0;
191 9df487d7 2003-11-23 devnull * timezone
193 9df487d7 2003-11-23 devnull dateword(date, buf);
194 9df487d7 2003-11-23 devnull if(strncmp(buf, "gmt", 3) != 0)
195 9df487d7 2003-11-23 devnull return 0;
198 9df487d7 2003-11-23 devnull strcpy(tm.zone, "GMT");
199 9df487d7 2003-11-23 devnull tm.tzoff = 0;
200 4bef0baf 2004-12-27 devnull tm.yday = 0;
201 9df487d7 2003-11-23 devnull return tm2sec(&tm);
204 9df487d7 2003-11-23 devnull static int
205 9df487d7 2003-11-23 devnull dateindex(char *d, char **tab, int n)
209 9df487d7 2003-11-23 devnull for(i = 0; i < n; i++)
210 9df487d7 2003-11-23 devnull if(cistrcmp(d, tab[i]) == 0)
211 9df487d7 2003-11-23 devnull return i;
212 9df487d7 2003-11-23 devnull return -1;