]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3244. [func] Added readline support to nslookup and nsupdate.
authorEvan Hunt <each@isc.org>
Fri, 16 Dec 2011 23:01:17 +0000 (23:01 +0000)
committerEvan Hunt <each@isc.org>
Fri, 16 Dec 2011 23:01:17 +0000 (23:01 +0000)
Also simplified nsupdate syntax to make "update"
and "prereq" optional. [RT #24659]

CHANGES
bin/dig/nslookup.c
bin/nsupdate/nsupdate.c
bin/nsupdate/nsupdate.docbook
bin/tests/system/nsupdate/tests.sh
config.h.in
configure.in

diff --git a/CHANGES b/CHANGES
index c40093a1e55e02cf8fe3a43c96110daf04513e56..bfa947a1607b5f4657dc4c297f778caff64427d8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+3244.  [func]          Added readline support to nslookup and nsupdate.
+                       Also simplified nsupdate syntax to make "update" 
+                       and "prereq" optional. [RT #24659]
+
 3243.  [port]          freebsd,netbsd,bsdi: the thread defaults were not
                        being properly set.
 
index b45272b0da6270dc46af484c4ed079da8178d665..2f56b8522af69afb1e49e892a5d6dc9bec0d5137 100644 (file)
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: nslookup.c,v 1.129 2011/02/21 23:47:44 tbox Exp $ */
+/* $Id: nslookup.c,v 1.130 2011/12/16 23:01:16 each Exp $ */
 
 #include <config.h>
 
 #include <stdlib.h>
+#include <unistd.h>
 
 #include <isc/app.h>
 #include <isc/buffer.h>
 
 #include <dig/dig.h>
 
+#if defined(HAVE_READLINE)
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif
+
 static isc_boolean_t short_form = ISC_TRUE,
        tcpmode = ISC_FALSE,
        identify = ISC_FALSE, stats = ISC_TRUE,
@@ -53,6 +59,8 @@ static isc_boolean_t short_form = ISC_TRUE,
        section_additional = ISC_TRUE, recurse = ISC_TRUE,
        aaonly = ISC_FALSE, nofail = ISC_TRUE;
 
+static isc_boolean_t interactive;
+
 static isc_boolean_t in_use = ISC_FALSE;
 static char defclass[MXRD] = "IN";
 static char deftype[MXRD] = "A";
@@ -708,28 +716,12 @@ addlookup(char *opt) {
 }
 
 static void
-get_next_command(void) {
-       char *buf;
+do_next_command(char *input) {
        char *ptr, *arg;
-       char *input;
 
-       fflush(stdout);
-       buf = isc_mem_allocate(mctx, COMMSIZE);
-       if (buf == NULL)
-               fatal("memory allocation failure");
-       fputs("> ", stderr);
-       fflush(stderr);
-       isc_app_block();
-       ptr = fgets(buf, COMMSIZE, stdin);
-       isc_app_unblock();
-       if (ptr == NULL) {
-               in_use = ISC_FALSE;
-               goto cleanup;
-       }
-       input = buf;
        ptr = next_token(&input, " \t\r\n");
        if (ptr == NULL)
-               goto cleanup;
+               return;
        arg = next_token(&input, " \t\r\n");
        if ((strcasecmp(ptr, "set") == 0) &&
            (arg != NULL))
@@ -743,20 +735,48 @@ get_next_command(void) {
                show_settings(ISC_TRUE, ISC_TRUE);
        } else if (strcasecmp(ptr, "exit") == 0) {
                in_use = ISC_FALSE;
-               goto cleanup;
        } else if (strcasecmp(ptr, "help") == 0 ||
                   strcasecmp(ptr, "?") == 0) {
                printf("The '%s' command is not yet implemented.\n", ptr);
-               goto cleanup;
        } else if (strcasecmp(ptr, "finger") == 0 ||
                   strcasecmp(ptr, "root") == 0 ||
                   strcasecmp(ptr, "ls") == 0 ||
                   strcasecmp(ptr, "view") == 0) {
                printf("The '%s' command is not implemented.\n", ptr);
-               goto cleanup;
        } else
                addlookup(ptr);
- cleanup:
+}
+
+static void
+get_next_command(void) {
+       char *buf;
+       char *ptr;
+
+       fflush(stdout);
+       buf = isc_mem_allocate(mctx, COMMSIZE);
+       if (buf == NULL)
+               fatal("memory allocation failure");
+       isc_app_block();
+       if (interactive) {
+#ifdef HAVE_READLINE
+               ptr = readline("> ");
+               add_history(ptr);
+#else
+               fputs("> ", stderr);
+               fflush(stderr);
+               ptr = fgets(buf, COMMSIZE, stdin);
+#endif
+       } else
+               ptr = fgets(buf, COMMSIZE, stdin);
+       isc_app_unblock();
+       if (ptr == NULL) {
+               in_use = ISC_FALSE;
+       } else
+               do_next_command(ptr);
+#ifdef HAVE_READLINE
+       if (interactive)
+               free(ptr);
+#endif
        isc_mem_free(mctx, buf);
 }
 
@@ -852,6 +872,8 @@ int
 main(int argc, char **argv) {
        isc_result_t result;
 
+       interactive = ISC_TF(isatty(0));
+
        ISC_LIST_INIT(lookup_list);
        ISC_LIST_INIT(server_list);
        ISC_LIST_INIT(search_list);
index ba02366159378695efc0b21bf71f65871336c859..e0d1af01058016526469984c100cde7a7baa55da 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: nsupdate.c,v 1.197 2011/11/03 04:29:28 each Exp $ */
+/* $Id: nsupdate.c,v 1.198 2011/12/16 23:01:16 each Exp $ */
 
 /*! \file */
 
 #endif
 #include <bind9/getaddresses.h>
 
+#if defined(HAVE_READLINE)
+#include <readline/readline.h>
+#include <readline/history.h>
+#endif
 
 #ifdef HAVE_ADDRINFO
 #ifdef HAVE_GETADDRINFO
@@ -1154,6 +1158,11 @@ parse_rdata(char **cmdlinep, dns_rdataclass_t rdataclass,
        dns_rdatacallbacks_t callbacks;
        isc_result_t result;
 
+       if (cmdline == NULL) {
+               rdata->flags = DNS_RDATA_UPDATE;
+               return (STATUS_MORE);
+       }
+
        while (*cmdline != 0 && isspace((unsigned char)*cmdline))
                cmdline++;
 
@@ -1800,6 +1809,8 @@ evaluate_update(char *cmdline) {
        }
        if (strcasecmp(word, "delete") == 0)
                isdelete = ISC_TRUE;
+       else if (strcasecmp(word, "del") == 0)
+               isdelete = ISC_TRUE;
        else if (strcasecmp(word, "add") == 0)
                isdelete = ISC_FALSE;
        else {
@@ -1878,27 +1889,13 @@ show_message(FILE *stream, dns_message_t *msg, const char *description) {
        isc_buffer_free(&buf);
 }
 
-
 static isc_uint16_t
-get_next_command(void) {
-       char cmdlinebuf[MAXCMD];
-       char *cmdline;
+do_next_command(char *cmdline) {
        char *word;
 
-       ddebug("get_next_command()");
-       if (interactive) {
-               fprintf(stdout, "> ");
-               fflush(stdout);
-       }
-       isc_app_block();
-       cmdline = fgets(cmdlinebuf, MAXCMD, input);
-       isc_app_unblock();
-       if (cmdline == NULL)
-               return (STATUS_QUIT);
+       ddebug("do_next_command()");
        word = nsu_strsep(&cmdline, " \t\r\n");
 
-       if (feof(input))
-               return (STATUS_QUIT);
        if (*word == 0)
                return (STATUS_SEND);
        if (word[0] == ';')
@@ -1907,8 +1904,22 @@ get_next_command(void) {
                return (STATUS_QUIT);
        if (strcasecmp(word, "prereq") == 0)
                return (evaluate_prereq(cmdline));
+       if (strcasecmp(word, "nxdomain") == 0)
+               return (make_prereq(cmdline, ISC_FALSE, ISC_FALSE));
+       if (strcasecmp(word, "yxdomain") == 0)
+               return (make_prereq(cmdline, ISC_TRUE, ISC_FALSE));
+       if (strcasecmp(word, "nxrrset") == 0)
+               return (make_prereq(cmdline, ISC_FALSE, ISC_TRUE));
+       if (strcasecmp(word, "yxrrset") == 0)
+               return (make_prereq(cmdline, ISC_TRUE, ISC_TRUE));
        if (strcasecmp(word, "update") == 0)
                return (evaluate_update(cmdline));
+       if (strcasecmp(word, "delete") == 0)
+               return (update_addordelete(cmdline, ISC_TRUE));
+       if (strcasecmp(word, "del") == 0)
+               return (update_addordelete(cmdline, ISC_TRUE));
+       if (strcasecmp(word, "add") == 0)
+               return (update_addordelete(cmdline, ISC_FALSE));
        if (strcasecmp(word, "server") == 0)
                return (evaluate_server(cmdline));
        if (strcasecmp(word, "local") == 0)
@@ -1975,18 +1986,46 @@ get_next_command(void) {
 "oldgsstsig                (use Microsoft's GSS_TSIG to sign the request)\n"
 "zone name                 (set the zone to be updated)\n"
 "class CLASS               (set the zone's DNS class, e.g. IN (default), CH)\n"
-"prereq nxdomain name      (does this name not exist)\n"
-"prereq yxdomain name      (does this name exist)\n"
-"prereq nxrrset ....       (does this RRset exist)\n"
-"prereq yxrrset ....       (does this RRset not exist)\n"
-"update add ....           (add the given record to the zone)\n"
-"update delete ....        (remove the given record(s) from the zone)\n");
+"[prereq] nxdomain name    (does this name not exist)\n"
+"[prereq] yxdomain name    (does this name exist)\n"
+"[prereq] nxrrset ....     (does this RRset exist)\n"
+"[prereq] yxrrset ....     (does this RRset not exist)\n"
+"[update] add ....         (add the given record to the zone)\n"
+"[update] del[ete] ....    (remove the given record(s) from the zone)\n");
                return (STATUS_MORE);
        }
        fprintf(stderr, "incorrect section name: %s\n", word);
        return (STATUS_SYNTAX);
 }
 
+static isc_uint16_t
+get_next_command(void) {
+       isc_uint16_t result = STATUS_QUIT;
+       char cmdlinebuf[MAXCMD];
+       char *cmdline;
+
+       isc_app_block();
+       if (interactive) {
+#ifdef HAVE_READLINE
+               cmdline = readline("> ");
+               add_history(cmdline);
+#else
+               fprintf(stdout, "> ");
+               fflush(stdout);
+               cmdline = fgets(cmdlinebuf, MAXCMD, input);
+#endif
+       } else
+               cmdline = fgets(cmdlinebuf, MAXCMD, input);
+       isc_app_unblock();
+       if (cmdline != NULL)
+               result = do_next_command(cmdline);
+#ifdef HAVE_READLINE
+       if (interactive)
+               free(cmdline);
+#endif
+       return (result);
+}
+
 static isc_boolean_t
 user_interaction(void) {
        isc_uint16_t result = STATUS_MORE;
index 6378df7a7f1e766e15e7e3e1de73cec58a11b1eb..9ea461a029cd0e46fb92d87cad22608b0fe19da5 100644 (file)
@@ -18,7 +18,7 @@
  - PERFORMANCE OF THIS SOFTWARE.
 -->
 
-<!-- $Id: nsupdate.docbook,v 1.44 2010/07/09 23:46:51 tbox Exp $ -->
+<!-- $Id: nsupdate.docbook,v 1.45 2011/12/16 23:01:16 each Exp $ -->
 <refentry id="man.nsupdate">
   <refentryinfo>
     <date>Aug 25, 2009</date>
 
         <varlistentry>
           <term>
-              <command>prereq nxdomain</command>
+              <command><optional>prereq</optional> nxdomain</command>
               <arg choice="req">domain-name</arg>
             </term>
           <listitem>
 
         <varlistentry>
           <term>
-              <command>prereq yxdomain</command>
+              <command><optional>prereq</optional> yxdomain</command>
               <arg choice="req">domain-name</arg>
             </term>
           <listitem>
 
         <varlistentry>
           <term>
-              <command>prereq nxrrset</command>
+              <command><optional>prereq</optional> nxrrset</command>
               <arg choice="req">domain-name</arg>
               <arg choice="opt">class</arg>
               <arg choice="req">type</arg>
 
         <varlistentry>
           <term>
-              <command>prereq yxrrset</command>
+              <command><optional>prereq</optional> yxrrset</command>
               <arg choice="req">domain-name</arg>
               <arg choice="opt">class</arg>
               <arg choice="req">type</arg>
 
         <varlistentry>
           <term>
-              <command>prereq yxrrset</command>
+              <command><optional>prereq</optional> yxrrset</command>
               <arg choice="req">domain-name</arg>
               <arg choice="opt">class</arg>
               <arg choice="req">type</arg>
 
         <varlistentry>
           <term>
-              <command>update delete</command>
+              <command><optional>update</optional> del<optional>ete</optional></command>
               <arg choice="req">domain-name</arg>
               <arg choice="opt">ttl</arg>
               <arg choice="opt">class</arg>
 
         <varlistentry>
           <term>
-              <command>update add</command>
+              <command><optional>update</optional> add</command>
               <arg choice="req">domain-name</arg>
               <arg choice="req">ttl</arg>
               <arg choice="opt">class</arg>
index 136af2318f17915d7d62d97ab9570f2f78d897c5..2374b61874b3a6d76103b8758d49c808aec3d79d 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: tests.sh,v 1.41 2011/07/01 02:25:47 marka Exp $
+# $Id: tests.sh,v 1.42 2011/12/16 23:01:17 each Exp $
 
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
@@ -58,8 +58,8 @@ echo "I:updating zone"
 $NSUPDATE -k ns1/ddns.key <<END > /dev/null || status=1
 server 10.53.0.1 5300
 update add updated.example.nil. 600 A 10.10.10.1
-update add updated.example.nil. 600 TXT Foo
-update delete t.example.nil.
+add updated.example.nil. 600 TXT Foo
+delete t.example.nil.
 
 END
 echo "I:sleeping 5 seconds for server to incorporate changes"
@@ -303,7 +303,7 @@ $NSUPDATE -k ns1/ddns.key <<END > /dev/null || status=1
 server 10.53.0.1 5300
 update add updated3.example.nil. 600 A 10.10.10.3
 update add updated3.example.nil. 600 TXT Zap
-update delete d.example.nil.
+del d.example.nil.
 send
 END
 
index 5d252c31f0e85f2ee43ea0756a71953bdbece069..740b02dab397016e5a035ca041e27ed1ac84e190 100644 (file)
@@ -16,7 +16,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: config.h.in,v 1.150 2011/12/16 00:10:04 marka Exp $ */
+/* $Id: config.h.in,v 1.151 2011/12/16 23:01:16 each Exp $ */
 
 /*! \file */
 
@@ -280,6 +280,9 @@ int sigwait(const unsigned int *set, int *sig);
 /* Define if your OpenSSL version supports GOST. */
 #undef HAVE_OPENSSL_GOST
 
+/* Define to 1 if you have the `readline' function. */
+#undef HAVE_READLINE
+
 /* Define to 1 if you have the <regex.h> header file. */
 #undef HAVE_REGEX_H
 
index 12a3b88a68323dbebf6c3c20b344fcdb46d508d5..8582291d874886719f367717d1453430442138cd 100644 (file)
@@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl
 esyscmd([sed "s/^/# /" COPYRIGHT])dnl
 AC_DIVERT_POP()dnl
 
-AC_REVISION($Revision: 1.531 $)
+AC_REVISION($Revision: 1.532 $)
 
 AC_INIT(lib/dns/name.c)
 AC_PREREQ(2.59)
@@ -2202,6 +2202,28 @@ AC_CHECK_FUNC(strlcat,
        [ISC_PLATFORM_NEEDSTRLCAT="#define ISC_PLATFORM_NEEDSTRLCAT 1"])
 AC_SUBST(ISC_PLATFORM_NEEDSTRLCAT)
 
+
+AC_ARG_WITH(readline,
+        [  --with-readline[=LIBSPEC]    specify readline library [default -lreadline]],
+        readline="$withval", readline="-lreadline")
+case "$readline" in
+no)    ;;
+*)
+       if test "x$readline" = "xyes"
+       then
+               readline=-lreadline
+       fi
+       saved_LIBS="$LIBS"
+       LIBS="$LIBS $readline"
+       AC_CHECK_FUNCS(readline)
+       if test "$ac_cv_func_readline" = "no" 
+       then
+               LIBS="$saved_LIBS"
+       fi
+        ;;
+esac
+
+
 ISC_PRINT_OBJS=
 ISC_PRINT_SRCS=
 AC_MSG_CHECKING(sprintf)