commit a228cdba0ed434a6b8418abace9684f9c58323f2
parent 39afa6c25b9a51f07f06384c5155d791e9bbb6ff
Author: Joris Vink <joris@coders.se>
Date:   Wed,  1 May 2013 20:10:45 +0200
introduce kore_split_string() to properly split strings apart.
introduce kore_date_to_time() to conver http-date formatted strings to time_t.
Diffstat:
6 files changed, 122 insertions(+), 8 deletions(-)
diff --git a/includes/http.h b/includes/http.h
@@ -30,6 +30,7 @@ struct http_request {
 
 void		http_init(void);
 void		http_process(void);
+time_t		http_date_to_time(char *);
 void		http_request_free(struct http_request *);
 int		http_response(struct http_request *, int,
 		    u_int8_t *, u_int32_t, char *);
diff --git a/includes/kore.h b/includes/kore.h
@@ -95,10 +95,12 @@ extern char	*server_ip;
 void		*kore_malloc(size_t);
 void		*kore_calloc(size_t, size_t);
 void		*kore_realloc(void *, size_t);
+time_t		kore_date_to_time(char *);
 char		*kore_strdup(const char *);
 void		kore_parse_config(const char *);
 void		kore_strlcpy(char *, const char *, size_t);
 void		kore_server_disconnect(struct connection *);
+int		kore_split_string(char *, char *, char **, size_t);
 long long	kore_strtonum(const char *, long long, long long, int *);
 
 void		kore_module_load(char *);
diff --git a/src/config.c b/src/config.c
@@ -57,7 +57,7 @@ kore_parse_config(const char *config_path)
 {
 	FILE		*fp;
 	int		i, lineno;
-	char		buf[BUFSIZ], *p, *t, **ap, *argv[5];
+	char		buf[BUFSIZ], *p, *t, *argv[5];
 
 	if ((fp = fopen(config_path, "r")) == NULL)
 		fatal("configuration given cannot be opened: %s", config_path);
@@ -79,13 +79,7 @@ kore_parse_config(const char *config_path)
 				*t = ' ';
 		}
 
-		for (ap = argv; ap < &argv[4] &&
-		    (*ap = strsep(&p, " ")) != NULL;) {
-			if (**ap != '\0')
-				ap++;
-		}
-		*ap = NULL;
-
+		kore_split_string(p, " ", argv, 5);
 		for (i = 0; config_names[i].name != NULL; i++) {
 			if (!strcmp(config_names[i].name, argv[0])) {
 				if (!config_names[i].configure(argv)) {
diff --git a/src/http.c b/src/http.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <zlib.h>
 
 #include "spdy.h"
diff --git a/src/kore.c b/src/kore.c
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <time.h>
 #include <zlib.h>
 
 #include "spdy.h"
diff --git a/src/utils.c b/src/utils.c
@@ -36,6 +36,25 @@
 #include "spdy.h"
 #include "kore.h"
 
+static struct {
+	char		*name;
+	int		value;
+} month_names[] = {
+	{ "Jan",	0 },
+	{ "Feb",	1 },
+	{ "Mar",	2 },
+	{ "Apr",	3 },
+	{ "May",	4 },
+	{ "Jun",	5 },
+	{ "Jul",	6 },
+	{ "Aug",	7 },
+	{ "Sep",	8 },
+	{ "Oct",	9 },
+	{ "Nov",	10 },
+	{ "Dec",	11 },
+	{ NULL,		0 },
+};
+
 void *
 kore_malloc(size_t len)
 {
@@ -140,6 +159,102 @@ kore_strtonum(const char *str, long long min, long long max, int *err)
 	return (l);
 }
 
+int
+kore_split_string(char *input, char *delim, char **out, size_t ele)
+{
+	int		count;
+	char		**ap;
+
+	count = 0;
+	for (ap = out; ap < &out[ele - 1] &&
+	    (*ap = strsep(&input, delim)) != NULL;) {
+		if (**ap != '\0') {
+			ap++;
+			count++;
+		}
+	}
+
+	*ap = NULL;
+	return (count);
+}
+
+time_t
+kore_date_to_time(char *http_date)
+{
+	time_t			t;
+	int			err, i;
+	struct tm		tm, *gtm;
+	char			*args[7], *tbuf[5], *sdup;
+
+	time(&t);
+	gtm = gmtime(&t);
+	sdup = kore_strdup(http_date);
+
+	t = KORE_RESULT_ERROR;
+
+	if (kore_split_string(sdup, " ", args, 7) != 6) {
+		kore_log("misformed http-date: '%s'", http_date);
+		goto out;
+	}
+
+	tm.tm_year = kore_strtonum(args[3], 2013, 2068, &err) - 1900;
+	if (err == KORE_RESULT_ERROR || tm.tm_year < gtm->tm_year) {
+		kore_log("misformed year in http-date: '%s'", http_date);
+		goto out;
+	}
+
+	for (i = 0; month_names[i].name != NULL; i++) {
+		if (!strcmp(month_names[i].name, args[2])) {
+			tm.tm_mon = month_names[i].value;
+			break;
+		}
+	}
+
+	if (month_names[i].name == NULL) {
+		kore_log("misformed month in http-date: '%s'", http_date);
+		goto out;
+	}
+
+	tm.tm_mday = kore_strtonum(args[1], 1, 31, &err);
+	if (err == KORE_RESULT_ERROR) {
+		kore_log("misformed mday in http-date: '%s'", http_date);
+		goto out;
+	}
+
+	if (kore_split_string(args[4], ":", tbuf, 5) != 3) {
+		kore_log("misformed HH:MM:SS in http-date: '%s'", http_date);
+		goto out;
+	}
+
+	tm.tm_hour = kore_strtonum(tbuf[0], 1, 23, &err);
+	if (err == KORE_RESULT_ERROR) {
+		kore_log("misformed hour in http-date: '%s'", http_date);
+		goto out;
+	}
+
+	tm.tm_min = kore_strtonum(tbuf[1], 1, 59, &err);
+	if (err == KORE_RESULT_ERROR) {
+		kore_log("misformed minutes in http-date: '%s'", http_date);
+		goto out;
+	}
+
+	tm.tm_sec = kore_strtonum(tbuf[2], 0, 60, &err);
+	if (err == KORE_RESULT_ERROR) {
+		kore_log("misformed seconds in http-date: '%s'", http_date);
+		goto out;
+	}
+
+	t = mktime(&tm);
+	if (t == -1) {
+		t = 0;
+		kore_log("mktime() on '%s' failed", http_date);
+	}
+
+out:
+	free(sdup);
+	return (t);
+}
+
 void
 fatal(const char *fmt, ...)
 {