From ba2376b9e03b9bd214242c987609a658ef24ec41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Tue, 11 Aug 2020 16:14:36 +0200 Subject: [PATCH 1/2] Update and cleanup the readline library support This commit updates and simplifies the checks for the readline support in nslookup and nsupdate: * Change the autoconf checks to pkg-config only, all supported libraries have accompanying .pc files now. * Add editline support in addition to libedit and GNU readline * Add isc/readline.h shim header that defines dummy readline() function when no readline library is available --- Makefile.top | 5 ++ bin/dig/Makefile.am | 10 ++-- bin/dig/nslookup.c | 49 ++++-------------- bin/nsupdate/Makefile.am | 6 ++- bin/nsupdate/nsupdate.c | 41 +++------------ configure.ac | 93 ++++++++++++---------------------- lib/isc/Makefile.am | 1 + lib/isc/include/isc/readline.h | 56 ++++++++++++++++++++ util/copyrights | 1 + 9 files changed, 125 insertions(+), 137 deletions(-) create mode 100644 lib/isc/include/isc/readline.h diff --git a/Makefile.top b/Makefile.top index 140ab4406e..727f08bf49 100644 --- a/Makefile.top +++ b/Makefile.top @@ -33,6 +33,11 @@ LIBISC_CFLAGS += \ $(LIBXML2_CFLAGS) endif HAVE_LIBXML2 +if HAVE_READLINE +LIBISC_CFLAGS += \ + $(READLINE_CFLAGS) +endif HAVE_READLINE + LIBISC_LIBS = $(top_builddir)/lib/isc/libisc.la LIBDNS_CFLAGS = \ diff --git a/bin/dig/Makefile.am b/bin/dig/Makefile.am index 7bcd2f5e65..538a5fdcfe 100644 --- a/bin/dig/Makefile.am +++ b/bin/dig/Makefile.am @@ -25,6 +25,10 @@ libdighost_la_SOURCES = \ bin_PROGRAMS = dig host nslookup -nslookup_LDADD = \ - $(LDADD) \ - $(READLINE_LIB) +nslookup_LDADD = \ + $(LDADD) + +if HAVE_READLINE +nslookup_LDADD += \ + $(READLINE_LIBS) +endif HAVE_READLINE diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c index 7309c8cdbf..ed9728bb7d 100644 --- a/bin/dig/nslookup.c +++ b/bin/dig/nslookup.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -38,27 +39,6 @@ #include "dighost.h" -#if defined(HAVE_READLINE) -#if defined(HAVE_EDIT_READLINE_READLINE_H) -#include -#if defined(HAVE_EDIT_READLINE_HISTORY_H) -#include -#endif /* if defined(HAVE_EDIT_READLINE_HISTORY_H) */ -#elif defined(HAVE_EDITLINE_READLINE_H) -#include -#elif defined(HAVE_READLINE_READLINE_H) -/* Prevent deprecated functions being declared. */ -#define _FUNCTION_DEF 1 -/* Ensure rl_message() gets prototype. */ -#define USE_VARARGS 1 -#define PREFER_STDARG 1 -#include -#if defined(HAVE_READLINE_HISTORY_H) -#include -#endif /* if defined(HAVE_READLINE_HISTORY_H) */ -#endif /* if defined(HAVE_EDIT_READLINE_READLINE_H) */ -#endif /* if defined(HAVE_READLINE) */ - static bool short_form = true, tcpmode = false, tcpmode_set = false, identify = false, stats = true, comments = true, section_question = true, section_answer = true, @@ -853,38 +833,27 @@ do_next_command(char *input) { static void get_next_command(void) { - char *buf; - char *ptr; + char cmdlinebuf[COMMSIZE]; + char *cmdline, *ptr = NULL; - fflush(stdout); - buf = isc_mem_allocate(mctx, COMMSIZE); isc_app_block(); if (interactive) { -#ifdef HAVE_READLINE - ptr = readline("> "); - if (ptr != NULL) { + cmdline = ptr = readline("> "); + if (ptr != NULL && *ptr != 0) { add_history(ptr); } -#else /* ifdef HAVE_READLINE */ - fprintf(stderr, "> "); - fflush(stderr); - ptr = fgets(buf, COMMSIZE, stdin); -#endif /* ifdef HAVE_READLINE */ } else { - ptr = fgets(buf, COMMSIZE, stdin); + cmdline = fgets(cmdlinebuf, COMMSIZE, stdin); } isc_app_unblock(); - if (ptr == NULL) { + if (cmdline == NULL) { in_use = false; } else { - do_next_command(ptr); + do_next_command(cmdline); } -#ifdef HAVE_READLINE - if (interactive) { + if (ptr != NULL) { free(ptr); } -#endif /* ifdef HAVE_READLINE */ - isc_mem_free(mctx, buf); } ISC_NORETURN static void diff --git a/bin/nsupdate/Makefile.am b/bin/nsupdate/Makefile.am index 8e2cbaa6ef..29fd0cfac0 100644 --- a/bin/nsupdate/Makefile.am +++ b/bin/nsupdate/Makefile.am @@ -18,8 +18,12 @@ LDADD = \ $(LIBISCCFG_LIBS) \ $(LIBIRS_LIBS) \ $(LIBBIND9_LIBS) \ - $(READLINE_LIB) \ $(GSSAPI_LIBS) \ $(KRB5_LIBS) +if HAVE_READLINE +LDADD += \ + $(READLINE_LIBS) +endif + bin_PROGRAMS = nsupdate diff --git a/bin/nsupdate/nsupdate.c b/bin/nsupdate/nsupdate.c index 654c6508d8..8416760d93 100644 --- a/bin/nsupdate/nsupdate.c +++ b/bin/nsupdate/nsupdate.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -94,25 +95,6 @@ #include -#if defined(HAVE_READLINE) -#if defined(HAVE_EDIT_READLINE_READLINE_H) -#include -#if defined(HAVE_EDIT_READLINE_HISTORY_H) -#include -#endif /* if defined(HAVE_EDIT_READLINE_HISTORY_H) */ -#elif defined(HAVE_EDITLINE_READLINE_H) -#include -#else /* if defined(HAVE_EDIT_READLINE_READLINE_H) */ -/* Prevent deprecated functions being declared. */ -#define _FUNCTION_DEF 1 -/* Ensure rl_message() gets prototype. */ -#define USE_VARARGS 1 -#define PREFER_STDARG 1 -#include -#include -#endif /* if defined(HAVE_EDIT_READLINE_READLINE_H) */ -#endif /* if defined(HAVE_READLINE) */ - #define MAXCMD (128 * 1024) #define MAXWIRE (64 * 1024) #define PACKETSIZE ((64 * 1024) - 1) @@ -2295,20 +2277,14 @@ static uint16_t get_next_command(void) { uint16_t result = STATUS_QUIT; char cmdlinebuf[MAXCMD]; - char *cmdline; + char *cmdline = NULL, *ptr = NULL; isc_app_block(); if (interactive) { -#ifdef HAVE_READLINE - cmdline = readline("> "); - if (cmdline != NULL) { - add_history(cmdline); + cmdline = ptr = readline("> "); + if (ptr != NULL && *ptr != 0) { + add_history(ptr); } -#else /* ifdef HAVE_READLINE */ - fprintf(stdout, "> "); - fflush(stdout); - cmdline = fgets(cmdlinebuf, MAXCMD, input); -#endif /* ifdef HAVE_READLINE */ } else { cmdline = fgets(cmdlinebuf, MAXCMD, input); } @@ -2324,11 +2300,10 @@ get_next_command(void) { (void)nsu_strsep(&tmp, "\r\n"); result = do_next_command(cmdline); } -#ifdef HAVE_READLINE - if (interactive) { - free(cmdline); + if (ptr != NULL) { + free(ptr); } -#endif /* ifdef HAVE_READLINE */ + return (result); } diff --git a/configure.ac b/configure.ac index edc3eefbcf..7f2fe3738d 100644 --- a/configure.ac +++ b/configure.ac @@ -976,66 +976,39 @@ AS_IF([test "$enable_tcp_fastopen" = "yes"], # AC_CHECK_FUNCS([strlcpy strlcat]) -AC_SUBST(READLINE_LIB) -AC_ARG_WITH(readline, - AS_HELP_STRING([--with-readline[=LIBSPEC]], - [specify readline library [default auto]]), - use_readline="$withval", use_readline="auto") -case "$use_readline" in -no) ;; -*) - saved_LIBS="$LIBS" - case "$use_readline" in - yes|auto) try_readline="-ledit"; or_readline="-lreadline" ;; - *) try_readline="$use_readline" - esac - for readline in "$try_readline" $or_readline - do - LIBS="$readline" - AC_MSG_NOTICE(checking for readline with $readline) - AC_CHECK_FUNCS(readline) - if test "yes" = "$ac_cv_func_readline" - then - READLINE_LIB="$readline" - break - fi - for lib in -lterminfo -ltermcap -lncurses -lcurses - do - AC_MSG_NOTICE(checking for readline with $readline $lib) - unset ac_cv_func_readline - LIBS="$readline $lib" - AC_CHECK_FUNCS(readline) - if test "yes" = "$ac_cv_func_readline" - then - READLINE_LIB="$readline $lib" - break - fi - done - if test "yes" = "$ac_cv_func_readline" - then - break - fi - done - if test "auto" != "$use_readline" && - test "X$READLINE_LIB" = "X" - then - AC_MSG_ERROR([The readline library was not found.]) - fi - LIBS="$saved_LIBS" - ;; -esac -if test "yes" = "$ac_cv_func_readline" -then - case "$READLINE_LIB" in - *edit*) - AC_CHECK_HEADERS(editline/readline.h) - AC_CHECK_HEADERS(edit/readline/readline.h) - AC_CHECK_HEADERS(edit/readline/history.h) - ;; - esac - AC_CHECK_HEADERS(readline/readline.h) - AC_CHECK_HEADERS(readline/history.h) -fi +# +# Check for readline support +# + +AC_ARG_WITH([readline], + [AS_HELP_STRING([--with-readline=yes|no|libedit|readline], + [specify readline library [default auto]])], + [], [with_readline="auto"]) + +AS_CASE([$with_readline], + [no],[], + [auto], + [PKG_CHECK_MODULES([READLINE], [libedit], + [AC_DEFINE([HAVE_READLINE_LIBEDIT], [1], [Build with libedit support])], + [PKG_CHECK_MODULES([READLINE], [editline], + [AC_DEFINE([HAVE_READLINE_EDITLINE], [1], [Build with editline support.])], + [PKG_CHECK_MODULES([READLINE], [readline], + [AC_DEFINE([HAVE_READLINE_READLINE], [1], [Build with readline support.])], + [AS_IF([test "$with_readline" = "yes"], + [AC_MSG_ERROR([readline support requested, but none of the libraries have been found.])])])])])], + [libedit], + [PKG_CHECK_MODULES([READLINE], [libedit], + [AC_DEFINE([HAVE_READLINE_LIBEDIT], [1], [Build with libedit support])])], + [editline], + [PKG_CHECK_MODULES([READLINE], [editline], + [AC_DEFINE([HAVE_READLINE_EDITLINE], [1], [Build with editline support])])], + [readline], + [PKG_CHECK_MODULES([READLINE], [readline], + [AC_DEFINE([HAVE_READLINE_READLINE], [1], [Build with readline support])])], + [AC_MSG_ERROR([Unknown readline '$with_readline' library requested.])]) +AM_CONDITIONAL([HAVE_READLINE], [test -n "$READLINE_LIBS"]) +AC_SUBST([READLINE_CFLAGS]) +AC_SUBST([READLINE_LIBS]) # # Security Stuff diff --git a/lib/isc/Makefile.am b/lib/isc/Makefile.am index 19bf5b677e..cde0947bde 100644 --- a/lib/isc/Makefile.am +++ b/lib/isc/Makefile.am @@ -66,6 +66,7 @@ libisc_la_HEADERS = \ include/isc/radix.h \ include/isc/random.h \ include/isc/ratelimiter.h \ + include/isc/readline.h \ include/isc/refcount.h \ include/isc/regex.h \ include/isc/region.h \ diff --git a/lib/isc/include/isc/readline.h b/lib/isc/include/isc/readline.h new file mode 100644 index 0000000000..81112280dc --- /dev/null +++ b/lib/isc/include/isc/readline.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +#pragma once + +/* + * A little wrapper around readline(), add_history() and free() to make using + * the readline code simpler. + */ + +#if defined(HAVE_READLINE_LIBEDIT) +#include +#elif defined(HAVE_READLINE_EDITLINE) +#include +#elif defined(HAVE_READLINE_READLINE) +/* Prevent deprecated functions being declared. */ +#define _FUNCTION_DEF 1 +/* Ensure rl_message() gets prototype. */ +#define USE_VARARGS 1 +#define PREFER_STDARG 1 +#include +#include +#endif + +#if !defined(HAVE_READLINE_LIBEDIT) && !defined(HAVE_READLINE_EDITLINE) && \ + !defined(HAVE_READLINE_READLINE) + +#include +#include + +#define RL_MAXCMD (128 * 1024) + +static inline char * +readline(const char *prompt) { + char *line, *buf = malloc(RL_MAXCMD); + fprintf(stdout, "%s", prompt); + fflush(stdout); + line = fgets(buf, RL_MAXCMD, stdin); + if (line == NULL) { + free(buf); + return (NULL); + } + return (buf); +}; + +#define add_history(line) + +#endif diff --git a/util/copyrights b/util/copyrights index d50730d93e..6ea744aaee 100644 --- a/util/copyrights +++ b/util/copyrights @@ -1832,6 +1832,7 @@ ./lib/isc/include/isc/radix.h C 2007,2008,2013,2014,2016,2018,2019,2020 ./lib/isc/include/isc/random.h C 1999,2000,2001,2004,2005,2006,2007,2009,2014,2016,2017,2018,2019,2020 ./lib/isc/include/isc/ratelimiter.h C 1999,2000,2001,2002,2004,2005,2006,2007,2009,2014,2016,2018,2019,2020 +./lib/isc/include/isc/readline.h C 2020 ./lib/isc/include/isc/refcount.h C 2001,2003,2004,2005,2006,2007,2009,2016,2017,2018,2019,2020 ./lib/isc/include/isc/regex.h C 2013,2016,2018,2019,2020 ./lib/isc/include/isc/region.h C 1998,1999,2000,2001,2002,2004,2005,2006,2007,2013,2016,2018,2019,2020 From be8c589f28cf518669e5b0805a2b65f4b76787bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Wed, 12 Aug 2020 09:23:01 +0200 Subject: [PATCH 2/2] Add CHANGES note for GL !3942 --- CHANGES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES b/CHANGES index 00ce9e2da8..36a9eae78a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +5490. [func] Refactor the readline support to use pkg-config and + add support for editline library. [GL !3942] + 5489. [bug] Named failed to reject some invalid records resulting in records that, after being printed, could not be loaded or would result in DNSSEC validation failures