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, 2009 Free Software Foundation, Inc. 4 5This file is part of GNU Wget. 6 7GNU Wget is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 3 of the License, or 10(at your option) any later version. 11 12GNU Wget is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with Wget. If not, see <http://www.gnu.org/licenses/>. 19 20Additional permission under GNU GPL version 3 section 7 21 22If you modify this program, or any covered work, by linking or 23combining it with the OpenSSL project's OpenSSL library (or a 24modified version of that library), containing parts covered by the 25terms of the OpenSSL or SSLeay licenses, the Free Software Foundation 26grants you additional permission to convey the resulting work. 27Corresponding Source for a non-source form of such a combination 28shall include the source code for the parts of OpenSSL used as well 29as 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 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. */ 63int 64strcasecmp (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. */ 92int 93strncasecmp (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 119void * 120memrchr (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 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 160static struct tm *localtime_r __P ((const time_t *, struct tm *)); 161static struct tm * 162localtime_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. */ 310extern const struct locale_data _nl_C_LC_TIME; 311extern 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 328static char const weekday_name[][10] = 329 { 330 "Sunday", "Monday", "Tuesday", "Wednesday", 331 "Thursday", "Friday", "Saturday" 332 }; 333static char const ab_weekday_name[][4] = 334 { 335 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" 336 }; 337static char const month_name[][10] = 338 { 339 "January", "February", "March", "April", "May", "June", 340 "July", "August", "September", "October", "November", "December" 341 }; 342static 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 354const 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? */ 361enum 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. */ 372static void 373day_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. */ 390static void 391day_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 397static char * 398#ifdef _LIBC 399internal_function 400#endif 401strptime_internal __P ((const char *buf, const char *format, struct tm *tm, 402 enum locale_status *decided)); 403 404static char * 405#ifdef _LIBC 406internal_function 407#endif 408strptime_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 1031char * 1032strptime (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 1048const 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 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 1081int 1082fnmatch (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 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 1260time_t 1261timegm (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 1298static inline int 1299char_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 1329strtoll_type 1330strtoll (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 */ 1429