/* Replacements for routines missing on some systems.
- Copyright (C) 1995-2005 Free Software Foundation, Inc.
+ Copyright (C) 1996-2005 Free Software Foundation, Inc.
This file is part of GNU Wget.
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with Wget; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+along with Wget; if not, write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
In addition, as a special exception, the Free Software Foundation
gives permission to link the code of its release of Wget with the
#include "wget.h"
/* Some systems lack certain functions normally taken for granted.
- For example, Windows doesn't have strptime, and some systems lack
- strcasecmp and strncasecmp. This file should contain fallback
- implementations of the missing functions. It should *not* define
+ For example, Windows doesn't have strptime, and some systems don't
+ have a usable fnmatch. This file should contain fallback
+ implementations of such missing functions. It should *not* define
new Wget-specific interfaces -- those should be placed in utils.c
or elsewhere. */
\f
and given a prefix, but many systems out there are still (as of
this writing in 2005) broken and we must cater to them.
- Additionally, according to anecdotal evidence and conventional
- wisdom I lack courage to challenge, many implementations of fnmatch
- are notoriously buggy and unreliable. So we use our version by
- default, except when compiling under systems where fnmatch is known
- to work (currently on GNU libc-based systems and Solaris.) */
+ Additionally, according to some conventional, many historical
+ implementations of fnmatch are buggy and unreliable. If yours is
+ such, undefine SYSTEM_FNMATCH in sysdep.h and tell us about it. */
#ifndef SYSTEM_FNMATCH
}
#endif /* not SYSTEM_FNMATCH */
+\f
+#ifndef HAVE_TIMEGM
+/* timegm is a GNU extension, but lately also available on *BSD and
+ possibly elsewhere. */
+
+/* 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.
+
+ It 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 */