]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
2540. [func] Add a nibble mode to $GENERATE. [RT #1887]
authorMark Andrews <marka@isc.org>
Fri, 30 Jan 2009 04:35:44 +0000 (04:35 +0000)
committerMark Andrews <marka@isc.org>
Fri, 30 Jan 2009 04:35:44 +0000 (04:35 +0000)
CHANGES
doc/arm/Bv9ARM-book.xml
lib/dns/master.c

diff --git a/CHANGES b/CHANGES
index e3513d1d29710b9f8c9e6d011eb6254637f29a9f..594763bf98d3e145abfc86945fc447c72d35775e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -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]
 
index 9c241627c0ad2ec8d39ac7cc1971d6eeb03061f5..10c679c1d764deb160f8e499c9801e92b5623dcb 100644 (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>
index 2518e210aad90e7f03734ddc331dc1ac4eef45cb..dcd5955057ea04370f085db0c23a356c724dbe80 100644 (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;