Fixed option ordering bug
authorJamie Cameron <jcameron@webmin.com>
Tue, 21 Oct 2008 06:37:11 +0000 (06:37 +0000)
committerJamie Cameron <jcameron@webmin.com>
Tue, 21 Oct 2008 06:37:11 +0000 (06:37 +0000)
dhcpd/CHANGELOG
dhcpd/dhcpd-lib.pl
dhcpd/save_options.cgi

index e83f69e..9b158d6 100644 (file)
@@ -23,3 +23,5 @@ Fixed a bug that causes hosts to be deleted when searching for them!
 Clashes between hosts with the same IP address, MAC address or hostname are no longer allowed by default - but this can be changed on the DHCP Server access control page in the Webmin User's module.
 ---- Changes since 1.420 ----
 Support the new configuration file format for custom options, as used in DHCPd version 3.
+---- Changes since 1.430 ----
+Fixed bug that can cause option definitions and values to be incorrectly ordered.
index 0749d9d..bb661bb 100755 (executable)
@@ -325,7 +325,7 @@ else {
        }
 }
 
-# save_directive(&parent, [name|&oldvalues], &values, indent, start)
+# save_directive(&parent, [name|&oldvalues], &values, indent, start, [after])
 # Given a structure containing a directive name, type, values and members
 # add, update or remove that directive in config structure and data files.
 # Updating of files assumes that there is no overlap between directives -
@@ -337,10 +337,28 @@ $pm = $_[0]->{'members'};
 @oldv = ref($_[1]) ? @{$_[1]} : &find($_[1], $pm);
 @newv = @{$_[2]};
 for($i=0; $i<@oldv || $i<@newv; $i++) {
-       if ($i >= @oldv && $_[4]) {
+       if ($i >= @oldv && $_[5]) {
+               # a new directive is being added.. put it after some other
+               $lref = $_[0]->{'file'} ? &read_file_lines($_[0]->{'file'})
+                                       : [ ];
+               @nl = &directive_lines($newv[$i], $_[3]);
+               $nline = $_[5]->{'line'}+1;
+               $nidx = &indexof($_[5], @$pm) + 1;
+               splice(@$lref, $nline, 0, @nl);
+               &renumber(&get_config(), $nline,
+                         $_[0]->{'file'}, scalar(@nl));
+               &renumber_index($_[0]->{'members'}, $nidx, 1);
+               $newv[$i]->{'index'} = $nidx;
+               $newv[$i]->{'file'} = $_[0]->{'file'};
+               $newv[$i]->{'line'} = $nline;
+               $newv[$i]->{'eline'} = $nline + scalar(@nl);
+               splice(@$pm, $nidx, 0, $newv[$i]);
+               }
+       elsif ($i >= @oldv && $_[4]) {
                # a new directive is being added.. put it at the start of
                # the parent
-               $lref = $_[0]->{'file'} ? &read_file_lines($_[0]->{'file'}) : [ ];
+               $lref = $_[0]->{'file'} ? &read_file_lines($_[0]->{'file'})
+                                       : [ ];
                @nl = &directive_lines($newv[$i], $_[3]);
                $nline = $_[0]->{'fline'}+1;
                splice(@$lref, $nline, 0, @nl);
@@ -377,6 +395,9 @@ for($i=0; $i<@oldv || $i<@newv; $i++) {
                }
        else {
                # updating some directive
+               if (!defined($newv[$i]->{'comment'})) {
+                       $newv[$i]->{'comment'} = $oldv[$i]->{'comment'};
+                       }
                $lref = $oldv[$i]->{'file'} ? &read_file_lines($oldv[$i]->{'file'}) : [ ];
                @nl = &directive_lines($newv[$i], $_[3]);
                $ol = $oldv[$i]->{'eline'} - $oldv[$i]->{'line'} + 1;
index 8910f43..d6c3718 100755 (executable)
@@ -106,6 +106,12 @@ if ($config{'dhcpd_version'} >= 3) {
                }
        &save_directive($client, \@defs, \@newdefs, $indent, 1);
 
+       # Find the last definition
+       $maxdef = undef;
+       foreach $d (@newdefs) {
+               $maxdef = $d if (!$maxdef || $d->{'line'} > $maxdef->{'line'});
+               }
+
        # Save custom options
        @custom = grep { $_->{'name'} eq 'option' &&
                         $optdef{$_->{'values'}->[0]} &&
@@ -120,7 +126,8 @@ if ($config{'dhcpd_version'} >= 3) {
                push(@newcustom, { 'name' => 'option',
                                   'values' => [ $in{"cname_$i"}, $cv ] } );
                }
-       &save_directive($client, \@custom, \@newcustom, $indent, 1);
+       &save_directive($client, \@custom, \@newcustom, $indent,
+                       $maxdef ? 0 : 1, $maxdef);
        }
 else {
        # Save custom options