2540. [func] Add a nibble mode to $GENERATE. [RT #1887]

This commit is contained in:
Mark Andrews 2009-01-30 04:35:44 +00:00
parent e80b693272
commit 53cd44e716
3 changed files with 84 additions and 12 deletions

View file

@ -1,3 +1,5 @@
2540. [func] Add a nibble mode to $GENERATE. [RT #18872]
2539. [security] Update the interaction between recursion, allow-query,
allow-query-cache and allow-recursion. [RT #19198]

View file

@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- File: $Id: Bv9ARM-book.xml,v 1.390 2009/01/30 03:48:54 marka Exp $ -->
<!-- File: $Id: Bv9ARM-book.xml,v 1.391 2009/01/30 04:35:44 marka Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
@ -11476,20 +11476,30 @@ HOST-127.EXAMPLE. MX 0 .
Available output forms are decimal
(<command>d</command>), octal
(<command>o</command>) and hexadecimal
(<command>o</command>), hexadecimal
(<command>x</command> or <command>X</command>
for uppercase). The default modifier is
for uppercase) and nibble
(<command>n</command> or <command>N</command>\
for uppercase). The default modifier is
<command>${0,0,d}</command>. If the
<command>lhs</command> is not absolute, the
current <command>$ORIGIN</command> is appended
to the name.
</para>
<para>
For compatibility with earlier versions, <command>$$</command> is still
recognized as indicating a literal $ in the output.
</para>
</entry>
</row>
<para>
In nibble mode the value will be treated as
a if it was a reversed hexadecimal string
with each hexadecimal digit as a seperate
label. The width field includes the label
seperator.
</para>
<para>
For compatibility with earlier versions,
<command>$$</command> is still recognized as
indicating a literal $ in the output.
</para>
</entry>
</row>
<row rowsep="0">
<entry colname="1">
<para><command>ttl</command></para>

View file

@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: master.c,v 1.174 2009/01/17 23:47:42 tbox Exp $ */
/* $Id: master.c,v 1.175 2009/01/30 04:35:44 marka Exp $ */
/*! \file */
@ -618,6 +618,57 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx,
return (result);
}
static const char *hex = "0123456789abcdef0123456789ABCDEF";
/*%
* Convert value into a nibble sequence from least significant to most
* significant nibble. Zero fill upper most significant nibbles if
* required to make the width.
*
* Returns the number of characters that should have been written without
* counting the terminating NUL.
*/
static unsigned int
nibbles(char *numbuf, size_t length, unsigned int width, char mode, int value) {
unsigned int count = 0;
/*
* This reserve space for the NUL string terminator.
*/
if (length > 0) {
*numbuf = '\0';
length--;
}
do {
char val = hex[(value & 0x0f) + ((mode == 'n') ? 0 : 16)];
value >>= 4;
if (length > 0) {
*numbuf++ = val;
*numbuf = '\0';
length--;
}
if (width > 0)
width--;
count++;
/*
* If width is non zero then we need to add a label seperator.
* If value is non zero then we need to add another label and
* that requires a label seperator.
*/
if (width > 0 || value != 0) {
if (length > 0) {
*numbuf++ = '.';
*numbuf = '\0';
length--;
}
if (width > 0)
width--;
count++;
}
} while (value != 0 || width > 0);
return (count);
}
static isc_result_t
genname(char *name, int it, char *buffer, size_t length) {
char fmt[sizeof("%04000000000d")];
@ -628,6 +679,7 @@ genname(char *name, int it, char *buffer, size_t length) {
isc_textregion_t r;
unsigned int n;
unsigned int width;
isc_boolean_t nibblemode;
r.base = buffer;
r.length = length;
@ -642,10 +694,11 @@ genname(char *name, int it, char *buffer, size_t length) {
isc_textregion_consume(&r, 1);
continue;
}
nibblemode = ISC_FALSE;
strcpy(fmt, "%d");
/* Get format specifier. */
if (*name == '{' ) {
n = sscanf(name, "{%d,%u,%1[doxX]}",
n = sscanf(name, "{%d,%u,%1[doxXnN]}",
&delta, &width, mode);
switch (n) {
case 1:
@ -655,6 +708,8 @@ genname(char *name, int it, char *buffer, size_t length) {
"%%0%ud", width);
break;
case 3:
if (mode[0] == 'n' || mode[0] == 'N')
nibblemode = ISC_TRUE;
n = snprintf(fmt, sizeof(fmt),
"%%0%u%c", width, mode[0]);
break;
@ -667,7 +722,12 @@ genname(char *name, int it, char *buffer, size_t length) {
while (*name != '\0' && *name++ != '}')
continue;
}
n = snprintf(numbuf, sizeof(numbuf), fmt, it + delta);
if (nibblemode)
n = nibbles(numbuf, sizeof(numbuf), width,
mode[0], it + delta);
else
n = snprintf(numbuf, sizeof(numbuf), fmt,
it + delta);
if (n >= sizeof(numbuf))
return (ISC_R_NOSPACE);
cp = numbuf;