From cd750f6e7449678173e8cfe080ae0bf3dcb424cf Mon Sep 17 00:00:00 2001 From: Evan Hunt Date: Tue, 29 Apr 2014 16:58:36 -0700 Subject: [PATCH] [master] dig +ttlunits 3829. [func] "dig +ttlunits" causes dig to print TTL values with time-unit suffixes: w, d, h, m, s for weeks, days, hours, minutes, and seconds. (Thanks to Tony Finch.) [RT #35823] --- CHANGES | 5 +++++ README | 3 +++ bin/dig/dig.c | 22 ++++++++++++++++++---- bin/dig/dig.docbook | 11 +++++++++++ lib/dns/include/dns/masterdump.h | 2 ++ lib/dns/include/dns/ttl.h | 9 +++++++++ lib/dns/masterdump.c | 28 +++++++++++++++++++--------- lib/dns/ttl.c | 9 ++++++++- 8 files changed, 75 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index 7677a804c1..cc4f9972b4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +3829. [func] "dig +ttlunits" causes dig to print TTL values + with time-unit suffixes: w, d, h, m, s for + weeks, days, hours, minutes, and seconds. (Thanks + to Tony Finch.) [RT #35823] + 3828. [placeholder] 3827. [func] "dnssec-signzone -N date" updates serial number diff --git a/README b/README index d1117ba018..499e3f5fe8 100644 --- a/README +++ b/README @@ -61,6 +61,9 @@ BIND 9.11.0 in single-line-per-record format. - "dig" now supports sending arbitary EDNS options by specifying them on the command line. + - "dig +ttlunits" causes dig to print TTL values with time-unit + suffixes: w, d, h, m, s for weeks, days, hours, minutes, and + seconds. - "serial-update-format" can now be set to "date". On update, the serial number will be set to the current date in YYYYMMDDNN format. diff --git a/bin/dig/dig.c b/bin/dig/dig.c index 0b774bd9eb..8a8bf9f417 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -69,7 +69,7 @@ static isc_boolean_t short_form = ISC_FALSE, printcmd = ISC_TRUE, ip6_int = ISC_FALSE, plusquest = ISC_FALSE, pluscomm = ISC_FALSE, multiline = ISC_FALSE, nottl = ISC_FALSE, noclass = ISC_FALSE, onesoa = ISC_FALSE, rrcomments = ISC_FALSE, use_usec = ISC_FALSE, - nocrypto = ISC_FALSE; + nocrypto = ISC_FALSE, ttlunits = ISC_FALSE; static isc_uint32_t splitwidth = 0xffffffff; /*% opcode text */ @@ -218,6 +218,7 @@ help(void) { " +[no]short (Disable everything except short\n" " form of answer)\n" " +[no]ttlid (Control display of ttls in records)\n" +" +[no]ttlunits (Display TTLs in human-readable units)\n" " +[no]all (Set or clear all display flags)\n" " +[no]qr (Print question before sending)\n" " +[no]nssearch (Search all authoritative nameservers)\n" @@ -424,6 +425,8 @@ printrdataset(dns_name_t *owner_name, dns_rdataset_t *rdataset, return(ISC_FALSE); styleflags |= DNS_STYLEFLAG_REL_OWNER; + if (ttlunits) + styleflags |= DNS_STYLEFLAG_TTL_UNITS; if (nottl) styleflags |= DNS_STYLEFLAG_NO_TTL; if (noclass) @@ -483,6 +486,8 @@ printmessage(dig_query_t *query, dns_message_t *msg, isc_boolean_t headers) { styleflags |= DNS_STYLEFLAG_COMMENT; if (rrcomments) styleflags |= DNS_STYLEFLAG_RRCOMMENT; + if (ttlunits) + styleflags |= DNS_STYLEFLAG_TTL_UNITS; if (nottl) styleflags |= DNS_STYLEFLAG_NO_TTL; if (noclass) @@ -1297,9 +1302,18 @@ plus_option(char *option, isc_boolean_t is_batchfile, goto invalid_option; } break; - case 't': /* ttlid */ - FULLCHECK("ttlid"); - nottl = ISC_TF(!state); + case 't': + switch (cmd[3]) { + case 'i': /* ttlid */ + FULLCHECK("ttlid"); + nottl = ISC_TF(!state); + break; + case 'u': /* ttlunits */ + FULLCHECK("ttlunits"); + nottl = ISC_FALSE; + ttlunits = ISC_TF(state); + break; + } break; default: goto invalid_option; diff --git a/bin/dig/dig.docbook b/bin/dig/dig.docbook index ac03478a3e..8af7873338 100644 --- a/bin/dig/dig.docbook +++ b/bin/dig/dig.docbook @@ -510,6 +510,17 @@ + + + + + Display [do not display] the TTL in friendly human-readable + time units of "s", "m", "h", "d", and "w", representing + seconds, minutes, hours, days and weeks. Implies +ttlid. + + + + diff --git a/lib/dns/include/dns/masterdump.h b/lib/dns/include/dns/masterdump.h index 4d5fd044da..7318184a95 100644 --- a/lib/dns/include/dns/masterdump.h +++ b/lib/dns/include/dns/masterdump.h @@ -106,6 +106,8 @@ typedef struct dns_master_style dns_master_style_t; /*% Comment out data by prepending with ";" */ #define DNS_STYLEFLAG_COMMENTDATA 0x10000000U +/*% Print TTL with human-readable units. */ +#define DNS_STYLEFLAG_TTL_UNITS 0x20000000U ISC_LANG_BEGINDECLS diff --git a/lib/dns/include/dns/ttl.h b/lib/dns/include/dns/ttl.h index c2525183b7..fd5dc3f5da 100644 --- a/lib/dns/include/dns/ttl.h +++ b/lib/dns/include/dns/ttl.h @@ -38,6 +38,9 @@ ISC_LANG_BEGINDECLS isc_result_t dns_ttl_totext(isc_uint32_t src, isc_boolean_t verbose, isc_buffer_t *target); +isc_result_t +dns_ttl_totext2(isc_uint32_t src, isc_boolean_t verbose, + isc_boolean_t upcase, isc_buffer_t *target); /*%< * Output a TTL or other time interval in a human-readable form. * The time interval is given as a count of seconds in 'src'. @@ -48,6 +51,12 @@ dns_ttl_totext(isc_uint32_t src, isc_boolean_t verbose, * If 'verbose' is ISC_TRUE, use a verbose style like the SOA comments * in "dig", like "1 week 2 days 3 hours 4 minutes 5 seconds". * + * If 'upcase' is ISC_TRUE, we conform to the BIND 8 style in which + * the unit letter is capitalized if there is only a single unit + * letter to print (for example, "1m30s", but "2M") + * + * If 'upcase' is ISC_FALSE, unit letters are always in lower case. + * * Returns: * \li ISC_R_SUCCESS * \li ISC_R_NOSPACE diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c index 51d0ec5601..b2b2ab4246 100644 --- a/lib/dns/masterdump.c +++ b/lib/dns/masterdump.c @@ -494,15 +494,25 @@ rdataset_totext(dns_rdataset_t *rdataset, unsigned int length; INDENT_TO(ttl_column); - length = snprintf(ttlbuf, sizeof(ttlbuf), "%u", - rdataset->ttl); - INSIST(length <= sizeof(ttlbuf)); - isc_buffer_availableregion(target, &r); - if (r.length < length) - return (ISC_R_NOSPACE); - memmove(r.base, ttlbuf, length); - isc_buffer_add(target, length); - column += length; + if ((ctx->style.flags & DNS_STYLEFLAG_TTL_UNITS) != 0) { + length = target->used; + result = dns_ttl_totext2(rdataset->ttl, + ISC_FALSE, ISC_FALSE, + target); + if (result != ISC_R_SUCCESS) + return (result); + column += target->used - length; + } else { + length = snprintf(ttlbuf, sizeof(ttlbuf), "%u", + rdataset->ttl); + INSIST(length <= sizeof(ttlbuf)); + isc_buffer_availableregion(target, &r); + if (r.length < length) + return (ISC_R_NOSPACE); + memmove(r.base, ttlbuf, length); + isc_buffer_add(target, length); + column += length; + } /* * If the $TTL directive is not in use, the TTL we diff --git a/lib/dns/ttl.c b/lib/dns/ttl.c index d8ed357449..59d2ef42bb 100644 --- a/lib/dns/ttl.c +++ b/lib/dns/ttl.c @@ -79,6 +79,13 @@ ttlfmt(unsigned int t, const char *s, isc_boolean_t verbose, */ isc_result_t dns_ttl_totext(isc_uint32_t src, isc_boolean_t verbose, isc_buffer_t *target) { + return (dns_ttl_totext2(src, verbose, ISC_TRUE, target)); +} + +isc_result_t +dns_ttl_totext2(isc_uint32_t src, isc_boolean_t verbose, + isc_boolean_t upcase, isc_buffer_t *target) +{ unsigned secs, mins, hours, days, weeks, x; secs = src % 60; src /= 60; @@ -116,7 +123,7 @@ dns_ttl_totext(isc_uint32_t src, isc_boolean_t verbose, isc_buffer_t *target) { * in upper case. (Why? Because BIND 8 does that. * Presumably it has a reason.) */ - if (x == 1 && !verbose) { + if (x == 1 && upcase && !verbose) { isc_region_t region; /* * The unit letter is the last character in the