+
+#ifdef NEED_MON_YDAY
+const unsigned short int __mon_yday[2][13] =
+ {
+ /* Normal years. */
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+ /* Leap years. */
+ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+ };
+#endif
+\f
+/* fnmatch is required by POSIX, but we include an implementation for
+ the sake of systems that don't have it, most notably Windows. Some
+ systems do have fnmatch, but Apache's installation process installs
+ its own fnmatch.h (incompatible with the system one!) in a system
+ include directory, effectively rendering fnmatch unusable. This
+ has been fixed with Apache 2, where fnmatch has been moved to apr
+ 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 some conventional wisdom, 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
+
+#define __FNM_FLAGS (FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD)
+
+/* Match STRING against the filename pattern PATTERN, returning zero
+ if it matches, FNM_NOMATCH if not. This implementation comes from
+ an earlier version of GNU Bash. (It doesn't make sense to update
+ it with a newer version because those versions add a lot of
+ features Wget doesn't use or care about.) */
+
+int
+fnmatch (const char *pattern, const char *string, int flags)
+{
+ register const char *p = pattern, *n = string;
+ register char c;
+
+ if ((flags & ~__FNM_FLAGS) != 0)
+ {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ while ((c = *p++) != '\0')
+ {
+ switch (c)
+ {
+ case '?':
+ if (*n == '\0')
+ return (FNM_NOMATCH);
+ else if ((flags & FNM_PATHNAME) && *n == '/')
+ return (FNM_NOMATCH);
+ else if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
+ return (FNM_NOMATCH);
+ break;
+
+ case '\\':
+ if (!(flags & FNM_NOESCAPE))
+ c = *p++;
+ if (*n != c)
+ return (FNM_NOMATCH);
+ break;
+
+ case '*':
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
+ return (FNM_NOMATCH);
+
+ for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
+ if (((flags & FNM_PATHNAME) && *n == '/') ||
+ (c == '?' && *n == '\0'))
+ return (FNM_NOMATCH);
+
+ if (c == '\0')
+ return (0);
+
+ {
+ char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
+ for (--p; *n != '\0'; ++n)
+ if ((c == '[' || *n == c1) &&
+ fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
+ return (0);
+ return (FNM_NOMATCH);
+ }
+
+ case '[':
+ {
+ /* Nonzero if the sense of the character class is
+ inverted. */
+ register int not;
+
+ if (*n == '\0')
+ return (FNM_NOMATCH);
+
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
+ return (FNM_NOMATCH);
+
+ /* Make sure there is a closing `]'. If there isn't,
+ the `[' is just a character to be matched. */
+ {
+ register const char *np;
+
+ for (np = p; np && *np && *np != ']'; np++)
+ ;
+
+ if (np && !*np)
+ {
+ if (*n != '[')
+ return (FNM_NOMATCH);
+ goto next_char;
+ }
+ }
+
+ not = (*p == '!' || *p == '^');
+ if (not)
+ ++p;
+
+ c = *p++;
+ while (1)
+ {
+ register char cstart = c, cend = c;
+
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ cstart = cend = *p++;
+
+ if (c == '\0')
+ /* [ (unterminated) loses. */
+ return (FNM_NOMATCH);
+
+ c = *p++;
+
+ if ((flags & FNM_PATHNAME) && c == '/')
+ /* [/] can never match. */
+ return (FNM_NOMATCH);
+
+ if (c == '-' && *p != ']')
+ {
+ cend = *p++;
+ if (!(flags & FNM_NOESCAPE) && cend == '\\')
+ cend = *p++;
+ if (cend == '\0')
+ return (FNM_NOMATCH);
+ c = *p++;
+ }
+
+ if (*n >= cstart && *n <= cend)
+ goto matched;
+
+ if (c == ']')
+ break;
+ }
+ if (!not)
+ return (FNM_NOMATCH);
+
+ next_char:
+ break;
+
+ matched:
+ /* Skip the rest of the [...] that already matched. */
+ while (c != ']')
+ {
+ if (c == '\0')
+ /* [... (unterminated) loses. */
+ return (FNM_NOMATCH);
+
+ c = *p++;
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ /* 1003.2d11 is unclear if this is right. %%% */
+ ++p;
+ }
+ if (not)
+ return (FNM_NOMATCH);
+ }
+ break;
+
+ default:
+ if (c != *n)
+ return (FNM_NOMATCH);
+ }
+
+ ++n;
+ }
+
+ if (*n == '\0')
+ return (0);
+
+ return (FNM_NOMATCH);
+}
+
+#endif /* not SYSTEM_FNMATCH */
+\f
+#ifndef HAVE_TIMEGM
+/* timegm is a GNU extension, but lately also available on *BSD
+ systems and possibly elsewhere. */
+
+/* True if YEAR is a leap year. */
+#define ISLEAP(year) \
+ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+
+/* Number of leap years in the range [y1, y2). */
+#define LEAPYEARS(y1, y2) \
+ ((y2-1)/4 - (y1-1)/4) - ((y2-1)/100 - (y1-1)/100) + ((y2-1)/400 - (y1-1)/400)
+
+/* Inverse of gmtime: converts struct tm to time_t, assuming the data
+ in tm is UTC rather than local timezone. This implementation
+ returns the number of seconds elapsed since midnight 1970-01-01,
+ converted to time_t. */
+
+time_t
+timegm (struct tm *t)
+{
+ static const unsigned short int month_to_days[][13] = {
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, /* normal */
+ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 } /* leap */
+ };
+ const int year = 1900 + t->tm_year;
+ unsigned long secs; /* until 2106-02-07 for 32-bit unsigned long */
+ int days;
+
+ if (year < 1970)
+ return (time_t) -1;
+
+ days = 365 * (year - 1970);
+ /* Take into account leap years between 1970 and YEAR, not counting
+ YEAR itself. */
+ days += LEAPYEARS (1970, year);
+ if (t->tm_mon < 0 || t->tm_mon >= 12)
+ return (time_t) -1;
+ days += month_to_days[ISLEAP (year)][t->tm_mon];
+ days += t->tm_mday - 1;
+
+ secs = days * 86400 + t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec;
+ return (time_t) secs;
+}
+#endif /* HAVE_TIMEGM */
+
+#ifdef NEED_STRTOLL
+/* strtoll is required by C99 and used by Wget only on systems with
+ LFS. Unfortunately, some systems have LFS, but no strtoll or
+ equivalent. These include HPUX 11.0 and Windows.
+
+ We use #ifdef NEED_STRTOLL instead of #ifndef HAVE_STRTOLL because
+ of the systems which have a suitable replacement (e.g. _strtoi64 on
+ Windows), on which Wget's str_to_wgint is instructed to use that
+ instead. */
+
+static inline int
+char_value (char c, int base)
+{
+ int value;
+ if (c < '0')
+ return -1;
+ if ('0' <= c && c <= '9')
+ value = c - '0';
+ else if ('a' <= c && c <= 'z')
+ value = c - 'a' + 10;
+ else if ('A' <= c && c <= 'Z')
+ value = c - 'A' + 10;
+ else
+ return -1;
+ if (value >= base)
+ return -1;
+ return value;
+}
+
+#define STRTOLL_MAX TYPE_MAXIMUM (strtoll_type)
+/* This definition assumes two's complement arithmetic */
+#define STRTOLL_MIN (-STRTOLL_MAX - 1)
+
+/* Like a%b, but always returns a positive number when A is negative.
+ (C doesn't guarantee the sign of the result.) */
+#define MOD(a, b) ((strtoll_type) -1 % 2 == 1 ? (a) % (b) : - ((a) % (b)))
+
+/* A strtoll-like replacement for systems that have an integral type
+ larger than long but don't supply strtoll. This implementation
+ makes no assumptions about the size of strtoll_type. */
+
+strtoll_type
+strtoll (const char *nptr, char **endptr, int base)
+{
+ strtoll_type result = 0;
+ bool negative;
+
+ if (base != 0 && (base < 2 || base > 36))
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ while (*nptr == ' ' || *nptr == '\t')
+ ++nptr;
+ if (*nptr == '-')
+ {
+ negative = true;
+ ++nptr;
+ }
+ else if (*nptr == '+')
+ {
+ negative = false;
+ ++nptr;
+ }
+ else
+ negative = false;
+
+ /* If BASE is 0, determine the real base based on the beginning on
+ the number; octal numbers begin with "0", hexadecimal with "0x",
+ and the others are considered octal. */
+ if (*nptr == '0')
+ {
+ if ((base == 0 || base == 16)
+ &&
+ (*(nptr + 1) == 'x' || *(nptr + 1) == 'X'))
+ {
+ base = 16;
+ nptr += 2;
+ /* "0x" must be followed by at least one hex char. If not,
+ return 0 and place ENDPTR on 'x'. */
+ if (!c_isxdigit (*nptr))
+ {
+ --nptr;
+ goto out;
+ }
+ }
+ else if (base == 0)
+ base = 8;
+ }
+ else if (base == 0)
+ base = 10;
+
+ if (!negative)
+ {
+ /* Parse positive number, checking for overflow. */
+ int digit;
+ /* Overflow watermark. If RESULT exceeds it, overflow occurs on
+ this digit. If result==WATERMARK, current digit may not
+ exceed the last digit of maximum value. */
+ const strtoll_type WATERMARK = STRTOLL_MAX / base;
+ for (; (digit = char_value (*nptr, base)) != -1; ++nptr)
+ {
+ if (result > WATERMARK
+ || (result == WATERMARK && digit > STRTOLL_MAX % base))
+ {
+ result = STRTOLL_MAX;
+ errno = ERANGE;
+ break;
+ }
+ result = base * result + digit;
+ }
+ }
+ else
+ {
+ /* Parse negative number, checking for underflow. */
+ int digit;
+ const strtoll_type WATERMARK = STRTOLL_MIN / base;
+ for (; (digit = char_value (*nptr, base)) != -1; ++nptr)
+ {
+ if (result < WATERMARK
+ || (result == WATERMARK && digit > MOD (STRTOLL_MIN, base)))
+ {
+ result = STRTOLL_MIN;
+ errno = ERANGE;
+ break;
+ }
+ result = base * result - digit;
+ }
+ }
+ out:
+ if (endptr)
+ *endptr = (char *) nptr;
+ return result;
+}
+
+#undef STRTOLL_MAX
+#undef STRTOLL_MIN
+#undef ABS
+
+#endif /* NEED_STRTOLL */