]> git.ipfire.org Git - thirdparty/shadow.git/commitdiff
lib/getdate.c: Use strptime(3) to simplify
authorAlejandro Colomar <alx@kernel.org>
Tue, 18 Feb 2025 22:25:29 +0000 (23:25 +0100)
committerIker Pedrosa <ikerpedrosam@gmail.com>
Mon, 2 Jun 2025 07:59:51 +0000 (09:59 +0200)
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: <https://inbox.sourceware.org/libc-alpha/Z_LqUgildoq33vI-@cloudsdale.the-delta.net.eu.org/T/#u>
Cc: Iker Pedrosa <ipedrosa@redhat.com>
Cc: Serge Hallyn <serge@hallyn.com>
Cc: Rich Felker <dalias@libc.org>
Co-authored-by: "Haelwenn (lanodan) Monnier" <contact@hacktivis.me>
Signed-off-by: "Haelwenn (lanodan) Monnier" <contact@hacktivis.me>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
lib/getdate.c

index f9a3f837abf516be85653e9ca8f48d87fc70bbf7..cc2c3f15598a020836276db3f3102cb9225699cf 100644 (file)
@@ -1,81 +1,31 @@
 // SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
+// SPDX-FileCopyrightText: 2025, "Haelwenn (lanodan) Monnier" <contact@hacktivis.me>
 // SPDX-License-Identifier: BSD-3-Clause
 
 
 #include <config.h>
 
-#include <errno.h>
-#include <limits.h>
 #include <stddef.h>
-#include <string.h>
 #include <time.h>
 
-#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);
 }