15185a700Sflorian /*
25185a700Sflorian * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
35185a700Sflorian *
45185a700Sflorian * Permission to use, copy, modify, and/or distribute this software for any
55185a700Sflorian * purpose with or without fee is hereby granted, provided that the above
65185a700Sflorian * copyright notice and this permission notice appear in all copies.
75185a700Sflorian *
85185a700Sflorian * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
95185a700Sflorian * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
105185a700Sflorian * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
115185a700Sflorian * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
125185a700Sflorian * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
135185a700Sflorian * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
145185a700Sflorian * PERFORMANCE OF THIS SOFTWARE.
155185a700Sflorian */
165185a700Sflorian
175185a700Sflorian /*! \file */
185185a700Sflorian
195185a700Sflorian #include <limits.h>
205185a700Sflorian #include <stdlib.h>
215185a700Sflorian #include <string.h>
225185a700Sflorian
235185a700Sflorian #include <isc/types.h>
245185a700Sflorian #include <isc/util.h>
255185a700Sflorian
265185a700Sflorian #include <dns/fixedname.h>
275185a700Sflorian #include <dns/masterdump.h>
285185a700Sflorian #include <dns/rdata.h>
295185a700Sflorian #include <dns/rdataclass.h>
305185a700Sflorian #include <dns/rdataset.h>
315185a700Sflorian #include <dns/rdatatype.h>
325185a700Sflorian #include <dns/result.h>
335185a700Sflorian
345185a700Sflorian #define RETERR(x) do { \
355185a700Sflorian isc_result_t _r = (x); \
365185a700Sflorian if (_r != ISC_R_SUCCESS) \
375185a700Sflorian return (_r); \
385185a700Sflorian } while (0)
395185a700Sflorian
405185a700Sflorian struct dns_master_style {
415185a700Sflorian dns_masterstyle_flags_t flags; /* DNS_STYLEFLAG_* */
425185a700Sflorian unsigned int ttl_column;
435185a700Sflorian unsigned int class_column;
445185a700Sflorian unsigned int type_column;
455185a700Sflorian unsigned int rdata_column;
465185a700Sflorian unsigned int line_length;
475185a700Sflorian unsigned int tab_width;
485185a700Sflorian unsigned int split_width;
495185a700Sflorian };
505185a700Sflorian
515185a700Sflorian /*%
525185a700Sflorian * The maximum length of the newline+indentation that is output
535185a700Sflorian * when inserting a line break in an RR. This effectively puts an
545185a700Sflorian * upper limits on the value of "rdata_column", because if it is
555185a700Sflorian * very large, the tabs and spaces needed to reach it will not fit.
565185a700Sflorian */
575185a700Sflorian #define DNS_TOTEXT_LINEBREAK_MAXLEN 100
585185a700Sflorian
595185a700Sflorian /*%
605185a700Sflorian * Context structure for a masterfile dump in progress.
615185a700Sflorian */
625185a700Sflorian typedef struct dns_totext_ctx {
635185a700Sflorian dns_master_style_t style;
64*1fb015a8Sflorian int class_printed;
655185a700Sflorian char * linebreak;
665185a700Sflorian char linebreak_buf[DNS_TOTEXT_LINEBREAK_MAXLEN];
675185a700Sflorian dns_name_t * origin;
685185a700Sflorian dns_name_t * neworigin;
695185a700Sflorian dns_fixedname_t origin_fixname;
705185a700Sflorian uint32_t current_ttl;
71*1fb015a8Sflorian int current_ttl_valid;
725185a700Sflorian } dns_totext_ctx_t;
735185a700Sflorian
745185a700Sflorian /*%
755185a700Sflorian * A style suitable for dns_rdataset_totext().
765185a700Sflorian */
775185a700Sflorian const dns_master_style_t
785185a700Sflorian dns_master_style_debug = {
795185a700Sflorian DNS_STYLEFLAG_REL_OWNER,
805185a700Sflorian 24, 32, 40, 48, 80, 8, UINT_MAX
815185a700Sflorian };
825185a700Sflorian
835185a700Sflorian #define N_SPACES 10
845185a700Sflorian static char spaces[N_SPACES+1] = " ";
855185a700Sflorian
865185a700Sflorian #define N_TABS 10
875185a700Sflorian static char tabs[N_TABS+1] = "\t\t\t\t\t\t\t\t\t\t";
885185a700Sflorian
895185a700Sflorian /*%
905185a700Sflorian * Output tabs and spaces to go from column '*current' to
915185a700Sflorian * column 'to', and update '*current' to reflect the new
925185a700Sflorian * current column.
935185a700Sflorian */
945185a700Sflorian static isc_result_t
indent(unsigned int * current,unsigned int to,int tabwidth,isc_buffer_t * target)955185a700Sflorian indent(unsigned int *current, unsigned int to, int tabwidth,
965185a700Sflorian isc_buffer_t *target)
975185a700Sflorian {
985185a700Sflorian isc_region_t r;
995185a700Sflorian unsigned char *p;
1005185a700Sflorian unsigned int from;
1015185a700Sflorian int ntabs, nspaces, t;
1025185a700Sflorian
1035185a700Sflorian from = *current;
1045185a700Sflorian
1055185a700Sflorian if (to < from + 1)
1065185a700Sflorian to = from + 1;
1075185a700Sflorian
1085185a700Sflorian ntabs = to / tabwidth - from / tabwidth;
1095185a700Sflorian if (ntabs < 0)
1105185a700Sflorian ntabs = 0;
1115185a700Sflorian
1125185a700Sflorian if (ntabs > 0) {
1135185a700Sflorian isc_buffer_availableregion(target, &r);
1145185a700Sflorian if (r.length < (unsigned) ntabs)
1155185a700Sflorian return (ISC_R_NOSPACE);
1165185a700Sflorian p = r.base;
1175185a700Sflorian
1185185a700Sflorian t = ntabs;
1195185a700Sflorian while (t) {
1205185a700Sflorian int n = t;
1215185a700Sflorian if (n > N_TABS)
1225185a700Sflorian n = N_TABS;
1235185a700Sflorian memmove(p, tabs, n);
1245185a700Sflorian p += n;
1255185a700Sflorian t -= n;
1265185a700Sflorian }
1275185a700Sflorian isc_buffer_add(target, ntabs);
1285185a700Sflorian from = (to / tabwidth) * tabwidth;
1295185a700Sflorian }
1305185a700Sflorian
1315185a700Sflorian nspaces = to - from;
1325185a700Sflorian INSIST(nspaces >= 0);
1335185a700Sflorian
1345185a700Sflorian isc_buffer_availableregion(target, &r);
1355185a700Sflorian if (r.length < (unsigned) nspaces)
1365185a700Sflorian return (ISC_R_NOSPACE);
1375185a700Sflorian p = r.base;
1385185a700Sflorian
1395185a700Sflorian t = nspaces;
1405185a700Sflorian while (t) {
1415185a700Sflorian int n = t;
1425185a700Sflorian if (n > N_SPACES)
1435185a700Sflorian n = N_SPACES;
1445185a700Sflorian memmove(p, spaces, n);
1455185a700Sflorian p += n;
1465185a700Sflorian t -= n;
1475185a700Sflorian }
1485185a700Sflorian isc_buffer_add(target, nspaces);
1495185a700Sflorian
1505185a700Sflorian *current = to;
1515185a700Sflorian return (ISC_R_SUCCESS);
1525185a700Sflorian }
1535185a700Sflorian
1545185a700Sflorian static isc_result_t
totext_ctx_init(const dns_master_style_t * style,dns_totext_ctx_t * ctx)1555185a700Sflorian totext_ctx_init(const dns_master_style_t *style, dns_totext_ctx_t *ctx) {
1565185a700Sflorian isc_result_t result;
1575185a700Sflorian
1585185a700Sflorian REQUIRE(style->tab_width != 0);
1595185a700Sflorian
1605185a700Sflorian ctx->style = *style;
161*1fb015a8Sflorian ctx->class_printed = 0;
1625185a700Sflorian
1635185a700Sflorian dns_fixedname_init(&ctx->origin_fixname);
1645185a700Sflorian
1655185a700Sflorian /*
1665185a700Sflorian * Set up the line break string if needed.
1675185a700Sflorian */
1685185a700Sflorian if ((ctx->style.flags & DNS_STYLEFLAG_MULTILINE) != 0) {
1695185a700Sflorian isc_buffer_t buf;
1705185a700Sflorian isc_region_t r;
1715185a700Sflorian unsigned int col = 0;
1725185a700Sflorian
1735185a700Sflorian isc_buffer_init(&buf, ctx->linebreak_buf,
1745185a700Sflorian sizeof(ctx->linebreak_buf));
1755185a700Sflorian
1765185a700Sflorian isc_buffer_availableregion(&buf, &r);
1775185a700Sflorian if (r.length < 1)
1785185a700Sflorian return (DNS_R_TEXTTOOLONG);
1795185a700Sflorian r.base[0] = '\n';
1805185a700Sflorian isc_buffer_add(&buf, 1);
1815185a700Sflorian
1825185a700Sflorian if ((ctx->style.flags & DNS_STYLEFLAG_COMMENTDATA) != 0) {
1835185a700Sflorian isc_buffer_availableregion(&buf, &r);
1845185a700Sflorian if (r.length < 1)
1855185a700Sflorian return (DNS_R_TEXTTOOLONG);
1865185a700Sflorian r.base[0] = ';';
1875185a700Sflorian isc_buffer_add(&buf, 1);
1885185a700Sflorian }
1895185a700Sflorian
1905185a700Sflorian result = indent(&col, ctx->style.rdata_column,
1915185a700Sflorian ctx->style.tab_width, &buf);
1925185a700Sflorian /*
1935185a700Sflorian * Do not return ISC_R_NOSPACE if the line break string
1945185a700Sflorian * buffer is too small, because that would just make
1955185a700Sflorian * dump_rdataset() retry indefinitely with ever
1965185a700Sflorian * bigger target buffers. That's a different buffer,
1975185a700Sflorian * so it won't help. Use DNS_R_TEXTTOOLONG as a substitute.
1985185a700Sflorian */
1995185a700Sflorian if (result == ISC_R_NOSPACE)
2005185a700Sflorian return (DNS_R_TEXTTOOLONG);
2015185a700Sflorian if (result != ISC_R_SUCCESS)
2025185a700Sflorian return (result);
2035185a700Sflorian
2045185a700Sflorian isc_buffer_availableregion(&buf, &r);
2055185a700Sflorian if (r.length < 1)
2065185a700Sflorian return (DNS_R_TEXTTOOLONG);
2075185a700Sflorian r.base[0] = '\0';
2085185a700Sflorian isc_buffer_add(&buf, 1);
2095185a700Sflorian ctx->linebreak = ctx->linebreak_buf;
2105185a700Sflorian } else {
2115185a700Sflorian ctx->linebreak = NULL;
2125185a700Sflorian }
2135185a700Sflorian
2145185a700Sflorian ctx->origin = NULL;
2155185a700Sflorian ctx->neworigin = NULL;
2165185a700Sflorian ctx->current_ttl = 0;
217*1fb015a8Sflorian ctx->current_ttl_valid = 0;
2185185a700Sflorian
2195185a700Sflorian return (ISC_R_SUCCESS);
2205185a700Sflorian }
2215185a700Sflorian
2225185a700Sflorian #define INDENT_TO(col) \
2235185a700Sflorian do { \
2245185a700Sflorian if ((result = indent(&column, ctx->style.col, \
2255185a700Sflorian ctx->style.tab_width, target)) \
2265185a700Sflorian != ISC_R_SUCCESS) \
2275185a700Sflorian return (result); \
2285185a700Sflorian } while (0)
2295185a700Sflorian
2305185a700Sflorian /*
2315185a700Sflorian * Convert 'rdataset' to master file text format according to 'ctx',
2325185a700Sflorian * storing the result in 'target'. If 'owner_name' is NULL, it
2335185a700Sflorian * is omitted; otherwise 'owner_name' must be valid and have at least
2345185a700Sflorian * one label.
2355185a700Sflorian */
2365185a700Sflorian
2375185a700Sflorian static isc_result_t
rdataset_totext(dns_rdataset_t * rdataset,dns_name_t * owner_name,dns_totext_ctx_t * ctx,int omit_final_dot,isc_buffer_t * target)2385185a700Sflorian rdataset_totext(dns_rdataset_t *rdataset,
2395185a700Sflorian dns_name_t *owner_name,
2405185a700Sflorian dns_totext_ctx_t *ctx,
241*1fb015a8Sflorian int omit_final_dot,
2425185a700Sflorian isc_buffer_t *target)
2435185a700Sflorian {
2445185a700Sflorian isc_result_t result;
2455185a700Sflorian unsigned int column;
246*1fb015a8Sflorian int first = 1;
2475185a700Sflorian uint32_t current_ttl;
248*1fb015a8Sflorian int current_ttl_valid;
2495185a700Sflorian dns_rdatatype_t type;
2505185a700Sflorian unsigned int type_start;
2515185a700Sflorian
2525185a700Sflorian result = dns_rdataset_first(rdataset);
2535185a700Sflorian
2545185a700Sflorian current_ttl = ctx->current_ttl;
2555185a700Sflorian current_ttl_valid = ctx->current_ttl_valid;
2565185a700Sflorian
2575185a700Sflorian while (result == ISC_R_SUCCESS) {
2585185a700Sflorian column = 0;
2595185a700Sflorian
2605185a700Sflorian /*
2615185a700Sflorian * Comment?
2625185a700Sflorian */
2635185a700Sflorian if ((ctx->style.flags & DNS_STYLEFLAG_COMMENTDATA) != 0)
264873f12b9Sflorian RETERR(isc_str_tobuffer(";", target));
2655185a700Sflorian
2665185a700Sflorian /*
2675185a700Sflorian * Owner name.
2685185a700Sflorian */
2695185a700Sflorian if (owner_name != NULL &&
2705185a700Sflorian ! ((ctx->style.flags & DNS_STYLEFLAG_OMIT_OWNER) != 0 &&
2715185a700Sflorian !first))
2725185a700Sflorian {
2735185a700Sflorian unsigned int name_start = target->used;
2745185a700Sflorian RETERR(dns_name_totext(owner_name,
2755185a700Sflorian omit_final_dot,
2765185a700Sflorian target));
2775185a700Sflorian column += target->used - name_start;
2785185a700Sflorian }
2795185a700Sflorian
2805185a700Sflorian /*
2815185a700Sflorian * TTL.
2825185a700Sflorian */
2835185a700Sflorian if ((ctx->style.flags & DNS_STYLEFLAG_NO_TTL) == 0 &&
2845185a700Sflorian !((ctx->style.flags & DNS_STYLEFLAG_OMIT_TTL) != 0 &&
2855185a700Sflorian current_ttl_valid &&
2865185a700Sflorian rdataset->ttl == current_ttl))
2875185a700Sflorian {
2885185a700Sflorian char ttlbuf[64];
2895185a700Sflorian isc_region_t r;
2905185a700Sflorian unsigned int length;
2915185a700Sflorian
2925185a700Sflorian INDENT_TO(ttl_column);
2935185a700Sflorian length = snprintf(ttlbuf, sizeof(ttlbuf), "%u",
2945185a700Sflorian rdataset->ttl);
2955185a700Sflorian INSIST(length <= sizeof(ttlbuf));
2965185a700Sflorian isc_buffer_availableregion(target, &r);
2975185a700Sflorian if (r.length < length)
2985185a700Sflorian return (ISC_R_NOSPACE);
2995185a700Sflorian memmove(r.base, ttlbuf, length);
3005185a700Sflorian isc_buffer_add(target, length);
3015185a700Sflorian column += length;
3025185a700Sflorian
3035185a700Sflorian /*
3045185a700Sflorian * If the $TTL directive is not in use, the TTL we
3055185a700Sflorian * just printed becomes the default for subsequent RRs.
3065185a700Sflorian */
3075185a700Sflorian if ((ctx->style.flags & DNS_STYLEFLAG_TTL) == 0) {
3085185a700Sflorian current_ttl = rdataset->ttl;
309*1fb015a8Sflorian current_ttl_valid = 1;
3105185a700Sflorian }
3115185a700Sflorian }
3125185a700Sflorian
3135185a700Sflorian /*
3145185a700Sflorian * Class.
3155185a700Sflorian */
3165185a700Sflorian if ((ctx->style.flags & DNS_STYLEFLAG_NO_CLASS) == 0 &&
3175185a700Sflorian ((ctx->style.flags & DNS_STYLEFLAG_OMIT_CLASS) == 0 ||
318*1fb015a8Sflorian !ctx->class_printed))
3195185a700Sflorian {
3205185a700Sflorian unsigned int class_start;
3215185a700Sflorian INDENT_TO(class_column);
3225185a700Sflorian class_start = target->used;
3235185a700Sflorian result = dns_rdataclass_totext(rdataset->rdclass,
3245185a700Sflorian target);
3255185a700Sflorian if (result != ISC_R_SUCCESS)
3265185a700Sflorian return (result);
3275185a700Sflorian column += (target->used - class_start);
3285185a700Sflorian }
3295185a700Sflorian
3305185a700Sflorian /*
3315185a700Sflorian * Type.
3325185a700Sflorian */
3335185a700Sflorian
3345185a700Sflorian type = rdataset->type;
3355185a700Sflorian
3365185a700Sflorian INDENT_TO(type_column);
3375185a700Sflorian type_start = target->used;
3385185a700Sflorian switch (type) {
3395185a700Sflorian case dns_rdatatype_keydata:
3405185a700Sflorian #define KEYDATA "KEYDATA"
3415185a700Sflorian if ((ctx->style.flags & DNS_STYLEFLAG_KEYDATA) != 0) {
3425185a700Sflorian if (isc_buffer_availablelength(target) <
3435185a700Sflorian (sizeof(KEYDATA) - 1))
3445185a700Sflorian return (ISC_R_NOSPACE);
3455185a700Sflorian isc_buffer_putstr(target, KEYDATA);
3465185a700Sflorian break;
3475185a700Sflorian }
3485185a700Sflorian /* FALLTHROUGH */
3495185a700Sflorian default:
3505185a700Sflorian result = dns_rdatatype_totext(type, target);
3515185a700Sflorian if (result != ISC_R_SUCCESS)
3525185a700Sflorian return (result);
3535185a700Sflorian }
3545185a700Sflorian column += (target->used - type_start);
3555185a700Sflorian
3565185a700Sflorian /*
3575185a700Sflorian * Rdata.
3585185a700Sflorian */
3595185a700Sflorian INDENT_TO(rdata_column);
3605185a700Sflorian {
3615185a700Sflorian dns_rdata_t rdata = DNS_RDATA_INIT;
3625185a700Sflorian isc_region_t r;
3635185a700Sflorian
3645185a700Sflorian dns_rdataset_current(rdataset, &rdata);
3655185a700Sflorian
3665185a700Sflorian RETERR(dns_rdata_tofmttext(&rdata,
3675185a700Sflorian ctx->origin,
3685185a700Sflorian (unsigned int)
3695185a700Sflorian ctx->style.flags,
3705185a700Sflorian ctx->style.line_length -
3715185a700Sflorian ctx->style.rdata_column,
3725185a700Sflorian ctx->style.split_width,
3735185a700Sflorian ctx->linebreak,
3745185a700Sflorian target));
3755185a700Sflorian
3765185a700Sflorian isc_buffer_availableregion(target, &r);
3775185a700Sflorian if (r.length < 1)
3785185a700Sflorian return (ISC_R_NOSPACE);
3795185a700Sflorian r.base[0] = '\n';
3805185a700Sflorian isc_buffer_add(target, 1);
3815185a700Sflorian }
3825185a700Sflorian
383*1fb015a8Sflorian first = 0;
3845185a700Sflorian result = dns_rdataset_next(rdataset);
3855185a700Sflorian }
3865185a700Sflorian
3875185a700Sflorian if (result != ISC_R_NOMORE)
3885185a700Sflorian return (result);
3895185a700Sflorian
3905185a700Sflorian /*
3915185a700Sflorian * Update the ctx state to reflect what we just printed.
3925185a700Sflorian * This is done last, only when we are sure we will return
3935185a700Sflorian * success, because this function may be called multiple
3945185a700Sflorian * times with increasing buffer sizes until it succeeds,
3955185a700Sflorian * and failed attempts must not update the state prematurely.
3965185a700Sflorian */
397*1fb015a8Sflorian ctx->class_printed = 1;
3985185a700Sflorian ctx->current_ttl= current_ttl;
3995185a700Sflorian ctx->current_ttl_valid = current_ttl_valid;
4005185a700Sflorian
4015185a700Sflorian return (ISC_R_SUCCESS);
4025185a700Sflorian }
4035185a700Sflorian
4045185a700Sflorian /*
4055185a700Sflorian * Print the name, type, and class of an empty rdataset,
4065185a700Sflorian * such as those used to represent the question section
4075185a700Sflorian * of a DNS message.
4085185a700Sflorian */
4095185a700Sflorian static isc_result_t
question_totext(dns_rdataset_t * rdataset,dns_name_t * owner_name,dns_totext_ctx_t * ctx,int omit_final_dot,isc_buffer_t * target)4105185a700Sflorian question_totext(dns_rdataset_t *rdataset,
4115185a700Sflorian dns_name_t *owner_name,
4125185a700Sflorian dns_totext_ctx_t *ctx,
413*1fb015a8Sflorian int omit_final_dot,
4145185a700Sflorian isc_buffer_t *target)
4155185a700Sflorian {
4165185a700Sflorian unsigned int column;
4175185a700Sflorian isc_result_t result;
4185185a700Sflorian isc_region_t r;
4195185a700Sflorian
4205185a700Sflorian result = dns_rdataset_first(rdataset);
4215185a700Sflorian REQUIRE(result == ISC_R_NOMORE);
4225185a700Sflorian
4235185a700Sflorian column = 0;
4245185a700Sflorian
4255185a700Sflorian /* Owner name */
4265185a700Sflorian {
4275185a700Sflorian unsigned int name_start = target->used;
4285185a700Sflorian RETERR(dns_name_totext(owner_name,
4295185a700Sflorian omit_final_dot,
4305185a700Sflorian target));
4315185a700Sflorian column += target->used - name_start;
4325185a700Sflorian }
4335185a700Sflorian
4345185a700Sflorian /* Class */
4355185a700Sflorian {
4365185a700Sflorian unsigned int class_start;
4375185a700Sflorian INDENT_TO(class_column);
4385185a700Sflorian class_start = target->used;
4395185a700Sflorian result = dns_rdataclass_totext(rdataset->rdclass, target);
4405185a700Sflorian if (result != ISC_R_SUCCESS)
4415185a700Sflorian return (result);
4425185a700Sflorian column += (target->used - class_start);
4435185a700Sflorian }
4445185a700Sflorian
4455185a700Sflorian /* Type */
4465185a700Sflorian {
4475185a700Sflorian unsigned int type_start;
4485185a700Sflorian INDENT_TO(type_column);
4495185a700Sflorian type_start = target->used;
4505185a700Sflorian result = dns_rdatatype_totext(rdataset->type, target);
4515185a700Sflorian if (result != ISC_R_SUCCESS)
4525185a700Sflorian return (result);
4535185a700Sflorian column += (target->used - type_start);
4545185a700Sflorian }
4555185a700Sflorian
4565185a700Sflorian isc_buffer_availableregion(target, &r);
4575185a700Sflorian if (r.length < 1)
4585185a700Sflorian return (ISC_R_NOSPACE);
4595185a700Sflorian r.base[0] = '\n';
4605185a700Sflorian isc_buffer_add(target, 1);
4615185a700Sflorian
4625185a700Sflorian return (ISC_R_SUCCESS);
4635185a700Sflorian }
4645185a700Sflorian
4655185a700Sflorian isc_result_t
dns_rdataset_totext(dns_rdataset_t * rdataset,dns_name_t * owner_name,int omit_final_dot,int question,isc_buffer_t * target)4665185a700Sflorian dns_rdataset_totext(dns_rdataset_t *rdataset,
4675185a700Sflorian dns_name_t *owner_name,
468*1fb015a8Sflorian int omit_final_dot,
469*1fb015a8Sflorian int question,
4705185a700Sflorian isc_buffer_t *target)
4715185a700Sflorian {
4725185a700Sflorian dns_totext_ctx_t ctx;
4735185a700Sflorian isc_result_t result;
4745185a700Sflorian result = totext_ctx_init(&dns_master_style_debug, &ctx);
4755185a700Sflorian if (result != ISC_R_SUCCESS) {
4765185a700Sflorian UNEXPECTED_ERROR(__FILE__, __LINE__,
4775185a700Sflorian "could not set master file style");
4785185a700Sflorian return (ISC_R_UNEXPECTED);
4795185a700Sflorian }
4805185a700Sflorian
4815185a700Sflorian /*
4825185a700Sflorian * The caller might want to give us an empty owner
4835185a700Sflorian * name (e.g. if they are outputting into a master
4845185a700Sflorian * file and this rdataset has the same name as the
4855185a700Sflorian * previous one.)
4865185a700Sflorian */
4875185a700Sflorian if (dns_name_countlabels(owner_name) == 0)
4885185a700Sflorian owner_name = NULL;
4895185a700Sflorian
4905185a700Sflorian if (question)
4915185a700Sflorian return (question_totext(rdataset, owner_name, &ctx,
4925185a700Sflorian omit_final_dot, target));
4935185a700Sflorian else
4945185a700Sflorian return (rdataset_totext(rdataset, owner_name, &ctx,
4955185a700Sflorian omit_final_dot, target));
4965185a700Sflorian }
4975185a700Sflorian
4985185a700Sflorian isc_result_t
dns_master_rdatasettotext(dns_name_t * owner_name,dns_rdataset_t * rdataset,const dns_master_style_t * style,isc_buffer_t * target)4995185a700Sflorian dns_master_rdatasettotext(dns_name_t *owner_name,
5005185a700Sflorian dns_rdataset_t *rdataset,
5015185a700Sflorian const dns_master_style_t *style,
5025185a700Sflorian isc_buffer_t *target)
5035185a700Sflorian {
5045185a700Sflorian dns_totext_ctx_t ctx;
5055185a700Sflorian isc_result_t result;
5065185a700Sflorian result = totext_ctx_init(style, &ctx);
5075185a700Sflorian if (result != ISC_R_SUCCESS) {
5085185a700Sflorian UNEXPECTED_ERROR(__FILE__, __LINE__,
5095185a700Sflorian "could not set master file style");
5105185a700Sflorian return (ISC_R_UNEXPECTED);
5115185a700Sflorian }
5125185a700Sflorian
5135185a700Sflorian return (rdataset_totext(rdataset, owner_name, &ctx,
514*1fb015a8Sflorian 0, target));
5155185a700Sflorian }
5165185a700Sflorian
5175185a700Sflorian isc_result_t
dns_master_questiontotext(dns_name_t * owner_name,dns_rdataset_t * rdataset,const dns_master_style_t * style,isc_buffer_t * target)5185185a700Sflorian dns_master_questiontotext(dns_name_t *owner_name,
5195185a700Sflorian dns_rdataset_t *rdataset,
5205185a700Sflorian const dns_master_style_t *style,
5215185a700Sflorian isc_buffer_t *target)
5225185a700Sflorian {
5235185a700Sflorian dns_totext_ctx_t ctx;
5245185a700Sflorian isc_result_t result;
5255185a700Sflorian result = totext_ctx_init(style, &ctx);
5265185a700Sflorian if (result != ISC_R_SUCCESS) {
5275185a700Sflorian UNEXPECTED_ERROR(__FILE__, __LINE__,
5285185a700Sflorian "could not set master file style");
5295185a700Sflorian return (ISC_R_UNEXPECTED);
5305185a700Sflorian }
5315185a700Sflorian
5325185a700Sflorian return (question_totext(rdataset, owner_name, &ctx,
533*1fb015a8Sflorian 0, target));
5345185a700Sflorian }
5355185a700Sflorian
5365185a700Sflorian isc_result_t
dns_master_stylecreate2(dns_master_style_t ** stylep,unsigned int flags,unsigned int ttl_column,unsigned int class_column,unsigned int type_column,unsigned int rdata_column,unsigned int line_length,unsigned int tab_width,unsigned int split_width)5375185a700Sflorian dns_master_stylecreate2(dns_master_style_t **stylep, unsigned int flags,
5385185a700Sflorian unsigned int ttl_column, unsigned int class_column,
5395185a700Sflorian unsigned int type_column, unsigned int rdata_column,
5405185a700Sflorian unsigned int line_length, unsigned int tab_width,
5415185a700Sflorian unsigned int split_width)
5425185a700Sflorian {
5435185a700Sflorian dns_master_style_t *style;
5445185a700Sflorian
5455185a700Sflorian REQUIRE(stylep != NULL && *stylep == NULL);
5465185a700Sflorian style = malloc(sizeof(*style));
5475185a700Sflorian if (style == NULL)
5485185a700Sflorian return (ISC_R_NOMEMORY);
5495185a700Sflorian
5505185a700Sflorian style->flags = flags;
5515185a700Sflorian style->ttl_column = ttl_column;
5525185a700Sflorian style->class_column = class_column;
5535185a700Sflorian style->type_column = type_column;
5545185a700Sflorian style->rdata_column = rdata_column;
5555185a700Sflorian style->line_length = line_length;
5565185a700Sflorian style->tab_width = tab_width;
5575185a700Sflorian style->split_width = split_width;
5585185a700Sflorian
5595185a700Sflorian *stylep = style;
5605185a700Sflorian return (ISC_R_SUCCESS);
5615185a700Sflorian }
5625185a700Sflorian
5635185a700Sflorian void
dns_master_styledestroy(dns_master_style_t ** stylep)5645185a700Sflorian dns_master_styledestroy(dns_master_style_t **stylep) {
5655185a700Sflorian dns_master_style_t *style;
5665185a700Sflorian
5675185a700Sflorian REQUIRE(stylep != NULL && *stylep != NULL);
5685185a700Sflorian style = *stylep;
5695185a700Sflorian *stylep = NULL;
5705185a700Sflorian free(style);
5715185a700Sflorian }
572