diff --git a/net/netplan-lib.pl b/net/netplan-lib.pl index edd7e0bc4..b0287261e 100644 --- a/net/netplan-lib.pl +++ b/net/netplan-lib.pl @@ -586,44 +586,71 @@ foreach my $origl (@$lref) { if ($l =~ /^(\s*)(\S+):\s*(.*)/) { # Name and possibly value my $i = length($1); - my $dir = { 'indent' => length($1), - 'name' => $2, - 'value' => $3, - 'line' => $lnum, - 'eline' => $lnum, - 'parent' => $parent, - 'members' => [], - }; - if ($dir->{'value'} =~ /^\[(.*)\]$/) { - $dir->{'value'} = [ &split_addr_list("$1") ]; + if ($i > $lastdir->{'indent'} + 2 && + ref($lastdir->{'value'}) eq 'ARRAY' && + @{$lastdir->{'value'}} && + ref($lastdir->{'value'}->[0]) eq 'HASH') { + # Another key in the current value hash + my $v = $lastdir->{'value'}; + $v->[@$v-1]->{$2} = $3; + &set_parent_elines($lastdir, $lnum); } - if (!$lastdir || $i == $lastdir->{'indent'}) { - # At same level as previous directive, which puts it - # underneath current parent - push(@{$parent->{'members'}}, $dir); - } - elsif ($i > $lastdir->{'indent'}) { - # A further ident by one level, meaning that it is under - # the previous directive - $parent = $lastdir; - $dir->{'parent'} = $parent; - push(@{$parent->{'members'}}, $dir); - } - elsif ($i < $lastdir->{'indent'}) { - # Indent has decreased, so this must be under a previous - # parent directive - $parent = $parent->{'parent'}; - while($i <= $parent->{'indent'}) { - $parent = $parent->{'parent'}; + else { + # A regular directive + my $dir = { 'indent' => length($1), + 'name' => $2, + 'value' => $3, + 'line' => $lnum, + 'eline' => $lnum, + 'parent' => $parent, + 'members' => [], + }; + if ($dir->{'value'} =~ /^\[(.*)\]$/) { + $dir->{'value'} = [ &split_addr_list("$1") ]; } - push(@{$parent->{'members'}}, $dir); - $dir->{'parent'} = $parent; + if (!$lastdir || $i == $lastdir->{'indent'}) { + # At same level as previous directive, which + # puts it underneath current parent + push(@{$parent->{'members'}}, $dir); + } + elsif ($i > $lastdir->{'indent'}) { + # A further ident by one level, meaning that it + # is under the previous directive + $parent = $lastdir; + $dir->{'parent'} = $parent; + push(@{$parent->{'members'}}, $dir); + } + elsif ($i < $lastdir->{'indent'}) { + # Indent has decreased, so this must be under a + # previous parent directive + $parent = $parent->{'parent'}; + while($i <= $parent->{'indent'}) { + $parent = $parent->{'parent'}; + } + push(@{$parent->{'members'}}, $dir); + $dir->{'parent'} = $parent; + } + $lastdir = $dir; + &set_parent_elines($parent, $lnum); } - $lastdir = $dir; + } + elsif ($l =~ /^(\s*)\-\s*(\S+):\s*(\S.*)$/) { + # Value that is itself a key-value pair + # routes: + # - to: 1.2.3.4/24 + # via: 1.2.3.1 + # metric: 100 + $lastdir->{'value'} ||= [ ]; + my $v = { $2 => $3 }; + push(@{$lastdir->{'value'}}, $v); + $lastdir->{'eline'} = $lnum; &set_parent_elines($parent, $lnum); } elsif ($l =~ /^(\s*)\-\s*(\S+)\s*$/) { # Value-only line that is an extra value for the previous dir + # addresses: + # - 1.2.3.4/24 + # - 5.6.7.8/24 $lastdir->{'value'} ||= [ ]; $lastdir->{'value'} = [ $lastdir->{'value'} ] if (!ref($lastdir->{'value'})); push(@{$lastdir->{'value'}}, $2); @@ -650,14 +677,37 @@ foreach my $c (@$conf) { } # yaml_lines(&directive, indent-string) +# Converts a YAML directive into text lines sub yaml_lines { my ($yaml, $id) = @_; my @rv; -push(@rv, $id.$yaml->{'name'}.":". - (ref($yaml->{'value'}) eq 'ARRAY' ? - " [".&join_addr_list(@{$yaml->{'value'}})."]" : - defined($yaml->{'value'}) ? " ".$yaml->{'value'} : "")); +my $v = $id.$yaml->{'name'}.":"; +if (ref($yaml->{'value'}) eq 'ARRAY') { + my @a = @{$yaml->{'value'}}; + if (@a && ref($a[0]) eq 'HASH') { + # Array of hashes, like for routes + push(@rv, $v); + foreach my $a (@a) { + my @k = sort(keys %$a); + my $f = shift(@k); + push(@rv, $id." - ".$f.": ".$a->{$f}); + foreach my $f (@k) { + push(@rv, $id." ".$f.": ".$a->{$f}); + } + } + } + else { + # Array of strings + push(@rv, $v." [".&join_addr_list(@a)."]"); + } + } +elsif (defined($yaml->{'value'})) { + push(@rv, $v." ".$yaml->{'value'}); + } +else { + push(@rv, $v); + } if ($yaml->{'members'}) { foreach my $m (@{$yaml->{'members'}}) { push(@rv, &yaml_lines($m, $id." ")); diff --git a/net/save_bifc.cgi b/net/save_bifc.cgi index bd1764fd9..c2b1c91a3 100755 --- a/net/save_bifc.cgi +++ b/net/save_bifc.cgi @@ -188,6 +188,9 @@ else { $b->{'broadcast'} = &compute_broadcast( $b->{'address'}, $b->{'netmask'}); } + else { + $b->{'broadcast'} = undef; + } } elsif (&can_edit("broadcast", $b)) { # Manually entered broadcast diff --git a/web-lib-funcs.pl b/web-lib-funcs.pl index f218f91ae..1ebf11e3c 100755 --- a/web-lib-funcs.pl +++ b/web-lib-funcs.pl @@ -2126,6 +2126,7 @@ if ($main::webmin_script_type eq 'web' && !$ENV{"MINISERV_CONFIG"} && } my $i; +my $flag = $miniserv{'restartflag'} || $var_directory."/restart-flag"; if ($gconfig{'os_type'} ne 'windows') { # On Unix systems, we can restart with a signal my ($pid, $addr, $i); @@ -2152,10 +2153,13 @@ if ($gconfig{'os_type'} ne 'windows') { } } - # Just signal miniserv to restart + # Just signal miniserv to restart, and also create the flag file in + # case signals aren't being processed if (!&kill_logged('HUP', $pid)) { &error("Incorrect Webmin PID $pid") if (!$ignore); } + open(TOUCH, ">$flag"); + close(TOUCH); # Wait till new PID is written, indicating a restart for($i=0; $i<60; $i++) { @@ -2172,7 +2176,7 @@ if ($gconfig{'os_type'} ne 'windows') { } else { # On Windows, we need to use the flag file - open(TOUCH, ">$miniserv{'restartflag'}"); + open(TOUCH, ">$flag"); close(TOUCH); } diff --git a/webmin/webmin-lib.pl b/webmin/webmin-lib.pl index 1fdcdb799..30447b3dd 100755 --- a/webmin/webmin-lib.pl +++ b/webmin/webmin-lib.pl @@ -1618,7 +1618,7 @@ sub prefix_to_mask { return $_[0] >= 24 ? "255.255.255.".(256-(2 ** (32-$_[0]))) : $_[0] >= 16 ? "255.255.".(256-(2 ** (24-$_[0]))).".0" : - $_[0] >= 16 ? "255.".(256-(2 ** (16-$_[0]))).".0.0" : + $_[0] >= 8 ? "255.".(256-(2 ** (16-$_[0]))).".0.0" : (256-(2 ** (8-$_[0]))).".0.0.0"; }