Commit 1d32b1df authored by Evan Hunt's avatar Evan Hunt

3244. [func] Added readline support to nslookup and nsupdate.

			Also simplified nsupdate syntax to make "update"
			and "prereq" optional. [RT #24659]
parent 8fee6590
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.
......
......@@ -15,11 +15,12 @@
* 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>
......@@ -45,6 +46,11 @@
#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);
......
......@@ -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 */
......@@ -85,6 +85,10 @@
#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;
......
......@@ -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>
......@@ -424,7 +424,7 @@
<varlistentry>
<term>
<command>prereq nxdomain</command>
<command><optional>prereq</optional> nxdomain</command>
<arg choice="req">domain-name</arg>
</term>
<listitem>
......@@ -438,7 +438,7 @@
<varlistentry>
<term>
<command>prereq yxdomain</command>
<command><optional>prereq</optional> yxdomain</command>
<arg choice="req">domain-name</arg>
</term>
<listitem>
......@@ -452,7 +452,7 @@
<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>
......@@ -474,7 +474,7 @@
<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>
......@@ -496,7 +496,7 @@
<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>
......@@ -530,7 +530,7 @@
<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>
......@@ -556,7 +556,7 @@
<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>
......
......@@ -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
......
......@@ -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
......
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment