+ year = strtoul(val, &p, 10);
+ if ((*p != '-' && *p) || year < 1970 || year > 2038)
+ goto fail;
+ else if (!*p)
+ goto ret;
+
+ mon = strtoul(++p, &p, 10);
+ if ((*p != '-' && *p) || mon > 12)
+ goto fail;
+ else if (!*p)
+ goto ret;
+
+ day = strtoul(++p, &p, 10);
+ if ((*p != 'T' && *p) || day > 31)
+ goto fail;
+ else if (!*p)
+ goto ret;
+
+ hour = strtoul(++p, &p, 10);
+ if ((*p != ':' && *p) || hour > 23)
+ goto fail;
+ else if (!*p)
+ goto ret;
+
+ min = strtoul(++p, &p, 10);
+ if ((*p != ':' && *p) || min > 59)
+ goto fail;
+ else if (!*p)
+ goto ret;
+
+ sec = strtoul(++p, &p, 10);
+ if (*p || sec > 59)
+ goto fail;
+
+ret:
+ tm.tm_year = year - 1900;
+ tm.tm_mon = mon - 1;
+ tm.tm_mday = day;
+ tm.tm_hour = hour;
+ tm.tm_min = min;
+ tm.tm_sec = sec;
+
+ if (mktime(&tm) >= 0)
+ {
+ *((struct tm *)ptr) = tm;
+ return true;
+ }
+
+fail:
+ return false;
+}
+
+bool
+fw3_parse_time(void *ptr, const char *val, bool is_list)
+{
+ unsigned int hour = 0, min = 0, sec = 0;
+ char *p;
+
+ hour = strtoul(val, &p, 10);
+ if (*p != ':' || hour > 23)
+ goto fail;
+
+ min = strtoul(++p, &p, 10);
+ if ((*p != ':' && *p) || min > 59)
+ goto fail;
+ else if (!*p)
+ goto ret;
+
+ sec = strtoul(++p, &p, 10);
+ if (*p || sec > 59)
+ goto fail;
+
+ret:
+ *((int *)ptr) = 60 * 60 * hour + 60 * min + sec;
+ return true;
+
+fail:
+ return false;
+}
+
+bool
+fw3_parse_weekdays(void *ptr, const char *val, bool is_list)
+{
+ unsigned int w = 0;
+ char *p, *s;
+
+ if (*val == '!')