123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- #include <u.h>
- #include <libc.h>
- #include <httpd.h>
- /*
- * print dates in the format
- * Wkd, DD Mon YYYY HH:MM:SS GMT
- * parse dates of formats
- * Wkd, DD Mon YYYY HH:MM:SS GMT
- * Weekday, DD-Mon-YY HH:MM:SS GMT
- * Wkd Mon ( D|DD) HH:MM:SS YYYY
- * plus anything similar
- */
- static char *
- weekdayname[7] =
- {
- "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
- };
- static char *
- wdayname[7] =
- {
- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
- };
- static char *
- monname[12] =
- {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
- static int dateindex(char*, char**, int);
- static int
- dtolower(int c)
- {
- if(c >= 'A' && c <= 'Z')
- return c - 'A' + 'a';
- return c;
- }
- static int
- disalpha(int c)
- {
- return c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z';
- }
- static int
- disdig(int c)
- {
- return c >= '0' && c <= '9';
- }
- int
- hdatefmt(Fmt *f)
- {
- Tm *tm;
- ulong t;
- t = va_arg(f->args, ulong);
- tm = gmtime(t);
- return fmtprint(f, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
- wdayname[tm->wday], tm->mday, monname[tm->mon], tm->year+1900,
- tm->hour, tm->min, tm->sec);
- }
- static char*
- dateword(char *date, char *buf)
- {
- char *p;
- int c;
- p = buf;
- while(!disalpha(c = *date) && !disdig(c) && c)
- date++;
- while(disalpha(c = *date)){
- if(p - buf < 30)
- *p++ = dtolower(c);
- date++;
- }
- *p = 0;
- return date;
- }
- static int
- datenum(char **d)
- {
- char *date;
- int c, n;
- date = *d;
- while(!disdig(c = *date) && c)
- date++;
- if(c == 0){
- *d = date;
- return -1;
- }
- n = 0;
- while(disdig(c = *date)){
- n = n * 10 + c - '0';
- date++;
- }
- *d = date;
- return n;
- }
- /*
- * parse a date and return the seconds since the epoch
- * return 0 for a failure
- */
- ulong
- hdate2sec(char *date)
- {
- Tm tm;
- char buf[32];
- /*
- * Weekday|Wday
- */
- date = dateword(date, buf);
- tm.wday = dateindex(buf, wdayname, 7);
- if(tm.wday < 0)
- tm.wday = dateindex(buf, weekdayname, 7);
- if(tm.wday < 0)
- return 0;
- /*
- * check for the two major formats
- */
- date = dateword(date, buf);
- tm.mon = dateindex(buf, monname, 12);
- if(tm.mon >= 0){
- /*
- * MM
- */
- tm.mday = datenum(&date);
- if(tm.mday < 1 || tm.mday > 31)
- return 0;
- /*
- * HH:MM:SS
- */
- tm.hour = datenum(&date);
- if(tm.hour < 0 || tm.hour >= 24)
- return 0;
- tm.min = datenum(&date);
- if(tm.min < 0 || tm.min >= 60)
- return 0;
- tm.sec = datenum(&date);
- if(tm.sec < 0 || tm.sec >= 60)
- return 0;
- /*
- * YYYY
- */
- tm.year = datenum(&date);
- if(tm.year < 70 || tm.year > 99 && tm.year < 1970)
- return 0;
- if(tm.year >= 1970)
- tm.year -= 1900;
- }else{
- /*
- * MM-Mon-(YY|YYYY)
- */
- tm.mday = datenum(&date);
- if(tm.mday < 1 || tm.mday > 31)
- return 0;
- date = dateword(date, buf);
- tm.mon = dateindex(buf, monname, 12);
- if(tm.mon < 0 || tm.mon >= 12)
- return 0;
- tm.year = datenum(&date);
- if(tm.year < 70 || tm.year > 99 && tm.year < 1970)
- return 0;
- if(tm.year >= 1970)
- tm.year -= 1900;
- /*
- * HH:MM:SS
- */
- tm.hour = datenum(&date);
- if(tm.hour < 0 || tm.hour >= 24)
- return 0;
- tm.min = datenum(&date);
- if(tm.min < 0 || tm.min >= 60)
- return 0;
- tm.sec = datenum(&date);
- if(tm.sec < 0 || tm.sec >= 60)
- return 0;
- /*
- * timezone
- */
- dateword(date, buf);
- if(strncmp(buf, "gmt", 3) != 0)
- return 0;
- }
- strcpy(tm.zone, "GMT");
- tm.tzoff = 0;
- tm.yday = 0;
- return tm2sec(&tm);
- }
- static int
- dateindex(char *d, char **tab, int n)
- {
- int i;
- for(i = 0; i < n; i++)
- if(cistrcmp(d, tab[i]) == 0)
- return i;
- return -1;
- }
|