diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 65c763e244..2d69c44956 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dig.c,v 1.215 2007/03/30 23:46:45 tbox Exp $ */ +/* $Id: dig.c,v 1.216 2007/04/03 23:06:39 marka Exp $ */ /*! \file */ @@ -650,42 +650,6 @@ printgreeting(int argc, char **argv, dig_lookup_t *lookup) { } } -/*% - * Reorder an argument list so that server names all come at the end. - * This is a bit of a hack, to allow batch-mode processing to properly - * handle the server options. - */ -static void -reorder_args(int argc, char *argv[]) { - int i, j; - char *ptr; - int end; - - debug("reorder_args()"); - end = argc - 1; - while (argv[end][0] == '@') { - end--; - if (end == 0) - return; - } - debug("arg[end]=%s", argv[end]); - for (i = end; i > 0; i--) { - debug("arg[%d]=%s", i, argv[i]); - if (argv[i][0] == '@') { - ptr = argv[i]; - for (j = i + 1; j <= end; j++) { - debug("Moving %s to %d", argv[j], j - 1); - argv[j - 1] = argv[j]; - } - debug("moving %s to end, %d", ptr, end); - argv[end] = ptr; - end--; - if (end < 1) - return; - } - } -} - static isc_uint32_t parse_uint(char *arg, const char *desc, isc_uint32_t max) { isc_result_t result; @@ -1104,7 +1068,9 @@ static const char *single_dash_opts = "46dhimnv"; static const char *dash_opts = "46bcdfhikmnptvyx"; static isc_boolean_t dash_option(char *option, char *next, dig_lookup_t **lookup, - isc_boolean_t *open_type_class, isc_boolean_t config_only) + isc_boolean_t *open_type_class, isc_boolean_t *need_clone, + isc_boolean_t config_only, int argc, char **argv, + isc_boolean_t *firstarg) { char opt, *value, *ptr, *ptr2, *ptr3; isc_result_t result; @@ -1241,14 +1207,20 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, return (value_from_next); case 'q': if (!config_only) { - (*lookup) = clone_lookup(default_lookup, - ISC_TRUE); + if (*need_clone) + (*lookup) = clone_lookup(default_lookup, + ISC_TRUE); + *need_clone = ISC_TRUE; strncpy((*lookup)->textname, value, sizeof((*lookup)->textname)); (*lookup)->textname[sizeof((*lookup)->textname)-1]=0; (*lookup)->trace_root = ISC_TF((*lookup)->trace || (*lookup)->ns_search_only); (*lookup)->new_search = ISC_TRUE; + if (*firstarg) { + printgreeting(argc, argv, *lookup); + *firstarg = ISC_FALSE; + } ISC_LIST_APPEND(lookup_list, (*lookup), link); debug("looking up %s", (*lookup)->textname); } @@ -1376,7 +1348,9 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, keysecret[sizeof(keysecret)-1]=0; return (value_from_next); case 'x': - *lookup = clone_lookup(default_lookup, ISC_TRUE); + if (*need_clone) + *lookup = clone_lookup(default_lookup, ISC_TRUE); + *need_clone = ISC_TRUE; if (get_reverse(textname, sizeof(textname), value, ip6_int, ISC_FALSE) == ISC_R_SUCCESS) { strncpy((*lookup)->textname, textname, @@ -1390,6 +1364,10 @@ dash_option(char *option, char *next, dig_lookup_t **lookup, if (!(*lookup)->rdclassset) (*lookup)->rdclass = dns_rdataclass_in; (*lookup)->new_search = ISC_TRUE; + if (*firstarg) { + printgreeting(argc, argv, *lookup); + *firstarg = ISC_FALSE; + } ISC_LIST_APPEND(lookup_list, *lookup, link); } else { fprintf(stderr, "Invalid IP address %s\n", value); @@ -1482,6 +1460,7 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, #endif char *input; int i; + isc_boolean_t need_clone = ISC_TRUE; /* * The semantics for parsing the args is a bit complex; if @@ -1529,9 +1508,8 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, bargv[0] = argv[0]; argv0 = argv[0]; - reorder_args(bargc, (char **)bargv); for(i = 0; i < bargc; i++) - debug("cmdline argv %d: %s", + debug(".digrc argv %d: %s", i, bargv[i]); parse_args(ISC_TRUE, ISC_TRUE, bargc, (char **)bargv); @@ -1541,7 +1519,12 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, #endif } - lookup = default_lookup; + if (is_batchfile && !config_only) { + /* Processing '-f batchfile'. */ + lookup = clone_lookup(default_lookup, ISC_TRUE); + need_clone = ISC_FALSE; + } else + lookup = default_lookup; rc = argc; rv = argv; @@ -1558,14 +1541,16 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, if (rc <= 1) { if (dash_option(&rv[0][1], NULL, &lookup, &open_type_class, - config_only)) { + &need_clone, config_only, + argc, argv, &firstarg)) { rc--; rv++; } } else { if (dash_option(&rv[0][1], rv[1], &lookup, &open_type_class, - config_only)) { + &need_clone, config_only, + argc, argv, &firstarg)) { rc--; rv++; } @@ -1633,21 +1618,29 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, continue; } } + if (!config_only) { - lookup = clone_lookup(default_lookup, - ISC_TRUE); + if (need_clone) + lookup = clone_lookup(default_lookup, + ISC_TRUE); + need_clone = ISC_TRUE; strncpy(lookup->textname, rv[0], sizeof(lookup->textname)); lookup->textname[sizeof(lookup->textname)-1]=0; lookup->trace_root = ISC_TF(lookup->trace || lookup->ns_search_only); lookup->new_search = ISC_TRUE; + if (firstarg) { + printgreeting(argc, argv, lookup); + firstarg = ISC_FALSE; + } ISC_LIST_APPEND(lookup_list, lookup, link); debug("looking up %s", lookup->textname); } /* XXX Error message */ } } + /* * If we have a batchfile, seed the lookup list with the * first entry, then trust the callback in dighost_shutdown @@ -1682,17 +1675,20 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, bargv[0] = argv[0]; argv0 = argv[0]; - reorder_args(bargc, (char **)bargv); for(i = 0; i < bargc; i++) debug("batch argv %d: %s", i, bargv[i]); parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv); + return; } + return; } /* * If no lookup specified, search for root */ if ((lookup_list.head == NULL) && !config_only) { - lookup = clone_lookup(default_lookup, ISC_TRUE); + if (need_clone) + lookup = clone_lookup(default_lookup, ISC_TRUE); + need_clone = ISC_TRUE; lookup->trace_root = ISC_TF(lookup->trace || lookup->ns_search_only); lookup->new_search = ISC_TRUE; @@ -1704,10 +1700,9 @@ parse_args(isc_boolean_t is_batchfile, isc_boolean_t config_only, firstarg = ISC_FALSE; } ISC_LIST_APPEND(lookup_list, lookup, link); - } else if (!config_only && firstarg) { - printgreeting(argc, argv, lookup); - firstarg = ISC_FALSE; } + if (!need_clone) + destroy_lookup(lookup); } /* @@ -1749,7 +1744,6 @@ dighost_shutdown(void) { bargv[0] = argv0; - reorder_args(bargc, (char **)bargv); for(i = 0; i < bargc; i++) debug("batch argv %d: %s", i, bargv[i]); parse_args(ISC_TRUE, ISC_FALSE, bargc, (char **)bargv); @@ -1767,7 +1761,6 @@ dighost_shutdown(void) { int main(int argc, char **argv) { isc_result_t result; - dig_server_t *s, *s2; ISC_LIST_INIT(lookup_list); ISC_LIST_INIT(server_list); @@ -1788,16 +1781,7 @@ main(int argc, char **argv) { result = isc_app_onrun(mctx, global_task, onrun_callback, NULL); check_result(result, "isc_app_onrun"); isc_app_run(); - s = ISC_LIST_HEAD(default_lookup->my_server_list); - while (s != NULL) { - debug("freeing server %p belonging to %p", - s, default_lookup); - s2 = s; - s = ISC_LIST_NEXT(s, link); - ISC_LIST_DEQUEUE(default_lookup->my_server_list, s2, link); - isc_mem_free(mctx, s2); - } - isc_mem_free(mctx, default_lookup); + destroy_lookup(default_lookup); if (batchname != NULL) { if (batchfp != stdin) fclose(batchfp); diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 5219f5ec0f..986a6774ec 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.301 2007/02/27 00:58:08 marka Exp $ */ +/* $Id: dighost.c,v 1.302 2007/04/03 23:06:39 marka Exp $ */ /*! \file * \note @@ -1276,9 +1276,7 @@ clear_query(dig_query_t *query) { */ static isc_boolean_t try_clear_lookup(dig_lookup_t *lookup) { - dig_server_t *s; dig_query_t *q; - void *ptr; REQUIRE(lookup != NULL); @@ -1299,7 +1297,16 @@ try_clear_lookup(dig_lookup_t *lookup) { * At this point, we know there are no queries on the lookup, * so can make it go away also. */ - debug("cleared"); + destroy_lookup(lookup); + return (ISC_TRUE); +} + +void +destroy_lookup(dig_lookup_t *lookup) { + dig_server_t *s; + void *ptr; + + debug("destroy"); s = ISC_LIST_HEAD(lookup->my_server_list); while (s != NULL) { debug("freeing server %p belonging to %p", s, lookup); @@ -1324,7 +1331,6 @@ try_clear_lookup(dig_lookup_t *lookup) { dst_context_destroy(&lookup->tsigctx); isc_mem_free(mctx, lookup); - return (ISC_TRUE); } /*% diff --git a/bin/dig/include/dig/dig.h b/bin/dig/include/dig/dig.h index 178cbbcdee..f63fa2f032 100644 --- a/bin/dig/include/dig/dig.h +++ b/bin/dig/include/dig/dig.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dig.h,v 1.103 2007/02/26 23:46:54 tbox Exp $ */ +/* $Id: dig.h,v 1.104 2007/04/03 23:06:39 marka Exp $ */ #ifndef DIG_H #define DIG_H @@ -303,6 +303,9 @@ check_result(isc_result_t result, const char *msg); void setup_lookup(dig_lookup_t *lookup); +void +destroy_lookup(dig_lookup_t *lookup); + void do_lookup(dig_lookup_t *lookup);