Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <httpd.h>
4
 
5
/*
6
 * print dates in the format
7
 * Wkd, DD Mon YYYY HH:MM:SS GMT
8
 * parse dates of formats
9
 * Wkd, DD Mon YYYY HH:MM:SS GMT
10
 * Weekday, DD-Mon-YY HH:MM:SS GMT
11
 * Wkd Mon ( D|DD) HH:MM:SS YYYY
12
 * plus anything similar
13
 */
14
static char *
15
weekdayname[7] =
16
{
17
	"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
18
};
19
static char *
20
wdayname[7] =
21
{
22
	"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
23
};
24
 
25
static char *
26
monname[12] =
27
{
28
	"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
29
};
30
 
31
static	int	dateindex(char*, char**, int);
32
 
33
static int
34
dtolower(int c)
35
{
36
	if(c >= 'A' && c <= 'Z')
37
		return c - 'A' + 'a';
38
	return c;
39
}
40
 
41
static int
42
disalpha(int c)
43
{
44
	return c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';
45
}
46
 
47
static int
48
disdig(int c)
49
{
50
	return c >= '0' && c <= '9';
51
}
52
 
53
int
54
hdatefmt(Fmt *f)
55
{
56
	Tm *tm;
57
	ulong t;
58
 
59
	t = va_arg(f->args, ulong);
60
	tm = gmtime(t);
61
	return fmtprint(f, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
62
		wdayname[tm->wday], tm->mday, monname[tm->mon], tm->year+1900,
63
		tm->hour, tm->min, tm->sec);
64
}
65
 
66
static char*
67
dateword(char *date, char *buf)
68
{
69
	char *p;
70
	int c;
71
 
72
	p = buf;
73
	while(!disalpha(c = *date) && !disdig(c) && c)
74
		date++;
75
	while(disalpha(c = *date)){
76
		if(p - buf < 30)
77
			*p++ = dtolower(c);
78
		date++;
79
	}
80
	*p = 0;
81
	return date;
82
}
83
 
84
static int
85
datenum(char **d)
86
{
87
	char *date;
88
	int c, n;
89
 
90
	date = *d;
91
	while(!disdig(c = *date) && c)
92
		date++;
93
	if(c == 0){
94
		*d = date;
95
		return -1;
96
	}
97
	n = 0;
98
	while(disdig(c = *date)){
99
		n = n * 10 + c - '0';
100
		date++;
101
	}
102
	*d = date;
103
	return n;
104
}
105
 
106
/*
107
 * parse a date and return the seconds since the epoch
108
 * return 0 for a failure
109
 */
110
ulong
111
hdate2sec(char *date)
112
{
113
	Tm tm;
114
	char buf[32];
115
 
116
	/*
117
	 * Weekday|Wday
118
	 */
119
	date = dateword(date, buf);
120
	tm.wday = dateindex(buf, wdayname, 7);
121
	if(tm.wday < 0)
122
		tm.wday = dateindex(buf, weekdayname, 7);
123
	if(tm.wday < 0)
124
		return 0;
125
 
126
	/*
127
	 * check for the two major formats
128
	 */
129
	date = dateword(date, buf);
130
	tm.mon = dateindex(buf, monname, 12);
131
	if(tm.mon >= 0){
132
		/*
133
		 * MM
134
		 */
135
		tm.mday = datenum(&date);
136
		if(tm.mday < 1 || tm.mday > 31)
137
			return 0;
138
 
139
		/*
140
		 * HH:MM:SS
141
		 */
142
		tm.hour = datenum(&date);
143
		if(tm.hour < 0 || tm.hour >= 24)
144
			return 0;
145
		tm.min = datenum(&date);
146
		if(tm.min < 0 || tm.min >= 60)
147
			return 0;
148
		tm.sec = datenum(&date);
149
		if(tm.sec < 0 || tm.sec >= 60)
150
			return 0;
151
 
152
		/*
153
		 * YYYY
154
		 */
155
		tm.year = datenum(&date);
156
		if(tm.year < 70 || tm.year > 99 && tm.year < 1970)
157
			return 0;
158
		if(tm.year >= 1970)
159
			tm.year -= 1900;
160
	}else{
161
		/*
162
		 * MM-Mon-(YY|YYYY)
163
		 */
164
		tm.mday = datenum(&date);
165
		if(tm.mday < 1 || tm.mday > 31)
166
			return 0;
167
		date = dateword(date, buf);
168
		tm.mon = dateindex(buf, monname, 12);
169
		if(tm.mon < 0 || tm.mon >= 12)
170
			return 0;
171
		tm.year = datenum(&date);
172
		if(tm.year < 70 || tm.year > 99 && tm.year < 1970)
173
			return 0;
174
		if(tm.year >= 1970)
175
			tm.year -= 1900;
176
 
177
		/*
178
		 * HH:MM:SS
179
		 */
180
		tm.hour = datenum(&date);
181
		if(tm.hour < 0 || tm.hour >= 24)
182
			return 0;
183
		tm.min = datenum(&date);
184
		if(tm.min < 0 || tm.min >= 60)
185
			return 0;
186
		tm.sec = datenum(&date);
187
		if(tm.sec < 0 || tm.sec >= 60)
188
			return 0;
189
 
190
		/*
191
		 * timezone
192
		 */
193
		dateword(date, buf);
194
		if(strncmp(buf, "gmt", 3) != 0)
195
			return 0;
196
	}
197
 
198
	strcpy(tm.zone, "GMT");
199
	tm.tzoff = 0;
200
	tm.yday = 0;
201
	return tm2sec(&tm);
202
}
203
 
204
static int
205
dateindex(char *d, char **tab, int n)
206
{
207
	int i;
208
 
209
	for(i = 0; i < n; i++)
210
		if(cistrcmp(d, tab[i]) == 0)
211
			return i;
212
	return -1;
213
}