diff --git a/bin/check/check-tool.c b/bin/check/check-tool.c index 5f00121d26..38387b172b 100644 --- a/bin/check/check-tool.c +++ b/bin/check/check-tool.c @@ -695,8 +695,13 @@ load_zone(isc_mem_t *mctx, const char *zonename, const char *filename, CHECK(dns_name_fromtext(origin, &buffer, dns_rootname, 0, NULL)); CHECK(dns_zone_setorigin(zone, origin)); dns_zone_setdbtype(zone, 1, (const char *const *)dbtype); - CHECK(dns_zone_setfile(zone, filename, fileformat, - &dns_master_style_default)); + if (strcmp(filename, "-") == 0) { + CHECK(dns_zone_setstream(zone, stdin, fileformat, + &dns_master_style_default)); + } else { + CHECK(dns_zone_setfile(zone, filename, fileformat, + &dns_master_style_default)); + } if (journal != NULL) { CHECK(dns_zone_setjournal(zone, journal)); } diff --git a/bin/check/named-checkzone.c b/bin/check/named-checkzone.c index e50f84e0d2..4b15bd02b2 100644 --- a/bin/check/named-checkzone.c +++ b/bin/check/named-checkzone.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -76,7 +77,7 @@ usage(void) { "[-i (full|full-sibling|local|local-sibling|none)] " "[-M (ignore|warn|fail)] [-S (ignore|warn|fail)] " "[-W (ignore|warn)] " - "%s zonename filename\n", + "%s zonename [ (filename|-) ]\n", prog_name, progmode == progmode_check ? "[-o filename]" : "-o filename"); exit(1); @@ -94,7 +95,7 @@ int main(int argc, char **argv) { int c; char *origin = NULL; - char *filename = NULL; + const char *filename = NULL; isc_log_t *lctx = NULL; isc_result_t result; char classname_in[] = "IN"; @@ -512,7 +513,8 @@ main(int argc, char **argv) { logdump = false; } - if (isc_commandline_index + 2 != argc) { + if (argc - isc_commandline_index < 1 || + argc - isc_commandline_index > 2) { usage(); } @@ -529,7 +531,16 @@ main(int argc, char **argv) { dns_result_register(); origin = argv[isc_commandline_index++]; - filename = argv[isc_commandline_index++]; + + if (isc_commandline_index == argc) { + /* "-" will be interpreted as stdin */ + filename = "-"; + } else { + filename = argv[isc_commandline_index]; + } + + isc_commandline_index++; + result = load_zone(mctx, origin, filename, inputformat, classname, maxttl, &zone); @@ -563,5 +574,6 @@ main(int argc, char **argv) { #ifdef _WIN32 DestroySockets(); #endif /* ifdef _WIN32 */ + return ((result == ISC_R_SUCCESS) ? 0 : 1); } diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index f209e95bf0..80ccb22979 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -295,6 +295,23 @@ dns_zone_getfile(dns_zone_t *zone); *\li Pointer to null-terminated file name, or NULL. */ +isc_result_t +dns_zone_setstream(dns_zone_t *zone, const FILE *stream, + dns_masterformat_t format, const dns_master_style_t *style); +/*%< + * Sets the source stream from which the zone will load its database. + * + * Requires: + *\li 'zone' to be a valid zone. + *\li 'stream' to be a valid and open FILE *. + *\li 'zone->masterfile' to be NULL, since we should load data either from + * 'stream' or from a master file, but not both. + * + * Returns: + *\li #ISC_R_NOMEMORY + *\li #ISC_R_SUCCESS + */ + void dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t records); /*%< diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in index 83d750cb03..38ee1a123a 100644 --- a/lib/dns/win32/libdns.def.in +++ b/lib/dns/win32/libdns.def.in @@ -1351,6 +1351,7 @@ dns_zone_setssutable dns_zone_setstatistics dns_zone_setstatlevel dns_zone_setstats +dns_zone_setstream dns_zone_settask dns_zone_settype dns_zone_setupdateacl diff --git a/lib/dns/zone.c b/lib/dns/zone.c index a7d11e8192..b0161c3311 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -214,6 +214,7 @@ struct dns_zone { isc_refcount_t irefs; dns_name_t origin; char *masterfile; + const FILE *stream; /* loading from a stream? */ ISC_LIST(dns_include_t) includes; /* Include files */ ISC_LIST(dns_include_t) newincludes; /* Loading */ unsigned int nincludes; @@ -986,6 +987,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->strrdclass = NULL; zone->strviewname = NULL; zone->masterfile = NULL; + zone->stream = NULL; ISC_LIST_INIT(zone->includes); ISC_LIST_INIT(zone->newincludes); zone->nincludes = 0; @@ -1672,6 +1674,7 @@ dns_zone_setfile(dns_zone_t *zone, const char *file, dns_masterformat_t format, isc_result_t result = ISC_R_SUCCESS; REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(zone->stream == NULL); LOCK_ZONE(zone); result = dns_zone_setstring(zone, &zone->masterfile, file); @@ -1694,6 +1697,27 @@ dns_zone_getfile(dns_zone_t *zone) { return (zone->masterfile); } +isc_result_t +dns_zone_setstream(dns_zone_t *zone, const FILE *stream, + dns_masterformat_t format, const dns_master_style_t *style) { + isc_result_t result = ISC_R_SUCCESS; + + REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(stream != NULL); + REQUIRE(zone->masterfile == NULL); + + LOCK_ZONE(zone); + zone->stream = stream; + zone->masterformat = format; + if (format == dns_masterformat_text) { + zone->masterstyle = style; + } + result = default_journal(zone); + UNLOCK_ZONE(zone); + + return (result); +} + dns_ttl_t dns_zone_getmaxttl(dns_zone_t *zone) { REQUIRE(DNS_ZONE_VALID(zone)); @@ -2175,8 +2199,10 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) { (zone->type == dns_zone_redirect && zone->masters != NULL)) && rbt) { - if (zone->masterfile == NULL || - !isc_file_exists(zone->masterfile)) { + if (zone->stream == NULL && + (zone->masterfile == NULL || + !isc_file_exists(zone->masterfile))) + { if (zone->masterfile != NULL) { dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1), @@ -2221,7 +2247,7 @@ zone_load(dns_zone_t *zone, unsigned int flags, bool locked) { } if (!dns_db_ispersistent(db)) { - if (zone->masterfile != NULL) { + if (zone->masterfile != NULL || zone->stream != NULL) { result = zone_startload(db, zone, loadtime); } else { result = DNS_R_NOMASTERFILE; @@ -2643,11 +2669,21 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { zone_idetach(&callbacks.zone); return (result); } - result = dns_master_loadfile( - zone->masterfile, &zone->origin, &zone->origin, - zone->rdclass, options, 0, &callbacks, - zone_registerinclude, zone, zone->mctx, - zone->masterformat, zone->maxttl); + + if (zone->stream != NULL) { + FILE *stream = NULL; + DE_CONST(zone->stream, stream); + result = dns_master_loadstream( + stream, &zone->origin, &zone->origin, + zone->rdclass, options, &callbacks, zone->mctx); + } else { + result = dns_master_loadfile( + zone->masterfile, &zone->origin, &zone->origin, + zone->rdclass, options, 0, &callbacks, + zone_registerinclude, zone, zone->mctx, + zone->masterformat, zone->maxttl); + } + tresult = dns_db_endload(db, &callbacks); if (result == ISC_R_SUCCESS) { result = tresult;