diff --git a/MANIFEST b/MANIFEST index d5a05680f..ab9403817 100644 --- a/MANIFEST +++ b/MANIFEST @@ -205,12 +205,14 @@ lib/util/gettime.c lib/util/getusershell.c lib/util/gidlist.c lib/util/glob.c +lib/util/gmtime_r.c lib/util/inet_ntop.c lib/util/inet_pton.c lib/util/isblank.c lib/util/json.c lib/util/key_val.c lib/util/lbuf.c +lib/util/localtime_r.c lib/util/locking.c lib/util/logfac.c lib/util/logpri.c diff --git a/config.h.in b/config.h.in index e5c52f4ce..428b8a342 100644 --- a/config.h.in +++ b/config.h.in @@ -408,6 +408,9 @@ /* Define to 1 if you have the `glob' function. */ #undef HAVE_GLOB +/* Define to 1 if you have the `gmtime_r' function. */ +#undef HAVE_GMTIME_R + /* Define to 1 if you have the `grantpt' function. */ #undef HAVE_GRANTPT @@ -545,6 +548,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_RANDOM_H +/* Define to 1 if you have the `localtime_r' function. */ +#undef HAVE_LOCALTIME_R + /* Define to 1 if you have the `lockf' function. */ #undef HAVE_LOCKF diff --git a/configure b/configure index e68f1a9de..1c3d518cb 100755 --- a/configure +++ b/configure @@ -21107,6 +21107,58 @@ esac done +fi + +done + + for ac_func in localtime_r +do : + ac_fn_c_check_func "$LINENO" "localtime_r" "ac_cv_func_localtime_r" +if test "x$ac_cv_func_localtime_r" = xyes +then : + printf "%s\n" "#define HAVE_LOCALTIME_R 1" >>confdefs.h + +else $as_nop + + case " $LIBOBJS " in + *" localtime_r.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS localtime_r.$ac_objext" + ;; +esac + + + for _sym in sudo_localtime_r; do + COMPAT_EXP="${COMPAT_EXP}${_sym} +" + done + + +fi + +done + + for ac_func in gmtime_r +do : + ac_fn_c_check_func "$LINENO" "gmtime_r" "ac_cv_func_gmtime_r" +if test "x$ac_cv_func_gmtime_r" = xyes +then : + printf "%s\n" "#define HAVE_GMTIME_R 1" >>confdefs.h + +else $as_nop + + case " $LIBOBJS " in + *" gmtime_r.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS gmtime_r.$ac_objext" + ;; +esac + + + for _sym in sudo_gmtime_r; do + COMPAT_EXP="${COMPAT_EXP}${_sym} +" + done + + fi done diff --git a/configure.ac b/configure.ac index f767ee28c..d6e6ac831 100644 --- a/configure.ac +++ b/configure.ac @@ -2570,6 +2570,14 @@ AC_CHECK_FUNCS([cfmakeraw], [], [ AC_LIBOBJ(cfmakeraw) SUDO_APPEND_COMPAT_EXP(sudo_cfmakeraw) ]) +AC_CHECK_FUNCS([localtime_r], [], [ + AC_LIBOBJ(localtime_r) + SUDO_APPEND_COMPAT_EXP(sudo_localtime_r) +]) +AC_CHECK_FUNCS([gmtime_r], [], [ + AC_LIBOBJ(gmtime_r) + SUDO_APPEND_COMPAT_EXP(sudo_gmtime_r) +]) AC_CHECK_FUNCS([getgrouplist], [], [ case "$host_os" in aix*) diff --git a/include/sudo_compat.h b/include/sudo_compat.h index 1312cd550..95b0969ed 100644 --- a/include/sudo_compat.h +++ b/include/sudo_compat.h @@ -24,7 +24,7 @@ #ifndef SUDO_COMPAT_H #define SUDO_COMPAT_H -#include /* for gid_t, mode_t, size_t, ssize_t, uid_t */ +#include /* for gid_t, mode_t, size_t, ssize_t, time_t, uid_t */ #if defined(__hpux) && !defined(__LP64__) # include /* for pread/pread64, and pwrite/pwrite64 */ #endif @@ -401,6 +401,7 @@ struct passwd; struct stat; struct timespec; struct termios; +struct tm; #ifndef HAVE_CFMAKERAW sudo_dso_public void sudo_cfmakeraw(struct termios *term); @@ -456,6 +457,16 @@ char *getusershell(void); void setusershell(void); void endusershell(void); #endif /* HAVE_GETUSERSHELL */ +#ifndef HAVE_GMTIME_R +sudo_dso_public struct tm *sudo_gmtime_r(const time_t *, struct tm *); +# undef gmtime_r +# define gmtime_r(_a, _b, _c, _d) sudo_gmtime_r((_a), (_b)) +#endif /* HAVE_GMTIME_R */ +#ifndef HAVE_LOCALTIME_R +sudo_dso_public struct tm *sudo_localtime_r(const time_t *, struct tm *); +# undef localtime_r +# define localtime_r(_a, _b, _c, _d) sudo_localtime_r((_a), (_b)) +#endif /* HAVE_LOCALTIME_R */ #ifndef HAVE_UTIMENSAT sudo_dso_public int sudo_utimensat(int fd, const char *file, const struct timespec *times, int flag); # undef utimensat diff --git a/lib/util/gmtime_r.c b/lib/util/gmtime_r.c new file mode 100644 index 000000000..b9feb1f71 --- /dev/null +++ b/lib/util/gmtime_r.c @@ -0,0 +1,49 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2021 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This is an open source non-commercial project. Dear PVS-Studio, please check it. + * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + */ + +#include + +#ifndef HAVE_GMTIME_R + +#include +#include + +#include "sudo_compat.h" +#include "sudo_util.h" + +/* + * Fake gmtime_r() that just stores the result. + * Still has the normal gmtime() side effects. + */ +struct tm * +sudo_gmtime_r(const time_t *timer, struct tm *result) +{ + struct tm *tm; + + if ((tm = gmtime(timer)) == NULL) + return NULL; + memcpy(result, tm, sizeof(struct tm)); + + return result; +} +#endif /* HAVE_GMTIME_T */ diff --git a/lib/util/localtime_r.c b/lib/util/localtime_r.c new file mode 100644 index 000000000..674cb1aa5 --- /dev/null +++ b/lib/util/localtime_r.c @@ -0,0 +1,49 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2021 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * This is an open source non-commercial project. Dear PVS-Studio, please check it. + * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + */ + +#include + +#ifndef HAVE_LOCALTIME_R + +#include +#include + +#include "sudo_compat.h" +#include "sudo_util.h" + +/* + * Fake localtime_r() that just stores the result. + * Still has the normal localtime() side effects. + */ +struct tm * +sudo_localtime_r(const time_t *timer, struct tm *result) +{ + struct tm *tm; + + if ((tm = localtime(timer)) == NULL) + return NULL; + memcpy(result, tm, sizeof(struct tm)); + + return result; +} +#endif /* HAVE_LOCALTIME_T */