]> sjero.net Git - wget/blob - src/cmpt.c
Restore string after function call.
[wget] / src / cmpt.c
1 /* Replacements for routines missing on some systems.
2    Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3    2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4
5 This file is part of GNU Wget.
6
7 GNU Wget is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 GNU Wget is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Wget.  If not, see <http://www.gnu.org/licenses/>.
19
20 Additional permission under GNU GPL version 3 section 7
21
22 If you modify this program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a
24 modified version of that library), containing parts covered by the
25 terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
26 grants you additional permission to convey the resulting work.
27 Corresponding Source for a non-source form of such a combination
28 shall include the source code for the parts of OpenSSL used as well
29 as that of the covered work.  */
30
31 #include "wget.h"
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <time.h>
37
38 #ifdef HAVE_UNISTD_H
39 # include <unistd.h>
40 #endif
41
42 #include <errno.h>
43
44 /* Some systems lack certain functions normally taken for granted.
45    For example, Windows doesn't have strptime, and some systems don't
46    have a usable fnmatch.  This file should contain fallback
47    implementations of such missing functions.  It should *not* define
48    new Wget-specific interfaces -- those should be placed in utils.c
49    or elsewhere.  */
50 \f
51 /* strcasecmp and strncasecmp apparently originated with BSD 4.4.
52    SUSv3 seems to be the only standard out there (that I can find)
53    that requires their existence, so in theory there might be systems
54    still in use that lack them.  Note that these don't get defined
55    under Windows because mswindows.h defines them to the equivalent
56    Windows functions stricmp and strnicmp.  */
57
58 #ifndef HAVE_STRCASECMP
59 /* From GNU libc.  */
60 /* Compare S1 and S2, ignoring case, returning less than, equal to or
61    greater than zero if S1 is lexiographically less than,
62    equal to or greater than S2.  */
63 int
64 strcasecmp (const char *s1, const char *s2)
65 {
66   register const unsigned char *p1 = (const unsigned char *) s1;
67   register const unsigned char *p2 = (const unsigned char *) s2;
68   unsigned char c1, c2;
69
70   if (p1 == p2)
71     return 0;
72
73   do
74     {
75       c1 = c_tolower (*p1++);
76       c2 = c_tolower (*p2++);
77       if (c1 == '\0')
78         break;
79     }
80   while (c1 == c2);
81
82   return c1 - c2;
83 }
84 #endif /* not HAVE_STRCASECMP */
85
86 #ifndef HAVE_STRNCASECMP
87 /* From GNU libc.  */
88 /* Compare no more than N characters of S1 and S2,
89    ignoring case, returning less than, equal to or
90    greater than zero if S1 is lexicographically less
91    than, equal to or greater than S2.  */
92 int
93 strncasecmp (const char *s1, const char *s2, size_t n)
94 {
95   register const unsigned char *p1 = (const unsigned char *) s1;
96   register const unsigned char *p2 = (const unsigned char *) s2;
97   unsigned char c1, c2;
98
99   if (p1 == p2 || n == 0)
100     return 0;
101
102   do
103     {
104       c1 = c_tolower (*p1++);
105       c2 = c_tolower (*p2++);
106       if (c1 == '\0' || c1 != c2)
107         return c1 - c2;
108     } while (--n > 0);
109
110   return c1 - c2;
111 }
112 #endif /* not HAVE_STRNCASECMP */
113
114 #ifndef HAVE_MEMRCHR
115 /* memrchr is a GNU extension.  It is like the memchr function, except
116    that it searches backwards from the end of the n bytes pointed to
117    by s instead of forwards from the front.  */
118
119 void *
120 memrchr (const void *s, int c, size_t n)
121 {
122   const char *b = s;
123   const char *e = b + n;
124   while (e > b)
125     if (*--e == c)
126       return (void *) e;
127   return NULL;
128 }
129 #endif
130 \f
131 /* strptime is required by POSIX, but it is missing from Windows,
132    which means we must keep a fallback implementation.  It is
133    reportedly missing or broken on many older Unix systems as well, so
134    it's good to have around.  */
135
136 #ifndef HAVE_STRPTIME
137 /* From GNU libc 2.1.3.  */
138 /* Ulrich, thanks for helping me out with this!  --hniksic  */
139
140 /* strptime - Convert a string representation of time to a time value.
141    Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
142    This file is part of the GNU C Library.
143    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.  */
144
145 /* XXX This version of the implementation is not really complete.
146    Some of the fields cannot add information alone.  But if seeing
147    some of them in the same format (such as year, week and weekday)
148    this is enough information for determining the date.  */
149
150 #ifndef __P
151 # define __P(args) args
152 #endif /* not __P */
153
154 #if ! HAVE_LOCALTIME_R && ! defined localtime_r
155 # ifdef _LIBC
156 #  define localtime_r __localtime_r
157 # else
158 /* Approximate localtime_r as best we can in its absence.  */
159 #  define localtime_r my_localtime_r
160 static struct tm *localtime_r __P ((const time_t *, struct tm *));
161 static struct tm *
162 localtime_r (t, tp)
163      const time_t *t;
164      struct tm *tp;
165 {
166   struct tm *l = localtime (t);
167   if (! l)
168     return 0;
169   *tp = *l;
170   return tp;
171 }
172 # endif /* ! _LIBC */
173 #endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
174
175
176 #define match_char(ch1, ch2) if (ch1 != ch2) return NULL
177 #if defined __GNUC__ && __GNUC__ >= 2
178 # define match_string(cs1, s2) \
179   ({ size_t len = strlen (cs1);                                               \
180      int result = strncasecmp ((cs1), (s2), len) == 0;                        \
181      if (result) (s2) += len;                                                 \
182      result; })
183 #else
184 /* Oh come on.  Get a reasonable compiler.  */
185 # define match_string(cs1, s2) \
186   (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1))
187 #endif
188 /* We intentionally do not use isdigit() for testing because this will
189    lead to problems with the wide character version.  */
190 #define get_number(from, to, n) \
191   do {                                                                        \
192     int __n = n;                                                              \
193     val = 0;                                                                  \
194     while (*rp == ' ')                                                        \
195       ++rp;                                                                   \
196     if (*rp < '0' || *rp > '9')                                               \
197       return NULL;                                                            \
198     do {                                                                      \
199       val *= 10;                                                              \
200       val += *rp++ - '0';                                                     \
201     } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9');        \
202     if (val < from || val > to)                                               \
203       return NULL;                                                            \
204   } while (0)
205 #ifdef _NL_CURRENT
206 /* Added check for __GNUC__ extensions here for Wget. --abbotti */
207 # if defined __GNUC__ && __GNUC__ >= 2
208 #  define get_alt_number(from, to, n) \
209   ({                                                                          \
210     __label__ do_normal;                                                      \
211     if (*decided != raw)                                                      \
212       {                                                                       \
213         const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS);                 \
214         int __n = n;                                                          \
215         int any = 0;                                                          \
216         while (*rp == ' ')                                                    \
217           ++rp;                                                               \
218         val = 0;                                                              \
219         do {                                                                  \
220           val *= 10;                                                          \
221           while (*alts != '\0')                                               \
222             {                                                                 \
223               size_t len = strlen (alts);                                     \
224               if (strncasecmp (alts, rp, len) == 0)                           \
225                 break;                                                        \
226               alts += len + 1;                                                \
227               ++val;                                                          \
228             }                                                                 \
229           if (*alts == '\0')                                                  \
230             {                                                                 \
231               if (*decided == not && ! any)                                   \
232                 goto do_normal;                                               \
233               /* If we haven't read anything it's an error.  */               \
234               if (! any)                                                      \
235                 return NULL;                                                  \
236               /* Correct the premature multiplication.  */                    \
237               val /= 10;                                                      \
238               break;                                                          \
239             }                                                                 \
240           else                                                                \
241             *decided = loc;                                                   \
242         } while (--__n > 0 && val * 10 <= to);                                \
243         if (val < from || val > to)                                           \
244           return NULL;                                                        \
245       }                                                                       \
246     else                                                                      \
247       {                                                                       \
248        do_normal:                                                             \
249         get_number (from, to, n);                                             \
250       }                                                                       \
251     0;                                                                        \
252   })
253 # else
254 #  define get_alt_number(from, to, n) \
255   do {
256     if (*decided != raw)                                                      \
257       {                                                                       \
258         const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS);                 \
259         int __n = n;                                                          \
260         int any = 0;                                                          \
261         while (*rp == ' ')                                                    \
262           ++rp;                                                               \
263         val = 0;                                                              \
264         do {                                                                  \
265           val *= 10;                                                          \
266           while (*alts != '\0')                                               \
267             {                                                                 \
268               size_t len = strlen (alts);                                     \
269               if (strncasecmp (alts, rp, len) == 0)                           \
270                 break;                                                        \
271               alts += len + 1;                                                \
272               ++val;                                                          \
273             }                                                                 \
274           if (*alts == '\0')                                                  \
275             {                                                                 \
276               if (*decided == not && ! any)                                   \
277                 goto do_normal;                                               \
278               /* If we haven't read anything it's an error.  */               \
279               if (! any)                                                      \
280                 return NULL;                                                  \
281               /* Correct the premature multiplication.  */                    \
282               val /= 10;                                                      \
283               break;                                                          \
284             }                                                                 \
285           else                                                                \
286             *decided = loc;                                                   \
287         } while (--__n > 0 && val * 10 <= to);                                \
288         if (val < from || val > to)                                           \
289           return NULL;                                                        \
290       }                                                                       \
291     else                                                                      \
292       {                                                                       \
293        do_normal:                                                             \
294         get_number (from, to, n);                                             \
295       }                                                                       \
296   } while (0)
297 # endif /* defined __GNUC__ && __GNUC__ >= 2 */
298 #else
299 # define get_alt_number(from, to, n) \
300   /* We don't have the alternate representation.  */                          \
301   get_number(from, to, n)
302 #endif
303 #define recursive(new_fmt) \
304   (*(new_fmt) != '\0'                                                         \
305    && (rp = strptime_internal (rp, (new_fmt), tm, decided)) != NULL)
306
307
308 #ifdef _LIBC
309 /* This is defined in locale/C-time.c in the GNU libc.  */
310 extern const struct locale_data _nl_C_LC_TIME;
311 extern const unsigned short int __mon_yday[2][13];
312
313 # define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string)
314 # define ab_weekday_name \
315   (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string)
316 # define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string)
317 # define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string)
318 # define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
319 # define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string)
320 # define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string)
321 # define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string)
322 # define HERE_T_FMT_AMPM \
323   (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string)
324 # define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string)
325
326 # define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n)
327 #else
328 static char const weekday_name[][10] =
329   {
330     "Sunday", "Monday", "Tuesday", "Wednesday",
331     "Thursday", "Friday", "Saturday"
332   };
333 static char const ab_weekday_name[][4] =
334   {
335     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
336   };
337 static char const month_name[][10] =
338   {
339     "January", "February", "March", "April", "May", "June",
340     "July", "August", "September", "October", "November", "December"
341   };
342 static char const ab_month_name[][4] =
343   {
344     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
345     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
346   };
347 # define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y"
348 # define HERE_D_FMT "%m/%d/%y"
349 # define HERE_AM_STR "AM"
350 # define HERE_PM_STR "PM"
351 # define HERE_T_FMT_AMPM "%I:%M:%S %p"
352 # define HERE_T_FMT "%H:%M:%S"
353
354 const unsigned short int __mon_yday[2][13];
355 # ifndef NEED_MON_YDAY
356 #  define NEED_MON_YDAY
357 # endif
358 #endif
359
360 /* Status of lookup: do we use the locale data or the raw data?  */
361 enum locale_status { not, loc, raw };
362
363
364 #ifndef __isleap
365 /* Nonzero if YEAR is a leap year (every 4 years,
366    except every 100th isn't, and every 400th is).  */
367 # define __isleap(year) \
368   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
369 #endif
370
371 /* Compute the day of the week.  */
372 static void
373 day_of_the_week (struct tm *tm)
374 {
375   /* We know that January 1st 1970 was a Thursday (= 4).  Compute the
376      the difference between this data in the one on TM and so determine
377      the weekday.  */
378   int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2);
379   int wday = (-473
380               + (365 * (tm->tm_year - 70))
381               + (corr_year / 4)
382               - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0)
383               + (((corr_year / 4) / 25) / 4)
384               + __mon_yday[0][tm->tm_mon]
385               + tm->tm_mday - 1);
386   tm->tm_wday = ((wday % 7) + 7) % 7;
387 }
388
389 /* Compute the day of the year.  */
390 static void
391 day_of_the_year (struct tm *tm)
392 {
393   tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon]
394                  + (tm->tm_mday - 1));
395 }
396
397 static char *
398 #ifdef _LIBC
399 internal_function
400 #endif
401 strptime_internal __P ((const char *buf, const char *format, struct tm *tm,
402                         enum locale_status *decided));
403
404 static char *
405 #ifdef _LIBC
406 internal_function
407 #endif
408 strptime_internal (rp, fmt, tm, decided)
409      const char *rp;
410      const char *fmt;
411      struct tm *tm;
412      enum locale_status *decided;
413 {
414 #ifdef _NL_CURRENT
415   const char *rp_backup;
416 #endif
417   int cnt;
418   size_t val;
419   int have_I, is_pm;
420   int century, want_century;
421   int have_wday, want_xday;
422   int have_yday;
423   int have_mon, have_mday;
424
425   have_I = is_pm = 0;
426   century = -1;
427   want_century = 0;
428   have_wday = want_xday = have_yday = have_mon = have_mday = 0;
429
430   while (*fmt != '\0')
431     {
432       /* A white space in the format string matches 0 more or white
433          space in the input string.  */
434       if (c_isspace (*fmt))
435         {
436           while (c_isspace (*rp))
437             ++rp;
438           ++fmt;
439           continue;
440         }
441
442       /* Any character but `%' must be matched by the same character
443          in the iput string.  */
444       if (*fmt != '%')
445         {
446           match_char (*fmt++, *rp++);
447           continue;
448         }
449
450       ++fmt;
451 #ifndef _NL_CURRENT
452       /* We need this for handling the `E' modifier.  */
453     start_over:
454 #endif
455
456 #ifdef _NL_CURRENT
457       /* Make back up of current processing pointer.  */
458       rp_backup = rp;
459 #endif
460
461       switch (*fmt++)
462         {
463         case '%':
464           /* Match the `%' character itself.  */
465           match_char ('%', *rp++);
466           break;
467         case 'a':
468         case 'A':
469           /* Match day of week.  */
470           for (cnt = 0; cnt < 7; ++cnt)
471             {
472 #ifdef _NL_CURRENT
473               if (*decided !=raw)
474                 {
475                   if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
476                     {
477                       if (*decided == not
478                           && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
479                                      weekday_name[cnt]))
480                         *decided = loc;
481                       break;
482                     }
483                   if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
484                     {
485                       if (*decided == not
486                           && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
487                                      ab_weekday_name[cnt]))
488                         *decided = loc;
489                       break;
490                     }
491                 }
492 #endif
493               if (*decided != loc
494                   && (match_string (weekday_name[cnt], rp)
495                       || match_string (ab_weekday_name[cnt], rp)))
496                 {
497                   *decided = raw;
498                   break;
499                 }
500             }
501           if (cnt == 7)
502             /* Does not match a weekday name.  */
503             return NULL;
504           tm->tm_wday = cnt;
505           have_wday = 1;
506           break;
507         case 'b':
508         case 'B':
509         case 'h':
510           /* Match month name.  */
511           for (cnt = 0; cnt < 12; ++cnt)
512             {
513 #ifdef _NL_CURRENT
514               if (*decided !=raw)
515                 {
516                   if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
517                     {
518                       if (*decided == not
519                           && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
520                                      month_name[cnt]))
521                         *decided = loc;
522                       break;
523                     }
524                   if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
525                     {
526                       if (*decided == not
527                           && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
528                                      ab_month_name[cnt]))
529                         *decided = loc;
530                       break;
531                     }
532                 }
533 #endif
534               if (match_string (month_name[cnt], rp)
535                   || match_string (ab_month_name[cnt], rp))
536                 {
537                   *decided = raw;
538                   break;
539                 }
540             }
541           if (cnt == 12)
542             /* Does not match a month name.  */
543             return NULL;
544           tm->tm_mon = cnt;
545           want_xday = 1;
546           break;
547         case 'c':
548           /* Match locale's date and time format.  */
549 #ifdef _NL_CURRENT
550           if (*decided != raw)
551             {
552               if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
553                 {
554                   if (*decided == loc)
555                     return NULL;
556                   else
557                     rp = rp_backup;
558                 }
559               else
560                 {
561                   if (*decided == not &&
562                       strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
563                     *decided = loc;
564                   want_xday = 1;
565                   break;
566                 }
567               *decided = raw;
568             }
569 #endif
570           if (!recursive (HERE_D_T_FMT))
571             return NULL;
572           want_xday = 1;
573           break;
574         case 'C':
575           /* Match century number.  */
576           get_number (0, 99, 2);
577           century = val;
578           want_xday = 1;
579           break;
580         case 'd':
581         case 'e':
582           /* Match day of month.  */
583           get_number (1, 31, 2);
584           tm->tm_mday = val;
585           have_mday = 1;
586           want_xday = 1;
587           break;
588         case 'F':
589           if (!recursive ("%Y-%m-%d"))
590             return NULL;
591           want_xday = 1;
592           break;
593         case 'x':
594 #ifdef _NL_CURRENT
595           if (*decided != raw)
596             {
597               if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
598                 {
599                   if (*decided == loc)
600                     return NULL;
601                   else
602                     rp = rp_backup;
603                 }
604               else
605                 {
606                   if (*decided == not
607                       && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
608                     *decided = loc;
609                   want_xday = 1;
610                   break;
611                 }
612               *decided = raw;
613             }
614 #endif
615           /* Fall through.  */
616         case 'D':
617           /* Match standard day format.  */
618           if (!recursive (HERE_D_FMT))
619             return NULL;
620           want_xday = 1;
621           break;
622         case 'k':
623         case 'H':
624           /* Match hour in 24-hour clock.  */
625           get_number (0, 23, 2);
626           tm->tm_hour = val;
627           have_I = 0;
628           break;
629         case 'I':
630           /* Match hour in 12-hour clock.  */
631           get_number (1, 12, 2);
632           tm->tm_hour = val % 12;
633           have_I = 1;
634           break;
635         case 'j':
636           /* Match day number of year.  */
637           get_number (1, 366, 3);
638           tm->tm_yday = val - 1;
639           have_yday = 1;
640           break;
641         case 'm':
642           /* Match number of month.  */
643           get_number (1, 12, 2);
644           tm->tm_mon = val - 1;
645           have_mon = 1;
646           want_xday = 1;
647           break;
648         case 'M':
649           /* Match minute.  */
650           get_number (0, 59, 2);
651           tm->tm_min = val;
652           break;
653         case 'n':
654         case 't':
655           /* Match any white space.  */
656           while (c_isspace (*rp))
657             ++rp;
658           break;
659         case 'p':
660           /* Match locale's equivalent of AM/PM.  */
661 #ifdef _NL_CURRENT
662           if (*decided != raw)
663             {
664               if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
665                 {
666                   if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
667                     *decided = loc;
668                   break;
669                 }
670               if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
671                 {
672                   if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
673                     *decided = loc;
674                   is_pm = 1;
675                   break;
676                 }
677               *decided = raw;
678             }
679 #endif
680           if (!match_string (HERE_AM_STR, rp))
681             {
682               if (match_string (HERE_PM_STR, rp))
683                 is_pm = 1;
684               else
685                 return NULL;
686             }
687           break;
688         case 'r':
689 #ifdef _NL_CURRENT
690           if (*decided != raw)
691             {
692               if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
693                 {
694                   if (*decided == loc)
695                     return NULL;
696                   else
697                     rp = rp_backup;
698                 }
699               else
700                 {
701                   if (*decided == not &&
702                       strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
703                               HERE_T_FMT_AMPM))
704                     *decided = loc;
705                   break;
706                 }
707               *decided = raw;
708             }
709 #endif
710           if (!recursive (HERE_T_FMT_AMPM))
711             return NULL;
712           break;
713         case 'R':
714           if (!recursive ("%H:%M"))
715             return NULL;
716           break;
717         case 's':
718           {
719             /* The number of seconds may be very high so we cannot use
720                the `get_number' macro.  Instead read the number
721                character for character and construct the result while
722                doing this.  */
723             time_t secs = 0;
724             if (*rp < '0' || *rp > '9')
725               /* We need at least one digit.  */
726               return NULL;
727
728             do
729               {
730                 secs *= 10;
731                 secs += *rp++ - '0';
732               }
733             while (*rp >= '0' && *rp <= '9');
734
735             if (localtime_r (&secs, tm) == NULL)
736               /* Error in function.  */
737               return NULL;
738           }
739           break;
740         case 'S':
741           get_number (0, 61, 2);
742           tm->tm_sec = val;
743           break;
744         case 'X':
745 #ifdef _NL_CURRENT
746           if (*decided != raw)
747             {
748               if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
749                 {
750                   if (*decided == loc)
751                     return NULL;
752                   else
753                     rp = rp_backup;
754                 }
755               else
756                 {
757                   if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
758                     *decided = loc;
759                   break;
760                 }
761               *decided = raw;
762             }
763 #endif
764           /* Fall through.  */
765         case 'T':
766           if (!recursive (HERE_T_FMT))
767             return NULL;
768           break;
769         case 'u':
770           get_number (1, 7, 1);
771           tm->tm_wday = val % 7;
772           have_wday = 1;
773           break;
774         case 'g':
775           get_number (0, 99, 2);
776           /* XXX This cannot determine any field in TM.  */
777           break;
778         case 'G':
779           if (*rp < '0' || *rp > '9')
780             return NULL;
781           /* XXX Ignore the number since we would need some more
782              information to compute a real date.  */
783           do
784             ++rp;
785           while (*rp >= '0' && *rp <= '9');
786           break;
787         case 'U':
788         case 'V':
789         case 'W':
790           get_number (0, 53, 2);
791           /* XXX This cannot determine any field in TM without some
792              information.  */
793           break;
794         case 'w':
795           /* Match number of weekday.  */
796           get_number (0, 6, 1);
797           tm->tm_wday = val;
798           have_wday = 1;
799           break;
800         case 'y':
801           /* Match year within century.  */
802           get_number (0, 99, 2);
803           /* The "Year 2000: The Millennium Rollover" paper suggests that
804              values in the range 69-99 refer to the twentieth century.  */
805           tm->tm_year = val >= 69 ? val : val + 100;
806           /* Indicate that we want to use the century, if specified.  */
807           want_century = 1;
808           want_xday = 1;
809           break;
810         case 'Y':
811           /* Match year including century number.  */
812           get_number (0, 9999, 4);
813           tm->tm_year = val - 1900;
814           want_century = 0;
815           want_xday = 1;
816           break;
817         case 'Z':
818           /* XXX How to handle this?  */
819           break;
820         case 'E':
821 #ifdef _NL_CURRENT
822           switch (*fmt++)
823             {
824             case 'c':
825               /* Match locale's alternate date and time format.  */
826               if (*decided != raw)
827                 {
828                   const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
829
830                   if (*fmt == '\0')
831                     fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
832
833                   if (!recursive (fmt))
834                     {
835                       if (*decided == loc)
836                         return NULL;
837                       else
838                         rp = rp_backup;
839                     }
840                   else
841                     {
842                       if (strcmp (fmt, HERE_D_T_FMT))
843                         *decided = loc;
844                       want_xday = 1;
845                       break;
846                     }
847                   *decided = raw;
848                 }
849               /* The C locale has no era information, so use the
850                  normal representation.  */
851               if (!recursive (HERE_D_T_FMT))
852                 return NULL;
853               want_xday = 1;
854               break;
855             case 'C':
856             case 'y':
857             case 'Y':
858               /* Match name of base year in locale's alternate
859                  representation.  */
860               /* XXX This is currently not implemented.  It should
861                  use the value _NL_CURRENT (LC_TIME, ERA).  */
862               break;
863             case 'x':
864               if (*decided != raw)
865                 {
866                   const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
867
868                   if (*fmt == '\0')
869                     fmt = _NL_CURRENT (LC_TIME, D_FMT);
870
871                   if (!recursive (fmt))
872                     {
873                       if (*decided == loc)
874                         return NULL;
875                       else
876                         rp = rp_backup;
877                     }
878                   else
879                     {
880                       if (strcmp (fmt, HERE_D_FMT))
881                         *decided = loc;
882                       break;
883                     }
884                   *decided = raw;
885                 }
886               if (!recursive (HERE_D_FMT))
887                 return NULL;
888               break;
889             case 'X':
890               if (*decided != raw)
891                 {
892                   const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
893
894                   if (*fmt == '\0')
895                     fmt = _NL_CURRENT (LC_TIME, T_FMT);
896
897                   if (!recursive (fmt))
898                     {
899                       if (*decided == loc)
900                         return NULL;
901                       else
902                         rp = rp_backup;
903                     }
904                   else
905                     {
906                       if (strcmp (fmt, HERE_T_FMT))
907                         *decided = loc;
908                       break;
909                     }
910                   *decided = raw;
911                 }
912               if (!recursive (HERE_T_FMT))
913                 return NULL;
914               break;
915             default:
916               return NULL;
917             }
918           break;
919 #else
920           /* We have no information about the era format.  Just use
921              the normal format.  */
922           if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
923               && *fmt != 'x' && *fmt != 'X')
924             /* This is an illegal format.  */
925             return NULL;
926
927           goto start_over;
928 #endif
929         case 'O':
930           switch (*fmt++)
931             {
932             case 'd':
933             case 'e':
934               /* Match day of month using alternate numeric symbols.  */
935               get_alt_number (1, 31, 2);
936               tm->tm_mday = val;
937               have_mday = 1;
938               want_xday = 1;
939               break;
940             case 'H':
941               /* Match hour in 24-hour clock using alternate numeric
942                  symbols.  */
943               get_alt_number (0, 23, 2);
944               tm->tm_hour = val;
945               have_I = 0;
946               break;
947             case 'I':
948               /* Match hour in 12-hour clock using alternate numeric
949                  symbols.  */
950               get_alt_number (1, 12, 2);
951               tm->tm_hour = val - 1;
952               have_I = 1;
953               break;
954             case 'm':
955               /* Match month using alternate numeric symbols.  */
956               get_alt_number (1, 12, 2);
957               tm->tm_mon = val - 1;
958               have_mon = 1;
959               want_xday = 1;
960               break;
961             case 'M':
962               /* Match minutes using alternate numeric symbols.  */
963               get_alt_number (0, 59, 2);
964               tm->tm_min = val;
965               break;
966             case 'S':
967               /* Match seconds using alternate numeric symbols.  */
968               get_alt_number (0, 61, 2);
969               tm->tm_sec = val;
970               break;
971             case 'U':
972             case 'V':
973             case 'W':
974               get_alt_number (0, 53, 2);
975               /* XXX This cannot determine any field in TM without
976                  further information.  */
977               break;
978             case 'w':
979               /* Match number of weekday using alternate numeric symbols.  */
980               get_alt_number (0, 6, 1);
981               tm->tm_wday = val;
982               have_wday = 1;
983               break;
984             case 'y':
985               /* Match year within century using alternate numeric symbols.  */
986               get_alt_number (0, 99, 2);
987               tm->tm_year = val >= 69 ? val : val + 100;
988               want_xday = 1;
989               break;
990             default:
991               return NULL;
992             }
993           break;
994         default:
995           return NULL;
996         }
997     }
998
999   if (have_I && is_pm)
1000     tm->tm_hour += 12;
1001
1002   if (century != -1)
1003     {
1004       if (want_century)
1005         tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;
1006       else
1007         /* Only the century, but not the year.  Strange, but so be it.  */
1008         tm->tm_year = (century - 19) * 100;
1009     }
1010
1011   if (want_xday && !have_wday) {
1012       if ( !(have_mon && have_mday) && have_yday)  {
1013           /* we don't have tm_mon and/or tm_mday, compute them */
1014           int t_mon = 0;
1015           while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
1016               t_mon++;
1017           if (!have_mon)
1018               tm->tm_mon = t_mon - 1;
1019           if (!have_mday)
1020               tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1;
1021       }
1022       day_of_the_week (tm);
1023   }
1024   if (want_xday && !have_yday)
1025     day_of_the_year (tm);
1026
1027   return (char *) rp;
1028 }
1029
1030
1031 char *
1032 strptime (buf, format, tm)
1033      const char *buf;
1034      const char *format;
1035      struct tm *tm;
1036 {
1037   enum locale_status decided;
1038 #ifdef _NL_CURRENT
1039   decided = not;
1040 #else
1041   decided = raw;
1042 #endif
1043   return strptime_internal (buf, format, tm, &decided);
1044 }
1045 #endif /* not HAVE_STRPTIME */
1046
1047 #ifdef NEED_MON_YDAY
1048 const unsigned short int __mon_yday[2][13] =
1049   {
1050     /* Normal years.  */
1051     { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
1052     /* Leap years.  */
1053     { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
1054   };
1055 #endif
1056 \f
1057 /* fnmatch is required by POSIX, but we include an implementation for
1058    the sake of systems that don't have it, most notably Windows.  Some
1059    systems do have fnmatch, but Apache's installation process installs
1060    its own fnmatch.h (incompatible with the system one!) in a system
1061    include directory, effectively rendering fnmatch unusable.  This
1062    has been fixed with Apache 2, where fnmatch has been moved to apr
1063    and given a prefix, but many systems out there are still (as of
1064    this writing in 2005) broken and we must cater to them.
1065
1066    Additionally, according to some conventional wisdom, many
1067    historical implementations of fnmatch are buggy and unreliable.  If
1068    yours is such, undefine SYSTEM_FNMATCH in sysdep.h and tell us
1069    about it.  */
1070
1071 #ifndef SYSTEM_FNMATCH
1072
1073 #define __FNM_FLAGS     (FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD)
1074
1075 /* Match STRING against the filename pattern PATTERN, returning zero
1076    if it matches, FNM_NOMATCH if not.  This implementation comes from
1077    an earlier version of GNU Bash.  (It doesn't make sense to update
1078    it with a newer version because those versions add a lot of
1079    features Wget doesn't use or care about.)  */
1080
1081 int
1082 fnmatch (const char *pattern, const char *string, int flags)
1083 {
1084   register const char *p = pattern, *n = string;
1085   register char c;
1086
1087   if ((flags & ~__FNM_FLAGS) != 0)
1088     {
1089       errno = EINVAL;
1090       return (-1);
1091     }
1092
1093   while ((c = *p++) != '\0')
1094     {
1095       switch (c)
1096         {
1097         case '?':
1098           if (*n == '\0')
1099             return (FNM_NOMATCH);
1100           else if ((flags & FNM_PATHNAME) && *n == '/')
1101             return (FNM_NOMATCH);
1102           else if ((flags & FNM_PERIOD) && *n == '.' &&
1103                    (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1104             return (FNM_NOMATCH);
1105           break;
1106
1107         case '\\':
1108           if (!(flags & FNM_NOESCAPE))
1109             c = *p++;
1110           if (*n != c)
1111             return (FNM_NOMATCH);
1112           break;
1113
1114         case '*':
1115           if ((flags & FNM_PERIOD) && *n == '.' &&
1116               (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1117             return (FNM_NOMATCH);
1118
1119           for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
1120             if (((flags & FNM_PATHNAME) && *n == '/') ||
1121                 (c == '?' && *n == '\0'))
1122               return (FNM_NOMATCH);
1123
1124           if (c == '\0')
1125             return (0);
1126
1127           {
1128             char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
1129             for (--p; *n != '\0'; ++n)
1130               if ((c == '[' || *n == c1) &&
1131                   fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
1132                 return (0);
1133             return (FNM_NOMATCH);
1134           }
1135
1136         case '[':
1137           {
1138             /* Nonzero if the sense of the character class is
1139                inverted.  */
1140             register int not;
1141
1142             if (*n == '\0')
1143               return (FNM_NOMATCH);
1144
1145             if ((flags & FNM_PERIOD) && *n == '.' &&
1146                 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1147               return (FNM_NOMATCH);
1148
1149             /* Make sure there is a closing `]'.  If there isn't,
1150                the `[' is just a character to be matched.  */
1151             {
1152               register const char *np;
1153
1154               for (np = p; np && *np && *np != ']'; np++)
1155                 ;
1156
1157               if (np && !*np)
1158                 {
1159                   if (*n != '[')
1160                     return (FNM_NOMATCH);
1161                   goto next_char;
1162                 }
1163             }
1164
1165             not = (*p == '!' || *p == '^');
1166             if (not)
1167               ++p;
1168
1169             c = *p++;
1170             while (1)
1171               {
1172                 register char cstart = c, cend = c;
1173
1174                 if (!(flags & FNM_NOESCAPE) && c == '\\')
1175                   cstart = cend = *p++;
1176
1177                 if (c == '\0')
1178                   /* [ (unterminated) loses.  */
1179                   return (FNM_NOMATCH);
1180
1181                 c = *p++;
1182
1183                 if ((flags & FNM_PATHNAME) && c == '/')
1184                   /* [/] can never match.  */
1185                   return (FNM_NOMATCH);
1186
1187                 if (c == '-' && *p != ']')
1188                   {
1189                     cend = *p++;
1190                     if (!(flags & FNM_NOESCAPE) && cend == '\\')
1191                       cend = *p++;
1192                     if (cend == '\0')
1193                       return (FNM_NOMATCH);
1194                     c = *p++;
1195                   }
1196
1197                 if (*n >= cstart && *n <= cend)
1198                   goto matched;
1199
1200                 if (c == ']')
1201                   break;
1202               }
1203             if (!not)
1204               return (FNM_NOMATCH);
1205
1206           next_char:
1207             break;
1208
1209           matched:
1210             /* Skip the rest of the [...] that already matched.  */
1211             while (c != ']')
1212               {
1213                 if (c == '\0')
1214                   /* [... (unterminated) loses.  */
1215                   return (FNM_NOMATCH);
1216
1217                 c = *p++;
1218                 if (!(flags & FNM_NOESCAPE) && c == '\\')
1219                   /* 1003.2d11 is unclear if this is right.  %%% */
1220                   ++p;
1221               }
1222             if (not)
1223               return (FNM_NOMATCH);
1224           }
1225           break;
1226
1227         default:
1228           if (c != *n)
1229             return (FNM_NOMATCH);
1230         }
1231
1232       ++n;
1233     }
1234
1235   if (*n == '\0')
1236     return (0);
1237
1238   return (FNM_NOMATCH);
1239 }
1240
1241 #endif /* not SYSTEM_FNMATCH */
1242 \f
1243 #ifndef HAVE_TIMEGM
1244 /* timegm is a GNU extension, but lately also available on *BSD
1245    systems and possibly elsewhere. */
1246
1247 /* True if YEAR is a leap year. */
1248 #define ISLEAP(year)                                            \
1249   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
1250
1251 /* Number of leap years in the range [y1, y2). */
1252 #define LEAPYEARS(y1, y2)                                               \
1253   ((y2-1)/4 - (y1-1)/4) - ((y2-1)/100 - (y1-1)/100) + ((y2-1)/400 - (y1-1)/400)
1254
1255 /* Inverse of gmtime: converts struct tm to time_t, assuming the data
1256    in tm is UTC rather than local timezone.  This implementation
1257    returns the number of seconds elapsed since midnight 1970-01-01,
1258    converted to time_t.  */
1259
1260 time_t
1261 timegm (struct tm *t)
1262 {
1263   static const unsigned short int month_to_days[][13] = {
1264     { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, /* normal */
1265     { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }  /* leap */
1266   };
1267   const int year = 1900 + t->tm_year;
1268   unsigned long secs;  /* until 2106-02-07 for 32-bit unsigned long */
1269   int days;
1270
1271   if (year < 1970)
1272     return (time_t) -1;
1273
1274   days = 365 * (year - 1970);
1275   /* Take into account leap years between 1970 and YEAR, not counting
1276      YEAR itself.  */
1277   days += LEAPYEARS (1970, year);
1278   if (t->tm_mon < 0 || t->tm_mon >= 12)
1279     return (time_t) -1;
1280   days += month_to_days[ISLEAP (year)][t->tm_mon];
1281   days += t->tm_mday - 1;
1282
1283   secs = days * 86400 + t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec;
1284   return (time_t) secs;
1285 }
1286 #endif /* HAVE_TIMEGM */
1287
1288 #ifdef NEED_STRTOLL
1289 /* strtoll is required by C99 and used by Wget only on systems with
1290    LFS.  Unfortunately, some systems have LFS, but no strtoll or
1291    equivalent.  These include HPUX 11.0 and Windows.
1292
1293    We use #ifdef NEED_STRTOLL instead of #ifndef HAVE_STRTOLL because
1294    of the systems which have a suitable replacement (e.g. _strtoi64 on
1295    Windows), on which Wget's str_to_wgint is instructed to use that
1296    instead.  */
1297
1298 static inline int
1299 char_value (char c, int base)
1300 {
1301   int value;
1302   if (c < '0')
1303     return -1;
1304   if ('0' <= c && c <= '9')
1305     value = c - '0';
1306   else if ('a' <= c && c <= 'z')
1307     value = c - 'a' + 10;
1308   else if ('A' <= c && c <= 'Z')
1309     value = c - 'A' + 10;
1310   else
1311     return -1;
1312   if (value >= base)
1313     return -1;
1314   return value;
1315 }
1316
1317 #define STRTOLL_MAX TYPE_MAXIMUM (strtoll_type)
1318 /* This definition assumes two's complement arithmetic */
1319 #define STRTOLL_MIN (-STRTOLL_MAX - 1)
1320
1321 /* Like a%b, but always returns a positive number when A is negative.
1322    (C doesn't guarantee the sign of the result.)  */
1323 #define MOD(a, b) ((strtoll_type) -1 % 2 == 1 ? (a) % (b) : - ((a) % (b)))
1324
1325 /* A strtoll-like replacement for systems that have an integral type
1326    larger than long but don't supply strtoll.  This implementation
1327    makes no assumptions about the size of strtoll_type.  */
1328
1329 strtoll_type
1330 strtoll (const char *nptr, char **endptr, int base)
1331 {
1332   strtoll_type result = 0;
1333   bool negative;
1334
1335   if (base != 0 && (base < 2 || base > 36))
1336     {
1337       errno = EINVAL;
1338       return 0;
1339     }
1340
1341   while (*nptr == ' ' || *nptr == '\t')
1342     ++nptr;
1343   if (*nptr == '-')
1344     {
1345       negative = true;
1346       ++nptr;
1347     }
1348   else if (*nptr == '+')
1349     {
1350       negative = false;
1351       ++nptr;
1352     }
1353   else
1354     negative = false;
1355
1356   /* If BASE is 0, determine the real base based on the beginning on
1357      the number; octal numbers begin with "0", hexadecimal with "0x",
1358      and the others are considered octal.  */
1359   if (*nptr == '0')
1360     {
1361       if ((base == 0 || base == 16)
1362           &&
1363           (*(nptr + 1) == 'x' || *(nptr + 1) == 'X'))
1364         {
1365           base = 16;
1366           nptr += 2;
1367           /* "0x" must be followed by at least one hex char.  If not,
1368              return 0 and place ENDPTR on 'x'. */
1369           if (!c_isxdigit (*nptr))
1370             {
1371               --nptr;
1372               goto out;
1373             }
1374         }
1375       else if (base == 0)
1376         base = 8;
1377     }
1378   else if (base == 0)
1379     base = 10;
1380
1381   if (!negative)
1382     {
1383       /* Parse positive number, checking for overflow. */
1384       int digit;
1385       /* Overflow watermark.  If RESULT exceeds it, overflow occurs on
1386          this digit.  If result==WATERMARK, current digit may not
1387          exceed the last digit of maximum value. */
1388       const strtoll_type WATERMARK = STRTOLL_MAX / base;
1389       for (; (digit = char_value (*nptr, base)) != -1; ++nptr)
1390         {
1391           if (result > WATERMARK
1392               || (result == WATERMARK && digit > STRTOLL_MAX % base))
1393             {
1394               result = STRTOLL_MAX;
1395               errno = ERANGE;
1396               break;
1397             }
1398           result = base * result + digit;
1399         }
1400     }
1401   else
1402     {
1403       /* Parse negative number, checking for underflow. */
1404       int digit;
1405       const strtoll_type WATERMARK = STRTOLL_MIN / base;
1406       for (; (digit = char_value (*nptr, base)) != -1; ++nptr)
1407         {
1408           if (result < WATERMARK
1409               || (result == WATERMARK && digit > MOD (STRTOLL_MIN, base)))
1410             {
1411               result = STRTOLL_MIN;
1412               errno = ERANGE;
1413               break;
1414             }
1415           result = base * result - digit;
1416         }
1417     }
1418  out:
1419   if (endptr)
1420     *endptr = (char *) nptr;
1421   return result;
1422 }
1423
1424 #undef STRTOLL_MAX
1425 #undef STRTOLL_MIN
1426 #undef ABS
1427
1428 #endif  /* NEED_STRTOLL */