180ee5cbfSDavid du Colombier #include <u.h>
280ee5cbfSDavid du Colombier #include <libc.h>
380ee5cbfSDavid du Colombier #include <httpd.h>
480ee5cbfSDavid du Colombier
580ee5cbfSDavid du Colombier /*
680ee5cbfSDavid du Colombier * print dates in the format
780ee5cbfSDavid du Colombier * Wkd, DD Mon YYYY HH:MM:SS GMT
880ee5cbfSDavid du Colombier * parse dates of formats
980ee5cbfSDavid du Colombier * Wkd, DD Mon YYYY HH:MM:SS GMT
1080ee5cbfSDavid du Colombier * Weekday, DD-Mon-YY HH:MM:SS GMT
1180ee5cbfSDavid du Colombier * Wkd Mon ( D|DD) HH:MM:SS YYYY
1280ee5cbfSDavid du Colombier * plus anything similar
1380ee5cbfSDavid du Colombier */
1480ee5cbfSDavid du Colombier static char *
1580ee5cbfSDavid du Colombier weekdayname[7] =
1680ee5cbfSDavid du Colombier {
1780ee5cbfSDavid du Colombier "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
1880ee5cbfSDavid du Colombier };
1980ee5cbfSDavid du Colombier static char *
2080ee5cbfSDavid du Colombier wdayname[7] =
2180ee5cbfSDavid du Colombier {
2280ee5cbfSDavid du Colombier "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
2380ee5cbfSDavid du Colombier };
2480ee5cbfSDavid du Colombier
2580ee5cbfSDavid du Colombier static char *
2680ee5cbfSDavid du Colombier monname[12] =
2780ee5cbfSDavid du Colombier {
2880ee5cbfSDavid du Colombier "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
2980ee5cbfSDavid du Colombier };
3080ee5cbfSDavid du Colombier
3180ee5cbfSDavid du Colombier static int dateindex(char*, char**, int);
3280ee5cbfSDavid du Colombier
3380ee5cbfSDavid du Colombier static int
dtolower(int c)3480ee5cbfSDavid du Colombier dtolower(int c)
3580ee5cbfSDavid du Colombier {
3680ee5cbfSDavid du Colombier if(c >= 'A' && c <= 'Z')
3780ee5cbfSDavid du Colombier return c - 'A' + 'a';
3880ee5cbfSDavid du Colombier return c;
3980ee5cbfSDavid du Colombier }
4080ee5cbfSDavid du Colombier
4180ee5cbfSDavid du Colombier static int
disalpha(int c)4280ee5cbfSDavid du Colombier disalpha(int c)
4380ee5cbfSDavid du Colombier {
4480ee5cbfSDavid du Colombier return c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';
4580ee5cbfSDavid du Colombier }
4680ee5cbfSDavid du Colombier
4780ee5cbfSDavid du Colombier static int
disdig(int c)4880ee5cbfSDavid du Colombier disdig(int c)
4980ee5cbfSDavid du Colombier {
5080ee5cbfSDavid du Colombier return c >= '0' && c <= '9';
5180ee5cbfSDavid du Colombier }
5280ee5cbfSDavid du Colombier
5380ee5cbfSDavid du Colombier int
hdatefmt(Fmt * f)549a747e4fSDavid du Colombier hdatefmt(Fmt *f)
5580ee5cbfSDavid du Colombier {
5680ee5cbfSDavid du Colombier Tm *tm;
5780ee5cbfSDavid du Colombier ulong t;
5880ee5cbfSDavid du Colombier
599a747e4fSDavid du Colombier t = va_arg(f->args, ulong);
6080ee5cbfSDavid du Colombier tm = gmtime(t);
619a747e4fSDavid du Colombier return fmtprint(f, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
6280ee5cbfSDavid du Colombier wdayname[tm->wday], tm->mday, monname[tm->mon], tm->year+1900,
6380ee5cbfSDavid du Colombier tm->hour, tm->min, tm->sec);
6480ee5cbfSDavid du Colombier }
6580ee5cbfSDavid du Colombier
6680ee5cbfSDavid du Colombier static char*
dateword(char * date,char * buf)6780ee5cbfSDavid du Colombier dateword(char *date, char *buf)
6880ee5cbfSDavid du Colombier {
6980ee5cbfSDavid du Colombier char *p;
7080ee5cbfSDavid du Colombier int c;
7180ee5cbfSDavid du Colombier
7280ee5cbfSDavid du Colombier p = buf;
7380ee5cbfSDavid du Colombier while(!disalpha(c = *date) && !disdig(c) && c)
7480ee5cbfSDavid du Colombier date++;
7580ee5cbfSDavid du Colombier while(disalpha(c = *date)){
7680ee5cbfSDavid du Colombier if(p - buf < 30)
7780ee5cbfSDavid du Colombier *p++ = dtolower(c);
7880ee5cbfSDavid du Colombier date++;
7980ee5cbfSDavid du Colombier }
8080ee5cbfSDavid du Colombier *p = 0;
8180ee5cbfSDavid du Colombier return date;
8280ee5cbfSDavid du Colombier }
8380ee5cbfSDavid du Colombier
8480ee5cbfSDavid du Colombier static int
datenum(char ** d)8580ee5cbfSDavid du Colombier datenum(char **d)
8680ee5cbfSDavid du Colombier {
8780ee5cbfSDavid du Colombier char *date;
8880ee5cbfSDavid du Colombier int c, n;
8980ee5cbfSDavid du Colombier
9080ee5cbfSDavid du Colombier date = *d;
9180ee5cbfSDavid du Colombier while(!disdig(c = *date) && c)
9280ee5cbfSDavid du Colombier date++;
9380ee5cbfSDavid du Colombier if(c == 0){
9480ee5cbfSDavid du Colombier *d = date;
9580ee5cbfSDavid du Colombier return -1;
9680ee5cbfSDavid du Colombier }
9780ee5cbfSDavid du Colombier n = 0;
9880ee5cbfSDavid du Colombier while(disdig(c = *date)){
9980ee5cbfSDavid du Colombier n = n * 10 + c - '0';
10080ee5cbfSDavid du Colombier date++;
10180ee5cbfSDavid du Colombier }
10280ee5cbfSDavid du Colombier *d = date;
10380ee5cbfSDavid du Colombier return n;
10480ee5cbfSDavid du Colombier }
10580ee5cbfSDavid du Colombier
10680ee5cbfSDavid du Colombier /*
10780ee5cbfSDavid du Colombier * parse a date and return the seconds since the epoch
10880ee5cbfSDavid du Colombier * return 0 for a failure
10980ee5cbfSDavid du Colombier */
11080ee5cbfSDavid du Colombier ulong
hdate2sec(char * date)11180ee5cbfSDavid du Colombier hdate2sec(char *date)
11280ee5cbfSDavid du Colombier {
11380ee5cbfSDavid du Colombier Tm tm;
11480ee5cbfSDavid du Colombier char buf[32];
11580ee5cbfSDavid du Colombier
11680ee5cbfSDavid du Colombier /*
11780ee5cbfSDavid du Colombier * Weekday|Wday
11880ee5cbfSDavid du Colombier */
11980ee5cbfSDavid du Colombier date = dateword(date, buf);
12080ee5cbfSDavid du Colombier tm.wday = dateindex(buf, wdayname, 7);
12180ee5cbfSDavid du Colombier if(tm.wday < 0)
12280ee5cbfSDavid du Colombier tm.wday = dateindex(buf, weekdayname, 7);
12380ee5cbfSDavid du Colombier if(tm.wday < 0)
12480ee5cbfSDavid du Colombier return 0;
12580ee5cbfSDavid du Colombier
12680ee5cbfSDavid du Colombier /*
12780ee5cbfSDavid du Colombier * check for the two major formats
12880ee5cbfSDavid du Colombier */
12980ee5cbfSDavid du Colombier date = dateword(date, buf);
13080ee5cbfSDavid du Colombier tm.mon = dateindex(buf, monname, 12);
13180ee5cbfSDavid du Colombier if(tm.mon >= 0){
13280ee5cbfSDavid du Colombier /*
13380ee5cbfSDavid du Colombier * MM
13480ee5cbfSDavid du Colombier */
13580ee5cbfSDavid du Colombier tm.mday = datenum(&date);
13680ee5cbfSDavid du Colombier if(tm.mday < 1 || tm.mday > 31)
13780ee5cbfSDavid du Colombier return 0;
13880ee5cbfSDavid du Colombier
13980ee5cbfSDavid du Colombier /*
14080ee5cbfSDavid du Colombier * HH:MM:SS
14180ee5cbfSDavid du Colombier */
14280ee5cbfSDavid du Colombier tm.hour = datenum(&date);
14380ee5cbfSDavid du Colombier if(tm.hour < 0 || tm.hour >= 24)
14480ee5cbfSDavid du Colombier return 0;
14580ee5cbfSDavid du Colombier tm.min = datenum(&date);
14680ee5cbfSDavid du Colombier if(tm.min < 0 || tm.min >= 60)
14780ee5cbfSDavid du Colombier return 0;
14880ee5cbfSDavid du Colombier tm.sec = datenum(&date);
14980ee5cbfSDavid du Colombier if(tm.sec < 0 || tm.sec >= 60)
15080ee5cbfSDavid du Colombier return 0;
15180ee5cbfSDavid du Colombier
15280ee5cbfSDavid du Colombier /*
15380ee5cbfSDavid du Colombier * YYYY
15480ee5cbfSDavid du Colombier */
15580ee5cbfSDavid du Colombier tm.year = datenum(&date);
15680ee5cbfSDavid du Colombier if(tm.year < 70 || tm.year > 99 && tm.year < 1970)
15780ee5cbfSDavid du Colombier return 0;
15880ee5cbfSDavid du Colombier if(tm.year >= 1970)
15980ee5cbfSDavid du Colombier tm.year -= 1900;
16080ee5cbfSDavid du Colombier }else{
16180ee5cbfSDavid du Colombier /*
16280ee5cbfSDavid du Colombier * MM-Mon-(YY|YYYY)
16380ee5cbfSDavid du Colombier */
16480ee5cbfSDavid du Colombier tm.mday = datenum(&date);
16580ee5cbfSDavid du Colombier if(tm.mday < 1 || tm.mday > 31)
16680ee5cbfSDavid du Colombier return 0;
16780ee5cbfSDavid du Colombier date = dateword(date, buf);
16880ee5cbfSDavid du Colombier tm.mon = dateindex(buf, monname, 12);
16980ee5cbfSDavid du Colombier if(tm.mon < 0 || tm.mon >= 12)
17080ee5cbfSDavid du Colombier return 0;
17180ee5cbfSDavid du Colombier tm.year = datenum(&date);
17280ee5cbfSDavid du Colombier if(tm.year < 70 || tm.year > 99 && tm.year < 1970)
17380ee5cbfSDavid du Colombier return 0;
17480ee5cbfSDavid du Colombier if(tm.year >= 1970)
17580ee5cbfSDavid du Colombier tm.year -= 1900;
17680ee5cbfSDavid du Colombier
17780ee5cbfSDavid du Colombier /*
17880ee5cbfSDavid du Colombier * HH:MM:SS
17980ee5cbfSDavid du Colombier */
18080ee5cbfSDavid du Colombier tm.hour = datenum(&date);
18180ee5cbfSDavid du Colombier if(tm.hour < 0 || tm.hour >= 24)
18280ee5cbfSDavid du Colombier return 0;
18380ee5cbfSDavid du Colombier tm.min = datenum(&date);
18480ee5cbfSDavid du Colombier if(tm.min < 0 || tm.min >= 60)
18580ee5cbfSDavid du Colombier return 0;
18680ee5cbfSDavid du Colombier tm.sec = datenum(&date);
18780ee5cbfSDavid du Colombier if(tm.sec < 0 || tm.sec >= 60)
18880ee5cbfSDavid du Colombier return 0;
18980ee5cbfSDavid du Colombier
19080ee5cbfSDavid du Colombier /*
19180ee5cbfSDavid du Colombier * timezone
19280ee5cbfSDavid du Colombier */
19380ee5cbfSDavid du Colombier dateword(date, buf);
19480ee5cbfSDavid du Colombier if(strncmp(buf, "gmt", 3) != 0)
19580ee5cbfSDavid du Colombier return 0;
19680ee5cbfSDavid du Colombier }
19780ee5cbfSDavid du Colombier
19880ee5cbfSDavid du Colombier strcpy(tm.zone, "GMT");
19980ee5cbfSDavid du Colombier tm.tzoff = 0;
200*6b6b9ac8SDavid du Colombier tm.yday = 0;
20180ee5cbfSDavid du Colombier return tm2sec(&tm);
20280ee5cbfSDavid du Colombier }
20380ee5cbfSDavid du Colombier
20480ee5cbfSDavid du Colombier static int
dateindex(char * d,char ** tab,int n)20580ee5cbfSDavid du Colombier dateindex(char *d, char **tab, int n)
20680ee5cbfSDavid du Colombier {
20780ee5cbfSDavid du Colombier int i;
20880ee5cbfSDavid du Colombier
20980ee5cbfSDavid du Colombier for(i = 0; i < n; i++)
21080ee5cbfSDavid du Colombier if(cistrcmp(d, tab[i]) == 0)
21180ee5cbfSDavid du Colombier return i;
21280ee5cbfSDavid du Colombier return -1;
21380ee5cbfSDavid du Colombier }
214