Index: trunk/DNSDB.pm
===================================================================
--- trunk/DNSDB.pm	(revision 229)
+++ trunk/DNSDB.pm	(revision 230)
@@ -242,26 +242,19 @@
 sub _validate_1 {
   my $dbh = shift;
-  my $defrec = shift;
-  my $revrec = shift;
-  my $id = shift;      # parent (group_id for defrecs, rdns_id for reverse records,
-                       # domain_id for domain records)
-
-  # These next two should be references, so we can pass them back altered.  Yes, we really want to do that.
-  my $host = shift;
-  my $val = shift;
-  my $addr = shift;
-
-  return ('FAIL', 'Reverse zones cannot contain A records') if $revrec eq 'y';
+
+  my %args = @_;
+
+  return ('FAIL', 'Reverse zones cannot contain A records') if $args{revrec} eq 'y';
 
   # Coerce all hostnames to end in ".DOMAIN" for group/default records,
   # or the intended parent domain for live records.
-  my $pname = ($defrec eq 'y' ? 'DOMAIN' : domainName($dbh,$id));
-  $$host =~ s/\.*$/\.$pname/ if $$host !~ /$pname$/;
+  my $pname = ($args{defrec} eq 'y' ? 'DOMAIN' : domainName($dbh,$args{id}));
+  ${$args{host}} =~ s/\.*$/\.$pname/ if ${$args{host}} !~ /$pname$/;
 
   # Check IP is well-formed, and that it's a v4 address
   return ('FAIL',"A record must be a valid IPv4 address")
-	unless $addr && !$addr->{isv6};
+	unless $args{addr} && !$args{addr}->{isv6};
   # coerce IP/value to normalized form for storage
-  $$val = $addr->addr;
+  ${$args{val}} = $args{addr}->addr;
 
   return ('OK','OK');
@@ -270,4 +263,26 @@
 # NS record
 sub _validate_2 {
+  my $dbh = shift;
+
+  my %args = @_;
+
+  # Coerce the hostname to "DOMAIN" for forward default records, "ZONE" for reverse default records,
+  # or the intended parent zone for live records.
+##fixme:  allow for delegating <subdomain>.DOMAIN?
+  if ($args{revrec} eq 'y') {
+    my $pname = ($args{defrec} eq 'y' ? 'ZONE' : revName($dbh,$args{id}));
+    ${$args{host}} = $pname if ${$args{host}} ne $pname;
+  } else {
+    my $pname = ($args{defrec} eq 'y' ? 'DOMAIN' : domainName($dbh,$args{id}));
+    ${$args{host}} = $pname if ${$args{host}} ne $pname;
+  }
+
+# Let this lie for now.  Needs more magic.
+#  # Check IP is well-formed, and that it's a v4 address
+#  return ('FAIL',"A record must be a valid IPv4 address")
+#	unless $addr && !$addr->{isv6};
+#  # coerce IP/value to normalized form for storage
+#  $$val = $addr->addr;
+
   return ('OK','OK');
 } # done NS record
@@ -275,4 +290,18 @@
 # CNAME record
 sub _validate_5 {
+  my $dbh = shift;
+
+  my %args = @_;
+
+# Not really true, but these are only useful for delegating smaller-than-/24 IP blocks.
+# This is fundamentally a messy operation and should really just be taken care of by the
+# export process, not manual maintenance of the necessary records.
+  return ('FAIL', 'Reverse zones cannot contain CNAME records') if $args{revrec} eq 'y';
+
+  # Coerce all hostnames to end in ".DOMAIN" for group/default records,
+  # or the intended parent domain for live records.
+  my $pname = ($args{defrec} eq 'y' ? 'DOMAIN' : domainName($dbh,$args{id}));
+  ${$args{host}} =~ s/\.*$/\.$pname/ if ${$args{host}} !~ /$pname$/;
+
   return ('OK','OK');
 } # done CNAME record
@@ -280,4 +309,6 @@
 # SOA record
 sub _validate_6 {
+  # Smart monkeys won't stick their fingers in here;  we have
+  # separate dedicated routines to deal with SOA records.
   return ('OK','OK');
 } # done SOA record
@@ -290,4 +321,23 @@
 # MX record
 sub _validate_15 {
+  my $dbh = shift;
+
+  my %args = @_;
+
+# Not absolutely true but WTF use is an MX record for a reverse zone?
+  return ('FAIL', 'Reverse zones cannot contain MX records') if $args{revrec} eq 'y';
+
+  return ('FAIL', "Distance is required for MX records") unless defined(${$args{dist}});
+  ${$args{dist}} =~ s/\s*//g;
+  return ('FAIL',"Distance is required, and must be numeric") unless ${$args{dist}} =~ /^\d+$/;
+
+  ${$args{fields}} = "distance,";
+  push @{$args{vallist}}, ${$args{dist}};
+
+  # Coerce all hostnames to end in ".DOMAIN" for group/default records,
+  # or the intended parent domain for live records.
+  my $pname = ($args{defrec} eq 'y' ? 'DOMAIN' : domainName($dbh,$args{id}));
+  ${$args{host}} =~ s/\.*$/\.$pname/ if ${$args{host}} !~ /$pname$/;
+
   return ('OK','OK');
 } # done MX record
@@ -306,26 +356,19 @@
 sub _validate_28 {
   my $dbh = shift;
-  my $defrec = shift;
-  my $revrec = shift;
-  my $id = shift;      # parent (group_id for defrecs, rdns_id for reverse records,
-                       # domain_id for domain records)
-
-  # These next two should be references, so we can pass them back altered.  Yes, we really want to do that.
-  my $host = shift;
-  my $val = shift;
-  my $addr = shift;
-
-  return ('FAIL', 'Reverse zones cannot contain AAAA records') if $revrec eq 'y';
+
+  my %args = @_;
+
+  return ('FAIL', 'Reverse zones cannot contain AAAA records') if $args{revrec} eq 'y';
 
   # Coerce all hostnames to end in ".DOMAIN" for group/default records,
   # or the intended parent domain for live records.
-  my $pname = ($defrec eq 'y' ? 'DOMAIN' : domainName($dbh,$id));
-  $$host =~ s/\.*$/\.$pname/ if $$host !~ /$pname$/;
+  my $pname = ($args{defrec} eq 'y' ? 'DOMAIN' : domainName($dbh,$args{id}));
+  ${$args{host}} =~ s/\.*$/\.$pname/ if ${$args{host}} !~ /$pname$/;
 
   # Check IP is well-formed, and that it's a v6 address
   return ('FAIL',"AAAA record must be a valid IPv6 address")
-	unless $addr && $addr->{isv6};
+	unless $args{addr} && $args{addr}->{isv6};
   # coerce IP/value to normalized form for storage
-  $$val = $addr->addr;
+  ${$args{val}} = $args{addr}->addr;
 
   return ('OK','OK');
