/* Convert a string representation of time to a time value.
- Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1997-2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ Lesser General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <limits.h>
#include <stdio.h>
+#include <stdio_ext.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
#include <time.h>
+#include <unistd.h>
#include <sys/stat.h>
+#include <ctype.h>
+#include <alloca.h>
#define TM_YEAR_BASE 1900
6 memory allication failed (not enough memory available),
7 there is no line in the template that matches the input,
8 invalid input specification Example: February 31 or a time is
- specified that can not be represented in a time_t (representing
+ specified that can not be represented in a time_t (representing
the time in seconds since 00:00:00 UTC, January 1, 1970) */
int getdate_err;
char *result = NULL;
time_t timer;
struct tm tm;
- struct stat st;
+ struct stat64 st;
int mday_ok = 0;
datemsk = getenv ("DATEMSK");
if (datemsk == NULL || *datemsk == '\0')
return 1;
- if (stat (datemsk, &st) < 0)
+ if (stat64 (datemsk, &st) < 0)
return 3;
if (!S_ISREG (st.st_mode))
return 4;
+ if (__access (datemsk, R_OK) < 0)
+ return 2;
+
/* Open the template file. */
- fp = fopen (datemsk, "r");
+ fp = fopen (datemsk, "rce");
if (fp == NULL)
return 2;
+ /* No threads reading this stream. */
+ __fsetlocking (fp, FSETLOCKING_BYCALLER);
+
+ /* Skip leading whitespace. */
+ while (isspace (*string))
+ string++;
+
+ size_t inlen, oldlen;
+
+ oldlen = inlen = strlen (string);
+
+ /* Skip trailing whitespace. */
+ while (inlen > 0 && isspace (string[inlen - 1]))
+ inlen--;
+
+ char *instr = NULL;
+
+ if (inlen < oldlen)
+ {
+ bool using_malloc = false;
+
+ if (__libc_use_alloca (inlen + 1))
+ instr = alloca (inlen + 1);
+ else
+ {
+ instr = malloc (inlen + 1);
+ if (instr == NULL)
+ {
+ fclose (fp);
+ return 6;
+ }
+ using_malloc = true;
+ }
+ memcpy (instr, string, inlen);
+ instr[inlen] = '\0';
+ string = instr;
+
+ if (!using_malloc)
+ instr = NULL;
+ }
+
line = NULL;
len = 0;
do
/* Do the conversion. */
tp->tm_year = tp->tm_mon = tp->tm_mday = tp->tm_wday = INT_MIN;
tp->tm_hour = tp->tm_sec = tp->tm_min = INT_MIN;
+ tp->tm_isdst = -1;
+ tp->tm_gmtoff = 0;
+ tp->tm_zone = NULL;
result = strptime (string, line, tp);
if (result && *result == '\0')
break;
}
- while (!feof_unlocked (fp));
+ while (!__feof_unlocked (fp));
+
+ free (instr);
/* Free the buffer. */
free (line);
/* Check for errors. */
- if (ferror_unlocked (fp))
+ if (__ferror_unlocked (fp))
{
fclose (fp);
return 5;
tp->tm_sec = tm.tm_sec;
}
+ /* Fill in the gaps. */
+ if (tp->tm_hour == INT_MIN)
+ tp->tm_hour = 0;
+ if (tp->tm_min == INT_MIN)
+ tp->tm_min = 0;
+ if (tp->tm_sec == INT_MIN)
+ tp->tm_sec = 0;
+
/* If no date is given, today is assumed if the given hour is
greater than the current hour and tomorrow is assumed if
it is less. */
if (tp->tm_hour >= 0 && tp->tm_hour <= 23
- && tp->tm_year == INT_MIN && tp->tm_mon == INT_MIN
+ && tp->tm_mon == INT_MIN
&& tp->tm_mday == INT_MIN && tp->tm_wday == INT_MIN)
{
- tp->tm_year = tm.tm_year;
tp->tm_mon = tm.tm_mon;
tp->tm_mday = tm.tm_mday + ((tp->tm_hour - tm.tm_hour) < 0 ? 1 : 0);
mday_ok = 1;
}
- /* Fill in the gaps. */
+ /* More fillers. */
if (tp->tm_year == INT_MIN)
tp->tm_year = tm.tm_year;
- if (tp->tm_hour == INT_MIN)
- tp->tm_hour = 0;
- if (tp->tm_min == INT_MIN)
- tp->tm_min = 0;
- if (tp->tm_sec == INT_MIN)
- tp->tm_sec = 0;
+ if (tp->tm_mon == INT_MIN)
+ tp->tm_mon = tm.tm_mon;
/* Check if the day of month is within range, and if the time can be
represented in a time_t. We make use of the fact that the mktime