From: Alejandro Colomar Date: Tue, 18 Feb 2025 22:25:29 +0000 (+0100) Subject: lib/getdate.c: Use strptime(3) to simplify X-Git-Tag: 4.18.0-rc1~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b8abe4e9d721b63538ad145c13aa4c13a7b30304;p=thirdparty%2Fshadow.git lib/getdate.c: Use strptime(3) to simplify The following trick: t = 0; gmtime_r(&t, &tm); is a clever way to clear the tm(3type) structure, and set it to use UTC. We need to set it to set UTC with this trick, because strptime(3) doesn't set the timezone. I (Alex) tried previously using bzero(&tm, sizeof(tm)); strptime("UTC", "%Z", &tm); but glibc ignores the timezone, and musl (at least I tried in an Alpine container) seems to report an error. The idea to use gmtime_r(3) was from lanodan. Link: Cc: Iker Pedrosa Cc: Serge Hallyn Cc: Rich Felker Co-authored-by: "Haelwenn (lanodan) Monnier" Signed-off-by: "Haelwenn (lanodan) Monnier" Signed-off-by: Alejandro Colomar --- diff --git a/lib/getdate.c b/lib/getdate.c index f9a3f837a..cc2c3f155 100644 --- a/lib/getdate.c +++ b/lib/getdate.c @@ -1,81 +1,31 @@ // SPDX-FileCopyrightText: 2025, Alejandro Colomar +// SPDX-FileCopyrightText: 2025, "Haelwenn (lanodan) Monnier" // SPDX-License-Identifier: BSD-3-Clause #include -#include -#include #include -#include #include -#include "atoi/a2i/a2s.h" #include "getdate.h" -#include "string/strchr/strchrcnt.h" #include "string/strcmp/streq.h" -#include "string/strcmp/strprefix.h" -#include "string/strcmp/strsuffix.h" -#include "string/strspn/stpspn.h" - - -#define TM_YEAR_ORIGIN 1900 - - -static long yyDay; -static long yyMonth; -static long yyYear; - - -static int parse_date(const char *s); time_t get_date(const char *s) { - struct tm tm; - - if (parse_date(s) == -1) - return -1; - - tm.tm_year = yyYear - TM_YEAR_ORIGIN; - tm.tm_mon = yyMonth - 1; - tm.tm_mday = yyDay; - tm.tm_hour = tm.tm_min = tm.tm_sec = 0; - tm.tm_isdst = 0; - - return timegm(&tm); -} - - -static int -parse_date(const char *s) -{ - long n; - - if (!streq(stpspn(s, "0123456789-"), "") - || strchrcnt(s, '-') != 2 - || strprefix(s, "-") - || strsuffix(s, "-") - || strstr(s, "--")) - { - return -1; - } - - if (a2sl(&yyYear, s, &s, 10, LONG_MIN, LONG_MAX) == -1 && errno != ENOTSUP) - return -1; - - if (!strprefix(s++, "-")) - return -1; + time_t t; + struct tm tm; + const char *p; - if (a2sl(&yyMonth, s, &s, 10, LONG_MIN, LONG_MAX) == -1 && errno != ENOTSUP) + t = 0; + if (gmtime_r(&t, &tm) == NULL) return -1; - if (!strprefix(s++, "-")) + p = strptime(s, "%Y-%m-%d", &tm); + if (p == NULL || !streq(p, "")) return -1; - if (a2sl(&yyDay, s, NULL, 10, LONG_MIN, LONG_MAX) == -1) - return -1; - - return 0; + return timegm(&tm); }