15ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/*************************************************************************** 25ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * _ _ ____ _ 35ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Project ___| | | | _ \| | 45ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * / __| | | | |_) | | 55ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * | (__| |_| | _ <| |___ 65ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * \___|\___/|_| \_\_____| 75ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 8cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. 95ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This software is licensed as described in the file COPYING, which 115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * you should have received as part of this distribution. The terms 128f1a214b8a21b66f33454790dfba97ae2f818289Alex Deymo * are also available at https://curl.haxx.se/docs/copyright.html. 135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * You may opt to use, copy, modify, merge, publish, distribute and/or sell 155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * copies of the Software, and permit persons to whom the Software is 165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * furnished to do so, under the terms of the COPYING file. 175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * KIND, either express or implied. 205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen ***************************************************************************/ 225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* 235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen A brief summary of the date string formats this parser groks: 245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen RFC 2616 3.3.1 265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036 295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format 305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen we support dates without week day name: 325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 06 Nov 1994 08:49:37 GMT 345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 06-Nov-94 08:49:37 GMT 355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen Nov 6 08:49:37 1994 365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen without the time zone: 385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 06 Nov 1994 08:49:37 405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 06-Nov-94 08:49:37 415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen weird order: 435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1994 Nov 6 08:49:37 (GNU date fails) 455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen GMT 08:49:37 06-Nov-94 Sunday 465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 94 6 Nov 08:49:37 (GNU date fails) 475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen time left out: 495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1994 Nov 6 515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 06-Nov-94 525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen Sun Nov 6 94 535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen unusual separators: 555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1994.Nov.6 575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen Sun/Nov/6/94/GMT 585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen commonly used time zone names: 605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen Sun, 06 Nov 1994 08:49:37 CET 625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 06 Nov 1994 08:49:37 EST 635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen time zones specified using RFC822 style: 655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen Sun, 12 Sep 2004 15:05:58 -0700 675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen Sat, 11 Sep 2004 21:32:11 +0200 685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen compact numerical date strings: 705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 20040912 15:05:58 -0700 725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 20040911 +0200 735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen*/ 755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 76e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curl_setup.h" 77e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 78e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef HAVE_LIMITS_H 79e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include <limits.h> 805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#endif 815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include <curl/curl.h> 83cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes#include "strcase.h" 84e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "warnless.h" 855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#include "parsedate.h" 865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenconst char * const Curl_wkday[] = 885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; 895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic const char * const weekday[] = 905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ "Monday", "Tuesday", "Wednesday", "Thursday", 915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen "Friday", "Saturday", "Sunday" }; 925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenconst char * const Curl_month[]= 935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", 945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; 955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstruct tzinfo { 975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char name[5]; 985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int offset; /* +/- in minutes */ 995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}; 1005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 101e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* 102e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * parsedate() 103e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 104e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Returns: 105e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 106e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * PARSEDATE_OK - a fine conversion 107e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * PARSEDATE_FAIL - failed to convert 108e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * PARSEDATE_LATER - time overflow at the far end of time_t 109e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * PARSEDATE_SOONER - time underflow at the low end of time_t 110e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 111e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 112e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int parsedate(const char *date, time_t *output); 113e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 114e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define PARSEDATE_OK 0 115e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define PARSEDATE_FAIL -1 116e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define PARSEDATE_LATER 1 117e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define PARSEDATE_SOONER 2 118e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 1195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* Here's a bunch of frequently used time zone names. These were supported 1205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen by the old getdate parser. */ 1215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen#define tDAYZONE -60 /* offset for daylight savings time */ 1225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic const struct tzinfo tz[]= { 1235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"GMT", 0}, /* Greenwich Mean */ 1245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"UTC", 0}, /* Universal (Coordinated) */ 1255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"WET", 0}, /* Western European */ 1265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"BST", 0 tDAYZONE}, /* British Summer */ 1275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"WAT", 60}, /* West Africa */ 1285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"AST", 240}, /* Atlantic Standard */ 1295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"ADT", 240 tDAYZONE}, /* Atlantic Daylight */ 1305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"EST", 300}, /* Eastern Standard */ 1315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"EDT", 300 tDAYZONE}, /* Eastern Daylight */ 1325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"CST", 360}, /* Central Standard */ 1335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"CDT", 360 tDAYZONE}, /* Central Daylight */ 1345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"MST", 420}, /* Mountain Standard */ 1355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"MDT", 420 tDAYZONE}, /* Mountain Daylight */ 1365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"PST", 480}, /* Pacific Standard */ 1375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"PDT", 480 tDAYZONE}, /* Pacific Daylight */ 1385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"YST", 540}, /* Yukon Standard */ 1395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"YDT", 540 tDAYZONE}, /* Yukon Daylight */ 1405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"HST", 600}, /* Hawaii Standard */ 1415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"HDT", 600 tDAYZONE}, /* Hawaii Daylight */ 1425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"CAT", 600}, /* Central Alaska */ 1435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"AHST", 600}, /* Alaska-Hawaii Standard */ 1445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"NT", 660}, /* Nome */ 1455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"IDLW", 720}, /* International Date Line West */ 1465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"CET", -60}, /* Central European */ 1475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"MET", -60}, /* Middle European */ 1485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"MEWT", -60}, /* Middle European Winter */ 1495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"MEST", -60 tDAYZONE}, /* Middle European Summer */ 1505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"CEST", -60 tDAYZONE}, /* Central European Summer */ 1515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"MESZ", -60 tDAYZONE}, /* Middle European Summer */ 1525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"FWT", -60}, /* French Winter */ 1535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"FST", -60 tDAYZONE}, /* French Summer */ 1545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"EET", -120}, /* Eastern Europe, USSR Zone 1 */ 1555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"WAST", -420}, /* West Australian Standard */ 1565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"WADT", -420 tDAYZONE}, /* West Australian Daylight */ 1575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"CCT", -480}, /* China Coast, USSR Zone 7 */ 1585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"JST", -540}, /* Japan Standard, USSR Zone 8 */ 1595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"EAST", -600}, /* Eastern Australian Standard */ 1605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"EADT", -600 tDAYZONE}, /* Eastern Australian Daylight */ 1615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"GST", -600}, /* Guam Standard, USSR Zone 9 */ 1625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"NZT", -720}, /* New Zealand */ 1635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"NZST", -720}, /* New Zealand Standard */ 1645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"NZDT", -720 tDAYZONE}, /* New Zealand Daylight */ 1655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"IDLE", -720}, /* International Date Line East */ 1665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Next up: Military timezone names. RFC822 allowed these, but (as noted in 1675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen RFC 1123) had their signs wrong. Here we use the correct signs to match 1685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen actual military usage. 1695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 1705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"A", +1 * 60}, /* Alpha */ 1715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"B", +2 * 60}, /* Bravo */ 1725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"C", +3 * 60}, /* Charlie */ 1735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"D", +4 * 60}, /* Delta */ 1745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"E", +5 * 60}, /* Echo */ 1755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"F", +6 * 60}, /* Foxtrot */ 1765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"G", +7 * 60}, /* Golf */ 1775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"H", +8 * 60}, /* Hotel */ 1785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"I", +9 * 60}, /* India */ 179e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* "J", Juliet is not used as a timezone, to indicate the observer's local 180e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET time */ 1815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"K", +10 * 60}, /* Kilo */ 1825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"L", +11 * 60}, /* Lima */ 1835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"M", +12 * 60}, /* Mike */ 1845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"N", -1 * 60}, /* November */ 1855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"O", -2 * 60}, /* Oscar */ 1865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"P", -3 * 60}, /* Papa */ 1875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"Q", -4 * 60}, /* Quebec */ 1885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"R", -5 * 60}, /* Romeo */ 1895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"S", -6 * 60}, /* Sierra */ 1905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"T", -7 * 60}, /* Tango */ 1915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"U", -8 * 60}, /* Uniform */ 1925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"V", -9 * 60}, /* Victor */ 1935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"W", -10 * 60}, /* Whiskey */ 1945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"X", -11 * 60}, /* X-ray */ 1955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"Y", -12 * 60}, /* Yankee */ 1965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen {"Z", 0}, /* Zulu, zero meridian, a.k.a. UTC */ 1975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}; 1985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 1995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* returns: 2005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen -1 no day 2015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 0 monday - 6 sunday 2025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen*/ 2035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic int checkday(const char *check, size_t len) 2055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 2065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int i; 2075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen const char * const *what; 2085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen bool found= FALSE; 2095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(len > 3) 2105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen what = &weekday[0]; 2115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else 2125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen what = &Curl_wkday[0]; 2135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen for(i=0; i<7; i++) { 214cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes if(strcasecompare(check, what[0])) { 2155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen found=TRUE; 2165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen break; 2175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 2185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen what++; 2195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 2205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return found?i:-1; 2215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 2225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic int checkmonth(const char *check) 2245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 2255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int i; 2265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen const char * const *what; 2275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen bool found= FALSE; 2285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen what = &Curl_month[0]; 2305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen for(i=0; i<12; i++) { 231cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes if(strcasecompare(check, what[0])) { 2325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen found=TRUE; 2335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen break; 2345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 2355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen what++; 2365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 2375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return found?i:-1; /* return the offset or -1, no real offset is -1 */ 2385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 2395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* return the time zone offset between GMT and the input one, in number 2415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen of seconds or -1 if the timezone wasn't found/legal */ 2425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic int checktz(const char *check) 2445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 2455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen unsigned int i; 2465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen const struct tzinfo *what; 2475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen bool found= FALSE; 2485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen what = tz; 2505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen for(i=0; i< sizeof(tz)/sizeof(tz[0]); i++) { 251cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes if(strcasecompare(check, what->name)) { 2525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen found=TRUE; 2535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen break; 2545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 2555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen what++; 2565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 2575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return found?what->offset*60:-1; 2585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 2595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic void skip(const char **date) 2615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 2625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* skip everything that aren't letters or digits */ 2635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen while(**date && !ISALNUM(**date)) 2645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen (*date)++; 2655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 2665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenenum assume { 2685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen DATE_MDAY, 2695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen DATE_YEAR, 2705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen DATE_TIME 2715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}; 2725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* this is a clone of 'struct tm' but with all fields we don't need or use 2745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen cut out */ 2755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstruct my_tm { 2765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int tm_sec; 2775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int tm_min; 2785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int tm_hour; 2795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int tm_mday; 2805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int tm_mon; 2815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int tm_year; 2825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen}; 2835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* struct tm to time since epoch in GMT time zone. 2855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * This is similar to the standard mktime function but for GMT only, and 2865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * doesn't suffer from the various bugs and portability problems that 2875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * some systems' implementations have. 2885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 2895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsenstatic time_t my_timegm(struct my_tm *tm) 2905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 2915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen static const int month_days_cumulative [12] = 2925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; 2935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int month, year, leap_days; 2945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 2955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(tm->tm_year < 70) 2965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* we don't support years before 1970 as they will cause this function 2975ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen to return a negative value */ 2985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return -1; 2995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 3005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen year = tm->tm_year + 1900; 3015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen month = tm->tm_mon; 302e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(month < 0) { 3035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen year += (11 - month) / 12; 3045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen month = 11 - (11 - month) % 12; 3055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 306e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else if(month >= 12) { 3075ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen year -= month / 12; 3085ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen month = month % 12; 3095ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 3105ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 3115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen leap_days = year - (tm->tm_mon <= 1); 3125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen leap_days = ((leap_days / 4) - (leap_days / 100) + (leap_days / 400) 3135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen - (1969 / 4) + (1969 / 100) - (1969 / 400)); 3145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 3155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return ((((time_t) (year - 1970) * 365 3165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen + leap_days + month_days_cumulative [month] + tm->tm_mday - 1) * 24 3175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec; 3185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 3195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 3205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen/* 321e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * parsedate() 3225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 3235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * Returns: 3245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * 3255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * PARSEDATE_OK - a fine conversion 3265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * PARSEDATE_FAIL - failed to convert 3275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * PARSEDATE_LATER - time overflow at the far end of time_t 3285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen * PARSEDATE_SOONER - time underflow at the low end of time_t 3295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 3305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 331e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int parsedate(const char *date, time_t *output) 3325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 3335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen time_t t = 0; 3345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int wdaynum=-1; /* day of the week number, 0-6 (mon-sun) */ 3355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int monnum=-1; /* month of the year number, 0-11 */ 3365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int mdaynum=-1; /* day of month, 1 - 31 */ 3375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int hournum=-1; 3385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int minnum=-1; 3395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int secnum=-1; 3405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int yearnum=-1; 3415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int tzoff=-1; 3425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen struct my_tm tm; 3435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen enum assume dignext = DATE_MDAY; 3445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen const char *indate = date; /* save the original pointer */ 3455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int part = 0; /* max 6 parts */ 3465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 3475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen while(*date && (part < 6)) { 3485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen bool found=FALSE; 3495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 3505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen skip(&date); 3515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 3525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(ISALPHA(*date)) { 3535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* a name coming up */ 3545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char buf[32]=""; 3555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen size_t len; 356e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(sscanf(date, "%31[ABCDEFGHIJKLMNOPQRSTUVWXYZ" 357e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET "abcdefghijklmnopqrstuvwxyz]", buf)) 358e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET len = strlen(buf); 359e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else 360e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET len = 0; 3615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 3625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(wdaynum == -1) { 3635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen wdaynum = checkday(buf, len); 3645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(wdaynum != -1) 3655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen found = TRUE; 3665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 3675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!found && (monnum == -1)) { 3685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen monnum = checkmonth(buf); 3695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(monnum != -1) 3705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen found = TRUE; 3715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 3725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 3735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!found && (tzoff == -1)) { 3745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* this just must be a time zone string */ 3755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tzoff = checktz(buf); 3765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(tzoff != -1) 3775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen found = TRUE; 3785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 3795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 3805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!found) 3815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return PARSEDATE_FAIL; /* bad string */ 3825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 3835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen date += len; 3845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 3855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else if(ISDIGIT(*date)) { 3865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* a digit */ 3875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen int val; 3885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen char *end; 389cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes int len=0; 3905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if((secnum == -1) && 391cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes (3 == sscanf(date, "%02d:%02d:%02d%n", 392cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes &hournum, &minnum, &secnum, &len))) { 3935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* time stamp! */ 394cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes date += len; 3959bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels } 3969bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels else if((secnum == -1) && 397cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes (2 == sscanf(date, "%02d:%02d%n", &hournum, &minnum, &len))) { 3989bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels /* time stamp without seconds */ 399cee0338be80bb81b15101686d6f60864455f1e6eElliott Hughes date += len; 4009bd90e6e25f1e55f50201c87a1b5837de7e5b64aLucas Eckels secnum = 0; 4015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 4025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else { 403e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET long lval; 404e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int error; 405e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int old_errno; 406e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 407e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET old_errno = ERRNO; 408e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET SET_ERRNO(0); 409e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET lval = strtol(date, &end, 10); 410e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET error = ERRNO; 411e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(error != old_errno) 412e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET SET_ERRNO(old_errno); 413e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 414e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(error) 415e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return PARSEDATE_FAIL; 416e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 417e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#if LONG_MAX != INT_MAX 418e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if((lval > (long)INT_MAX) || (lval < (long)INT_MIN)) 419e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return PARSEDATE_FAIL; 420e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif 421e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 422e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET val = curlx_sltosi(lval); 4235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 4245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if((tzoff == -1) && 4255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen ((end - date) == 4) && 4265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen (val <= 1400) && 4275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen (indate< date) && 4285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen ((date[-1] == '+' || date[-1] == '-'))) { 4295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* four digits and a value less than or equal to 1400 (to take into 430e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET account all sorts of funny time zone diffs) and it is preceded 4315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen with a plus or minus. This is a time zone indication. 1400 is 4325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen picked since +1300 is frequently used and +1400 is mentioned as 4335ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen an edge number in the document "ISO C 200X Proposal: Timezone 4345ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen Functions" at http://david.tribble.com/text/c0xtimezone.html If 4355ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen anyone has a more authoritative source for the exact maximum time 4365ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen zone offsets, please speak up! */ 4375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen found = TRUE; 4385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tzoff = (val/100 * 60 + val%100)*60; 4395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 4405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* the + and - prefix indicates the local time compared to GMT, 4415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen this we need ther reversed math to get what we want */ 4425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tzoff = date[-1]=='+'?-tzoff:tzoff; 4435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 4445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 4455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(((end - date) == 8) && 4465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen (yearnum == -1) && 4475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen (monnum == -1) && 4485ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen (mdaynum == -1)) { 4495ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* 8 digits, no year, month or day yet. This is YYYYMMDD */ 4505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen found = TRUE; 4515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen yearnum = val/10000; 4525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen monnum = (val%10000)/100-1; /* month is 0 - 11 */ 4535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen mdaynum = val%100; 4545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 4555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 4565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!found && (dignext == DATE_MDAY) && (mdaynum == -1)) { 4575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if((val > 0) && (val<32)) { 4585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen mdaynum = val; 4595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen found = TRUE; 4605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 4615ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen dignext = DATE_YEAR; 4625ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 4635ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 4645ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!found && (dignext == DATE_YEAR) && (yearnum == -1)) { 4655ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen yearnum = val; 4665ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen found = TRUE; 4675ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(yearnum < 1900) { 4685ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(yearnum > 70) 4695ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen yearnum += 1900; 4705ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen else 4715ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen yearnum += 2000; 4725ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 4735ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(mdaynum == -1) 4745ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen dignext = DATE_MDAY; 4755ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 4765ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 4775ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(!found) 4785ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return PARSEDATE_FAIL; 4795ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 4805ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen date = end; 4815ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 4825ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 4835ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 4845ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen part++; 4855ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 4865ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 4875ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(-1 == secnum) 4885ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen secnum = minnum = hournum = 0; /* no time, make it zero */ 4895ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 4905ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if((-1 == mdaynum) || 4915ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen (-1 == monnum) || 4925ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen (-1 == yearnum)) 4935ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* lacks vital info, fail */ 4945ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return PARSEDATE_FAIL; 4955ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 4965ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* 32 bit time_t can only hold dates to the beginning of 2038 */ 4978eb97d044bca094e812492eb49a5cc1790cf1296Bertrand SIMONNET if(sizeof(time_t) < 5 && yearnum > 2037) { 4985ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *output = 0x7fffffff; 4995ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return PARSEDATE_LATER; 5005ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 5015ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 5025ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(yearnum < 1970) { 5035ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *output = 0; 5045ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return PARSEDATE_SOONER; 5055ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 5065ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 507e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if((mdaynum > 31) || (monnum > 11) || 508e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (hournum > 23) || (minnum > 59) || (secnum > 60)) 509e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return PARSEDATE_FAIL; /* clearly an illegal date */ 510e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 5115ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tm.tm_sec = secnum; 5125ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tm.tm_min = minnum; 5135ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tm.tm_hour = hournum; 5145ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tm.tm_mday = mdaynum; 5155ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tm.tm_mon = monnum; 5165ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen tm.tm_year = yearnum - 1900; 5175ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 5185ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* my_timegm() returns a time_t. time_t is often 32 bits, even on many 5195ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen architectures that feature 64 bit 'long'. 5205ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 5215ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen Some systems have 64 bit time_t and deal with years beyond 2038. However, 5225ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen even on some of the systems with 64 bit time_t mktime() returns -1 for 5235ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen dates beyond 03:14:07 UTC, January 19, 2038. (Such as AIX 5100-06) 5245ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen */ 5255ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen t = my_timegm(&tm); 5265ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 5275ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* time zone adjust (cast t to int to compare to negative one) */ 5285ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen if(-1 != (int)t) { 5295ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 5305ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* Add the time zone diff between local time zone and GMT. */ 5315ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen long delta = (long)(tzoff!=-1?tzoff:0); 5325ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 533e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if((delta>0) && (t > LONG_MAX - delta)) { 534e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *output = 0x7fffffff; 535e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return PARSEDATE_LATER; /* time_t overflow */ 536e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 5375ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 5385ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen t += delta; 5395ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 5405ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 5415ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen *output = t; 5425ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 5435ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return PARSEDATE_OK; 5445ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 5455ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 5465ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsentime_t curl_getdate(const char *p, const time_t *now) 5475ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen{ 548e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET time_t parsed = -1; 549e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int rc = parsedate(p, &parsed); 5505ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen (void)now; /* legacy argument from the past that we ignore */ 5515ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen 5525ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen switch(rc) { 5535ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen case PARSEDATE_OK: 5545ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen case PARSEDATE_LATER: 5555ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen case PARSEDATE_SOONER: 5565ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return parsed; 5575ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen } 5585ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen /* everything else is fail */ 5595ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen return -1; 5605ab5018bf8f0e39957d264f33c3eeddd958ed5d8Kristian Monsen} 561e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 562e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* 563e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Curl_gmtime() is a gmtime() replacement for portability. Do not use the 564e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * gmtime_r() or gmtime() functions anywhere else but here. 565e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 566e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 567e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 568e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETCURLcode Curl_gmtime(time_t intime, struct tm *store) 569e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 570e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const struct tm *tm; 571e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef HAVE_GMTIME_R 572e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* thread-safe version */ 573e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET tm = (struct tm *)gmtime_r(&intime, store); 574e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#else 575e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET tm = gmtime(&intime); 576e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(tm) 577e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *store = *tm; /* copy the pointed struct to the local copy */ 578e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif 579e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 580e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!tm) 581e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return CURLE_BAD_FUNCTION_ARGUMENT; 582e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return CURLE_OK; 583e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 584