From 886b96ebfd555cfeaf37ae46fc08421a41c61392 Mon Sep 17 00:00:00 2001 From: Andreas Gustafsson Date: Thu, 10 Aug 2000 00:53:36 +0000 Subject: [PATCH] 382. [func] The function dns_zone_setdbtype() now takes an argc/argv style vector of words and sets both the zone database type and its arguments, making the functions dns_zone_adddbarg() and dns_zone_cleardbargs() unnecessary. --- CHANGES | 7 ++ bin/named/zoneconf.c | 67 ++++++++++++++- lib/dns/include/dns/zone.h | 34 ++------ lib/dns/zone.c | 164 ++++++++++++++++++------------------- lib/dns/zoneconf.c | 67 ++++++++++++++- 5 files changed, 224 insertions(+), 115 deletions(-) diff --git a/CHANGES b/CHANGES index 834e1274ab..3a73facf8d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ + + 382. [func] The function dns_zone_setdbtype() now takes + an argc/argv style vector of words and sets + both the zone database type and its arguments, + making the functions dns_zone_adddbarg() + and dns_zone_cleardbargs() unnecessary. + 382. [bug] named -u failed on Debian Linux. 381. [bug] Check for IPV6_RECVPKTINFO and use it instead of diff --git a/bin/named/zoneconf.c b/bin/named/zoneconf.c index 9574b56ac5..a130d4c9a6 100644 --- a/bin/named/zoneconf.c +++ b/bin/named/zoneconf.c @@ -15,10 +15,11 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zoneconf.c,v 1.54 2000/08/08 23:14:28 gson Exp $ */ +/* $Id: zoneconf.c,v 1.55 2000/08/10 00:53:34 gson Exp $ */ #include +#include #include /* Required for HP/UX (and others?) */ #include @@ -105,6 +106,50 @@ dns_zonetype_fromconf(dns_c_zonetype_t cztype) { } } +/* + * Helper function for strtoargv(). Pardon the gratuitous recursion. + */ +static isc_result_t +strtoargvsub(isc_mem_t *mctx, char *s, int *argcp, char ***argvp, int n) { + isc_result_t result; + + /* Discard leading whitespace. */ + while (*s == ' ' || *s == '\t') + s++; + + if (*s == '\0') { + /* We have reached the end of the string. */ + *argcp = n; + *argvp = isc_mem_get(mctx, n * sizeof(char *)); + if (*argvp == NULL) + return (ISC_R_NOMEMORY); + } else { + char *p = s; + while (*p != ' ' && *p != '\t' && *p != '\0') + p++; + if (*p != '\0') + *p++ = '\0'; + + result = strtoargvsub(mctx, p, argcp, argvp, n + 1); + if (result != ISC_R_SUCCESS) + return (result); + (*argvp)[n] = s; + } + return (ISC_R_SUCCESS); +} + +/* + * Tokenize the string "s" into whitespace-separated words, + * return the number of words in '*argcp' and an array + * of pointers to the words in '*argvp'. The caller + * must free the array using isc_mem_put(). The string + * is modified in-place. + */ +static isc_result_t +strtoargv(isc_mem_t *mctx, char *s, int *argcp, char ***argvp) { + return (strtoargvsub(mctx, s, argcp, argvp, 0)); +} + isc_result_t dns_zone_configure(dns_c_ctx_t *cctx, dns_c_view_t *cview, dns_c_zone_t *czone, dns_aclconfctx_t *ac, @@ -122,6 +167,11 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_c_view_t *cview, isc_uint32_t uintval; isc_sockaddr_t sockaddr_any4, sockaddr_any6; dns_ssutable_t *ssutable = NULL; + char *cpval; + unsigned int dbargc; + char **dbargv; + static char default_dbtype[] = "rbt"; + isc_mem_t *mctx = dns_zone_getmctx(zone); isc_sockaddr_any(&sockaddr_any4); isc_sockaddr_any6(&sockaddr_any6); @@ -134,8 +184,19 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_c_view_t *cview, dns_zone_settype(zone, dns_zonetype_fromconf(czone->ztype)); - /* XXX needs to be an zone option */ - RETERR(dns_zone_setdbtype(zone, "rbt")); + cpval = NULL; + result = dns_c_zone_getdatabase(czone, &cpval); +#ifdef notyet + if (result != ISC_R_SUCCESS && cview != NULL) + result = dns_c_view_getdatabase(cview, &cpval); + if (result != ISC_R_SUCCESS) + result = dns_c_ctx_getdatabase(cview, &cpval); +#endif + if (result != ISC_R_SUCCESS) + cpval = default_dbtype; + RETERR(strtoargv(mctx, cpval, &dbargc, &dbargv)); + RETERR(dns_zone_setdbtype(zone, dbargc, dbargv)); + isc_mem_put(mctx, dbargv, dbargc * sizeof(*dbargv)); result = dns_c_zone_getfile(czone, &filename); if (result == ISC_R_SUCCESS) diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 5bc3c0e78b..f6a8631fa4 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.h,v 1.66 2000/08/08 23:36:24 gson Exp $ */ +/* $Id: zone.h,v 1.67 2000/08/10 00:53:36 gson Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -254,30 +254,6 @@ dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value); * 'zone' to be a valid zone. */ -isc_result_t -dns_zone_adddbarg(dns_zone_t *zone, char *arg); -/* - * Add 'arg' to the end of the list of database arguements. - * No attempt in made to validate the arguements. - * - * Require: - * 'zone' to be a valid zone. - * 'arg' to be non NULL. - * - * Returns: - * ISC_R_NOMEMORY - * ISC_R_SUCCESS - */ - -void -dns_zone_cleardbargs(dns_zone_t *zone); -/* - * Clear all database arguements. - * - * Require: - * 'zone' to be a valid zone. - */ - isc_result_t dns_zone_getdb(dns_zone_t *zone, dns_db_t **dbp); /* @@ -294,14 +270,18 @@ dns_zone_getdb(dns_zone_t *zone, dns_db_t **dbp); */ isc_result_t -dns_zone_setdbtype(dns_zone_t *zone, const char *db_type); +dns_zone_setdbtype(dns_zone_t *zone, + unsigned int dbargc, char **dbargv); /* - * Sets the database type. Current database types are: "rbt", "rbt64". + * Sets the database type to dbargv[0] and database arguments + * to subsequent dbargv elements. * 'db_type' is not checked to see if it is a valid database type. * * Require: * 'zone' to be a valid zone. * 'database' to be non NULL. + * 'dbargc' to be >= 1 + * 'dbargv' to point to dbargc NULL-terminated strings * * Returns: * ISC_R_NOMEMORY diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 5a6ab69cf8..9833ac4950 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.177 2000/08/09 00:17:20 bwelling Exp $ */ +/* $Id: zone.c,v 1.178 2000/08/10 00:53:33 gson Exp $ */ #include @@ -101,7 +101,6 @@ struct dns_zone { dns_zonetype_t type; unsigned int flags; unsigned int options; - char *db_type; unsigned int db_argc; char **db_argv; isc_stdtime_t expiretime; @@ -288,6 +287,8 @@ zone_get_from_db(dns_db_t *db, dns_name_t *origin, unsigned int *nscount, isc_uint32_t *refresh, isc_uint32_t *retry, isc_uint32_t *expire, isc_uint32_t *minimum); +static void zone_freedbargs(dns_zone_t *zone); + #define PRINT_ZONE_REF(zone) \ do { \ char *s = NULL; \ @@ -304,6 +305,9 @@ zone_get_from_db(dns_db_t *db, dns_name_t *origin, unsigned int *nscount, #define DNS_ENTER zone_log(zone, me, ISC_LOG_DEBUG(1), "enter") #define DNS_LEAVE zone_log(zone, me, ISC_LOG_DEBUG(1), "leave") +const unsigned int dbargc_default = 1; +const char *dbargv_default[] = { "rbt" }; + /*** *** Public functions. ***/ @@ -345,7 +349,6 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->type = dns_zone_none; zone->flags = 0; zone->options = 0; - zone->db_type = NULL; zone->db_argc = 0; zone->db_argv = NULL; zone->expiretime = 0; @@ -395,12 +398,24 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { ISC_LINK_INIT(zone, statelink); zone->statelist = NULL; + zone->magic = ZONE_MAGIC; + + /* Must be after magic is set. */ + result = dns_zone_setdbtype(zone, dbargc_default, + (char **) dbargv_default); + if (result != ISC_R_SUCCESS) + goto free_mutex; + ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL, DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, NULL, NULL); *zonep = zone; return (ISC_R_SUCCESS); + + free_mutex: + isc_mutex_destroy(&zone->lock); + return (ISC_R_NOMEMORY); } /* @@ -438,12 +453,9 @@ zone_free(dns_zone_t *zone) { if (zone->journal != NULL) isc_mem_free(zone->mctx, zone->journal); zone->journal = NULL; - if (zone->db_type != NULL) - isc_mem_free(zone->mctx, zone->db_type); - zone->db_type = NULL; if (zone->db != NULL) dns_db_detach(&zone->db); - dns_zone_cleardbargs(zone); + zone_freedbargs(zone); #ifndef NOMINUM_PUBLIC dns_zone_setmasterswithkeys(zone, NULL, NULL, 0); #else /* NOMINUM_PUBLIC */ @@ -523,19 +535,67 @@ dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) { UNLOCK(&zone->lock); } +static void +zone_freedbargs(dns_zone_t *zone) { + unsigned int i; + + /* Free the old database argument list. */ + if (zone->db_argv != NULL) { + for (i = 0; i < zone->db_argc; i++) + isc_mem_free(zone->mctx, zone->db_argv[i]); + isc_mem_put(zone->mctx, zone->db_argv, + zone->db_argc * sizeof *zone->db_argv); + } + zone->db_argc = 0; + zone->db_argv = NULL; +} + isc_result_t -dns_zone_setdbtype(dns_zone_t *zone, const char *db_type) { +dns_zone_setdbtype(dns_zone_t *zone, + unsigned int dbargc, char **dbargv) { isc_result_t result = ISC_R_SUCCESS; + char **new = NULL; + unsigned int i; REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(dbargc >= 1); + REQUIRE(dbargv != NULL); LOCK(&zone->lock); - if (zone->db_type != NULL) - isc_mem_free(zone->mctx, zone->db_type); - zone->db_type = isc_mem_strdup(zone->mctx, db_type); - if (zone->db_type == NULL) - result = ISC_R_NOMEMORY; - UNLOCK(&zone->lock); + + /* Set up a new database argument list. */ + new = isc_mem_get(zone->mctx, dbargc * sizeof *new); + if (new == NULL) + goto nomem; + for (i = 0; i < dbargc; i++) + new[i] = NULL; + for (i = 0; i < dbargc; i++) { + new[i] = isc_mem_strdup(zone->mctx, dbargv[i]); + if (new[i] == NULL) + goto nomem; + } + + /* Free the old list. */ + zone_freedbargs(zone); + + zone->db_argc = dbargc; + zone->db_argv = new; + result = ISC_R_SUCCESS; + goto unlock; + + nomem: + if (new != NULL) { + for (i = 0; i < dbargc; i++) { + if (zone->db_argv[i] != NULL) + isc_mem_free(zone->mctx, new[i]); + isc_mem_put(zone->mctx, new, + dbargc * sizeof *new); + } + } + result = ISC_R_NOMEMORY; + + unlock: + UNLOCK(&zone->lock); return (result); } @@ -688,10 +748,12 @@ dns_zone_load(dns_zone_t *zone) { if (result != ISC_R_SUCCESS) goto cleanup; - result = dns_db_create(zone->mctx, zone->db_type, + INSIST(zone->db_argc >= 1); + result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, (zone->type == dns_zone_stub) ? dns_dbtype_stub : dns_dbtype_zone, - zone->rdclass, zone->db_argc, zone->db_argv, + zone->rdclass, + zone->db_argc - 1, zone->db_argv + 1, &db); if (result != ISC_R_SUCCESS) @@ -1166,64 +1228,6 @@ dns_zone_getoptions(dns_zone_t *zone) { return (zone->options); } -isc_result_t -dns_zone_adddbarg(dns_zone_t *zone, char *arg) { - char **new = NULL; - - REQUIRE(DNS_ZONE_VALID(zone)); - REQUIRE(arg != NULL); - - /* - * Allocate new 'db_argv' and set last to be copy of 'arg'. - */ - LOCK(&zone->lock); - new = isc_mem_get(zone->mctx, (zone->db_argc + 1) * sizeof *new); - if (new == NULL) - goto cleanup; - new[zone->db_argc] = isc_mem_strdup(zone->mctx, arg); - if (new[zone->db_argc] == NULL) - goto cleanup; - - /* - * Copy old 'db_argv' if required the free it. - */ - if (zone->db_argc != 0) { - memcpy(new, zone->db_argv, zone->db_argc * sizeof *new); - isc_mem_put(zone->mctx, zone->db_argv, - zone->db_argc * sizeof *new); - } - - zone->db_argv = new; - zone->db_argc++; - UNLOCK(&zone->lock); - return (ISC_R_SUCCESS); - - cleanup: - if (new != NULL) - isc_mem_put(zone->mctx, new, - (zone->db_argc + 1) * sizeof *new); - UNLOCK(&zone->lock); - return (ISC_R_NOMEMORY); -} - -void -dns_zone_cleardbargs(dns_zone_t *zone) { - unsigned int i; - - REQUIRE(DNS_ZONE_VALID(zone)); - - LOCK(&zone->lock); - if (zone->db_argc) { - for (i = 0 ; i < zone->db_argc; i++) - isc_mem_free(zone->mctx, zone->db_argv[i]); - isc_mem_put(zone->mctx, zone->db_argv, - zone->db_argc * sizeof *zone->db_argv); - zone->db_argc = 0; - zone->db_argv = NULL; - } - UNLOCK(&zone->lock); -} - isc_result_t dns_zone_setxfrsource4(dns_zone_t *zone, isc_sockaddr_t *xfrsource) { REQUIRE(DNS_ZONE_VALID(zone)); @@ -2930,10 +2934,12 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { if (zone->db != NULL) dns_db_attach(zone->db, &stub->db); else { - result = dns_db_create(zone->mctx, "rbt", + INSIST(zone->db_argc >= 1); + result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin, dns_dbtype_stub, zone->rdclass, - zone->db_argc, zone->db_argv, + zone->db_argc - 1, + zone->db_argv + 1, &stub->db); if (result != ISC_R_SUCCESS) { zone_log(zone, me, ISC_LOG_INFO, @@ -3780,12 +3786,6 @@ dns_zone_equal(dns_zone_t *oldzone, dns_zone_t *newzone) { strcmp(oldzone->journal, newzone->journal) != 0)) goto false; - if ((oldzone->db_type == NULL && newzone->db_type != NULL) || - (oldzone->db_type != NULL && newzone->db_type == NULL) || - (oldzone->db_type != NULL && - strcmp(oldzone->db_type, newzone->db_type) != 0)) - goto false; - for (i = 0; i < oldzone->db_argc; i++) if (strcmp(oldzone->db_argv[i], newzone->db_argv[i]) != 0) goto false; diff --git a/lib/dns/zoneconf.c b/lib/dns/zoneconf.c index 9574b56ac5..a130d4c9a6 100644 --- a/lib/dns/zoneconf.c +++ b/lib/dns/zoneconf.c @@ -15,10 +15,11 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zoneconf.c,v 1.54 2000/08/08 23:14:28 gson Exp $ */ +/* $Id: zoneconf.c,v 1.55 2000/08/10 00:53:34 gson Exp $ */ #include +#include #include /* Required for HP/UX (and others?) */ #include @@ -105,6 +106,50 @@ dns_zonetype_fromconf(dns_c_zonetype_t cztype) { } } +/* + * Helper function for strtoargv(). Pardon the gratuitous recursion. + */ +static isc_result_t +strtoargvsub(isc_mem_t *mctx, char *s, int *argcp, char ***argvp, int n) { + isc_result_t result; + + /* Discard leading whitespace. */ + while (*s == ' ' || *s == '\t') + s++; + + if (*s == '\0') { + /* We have reached the end of the string. */ + *argcp = n; + *argvp = isc_mem_get(mctx, n * sizeof(char *)); + if (*argvp == NULL) + return (ISC_R_NOMEMORY); + } else { + char *p = s; + while (*p != ' ' && *p != '\t' && *p != '\0') + p++; + if (*p != '\0') + *p++ = '\0'; + + result = strtoargvsub(mctx, p, argcp, argvp, n + 1); + if (result != ISC_R_SUCCESS) + return (result); + (*argvp)[n] = s; + } + return (ISC_R_SUCCESS); +} + +/* + * Tokenize the string "s" into whitespace-separated words, + * return the number of words in '*argcp' and an array + * of pointers to the words in '*argvp'. The caller + * must free the array using isc_mem_put(). The string + * is modified in-place. + */ +static isc_result_t +strtoargv(isc_mem_t *mctx, char *s, int *argcp, char ***argvp) { + return (strtoargvsub(mctx, s, argcp, argvp, 0)); +} + isc_result_t dns_zone_configure(dns_c_ctx_t *cctx, dns_c_view_t *cview, dns_c_zone_t *czone, dns_aclconfctx_t *ac, @@ -122,6 +167,11 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_c_view_t *cview, isc_uint32_t uintval; isc_sockaddr_t sockaddr_any4, sockaddr_any6; dns_ssutable_t *ssutable = NULL; + char *cpval; + unsigned int dbargc; + char **dbargv; + static char default_dbtype[] = "rbt"; + isc_mem_t *mctx = dns_zone_getmctx(zone); isc_sockaddr_any(&sockaddr_any4); isc_sockaddr_any6(&sockaddr_any6); @@ -134,8 +184,19 @@ dns_zone_configure(dns_c_ctx_t *cctx, dns_c_view_t *cview, dns_zone_settype(zone, dns_zonetype_fromconf(czone->ztype)); - /* XXX needs to be an zone option */ - RETERR(dns_zone_setdbtype(zone, "rbt")); + cpval = NULL; + result = dns_c_zone_getdatabase(czone, &cpval); +#ifdef notyet + if (result != ISC_R_SUCCESS && cview != NULL) + result = dns_c_view_getdatabase(cview, &cpval); + if (result != ISC_R_SUCCESS) + result = dns_c_ctx_getdatabase(cview, &cpval); +#endif + if (result != ISC_R_SUCCESS) + cpval = default_dbtype; + RETERR(strtoargv(mctx, cpval, &dbargc, &dbargv)); + RETERR(dns_zone_setdbtype(zone, dbargc, dbargv)); + isc_mem_put(mctx, dbargv, dbargc * sizeof(*dbargv)); result = dns_c_zone_getfile(czone, &filename); if (result == ISC_R_SUCCESS)