masterdump.c revision 58aaab3687aac838542ee4ef65a9c094a5d34ab0
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * Copyright (C) 1999 Internet Software Consortium.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * Permission to use, copy, modify, and distribute this software for any
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * purpose with or without fee is hereby granted, provided that the above
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * copyright notice and this permission notice appear in all copies.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff#define RETERR(x) do { \
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff * Flags affecting master file formatting. Flags 0x0000FFFF
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff * define the formatting of the rdata part and are defined in
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff/* Omit the owner name when possible. */
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff * Omit the TTL when possible. If DNS_STYLEFLAG_TTL is
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * also set, this means no TTLs are ever printed
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff * because $TTL directives are generated before every
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * change in the TTL. In this case, no columns need to
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * be reserved for the TTL. Master files generated with
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * these options will be rejected by BIND 4.x because it
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * does not recognize the $TTL directive.
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * If DNS_STYLEFLAG_TTL is not also set, the TTL will be
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * omitted when it is equal to the previous TTL.
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * This is correct according to RFC1035, but the
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * TTLs may be silently misinterpreted by older
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff * versions of BIND which use the SOA MINTTL as a
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * default TTL value.
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff/* Omit the class when possible. */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff/* Output $TTL directives. */
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * Output $ORIGIN directives and print owner names relative to
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * the origin when possible.
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff/* Print domain names in RR data in relative form when possible.
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff For this to take effect, DNS_STYLEFLAG_REL_OWNER must also be set. */
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * The maximum length of the newline+indentation that is output
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff * when inserting a line break in an RR. This effectively puts an
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff * upper limits on the value of "rdata_column", because if it is
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * very large, the tabs and spaces needed to reach it will not fit.
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * Context structure for a masterfile dump in progress.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Grafftypedef struct dns_totext_ctx {
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff * The default master file style.
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * Because the TTL is always omitted, and the class is almost always
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * omitted, neither is allocated any columns.
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff * A style suitable for dns_rdataset_totext().
59c049874bbef182857c57bd9cca292898921c69Bob Halley * Output tabs and spaces to go from column '*current' to
59c049874bbef182857c57bd9cca292898921c69Bob Halley * column 'to', and update '*current' to reflect the new
59c049874bbef182857c57bd9cca292898921c69Bob Halley * current column.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graffindent(unsigned int *current, unsigned int to, int tabwidth,
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley unsigned char *p;
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley unsigned int from;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Grafftotext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx)
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff /* Set up the line break string if needed. */
439c0011e642fb1d26011116144af698125262dbMichael Graff if ((ctx->style.flags & DNS_STYLEFLAG_MULTILINE) != 0) {
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff unsigned int col = 0;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff result = indent(&col, ctx->style.rdata_column,
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff * Do not return DNS_R_NOSPACE if the line break string
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * buffer is too small, because that would just make
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * dump_rdataset() retry indenfinitely with ever
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * bigger target buffers. That's a different buffer,
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * so it won't help. Use DNS_R_TEXTTOOLONG as a substitute.
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff * Convert 'rdataset' to master file text format according to 'ctx',
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff * storing the result in 'target'. If 'owner_name' is NULL, it
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley * is omitted; otherwise 'owner_name' must be valid and have at least
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff unsigned int column;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley /* Owner name. */
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff ! ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0 &&
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (! ((ctx->style.flags & DNS_STYLEFLAG_OMIT_TTL) != 0 &&
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff unsigned int length;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff length = sprintf(ttlbuf, "%u", rdataset->ttl);
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * If the $TTL directive is not in use, the TTL we
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * just printed becomes the default for subsequent RRs.
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff if ((ctx->style.flags & DNS_STYLEFLAG_TTL) == 0) {
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff if ((ctx->style.flags & DNS_STYLEFLAG_OMIT_CLASS) == 0 ||
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff result = dns_rdataclass_totext(rdataset->rdclass,
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff result = dns_rdatatype_totext(rdataset->type, target);
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff * Update the ctx state to reflect what we just printed.
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff * This is done last, only when we are sure we will return
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff * success, because this function may be called multiple
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff * times with increasing buffer sizes until it succeeds,
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff * and failed attempts must not update the state prematurely.
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff * Print the name, type, and class of an empty rdataset,
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff * such as those used to represent the question section
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff * of a DNS message.
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff unsigned int column;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff /* Owner name */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff result = dns_rdataclass_totext(rdataset->rdclass, target);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff result = dns_rdatatype_totext(rdataset->type, target);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Provide a backwards compatible interface for printing a
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * single rdataset or question section. This is now used
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff result = totext_ctx_init(&dns_masterfile_style_debug, &ctx);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff "could not set master file style");
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * The caller might want to give us an empty owner
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * name (e.g. if they are outputting into a master
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * file and this rdataset has the same name as the
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * previous one.)
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff return (question_totext(rdataset, owner_name, &ctx,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff return (rdataset_totext(rdataset, owner_name, &ctx,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * Print an rdataset. 'buffer' is a scratch buffer, which must have been
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * dynamically allocated by the caller. It must be large enough to
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff * hold the result from dns_ttl_totext(). If more than that is needed,
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff * the buffer will be grown automatically.
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graffdump_rdataset(isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *rdataset,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff /* Output a $TTL directive if needed. */
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if ((ctx->style.flags & DNS_STYLEFLAG_TTL) != 0) {
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if ((ctx->style.flags & DNS_STYLEFLAG_COMMENT) != 0)
288f9443ac447c9c14f3722dd6d32c1faef0f009Michael Graff fprintf(f, "$TTL %u\t; %.*s\n", rdataset->ttl,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * Generate the text representation of the rdataset into
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * the buffer. If the buffer is too small, grow it.
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff isc_mem_put(mctx, buffer->base, buffer->length);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff /* Write the buffer contents to the master file. */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff nwritten = fwrite(r.base, 1, (size_t) r.length, f);
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley "master file write failed: %s\n",
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * Dump all the rdatasets of a domain name to a master file.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffdump_rdatasets(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter,
78854e02c127f31ab90f56da0531542004b45377Michael Graff * XXX We only dump the rdataset if it isn't a
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff * negative caching entry. Maybe our dumping routines
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff * will learn how to usefully dump such an entry later
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff result = dump_rdataset(mctx, name, &rdataset, ctx,
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff if ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0)
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff * Initial size of text conversion buffer. The buffer is used
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff * for several purposes: converting origin names, rdatasets,
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff * $DATE timestamps, and comment strings for $TTL directives.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * When converting rdatasets, it is dynamically resized, but
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * when converting origins, timestamps, etc it is not. Therefore,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff * the initial size must large enough to hold the longest possible
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley * text representation of any domain name (for $ORIGIN).
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * Dump an entire database into a master file.
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffdns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db,
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff "could not set master file style");
f788a5704623c1d686b770a0f014fd52834d4a67Michael Graff bufmem = isc_mem_get(mctx, initial_buffer_length);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_buffer_init(&buffer, bufmem, initial_buffer_length,
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * If the database has cache semantics, output an RFC2540
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * $DATE directive so that the TTLs can be adjusted when
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * it is reloaded. For zones it is not really needed, and
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley * it would make the file incompatible with pre-RFC2540
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * software, so we omit it in the zone case.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff fprintf(f, "$DATE %.*s\n", (int) r.length, (char *) r.base);
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff ((ctx.style.flags & DNS_STYLEFLAG_REL_OWNER) != 0) ?
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff result = dns_dbiterator_current(dbiter, &node, name);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff if (result != DNS_R_SUCCESS && result != DNS_R_NEWORIGIN)
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff result = dns_dbiterator_origin(dbiter, origin);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley result = dns_name_totext(origin, ISC_FALSE, &buffer);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley (char *) r.base);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if ((ctx.style.flags & DNS_STYLEFLAG_REL_DATA) != 0)
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley result = dns_db_allrdatasets(db, node, version, now, &rdsiter);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley result = dump_rdatasets(mctx, name, rdsiter, &ctx,
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffdns_master_dump(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff const dns_master_style_t *style, const char *filename)
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff "could not open %s",
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff result = dns_master_dumptostream(mctx, db, version, style, f);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (fclose(f) != 0) {
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff "error closing %s",