source: trunk/essentials/net-misc/wget/src/cmpt.c

Last change on this file was 3440, checked in by bird, 18 years ago

wget 1.10.2

File size: 44.9 KB
Line 
1/* Replacements for routines missing on some systems.
2 Copyright (C) 1995-2005 Free Software Foundation, Inc.
3
4This file is part of GNU Wget.
5
6GNU Wget is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11GNU Wget is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with Wget; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20In addition, as a special exception, the Free Software Foundation
21gives permission to link the code of its release of Wget with the
22OpenSSL project's "OpenSSL" library (or with modified versions of it
23that use the same license as the "OpenSSL" library), and distribute
24the linked executables. You must obey the GNU General Public License
25in all respects for all of the code used other than "OpenSSL". If you
26modify this file, you may extend this exception to your version of the
27file, but you are not obligated to do so. If you do not wish to do
28so, delete this exception statement from your version. */
29
30#include <config.h>
31
32#include <stdio.h>
33#include <stdlib.h>
34#ifdef HAVE_STRING_H
35# include <string.h>
36#else
37# include <strings.h>
38#endif /* HAVE_STRING_H */
39
40#include <sys/types.h>
41#ifdef HAVE_UNISTD_H
42# include <unistd.h>
43#endif
44#include <limits.h>
45
46#include <errno.h>
47#ifndef errno
48extern int errno;
49#endif
50
51#include "wget.h"
52
53#ifndef HAVE_STRERROR
54/* A strerror() clone, for systems that don't have it. */
55char *
56strerror (int err)
57{
58 /* This loses on a system without `sys_errlist'. */
59 extern char *sys_errlist[];
60 return sys_errlist[err];
61}
62#endif /* not HAVE_STRERROR */
63
64/* Some systems don't have some str* functions in libc. Here we
65 define them. The same goes for strptime. */
66
67#ifndef HAVE_STRCASECMP
68/* From GNU libc. */
69/* Compare S1 and S2, ignoring case, returning less than, equal to or
70 greater than zero if S1 is lexiographically less than,
71 equal to or greater than S2. */
72int
73strcasecmp (const char *s1, const char *s2)
74{
75 register const unsigned char *p1 = (const unsigned char *) s1;
76 register const unsigned char *p2 = (const unsigned char *) s2;
77 unsigned char c1, c2;
78
79 if (p1 == p2)
80 return 0;
81
82 do
83 {
84 c1 = TOLOWER (*p1++);
85 c2 = TOLOWER (*p2++);
86 if (c1 == '\0')
87 break;
88 }
89 while (c1 == c2);
90
91 return c1 - c2;
92}
93#endif /* not HAVE_STRCASECMP */
94
95#ifndef HAVE_STRNCASECMP
96/* From GNU libc. */
97/* Compare no more than N characters of S1 and S2,
98 ignoring case, returning less than, equal to or
99 greater than zero if S1 is lexicographically less
100 than, equal to or greater than S2. */
101int
102strncasecmp (const char *s1, const char *s2, size_t n)
103{
104 register const unsigned char *p1 = (const unsigned char *) s1;
105 register const unsigned char *p2 = (const unsigned char *) s2;
106 unsigned char c1, c2;
107
108 if (p1 == p2 || n == 0)
109 return 0;
110
111 do
112 {
113 c1 = TOLOWER (*p1++);
114 c2 = TOLOWER (*p2++);
115 if (c1 == '\0' || c1 != c2)
116 return c1 - c2;
117 } while (--n > 0);
118
119 return c1 - c2;
120}
121#endif /* not HAVE_STRNCASECMP */
122
123#ifndef HAVE_STRSTR
124/* From GNU libc 2.3.5. */
125
126/*
127 * My personal strstr() implementation that beats most other algorithms.
128 * Until someone tells me otherwise, I assume that this is the
129 * fastest implementation of strstr() in C.
130 * I deliberately chose not to comment it. You should have at least
131 * as much fun trying to understand it, as I had to write it :-).
132 *
133 * Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */
134
135typedef unsigned chartype;
136
137#undef strstr
138
139char *
140strstr (const char *phaystack, const char *pneedle)
141{
142 const unsigned char *haystack, *needle;
143 chartype b;
144 const unsigned char *rneedle;
145
146 haystack = (const unsigned char *) phaystack;
147
148 if ((b = *(needle = (const unsigned char *) pneedle)))
149 {
150 chartype c;
151 haystack--; /* possible ANSI violation */
152
153 {
154 chartype a;
155 do
156 if (!(a = *++haystack))
157 goto ret0;
158 while (a != b);
159 }
160
161 if (!(c = *++needle))
162 goto foundneedle;
163 ++needle;
164 goto jin;
165
166 for (;;)
167 {
168 {
169 chartype a;
170 if (0)
171 jin:{
172 if ((a = *++haystack) == c)
173 goto crest;
174 }
175 else
176 a = *++haystack;
177 do
178 {
179 for (; a != b; a = *++haystack)
180 {
181 if (!a)
182 goto ret0;
183 if ((a = *++haystack) == b)
184 break;
185 if (!a)
186 goto ret0;
187 }
188 }
189 while ((a = *++haystack) != c);
190 }
191 crest:
192 {
193 chartype a;
194 {
195 const unsigned char *rhaystack;
196 if (*(rhaystack = haystack-- + 1) == (a = *(rneedle = needle)))
197 do
198 {
199 if (!a)
200 goto foundneedle;
201 if (*++rhaystack != (a = *++needle))
202 break;
203 if (!a)
204 goto foundneedle;
205 }
206 while (*++rhaystack == (a = *++needle));
207 needle = rneedle; /* took the register-poor aproach */
208 }
209 if (!a)
210 break;
211 }
212 }
213 }
214foundneedle:
215 return (char *) haystack;
216ret0:
217 return 0;
218}
219#endif /* not HAVE_STRSTR */
220
221#ifndef HAVE_STRPBRK
222/* Find the first ocurrence in S of any character in ACCEPT. */
223char *
224strpbrk (const char *s, const char *accept)
225{
226 while (*s != '\0')
227 {
228 const char *a = accept;
229 while (*a != '\0')
230 if (*a++ == *s)
231 return (char *) s;
232 ++s;
233 }
234
235 return 0;
236}
237#endif /* HAVE_STRPBRK */
238
239#ifndef HAVE_MKTIME
240/* From GNU libc 2.0. */
241
242/* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
243 This file is part of the GNU C Library.
244 Contributed by Paul Eggert (eggert@twinsun.com). */
245
246#ifdef _LIBC
247# define HAVE_LIMITS_H 1
248# define HAVE_LOCALTIME_R 1
249# define STDC_HEADERS 1
250#endif
251
252/* Assume that leap seconds are possible, unless told otherwise.
253 If the host has a `zic' command with a `-L leapsecondfilename' option,
254 then it supports leap seconds; otherwise it probably doesn't. */
255#ifndef LEAP_SECONDS_POSSIBLE
256# define LEAP_SECONDS_POSSIBLE 1
257#endif
258
259#ifndef __P
260# define __P(args) PARAMS (args)
261#endif /* Not __P. */
262
263#ifndef CHAR_BIT
264# define CHAR_BIT 8
265#endif
266
267#ifndef INT_MIN
268# define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1))
269#endif
270#ifndef INT_MAX
271# define INT_MAX (~0 - INT_MIN)
272#endif
273
274#ifndef TIME_T_MIN
275/* The outer cast to time_t works around a bug in Cray C 5.0.3.0. */
276# define TIME_T_MIN ((time_t) \
277 (0 < (time_t) -1 ? (time_t) 0 \
278 : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)))
279#endif
280#ifndef TIME_T_MAX
281# define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
282#endif
283
284#define TM_YEAR_BASE 1900
285#define EPOCH_YEAR 1970
286
287#ifndef __isleap
288/* Nonzero if YEAR is a leap year (every 4 years,
289 except every 100th isn't, and every 400th is). */
290# define __isleap(year) \
291 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
292#endif
293
294/* How many days come before each month (0-12). */
295/* __mon_yday[][] is common to mktime and strptime implementations.
296 --abbotti */
297const unsigned short int __mon_yday[2][13];
298#ifndef NEED_MON_YDAY
299# define NEED_MON_YDAY
300#endif
301
302static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
303time_t __mktime_internal __P ((struct tm *,
304 struct tm *(*) (const time_t *, struct tm *),
305 time_t *));
306
307
308#ifdef _LIBC
309# define localtime_r __localtime_r
310#else
311# if ! HAVE_LOCALTIME_R && ! defined localtime_r
312/* Approximate localtime_r as best we can in its absence. */
313# define localtime_r my_mktime_localtime_r
314static struct tm *localtime_r __P ((const time_t *, struct tm *));
315static struct tm *
316localtime_r (t, tp)
317 const time_t *t;
318 struct tm *tp;
319{
320 struct tm *l = localtime (t);
321 if (! l)
322 return 0;
323 *tp = *l;
324 return tp;
325}
326# endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
327#endif /* ! _LIBC */
328
329
330/* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP),
331 measured in seconds, ignoring leap seconds.
332 YEAR uses the same numbering as TM->tm_year.
333 All values are in range, except possibly YEAR.
334 If overflow occurs, yield the low order bits of the correct answer. */
335static time_t
336ydhms_tm_diff (year, yday, hour, min, sec, tp)
337 int year, yday, hour, min, sec;
338 const struct tm *tp;
339{
340 /* Compute intervening leap days correctly even if year is negative.
341 Take care to avoid int overflow. time_t overflow is OK, since
342 only the low order bits of the correct time_t answer are needed.
343 Don't convert to time_t until after all divisions are done, since
344 time_t might be unsigned. */
345 int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
346 int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
347 int a100 = a4 / 25 - (a4 % 25 < 0);
348 int b100 = b4 / 25 - (b4 % 25 < 0);
349 int a400 = a100 >> 2;
350 int b400 = b100 >> 2;
351 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
352 time_t years = year - (time_t) tp->tm_year;
353 time_t days = (365 * years + intervening_leap_days
354 + (yday - tp->tm_yday));
355 return (60 * (60 * (24 * days + (hour - tp->tm_hour))
356 + (min - tp->tm_min))
357 + (sec - tp->tm_sec));
358}
359
360
361static time_t localtime_offset;
362
363/* Convert *TP to a time_t value. */
364time_t
365mktime (tp)
366 struct tm *tp;
367{
368#ifdef _LIBC
369 /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
370 time zone names contained in the external variable `tzname' shall
371 be set as if the tzset() function had been called. */
372 __tzset ();
373#endif
374
375 return __mktime_internal (tp, localtime_r, &localtime_offset);
376}
377
378/* Convert *TP to a time_t value, inverting
379 the monotonic and mostly-unit-linear conversion function CONVERT.
380 Use *OFFSET to keep track of a guess at the offset of the result,
381 compared to what the result would be for UTC without leap seconds.
382 If *OFFSET's guess is correct, only one CONVERT call is needed. */
383time_t
384__mktime_internal (tp, convert, offset)
385 struct tm *tp;
386 struct tm *(*convert) __P ((const time_t *, struct tm *));
387 time_t *offset;
388{
389 time_t t, dt, t0;
390 struct tm tm;
391
392 /* The maximum number of probes (calls to CONVERT) should be enough
393 to handle any combinations of time zone rule changes, solar time,
394 and leap seconds. Posix.1 prohibits leap seconds, but some hosts
395 have them anyway. */
396 int remaining_probes = 4;
397
398 /* Time requested. Copy it in case CONVERT modifies *TP; this can
399 occur if TP is localtime's returned value and CONVERT is localtime. */
400 int sec = tp->tm_sec;
401 int min = tp->tm_min;
402 int hour = tp->tm_hour;
403 int mday = tp->tm_mday;
404 int mon = tp->tm_mon;
405 int year_requested = tp->tm_year;
406 int isdst = tp->tm_isdst;
407
408 /* Ensure that mon is in range, and set year accordingly. */
409 int mon_remainder = mon % 12;
410 int negative_mon_remainder = mon_remainder < 0;
411 int mon_years = mon / 12 - negative_mon_remainder;
412 int year = year_requested + mon_years;
413
414 /* The other values need not be in range:
415 the remaining code handles minor overflows correctly,
416 assuming int and time_t arithmetic wraps around.
417 Major overflows are caught at the end. */
418
419 /* Calculate day of year from year, month, and day of month.
420 The result need not be in range. */
421 int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)]
422 [mon_remainder + 12 * negative_mon_remainder])
423 + mday - 1);
424
425 int sec_requested = sec;
426#if LEAP_SECONDS_POSSIBLE
427 /* Handle out-of-range seconds specially,
428 since ydhms_tm_diff assumes every minute has 60 seconds. */
429 if (sec < 0)
430 sec = 0;
431 if (59 < sec)
432 sec = 59;
433#endif
434
435 /* Invert CONVERT by probing. First assume the same offset as last time.
436 Then repeatedly use the error to improve the guess. */
437
438 tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
439 tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
440 t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
441
442 for (t = t0 + *offset;
443 (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
444 t += dt)
445 if (--remaining_probes == 0)
446 return -1;
447
448 /* Check whether tm.tm_isdst has the requested value, if any. */
449 if (0 <= isdst && 0 <= tm.tm_isdst)
450 {
451 int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
452 if (dst_diff)
453 {
454 /* Move two hours in the direction indicated by the disagreement,
455 probe some more, and switch to a new time if found.
456 The largest known fallback due to daylight savings is two hours:
457 once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */
458 time_t ot = t - 2 * 60 * 60 * dst_diff;
459 while (--remaining_probes != 0)
460 {
461 struct tm otm;
462 if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
463 (*convert) (&ot, &otm))))
464 {
465 t = ot;
466 tm = otm;
467 break;
468 }
469 if ((ot += dt) == t)
470 break; /* Avoid a redundant probe. */
471 }
472 }
473 }
474
475 *offset = t - t0;
476
477#if LEAP_SECONDS_POSSIBLE
478 if (sec_requested != tm.tm_sec)
479 {
480 /* Adjust time to reflect the tm_sec requested, not the normalized value.
481 Also, repair any damage from a false match due to a leap second. */
482 t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
483 (*convert) (&t, &tm);
484 }
485#endif
486
487 if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3)
488 {
489 /* time_t isn't large enough to rule out overflows in ydhms_tm_diff,
490 so check for major overflows. A gross check suffices,
491 since if t has overflowed, it is off by a multiple of
492 TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of
493 the difference that is bounded by a small value. */
494
495 double dyear = (double) year_requested + mon_years - tm.tm_year;
496 double dday = 366 * dyear + mday;
497 double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested;
498
499 if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec))
500 return -1;
501 }
502
503 *tp = tm;
504 return t;
505}
506
507#ifdef weak_alias
508weak_alias (mktime, timelocal)
509#endif
510#endif /* not HAVE_MKTIME */
511
512
513#ifndef HAVE_STRPTIME
514/* From GNU libc 2.1.3. */
515/* Ulrich, thanks for helping me out with this! --hniksic */
516
517/* strptime - Convert a string representation of time to a time value.
518 Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
519 This file is part of the GNU C Library.
520 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. */
521
522/* XXX This version of the implementation is not really complete.
523 Some of the fields cannot add information alone. But if seeing
524 some of them in the same format (such as year, week and weekday)
525 this is enough information for determining the date. */
526
527#ifndef __P
528# define __P(args) PARAMS (args)
529#endif /* not __P */
530
531#if ! HAVE_LOCALTIME_R && ! defined localtime_r
532# ifdef _LIBC
533# define localtime_r __localtime_r
534# else
535/* Approximate localtime_r as best we can in its absence. */
536# define localtime_r my_localtime_r
537static struct tm *localtime_r __P ((const time_t *, struct tm *));
538static struct tm *
539localtime_r (t, tp)
540 const time_t *t;
541 struct tm *tp;
542{
543 struct tm *l = localtime (t);
544 if (! l)
545 return 0;
546 *tp = *l;
547 return tp;
548}
549# endif /* ! _LIBC */
550#endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */
551
552
553#define match_char(ch1, ch2) if (ch1 != ch2) return NULL
554#if defined __GNUC__ && __GNUC__ >= 2
555# define match_string(cs1, s2) \
556 ({ size_t len = strlen (cs1); \
557 int result = strncasecmp ((cs1), (s2), len) == 0; \
558 if (result) (s2) += len; \
559 result; })
560#else
561/* Oh come on. Get a reasonable compiler. */
562# define match_string(cs1, s2) \
563 (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1))
564#endif
565/* We intentionally do not use isdigit() for testing because this will
566 lead to problems with the wide character version. */
567#define get_number(from, to, n) \
568 do { \
569 int __n = n; \
570 val = 0; \
571 while (*rp == ' ') \
572 ++rp; \
573 if (*rp < '0' || *rp > '9') \
574 return NULL; \
575 do { \
576 val *= 10; \
577 val += *rp++ - '0'; \
578 } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \
579 if (val < from || val > to) \
580 return NULL; \
581 } while (0)
582#ifdef _NL_CURRENT
583/* Added check for __GNUC__ extensions here for Wget. --abbotti */
584# if defined __GNUC__ && __GNUC__ >= 2
585# define get_alt_number(from, to, n) \
586 ({ \
587 __label__ do_normal; \
588 if (*decided != raw) \
589 { \
590 const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \
591 int __n = n; \
592 int any = 0; \
593 while (*rp == ' ') \
594 ++rp; \
595 val = 0; \
596 do { \
597 val *= 10; \
598 while (*alts != '\0') \
599 { \
600 size_t len = strlen (alts); \
601 if (strncasecmp (alts, rp, len) == 0) \
602 break; \
603 alts += len + 1; \
604 ++val; \
605 } \
606 if (*alts == '\0') \
607 { \
608 if (*decided == not && ! any) \
609 goto do_normal; \
610 /* If we haven't read anything it's an error. */ \
611 if (! any) \
612 return NULL; \
613 /* Correct the premature multiplication. */ \
614 val /= 10; \
615 break; \
616 } \
617 else \
618 *decided = loc; \
619 } while (--__n > 0 && val * 10 <= to); \
620 if (val < from || val > to) \
621 return NULL; \
622 } \
623 else \
624 { \
625 do_normal: \
626 get_number (from, to, n); \
627 } \
628 0; \
629 })
630# else
631# define get_alt_number(from, to, n) \
632 do {
633 if (*decided != raw) \
634 { \
635 const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \
636 int __n = n; \
637 int any = 0; \
638 while (*rp == ' ') \
639 ++rp; \
640 val = 0; \
641 do { \
642 val *= 10; \
643 while (*alts != '\0') \
644 { \
645 size_t len = strlen (alts); \
646 if (strncasecmp (alts, rp, len) == 0) \
647 break; \
648 alts += len + 1; \
649 ++val; \
650 } \
651 if (*alts == '\0') \
652 { \
653 if (*decided == not && ! any) \
654 goto do_normal; \
655 /* If we haven't read anything it's an error. */ \
656 if (! any) \
657 return NULL; \
658 /* Correct the premature multiplication. */ \
659 val /= 10; \
660 break; \
661 } \
662 else \
663 *decided = loc; \
664 } while (--__n > 0 && val * 10 <= to); \
665 if (val < from || val > to) \
666 return NULL; \
667 } \
668 else \
669 { \
670 do_normal: \
671 get_number (from, to, n); \
672 } \
673 } while (0)
674# endif /* defined __GNUC__ && __GNUC__ >= 2 */
675#else
676# define get_alt_number(from, to, n) \
677 /* We don't have the alternate representation. */ \
678 get_number(from, to, n)
679#endif
680#define recursive(new_fmt) \
681 (*(new_fmt) != '\0' \
682 && (rp = strptime_internal (rp, (new_fmt), tm, decided)) != NULL)
683
684
685#ifdef _LIBC
686/* This is defined in locale/C-time.c in the GNU libc. */
687extern const struct locale_data _nl_C_LC_TIME;
688extern const unsigned short int __mon_yday[2][13];
689
690# define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string)
691# define ab_weekday_name \
692 (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string)
693# define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string)
694# define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string)
695# define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string)
696# define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string)
697# define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string)
698# define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string)
699# define HERE_T_FMT_AMPM \
700 (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string)
701# define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string)
702
703# define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n)
704#else
705static char const weekday_name[][10] =
706 {
707 "Sunday", "Monday", "Tuesday", "Wednesday",
708 "Thursday", "Friday", "Saturday"
709 };
710static char const ab_weekday_name[][4] =
711 {
712 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
713 };
714static char const month_name[][10] =
715 {
716 "January", "February", "March", "April", "May", "June",
717 "July", "August", "September", "October", "November", "December"
718 };
719static char const ab_month_name[][4] =
720 {
721 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
722 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
723 };
724# define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y"
725# define HERE_D_FMT "%m/%d/%y"
726# define HERE_AM_STR "AM"
727# define HERE_PM_STR "PM"
728# define HERE_T_FMT_AMPM "%I:%M:%S %p"
729# define HERE_T_FMT "%H:%M:%S"
730
731/* __mon_yday[][] is common to mktime and strptime implementations.
732 --abbotti */
733const unsigned short int __mon_yday[2][13];
734# ifndef NEED_MON_YDAY
735# define NEED_MON_YDAY
736# endif
737#endif
738
739/* Status of lookup: do we use the locale data or the raw data? */
740enum locale_status { not, loc, raw };
741
742
743#ifndef __isleap
744/* Nonzero if YEAR is a leap year (every 4 years,
745 except every 100th isn't, and every 400th is). */
746# define __isleap(year) \
747 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
748#endif
749
750/* Compute the day of the week. */
751static void
752day_of_the_week (struct tm *tm)
753{
754 /* We know that January 1st 1970 was a Thursday (= 4). Compute the
755 the difference between this data in the one on TM and so determine
756 the weekday. */
757 int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2);
758 int wday = (-473
759 + (365 * (tm->tm_year - 70))
760 + (corr_year / 4)
761 - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0)
762 + (((corr_year / 4) / 25) / 4)
763 + __mon_yday[0][tm->tm_mon]
764 + tm->tm_mday - 1);
765 tm->tm_wday = ((wday % 7) + 7) % 7;
766}
767
768/* Compute the day of the year. */
769static void
770day_of_the_year (struct tm *tm)
771{
772 tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon]
773 + (tm->tm_mday - 1));
774}
775
776static char *
777#ifdef _LIBC
778internal_function
779#endif
780strptime_internal __P ((const char *buf, const char *format, struct tm *tm,
781 enum locale_status *decided));
782
783static char *
784#ifdef _LIBC
785internal_function
786#endif
787strptime_internal (rp, fmt, tm, decided)
788 const char *rp;
789 const char *fmt;
790 struct tm *tm;
791 enum locale_status *decided;
792{
793#ifdef _NL_CURRENT
794 const char *rp_backup;
795#endif
796 int cnt;
797 size_t val;
798 int have_I, is_pm;
799 int century, want_century;
800 int have_wday, want_xday;
801 int have_yday;
802 int have_mon, have_mday;
803
804 have_I = is_pm = 0;
805 century = -1;
806 want_century = 0;
807 have_wday = want_xday = have_yday = have_mon = have_mday = 0;
808
809 while (*fmt != '\0')
810 {
811 /* A white space in the format string matches 0 more or white
812 space in the input string. */
813 if (ISSPACE (*fmt))
814 {
815 while (ISSPACE (*rp))
816 ++rp;
817 ++fmt;
818 continue;
819 }
820
821 /* Any character but `%' must be matched by the same character
822 in the iput string. */
823 if (*fmt != '%')
824 {
825 match_char (*fmt++, *rp++);
826 continue;
827 }
828
829 ++fmt;
830#ifndef _NL_CURRENT
831 /* We need this for handling the `E' modifier. */
832 start_over:
833#endif
834
835#ifdef _NL_CURRENT
836 /* Make back up of current processing pointer. */
837 rp_backup = rp;
838#endif
839
840 switch (*fmt++)
841 {
842 case '%':
843 /* Match the `%' character itself. */
844 match_char ('%', *rp++);
845 break;
846 case 'a':
847 case 'A':
848 /* Match day of week. */
849 for (cnt = 0; cnt < 7; ++cnt)
850 {
851#ifdef _NL_CURRENT
852 if (*decided !=raw)
853 {
854 if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp))
855 {
856 if (*decided == not
857 && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt),
858 weekday_name[cnt]))
859 *decided = loc;
860 break;
861 }
862 if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp))
863 {
864 if (*decided == not
865 && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt),
866 ab_weekday_name[cnt]))
867 *decided = loc;
868 break;
869 }
870 }
871#endif
872 if (*decided != loc
873 && (match_string (weekday_name[cnt], rp)
874 || match_string (ab_weekday_name[cnt], rp)))
875 {
876 *decided = raw;
877 break;
878 }
879 }
880 if (cnt == 7)
881 /* Does not match a weekday name. */
882 return NULL;
883 tm->tm_wday = cnt;
884 have_wday = 1;
885 break;
886 case 'b':
887 case 'B':
888 case 'h':
889 /* Match month name. */
890 for (cnt = 0; cnt < 12; ++cnt)
891 {
892#ifdef _NL_CURRENT
893 if (*decided !=raw)
894 {
895 if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp))
896 {
897 if (*decided == not
898 && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt),
899 month_name[cnt]))
900 *decided = loc;
901 break;
902 }
903 if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp))
904 {
905 if (*decided == not
906 && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt),
907 ab_month_name[cnt]))
908 *decided = loc;
909 break;
910 }
911 }
912#endif
913 if (match_string (month_name[cnt], rp)
914 || match_string (ab_month_name[cnt], rp))
915 {
916 *decided = raw;
917 break;
918 }
919 }
920 if (cnt == 12)
921 /* Does not match a month name. */
922 return NULL;
923 tm->tm_mon = cnt;
924 want_xday = 1;
925 break;
926 case 'c':
927 /* Match locale's date and time format. */
928#ifdef _NL_CURRENT
929 if (*decided != raw)
930 {
931 if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT)))
932 {
933 if (*decided == loc)
934 return NULL;
935 else
936 rp = rp_backup;
937 }
938 else
939 {
940 if (*decided == not &&
941 strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT))
942 *decided = loc;
943 want_xday = 1;
944 break;
945 }
946 *decided = raw;
947 }
948#endif
949 if (!recursive (HERE_D_T_FMT))
950 return NULL;
951 want_xday = 1;
952 break;
953 case 'C':
954 /* Match century number. */
955 get_number (0, 99, 2);
956 century = val;
957 want_xday = 1;
958 break;
959 case 'd':
960 case 'e':
961 /* Match day of month. */
962 get_number (1, 31, 2);
963 tm->tm_mday = val;
964 have_mday = 1;
965 want_xday = 1;
966 break;
967 case 'F':
968 if (!recursive ("%Y-%m-%d"))
969 return NULL;
970 want_xday = 1;
971 break;
972 case 'x':
973#ifdef _NL_CURRENT
974 if (*decided != raw)
975 {
976 if (!recursive (_NL_CURRENT (LC_TIME, D_FMT)))
977 {
978 if (*decided == loc)
979 return NULL;
980 else
981 rp = rp_backup;
982 }
983 else
984 {
985 if (*decided == not
986 && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT))
987 *decided = loc;
988 want_xday = 1;
989 break;
990 }
991 *decided = raw;
992 }
993#endif
994 /* Fall through. */
995 case 'D':
996 /* Match standard day format. */
997 if (!recursive (HERE_D_FMT))
998 return NULL;
999 want_xday = 1;
1000 break;
1001 case 'k':
1002 case 'H':
1003 /* Match hour in 24-hour clock. */
1004 get_number (0, 23, 2);
1005 tm->tm_hour = val;
1006 have_I = 0;
1007 break;
1008 case 'I':
1009 /* Match hour in 12-hour clock. */
1010 get_number (1, 12, 2);
1011 tm->tm_hour = val % 12;
1012 have_I = 1;
1013 break;
1014 case 'j':
1015 /* Match day number of year. */
1016 get_number (1, 366, 3);
1017 tm->tm_yday = val - 1;
1018 have_yday = 1;
1019 break;
1020 case 'm':
1021 /* Match number of month. */
1022 get_number (1, 12, 2);
1023 tm->tm_mon = val - 1;
1024 have_mon = 1;
1025 want_xday = 1;
1026 break;
1027 case 'M':
1028 /* Match minute. */
1029 get_number (0, 59, 2);
1030 tm->tm_min = val;
1031 break;
1032 case 'n':
1033 case 't':
1034 /* Match any white space. */
1035 while (ISSPACE (*rp))
1036 ++rp;
1037 break;
1038 case 'p':
1039 /* Match locale's equivalent of AM/PM. */
1040#ifdef _NL_CURRENT
1041 if (*decided != raw)
1042 {
1043 if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp))
1044 {
1045 if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR))
1046 *decided = loc;
1047 break;
1048 }
1049 if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp))
1050 {
1051 if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR))
1052 *decided = loc;
1053 is_pm = 1;
1054 break;
1055 }
1056 *decided = raw;
1057 }
1058#endif
1059 if (!match_string (HERE_AM_STR, rp))
1060 if (match_string (HERE_PM_STR, rp))
1061 is_pm = 1;
1062 else
1063 return NULL;
1064 break;
1065 case 'r':
1066#ifdef _NL_CURRENT
1067 if (*decided != raw)
1068 {
1069 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM)))
1070 {
1071 if (*decided == loc)
1072 return NULL;
1073 else
1074 rp = rp_backup;
1075 }
1076 else
1077 {
1078 if (*decided == not &&
1079 strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM),
1080 HERE_T_FMT_AMPM))
1081 *decided = loc;
1082 break;
1083 }
1084 *decided = raw;
1085 }
1086#endif
1087 if (!recursive (HERE_T_FMT_AMPM))
1088 return NULL;
1089 break;
1090 case 'R':
1091 if (!recursive ("%H:%M"))
1092 return NULL;
1093 break;
1094 case 's':
1095 {
1096 /* The number of seconds may be very high so we cannot use
1097 the `get_number' macro. Instead read the number
1098 character for character and construct the result while
1099 doing this. */
1100 time_t secs = 0;
1101 if (*rp < '0' || *rp > '9')
1102 /* We need at least one digit. */
1103 return NULL;
1104
1105 do
1106 {
1107 secs *= 10;
1108 secs += *rp++ - '0';
1109 }
1110 while (*rp >= '0' && *rp <= '9');
1111
1112 if (localtime_r (&secs, tm) == NULL)
1113 /* Error in function. */
1114 return NULL;
1115 }
1116 break;
1117 case 'S':
1118 get_number (0, 61, 2);
1119 tm->tm_sec = val;
1120 break;
1121 case 'X':
1122#ifdef _NL_CURRENT
1123 if (*decided != raw)
1124 {
1125 if (!recursive (_NL_CURRENT (LC_TIME, T_FMT)))
1126 {
1127 if (*decided == loc)
1128 return NULL;
1129 else
1130 rp = rp_backup;
1131 }
1132 else
1133 {
1134 if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT))
1135 *decided = loc;
1136 break;
1137 }
1138 *decided = raw;
1139 }
1140#endif
1141 /* Fall through. */
1142 case 'T':
1143 if (!recursive (HERE_T_FMT))
1144 return NULL;
1145 break;
1146 case 'u':
1147 get_number (1, 7, 1);
1148 tm->tm_wday = val % 7;
1149 have_wday = 1;
1150 break;
1151 case 'g':
1152 get_number (0, 99, 2);
1153 /* XXX This cannot determine any field in TM. */
1154 break;
1155 case 'G':
1156 if (*rp < '0' || *rp > '9')
1157 return NULL;
1158 /* XXX Ignore the number since we would need some more
1159 information to compute a real date. */
1160 do
1161 ++rp;
1162 while (*rp >= '0' && *rp <= '9');
1163 break;
1164 case 'U':
1165 case 'V':
1166 case 'W':
1167 get_number (0, 53, 2);
1168 /* XXX This cannot determine any field in TM without some
1169 information. */
1170 break;
1171 case 'w':
1172 /* Match number of weekday. */
1173 get_number (0, 6, 1);
1174 tm->tm_wday = val;
1175 have_wday = 1;
1176 break;
1177 case 'y':
1178 /* Match year within century. */
1179 get_number (0, 99, 2);
1180 /* The "Year 2000: The Millennium Rollover" paper suggests that
1181 values in the range 69-99 refer to the twentieth century. */
1182 tm->tm_year = val >= 69 ? val : val + 100;
1183 /* Indicate that we want to use the century, if specified. */
1184 want_century = 1;
1185 want_xday = 1;
1186 break;
1187 case 'Y':
1188 /* Match year including century number. */
1189 get_number (0, 9999, 4);
1190 tm->tm_year = val - 1900;
1191 want_century = 0;
1192 want_xday = 1;
1193 break;
1194 case 'Z':
1195 /* XXX How to handle this? */
1196 break;
1197 case 'E':
1198#ifdef _NL_CURRENT
1199 switch (*fmt++)
1200 {
1201 case 'c':
1202 /* Match locale's alternate date and time format. */
1203 if (*decided != raw)
1204 {
1205 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT);
1206
1207 if (*fmt == '\0')
1208 fmt = _NL_CURRENT (LC_TIME, D_T_FMT);
1209
1210 if (!recursive (fmt))
1211 {
1212 if (*decided == loc)
1213 return NULL;
1214 else
1215 rp = rp_backup;
1216 }
1217 else
1218 {
1219 if (strcmp (fmt, HERE_D_T_FMT))
1220 *decided = loc;
1221 want_xday = 1;
1222 break;
1223 }
1224 *decided = raw;
1225 }
1226 /* The C locale has no era information, so use the
1227 normal representation. */
1228 if (!recursive (HERE_D_T_FMT))
1229 return NULL;
1230 want_xday = 1;
1231 break;
1232 case 'C':
1233 case 'y':
1234 case 'Y':
1235 /* Match name of base year in locale's alternate
1236 representation. */
1237 /* XXX This is currently not implemented. It should
1238 use the value _NL_CURRENT (LC_TIME, ERA). */
1239 break;
1240 case 'x':
1241 if (*decided != raw)
1242 {
1243 const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT);
1244
1245 if (*fmt == '\0')
1246 fmt = _NL_CURRENT (LC_TIME, D_FMT);
1247
1248 if (!recursive (fmt))
1249 {
1250 if (*decided == loc)
1251 return NULL;
1252 else
1253 rp = rp_backup;
1254 }
1255 else
1256 {
1257 if (strcmp (fmt, HERE_D_FMT))
1258 *decided = loc;
1259 break;
1260 }
1261 *decided = raw;
1262 }
1263 if (!recursive (HERE_D_FMT))
1264 return NULL;
1265 break;
1266 case 'X':
1267 if (*decided != raw)
1268 {
1269 const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT);
1270
1271 if (*fmt == '\0')
1272 fmt = _NL_CURRENT (LC_TIME, T_FMT);
1273
1274 if (!recursive (fmt))
1275 {
1276 if (*decided == loc)
1277 return NULL;
1278 else
1279 rp = rp_backup;
1280 }
1281 else
1282 {
1283 if (strcmp (fmt, HERE_T_FMT))
1284 *decided = loc;
1285 break;
1286 }
1287 *decided = raw;
1288 }
1289 if (!recursive (HERE_T_FMT))
1290 return NULL;
1291 break;
1292 default:
1293 return NULL;
1294 }
1295 break;
1296#else
1297 /* We have no information about the era format. Just use
1298 the normal format. */
1299 if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y'
1300 && *fmt != 'x' && *fmt != 'X')
1301 /* This is an illegal format. */
1302 return NULL;
1303
1304 goto start_over;
1305#endif
1306 case 'O':
1307 switch (*fmt++)
1308 {
1309 case 'd':
1310 case 'e':
1311 /* Match day of month using alternate numeric symbols. */
1312 get_alt_number (1, 31, 2);
1313 tm->tm_mday = val;
1314 have_mday = 1;
1315 want_xday = 1;
1316 break;
1317 case 'H':
1318 /* Match hour in 24-hour clock using alternate numeric
1319 symbols. */
1320 get_alt_number (0, 23, 2);
1321 tm->tm_hour = val;
1322 have_I = 0;
1323 break;
1324 case 'I':
1325 /* Match hour in 12-hour clock using alternate numeric
1326 symbols. */
1327 get_alt_number (1, 12, 2);
1328 tm->tm_hour = val - 1;
1329 have_I = 1;
1330 break;
1331 case 'm':
1332 /* Match month using alternate numeric symbols. */
1333 get_alt_number (1, 12, 2);
1334 tm->tm_mon = val - 1;
1335 have_mon = 1;
1336 want_xday = 1;
1337 break;
1338 case 'M':
1339 /* Match minutes using alternate numeric symbols. */
1340 get_alt_number (0, 59, 2);
1341 tm->tm_min = val;
1342 break;
1343 case 'S':
1344 /* Match seconds using alternate numeric symbols. */
1345 get_alt_number (0, 61, 2);
1346 tm->tm_sec = val;
1347 break;
1348 case 'U':
1349 case 'V':
1350 case 'W':
1351 get_alt_number (0, 53, 2);
1352 /* XXX This cannot determine any field in TM without
1353 further information. */
1354 break;
1355 case 'w':
1356 /* Match number of weekday using alternate numeric symbols. */
1357 get_alt_number (0, 6, 1);
1358 tm->tm_wday = val;
1359 have_wday = 1;
1360 break;
1361 case 'y':
1362 /* Match year within century using alternate numeric symbols. */
1363 get_alt_number (0, 99, 2);
1364 tm->tm_year = val >= 69 ? val : val + 100;
1365 want_xday = 1;
1366 break;
1367 default:
1368 return NULL;
1369 }
1370 break;
1371 default:
1372 return NULL;
1373 }
1374 }
1375
1376 if (have_I && is_pm)
1377 tm->tm_hour += 12;
1378
1379 if (century != -1)
1380 {
1381 if (want_century)
1382 tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;
1383 else
1384 /* Only the century, but not the year. Strange, but so be it. */
1385 tm->tm_year = (century - 19) * 100;
1386 }
1387
1388 if (want_xday && !have_wday) {
1389 if ( !(have_mon && have_mday) && have_yday) {
1390 /* we don't have tm_mon and/or tm_mday, compute them */
1391 int t_mon = 0;
1392 while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
1393 t_mon++;
1394 if (!have_mon)
1395 tm->tm_mon = t_mon - 1;
1396 if (!have_mday)
1397 tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1;
1398 }
1399 day_of_the_week (tm);
1400 }
1401 if (want_xday && !have_yday)
1402 day_of_the_year (tm);
1403
1404 return (char *) rp;
1405}
1406
1407
1408char *
1409strptime (buf, format, tm)
1410 const char *buf;
1411 const char *format;
1412 struct tm *tm;
1413{
1414 enum locale_status decided;
1415#ifdef _NL_CURRENT
1416 decided = not;
1417#else
1418 decided = raw;
1419#endif
1420 return strptime_internal (buf, format, tm, &decided);
1421}
1422#endif /* not HAVE_STRPTIME */
1423
1424#ifdef NEED_MON_YDAY
1425/* __mon_yday[][] is common to mktime and strptime implementations.
1426 --abbotti */
1427const unsigned short int __mon_yday[2][13] =
1428 {
1429 /* Normal years. */
1430 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
1431 /* Leap years. */
1432 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
1433 };
1434#endif
1435
1436#ifndef HAVE_MEMMOVE
1437void *
1438memmove (char *dest, const char *source, unsigned length)
1439{
1440 char *d0 = dest;
1441 if (source < dest)
1442 /* Moving from low mem to hi mem; start at end. */
1443 for (source += length, dest += length; length; --length)
1444 *--dest = *--source;
1445 else if (source != dest)
1446 {
1447 /* Moving from hi mem to low mem; start at beginning. */
1448 for (; length; --length)
1449 *dest++ = *source++;
1450 }
1451 return (void *) d0;
1452}
1453#endif /* not HAVE_MEMMOVE */
1454
1455/* fnmatch is a POSIX function, but we include an implementation for
1456 the sake of systems that don't have it. Furthermore, according to
1457 anecdotal evidence, historical implementations of fnmatch are buggy
1458 and unreliable. So we use our version, except when compiling under
1459 systems where fnmatch is known to work (currently glibc.) */
1460
1461#ifndef SYSTEM_FNMATCH
1462
1463#define __FNM_FLAGS (FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD)
1464
1465/* Match STRING against the filename pattern PATTERN, returning zero
1466 if it matches, FNM_NOMATCH if not. This implementation comes from
1467 an earlier version of GNU Bash. (It doesn't make sense to update
1468 it with a newer version because it adds a lot of features Wget
1469 doesn't use or care about.) */
1470
1471int
1472fnmatch (const char *pattern, const char *string, int flags)
1473{
1474 register const char *p = pattern, *n = string;
1475 register char c;
1476
1477 if ((flags & ~__FNM_FLAGS) != 0)
1478 {
1479 errno = EINVAL;
1480 return (-1);
1481 }
1482
1483 while ((c = *p++) != '\0')
1484 {
1485 switch (c)
1486 {
1487 case '?':
1488 if (*n == '\0')
1489 return (FNM_NOMATCH);
1490 else if ((flags & FNM_PATHNAME) && *n == '/')
1491 return (FNM_NOMATCH);
1492 else if ((flags & FNM_PERIOD) && *n == '.' &&
1493 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1494 return (FNM_NOMATCH);
1495 break;
1496
1497 case '\\':
1498 if (!(flags & FNM_NOESCAPE))
1499 c = *p++;
1500 if (*n != c)
1501 return (FNM_NOMATCH);
1502 break;
1503
1504 case '*':
1505 if ((flags & FNM_PERIOD) && *n == '.' &&
1506 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1507 return (FNM_NOMATCH);
1508
1509 for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
1510 if (((flags & FNM_PATHNAME) && *n == '/') ||
1511 (c == '?' && *n == '\0'))
1512 return (FNM_NOMATCH);
1513
1514 if (c == '\0')
1515 return (0);
1516
1517 {
1518 char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
1519 for (--p; *n != '\0'; ++n)
1520 if ((c == '[' || *n == c1) &&
1521 fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
1522 return (0);
1523 return (FNM_NOMATCH);
1524 }
1525
1526 case '[':
1527 {
1528 /* Nonzero if the sense of the character class is
1529 inverted. */
1530 register int not;
1531
1532 if (*n == '\0')
1533 return (FNM_NOMATCH);
1534
1535 if ((flags & FNM_PERIOD) && *n == '.' &&
1536 (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
1537 return (FNM_NOMATCH);
1538
1539 /* Make sure there is a closing `]'. If there isn't,
1540 the `[' is just a character to be matched. */
1541 {
1542 register const char *np;
1543
1544 for (np = p; np && *np && *np != ']'; np++);
1545
1546 if (np && !*np)
1547 {
1548 if (*n != '[')
1549 return (FNM_NOMATCH);
1550 goto next_char;
1551 }
1552 }
1553
1554 not = (*p == '!' || *p == '^');
1555 if (not)
1556 ++p;
1557
1558 c = *p++;
1559 while (1)
1560 {
1561 register char cstart = c, cend = c;
1562
1563 if (!(flags & FNM_NOESCAPE) && c == '\\')
1564 cstart = cend = *p++;
1565
1566 if (c == '\0')
1567 /* [ (unterminated) loses. */
1568 return (FNM_NOMATCH);
1569
1570 c = *p++;
1571
1572 if ((flags & FNM_PATHNAME) && c == '/')
1573 /* [/] can never match. */
1574 return (FNM_NOMATCH);
1575
1576 if (c == '-' && *p != ']')
1577 {
1578 cend = *p++;
1579 if (!(flags & FNM_NOESCAPE) && cend == '\\')
1580 cend = *p++;
1581 if (cend == '\0')
1582 return (FNM_NOMATCH);
1583 c = *p++;
1584 }
1585
1586 if (*n >= cstart && *n <= cend)
1587 goto matched;
1588
1589 if (c == ']')
1590 break;
1591 }
1592 if (!not)
1593 return (FNM_NOMATCH);
1594
1595 next_char:
1596 break;
1597
1598 matched:
1599 /* Skip the rest of the [...] that already matched. */
1600 while (c != ']')
1601 {
1602 if (c == '\0')
1603 /* [... (unterminated) loses. */
1604 return (FNM_NOMATCH);
1605
1606 c = *p++;
1607 if (!(flags & FNM_NOESCAPE) && c == '\\')
1608 /* 1003.2d11 is unclear if this is right. %%% */
1609 ++p;
1610 }
1611 if (not)
1612 return (FNM_NOMATCH);
1613 }
1614 break;
1615
1616 default:
1617 if (c != *n)
1618 return (FNM_NOMATCH);
1619 }
1620
1621 ++n;
1622 }
1623
1624 if (*n == '\0')
1625 return (0);
1626
1627 return (FNM_NOMATCH);
1628}
1629
1630#endif /* not SYSTEM_FNMATCH */
1631
1632
1633#ifndef HAVE_TIMEGM
1634/* timegm is a GNU extension, but lately also available on *BSD
1635 systems and possibly elsewhere. */
1636
1637/* True if YEAR is a leap year. */
1638#define ISLEAP(year) \
1639 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
1640
1641/* Number of leap years in the range [y1, y2). */
1642#define LEAPYEARS(y1, y2) \
1643 ((y2-1)/4 - (y1-1)/4) - ((y2-1)/100 - (y1-1)/100) + ((y2-1)/400 - (y1-1)/400)
1644
1645/* Inverse of gmtime: converts struct tm to time_t, assuming the data
1646 in tm is UTC rather than local timezone. This implementation
1647 returns the number of seconds elapsed since midnight 1970-01-01,
1648 converted to time_t. */
1649
1650time_t
1651timegm (struct tm *t)
1652{
1653 static const unsigned short int month_to_days[][13] = {
1654 { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, /* normal */
1655 { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 } /* leap */
1656 };
1657 const int year = 1900 + t->tm_year;
1658 unsigned long secs; /* until 2106-02-07 for 32-bit unsigned long */
1659 int days;
1660
1661 if (year < 1970)
1662 return (time_t) -1;
1663
1664 days = 365 * (year - 1970);
1665 /* Take into account leap years between 1970 and YEAR, not counting
1666 YEAR itself. */
1667 days += LEAPYEARS (1970, year);
1668 if (t->tm_mon < 0 || t->tm_mon >= 12)
1669 return (time_t) -1;
1670 days += month_to_days[ISLEAP (year)][t->tm_mon];
1671 days += t->tm_mday - 1;
1672
1673 secs = days * 86400 + t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec;
1674 return (time_t) secs;
1675}
1676#endif /* HAVE_TIMEGM */
1677
1678#ifdef NEED_STRTOLL
1679/* strtoll is required by C99 and used by Wget only on systems with
1680 LFS. Unfortunately, some systems have LFS, but no strtoll or
1681 equivalent. These include HPUX 11.0 and Windows.
1682
1683 We use #ifdef NEED_STRTOLL instead of #ifndef HAVE_STRTOLL because
1684 of the systems which have a suitable replacement (e.g. _strtoi64 on
1685 Windows), on which Wget's str_to_wgint is instructed to use that
1686 instead. */
1687
1688static inline int
1689char_value (char c, int base)
1690{
1691 int value;
1692 if (c < '0')
1693 return -1;
1694 if ('0' <= c && c <= '9')
1695 value = c - '0';
1696 else if ('a' <= c && c <= 'z')
1697 value = c - 'a' + 10;
1698 else if ('A' <= c && c <= 'Z')
1699 value = c - 'A' + 10;
1700 else
1701 return -1;
1702 if (value >= base)
1703 return -1;
1704 return value;
1705}
1706
1707#define LL strtoll_return /* long long or __int64 */
1708
1709/* These constants assume 64-bit strtoll_return. */
1710
1711/* A roundabout way of writing 2**63-1 = 9223372036854775807 */
1712#define STRTOLL_OVERFLOW (((LL) 1 << 62) - 1 + ((LL) 1 << 62))
1713/* A roundabout way of writing -2**63 = -9223372036854775808 */
1714#define STRTOLL_UNDERFLOW (-STRTOLL_OVERFLOW - 1)
1715
1716/* A strtoll replacement for systems that have LFS but don't supply
1717 strtoll. The headers typedef strtoll_return to long long or to
1718 __int64. */
1719
1720strtoll_return
1721strtoll (const char *nptr, char **endptr, int base)
1722{
1723 strtoll_return result = 0;
1724 int negative;
1725
1726 if (base != 0 && (base < 2 || base > 36))
1727 {
1728 errno = EINVAL;
1729 return 0;
1730 }
1731
1732 while (*nptr == ' ' || *nptr == '\t')
1733 ++nptr;
1734 if (*nptr == '-')
1735 {
1736 negative = 1;
1737 ++nptr;
1738 }
1739 else if (*nptr == '+')
1740 {
1741 negative = 0;
1742 ++nptr;
1743 }
1744 else
1745 negative = 0;
1746
1747 /* If base is 0, determine the real base based on the beginning on
1748 the number; octal numbers begin with "0", hexadecimal with "0x",
1749 and the others are considered octal. */
1750 if (*nptr == '0')
1751 {
1752 if ((base == 0 || base == 16)
1753 &&
1754 (*(nptr + 1) == 'x' || *(nptr + 1) == 'X'))
1755 {
1756 base = 16;
1757 nptr += 2;
1758 }
1759 else if (base == 0)
1760 base = 8;
1761 }
1762 else if (base == 0)
1763 base = 10;
1764
1765 if (!negative)
1766 {
1767 /* Parse positive number, checking for overflow. */
1768 int val;
1769 for (; (val = char_value (*nptr, base)) != -1; ++nptr)
1770 {
1771 strtoll_return newresult = base * result + val;
1772 if (newresult < result)
1773 {
1774 result = STRTOLL_OVERFLOW;
1775 errno = ERANGE;
1776 break;
1777 }
1778 result = newresult;
1779 }
1780 }
1781 else
1782 {
1783 /* Parse negative number, checking for underflow. */
1784 int val;
1785 for (; (val = char_value (*nptr, base)) != -1; ++nptr)
1786 {
1787 strtoll_return newresult = base * result - val;
1788 if (newresult > result)
1789 {
1790 result = STRTOLL_UNDERFLOW;
1791 errno = ERANGE;
1792 break;
1793 }
1794 result = newresult;
1795 }
1796 }
1797 if (endptr)
1798 *endptr = (char *) nptr;
1799 return result;
1800}
1801#endif /* NEED_STRTOLL */
Note: See TracBrowser for help on using the repository browser.