patches to support a/aaaa records with $generate

Joe Pruett joey at q7.com
Sun Jul 18 15:00:12 UTC 1999


i've gotten the word that these patches will be in a future release of
bind.  so i'll release them to the crowd as well and see if anyone finds a
problem.

----cut here----
--- doc/html/master.html	Thu Jun 10 12:42:18 1999
+++ /usr/local/src/bind-8.2.1/doc/html/master.html	Sat Jun 26 09:22:21 1999
@@ -95,14 +95,26 @@
 <DD>
 Lhs describes the owner name of the resource records to be created.
 Any single $ symbols within the LHS side are replaced by the iterator value.
-To get a $ in the output use a double $, e.g. $$.  If the lhs is not absolute
-the current $ORIGIN is appended to the name.
+To get a $ in the output use \$.  If the lhs is not absolute
+the current $ORIGIN is appended to the name, when appropriate.
+You can also apply an offset to the iterator by using ${offset} where
+offset is a decimal value to add to the iterator.
+And you can also change the format of the iterator by using a printf
+like string.  The format is ${offset,width,radix} where offset is as before
+(use 0 for no change), width is the minimum field width (always zero padded)
+radix is one of d, o, x, or X to change the radix to decimal, octal, hex, or hex
+with capital letters.
+The default is ${0,1,d}.
+For example: ${16,3} will add 16 to the iterator and be replaced by
+a 3 digit decimal representation.  ${0,2,x} will be replaced by a 2 digit
+hex representation.  To get a { character inserted into the text
+immediately after the iterator, use $\{.
 <DT>type</DT>
 <DD>
-At present the only supported types are PTR, CNAME and NS.
+At present the only supported types are A, AAAA, PTR, CNAME and NS.
 <DT>rhs</DT>
 <DD>
-Rhs is a domain name. It is processed similarly to the lhs.
+Rhs is the data. It is processed similarly to the lhs.
 <DD>
 </DL>
 <H2>Resource Records</H2>
--- src/bin/named/db_load.c	Thu Jun 10 18:25:48 1999
+++ /usr/local/src/bind-8.2.1/src/bin/named/db_load.c	Thu Jun 24 22:43:41 1999
@@ -395,9 +395,9 @@
 			if ((genend < genstart) || (genstart < 0) ||
 			    (genstep < 0))
 			    	ERRTO("$GENERATE invalid range");
-			if (!getword(genlhs, sizeof(genlhs), fp, 1))
+			if (!getword(genlhs, sizeof(genlhs), fp, 2))
 				ERRTOZ("$GENERATE missing LHS");
-			if (!getword(buf, sizeof(buf), fp, 1))
+			if (!getword(buf, sizeof(buf), fp, 0))
 				ERRTOZ("GENERATE missing TYPE");
 			type = sym_ston(__p_type_syms, buf, &success);
 			if (success == 0 || type == ns_t_any) {
@@ -412,11 +412,13 @@
 			case ns_t_ns:
 			case ns_t_ptr:
 			case ns_t_cname:
+			case ns_t_a:
+			case ns_t_aaaa:
 				break;
 			default:
 				ERRTO("$GENERATE unsupported type");
 			}
-			if (!getword(genrhs, sizeof(genrhs), fp, 1))
+			if (!getword(genrhs, sizeof(genrhs), fp, 2))
 				ERRTOZ("$GENERATE missing RHS");
 			for (i = genstart; i <= genend; i += genstep) {
 				if (genname(genlhs, i, origin, domain,
@@ -428,30 +430,57 @@
 					strcpy(buf, domain);
 					ERRTO("$GENERATE owner name error");
 				}
-				if (genname(genrhs, i, origin, (char *)data,
-						sizeof data) == -1)
-					ERRTOZ("$GENERATE genname RHS failed");
 				switch (type) {
 				case ns_t_ns:
-					context = hostname_ctx;
-					break;
 				case ns_t_ptr:
-					context = ns_ptrcontext(domain);
-					break;
 				case ns_t_cname:
-					context = domain_ctx;
+					if (genname(genrhs, i, origin, (char *)data,
+							sizeof data) == -1)
+						ERRTOZ("$GENERATE genname RHS failed");
+					switch (type) {
+					case ns_t_ns:
+						context = hostname_ctx;
+						break;
+					case ns_t_ptr:
+						context = ns_ptrcontext(domain);
+						break;
+					case ns_t_cname:
+						context = domain_ctx;
+						break;
+					}
+					if (!ns_nameok((char *)data, class, zp,
+							   transport, context,
+							   domain, inaddr_any)) {
+						strncpy(buf, domain, sizeof(buf));
+						buf[sizeof(buf)-1] = '\0';
+						ERRTO("$GENERATE name error");
+					}
+					n = strlen((char *)data) + 1;
 					break;
-				default:
-				       ERRTOZ("$GENERATE unsupported context");
-				}
-				if (!ns_nameok((char *)data, class, zp,
-					       transport, context,
-					       domain, inaddr_any)) {
-					strncpy(buf, domain, sizeof(buf));
+				case ns_t_a:
+				case ns_t_aaaa:
+					if (genname(genrhs, i, NULL, (char *)data,
+							sizeof data) == -1)
+						ERRTOZ("$GENERATE genname RHS failed");
+					strncpy(buf, data, sizeof(buf));
 					buf[sizeof(buf)-1] = '\0';
-					ERRTO("$GENERATE name error");
+					switch (type) {
+					case ns_t_a:
+						if (!inet_aton(buf, &ina))
+							ERRTO("IP Address");
+						(void) ina_put(ina, data);
+						n = NS_INT32SZ;
+						break;
+					case ns_t_aaaa:
+						if (inet_pton(AF_INET6, buf, data) <= 0)
+							ERRTO("IPv4 Address");
+						n = NS_IN6ADDRSZ;
+						break;
+					}
+					break;
+				default:
+					   ERRTOZ("$GENERATE unsupported context");
 				}
-				n = strlen((char *)data) + 1;
 				dp = savedata(class, type, (u_int32_t)ttl,
 					      (u_char *)data, (int)n);
 				dp->d_zone = zp - zones;
@@ -1192,6 +1221,7 @@
  *	size - of destination
  *	fp - file to read from
  *	preserve - should we preserve \ before \\ and \.?
+ *   if preserve == 2, then keep all \
  * return value:
  *	0 = no word; perhaps EOL or EOF; lineno was incremented.
  *	1 = word was read
@@ -1228,6 +1258,9 @@
 						c = '\\';
 					if (preserve)
 						switch (c) {
+						default:
+							if (preserve == 1)
+								break;
 						case '\\':
 						case '.':
 						case '0':
@@ -1275,6 +1308,9 @@
 				c = '\\';
 			if (preserve)
 				switch (c) {
+				default:
+					if (preserve == 1)
+						break;
 				case '\\':
 				case '.':
 				case '0':
@@ -1550,8 +1586,12 @@
 
 /*
  * Replace all single "$"'s in "name" with "it".
- * To get a "$" in the output use "$$".
+ * ${delta} will add delta to "it" before printing.
+ * ${delta,width} will change print width as well, zero fill is implied
+ * ${delta,width,radix} will change radix as well, can be d, o, x, X.
+ * i.e. ${0,2,X} will produce a two digit hex (upper case) with zero fill.
  * Append "origin" to name if required and validate result with makename.
+ * To get a "$" or "{" in the output use \ before it.
  * Return 0 on no error or -1 on error.
  * Resulting name stored in "buf".
  */
@@ -1562,15 +1602,37 @@
 	char *eom = buf + size;
 	char *cp;
 	char numbuf[32];
+	char fmt[32];
+	int delta = 0;
+	int width;
 
 	while (*name) {
 		if (*name == '$') {
 			if (*(++name) == '$') {
+				/* should be deprecated.  how? */
 				if (bp >= eom)
 					return (-1);
 				*bp++ = *name++;
 			} else {
-				sprintf(numbuf, "%d", it);
+				strcpy(fmt, "%d");
+				if (*name == '{') {
+					switch (sscanf(name, "{%d,%d,%1[doxX]}", &delta, &width, numbuf)) {
+					case 1:
+						break;
+					case 2:
+						sprintf(fmt, "%%0%dd", width);
+						break;
+					case 3:
+						sprintf(fmt, "%%0%d%c", width, numbuf[0]);
+						break;
+					default:
+						return (-1);
+					}
+					while (*name && *name++ != '}') {
+						continue;
+					}
+				}
+				sprintf(numbuf, fmt, it + delta);
 				cp = numbuf;
 				while (*cp) {
 					if (bp >= eom)
@@ -1578,6 +1640,34 @@
 					*bp++ = *cp++;
 				}
 			}
+		} else if (*name == '\\') {
+			if (*(++name) == '\0') {
+				if (bp >= eom)
+					return (-1);
+				*bp++ = '\\';
+			} else {
+				switch (*name) {
+				case '\\':
+				case '.':
+				case '0':
+				case '1':
+				case '2':
+				case '3':
+				case '4':
+				case '5':
+				case '6':
+				case '7':
+				case '8':
+				case '9':
+					if (bp >= eom)
+						return (-1);
+					*bp++ = '\\';
+				default:
+					if (bp >= eom)
+						return (-1);
+					*bp++ = *name++;
+				}
+			}
 		} else {
 			if (bp >= eom)
 				return (-1);
@@ -1587,7 +1677,7 @@
 	if (bp >= eom)
 		return (-1);
 	*bp = '\0';
-	return (makename(buf, origin, size));
+	return (origin == NULL ? 0 : makename(buf, origin, size));
 }
 
 
----cut here----



More information about the bind-users mailing list