Use names in record links instead of indexes
authorJamie Cameron <jcameron@webmin.com>
Sat, 28 May 2011 18:03:07 +0000 (11:03 -0700)
committerJamie Cameron <jcameron@webmin.com>
Sat, 28 May 2011 18:03:07 +0000 (11:03 -0700)
bind8/CHANGELOG
bind8/bind8-lib.pl
bind8/delete_recs.cgi
bind8/edit_record.cgi
bind8/edit_recs.cgi
bind8/lang/en
bind8/records-lib.pl
bind8/save_record.cgi

index 374cf73..8bd2f5a 100644 (file)
@@ -127,3 +127,5 @@ When adding cluster slave servers, their IPs are added to the also-notify and al
 IPv6 addresses can now be used for remote nameservers in slave and delegation zones.
 ---- Changes since 1.540 ----
 Added the Test Zone Transfer button to the slave zone page, to check if zone transfers are possible or not.
+---- Changes since 1.550 ----
+Links for editing and deleting records now using the record name instead of an index, which makes editing more reliable if records are also being updated by dynamic DNS or some other tool.
index 2355b45..bf69151 100755 (executable)
@@ -878,6 +878,7 @@ print &ui_hidden("sort", $in{'sort'});
 if (defined($_[5])) {
        print &ui_hidden("num", $_[5]);
        %rec = %{$_[6]};
+       print &ui_hidden("id", &record_id(\%rec));
        }
 else {
        print &ui_hidden("new", 1);
index f0b5235..2466da4 100755 (executable)
@@ -36,7 +36,9 @@ else {
        @recs = &read_zone_file($zone->{'file'}, $dom);
 
        foreach $d (sort { $b <=> $a } @d) {
-               $r = $recs[$d];
+               ($num, $id) = split(/\//, $d, 2);
+               $r = &find_record_by_id(\@recs, $id, $num);
+               next if (!$r);
                if ($in{'rev'}) {
                        # Find the reverse
                        $fulloldvalue0 = &convert_to_absolute(
index 77eead4..d11c3bd 100755 (executable)
@@ -11,7 +11,8 @@ $dom = $zone->{'name'};
 $type = $zone->{'type'};
 $file = $zone->{'file'};
 @recs = &read_zone_file($file, $dom);
-$rec = $recs[$in{'num'}];
+$rec = &find_record_by_id(\@recs, $in{'id'}, $in{'num'});
+$rec || &error($text{'edit_egone'});
 &can_edit_type($rec->{'type'}, \%access) ||
        &error($text{'recs_ecannottype'});
 
index a60513d..dced296 100755 (executable)
@@ -167,10 +167,11 @@ for($i=0; $i<@_; $i++) {
                }
        local @cols;
        $name = &html_escape($name);
+       $id = &record_id($r);
        if (!$access{'ro'} && $type eq 'master') {
                push(@cols, 
                      "<a href=\"edit_record.cgi?index=".
-                     "$in{'index'}&type=$in{'type'}&num=$r->{'num'}&".
+                     "$in{'index'}&id=$id&num=$r->{'num'}&type=$in{'type'}&".
                      "sort=$in{'sort'}&view=$in{'view'}\">$name</a>");
                }
        else {
@@ -225,7 +226,7 @@ for($i=0; $i<@_; $i++) {
                }
        if (!$access{'ro'} && $type eq 'master') {
                $rv .= &ui_checked_columns_row(\@cols, \@tds,
-                                             "d", $r->{'num'});
+                                             "d", $r->{'num'}."/".$id);
                }
        else {
                $rv .= &ui_columns_row(\@cols, \@tds);
index 99859cb..3b623c1 100644 (file)
@@ -238,6 +238,7 @@ edit_uprev=Update reverse?
 edit_over=Yes (and replace existing)
 edit_upfwd=Update forward?
 edit_err=Failed to save record
+edit_egone=Selected record no longer exists!
 edit_ettl='$1' is not a valid time-to-live
 edit_eip='$1' is not a valid IP address
 edit_eip6='$1' is not a valid IPv6 address
index 6605169..2c9ec0e 100755 (executable)
@@ -854,5 +854,33 @@ foreach my $r (@$recs) {
 return undef;
 }
 
+# record_id(&r)
+# Returns a unique ID string for a record, based on the name and value
+sub record_id
+{
+my ($r) = @_;
+return $r->{'name'}."/".$r->{'type'}.
+       (uc($r->{'type'}) eq 'SOA' ? '' : '/'.join('/', @{$r->{'values'}}));
+}
+
+# find_record_by_id(&recs, id, index)
+# Find a record by ID and possibly index
+sub find_record_by_id
+{
+my ($recs, $id, $num) = @_;
+my @rv = grep { &record_id($_) eq $id } @$recs;
+if (!@rv) {
+       return undef;
+       }
+elsif (@rv == 1) {
+       return $rv[0];
+       }
+else {
+       # Multiple matches .. find the one with the right index
+       @rv = grep { $_->{'num'} == $num } @rv;
+       return @rv ? $rv[0] : undef;
+       }
+}
+
 1;
 
index 65bcf50..9d7b321 100755 (executable)
@@ -27,7 +27,10 @@ else {
        }
 
 # get the old record if needed
-$r = $recs[$in{'num'}] if (defined($in{'num'}));
+if (defined($in{'num'})) {
+       $r = &find_record_by_id(\@recs, $in{'id'}, $in{'num'});
+       $r || &error($text{'edit_egone'});
+       }
 
 # check for deletion
 if ($in{'delete'}) {
@@ -540,7 +543,8 @@ else {
 &unlock_all_files();
 $r->{'newvalues'} = $vals;
 &webmin_log($in{'new'} ? 'create' : 'modify', 'record', $in{'origin'}, $r);
-&redirect("edit_recs.cgi?index=$in{'index'}&view=$in{'view'}&type=$in{'redirtype'}&sort=$in{'sort'}");
+&redirect("edit_recs.cgi?index=$in{'index'}&view=$in{'view'}&".
+         "type=$in{'redirtype'}&sort=$in{'sort'}");
 
 # valname(name)
 sub valname