aboutsummaryrefslogtreecommitdiff
path: root/src/libhttpd/date.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2003-11-23 18:19:35 +0000
committerrsc <devnull@localhost>2003-11-23 18:19:35 +0000
commit9df487d720a59bf8cb0dc4ccffc30ad8eb48256a (patch)
tree9267054a81cefbb9a8ae3847ae0ddfc1567bd961 /src/libhttpd/date.c
parentb6afd33e2f23953f00c6fac6b5d45946a9113654 (diff)
downloadplan9port-9df487d720a59bf8cb0dc4ccffc30ad8eb48256a.tar.gz
plan9port-9df487d720a59bf8cb0dc4ccffc30ad8eb48256a.tar.bz2
plan9port-9df487d720a59bf8cb0dc4ccffc30ad8eb48256a.zip
add libhttpd
Diffstat (limited to 'src/libhttpd/date.c')
-rw-r--r--src/libhttpd/date.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/libhttpd/date.c b/src/libhttpd/date.c
new file mode 100644
index 00000000..450f60f7
--- /dev/null
+++ b/src/libhttpd/date.c
@@ -0,0 +1,212 @@
+#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;
+ 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;
+}