From 11ba27271f8e085b06c79b732cf92f88e492f487 Mon Sep 17 00:00:00 2001 From: Matthias Andree Date: Mon, 4 May 2020 03:04:59 +0200 Subject: Add fm_realpath(): a malloc()ating realpath() wrapper. --- Makefile.am | 9 ++++++--- README | 4 +++- configure.ac | 11 ++++++----- fetchmail.h | 4 ++++ fm_realpath.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ t.realpath | 6 ++++++ 6 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 fm_realpath.c create mode 100755 t.realpath diff --git a/Makefile.am b/Makefile.am index 77fe40f5..2ba02438 100644 --- a/Makefile.am +++ b/Makefile.am @@ -47,7 +47,7 @@ DEPENDENCIES= libfm.a $(LIBOBJS) check_PROGRAMS= -TESTS= t.smoke t.validate-xhtml10 t.validate-xhtml t.x509_name_match +TESTS= t.smoke t.validate-xhtml10 t.validate-xhtml t.x509_name_match t.realpath LOG_COMPILER= env LC_ALL=C TZ=UTC $(SHELL) if NEED_TRIO @@ -72,7 +72,8 @@ fetchmail_SOURCES= fetchmail.h getopt.h \ unmime.c conf.c checkalias.c uid_db.h uid_db.c\ lock.h lock.c \ rcfile_l.l rcfile_y.y \ - ucs/norm_charmap.c ucs/norm_charmap.h + ucs/norm_charmap.c ucs/norm_charmap.h \ + fm_realpath.c if POP2_ENABLE fetchmail_SOURCES += pop2.c endif @@ -102,7 +103,9 @@ fetchmail_SOURCES += libesmtp/getaddrinfo.h libesmtp/getaddrinfo.c endif check_PROGRAMS += rfc822 unmime netrc rfc2047e mxget rfc822valid \ - x509_name_match + x509_name_match fm_realpath + +fm_realpath_CFLAGS= -DTEST rfc2047e_CFLAGS= -DTEST diff --git a/README b/README index 2e143438..c6264cde 100644 --- a/README +++ b/README @@ -37,7 +37,9 @@ NEXTSTEP, OSF 3.2, IRIX, and Rhapsody once upon a time. The current maintainer does not have access to these systems, and assumes that the system is at least Single-Unix-Specification V2 compatible, yet fetchmail should be compilable by a C89 compiler. It currently ships with a copy of the -trio library for systems that lack snprintf(). +trio library for systems that lack snprintf(). A further requirement is that +either realpath() permits its 2nd argument to be NULL for auto-allocation, +or that otherwise PATH_MAX be defined. Fetchmail should be able to be compiled with C89, C99, C11, C++98, C++03, C++11, C++14 compilers, but not C++17 because the "register" keyword is diff --git a/configure.ac b/configure.ac index 2cde1ba4..6fd2caf6 100644 --- a/configure.ac +++ b/configure.ac @@ -3,13 +3,13 @@ dnl Autoconfigure input file for fetchmail # Fetchmail automatic configuration support # # Eric S. Raymond -# 2004 - 2019 Matthias Andree +# 2004 - 2020 Matthias Andree # dnl Process this file with autoconf to produce a configure script. dnl dnl XXX - if bumping version here, check fetchmail.man, too! -AC_INIT([fetchmail],[6.4.4],[fetchmail-users@lists.sourceforge.net]) +AC_INIT([fetchmail],[6.4.5-rc1],[fetchmail-users@lists.sourceforge.net]) AC_CONFIG_SRCDIR([fetchmail.h]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_LIBOBJ_DIR([.]) @@ -98,6 +98,9 @@ AC_CHECK_DECLS([h_errno],,,[ AC_C_CONST dnl getopt needs this. AC_C_INLINE dnl uid_db.? need this. +AC_C_RESTRICT dnl fm_realpath needs this. +AC_C_VOLATILE dnl check for ANSI volatile + AM_PROG_LEX AC_PROG_MAKE_SET @@ -181,6 +184,7 @@ AC_CHECK_FUNCS(tcsetattr stty setsid geteuid seteuid dnl sigaction strdup setlocale) AC_CHECK_DECLS([strerror]) +AC_CHECK_DECLS([PATH_MAX],,,[#include ]) dnl INET6 is used by KAME/getnameinfo AC_CACHE_CHECK(for AF_INET6/PF_INET6,ac_cv_inet6, AC_COMPILE_IFELSE([ @@ -235,9 +239,6 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[char *p; p = (char *) xmalloc(1); ]])],[AC_DEFINE(HAVE_VOIDPOINTER,1,[Define if your C compiler allows void * as a function result]) AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)]) -dnl Check for ANSI volatile -AC_C_VOLATILE - dnl Check out the wait reality. We have to assume sys/wait.h is present. AC_CHECK_FUNCS(waitpid wait3) AC_MSG_CHECKING(for union wait); diff --git a/fetchmail.h b/fetchmail.h index f731e159..902aae18 100644 --- a/fetchmail.h +++ b/fetchmail.h @@ -792,4 +792,8 @@ int ntlm_helper(int sock, struct query *ctl, const char *protocol); && (run.showdots || !is_a_file(1))) #endif + +/* fm_realpath.c */ +char *fm_realpath(const char *restrict file_name); + /* fetchmail.h ends here */ diff --git a/fm_realpath.c b/fm_realpath.c new file mode 100644 index 00000000..5ae8ca08 --- /dev/null +++ b/fm_realpath.c @@ -0,0 +1,62 @@ +#include "config.h" +#include "fetchmail.h" +#include "i18n.h" + +#include +#include +#include +#include +#include + +/* similar to realpath(file_name, NULL) - on systems that do not natively + * support the resolved file name to be passed as NULL, malloc() the buffer of + * PATH_MAX + 1 bytes, or abort if the system does not define PATH_MAX + */ +char *fm_realpath(const char *restrict file_name) +{ + char *rv; + + if (NULL == file_name) { + errno = EINVAL; + return NULL; + } + + rv = realpath(file_name, NULL); + /* FreeBSD, recent GNU libc, and all SUSv4 + * compliant systems auto-allocate => done */ + if (NULL == rv && errno == EINVAL) { + /* Implementation does not auto-allocate, but + * PATH_MAX is provided (Solaris 10, f.i.) */ +#if HAVE_DECL_PATH_MAX + char *b = (char *)xmalloc(PATH_MAX + 1); + rv = realpath(file_name, b); +#else + /* unsupported */ + report(stderr, GT_("Your operating system neither defines PATH_MAX nor will it accept realpath(f, NULL). Aborting.\n")); + abort(); +#endif + } + return rv; +} + +#ifdef TEST +#include +const char *program_name= __FILE__; + +int main(int argc, char **argv) +{ + int i; + int e = EXIT_SUCCESS; + for (i = 1; i < argc; ++i) { + char *p = fm_realpath(argv[i]); + if (p) { + printf("%s -> %s\n", argv[i], p); + free(p); + } else { + fprintf(stderr, "%s: error: %s\n", argv[i], strerror(errno)); + e = EXIT_FAILURE; + } + } + exit(e); +} +#endif diff --git a/t.realpath b/t.realpath new file mode 100755 index 00000000..634fc15f --- /dev/null +++ b/t.realpath @@ -0,0 +1,6 @@ +#! /bin/sh + +# This is a rudimentary tests to check if realpath() works. + +set -eu +./fm_realpath "." "$(pwd)" -- cgit v1.2.3