From 65d666e33b65fb15e067e3aba7eac7d13fad1212 Mon Sep 17 00:00:00 2001 From: q66 Date: Sat, 8 Apr 2023 18:34:58 +0200 Subject: [PATCH] switch to freebsd implementations of strftime and strptime This allows the tools to have less deficient behavior on musl, as freebsd implements tons of extensions that musl does not, which regularly breaks scripts even in projects that have explicit support for BSD date, while also making them less useful. --- import-src.sh | 2 + include/time_bsd.h | 42 + patches/src.freebsd.patch | 1207 +++++++++++++++++++++- src.freebsd/compat/meson.build | 2 + src.freebsd/compat/strftime.c | 600 +++++++++++ src.freebsd/compat/strptime.c | 723 +++++++++++++ src.freebsd/coreutils/date/date.1 | 4 +- src.freebsd/coreutils/date/date.c | 19 +- src.freebsd/coreutils/date/meson.build | 10 +- src.freebsd/coreutils/ls/ls.1 | 2 +- src.freebsd/coreutils/ls/meson.build | 4 +- src.freebsd/coreutils/ls/print.c | 4 +- src.freebsd/coreutils/pr/meson.build | 9 +- src.freebsd/coreutils/pr/pr.c | 4 +- src.freebsd/coreutils/stat/meson.build | 8 +- src.freebsd/coreutils/stat/stat.1 | 4 +- src.freebsd/coreutils/stat/stat.c | 4 +- src.freebsd/coreutils/touch/meson.build | 7 +- src.freebsd/coreutils/touch/touch.c | 4 +- src.freebsd/coreutils/who/meson.build | 8 +- src.freebsd/coreutils/who/who.c | 4 +- src.freebsd/diffutils/diff/diffreg.c | 10 +- src.freebsd/diffutils/diff/meson.build | 8 +- src.freebsd/findutils/find/ls.c | 4 +- src.freebsd/findutils/find/meson.build | 22 +- src.freebsd/miscutils/calendar/day.c | 4 +- src.freebsd/miscutils/calendar/events.c | 4 +- src.freebsd/miscutils/calendar/locale.c | 10 +- src.freebsd/miscutils/ncal/meson.build | 1 + src.freebsd/miscutils/ncal/ncal.c | 6 +- src.freebsd/miscutils/script/meson.build | 3 +- src.freebsd/miscutils/script/script.c | 4 +- 32 files changed, 2632 insertions(+), 115 deletions(-) create mode 100644 include/time_bsd.h create mode 100644 src.freebsd/compat/strftime.c create mode 100644 src.freebsd/compat/strptime.c diff --git a/import-src.sh b/import-src.sh index d570ffa4..3057d2ac 100755 --- a/import-src.sh +++ b/import-src.sh @@ -234,6 +234,8 @@ cp -p usr/src/lib/libopenbsd/ohash.c ${CWD}/src.orig/compat cp -p usr/src/lib/libc/gen/setmode.c ${CWD}/src.orig/compat cp -p usr/src/lib/libc/string/strmode.c ${CWD}/src.orig/compat cp -p usr/src/lib/libc/gen/stringlist.c ${CWD}/src.orig/compat +cp -p usr/src/lib/libc/stdtime/strptime.c ${CWD}/src.orig/compat +cp -p usr/src/lib/libc/stdtime/strftime.c ${CWD}/src.orig/compat cp -p usr/src/contrib/libc-vis/vis.c ${CWD}/src.orig/compat cp -p usr/src/include/stringlist.h ${CWD}/src.orig/include cp -p usr/src/contrib/libc-vis/vis.h ${CWD}/src.orig/include diff --git a/include/time_bsd.h b/include/time_bsd.h new file mode 100644 index 00000000..04169b11 --- /dev/null +++ b/include/time_bsd.h @@ -0,0 +1,42 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2023 Daniel Kolesa + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef TIME_BSD_H +#define TIME_BSD_H + +#include +#include + +/* FreeBSD implementations of strptime and strftime + * + * used to get consistent behavior of utilities like date(1) even on libcs + * that do not bother to implement the various extensions such as %s + */ +char *strptime_bsd(const char *__restrict buf, const char *__restrict fmt, struct tm *__restrict tm); +size_t strftime_bsd(char *__restrict s, size_t maxsize, const char *__restrict format, const struct tm *__restrict t); + +#endif diff --git a/patches/src.freebsd.patch b/patches/src.freebsd.patch index 0d052fe8..d8908c25 100644 --- a/patches/src.freebsd.patch +++ b/patches/src.freebsd.patch @@ -145,6 +145,419 @@ return (mask); } +--- src.orig/compat/strftime.c ++++ src.freebsd/compat/strftime.c +@@ -30,27 +30,34 @@ + #endif /* !defined NOID */ + #endif /* !defined lint */ + +-#include "namespace.h" +-#include "private.h" +- + #if defined(LIBC_SCCS) && !defined(lint) + static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89"; + #endif /* LIBC_SCCS and not lint */ + #include + __FBSDID("$FreeBSD$"); + +-#include "tzfile.h" + #include + #include + #include +-#include "un-namespace.h" +-#include "timelocal.h" ++#include ++#include ++ ++#define DAYSPERWEEK 7 ++#define MONSPERYEAR 12 ++#define HOURSPERDAY 24 ++#define SECSPERMIN 60 ++#define MINSPERHOUR 60 ++#define DAYSPERNYEAR 365 ++#define DAYSPERLYEAR 366 ++#define TM_YEAR_BASE 1900 ++ ++#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) ++#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) + + static char * _add(const char *, char *, const char *); +-static char * _conv(int, const char *, char *, const char *, locale_t); +-static char * _fmt(const char *, const struct tm *, char *, const char *, +- int *, locale_t); +-static char * _yconv(int, int, int, int, char *, const char *, locale_t); ++static char * _conv(int, const char *, char *, const char *); ++static char * _fmt(const char *, const struct tm *, char *, const char *); ++static char * _yconv(int, int, int, int, char *, const char *); + + extern char * tzname[]; + +@@ -88,51 +95,23 @@ + }; + + size_t +-strftime_l(char * __restrict s, size_t maxsize, const char * __restrict format, +- const struct tm * __restrict t, locale_t loc) ++strftime_bsd(char * __restrict s, size_t maxsize, const char * __restrict format, ++ const struct tm * __restrict t) + { + char * p; +- int warn; +- FIX_LOCALE(loc); +- + tzset(); +- warn = IN_NONE; +- p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn, loc); +-#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU +- if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) { +- (void) fprintf_l(stderr, loc, "\n"); +- if (format == NULL) +- (void) fputs("NULL strftime format ", stderr); +- else (void) fprintf_l(stderr, loc, "strftime format \"%s\" ", +- format); +- (void) fputs("yields only two digits of years in ", stderr); +- if (warn == IN_SOME) +- (void) fputs("some locales", stderr); +- else if (warn == IN_THIS) +- (void) fputs("the current locale", stderr); +- else (void) fputs("all locales", stderr); +- (void) fputs("\n", stderr); +- } +-#endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */ ++ p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize); + if (p == s + maxsize) + return (0); + *p = '\0'; + return p - s; + } + +-size_t +-strftime(char * __restrict s, size_t maxsize, const char * __restrict format, +- const struct tm * __restrict t) +-{ +- return strftime_l(s, maxsize, format, t, __get_locale()); +-} +- + static char * + _fmt(const char *format, const struct tm * const t, char *pt, +- const char * const ptlim, int *warnp, locale_t loc) ++ const char * const ptlim) + { + int Ealternative, Oalternative, PadIndex; +- struct lc_time_T *tptr = __get_current_time_locale(loc); + + for ( ; *format; ++format) { + if (*format == '%') { +@@ -147,27 +126,26 @@ + case 'A': + pt = _add((t->tm_wday < 0 || + t->tm_wday >= DAYSPERWEEK) ? +- "?" : tptr->weekday[t->tm_wday], ++ "?" : nl_langinfo(DAY_1 + t->tm_wday), + pt, ptlim); + continue; + case 'a': + pt = _add((t->tm_wday < 0 || + t->tm_wday >= DAYSPERWEEK) ? +- "?" : tptr->wday[t->tm_wday], ++ "?" : nl_langinfo(ABDAY_1 + t->tm_wday), + pt, ptlim); + continue; + case 'B': + pt = _add((t->tm_mon < 0 || + t->tm_mon >= MONSPERYEAR) ? +- "?" : (Oalternative ? tptr->alt_month : +- tptr->month)[t->tm_mon], ++ "?" : nl_langinfo(MON_1 + t->tm_mon), + pt, ptlim); + continue; + case 'b': + case 'h': + pt = _add((t->tm_mon < 0 || + t->tm_mon >= MONSPERYEAR) ? +- "?" : tptr->mon[t->tm_mon], ++ "?" : nl_langinfo(ABMON_1 + t->tm_mon), + pt, ptlim); + continue; + case 'C': +@@ -179,26 +157,18 @@ + * (ado, 1993-05-24) + */ + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0, +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'c': +- { +- int warn2 = IN_SOME; +- +- pt = _fmt(tptr->c_fmt, t, pt, ptlim, &warn2, loc); +- if (warn2 == IN_ALL) +- warn2 = IN_THIS; +- if (warn2 > *warnp) +- *warnp = warn2; +- } ++ pt = _fmt(nl_langinfo(D_T_FMT), t, pt, ptlim); + continue; + case 'D': +- pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp, loc); ++ pt = _fmt("%m/%d/%y", t, pt, ptlim); + continue; + case 'd': + pt = _conv(t->tm_mday, + fmt_padding[PAD_FMT_DAYOFMONTH][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'E': + if (Ealternative || Oalternative) +@@ -225,25 +195,25 @@ + case 'e': + pt = _conv(t->tm_mday, + fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'F': +- pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp, loc); ++ pt = _fmt("%Y-%m-%d", t, pt, ptlim); + continue; + case 'H': + pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_HMS][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'I': + pt = _conv((t->tm_hour % 12) ? + (t->tm_hour % 12) : 12, + fmt_padding[PAD_FMT_HMS][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'j': + pt = _conv(t->tm_yday + 1, + fmt_padding[PAD_FMT_DAYOFYEAR][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'k': + /* +@@ -257,7 +227,7 @@ + * (ado, 1993-05-24) + */ + pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_SHMS][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + continue; + #ifdef KITCHEN_SINK + case 'K': +@@ -280,55 +250,49 @@ + pt = _conv((t->tm_hour % 12) ? + (t->tm_hour % 12) : 12, + fmt_padding[PAD_FMT_SHMS][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'M': + pt = _conv(t->tm_min, fmt_padding[PAD_FMT_HMS][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'm': + pt = _conv(t->tm_mon + 1, + fmt_padding[PAD_FMT_MONTH][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'n': + pt = _add("\n", pt, ptlim); + continue; + case 'p': +- pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ? +- tptr->pm : tptr->am, ++ pt = _add(nl_langinfo((t->tm_hour >= (HOURSPERDAY / 2)) ? ++ PM_STR : AM_STR), + pt, ptlim); + continue; + case 'R': +- pt = _fmt("%H:%M", t, pt, ptlim, warnp, loc); ++ pt = _fmt("%H:%M", t, pt, ptlim); + continue; + case 'r': +- pt = _fmt(tptr->ampm_fmt, t, pt, ptlim, +- warnp, loc); ++ pt = _fmt(nl_langinfo(T_FMT_AMPM), t, pt, ptlim); + continue; + case 'S': + pt = _conv(t->tm_sec, fmt_padding[PAD_FMT_HMS][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 's': + { + struct tm tm; +- char buf[INT_STRLEN_MAXIMUM( +- time_t) + 1]; ++ char buf[32]; + time_t mkt; + + tm = *t; + mkt = mktime(&tm); +- if (TYPE_SIGNED(time_t)) +- (void) sprintf_l(buf, loc, "%ld", +- (long) mkt); +- else (void) sprintf_l(buf, loc, "%lu", +- (unsigned long) mkt); ++ (void) sprintf(buf, "%lld", (long long) mkt); + pt = _add(buf, pt, ptlim); + } + continue; + case 'T': +- pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp, loc); ++ pt = _fmt("%H:%M:%S", t, pt, ptlim); + continue; + case 't': + pt = _add("\t", pt, ptlim); +@@ -337,7 +301,7 @@ + pt = _conv((t->tm_yday + DAYSPERWEEK - + t->tm_wday) / DAYSPERWEEK, + fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'u': + /* +@@ -348,7 +312,7 @@ + */ + pt = _conv((t->tm_wday == 0) ? + DAYSPERWEEK : t->tm_wday, +- "%d", pt, ptlim, loc); ++ "%d", pt, ptlim); + continue; + case 'V': /* ISO 8601 week number */ + case 'G': /* ISO 8601 year (four digits) */ +@@ -429,13 +393,12 @@ + #endif /* defined XPG4_1994_04_09 */ + if (*format == 'V') + pt = _conv(w, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + else if (*format == 'g') { +- *warnp = IN_ALL; + pt = _yconv(year, base, 0, 1, +- pt, ptlim, loc); ++ pt, ptlim); + } else pt = _yconv(year, base, 1, 1, +- pt, ptlim, loc); ++ pt, ptlim); + } + continue; + case 'v': +@@ -444,7 +407,7 @@ + * "date as dd-bbb-YYYY" + * (ado, 1993-05-24) + */ +- pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp, loc); ++ pt = _fmt("%e-%b-%Y", t, pt, ptlim); + continue; + case 'W': + pt = _conv((t->tm_yday + DAYSPERWEEK - +@@ -452,33 +415,24 @@ + (t->tm_wday - 1) : + (DAYSPERWEEK - 1))) / DAYSPERWEEK, + fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'w': +- pt = _conv(t->tm_wday, "%d", pt, ptlim, loc); ++ pt = _conv(t->tm_wday, "%d", pt, ptlim); + continue; + case 'X': +- pt = _fmt(tptr->X_fmt, t, pt, ptlim, warnp, loc); ++ pt = _fmt(nl_langinfo(T_FMT), t, pt, ptlim); + continue; + case 'x': +- { +- int warn2 = IN_SOME; +- +- pt = _fmt(tptr->x_fmt, t, pt, ptlim, &warn2, loc); +- if (warn2 == IN_ALL) +- warn2 = IN_THIS; +- if (warn2 > *warnp) +- *warnp = warn2; +- } ++ pt = _fmt(nl_langinfo(D_FMT), t, pt, ptlim); + continue; + case 'y': +- *warnp = IN_ALL; + pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1, +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'Y': + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1, +- pt, ptlim, loc); ++ pt, ptlim); + continue; + case 'Z': + #ifdef TM_ZONE +@@ -548,12 +502,15 @@ + (diff % MINSPERHOUR); + pt = _conv(diff, + fmt_padding[PAD_FMT_YEAR][PadIndex], +- pt, ptlim, loc); ++ pt, ptlim); + } + continue; + case '+': +- pt = _fmt(tptr->date_fmt, t, pt, ptlim, +- warnp, loc); ++#ifdef _DATE_FMT ++ pt = _fmt(nl_langinfo(_DATE_FMT), t, pt, ptlim); ++#else ++ pt = _fmt("%a %b %e %H:%M:%S %Z %Y", t, pt, ptlim); ++#endif + continue; + case '-': + if (PadIndex != PAD_DEFAULT) +@@ -589,11 +546,11 @@ + + static char * + _conv(const int n, const char * const format, char * const pt, +- const char * const ptlim, locale_t loc) ++ const char * const ptlim) + { +- char buf[INT_STRLEN_MAXIMUM(int) + 1]; ++ char buf[16]; + +- (void) sprintf_l(buf, loc, format, n); ++ (void) sprintf(buf, format, n); + return _add(buf, pt, ptlim); + } + +@@ -615,7 +572,7 @@ + + static char * + _yconv(const int a, const int b, const int convert_top, const int convert_yy, +- char *pt, const char * const ptlim, locale_t loc) ++ char *pt, const char * const ptlim) + { + register int lead; + register int trail; +@@ -634,10 +591,10 @@ + if (convert_top) { + if (lead == 0 && trail < 0) + pt = _add("-0", pt, ptlim); +- else pt = _conv(lead, "%02d", pt, ptlim, loc); ++ else pt = _conv(lead, "%02d", pt, ptlim); + } + if (convert_yy) + pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, +- ptlim, loc); ++ ptlim); + return (pt); + } --- src.orig/compat/stringlist.c +++ src.freebsd/compat/stringlist.c @@ -30,13 +30,11 @@ @@ -177,6 +590,461 @@ return sl; } +--- src.orig/compat/strptime.c ++++ src.freebsd/compat/strptime.c +@@ -47,20 +47,23 @@ + #endif /* not lint */ + __FBSDID("$FreeBSD$"); + +-#include "namespace.h" + #include + #include + #include + #include + #include + #include +-#include "private.h" +-#include "un-namespace.h" +-#include "libc_private.h" +-#include "timelocal.h" +-#include "tzfile.h" ++#include + +-static char * _strptime(const char *, const char *, struct tm *, int *, locale_t); ++#define DAYSPERWEEK 7 ++#define MONSPERYEAR 12 ++#define TM_SUNDAY 0 ++#define TM_MONDAY 1 ++#define TM_YEAR_BASE 1900 ++ ++#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) ++ ++static char * _strptime(const char *, const char *, struct tm *, int *); + + #define asizeof(a) (sizeof(a) / sizeof((a)[0])) + +@@ -86,18 +89,16 @@ + } + + static char * +-_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp, +- locale_t locale) ++_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp) + { + char c; +- const char *ptr; ++ const char *ptr, *ex; + int day_offset = -1, wday_offset; + int week_offset; + int i, len; + int flags; + int Ealternative, Oalternative; + int century, year; +- const struct lc_time_T *tptr = __get_current_time_locale(locale); + static int start_of_month[2][13] = { + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, + {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} +@@ -112,9 +113,9 @@ + c = *ptr++; + + if (c != '%') { +- if (isspace_l((unsigned char)c, locale)) ++ if (isspace((unsigned char)c)) + while (*buf != 0 && +- isspace_l((unsigned char)*buf, locale)) ++ isspace((unsigned char)*buf)) + buf++; + else if (c != *buf++) + return (NULL); +@@ -132,20 +133,24 @@ + break; + + case '+': +- buf = _strptime(buf, tptr->date_fmt, tm, GMTp, locale); ++#ifdef _DATE_FMT ++ buf = _strptime(buf, nl_langinfo(_DATE_FMT), tm, GMTp); ++#else ++ buf = _strptime(buf, "%a %b %e %H:%M:%S %Z %Y", tm, GMTp); ++#endif + if (buf == NULL) + return (NULL); + flags |= FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + break; + + case 'C': +- if (!isdigit_l((unsigned char)*buf, locale)) ++ if (!isdigit((unsigned char)*buf)) + return (NULL); + + /* XXX This will break for 3-digit centuries. */ + len = 2; + for (i = 0; len && *buf != 0 && +- isdigit_l((unsigned char)*buf, locale); buf++) { ++ isdigit((unsigned char)*buf); buf++) { + i *= 10; + i += *buf - '0'; + len--; +@@ -157,14 +162,14 @@ + break; + + case 'c': +- buf = _strptime(buf, tptr->c_fmt, tm, GMTp, locale); ++ buf = _strptime(buf, nl_langinfo(D_T_FMT), tm, GMTp); + if (buf == NULL) + return (NULL); + flags |= FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + break; + + case 'D': +- buf = _strptime(buf, "%m/%d/%y", tm, GMTp, locale); ++ buf = _strptime(buf, "%m/%d/%y", tm, GMTp); + if (buf == NULL) + return (NULL); + flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; +@@ -183,50 +188,50 @@ + goto label; + + case 'F': +- buf = _strptime(buf, "%Y-%m-%d", tm, GMTp, locale); ++ buf = _strptime(buf, "%Y-%m-%d", tm, GMTp); + if (buf == NULL) + return (NULL); + flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + break; + + case 'R': +- buf = _strptime(buf, "%H:%M", tm, GMTp, locale); ++ buf = _strptime(buf, "%H:%M", tm, GMTp); + if (buf == NULL) + return (NULL); + break; + + case 'r': +- buf = _strptime(buf, tptr->ampm_fmt, tm, GMTp, locale); ++ buf = _strptime(buf, nl_langinfo(T_FMT_AMPM), tm, GMTp); + if (buf == NULL) + return (NULL); + break; + + case 'T': +- buf = _strptime(buf, "%H:%M:%S", tm, GMTp, locale); ++ buf = _strptime(buf, "%H:%M:%S", tm, GMTp); + if (buf == NULL) + return (NULL); + break; + + case 'X': +- buf = _strptime(buf, tptr->X_fmt, tm, GMTp, locale); ++ buf = _strptime(buf, nl_langinfo(T_FMT), tm, GMTp); + if (buf == NULL) + return (NULL); + break; + + case 'x': +- buf = _strptime(buf, tptr->x_fmt, tm, GMTp, locale); ++ buf = _strptime(buf, nl_langinfo(D_FMT), tm, GMTp); + if (buf == NULL) + return (NULL); + flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + break; + + case 'j': +- if (!isdigit_l((unsigned char)*buf, locale)) ++ if (!isdigit((unsigned char)*buf)) + return (NULL); + + len = 3; + for (i = 0; len && *buf != 0 && +- isdigit_l((unsigned char)*buf, locale); buf++){ ++ isdigit((unsigned char)*buf); buf++){ + i *= 10; + i += *buf - '0'; + len--; +@@ -242,15 +247,15 @@ + case 'M': + case 'S': + if (*buf == 0 || +- isspace_l((unsigned char)*buf, locale)) ++ isspace((unsigned char)*buf)) + break; + +- if (!isdigit_l((unsigned char)*buf, locale)) ++ if (!isdigit((unsigned char)*buf)) + return (NULL); + + len = 2; + for (i = 0; len && *buf != 0 && +- isdigit_l((unsigned char)*buf, locale); buf++){ ++ isdigit((unsigned char)*buf); buf++){ + i *= 10; + i += *buf - '0'; + len--; +@@ -283,16 +288,16 @@ + + len = 2; + if ((c == 'k' || c == 'l') && +- isblank_l((unsigned char)*buf, locale)) { ++ isblank((unsigned char)*buf)) { + buf++; + len = 1; + } + +- if (!isdigit_l((unsigned char)*buf, locale)) ++ if (!isdigit((unsigned char)*buf)) + return (NULL); + + for (i = 0; len && *buf != 0 && +- isdigit_l((unsigned char)*buf, locale); buf++) { ++ isdigit((unsigned char)*buf); buf++) { + i *= 10; + i += *buf - '0'; + len--; +@@ -315,16 +320,18 @@ + if (tm->tm_hour > 12) + return (NULL); + +- len = strlen(tptr->am); +- if (strncasecmp_l(buf, tptr->am, len, locale) == 0) { ++ ex = nl_langinfo(AM_STR); ++ len = strlen(ex); ++ if (strncasecmp(buf, ex, len) == 0) { + if (tm->tm_hour == 12) + tm->tm_hour = 0; + buf += len; + break; + } + +- len = strlen(tptr->pm); +- if (strncasecmp_l(buf, tptr->pm, len, locale) == 0) { ++ ex = nl_langinfo(PM_STR); ++ len = strlen(ex); ++ if (strncasecmp(buf, ex, len) == 0) { + if (tm->tm_hour != 12) + tm->tm_hour += 12; + buf += len; +@@ -335,17 +342,17 @@ + + case 'A': + case 'a': +- for (i = 0; i < asizeof(tptr->weekday); i++) { +- len = strlen(tptr->weekday[i]); +- if (strncasecmp_l(buf, tptr->weekday[i], +- len, locale) == 0) ++ for (i = 0; i < DAYSPERWEEK; i++) { ++ ex = nl_langinfo(DAY_1 + i); ++ len = strlen(ex); ++ if (strncasecmp(buf, ex, len) == 0) + break; +- len = strlen(tptr->wday[i]); +- if (strncasecmp_l(buf, tptr->wday[i], +- len, locale) == 0) ++ ex = nl_langinfo(ABDAY_1 + i); ++ len = strlen(ex); ++ if (strncasecmp(buf, ex, len) == 0) + break; + } +- if (i == asizeof(tptr->weekday)) ++ if (i == DAYSPERWEEK) + return (NULL); + + buf += len; +@@ -361,12 +368,12 @@ + * point to calculate a real value, so just check the + * range for now. + */ +- if (!isdigit_l((unsigned char)*buf, locale)) ++ if (!isdigit((unsigned char)*buf)) + return (NULL); + + len = 2; + for (i = 0; len && *buf != 0 && +- isdigit_l((unsigned char)*buf, locale); buf++) { ++ isdigit((unsigned char)*buf); buf++) { + i *= 10; + i += *buf - '0'; + len--; +@@ -386,7 +393,7 @@ + + case 'u': + case 'w': +- if (!isdigit_l((unsigned char)*buf, locale)) ++ if (!isdigit((unsigned char)*buf)) + return (NULL); + + i = *buf++ - '0'; +@@ -405,7 +412,7 @@ + * before single digits. + */ + if (*buf != 0 && +- isspace_l((unsigned char)*buf, locale)) ++ isspace((unsigned char)*buf)) + buf++; + /* FALLTHROUGH */ + case 'd': +@@ -418,12 +425,12 @@ + * XXX The %e specifier may gobble one too many + * digits if used incorrectly. + */ +- if (!isdigit_l((unsigned char)*buf, locale)) ++ if (!isdigit((unsigned char)*buf)) + return (NULL); + + len = 2; + for (i = 0; len && *buf != 0 && +- isdigit_l((unsigned char)*buf, locale); buf++) { ++ isdigit((unsigned char)*buf); buf++) { + i *= 10; + i += *buf - '0'; + len--; +@@ -439,19 +446,18 @@ + case 'B': + case 'b': + case 'h': +- for (i = 0; i < asizeof(tptr->month); i++) { ++ for (i = 0; i < MONSPERYEAR; i++) { + if (Oalternative) { + if (c == 'B') { +- len = strlen(tptr->alt_month[i]); +- if (strncasecmp_l(buf, +- tptr->alt_month[i], +- len, locale) == 0) ++ ex = nl_langinfo(MON_1 + i); ++ len = strlen(ex); ++ if (strncasecmp(buf, ex, len) == 0) + break; + } + } else { +- len = strlen(tptr->month[i]); +- if (strncasecmp_l(buf, tptr->month[i], +- len, locale) == 0) ++ ex = nl_langinfo(MON_1 + i); ++ len = strlen(ex); ++ if (strncasecmp(buf, ex, len) == 0) + break; + } + } +@@ -459,15 +465,15 @@ + * Try the abbreviated month name if the full name + * wasn't found and Oalternative was not requested. + */ +- if (i == asizeof(tptr->month) && !Oalternative) { +- for (i = 0; i < asizeof(tptr->month); i++) { +- len = strlen(tptr->mon[i]); +- if (strncasecmp_l(buf, tptr->mon[i], +- len, locale) == 0) ++ if (i == MONSPERYEAR && !Oalternative) { ++ for (i = 0; i < MONSPERYEAR; i++) { ++ ex = nl_langinfo(ABMON_1 + i); ++ len = strlen(ex); ++ if (strncasecmp(buf, ex, len) == 0) + break; + } + } +- if (i == asizeof(tptr->month)) ++ if (i == MONSPERYEAR) + return (NULL); + + tm->tm_mon = i; +@@ -477,12 +483,12 @@ + break; + + case 'm': +- if (!isdigit_l((unsigned char)*buf, locale)) ++ if (!isdigit((unsigned char)*buf)) + return (NULL); + + len = 2; + for (i = 0; len && *buf != 0 && +- isdigit_l((unsigned char)*buf, locale); buf++) { ++ isdigit((unsigned char)*buf); buf++) { + i *= 10; + i += *buf - '0'; + len--; +@@ -504,7 +510,7 @@ + + sverrno = errno; + errno = 0; +- n = strtol_l(buf, &cp, 10, locale); ++ n = strtol(buf, &cp, 10); + if (errno == ERANGE || (long)(t = n) != n) { + errno = sverrno; + return (NULL); +@@ -522,15 +528,15 @@ + case 'Y': + case 'y': + if (*buf == 0 || +- isspace_l((unsigned char)*buf, locale)) ++ isspace((unsigned char)*buf)) + break; + +- if (!isdigit_l((unsigned char)*buf, locale)) ++ if (!isdigit((unsigned char)*buf)) + return (NULL); + + len = (c == 'Y') ? 4 : 2; + for (i = 0; len && *buf != 0 && +- isdigit_l((unsigned char)*buf, locale); buf++) { ++ isdigit((unsigned char)*buf); buf++) { + i *= 10; + i += *buf - '0'; + len--; +@@ -549,7 +555,7 @@ + char *zonestr; + + for (cp = buf; *cp && +- isupper_l((unsigned char)*cp, locale); ++cp) { ++ isupper((unsigned char)*cp); ++cp) { + /*empty*/} + if (cp - buf) { + zonestr = alloca(cp - buf + 1); +@@ -585,7 +591,7 @@ + buf++; + i = 0; + for (len = 4; len > 0; len--) { +- if (isdigit_l((unsigned char)*buf, locale)) { ++ if (isdigit((unsigned char)*buf)) { + i *= 10; + i += *buf - '0'; + buf++; +@@ -607,7 +613,7 @@ + + case 'n': + case 't': +- while (isspace_l((unsigned char)*buf, locale)) ++ while (isspace((unsigned char)*buf)) + buf++; + break; + +@@ -699,15 +705,14 @@ + } + + char * +-strptime_l(const char * __restrict buf, const char * __restrict fmt, +- struct tm * __restrict tm, locale_t loc) ++strptime_bsd(const char * __restrict buf, const char * __restrict fmt, ++ struct tm * __restrict tm) + { + char *ret; + int gmt; +- FIX_LOCALE(loc); + + gmt = 0; +- ret = _strptime(buf, fmt, tm, &gmt, loc); ++ ret = _strptime(buf, fmt, tm, &gmt); + if (ret && gmt) { + time_t t = timegm(tm); + +@@ -716,10 +721,3 @@ + + return (ret); + } +- +-char * +-strptime(const char * __restrict buf, const char * __restrict fmt, +- struct tm * __restrict tm) +-{ +- return strptime_l(buf, fmt, tm, __get_locale()); +-} --- src.orig/compat/vis.c +++ src.freebsd/compat/vis.c @@ -64,7 +64,6 @@ @@ -590,34 +1458,69 @@ return (0); } +--- src.orig/coreutils/date/date.1 ++++ src.freebsd/coreutils/date/date.1 +@@ -126,7 +126,7 @@ + .Oc Ar MM Op Cm \&. Ar SS + .Sm on + format. +-Parsing is done using ++Parsing is done using FreeBSD + .Xr strptime 3 . + .It Fl I Ns Op Ar FMT + Use +@@ -310,7 +310,7 @@ + The format string may contain any of the conversion specifications + described in the + .Xr strftime 3 +-manual page, as well as any arbitrary text. ++FreeBSD manual page, as well as any arbitrary text. + A newline + .Pq Ql \en + character is always output after the characters specified by --- src.orig/coreutils/date/date.c +++ src.freebsd/coreutils/date/date.c @@ -58,6 +58,8 @@ #include #include #include -+#include ++#include +#include #include "vary.h" -@@ -164,7 +166,14 @@ - if (!rflag && time(&tval) == -1) - err(1, "time"); +@@ -211,7 +213,7 @@ + */ + setlocale(LC_TIME, "C"); -- format = "%+"; -+ /* Linux libc's do not support %+ */ -+#ifdef _DATE_FMT -+ /* glibc extension */ -+ format = nl_langinfo(_DATE_FMT); -+#else -+ /* fallback, e.g. musl */ -+ format = "%a %b %e %H:%M:%S %Z %Y"; -+#endif +- (void)strftime(buf, sizeof(buf), format, lt); ++ (void)strftime_bsd(buf, sizeof(buf), format, lt); + printdate(buf); + } - if (Rflag) - format = rfc2822_format; -@@ -344,14 +353,18 @@ +@@ -234,10 +236,10 @@ + for (it = iso8601_fmts; it <= iso8601_selected; it++) + strlcat(fmtbuf, it->format_string, sizeof(fmtbuf)); + +- (void)strftime(buf, sizeof(buf), fmtbuf, lt); ++ (void)strftime_bsd(buf, sizeof(buf), fmtbuf, lt); + + if (iso8601_selected > iso8601_fmts) { +- (void)strftime(tzbuf, sizeof(tzbuf), "%z", lt); ++ (void)strftime_bsd(tzbuf, sizeof(tzbuf), "%z", lt); + memmove(&tzbuf[4], &tzbuf[3], 3); + tzbuf[3] = ':'; + strlcat(buf, tzbuf, sizeof(buf)); +@@ -263,7 +265,7 @@ + lt->tm_isdst = -1; /* divine correct DST */ + + if (fmt != NULL) { +- t = strptime(p, fmt, lt); ++ t = strptime_bsd(p, fmt, lt); + if (t == NULL) { + fprintf(stderr, "Failed conversion of ``%s''" + " using format ``%s''\n", p, fmt); +@@ -344,14 +346,18 @@ if (!jflag) { utx.ut_type = OLD_TIME; memset(utx.ut_id, 0, sizeof(utx.ut_id)); @@ -1984,6 +2887,15 @@ .Op Fl -color Ns = Ns Ar when .Op Fl D Ar format .Op Ar +@@ -100,7 +100,7 @@ + to format the date and time output. + The argument + .Ar format +-is a string used by ++is a string used by FreeBSD + .Xr strftime 3 . + Depending on the choice of format string, this may result in a + different number of columns in the output. @@ -122,9 +122,6 @@ an equals sign .Pq Ql = @@ -2249,6 +3161,15 @@ #include #include +@@ -54,7 +53,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #ifdef COLORLS @@ -248,7 +247,7 @@ if (f_accesstime) printtime(sp->st_atime); @@ -2258,6 +3179,15 @@ else if (f_statustime) printtime(sp->st_ctime); else +@@ -453,7 +452,7 @@ + } + } + if (tm != NULL) +- strftime(str, len, format, tm); ++ strftime_bsd(str, len, format, tm); + else + strlcpy(str, "bad date val", len); + } @@ -466,8 +465,11 @@ const char *format; static int d_first = -1; @@ -2447,10 +3377,19 @@ #include #include #include -+#include ++#include #include "pr.h" #include "extern.h" +@@ -1401,7 +1402,7 @@ + /* + * set up time field used in header + */ +- if (strftime(buf, HDBUF, timefrmt, timeptr) <= 0) { ++ if (strftime_bsd(buf, HDBUF, timefrmt, timeptr) <= 0) { + ++errcnt; + if (inf != stdin) + (void)fclose(inf); @@ -1857,7 +1858,9 @@ (void) setlocale(LC_TIME, (Lflag != NULL) ? Lflag : ""); @@ -3208,7 +4147,22 @@ .It Fl L Use .Xr stat 2 -@@ -273,11 +264,6 @@ +@@ -182,7 +173,7 @@ + .It Fl t Ar timefmt + Display timestamps using the specified format. + This format is +-passed directly to ++passed directly to FreeBSD + .Xr strftime 3 . + .It Fl x + Display information in a more verbose way as known from some +@@ -268,16 +259,11 @@ + May be used in combination with: + .Bl -tag -width indent + .It Cm amc +-Display date in ++Display date in FreeBSD + .Xr strftime 3 format. .It Cm dr Display actual device name. @@ -3271,6 +4225,15 @@ #include #include +@@ -65,7 +66,7 @@ + #include + #include + #include +-#include ++#include + #include + + #if HAVE_STRUCT_STAT_ST_FLAGS @@ -209,17 +210,14 @@ { struct stat st; @@ -3411,6 +4374,15 @@ /* FALLTHROUGH */ #if HAVE_STRUCT_STAT_ST_BIRTHTIME case SHOW_st_btime: +@@ -760,7 +735,7 @@ + tm = localtime(&ts.tv_sec); + } + (void)setlocale(LC_TIME, ""); +- (void)strftime(path, sizeof(path), timefmt, tm); ++ (void)strftime_bsd(path, sizeof(path), timefmt, tm); + sdata = path; + formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX | + FMTF_FLOAT | FMTF_STRING; @@ -1088,7 +1063,7 @@ #define hex2nibble(c) (c <= '9' ? c - '0' : toupper(c) - 'A' + 10) int @@ -4228,6 +5200,26 @@ if (WEXITSTATUS(pstat)) pstat = WEXITSTATUS(pstat); +--- src.orig/coreutils/touch/touch.c ++++ src.freebsd/coreutils/touch/touch.c +@@ -55,7 +55,7 @@ + #include + #include + #include +-#include ++#include + #include + + static void stime_arg1(const char *, struct timespec *); +@@ -333,7 +333,7 @@ + goto bad; + fmt = strchr(arg, 'T') != NULL ? "%Y-%m-%dT%H:%M:%S" : + "%Y-%m-%d %H:%M:%S"; +- p = strptime(arg, fmt, &t); ++ p = strptime_bsd(arg, fmt, &t); + if (p == NULL) + goto bad; + /* POSIX: must have at least one digit after dot */ --- src.orig/coreutils/tr/cmap.h +++ src.freebsd/coreutils/tr/cmap.h @@ -47,7 +47,7 @@ @@ -4775,11 +5767,13 @@ errno = EILSEQ; --- src.orig/coreutils/who/who.c +++ src.freebsd/coreutils/who/who.c -@@ -45,7 +45,6 @@ +@@ -44,8 +44,7 @@ + #include #include #include - #include +-#include -#include ++#include #include #include @@ -4805,6 +5799,15 @@ state = '?'; idle = 0; +@@ -194,7 +195,7 @@ + printf("%-12s ", ut->ut_line); + t = ut->ut_tv.tv_sec; + tm = localtime(&t); +- strftime(buf, sizeof(buf), d_first ? "%e %b %R" : "%b %e %R", tm); ++ strftime_bsd(buf, sizeof(buf), d_first ? "%e %b %R" : "%b %e %R", tm); + printf("%-*s ", 12, buf); + if (uflag) { + if (idle < 60) @@ -288,7 +289,7 @@ else name = "?"; @@ -5740,7 +6743,7 @@ #include +#include +#include -+#include ++#include -#include "pr.h" #include "diff.h" @@ -5823,6 +6826,34 @@ size_t nc; int last = lastline; const char *state = NULL; +@@ -1670,11 +1663,11 @@ + printf("%s %s\n", diff_format == D_CONTEXT ? "***" : "---", + label[0]); + else { +- strftime(buf, sizeof(buf), time_format, tm_ptr1); ++ strftime_bsd(buf, sizeof(buf), time_format, tm_ptr1); + printf("%s %s\t%s", diff_format == D_CONTEXT ? "***" : "---", + file1, buf); + if (!cflag) { +- strftime(buf, sizeof(buf), "%z", tm_ptr1); ++ strftime_bsd(buf, sizeof(buf), "%z", tm_ptr1); + printf(".%.9d %s", nsec1, buf); + } + printf("\n"); +@@ -1683,11 +1676,11 @@ + printf("%s %s\n", diff_format == D_CONTEXT ? "---" : "+++", + label[1]); + else { +- strftime(buf, sizeof(buf), time_format, tm_ptr2); ++ strftime_bsd(buf, sizeof(buf), time_format, tm_ptr2); + printf("%s %s\t%s", diff_format == D_CONTEXT ? "---" : "+++", + file2, buf); + if (!cflag) { +- strftime(buf, sizeof(buf), "%z", tm_ptr2); ++ strftime_bsd(buf, sizeof(buf), "%z", tm_ptr2); + printf(".%.9d %s", nsec2, buf); + } + printf("\n"); --- src.orig/diffutils/sdiff/sdiff.c +++ src.freebsd/diffutils/sdiff/sdiff.c @@ -260,16 +260,19 @@ @@ -6246,6 +7277,15 @@ #include #include +@@ -48,7 +49,7 @@ + #include + #include + #include +-#include ++#include + #include + + #include "find.h" @@ -62,13 +63,29 @@ printlong(char *name, char *accpath, struct stat *sb) { @@ -6278,6 +7318,15 @@ if (S_ISCHR(sb->st_mode) || S_ISBLK(sb->st_mode)) (void)printf("%#8jx ", (uintmax_t)sb->st_rdev); +@@ -105,7 +122,7 @@ + /* mmm dd yyyy || dd mmm yyyy */ + format = d_first ? "%e %b %Y " : "%b %e %Y "; + if ((tm = localtime(&ftime)) != NULL) +- strftime(longstring, sizeof(longstring), format, tm); ++ strftime_bsd(longstring, sizeof(longstring), format, tm); + else + strlcpy(longstring, "bad date val ", sizeof(longstring)); + fputs(longstring, stdout); --- src.orig/findutils/find/main.c +++ src.freebsd/findutils/find/main.c @@ -32,9 +32,11 @@ @@ -6992,13 +8041,33 @@ setenv("HOME", pw->pw_dir, 1); cal(); exit(0); +--- src.orig/miscutils/calendar/day.c ++++ src.freebsd/miscutils/calendar/day.c +@@ -37,7 +37,7 @@ + #include + #include + #include +-#include ++#include + + #include "calendar.h" + +@@ -65,7 +65,7 @@ + localtime_r(&time2, tp2); + year2 = 1900 + tp2->tm_year; + +- strftime(dayname, sizeof(dayname) - 1, "%A, %d %B %Y", tp1); ++ strftime_bsd(dayname, sizeof(dayname) - 1, "%A, %d %B %Y", tp1); + + setnnames(); + } --- src.orig/miscutils/calendar/events.c +++ src.freebsd/miscutils/calendar/events.c @@ -36,6 +36,7 @@ #include #include #include -+#include ++#include #ifdef WITH_ICONV #include #include @@ -7014,6 +8083,15 @@ while (walkthrough_dates(&e) != 0) { if (e) { +@@ -216,7 +220,7 @@ + tm.tm_mday = e->day; + tm.tm_mon = e->month - 1; + tm.tm_year = e->year - 1900; +- (void)strftime(dbuf, sizeof(dbuf), d_first ? "%e %b" : "%b %e", &tm); ++ (void)strftime_bsd(dbuf, sizeof(dbuf), d_first ? "%e %b" : "%b %e", &tm); + } + + /* --- src.orig/miscutils/calendar/io.c +++ src.freebsd/miscutils/calendar/io.c @@ -120,9 +120,6 @@ @@ -7056,6 +8134,53 @@ return (NULL); } +--- src.orig/miscutils/calendar/locale.c ++++ src.freebsd/miscutils/calendar/locale.c +@@ -37,7 +37,7 @@ + #include + #include + #include +-#include ++#include + + #include "calendar.h" + +@@ -81,7 +81,7 @@ + memset(&tm, 0, sizeof(struct tm)); + for (i = 0; i < 7; i++) { + tm.tm_wday = i; +- strftime(buf, sizeof(buf), "%a", &tm); ++ strftime_bsd(buf, sizeof(buf), "%a", &tm); + for (l = strlen(buf); + l > 0 && isspace((unsigned char)buf[l - 1]); + l--) +@@ -93,7 +93,7 @@ + errx(1, "cannot allocate memory"); + ndays[i].len = strlen(buf); + +- strftime(buf, sizeof(buf), "%A", &tm); ++ strftime_bsd(buf, sizeof(buf), "%A", &tm); + for (l = strlen(buf); + l > 0 && isspace((unsigned char)buf[l - 1]); + l--) +@@ -109,7 +109,7 @@ + memset(&tm, 0, sizeof(struct tm)); + for (i = 0; i < 12; i++) { + tm.tm_mon = i; +- strftime(buf, sizeof(buf), "%b", &tm); ++ strftime_bsd(buf, sizeof(buf), "%b", &tm); + for (l = strlen(buf); + l > 0 && isspace((unsigned char)buf[l - 1]); + l--) +@@ -121,7 +121,7 @@ + errx(1, "cannot allocate memory"); + nmonths[i].len = strlen(buf); + +- strftime(buf, sizeof(buf), "%B", &tm); ++ strftime_bsd(buf, sizeof(buf), "%B", &tm); + for (l = strlen(buf); + l > 0 && isspace((unsigned char)buf[l - 1]); + l--) --- src.orig/miscutils/calendar/pathnames.h +++ src.freebsd/miscutils/calendar/pathnames.h @@ -35,4 +35,4 @@ @@ -7429,6 +8554,15 @@ size_t len2; --- src.orig/miscutils/ncal/ncal.c +++ src.freebsd/miscutils/ncal/ncal.c +@@ -39,7 +39,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + #include @@ -545,8 +545,11 @@ char buf[MAX_WIDTH]; static int d_first = -1; @@ -7443,6 +8577,15 @@ /* force orthodox easter for years before 1583 */ if (y < 1583) orthodox = 1; +@@ -563,7 +566,7 @@ + tm.tm_year = dt.y - 1900; + tm.tm_mon = dt.m - 1; + tm.tm_mday = dt.d; +- strftime(buf, sizeof(buf), d_first ? "%e %B %Y" : "%B %e %Y", &tm); ++ strftime_bsd(buf, sizeof(buf), d_first ? "%e %B %Y" : "%B %e %Y", &tm); + printf("%s\n", buf); + } + @@ -628,12 +631,12 @@ /* Empty line between two rows of months */ @@ -7548,6 +8691,15 @@ return (s); } +@@ -1098,7 +1104,7 @@ + *y = ny; + return (0); + } +- if (strptime(s, "%B", &tm) != NULL || strptime(s, "%b", &tm) != NULL) { ++ if (strptime_bsd(s, "%B", &tm) != NULL || strptime_bsd(s, "%b", &tm) != NULL) { + *m = tm.tm_mon + 1; + return (0); + } --- src.orig/miscutils/rev/rev.c +++ src.freebsd/miscutils/rev/rev.c @@ -57,6 +57,46 @@ @@ -7682,7 +8834,7 @@ #include #include #include -+#include ++#include +#include +#include +#include @@ -7809,6 +8961,15 @@ } \ } while (0/*CONSTCOND*/) +@@ -581,7 +548,7 @@ + if (stamp.scr_len == 0) + continue; + if (tclock - lclock > 0) { +- l = strftime(buf, sizeof buf, tstamp_fmt, ++ l = strftime_bsd(buf, sizeof buf, tstamp_fmt, + localtime(&tclock)); + (void)write(STDOUT_FILENO, buf, l); + } --- src.orig/miscutils/wall/ttymsg.c +++ src.freebsd/miscutils/wall/ttymsg.c @@ -37,6 +37,7 @@ diff --git a/src.freebsd/compat/meson.build b/src.freebsd/compat/meson.build index d0329886..1b0dda72 100644 --- a/src.freebsd/compat/meson.build +++ b/src.freebsd/compat/meson.build @@ -6,6 +6,8 @@ libcompat_sources = [ 'ohash.c', 'setmode.c', 'strmode.c', + 'strftime.c', + 'strptime.c', 'stringlist.c', 'expand_number.c', 'vis.c', diff --git a/src.freebsd/compat/strftime.c b/src.freebsd/compat/strftime.c new file mode 100644 index 00000000..981ff20a --- /dev/null +++ b/src.freebsd/compat/strftime.c @@ -0,0 +1,600 @@ +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#ifndef lint +#ifndef NOID +static const char elsieid[] = "@(#)strftime.3 8.3"; +/* + * Based on the UCB version with the ID appearing below. + * This is ANSIish only when "multibyte character == plain character". + */ +#endif /* !defined NOID */ +#endif /* !defined lint */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89"; +#endif /* LIBC_SCCS and not lint */ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#define DAYSPERWEEK 7 +#define MONSPERYEAR 12 +#define HOURSPERDAY 24 +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define DAYSPERNYEAR 365 +#define DAYSPERLYEAR 366 +#define TM_YEAR_BASE 1900 + +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) +#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) + +static char * _add(const char *, char *, const char *); +static char * _conv(int, const char *, char *, const char *); +static char * _fmt(const char *, const struct tm *, char *, const char *); +static char * _yconv(int, int, int, int, char *, const char *); + +extern char * tzname[]; + +#ifndef YEAR_2000_NAME +#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS" +#endif /* !defined YEAR_2000_NAME */ + +#define IN_NONE 0 +#define IN_SOME 1 +#define IN_THIS 2 +#define IN_ALL 3 + +#define PAD_DEFAULT 0 +#define PAD_LESS 1 +#define PAD_SPACE 2 +#define PAD_ZERO 3 + +static const char fmt_padding[][4][5] = { + /* DEFAULT, LESS, SPACE, ZERO */ +#define PAD_FMT_MONTHDAY 0 +#define PAD_FMT_HMS 0 +#define PAD_FMT_CENTURY 0 +#define PAD_FMT_SHORTYEAR 0 +#define PAD_FMT_MONTH 0 +#define PAD_FMT_WEEKOFYEAR 0 +#define PAD_FMT_DAYOFMONTH 0 + { "%02d", "%d", "%2d", "%02d" }, +#define PAD_FMT_SDAYOFMONTH 1 +#define PAD_FMT_SHMS 1 + { "%2d", "%d", "%2d", "%02d" }, +#define PAD_FMT_DAYOFYEAR 2 + { "%03d", "%d", "%3d", "%03d" }, +#define PAD_FMT_YEAR 3 + { "%04d", "%d", "%4d", "%04d" } +}; + +size_t +strftime_bsd(char * __restrict s, size_t maxsize, const char * __restrict format, + const struct tm * __restrict t) +{ + char * p; + tzset(); + p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize); + if (p == s + maxsize) + return (0); + *p = '\0'; + return p - s; +} + +static char * +_fmt(const char *format, const struct tm * const t, char *pt, + const char * const ptlim) +{ + int Ealternative, Oalternative, PadIndex; + + for ( ; *format; ++format) { + if (*format == '%') { + Ealternative = 0; + Oalternative = 0; + PadIndex = PAD_DEFAULT; +label: + switch (*++format) { + case '\0': + --format; + break; + case 'A': + pt = _add((t->tm_wday < 0 || + t->tm_wday >= DAYSPERWEEK) ? + "?" : nl_langinfo(DAY_1 + t->tm_wday), + pt, ptlim); + continue; + case 'a': + pt = _add((t->tm_wday < 0 || + t->tm_wday >= DAYSPERWEEK) ? + "?" : nl_langinfo(ABDAY_1 + t->tm_wday), + pt, ptlim); + continue; + case 'B': + pt = _add((t->tm_mon < 0 || + t->tm_mon >= MONSPERYEAR) ? + "?" : nl_langinfo(MON_1 + t->tm_mon), + pt, ptlim); + continue; + case 'b': + case 'h': + pt = _add((t->tm_mon < 0 || + t->tm_mon >= MONSPERYEAR) ? + "?" : nl_langinfo(ABMON_1 + t->tm_mon), + pt, ptlim); + continue; + case 'C': + /* + * %C used to do a... + * _fmt("%a %b %e %X %Y", t); + * ...whereas now POSIX 1003.2 calls for + * something completely different. + * (ado, 1993-05-24) + */ + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0, + pt, ptlim); + continue; + case 'c': + pt = _fmt(nl_langinfo(D_T_FMT), t, pt, ptlim); + continue; + case 'D': + pt = _fmt("%m/%d/%y", t, pt, ptlim); + continue; + case 'd': + pt = _conv(t->tm_mday, + fmt_padding[PAD_FMT_DAYOFMONTH][PadIndex], + pt, ptlim); + continue; + case 'E': + if (Ealternative || Oalternative) + break; + Ealternative++; + goto label; + case 'O': + /* + * C99 locale modifiers. + * The sequences + * %Ec %EC %Ex %EX %Ey %EY + * %Od %oe %OH %OI %Om %OM + * %OS %Ou %OU %OV %Ow %OW %Oy + * are supposed to provide alternate + * representations. + * + * FreeBSD extension + * %OB + */ + if (Ealternative || Oalternative) + break; + Oalternative++; + goto label; + case 'e': + pt = _conv(t->tm_mday, + fmt_padding[PAD_FMT_SDAYOFMONTH][PadIndex], + pt, ptlim); + continue; + case 'F': + pt = _fmt("%Y-%m-%d", t, pt, ptlim); + continue; + case 'H': + pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim); + continue; + case 'I': + pt = _conv((t->tm_hour % 12) ? + (t->tm_hour % 12) : 12, + fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim); + continue; + case 'j': + pt = _conv(t->tm_yday + 1, + fmt_padding[PAD_FMT_DAYOFYEAR][PadIndex], + pt, ptlim); + continue; + case 'k': + /* + * This used to be... + * _conv(t->tm_hour % 12 ? + * t->tm_hour % 12 : 12, 2, ' '); + * ...and has been changed to the below to + * match SunOS 4.1.1 and Arnold Robbins' + * strftime version 3.0. That is, "%k" and + * "%l" have been swapped. + * (ado, 1993-05-24) + */ + pt = _conv(t->tm_hour, fmt_padding[PAD_FMT_SHMS][PadIndex], + pt, ptlim); + continue; +#ifdef KITCHEN_SINK + case 'K': + /* + ** After all this time, still unclaimed! + */ + pt = _add("kitchen sink", pt, ptlim); + continue; +#endif /* defined KITCHEN_SINK */ + case 'l': + /* + * This used to be... + * _conv(t->tm_hour, 2, ' '); + * ...and has been changed to the below to + * match SunOS 4.1.1 and Arnold Robbin's + * strftime version 3.0. That is, "%k" and + * "%l" have been swapped. + * (ado, 1993-05-24) + */ + pt = _conv((t->tm_hour % 12) ? + (t->tm_hour % 12) : 12, + fmt_padding[PAD_FMT_SHMS][PadIndex], + pt, ptlim); + continue; + case 'M': + pt = _conv(t->tm_min, fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim); + continue; + case 'm': + pt = _conv(t->tm_mon + 1, + fmt_padding[PAD_FMT_MONTH][PadIndex], + pt, ptlim); + continue; + case 'n': + pt = _add("\n", pt, ptlim); + continue; + case 'p': + pt = _add(nl_langinfo((t->tm_hour >= (HOURSPERDAY / 2)) ? + PM_STR : AM_STR), + pt, ptlim); + continue; + case 'R': + pt = _fmt("%H:%M", t, pt, ptlim); + continue; + case 'r': + pt = _fmt(nl_langinfo(T_FMT_AMPM), t, pt, ptlim); + continue; + case 'S': + pt = _conv(t->tm_sec, fmt_padding[PAD_FMT_HMS][PadIndex], + pt, ptlim); + continue; + case 's': + { + struct tm tm; + char buf[32]; + time_t mkt; + + tm = *t; + mkt = mktime(&tm); + (void) sprintf(buf, "%lld", (long long) mkt); + pt = _add(buf, pt, ptlim); + } + continue; + case 'T': + pt = _fmt("%H:%M:%S", t, pt, ptlim); + continue; + case 't': + pt = _add("\t", pt, ptlim); + continue; + case 'U': + pt = _conv((t->tm_yday + DAYSPERWEEK - + t->tm_wday) / DAYSPERWEEK, + fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], + pt, ptlim); + continue; + case 'u': + /* + * From Arnold Robbins' strftime version 3.0: + * "ISO 8601: Weekday as a decimal number + * [1 (Monday) - 7]" + * (ado, 1993-05-24) + */ + pt = _conv((t->tm_wday == 0) ? + DAYSPERWEEK : t->tm_wday, + "%d", pt, ptlim); + continue; + case 'V': /* ISO 8601 week number */ + case 'G': /* ISO 8601 year (four digits) */ + case 'g': /* ISO 8601 year (two digits) */ +/* + * From Arnold Robbins' strftime version 3.0: "the week number of the + * year (the first Monday as the first day of week 1) as a decimal number + * (01-53)." + * (ado, 1993-05-24) + * + * From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn: + * "Week 01 of a year is per definition the first week which has the + * Thursday in this year, which is equivalent to the week which contains + * the fourth day of January. In other words, the first week of a new year + * is the week which has the majority of its days in the new year. Week 01 + * might also contain days from the previous year and the week before week + * 01 of a year is the last week (52 or 53) of the previous year even if + * it contains days from the new year. A week starts with Monday (day 1) + * and ends with Sunday (day 7). For example, the first week of the year + * 1997 lasts from 1996-12-30 to 1997-01-05..." + * (ado, 1996-01-02) + */ + { + int year; + int base; + int yday; + int wday; + int w; + + year = t->tm_year; + base = TM_YEAR_BASE; + yday = t->tm_yday; + wday = t->tm_wday; + for ( ; ; ) { + int len; + int bot; + int top; + + len = isleap_sum(year, base) ? + DAYSPERLYEAR : + DAYSPERNYEAR; + /* + * What yday (-3 ... 3) does + * the ISO year begin on? + */ + bot = ((yday + 11 - wday) % + DAYSPERWEEK) - 3; + /* + * What yday does the NEXT + * ISO year begin on? + */ + top = bot - + (len % DAYSPERWEEK); + if (top < -3) + top += DAYSPERWEEK; + top += len; + if (yday >= top) { + ++base; + w = 1; + break; + } + if (yday >= bot) { + w = 1 + ((yday - bot) / + DAYSPERWEEK); + break; + } + --base; + yday += isleap_sum(year, base) ? + DAYSPERLYEAR : + DAYSPERNYEAR; + } +#ifdef XPG4_1994_04_09 + if ((w == 52 && + t->tm_mon == TM_JANUARY) || + (w == 1 && + t->tm_mon == TM_DECEMBER)) + w = 53; +#endif /* defined XPG4_1994_04_09 */ + if (*format == 'V') + pt = _conv(w, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], + pt, ptlim); + else if (*format == 'g') { + pt = _yconv(year, base, 0, 1, + pt, ptlim); + } else pt = _yconv(year, base, 1, 1, + pt, ptlim); + } + continue; + case 'v': + /* + * From Arnold Robbins' strftime version 3.0: + * "date as dd-bbb-YYYY" + * (ado, 1993-05-24) + */ + pt = _fmt("%e-%b-%Y", t, pt, ptlim); + continue; + case 'W': + pt = _conv((t->tm_yday + DAYSPERWEEK - + (t->tm_wday ? + (t->tm_wday - 1) : + (DAYSPERWEEK - 1))) / DAYSPERWEEK, + fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], + pt, ptlim); + continue; + case 'w': + pt = _conv(t->tm_wday, "%d", pt, ptlim); + continue; + case 'X': + pt = _fmt(nl_langinfo(T_FMT), t, pt, ptlim); + continue; + case 'x': + pt = _fmt(nl_langinfo(D_FMT), t, pt, ptlim); + continue; + case 'y': + pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1, + pt, ptlim); + continue; + case 'Y': + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1, + pt, ptlim); + continue; + case 'Z': +#ifdef TM_ZONE + if (t->TM_ZONE != NULL) + pt = _add(t->TM_ZONE, pt, ptlim); + else +#endif /* defined TM_ZONE */ + if (t->tm_isdst >= 0) + pt = _add(tzname[t->tm_isdst != 0], + pt, ptlim); + /* + * C99 says that %Z must be replaced by the + * empty string if the time zone is not + * determinable. + */ + continue; + case 'z': + { + int diff; + char const * sign; + + if (t->tm_isdst < 0) + continue; +#ifdef TM_GMTOFF + diff = t->TM_GMTOFF; +#else /* !defined TM_GMTOFF */ + /* + * C99 says that the UTC offset must + * be computed by looking only at + * tm_isdst. This requirement is + * incorrect, since it means the code + * must rely on magic (in this case + * altzone and timezone), and the + * magic might not have the correct + * offset. Doing things correctly is + * tricky and requires disobeying C99; + * see GNU C strftime for details. + * For now, punt and conform to the + * standard, even though it's incorrect. + * + * C99 says that %z must be replaced by the + * empty string if the time zone is not + * determinable, so output nothing if the + * appropriate variables are not available. + */ + if (t->tm_isdst == 0) +#ifdef USG_COMPAT + diff = -timezone; +#else /* !defined USG_COMPAT */ + continue; +#endif /* !defined USG_COMPAT */ + else +#ifdef ALTZONE + diff = -altzone; +#else /* !defined ALTZONE */ + continue; +#endif /* !defined ALTZONE */ +#endif /* !defined TM_GMTOFF */ + if (diff < 0) { + sign = "-"; + diff = -diff; + } else + sign = "+"; + pt = _add(sign, pt, ptlim); + diff /= SECSPERMIN; + diff = (diff / MINSPERHOUR) * 100 + + (diff % MINSPERHOUR); + pt = _conv(diff, + fmt_padding[PAD_FMT_YEAR][PadIndex], + pt, ptlim); + } + continue; + case '+': +#ifdef _DATE_FMT + pt = _fmt(nl_langinfo(_DATE_FMT), t, pt, ptlim); +#else + pt = _fmt("%a %b %e %H:%M:%S %Z %Y", t, pt, ptlim); +#endif + continue; + case '-': + if (PadIndex != PAD_DEFAULT) + break; + PadIndex = PAD_LESS; + goto label; + case '_': + if (PadIndex != PAD_DEFAULT) + break; + PadIndex = PAD_SPACE; + goto label; + case '0': + if (PadIndex != PAD_DEFAULT) + break; + PadIndex = PAD_ZERO; + goto label; + case '%': + /* + * X311J/88-090 (4.12.3.5): if conversion char is + * undefined, behavior is undefined. Print out the + * character itself as printf(3) also does. + */ + default: + break; + } + } + if (pt == ptlim) + break; + *pt++ = *format; + } + return (pt); +} + +static char * +_conv(const int n, const char * const format, char * const pt, + const char * const ptlim) +{ + char buf[16]; + + (void) sprintf(buf, format, n); + return _add(buf, pt, ptlim); +} + +static char * +_add(const char *str, char *pt, const char * const ptlim) +{ + while (pt < ptlim && (*pt = *str++) != '\0') + ++pt; + return (pt); +} + +/* + * POSIX and the C Standard are unclear or inconsistent about + * what %C and %y do if the year is negative or exceeds 9999. + * Use the convention that %C concatenated with %y yields the + * same output as %Y, and that %Y contains at least 4 bytes, + * with more only if necessary. + */ + +static char * +_yconv(const int a, const int b, const int convert_top, const int convert_yy, + char *pt, const char * const ptlim) +{ + register int lead; + register int trail; + +#define DIVISOR 100 + trail = a % DIVISOR + b % DIVISOR; + lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR; + trail %= DIVISOR; + if (trail < 0 && lead > 0) { + trail += DIVISOR; + --lead; + } else if (lead < 0 && trail > 0) { + trail -= DIVISOR; + ++lead; + } + if (convert_top) { + if (lead == 0 && trail < 0) + pt = _add("-0", pt, ptlim); + else pt = _conv(lead, "%02d", pt, ptlim); + } + if (convert_yy) + pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, + ptlim); + return (pt); +} diff --git a/src.freebsd/compat/strptime.c b/src.freebsd/compat/strptime.c new file mode 100644 index 00000000..50563971 --- /dev/null +++ b/src.freebsd/compat/strptime.c @@ -0,0 +1,723 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Gary Mills + * Copyright 2011, Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 1994 Powerdog Industries. All rights reserved. + * + * Copyright (c) 2011 The FreeBSD Foundation + * All rights reserved. + * Portions of this software were developed by David Chisnall + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY POWERDOG INDUSTRIES ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE POWERDOG INDUSTRIES BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of Powerdog Industries. + */ + +#include +#ifndef lint +#ifndef NOID +static char copyright[] __unused = +"@(#) Copyright (c) 1994 Powerdog Industries. All rights reserved."; +static char sccsid[] __unused = "@(#)strptime.c 0.1 (Powerdog) 94/03/27"; +#endif /* !defined NOID */ +#endif /* not lint */ +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#define DAYSPERWEEK 7 +#define MONSPERYEAR 12 +#define TM_SUNDAY 0 +#define TM_MONDAY 1 +#define TM_YEAR_BASE 1900 + +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) + +static char * _strptime(const char *, const char *, struct tm *, int *); + +#define asizeof(a) (sizeof(a) / sizeof((a)[0])) + +#define FLAG_NONE (1 << 0) +#define FLAG_YEAR (1 << 1) +#define FLAG_MONTH (1 << 2) +#define FLAG_YDAY (1 << 3) +#define FLAG_MDAY (1 << 4) +#define FLAG_WDAY (1 << 5) + +/* + * Calculate the week day of the first day of a year. Valid for + * the Gregorian calendar, which began Sept 14, 1752 in the UK + * and its colonies. Ref: + * http://en.wikipedia.org/wiki/Determination_of_the_day_of_the_week + */ + +static int +first_wday_of(int year) +{ + return (((2 * (3 - (year / 100) % 4)) + (year % 100) + + ((year % 100) / 4) + (isleap(year) ? 6 : 0) + 1) % 7); +} + +static char * +_strptime(const char *buf, const char *fmt, struct tm *tm, int *GMTp) +{ + char c; + const char *ptr, *ex; + int day_offset = -1, wday_offset; + int week_offset; + int i, len; + int flags; + int Ealternative, Oalternative; + int century, year; + static int start_of_month[2][13] = { + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, + {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366} + }; + + flags = FLAG_NONE; + century = -1; + year = -1; + + ptr = fmt; + while (*ptr != 0) { + c = *ptr++; + + if (c != '%') { + if (isspace((unsigned char)c)) + while (*buf != 0 && + isspace((unsigned char)*buf)) + buf++; + else if (c != *buf++) + return (NULL); + continue; + } + + Ealternative = 0; + Oalternative = 0; +label: + c = *ptr++; + switch (c) { + case '%': + if (*buf++ != '%') + return (NULL); + break; + + case '+': +#ifdef _DATE_FMT + buf = _strptime(buf, nl_langinfo(_DATE_FMT), tm, GMTp); +#else + buf = _strptime(buf, "%a %b %e %H:%M:%S %Z %Y", tm, GMTp); +#endif + if (buf == NULL) + return (NULL); + flags |= FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + break; + + case 'C': + if (!isdigit((unsigned char)*buf)) + return (NULL); + + /* XXX This will break for 3-digit centuries. */ + len = 2; + for (i = 0; len && *buf != 0 && + isdigit((unsigned char)*buf); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + + century = i; + flags |= FLAG_YEAR; + + break; + + case 'c': + buf = _strptime(buf, nl_langinfo(D_T_FMT), tm, GMTp); + if (buf == NULL) + return (NULL); + flags |= FLAG_WDAY | FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + break; + + case 'D': + buf = _strptime(buf, "%m/%d/%y", tm, GMTp); + if (buf == NULL) + return (NULL); + flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + break; + + case 'E': + if (Ealternative || Oalternative) + break; + Ealternative++; + goto label; + + case 'O': + if (Ealternative || Oalternative) + break; + Oalternative++; + goto label; + + case 'F': + buf = _strptime(buf, "%Y-%m-%d", tm, GMTp); + if (buf == NULL) + return (NULL); + flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + break; + + case 'R': + buf = _strptime(buf, "%H:%M", tm, GMTp); + if (buf == NULL) + return (NULL); + break; + + case 'r': + buf = _strptime(buf, nl_langinfo(T_FMT_AMPM), tm, GMTp); + if (buf == NULL) + return (NULL); + break; + + case 'T': + buf = _strptime(buf, "%H:%M:%S", tm, GMTp); + if (buf == NULL) + return (NULL); + break; + + case 'X': + buf = _strptime(buf, nl_langinfo(T_FMT), tm, GMTp); + if (buf == NULL) + return (NULL); + break; + + case 'x': + buf = _strptime(buf, nl_langinfo(D_FMT), tm, GMTp); + if (buf == NULL) + return (NULL); + flags |= FLAG_MONTH | FLAG_MDAY | FLAG_YEAR; + break; + + case 'j': + if (!isdigit((unsigned char)*buf)) + return (NULL); + + len = 3; + for (i = 0; len && *buf != 0 && + isdigit((unsigned char)*buf); buf++){ + i *= 10; + i += *buf - '0'; + len--; + } + if (i < 1 || i > 366) + return (NULL); + + tm->tm_yday = i - 1; + flags |= FLAG_YDAY; + + break; + + case 'M': + case 'S': + if (*buf == 0 || + isspace((unsigned char)*buf)) + break; + + if (!isdigit((unsigned char)*buf)) + return (NULL); + + len = 2; + for (i = 0; len && *buf != 0 && + isdigit((unsigned char)*buf); buf++){ + i *= 10; + i += *buf - '0'; + len--; + } + + if (c == 'M') { + if (i > 59) + return (NULL); + tm->tm_min = i; + } else { + if (i > 60) + return (NULL); + tm->tm_sec = i; + } + + break; + + case 'H': + case 'I': + case 'k': + case 'l': + /* + * %k and %l specifiers are documented as being + * blank-padded. However, there is no harm in + * allowing zero-padding. + * + * XXX %k and %l specifiers may gobble one too many + * digits if used incorrectly. + */ + + len = 2; + if ((c == 'k' || c == 'l') && + isblank((unsigned char)*buf)) { + buf++; + len = 1; + } + + if (!isdigit((unsigned char)*buf)) + return (NULL); + + for (i = 0; len && *buf != 0 && + isdigit((unsigned char)*buf); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + if (c == 'H' || c == 'k') { + if (i > 23) + return (NULL); + } else if (i == 0 || i > 12) + return (NULL); + + tm->tm_hour = i; + + break; + + case 'p': + /* + * XXX This is bogus if parsed before hour-related + * specifiers. + */ + if (tm->tm_hour > 12) + return (NULL); + + ex = nl_langinfo(AM_STR); + len = strlen(ex); + if (strncasecmp(buf, ex, len) == 0) { + if (tm->tm_hour == 12) + tm->tm_hour = 0; + buf += len; + break; + } + + ex = nl_langinfo(PM_STR); + len = strlen(ex); + if (strncasecmp(buf, ex, len) == 0) { + if (tm->tm_hour != 12) + tm->tm_hour += 12; + buf += len; + break; + } + + return (NULL); + + case 'A': + case 'a': + for (i = 0; i < DAYSPERWEEK; i++) { + ex = nl_langinfo(DAY_1 + i); + len = strlen(ex); + if (strncasecmp(buf, ex, len) == 0) + break; + ex = nl_langinfo(ABDAY_1 + i); + len = strlen(ex); + if (strncasecmp(buf, ex, len) == 0) + break; + } + if (i == DAYSPERWEEK) + return (NULL); + + buf += len; + tm->tm_wday = i; + flags |= FLAG_WDAY; + break; + + case 'U': + case 'W': + /* + * XXX This is bogus, as we can not assume any valid + * information present in the tm structure at this + * point to calculate a real value, so just check the + * range for now. + */ + if (!isdigit((unsigned char)*buf)) + return (NULL); + + len = 2; + for (i = 0; len && *buf != 0 && + isdigit((unsigned char)*buf); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + if (i > 53) + return (NULL); + + if (c == 'U') + day_offset = TM_SUNDAY; + else + day_offset = TM_MONDAY; + + + week_offset = i; + + break; + + case 'u': + case 'w': + if (!isdigit((unsigned char)*buf)) + return (NULL); + + i = *buf++ - '0'; + if (i < 0 || i > 7 || (c == 'u' && i < 1) || + (c == 'w' && i > 6)) + return (NULL); + + tm->tm_wday = i % 7; + flags |= FLAG_WDAY; + + break; + + case 'e': + /* + * With %e format, our strftime(3) adds a blank space + * before single digits. + */ + if (*buf != 0 && + isspace((unsigned char)*buf)) + buf++; + /* FALLTHROUGH */ + case 'd': + /* + * The %e specifier was once explicitly documented as + * not being zero-padded but was later changed to + * equivalent to %d. There is no harm in allowing + * such padding. + * + * XXX The %e specifier may gobble one too many + * digits if used incorrectly. + */ + if (!isdigit((unsigned char)*buf)) + return (NULL); + + len = 2; + for (i = 0; len && *buf != 0 && + isdigit((unsigned char)*buf); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + if (i == 0 || i > 31) + return (NULL); + + tm->tm_mday = i; + flags |= FLAG_MDAY; + + break; + + case 'B': + case 'b': + case 'h': + for (i = 0; i < MONSPERYEAR; i++) { + if (Oalternative) { + if (c == 'B') { + ex = nl_langinfo(MON_1 + i); + len = strlen(ex); + if (strncasecmp(buf, ex, len) == 0) + break; + } + } else { + ex = nl_langinfo(MON_1 + i); + len = strlen(ex); + if (strncasecmp(buf, ex, len) == 0) + break; + } + } + /* + * Try the abbreviated month name if the full name + * wasn't found and Oalternative was not requested. + */ + if (i == MONSPERYEAR && !Oalternative) { + for (i = 0; i < MONSPERYEAR; i++) { + ex = nl_langinfo(ABMON_1 + i); + len = strlen(ex); + if (strncasecmp(buf, ex, len) == 0) + break; + } + } + if (i == MONSPERYEAR) + return (NULL); + + tm->tm_mon = i; + buf += len; + flags |= FLAG_MONTH; + + break; + + case 'm': + if (!isdigit((unsigned char)*buf)) + return (NULL); + + len = 2; + for (i = 0; len && *buf != 0 && + isdigit((unsigned char)*buf); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + if (i < 1 || i > 12) + return (NULL); + + tm->tm_mon = i - 1; + flags |= FLAG_MONTH; + + break; + + case 's': + { + char *cp; + int sverrno; + long n; + time_t t; + + sverrno = errno; + errno = 0; + n = strtol(buf, &cp, 10); + if (errno == ERANGE || (long)(t = n) != n) { + errno = sverrno; + return (NULL); + } + errno = sverrno; + buf = cp; + if (gmtime_r(&t, tm) == NULL) + return (NULL); + *GMTp = 1; + flags |= FLAG_YDAY | FLAG_WDAY | FLAG_MONTH | + FLAG_MDAY | FLAG_YEAR; + } + break; + + case 'Y': + case 'y': + if (*buf == 0 || + isspace((unsigned char)*buf)) + break; + + if (!isdigit((unsigned char)*buf)) + return (NULL); + + len = (c == 'Y') ? 4 : 2; + for (i = 0; len && *buf != 0 && + isdigit((unsigned char)*buf); buf++) { + i *= 10; + i += *buf - '0'; + len--; + } + if (c == 'Y') + century = i / 100; + year = i % 100; + + flags |= FLAG_YEAR; + + break; + + case 'Z': + { + const char *cp; + char *zonestr; + + for (cp = buf; *cp && + isupper((unsigned char)*cp); ++cp) { + /*empty*/} + if (cp - buf) { + zonestr = alloca(cp - buf + 1); + strncpy(zonestr, buf, cp - buf); + zonestr[cp - buf] = '\0'; + tzset(); + if (0 == strcmp(zonestr, "GMT") || + 0 == strcmp(zonestr, "UTC")) { + *GMTp = 1; + } else if (0 == strcmp(zonestr, tzname[0])) { + tm->tm_isdst = 0; + } else if (0 == strcmp(zonestr, tzname[1])) { + tm->tm_isdst = 1; + } else { + return (NULL); + } + buf += cp - buf; + } + } + break; + + case 'z': + { + int sign = 1; + + if (*buf != '+') { + if (*buf == '-') + sign = -1; + else + return (NULL); + } + + buf++; + i = 0; + for (len = 4; len > 0; len--) { + if (isdigit((unsigned char)*buf)) { + i *= 10; + i += *buf - '0'; + buf++; + } else if (len == 2) { + i *= 100; + break; + } else + return (NULL); + } + + if (i > 1400 || (sign == -1 && i > 1200) || + (i % 100) >= 60) + return (NULL); + tm->tm_hour -= sign * (i / 100); + tm->tm_min -= sign * (i % 100); + *GMTp = 1; + } + break; + + case 'n': + case 't': + while (isspace((unsigned char)*buf)) + buf++; + break; + + default: + return (NULL); + } + } + + if (century != -1 || year != -1) { + if (year == -1) + year = 0; + if (century == -1) { + if (year < 69) + year += 100; + } else + year += century * 100 - TM_YEAR_BASE; + tm->tm_year = year; + } + + if (!(flags & FLAG_YDAY) && (flags & FLAG_YEAR)) { + if ((flags & (FLAG_MONTH | FLAG_MDAY)) == + (FLAG_MONTH | FLAG_MDAY)) { + tm->tm_yday = start_of_month[isleap(tm->tm_year + + TM_YEAR_BASE)][tm->tm_mon] + (tm->tm_mday - 1); + flags |= FLAG_YDAY; + } else if (day_offset != -1) { + int tmpwday, tmpyday, fwo; + + fwo = first_wday_of(tm->tm_year + TM_YEAR_BASE); + /* No incomplete week (week 0). */ + if (week_offset == 0 && fwo == day_offset) + return (NULL); + + /* Set the date to the first Sunday (or Monday) + * of the specified week of the year. + */ + tmpwday = (flags & FLAG_WDAY) ? tm->tm_wday : + day_offset; + tmpyday = (7 - fwo + day_offset) % 7 + + (week_offset - 1) * 7 + + (tmpwday - day_offset + 7) % 7; + /* Impossible yday for incomplete week (week 0). */ + if (tmpyday < 0) { + if (flags & FLAG_WDAY) + return (NULL); + tmpyday = 0; + } + tm->tm_yday = tmpyday; + flags |= FLAG_YDAY; + } + } + + if ((flags & (FLAG_YEAR | FLAG_YDAY)) == (FLAG_YEAR | FLAG_YDAY)) { + if (!(flags & FLAG_MONTH)) { + i = 0; + while (tm->tm_yday >= + start_of_month[isleap(tm->tm_year + + TM_YEAR_BASE)][i]) + i++; + if (i > 12) { + i = 1; + tm->tm_yday -= + start_of_month[isleap(tm->tm_year + + TM_YEAR_BASE)][12]; + tm->tm_year++; + } + tm->tm_mon = i - 1; + flags |= FLAG_MONTH; + } + if (!(flags & FLAG_MDAY)) { + tm->tm_mday = tm->tm_yday - + start_of_month[isleap(tm->tm_year + TM_YEAR_BASE)] + [tm->tm_mon] + 1; + flags |= FLAG_MDAY; + } + if (!(flags & FLAG_WDAY)) { + i = 0; + wday_offset = first_wday_of(tm->tm_year); + while (i++ <= tm->tm_yday) { + if (wday_offset++ >= 6) + wday_offset = 0; + } + tm->tm_wday = wday_offset; + flags |= FLAG_WDAY; + } + } + + return ((char *)buf); +} + +char * +strptime_bsd(const char * __restrict buf, const char * __restrict fmt, + struct tm * __restrict tm) +{ + char *ret; + int gmt; + + gmt = 0; + ret = _strptime(buf, fmt, tm, &gmt); + if (ret && gmt) { + time_t t = timegm(tm); + + localtime_r(&t, tm); + } + + return (ret); +} diff --git a/src.freebsd/coreutils/date/date.1 b/src.freebsd/coreutils/date/date.1 index 0fbc8b90..2d4c8f9d 100644 --- a/src.freebsd/coreutils/date/date.1 +++ b/src.freebsd/coreutils/date/date.1 @@ -126,7 +126,7 @@ provided rather than using the default .Oc Ar MM Op Cm \&. Ar SS .Sm on format. -Parsing is done using +Parsing is done using FreeBSD .Xr strptime 3 . .It Fl I Ns Op Ar FMT Use @@ -310,7 +310,7 @@ which specifies the format in which to display the date and time. The format string may contain any of the conversion specifications described in the .Xr strftime 3 -manual page, as well as any arbitrary text. +FreeBSD manual page, as well as any arbitrary text. A newline .Pq Ql \en character is always output after the characters specified by diff --git a/src.freebsd/coreutils/date/date.c b/src.freebsd/coreutils/date/date.c index 93d72862..6f8bc675 100644 --- a/src.freebsd/coreutils/date/date.c +++ b/src.freebsd/coreutils/date/date.c @@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include "vary.h" @@ -166,14 +166,7 @@ main(int argc, char *argv[]) if (!rflag && time(&tval) == -1) err(1, "time"); - /* Linux libc's do not support %+ */ -#ifdef _DATE_FMT - /* glibc extension */ - format = nl_langinfo(_DATE_FMT); -#else - /* fallback, e.g. musl */ - format = "%a %b %e %H:%M:%S %Z %Y"; -#endif + format = "%+"; if (Rflag) format = rfc2822_format; @@ -220,7 +213,7 @@ main(int argc, char *argv[]) */ setlocale(LC_TIME, "C"); - (void)strftime(buf, sizeof(buf), format, lt); + (void)strftime_bsd(buf, sizeof(buf), format, lt); printdate(buf); } @@ -243,10 +236,10 @@ printisodate(struct tm *lt) for (it = iso8601_fmts; it <= iso8601_selected; it++) strlcat(fmtbuf, it->format_string, sizeof(fmtbuf)); - (void)strftime(buf, sizeof(buf), fmtbuf, lt); + (void)strftime_bsd(buf, sizeof(buf), fmtbuf, lt); if (iso8601_selected > iso8601_fmts) { - (void)strftime(tzbuf, sizeof(tzbuf), "%z", lt); + (void)strftime_bsd(tzbuf, sizeof(tzbuf), "%z", lt); memmove(&tzbuf[4], &tzbuf[3], 3); tzbuf[3] = ':'; strlcat(buf, tzbuf, sizeof(buf)); @@ -272,7 +265,7 @@ setthetime(const char *fmt, const char *p, int jflag) lt->tm_isdst = -1; /* divine correct DST */ if (fmt != NULL) { - t = strptime(p, fmt, lt); + t = strptime_bsd(p, fmt, lt); if (t == NULL) { fprintf(stderr, "Failed conversion of ``%s''" " using format ``%s''\n", p, fmt); diff --git a/src.freebsd/coreutils/date/meson.build b/src.freebsd/coreutils/date/meson.build index 983ee3bd..ac37b65c 100644 --- a/src.freebsd/coreutils/date/meson.build +++ b/src.freebsd/coreutils/date/meson.build @@ -1,11 +1,9 @@ date_prog = executable( 'date', - [ 'date.c', - 'vary.c', - ], - include_directories : inc, - link_with : [ libcompat ], - install : true, + ['date.c', 'vary.c',], + include_directories: [inc], + link_with: [libcompat], + install: true, ) install_man('date.1') diff --git a/src.freebsd/coreutils/ls/ls.1 b/src.freebsd/coreutils/ls/ls.1 index 7456dbe6..f54d7a32 100644 --- a/src.freebsd/coreutils/ls/ls.1 +++ b/src.freebsd/coreutils/ls/ls.1 @@ -100,7 +100,7 @@ format, use to format the date and time output. The argument .Ar format -is a string used by +is a string used by FreeBSD .Xr strftime 3 . Depending on the choice of format string, this may result in a different number of columns in the output. diff --git a/src.freebsd/coreutils/ls/meson.build b/src.freebsd/coreutils/ls/meson.build index b44448e6..0254820c 100644 --- a/src.freebsd/coreutils/ls/meson.build +++ b/src.freebsd/coreutils/ls/meson.build @@ -9,7 +9,7 @@ endif ls_prog = executable( 'ls', ['cmp.c', 'ls.c', 'print.c', 'util.c'], c_args: ls_cargs, - include_directories: inc, + include_directories: [inc], link_with: [libcompat], dependencies: ls_deps, install: true, @@ -18,7 +18,7 @@ ls_prog = executable( if tiny.enabled() and get_option('color_ls') lstiny_prog = executable( 'ls.tiny', ['cmp.c', 'ls.c', 'print.c', 'util.c'], - include_directories: inc, + include_directories: [inc], link_with: [libcompat], dependencies: [libfts], install: true diff --git a/src.freebsd/coreutils/ls/print.c b/src.freebsd/coreutils/ls/print.c index 98b38cd9..e6374319 100644 --- a/src.freebsd/coreutils/ls/print.c +++ b/src.freebsd/coreutils/ls/print.c @@ -53,7 +53,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include #ifdef COLORLS @@ -452,7 +452,7 @@ ls_strftime(char *str, size_t len, const char *fmt, const struct tm *tm) } } if (tm != NULL) - strftime(str, len, format, tm); + strftime_bsd(str, len, format, tm); else strlcpy(str, "bad date val", len); } diff --git a/src.freebsd/coreutils/pr/meson.build b/src.freebsd/coreutils/pr/meson.build index fb1269df..d7c11240 100644 --- a/src.freebsd/coreutils/pr/meson.build +++ b/src.freebsd/coreutils/pr/meson.build @@ -1,10 +1,9 @@ pr_prog = executable( 'pr', - [ 'egetopt.c', - 'pr.c' - ], - include_directories : inc, - install : true, + ['egetopt.c', 'pr.c'], + include_directories: [inc], + link_with: [libcompat], + install: true, ) install_man('pr.1') diff --git a/src.freebsd/coreutils/pr/pr.c b/src.freebsd/coreutils/pr/pr.c index 4e8e25f4..f50273f0 100644 --- a/src.freebsd/coreutils/pr/pr.c +++ b/src.freebsd/coreutils/pr/pr.c @@ -65,7 +65,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include "pr.h" #include "extern.h" @@ -1402,7 +1402,7 @@ nxtfile(int argc, char **argv, const char **fname, char *buf, int dt) /* * set up time field used in header */ - if (strftime(buf, HDBUF, timefrmt, timeptr) <= 0) { + if (strftime_bsd(buf, HDBUF, timefrmt, timeptr) <= 0) { ++errcnt; if (inf != stdin) (void)fclose(inf); diff --git a/src.freebsd/coreutils/stat/meson.build b/src.freebsd/coreutils/stat/meson.build index 5ac43b43..4f687ba0 100644 --- a/src.freebsd/coreutils/stat/meson.build +++ b/src.freebsd/coreutils/stat/meson.build @@ -1,9 +1,9 @@ stat_prog = executable( 'stat', - [ 'stat.c' ], - include_directories : [ inc, ], - link_with : [ libcompat, ], - install : true, + ['stat.c'], + include_directories: [inc], + link_with: [libcompat], + install: true, ) install_man('stat.1') diff --git a/src.freebsd/coreutils/stat/stat.1 b/src.freebsd/coreutils/stat/stat.1 index dfdb9061..44d8e307 100644 --- a/src.freebsd/coreutils/stat/stat.1 +++ b/src.freebsd/coreutils/stat/stat.1 @@ -173,7 +173,7 @@ suitable for initializing variables. .It Fl t Ar timefmt Display timestamps using the specified format. This format is -passed directly to +passed directly to FreeBSD .Xr strftime 3 . .It Fl x Display information in a more verbose way as known from some @@ -259,7 +259,7 @@ applicable, should be in string format. May be used in combination with: .Bl -tag -width indent .It Cm amc -Display date in +Display date in FreeBSD .Xr strftime 3 format. .It Cm dr diff --git a/src.freebsd/coreutils/stat/stat.c b/src.freebsd/coreutils/stat/stat.c index b710512b..f20e4c76 100644 --- a/src.freebsd/coreutils/stat/stat.c +++ b/src.freebsd/coreutils/stat/stat.c @@ -66,7 +66,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #if HAVE_STRUCT_STAT_ST_FLAGS @@ -735,7 +735,7 @@ format1(const struct stat *st, tm = localtime(&ts.tv_sec); } (void)setlocale(LC_TIME, ""); - (void)strftime(path, sizeof(path), timefmt, tm); + (void)strftime_bsd(path, sizeof(path), timefmt, tm); sdata = path; formats = FMTF_DECIMAL | FMTF_OCTAL | FMTF_UNSIGNED | FMTF_HEX | FMTF_FLOAT | FMTF_STRING; diff --git a/src.freebsd/coreutils/touch/meson.build b/src.freebsd/coreutils/touch/meson.build index 37d04b8a..73b32b27 100644 --- a/src.freebsd/coreutils/touch/meson.build +++ b/src.freebsd/coreutils/touch/meson.build @@ -1,8 +1,9 @@ touch_prog = executable( 'touch', - [ 'touch.c' ], - include_directories : inc, - install : true, + ['touch.c'], + include_directories: [inc], + link_with: [libcompat], + install: true, ) install_man('touch.1') diff --git a/src.freebsd/coreutils/touch/touch.c b/src.freebsd/coreutils/touch/touch.c index 1594eacb..032302b2 100644 --- a/src.freebsd/coreutils/touch/touch.c +++ b/src.freebsd/coreutils/touch/touch.c @@ -55,7 +55,7 @@ static const char sccsid[] = "@(#)touch.c 8.1 (Berkeley) 6/6/93"; #include #include #include -#include +#include #include static void stime_arg1(const char *, struct timespec *); @@ -333,7 +333,7 @@ stime_darg(const char *arg, struct timespec *tvp) goto bad; fmt = strchr(arg, 'T') != NULL ? "%Y-%m-%dT%H:%M:%S" : "%Y-%m-%d %H:%M:%S"; - p = strptime(arg, fmt, &t); + p = strptime_bsd(arg, fmt, &t); if (p == NULL) goto bad; /* POSIX: must have at least one digit after dot */ diff --git a/src.freebsd/coreutils/who/meson.build b/src.freebsd/coreutils/who/meson.build index 917dda3d..92cdff31 100644 --- a/src.freebsd/coreutils/who/meson.build +++ b/src.freebsd/coreutils/who/meson.build @@ -1,9 +1,9 @@ who_prog = executable( 'who', - [ 'who.c' ], - include_directories : [ inc, ], - link_with : [ libcompat ], - install : true, + ['who.c'], + include_directories: [inc], + link_with: [libcompat], + install: true, ) install_man('who.1') diff --git a/src.freebsd/coreutils/who/who.c b/src.freebsd/coreutils/who/who.c index ef935a56..154e355b 100644 --- a/src.freebsd/coreutils/who/who.c +++ b/src.freebsd/coreutils/who/who.c @@ -44,7 +44,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include @@ -195,7 +195,7 @@ row(const struct utmpx *ut) printf("%-12s ", ut->ut_line); t = ut->ut_tv.tv_sec; tm = localtime(&t); - strftime(buf, sizeof(buf), d_first ? "%e %b %R" : "%b %e %R", tm); + strftime_bsd(buf, sizeof(buf), d_first ? "%e %b %R" : "%b %e %R", tm); printf("%-*s ", 12, buf); if (uflag) { if (idle < 60) diff --git a/src.freebsd/diffutils/diff/diffreg.c b/src.freebsd/diffutils/diff/diffreg.c index 02a0ece3..2b6ec068 100644 --- a/src.freebsd/diffutils/diff/diffreg.c +++ b/src.freebsd/diffutils/diff/diffreg.c @@ -87,7 +87,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include "diff.h" #include "xmalloc.h" @@ -1663,11 +1663,11 @@ print_header(const char *file1, const char *file2) printf("%s %s\n", diff_format == D_CONTEXT ? "***" : "---", label[0]); else { - strftime(buf, sizeof(buf), time_format, tm_ptr1); + strftime_bsd(buf, sizeof(buf), time_format, tm_ptr1); printf("%s %s\t%s", diff_format == D_CONTEXT ? "***" : "---", file1, buf); if (!cflag) { - strftime(buf, sizeof(buf), "%z", tm_ptr1); + strftime_bsd(buf, sizeof(buf), "%z", tm_ptr1); printf(".%.9d %s", nsec1, buf); } printf("\n"); @@ -1676,11 +1676,11 @@ print_header(const char *file1, const char *file2) printf("%s %s\n", diff_format == D_CONTEXT ? "---" : "+++", label[1]); else { - strftime(buf, sizeof(buf), time_format, tm_ptr2); + strftime_bsd(buf, sizeof(buf), time_format, tm_ptr2); printf("%s %s\t%s", diff_format == D_CONTEXT ? "---" : "+++", file2, buf); if (!cflag) { - strftime(buf, sizeof(buf), "%z", tm_ptr2); + strftime_bsd(buf, sizeof(buf), "%z", tm_ptr2); printf(".%.9d %s", nsec2, buf); } printf("\n"); diff --git a/src.freebsd/diffutils/diff/meson.build b/src.freebsd/diffutils/diff/meson.build index 12b70a7a..da42c1ad 100644 --- a/src.freebsd/diffutils/diff/meson.build +++ b/src.freebsd/diffutils/diff/meson.build @@ -1,9 +1,9 @@ diff_prog = executable( 'diff', - [ 'diff.c', 'diffdir.c', 'diffreg.c', 'xmalloc.c', ], - include_directories : inc, - link_with : [ libcompat ], - install : true, + ['diff.c', 'diffdir.c', 'diffreg.c', 'xmalloc.c'], + include_directories: [inc], + link_with: [libcompat], + install: true, ) install_man('diff.1') diff --git a/src.freebsd/findutils/find/ls.c b/src.freebsd/findutils/find/ls.c index cd5cbf8b..9cbb56ac 100644 --- a/src.freebsd/findutils/find/ls.c +++ b/src.freebsd/findutils/find/ls.c @@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include "find.h" @@ -122,7 +122,7 @@ printtime(time_t ftime) /* mmm dd yyyy || dd mmm yyyy */ format = d_first ? "%e %b %Y " : "%b %e %Y "; if ((tm = localtime(&ftime)) != NULL) - strftime(longstring, sizeof(longstring), format, tm); + strftime_bsd(longstring, sizeof(longstring), format, tm); else strlcpy(longstring, "bad date val ", sizeof(longstring)); fputs(longstring, stdout); diff --git a/src.freebsd/findutils/find/meson.build b/src.freebsd/findutils/find/meson.build index cf42fd6c..b5550669 100644 --- a/src.freebsd/findutils/find/meson.build +++ b/src.freebsd/findutils/find/meson.build @@ -1,20 +1,14 @@ find_prog = executable( 'find', - [ 'find.c', - 'function.c', - yacc.process('getdate.y'), - 'ls.c', - 'main.c', - 'misc.c', - 'operator.c', - 'option.c', + [ + 'find.c', 'function.c', yacc.process('getdate.y'), + 'ls.c', 'main.c', 'misc.c', 'operator.c', 'option.c', ], - c_args : [ '-DQUAD_MAX=LONG_MAX', - '-DMAXLOGNAME=LOGIN_NAME_MAX', ], - include_directories : inc, - dependencies : [ libfts, librpmatch, ], - link_with : [ libcompat ], - install : true, + c_args: ['-DQUAD_MAX=LONG_MAX', '-DMAXLOGNAME=LOGIN_NAME_MAX'], + include_directories: [inc], + dependencies: [libfts, librpmatch], + link_with: [libcompat], + install: true, ) install_man('find.1') diff --git a/src.freebsd/miscutils/calendar/day.c b/src.freebsd/miscutils/calendar/day.c index 84562ccd..9cdbc8c2 100644 --- a/src.freebsd/miscutils/calendar/day.c +++ b/src.freebsd/miscutils/calendar/day.c @@ -37,7 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include "calendar.h" @@ -65,7 +65,7 @@ settimes(time_t now, int before, int after, int friday, struct tm *tp1, struct t localtime_r(&time2, tp2); year2 = 1900 + tp2->tm_year; - strftime(dayname, sizeof(dayname) - 1, "%A, %d %B %Y", tp1); + strftime_bsd(dayname, sizeof(dayname) - 1, "%A, %d %B %Y", tp1); setnnames(); } diff --git a/src.freebsd/miscutils/calendar/events.c b/src.freebsd/miscutils/calendar/events.c index d141871a..551755ee 100644 --- a/src.freebsd/miscutils/calendar/events.c +++ b/src.freebsd/miscutils/calendar/events.c @@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #ifdef WITH_ICONV #include #include @@ -220,7 +220,7 @@ event_print_all(FILE *fp) tm.tm_mday = e->day; tm.tm_mon = e->month - 1; tm.tm_year = e->year - 1900; - (void)strftime(dbuf, sizeof(dbuf), d_first ? "%e %b" : "%b %e", &tm); + (void)strftime_bsd(dbuf, sizeof(dbuf), d_first ? "%e %b" : "%b %e", &tm); } /* diff --git a/src.freebsd/miscutils/calendar/locale.c b/src.freebsd/miscutils/calendar/locale.c index 34f0f98c..47bae730 100644 --- a/src.freebsd/miscutils/calendar/locale.c +++ b/src.freebsd/miscutils/calendar/locale.c @@ -37,7 +37,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include "calendar.h" @@ -81,7 +81,7 @@ setnnames(void) memset(&tm, 0, sizeof(struct tm)); for (i = 0; i < 7; i++) { tm.tm_wday = i; - strftime(buf, sizeof(buf), "%a", &tm); + strftime_bsd(buf, sizeof(buf), "%a", &tm); for (l = strlen(buf); l > 0 && isspace((unsigned char)buf[l - 1]); l--) @@ -93,7 +93,7 @@ setnnames(void) errx(1, "cannot allocate memory"); ndays[i].len = strlen(buf); - strftime(buf, sizeof(buf), "%A", &tm); + strftime_bsd(buf, sizeof(buf), "%A", &tm); for (l = strlen(buf); l > 0 && isspace((unsigned char)buf[l - 1]); l--) @@ -109,7 +109,7 @@ setnnames(void) memset(&tm, 0, sizeof(struct tm)); for (i = 0; i < 12; i++) { tm.tm_mon = i; - strftime(buf, sizeof(buf), "%b", &tm); + strftime_bsd(buf, sizeof(buf), "%b", &tm); for (l = strlen(buf); l > 0 && isspace((unsigned char)buf[l - 1]); l--) @@ -121,7 +121,7 @@ setnnames(void) errx(1, "cannot allocate memory"); nmonths[i].len = strlen(buf); - strftime(buf, sizeof(buf), "%B", &tm); + strftime_bsd(buf, sizeof(buf), "%B", &tm); for (l = strlen(buf); l > 0 && isspace((unsigned char)buf[l - 1]); l--) diff --git a/src.freebsd/miscutils/ncal/meson.build b/src.freebsd/miscutils/ncal/meson.build index 1f7eae09..b70f8866 100644 --- a/src.freebsd/miscutils/ncal/meson.build +++ b/src.freebsd/miscutils/ncal/meson.build @@ -2,6 +2,7 @@ ncal_prog = executable( 'ncal', ['ncal.c', 'calendar.c', 'easter.c'], include_directories: [inc], + link_with: [libcompat], dependencies: [libtinfo], install: true, ) diff --git a/src.freebsd/miscutils/ncal/ncal.c b/src.freebsd/miscutils/ncal/ncal.c index 217fbee7..4ca28ee5 100644 --- a/src.freebsd/miscutils/ncal/ncal.c +++ b/src.freebsd/miscutils/ncal/ncal.c @@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include #include @@ -566,7 +566,7 @@ printeaster(int y, int julian, int orthodox) tm.tm_year = dt.y - 1900; tm.tm_mon = dt.m - 1; tm.tm_mday = dt.d; - strftime(buf, sizeof(buf), d_first ? "%e %B %Y" : "%B %e %Y", &tm); + strftime_bsd(buf, sizeof(buf), d_first ? "%e %B %Y" : "%B %e %Y", &tm); printf("%s\n", buf); } @@ -1104,7 +1104,7 @@ parsemonth(const char *s, int *m, int *y) *y = ny; return (0); } - if (strptime(s, "%B", &tm) != NULL || strptime(s, "%b", &tm) != NULL) { + if (strptime_bsd(s, "%B", &tm) != NULL || strptime_bsd(s, "%b", &tm) != NULL) { *m = tm.tm_mon + 1; return (0); } diff --git a/src.freebsd/miscutils/script/meson.build b/src.freebsd/miscutils/script/meson.build index 0ebdb005..01e65866 100644 --- a/src.freebsd/miscutils/script/meson.build +++ b/src.freebsd/miscutils/script/meson.build @@ -1,7 +1,8 @@ script_prog = executable( 'script', [ 'script.c' ], - include_directories: inc, + include_directories: [inc], + link_with: [libcompat], install: true, ) diff --git a/src.freebsd/miscutils/script/script.c b/src.freebsd/miscutils/script/script.c index 970a4231..0562fbc9 100644 --- a/src.freebsd/miscutils/script/script.c +++ b/src.freebsd/miscutils/script/script.c @@ -60,7 +60,7 @@ static const char sccsid[] = "@(#)script.c 8.1 (Berkeley) 6/6/93"; #include #include #include -#include +#include #include #include #include @@ -548,7 +548,7 @@ playback(FILE *fp) if (stamp.scr_len == 0) continue; if (tclock - lclock > 0) { - l = strftime(buf, sizeof buf, tstamp_fmt, + l = strftime_bsd(buf, sizeof buf, tstamp_fmt, localtime(&tclock)); (void)write(STDOUT_FILENO, buf, l); }