X-Git-Url: http://sjero.net/git/?a=blobdiff_plain;f=src%2Fcmpt.c;h=19b56265ff7b9f283206f94575fea44d0966769a;hb=bb8a5f2eb92c6c05b4f76904100dd5007fd421d8;hp=8168f0d5877936642d14aef4bda1c0fc4b645593;hpb=0561a866c30bb075d0196b25137d7736457e9ac4;p=wget diff --git a/src/cmpt.c b/src/cmpt.c index 8168f0d5..19b56265 100644 --- a/src/cmpt.c +++ b/src/cmpt.c @@ -1222,3 +1222,71 @@ fnmatch (const char *pattern, const char *string, int flags) } #endif /* not SYSTEM_FNMATCH */ + +#ifndef HAVE_TIMEGM +/* timegm is a GNU extension typically unavailable on non-glibc-based + platforms. */ + +/* Inverse of gmtime: converts struct tm to time_t, assuming the data + in tm is UTC rather than local timezone. + + mktime is similar but assumes struct tm, also known as the + "broken-down" form of time, is in local time zone. This + implementation of timegm uses mktime to make the conversion + understanding that an offset will be introduced by the local time + assumption. + + timegm then measures the introduced offset by applying gmtime to + the initial result and applying mktime to the resulting + "broken-down" form. The difference between the two mktime results + is the measured offset which is then subtracted from the initial + mktime result to yield a calendar time which is the value returned. + + tm_isdst in struct tm is set to 0 to force mktime to introduce a + consistent offset (the non DST offset) since tm and tm+o might be + on opposite sides of a DST change. + + Some implementations of mktime return -1 for the nonexistent + localtime hour at the beginning of DST. In this event, use + mktime(tm - 1hr) + 3600. + + Schematically + mktime(tm) --> t+o + gmtime(t+o) --> tm+o + mktime(tm+o) --> t+2o + t+o - (t+2o - t+o) = t + + Contributed by Roger Beeman , with the help of + Mark Baushke and other experts at CISCO. Further + improved by Roger with assistance from Edward J. Sabol based on + input by Jamie Zawinski. */ + +time_t +timegm (struct tm *t) +{ + time_t tl, tb; + struct tm *tg; + + tl = mktime (t); + if (tl == -1) + { + t->tm_hour--; + tl = mktime (t); + if (tl == -1) + return -1; /* can't deal with contents of T */ + tl += 3600; + } + tg = gmtime (&tl); + tg->tm_isdst = 0; + tb = mktime (tg); + if (tb == -1) + { + tg->tm_hour--; + tb = mktime (tg); + if (tb == -1) + return -1; /* can't deal with output from gmtime */ + tb += 3600; + } + return (tl - (tb - tl)); +} +#endif /* HAVE_TIMEGM */