Index: trunk/DNSDB.pm
===================================================================
--- trunk/DNSDB.pm	(revision 338)
+++ trunk/DNSDB.pm	(revision 339)
@@ -4023,5 +4023,5 @@
   my $domsth = $dbh->prepare("SELECT domain_id,domain,status FROM domains WHERE status=1");
   my $recsth = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl,record_id ".
-	"FROM records WHERE domain_id=?");
+	"FROM records WHERE domain_id=? AND NOT type=65283");
   $domsth->execute();
   while (my ($domid,$dom,$domstat) = $domsth->fetchrow_array) {
@@ -4089,4 +4089,35 @@
     my @o = ($tmp =~ /^(..)(..)$/);	# split into octets
     return sprintf "\\%0.3o\\%0.3o", hex($o[0]), hex($o[1]);;
+  }
+
+## WARNING:  This works to export even the whole Internet's worth of IP space...
+##  if you have the disk/RAM to handle the dataset, and you call this sub based on /16-sized chunks
+##  A /16 took ~3 seconds with a handful of separate records;  adding a /8 pushed export time out to ~13m:40s 
+##  0/0 is estimated to take ~54 hours and ~256G of disk
+##  RAM usage depends on how many non-template entries you have in the set.
+##  This should probably be done on record addition rather than export;  large blocks may need to be done in a
+##  forked process
+  sub __publish_subnet {
+    my $sub = shift;
+    my $recflags = shift;
+    my $hpat = shift;
+    my $fh = shift;
+    my $ttl = shift;
+    my $stamp = shift;
+    my $loc = shift;
+    my $ptronly = shift || 0;
+
+    my $iplist = $sub->splitref(32);
+    foreach (@$iplist) {
+      my $ip = $_->addr;
+      # make as if we split the non-octet-aligned block into octet-aligned blocks as with SOA
+      next if $ip =~ /\.(0|255)$/;
+      next if $$recflags{$ip};
+      $$recflags{$ip}++;
+      my $rec = $hpat;	# start fresh with the template for each IP
+      _template4_expand(\$rec, $ip);
+      print $fh ($ptronly ? "^"._ZONE($_, 'ZONE.in-addr.arpa', 'r', '.').":$rec" : "=$rec:$ip").
+	":$ttl:$stamp:$loc\n";
+    }
   }
 
@@ -4250,5 +4281,4 @@
       } elsif ($type == 65282) { # PTR template
 
-##work
 	# only useful for v4 with standard DNS software, since this expands all
 	# IPs in $zone (or possibly $val?) with autogenerated records
@@ -4256,14 +4286,10 @@
 	return if $val->{isv6};
 
-	my $iplist = $val->hostenumref;
-	foreach (@$iplist) {
-	  my $ip = $_->addr;
-	  # make as if we split the non-octet-aligned block into octet-aligned blocks as with SOA
-	  next if $ip =~ /\.(0|255)$/;
-	  next if $$recflags{$ip};
-	  $$recflags{$ip}++;
-	  my $rec = $host;	# start fresh with the template for each IP
-	  _template4_expand(\$rec, $ip);
-	  print $datafile "^"._ZONE($_, 'ZONE.in-addr.arpa', 'r', '.').":$rec:$ttl:$stamp:$loc\n";
+	if ($val->masklen <= 16) {
+	  foreach my $sub ($val->split(16)) {
+	    __publish_subnet($sub, $recflags, $host, $datafile, $ttl, $stamp, $loc, 1);
+	  }
+	} else {
+	  __publish_subnet($val, $recflags, $host, $datafile, $ttl, $stamp, $loc, 1);
 	}
 
@@ -4273,14 +4299,11 @@
 	# Just In Case.  An A+PTR should be impossible to add to a v6 revzone via API.
 	return if $val->{isv6};
-	my $iplist = $val->hostenumref;
-	foreach (@$iplist) {
-	  my $ip = $_->addr;
-	  # make as if we split the non-octet-aligned block into octet-aligned blocks as with SOA
-	  next if $ip =~ /\.(0|255)$/;
-	  next if $$recflags{$ip};
-	  $$recflags{$ip}++;
-	  my $rec = $host;	# start fresh with the template for each IP
-	  _template4_expand(\$rec, $ip);
-	  print $datafile "=$rec:$ip:$ttl:$stamp:$loc\n";
+
+	if ($val->masklen <= 16) {
+	  foreach my $sub ($val->split(16)) {
+	    __publish_subnet($sub, $recflags, $host, $datafile, $ttl, $stamp, $loc, 0);
+	  }
+	} else {
+	  __publish_subnet($val, $recflags, $host, $datafile, $ttl, $stamp, $loc, 0);
 	}
 
