Commit 0a24389d authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Be much more explicit about the string->time conversion disaster

visited upon us by the brilliant minds behind POSIX.

Parts from:	Solaris patch from Theo Schlossnagle



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@3077 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent a6f9909b
......@@ -429,7 +429,13 @@ main(int argc, char * const *argv)
setbuf(stdout, NULL);
setbuf(stderr, NULL);
AZ(setenv("TZ", "GMT", 1));
/*
* Run in UTC timezone, on the off-chance that this operating
* system does not have a timegm() function, and translates
* timestamps on the local timescale.
* See lib/libvarnish/time.c
*/
AZ(setenv("TZ", "UTC", 1));
tzset();
memset(cli, 0, sizeof cli);
......
......@@ -101,6 +101,7 @@ AC_CHECK_FUNCS([strptime])
AC_CHECK_FUNCS([fmtcheck])
AC_CHECK_FUNCS([getdtablesize])
AC_CHECK_FUNCS([abort2])
AC_CHECK_FUNCS([timegm])
save_LIBS="${LIBS}"
LIBS="${PTHREAD_LIBS}"
......
......@@ -112,18 +112,70 @@ static const char *fmts[] = {
time_t
TIM_parse(const char *p)
{
time_t t;
struct tm tm;
const char **r;
for (r = fmts; *r != NULL; r++) {
memset(&tm, 0, sizeof tm);
if (strptime(p, *r, &tm) != NULL)
return (mktime(&tm));
if (strptime(p, *r, &tm) != NULL) {
/*
* Make sure this is initialized on the off-chance
* that some raving loonie would apply DST to UTC.
*/
tm.tm_isdst = -1;
#if defined(HAVE_TIMEGM)
t = timegm(&tm);
#else
/*
* Ahh, another POSIX_STUPIDITY, how unexpected.
* Instead of, as would have been logical, to have
* tm_timezone element, mktime() is standardized as
* always working in localtime. This brilliant idea
* came from the same people who said "leap-seconds ?
* Naah, screw it!".
*
* On broken systems without a working timegm(),
* it is the responsibility of the calling program
* to set the timezone to UTC. We check that.
*/
t = mktime(&tm);
assert(!strcmp(tzname[0], "UTC"));
#endif
return (t);
}
}
return (0);
}
#ifdef TEST_DRIVER
#include <stdlib.h>
/*
* Compile with:
* cc -o foo -DTEST_DRIVER -I../.. -I../../include time.c assert.c
* Test with:
* env TZ=UTC ./foo
* env TZ=CET ./foo
*/
static void
tst(const char *s, time_t good)
{
time_t t;
char buf[BUFSIZ];
t = TIM_parse(s);
TIM_format(t, buf);
printf("%-30s -> %12jd -> %s\n", s, (intmax_t)t, buf);
if (t != good) {
printf("Parse error! Got: %jd should have %jd diff %jd\n",
(intmax_t)t, (intmax_t)good, (intmax_t)(t - good));
exit (2);
}
}
int
main(int argc, char **argv)
{
......@@ -136,9 +188,9 @@ main(int argc, char **argv)
printf("scan = %d <%s>\n", TIM_parse(buf), buf);
/* Examples from RFC2616 section 3.3.1 */
printf("scan = %d\n", TIM_parse("Sun, 06 Nov 1994 08:49:37 GMT"));
printf("scan = %d\n", TIM_parse("Sunday, 06-Nov-94 08:49:37 GMT"));
printf("scan = %d\n", TIM_parse("Sun Nov 6 08:49:37 1994"));
tst("Sun, 06 Nov 1994 08:49:37 GMT", 784111777);
tst("Sunday, 06-Nov-94 08:49:37 GMT", 784111777);
tst("Sun Nov 6 08:49:37 1994", 784111777);
return (0);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment