From e9a910b33c7837b4b868e3abda18eb4810df7f02 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sat, 4 Oct 2025 09:14:33 +0100 Subject: config/git: import suckless sbase i currently use the output of sha512sum in several places of xbmk, which is a bit unreliable in case output changes. other cases where i use util outputs in variables are probably reliable, because i'm using mostly posix utilities in those. to mitigate this, i now import suckless sbase, which has a reasonable sha512sum implementation. *every* binary it builds is being placed in build.list, because i'll probably start using more of them. for example, i may start modifying the "date" implementation, adding the GNU-specific options that i need as mentioned on init.sh i'm importing it in util/ because the sha512sum util is needed for verifying project sources, so if sbase itself is a "project source", that means we can into a chicken and egg bootstrapping problem. this is sbase at revision: 055cc1ae1b3a13c3d8f25af0a4a3316590efcd48 Signed-off-by: Leah Rowe --- util/sbase/date.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 util/sbase/date.c (limited to 'util/sbase/date.c') diff --git a/util/sbase/date.c b/util/sbase/date.c new file mode 100644 index 00000000..109f3710 --- /dev/null +++ b/util/sbase/date.c @@ -0,0 +1,103 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include + +#include "util.h" + +static void +usage(void) +{ + eprintf("usage: %s [-u] [-d time] [+format | mmddHHMM[[CC]yy]]\n", argv0); +} + +static int +datefield(const char *s, size_t i) +{ + if (!isdigit(s[i]) || !isdigit(s[i+1])) + eprintf("invalid date format: %s\n", s); + + return (s[i] - '0') * 10 + (s[i+1] - '0'); +} + +static void +setdate(const char *s, struct tm *now) +{ + struct tm date; + struct timespec ts; + + switch (strlen(s)) { + case 8: + date.tm_year = now->tm_year; + break; + case 10: + date.tm_year = datefield(s, 8); + if (date.tm_year < 69) + date.tm_year += 100; + break; + case 12: + date.tm_year = ((datefield(s, 8) - 19) * 100) + datefield(s, 10); + break; + default: + eprintf("invalid date format: %s\n", s); + break; + } + + date.tm_mon = datefield(s, 0) - 1; + date.tm_mday = datefield(s, 2); + date.tm_hour = datefield(s, 4); + date.tm_min = datefield(s, 6); + date.tm_sec = 0; + date.tm_isdst = -1; + + ts.tv_sec = mktime(&date); + if (ts.tv_sec == -1) + eprintf("mktime:"); + ts.tv_nsec = 0; + + if (clock_settime(CLOCK_REALTIME, &ts) == -1) + eprintf("clock_settime:"); +} + +int +main(int argc, char *argv[]) +{ + struct tm *now; + time_t t; + char buf[BUFSIZ], *fmt = "%a %b %e %H:%M:%S %Z %Y"; + + t = time(NULL); + if (t == -1) + eprintf("time:"); + + ARGBEGIN { + case 'd': + t = estrtonum(EARGF(usage()), 0, LLONG_MAX); + break; + case 'u': + if (setenv("TZ", "UTC0", 1) < 0) + eprintf("setenv:"); + break; + default: + usage(); + } ARGEND + + if (!(now = localtime(&t))) + eprintf("localtime:"); + if (argc) { + if (argc != 1) + usage(); + if (argv[0][0] != '+') { + setdate(argv[0], now); + return 0; + } + fmt = &argv[0][1]; + } + + strftime(buf, sizeof(buf), fmt, now); + puts(buf); + + return fshut(stdout, ""); +} -- cgit v1.2.1