masterdump.c revision 58aaab3687aac838542ee4ef65a9c094a5d34ab0
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff/*
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * Copyright (C) 1999 Internet Software Consortium.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff *
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 *
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
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff * SOFTWARE.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff */
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#include <config.h>
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#include <stddef.h>
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#include <stdlib.h>
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff#include <string.h>
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#include <time.h>
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley#include <errno.h>
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#include <isc/assertions.h>
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff#include <isc/error.h>
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff#include <isc/boolean.h>
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff#include <isc/region.h>
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff#include <dns/types.h>
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff#include <dns/result.h>
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff#include <dns/name.h>
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff#include <dns/fixedname.h>
058eeac2105c39e7cb31fb75ee0b473717ec3bbcMark Andrews#include <dns/rdata.h>
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff#include <dns/rdataclass.h>
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff#include <dns/rdatatype.h>
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graff#include <dns/rdataset.h>
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff#include <dns/rdatasetiter.h>
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff#include <dns/db.h>
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff#include <dns/dbiterator.h>
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff#include <dns/time.h>
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#include <dns/ttl.h>
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff#include <dns/masterdump.h>
3024dbecbac365171bc6de0f3fa04951d6558be3Michael Graff
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff#define RETERR(x) do { \
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff dns_result_t __r = (x); \
440be4c866f6935ac069db79a414304507a664c2Michael Graff if (__r != DNS_R_SUCCESS) \
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff return (__r); \
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley } while (0)
e45d323a2a0f4ca08d4b139546e60a5fa7bd3f0cMichael Graff
29f28fe573d4b3b318b3b026d567c1eb86738015Michael Graffstruct dns_master_style {
86944a4c8002e80ae9b6eb5a5e29b797879be45fMichael Graff unsigned int flags; /* DNS_STYLEFLAG_* */
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff unsigned int ttl_column;
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff unsigned int class_column;
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff unsigned int type_column;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff unsigned int rdata_column;
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graff unsigned int line_length;
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff unsigned int tab_width;
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff};
439c0011e642fb1d26011116144af698125262dbMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff/*
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff * Flags affecting master file formatting. Flags 0x0000FFFF
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff * define the formatting of the rdata part and are defined in
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff * rdata.h.
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff */
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff/* Omit the owner name when possible. */
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff#define DNS_STYLEFLAG_OMIT_OWNER 0x00010000U
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff
31fab17bcdbe302592a6c0dc5374ef56333ee879Michael Graff/*
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 *
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.
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff#define DNS_STYLEFLAG_OMIT_TTL 0x00020000U
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff/* Omit the class when possible. */
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff#define DNS_STYLEFLAG_OMIT_CLASS 0x00040000U
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff/* Output $TTL directives. */
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley#define DNS_STYLEFLAG_TTL 0x00080000U
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley/*
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * Output $ORIGIN directives and print owner names relative to
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley * the origin when possible.
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff#define DNS_STYLEFLAG_REL_OWNER 0x00100000U
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
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. */
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff#define DNS_STYLEFLAG_REL_DATA 0x00200000U
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff/*
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.
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff */
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff#define DNS_TOTEXT_LINEBREAK_MAXLEN 100
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff/*
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley * Context structure for a masterfile dump in progress.
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff */
66bd3b3c6b171271c705b897823dcdcf29464698Michael Grafftypedef struct dns_totext_ctx {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff dns_master_style_t style;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_boolean_t class_printed;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff char * linebreak;
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley char linebreak_buf[DNS_TOTEXT_LINEBREAK_MAXLEN];
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff dns_name_t * origin;
439c0011e642fb1d26011116144af698125262dbMichael Graff dns_fixedname_t origin_fixname;
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff isc_uint32_t current_ttl;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff isc_boolean_t current_ttl_valid;
11efdeb076d65fa9f0c5fc067dc040e7c99dfba6Michael Graff} dns_totext_ctx_t;
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff
84c46a7acb961cac19c0d857bfdd00f3383a9bc6Michael Graff/*
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff * The default master file style.
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley *
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff * Because the TTL is always omitted, and the class is almost always
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * omitted, neither is allocated any columns.
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff */
e51511aa3281f8dc384eb1283115c7f8d5c402aeMichael Graffconst dns_master_style_t
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graffdns_master_style_default = {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff DNS_STYLEFLAG_OMIT_OWNER |
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff DNS_STYLEFLAG_OMIT_CLASS |
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff DNS_STYLEFLAG_REL_OWNER |
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff DNS_STYLEFLAG_REL_DATA |
2992344aacdb08e4af936c176d49ef789f5673ddMichael Graff DNS_STYLEFLAG_OMIT_TTL |
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff DNS_STYLEFLAG_TTL |
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff DNS_STYLEFLAG_COMMENT |
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley DNS_STYLEFLAG_MULTILINE,
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff 24, 24, 24, 32, 80, 8
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff};
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff/*
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff * A style suitable for dns_rdataset_totext().
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley */
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halleydns_master_style_t
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graffdns_masterfile_style_debug = {
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff DNS_STYLEFLAG_REL_OWNER,
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff 24, 32, 40, 48, 80, 8
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff};
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graff#define N_SPACES 10
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graffchar spaces[N_SPACES+1] = " ";
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley#define N_TABS 10
213973a334f92d4aef4ef62b4538fc2e4d0e8082Michael Graffchar tabs[N_TABS+1] = "\t\t\t\t\t\t\t\t\t\t";
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley/*
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.
59c049874bbef182857c57bd9cca292898921c69Bob Halley */
59c049874bbef182857c57bd9cca292898921c69Bob Halleystatic dns_result_t
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graffindent(unsigned int *current, unsigned int to, int tabwidth,
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff isc_buffer_t *target)
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley{
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley isc_region_t r;
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley unsigned char *p;
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley unsigned int from;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff int ntabs, nspaces, t;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff from = *current;
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
1f90c108282533a23b8362c34bcde4267c1eb4b1Michael Graff if (to < from + 1)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff to = from + 1;
ebdd11e84734e28ddd64562e82a7c646a58a04f4Michael Graff
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley ntabs = to / tabwidth - from / tabwidth;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley if (ntabs < 0)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff ntabs = 0;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (ntabs > 0) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff isc_buffer_available(target, &r);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (r.length < (unsigned) ntabs)
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff return (DNS_R_NOSPACE);
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff p = r.base;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
28ab8277a068f273f0a805a83b4811446cb78a5bBob Halley t = ntabs;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff while (t) {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff int n = t;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff if (n > N_TABS)
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff n = N_TABS;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff memcpy(p, tabs, n);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff p += n;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff t -= n;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff }
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff isc_buffer_add(target, ntabs);
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff from = (to / tabwidth) * tabwidth;
bb143613cf26e0f27dfd9caf1a7336065d064b26Michael Graff }
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley nspaces = to - from;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff INSIST(nspaces >= 0);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley isc_buffer_available(target, &r);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if (r.length < (unsigned) nspaces)
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley return (DNS_R_NOSPACE);
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley p = r.base;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley t = nspaces;
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley while (t) {
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff int n = t;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff if (n > N_SPACES)
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff n = N_SPACES;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff memcpy(p, spaces, n);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff p += n;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff t -= n;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff }
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_buffer_add(target, nspaces);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff *current = to;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff return (DNS_R_SUCCESS);
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff}
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graffstatic dns_result_t
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Grafftotext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx)
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff{
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff dns_result_t result;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff ctx->style = *style;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff REQUIRE(style->tab_width != 0);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff dns_fixedname_init(&ctx->origin_fixname);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff /* Set up the line break string if needed. */
439c0011e642fb1d26011116144af698125262dbMichael Graff if ((ctx->style.flags & DNS_STYLEFLAG_MULTILINE) != 0) {
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff isc_buffer_t buf;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_region_t r;
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff unsigned int col = 0;
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_buffer_init(&buf, ctx->linebreak_buf,
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff sizeof(ctx->linebreak_buf),
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff ISC_BUFFERTYPE_TEXT);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff isc_buffer_available(&buf, &r);
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff if (r.length < 1)
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff return (DNS_R_TEXTTOOLONG);
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff r.base[0] = '\n';
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_buffer_add(&buf, 1);
439c0011e642fb1d26011116144af698125262dbMichael Graff
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff result = indent(&col, ctx->style.rdata_column,
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff ctx->style.tab_width, &buf);
f181f94ec8da8b1dbcc6353e8be965ea4a5ea282Michael Graff /*
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.
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff */
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff if (result == DNS_R_NOSPACE)
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff return (DNS_R_TEXTTOOLONG);
66bd3b3c6b171271c705b897823dcdcf29464698Michael Graff if (result != DNS_R_SUCCESS)
11fcc67616fac1bc6a28b3d4fed24641137888e7Michael Graff return (result);
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff
ad3a5c4b7e21af04d1b872f933c2e19e5c0a135bMichael Graff isc_buffer_available(&buf, &r);
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff if (r.length < 1)
439c0011e642fb1d26011116144af698125262dbMichael Graff return (DNS_R_TEXTTOOLONG);
439c0011e642fb1d26011116144af698125262dbMichael Graff r.base[0] = '\0';
439c0011e642fb1d26011116144af698125262dbMichael Graff isc_buffer_add(&buf, 1);
439c0011e642fb1d26011116144af698125262dbMichael Graff ctx->linebreak = ctx->linebreak_buf;
f36a81c88493985ee2d1c53cc6fe88f4b00dbbc8Michael Graff } else {
439c0011e642fb1d26011116144af698125262dbMichael Graff ctx->linebreak = NULL;
439c0011e642fb1d26011116144af698125262dbMichael Graff }
439c0011e642fb1d26011116144af698125262dbMichael Graff
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff ctx->class_printed = ISC_FALSE;
c803787146cadcb2d7e10cbf4491f3be513dfa1aMichael Graff ctx->origin = NULL;
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff return (DNS_R_SUCCESS);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff}
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff#define INDENT_TO(col) \
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff do { \
fe14eafefa91fada7cea0a55b09196c01477406cBob Halley if ((result = indent(&column, ctx->style.col, \
439c0011e642fb1d26011116144af698125262dbMichael Graff ctx->style.tab_width, target)) \
439c0011e642fb1d26011116144af698125262dbMichael Graff != DNS_R_SUCCESS) \
439c0011e642fb1d26011116144af698125262dbMichael Graff return (result); \
439c0011e642fb1d26011116144af698125262dbMichael Graff } while (0)
1c3bc66ada38236cc81c41b7174a9f0a872c9ab6Michael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graff/*
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
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff * one label.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff */
439c0011e642fb1d26011116144af698125262dbMichael Graff
439c0011e642fb1d26011116144af698125262dbMichael Graffstatic dns_result_t
439c0011e642fb1d26011116144af698125262dbMichael Graffrdataset_totext(dns_rdataset_t *rdataset,
439c0011e642fb1d26011116144af698125262dbMichael Graff dns_name_t *owner_name,
d8590892d10fc9528b0dde7e2781935e7b8d7a87Michael Graff dns_totext_ctx_t *ctx,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff isc_boolean_t omit_final_dot,
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_buffer_t *target)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff{
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff dns_result_t result;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff unsigned int column;
4abed3e3563c7ad346178433130e6d150d3ffeafBob Halley isc_boolean_t first = ISC_TRUE;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff isc_uint32_t current_ttl;
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff isc_boolean_t current_ttl_valid;
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley REQUIRE(DNS_RDATASET_VALID(rdataset));
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley result = dns_rdataset_first(rdataset);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff REQUIRE(result == DNS_R_SUCCESS);
3ac63b472022ff92691d1fe69ac715a729671965Michael Graff
651228967966ba4fb2e52f92d1207c790af4b130Michael Graff current_ttl = ctx->current_ttl;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff current_ttl_valid = ctx->current_ttl_valid;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff do {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff column = 0;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley /* Owner name. */
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff if (owner_name != NULL &&
e883738546c7c73b761bce8a15e08661863d3ae1Michael Graff ! ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0 &&
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff !first))
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff {
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff unsigned int name_start = target->used;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff RETERR(dns_name_totext(owner_name,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff omit_final_dot,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff target));
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff column += target->used - name_start;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff }
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
897c9ddb4d745b2bfecf98b17e5487bb6656299aMichael Graff /* TTL. */
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (! ((ctx->style.flags & DNS_STYLEFLAG_OMIT_TTL) != 0 &&
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff current_ttl_valid &&
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff rdataset->ttl == current_ttl))
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff {
14b98cb34eda66c87ce41a207704a2c232280eafMichael Graff char ttlbuf[64];
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff isc_region_t r;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff unsigned int length;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff INDENT_TO(ttl_column);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff length = sprintf(ttlbuf, "%u", rdataset->ttl);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff INSIST(length <= sizeof ttlbuf);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff isc_buffer_available(target, &r);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff if (r.length < length)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff return (DNS_R_NOSPACE);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff memcpy(r.base, ttlbuf, length);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff isc_buffer_add(target, length);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff column += length;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff /*
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 */
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff if ((ctx->style.flags & DNS_STYLEFLAG_TTL) == 0) {
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff current_ttl = rdataset->ttl;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff current_ttl_valid = ISC_TRUE;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff }
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff }
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff /* Class. */
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff if ((ctx->style.flags & DNS_STYLEFLAG_OMIT_CLASS) == 0 ||
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff ctx->class_printed == ISC_FALSE)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff {
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff unsigned int class_start;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff INDENT_TO(class_column);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff class_start = target->used;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff result = dns_rdataclass_totext(rdataset->rdclass,
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff target);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff if (result != DNS_R_SUCCESS)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff return (result);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff column += (target->used - class_start);
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley }
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley /* Type. */
24a2d84aedbad12fba2ca319c98745e62ef0bc16Bob Halley {
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff unsigned int type_start;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff INDENT_TO(type_column);
4a3ad0da975d7115d401700f955814a0dff1adb0Bob Halley type_start = target->used;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff result = dns_rdatatype_totext(rdataset->type, target);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff if (result != DNS_R_SUCCESS)
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff return (result);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff column += (target->used - type_start);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff }
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff /* Rdata. */
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff {
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff dns_rdata_t rdata;
78854e02c127f31ab90f56da0531542004b45377Michael Graff isc_region_t r;
78854e02c127f31ab90f56da0531542004b45377Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff INDENT_TO(rdata_column);
78854e02c127f31ab90f56da0531542004b45377Michael Graff dns_rdataset_current(rdataset, &rdata);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
78854e02c127f31ab90f56da0531542004b45377Michael Graff RETERR(dns_rdata_tofmttext(&rdata,
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff ctx->origin,
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff ctx->style.flags,
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley ctx->style.line_length -
daf83a29374c487a2800333d371e98e77e5a0d64Bob Halley ctx->style.rdata_column,
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff ctx->linebreak,
294802790e8030f1c19b6c2c5d5204b6f464c729Michael Graff target));
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff isc_buffer_available(target, &r);
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff if (r.length < 1)
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff return (DNS_R_NOSPACE);
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff r.base[0] = '\n';
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff isc_buffer_add(target, 1);
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff }
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff first = ISC_FALSE;
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff result = dns_rdataset_next(rdataset);
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff } while (result == DNS_R_SUCCESS);
21e7034ec046105c00a0dab86c83732e2e77ad99Michael Graff
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff if (result != DNS_R_NOMORE)
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff return (result);
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff /*
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 */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff ctx->class_printed = ISC_TRUE;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff ctx->current_ttl= current_ttl;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff ctx->current_ttl_valid = current_ttl_valid;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff return (DNS_R_SUCCESS);
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff}
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff/*
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.
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic dns_result_t
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffquestion_totext(dns_rdataset_t *rdataset,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_name_t *owner_name,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_totext_ctx_t *ctx,
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff isc_boolean_t omit_final_dot,
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff isc_buffer_t *target)
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff{
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff unsigned int column;
f6f4ceece41f040cc43722afa9a5cd1f54a576b6Michael Graff dns_result_t result;
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff isc_region_t r;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff REQUIRE(DNS_RDATASET_VALID(rdataset));
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff result = dns_rdataset_first(rdataset);
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff REQUIRE(result == DNS_R_NOMORE);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff column = 0;
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff /* Owner name */
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff {
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff unsigned int name_start = target->used;
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff RETERR(dns_name_totext(owner_name,
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff omit_final_dot,
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff target));
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff column += target->used - name_start;
01883602b1e9c0a91f1c3526d80d8ef9db747e92Mark Andrews }
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff /* Class */
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff {
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff unsigned int class_start;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff INDENT_TO(class_column);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff class_start = target->used;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff result = dns_rdataclass_totext(rdataset->rdclass, target);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff if (result != DNS_R_SUCCESS)
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff return (result);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff column += (target->used - class_start);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff }
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff /* Type */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff {
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff unsigned int type_start;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff INDENT_TO(type_column);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff type_start = target->used;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff result = dns_rdatatype_totext(rdataset->type, target);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (result != DNS_R_SUCCESS)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff return (result);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff column += (target->used - type_start);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff }
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff isc_buffer_available(target, &r);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff if (r.length < 1)
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff return (DNS_R_NOSPACE);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff r.base[0] = '\n';
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff isc_buffer_add(target, 1);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff return (DNS_R_SUCCESS);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff}
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff/*
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley * Provide a backwards compatible interface for printing a
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * single rdataset or question section. This is now used
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff * only by wire_test.c.
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff */
528829aa8ad69238e674cd81078bc14d4199691bMichael Graffdns_result_t
528829aa8ad69238e674cd81078bc14d4199691bMichael Graffdns_rdataset_totext(dns_rdataset_t *rdataset,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dns_name_t *owner_name,
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff isc_boolean_t omit_final_dot,
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff isc_boolean_t no_rdata_or_ttl,
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff isc_buffer_t *target)
d1fb73ada84ee15ea078c80b1cd0ca8ddc6aa856Michael Graff{
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dns_totext_ctx_t ctx;
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff dns_result_t result;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff result = totext_ctx_init(&dns_masterfile_style_debug, &ctx);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff if (result != DNS_R_SUCCESS) {
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff UNEXPECTED_ERROR(__FILE__, __LINE__,
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff "could not set master file style");
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff return (DNS_R_UNEXPECTED);
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff }
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graff /*
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.)
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley */
d947011dc393d9f9988d1349d585b246d19cc3c7Michael Graff if (dns_name_countlabels(owner_name) == 0)
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff owner_name = NULL;
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff if (no_rdata_or_ttl)
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff return (question_totext(rdataset, owner_name, &ctx,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff omit_final_dot, target));
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff else
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff return (rdataset_totext(rdataset, owner_name, &ctx,
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff omit_final_dot, target));
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff}
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff/*
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 Graff */
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff
528829aa8ad69238e674cd81078bc14d4199691bMichael Graffstatic dns_result_t
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graffdump_rdataset(isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *rdataset,
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff dns_totext_ctx_t *ctx,
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff isc_buffer_t *buffer, FILE *f)
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff{
2bcb48cfcae36398454c98e40c563e2cde748e07Michael Graff isc_region_t r;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff dns_result_t result;
59c049874bbef182857c57bd9cca292898921c69Bob Halley size_t nwritten;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff REQUIRE(buffer->length > 0);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff /* Output a $TTL directive if needed. */
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if ((ctx->style.flags & DNS_STYLEFLAG_TTL) != 0) {
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (ctx->current_ttl_valid == ISC_FALSE ||
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff ctx->current_ttl != rdataset->ttl)
59c049874bbef182857c57bd9cca292898921c69Bob Halley {
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if ((ctx->style.flags & DNS_STYLEFLAG_COMMENT) != 0)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff {
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff isc_buffer_clear(buffer);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff result = dns_ttl_totext(rdataset->ttl,
1ac7292ced16b8469bebf04356d50279eae78d97Bob Halley ISC_TRUE, buffer);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff INSIST(result == DNS_R_SUCCESS);
78854e02c127f31ab90f56da0531542004b45377Michael Graff isc_buffer_used(buffer, &r);
288f9443ac447c9c14f3722dd6d32c1faef0f009Michael Graff fprintf(f, "$TTL %u\t; %.*s\n", rdataset->ttl,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff (int) r.length, (char *) r.base);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff } else {
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff fprintf(f, "$TTL %u\n", rdataset->ttl);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff }
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff ctx->current_ttl = rdataset->ttl;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff ctx->current_ttl_valid = ISC_TRUE;
59c049874bbef182857c57bd9cca292898921c69Bob Halley }
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff }
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff isc_buffer_clear(buffer);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff /*
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * Generate the text representation of the rdataset into
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff * the buffer. If the buffer is too small, grow it.
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff */
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff for (;;) {
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff int newlength;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff void *newmem;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff result = rdataset_totext(rdataset, name, ctx,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff ISC_FALSE, buffer);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (result != DNS_R_NOSPACE)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff break;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff isc_mem_put(mctx, buffer->base, buffer->length);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff newlength = buffer->length * 2;
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff newmem = isc_mem_get(mctx, newlength);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (newmem == NULL)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff return (DNS_R_NOMEMORY);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff isc_buffer_init(buffer, newmem, newlength,
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff ISC_BUFFERTYPE_TEXT);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff }
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (result != DNS_R_SUCCESS)
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff return (result);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff /* Write the buffer contents to the master file. */
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff isc_buffer_used(buffer, &r);
3115cd89bc1e1fd3ecc4705d253e3484a3f5c555Michael Graff nwritten = fwrite(r.base, 1, (size_t) r.length, f);
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley if (nwritten != (size_t) r.length) {
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley UNEXPECTED_ERROR(__FILE__, __LINE__,
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley "master file write failed: %s\n",
8cdfd17426179ae6f629a9b7475d46a22f535047Bob Halley strerror(errno));
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff return (DNS_R_UNEXPECTED);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff }
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff return (DNS_R_SUCCESS);
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff}
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff/*
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff * Dump all the rdatasets of a domain name to a master file.
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff */
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffstatic dns_result_t
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffdump_rdatasets(isc_mem_t *mctx, dns_name_t *name, dns_rdatasetiter_t *rdsiter,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_totext_ctx_t *ctx,
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_buffer_t *buffer, FILE *f)
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff{
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_result_t result;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff dns_rdataset_t rdataset;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff dns_rdataset_init(&rdataset);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff result = dns_rdatasetiter_first(rdsiter);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff while (result == DNS_R_SUCCESS) {
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_rdatasetiter_current(rdsiter, &rdataset);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff if (rdataset.type != 0) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff /*
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 * on.
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff */
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff result = dump_rdataset(mctx, name, &rdataset, ctx,
517274e709a3c730cd42f37dc1260dde95d1ea38Michael Graff buffer, f);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff } else
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff result = DNS_R_SUCCESS;
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff dns_rdataset_disassociate(&rdataset);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff if (result != DNS_R_SUCCESS)
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff return (result);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff result = dns_rdatasetiter_next(rdsiter);
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff if ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0)
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff name = NULL;
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff }
4281fe4a80af7402613f0d5c3eeff8829a4ede1fMichael Graff if (result != DNS_R_NOMORE)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff return (result);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff return (DNS_R_SUCCESS);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley}
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff
7ec42e4be45c0486ce80461293f377fb4b904dc0Michael Graff/*
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 *
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).
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff */
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graffconst int initial_buffer_length = 1200;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff/*
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff * Dump an entire database into a master file.
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff */
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffstatic dns_result_t
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graffdns_master_dumptostream(isc_mem_t *mctx, dns_db_t *db,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_dbversion_t *version,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff const dns_master_style_t *style,
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff FILE *f)
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff{
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_fixedname_t fixname;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_name_t *name;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_dbiterator_t *dbiter = NULL;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_result_t result;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff isc_buffer_t buffer;
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff char *bufmem;
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff isc_stdtime_t now;
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff isc_region_t r;
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff dns_totext_ctx_t ctx;
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff
f788a5704623c1d686b770a0f014fd52834d4a67Michael Graff result = totext_ctx_init(style, &ctx);
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff if (result != DNS_R_SUCCESS) {
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff UNEXPECTED_ERROR(__FILE__, __LINE__,
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff "could not set master file style");
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff return (DNS_R_UNEXPECTED);
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff }
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff dns_fixedname_init(&fixname);
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff name = dns_fixedname_name(&fixname);
65f6d2e1c1fce0989c13c2efb44b8dd26cd977f3Michael Graff
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff isc_stdtime_get(&now);
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff
f788a5704623c1d686b770a0f014fd52834d4a67Michael Graff bufmem = isc_mem_get(mctx, initial_buffer_length);
93d3a6fd20aceb9998eca4723bba8810243e7689Michael Graff if (bufmem == NULL)
3d12fa7e76c02d06e1adeaa7846b60378a3cd204Michael Graff return (DNS_R_NOMEMORY);
59e22acc4f79ff481f7bfa46ef0558957ae53cfcMichael Graff
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley isc_buffer_init(&buffer, bufmem, initial_buffer_length,
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley ISC_BUFFERTYPE_TEXT);
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley
16508d9185e5eb96af2ebe900a08c46a6e5eb7edBob Halley /*
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.
ff9bb3fc5453bbf310b67c560fbf04a5c0fb60daMichael Graff */
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff if (dns_db_iscache(db)) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff result = dns_time32_totext(now, &buffer);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff RUNTIME_CHECK(result == DNS_R_SUCCESS);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_buffer_used(&buffer, &r);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff fprintf(f, "$DATE %.*s\n", (int) r.length, (char *) r.base);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff }
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff result = dns_db_createiterator(db,
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff ((ctx.style.flags & DNS_STYLEFLAG_REL_OWNER) != 0) ?
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff ISC_TRUE : ISC_FALSE,
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff &dbiter);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff if (result != DNS_R_SUCCESS)
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff goto create_iter_failure;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff result = dns_dbiterator_first(dbiter);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff while (result == DNS_R_SUCCESS) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff dns_rdatasetiter_t *rdsiter = NULL;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff dns_dbnode_t *node = NULL;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff result = dns_dbiterator_current(dbiter, &node, name);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff if (result != DNS_R_SUCCESS && result != DNS_R_NEWORIGIN)
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff break;
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff if (result == DNS_R_NEWORIGIN) {
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff dns_name_t *origin =
d43c2cc7bc4022701f141e299ea8f3fb1d0640c2Michael Graff dns_fixedname_name(&ctx.origin_fixname);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff result = dns_dbiterator_origin(dbiter, origin);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff RUNTIME_CHECK(result == DNS_R_SUCCESS);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_buffer_clear(&buffer);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley result = dns_name_totext(origin, ISC_FALSE, &buffer);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley RUNTIME_CHECK(result == DNS_R_SUCCESS);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff isc_buffer_used(&buffer, &r);
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff fprintf(f, "$ORIGIN %.*s\n", (int) r.length,
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley (char *) r.base);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if ((ctx.style.flags & DNS_STYLEFLAG_REL_DATA) != 0)
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley ctx.origin = origin;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley }
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley result = dns_db_allrdatasets(db, node, version, now, &rdsiter);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (result != DNS_R_SUCCESS) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dns_db_detachnode(db, &node);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley goto iter_failure;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley }
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley result = dump_rdatasets(mctx, name, rdsiter, &ctx,
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley &buffer, f);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (result != DNS_R_SUCCESS) {
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dns_db_detachnode(db, &node);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley goto iter_failure;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley }
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dns_rdatasetiter_destroy(&rdsiter);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dns_db_detachnode(db, &node);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley result = dns_dbiterator_next(dbiter);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley }
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley if (result != DNS_R_NOMORE)
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley goto iter_failure;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley result = DNS_R_SUCCESS;
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley iter_failure:
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley dns_dbiterator_destroy(&dbiter);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley create_iter_failure:
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley isc_mem_put(mctx, buffer.base, buffer.length);
a44c12b332b867f29631e235eb11d1263c73d6c0Bob Halley return (result);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff}
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graffdns_result_t
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{
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff FILE *f;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff dns_result_t result;
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff f = fopen(filename, "w");
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff if (f == NULL) {
a385f150bb21b8b81f70ed7df545357a83f1da82Michael Graff UNEXPECTED_ERROR(__FILE__, __LINE__,
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff "could not open %s",
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff filename);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff return (DNS_R_UNEXPECTED);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff }
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff result = dns_master_dumptostream(mctx, db, version, style, f);
a253e35c2451818fb39f9b808c7641adb5275fb3Michael Graff
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff if (fclose(f) != 0) {
6dde125c2f47617ceef1518cf9e5588e8f366b71Michael Graff UNEXPECTED_ERROR(__FILE__, __LINE__,
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff "error closing %s",
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff filename);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff return (DNS_R_UNEXPECTED);
30251e07d1705d1a85b0e1d5a969496e1aed612eMichael Graff }
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley return (result);
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley}
45dadd25ba4b72ec2d8eecc342edc787d8421e3aBob Halley