Converted buttons on the module's main page to use the Webmin UI library.
Expired leases are no longer counted towards usage on the DHCP Leases page.
Added a mode to the DHCP Leases page to show usage by subnet, thanks to a suggestion by Coles.
+When applying the configuration fails with an error mentioning a line in the config file, 10 lines around that will also be displayed by Webmin in the error.
{
if ($in{'r_sub'} < $in{'w_sub'} || $in{'r_sha'} < $in{'w_sha'} ||
$in{'r_hst'} < $in{'w_hst'} || $in{'r_grp'} < $in{'w_grp'}) {
- $whatfailed = $text{'acl_err'};
&error($text{'acl_ernow'});
}
$_[0]->{'apply'}=$in{'apply'};
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
@host = &find("host", $par->{'members'});
@group = &find("group", $par->{'members'});
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
if ($to_del->{'name'} eq "group") {
&error("$text{'eacl_np'} $text{'eacl_pdg'}")
if !&can('rw', \%access, $to_del, 1);
&ReadParse();
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
if( !($access{'w_leases'} && $access{'r_leases'}) ) {
&error("$text{'eacl_np'} $text{'eacl_pdl'}");
}
if ($config{'restart_cmd'}) {
# Run the restart script
$out = &backquote_logged("$config{'restart_cmd'} 2>&1");
- return "<pre>$out</pre>" if ($?);
}
else {
# Kill and re-run the server
else {
$out = &backquote_logged("$config{'dhcpd_path'} -cf $config{'dhcpd_conf'} -lf $config{'lease_file'} $config{'interfaces'} 2>&1");
}
- return "<pre>$out</pre>" if ($?);
+ }
+if ($?) {
+ return &parse_error_out($out);
}
return undef;
}
+# Find and add config file lines around those in an error message
+sub parse_error_out
+{
+local ($out) = @_;
+local $conftext;
+if ($out =~ /(\S+)\s+line\s+(\d+):/) {
+ local ($file, $line) = ($1, $2);
+ local $lref = &read_file_lines($file, 1);
+ local $start = $line - 5;
+ local $end = $line + 5;
+ $start = 0 if ($start < 0);
+ $end = @$lref-1 if ($end > @$lref-1);
+ $conftext = &text('restart_conftext', $line, $file)."<br>".
+ "<pre>".&html_escape(join("\n", @$lref[$start .. $end]))."</pre>";
+ }
+return "<pre>".&html_escape($out)."</pre>".$conftext;
+}
+
# stop_dhcpd()
# Stop the running DHCP server. Returns undef on success, or an error message
# on failure.
$out = &backquote_logged("$config{'dhcpd_path'} -cf $config{'dhcpd_conf'} -lf $config{'lease_file'} $config{'interfaces'} 2>&1");
}
if ($? || $out =~ /error|failed/i) {
- return "<pre>$out</pre>";
+ return &parse_error_out($out);
}
else {
return undef;
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
if ($in{'new'}) {
&error("$text{'eacl_np'} $text{'eacl_pig'}")
unless &can('c', \%access, $group) && &can('rw', \%access, $par);
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
if ($in{'new'} ) {
&error("$text{'eacl_np'} $text{'eacl_pih'}")
unless &can('c', \%access, $host) && &can('rw', \%access, $par);
# check acls
# %access = &get_module_acl();
-# &error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+# &error_setup($text{'eacl_aviol'});
# &error("$text{'eacl_np'} $text{'eacl_pss'}") if !&can('r',\%access,$sub);
if ($in{'new'}) {
$conf = &get_config();
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
$client = &get_parent_config();
push(@parents, $client);
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
&error("$text{'eacl_np'} $text{'eacl_pss'}") if !&can('r',\%access,$sub);
# display
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
if ($in{'new'} ) {
&error("$text{'eacl_np'} $text{'eacl_pin'}")
unless &can('c', \%access, $sha) && &can('rw', \%access, $par);
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
if ($in{'new'}) {
&error("$text{'eacl_np'} $text{'eacl_pis'}")
unless &can('c', \%access, $sub) && &can('rw', \%access, $par);
restart_errmsg1=Failed to restart dhcpd
restart_errmsg2=Failed to signal process
start_failstart=Failed to start dhcpd
+restart_conftext=Lines around $1 in $2 :
sgroup_faildel=Failed to delete group
sgroup_failsave=Failed to save group
$timenow = time();
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
&error("$text{'eacl_np'} $text{'eacl_psl'}") unless $access{'r_leases'};
if ($in{'network'}) {
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
if ($in{'delete'}) {
&error("$text{'eacl_np'} $text{'eacl_pdg'}")
if !&can('rw', \%access, $group, 1);
exit;
}
else {
- $whatfailed = $in{'delete'} ? $text{'sgroup_faildel'} :
- $text{'sgroup_failsave'};
+ &error_setup($in{'delete'} ? $text{'sgroup_faildel'} :
+ $text{'sgroup_failsave'});
# Move hosts into or out of this group
@wasin = &find("host", $group->{'members'});
}
}
- $whatfailed = "<blink><font color=red>$text{'eacl_aviol'}</font></blink>";
+ &error_setup($text{'eacl_aviol'});
foreach $h (&unique(@wasin, @nowin)) {
$was = &indexof($h, @wasin) != -1;
$now = &indexof($h, @nowin) != -1;
$group->{'comment'} = $in{'desc'};
&parse_params($group, $indent+1);
- $whatfailed = $text{'sgroup_failsave'};
+ &error_setup($text{'sgroup_failsave'});
@partypes = ( "", "shared-network", "subnet" );
if (!$npar || $in{'assign'} > 0 && $npar->{'name'} ne $partypes[$in{'assign'}]) {
if ($in{'jsquirk'}) {
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
if ($in{'delete'}) {
&error("$text{'eacl_np'} $text{'eacl_pdh'}")
if !&can('rw', \%access, $host, 1);
# save
if ($in{'delete'}) {
# Delete this host
- $whatfailed = $text{'shost_faildel'};
+ &error_setup($text{'shost_faildel'});
&save_directive($par, [ $host ], [ ], 0);
&drop_dhcpd_acl('hst', \%access, $host->{'values'}->[0]);
}
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
if ($client->{'name'} eq 'subnet') {
&error("$text{'eacl_np'} $text{'eacl_pus'}")
if !&can('rw', \%access, $client);
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
&error("$text{'eacl_np'} $text{'eacl_pus'}") if !&can('rw', \%access, $sub);
# save
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
if ($in{'delete'}) {
&error("$text{'eacl_np'} $text{'eacl_pdn'}")
if !&can('rw', \%access, $sha, 1);
}
else {
if ($in{'delete'}) {
- $whatfailed = $text{'sshared_faildel'};
+ &error_setup($text{'sshared_faildel'});
}
else {
- $whatfailed = $text{'sshared_failsave'};
+ &error_setup($text{'sshared_failsave'});
$in{'name'} =~ /^\S+$/ ||
&error($text{'sshared_invalidsname'});
$sha->{'values'} = [ $in{'name'} ];
}
}
- $whatfailed = "<blink><font color=red>$text{'eacl_aviol'}</font></blink>";
+ &error_setup($text{'eacl_aviol'});
foreach $h (&unique(@wasin, @nowin)) {
$was = &indexof($h, @wasin) != -1;
$now = &indexof($h, @nowin) != -1;
local(@subnets);
@subnets = &find("subnet", $_[0]->{'members'});
if (@subnets == 0) {
- $whatfailed = $text{'sshared_failsave'};
+ &error_setup($text{'sshared_failsave'});
&error(&text('sshared_nosubnet', $_[0]->{'values'}->[0]));
}
}
# check acls
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
if ($in{'delete'}) {
&error("$text{'eacl_np'} $text{'eacl_pds'}")
if !&can('rw', \%access, $sub, 1);
}
else {
if ($in{'delete'}) {
- $whatfailed = $text{'ssub_faildel'};
+ &error_setup($text{'ssub_faildel'});
if ($par->{'name'} eq "shared-network") {
@subnets = &find("subnet", $par->{'members'});
if (@subnets < 2) {
}
}
else {
- $whatfailed = $text{'ssub_failsave'};
+ &error_setup($text{'ssub_failsave'});
# Validate and save inputs
gethostbyname($in{'network'}) || &check_ipaddress($in{'network'}) ||
&error("'$in{'network'}' $text{'ssub_invalidsubaddr'}");
}
}
- $whatfailed = "<blink><font color=red>$text{'eacl_aviol'}</font></blink>";
+ &error_setup($text{'eacl_aviol'});
foreach $h (&unique(@wasin, @nowin)) {
$was = &indexof($h, @wasin) != -1;
$now = &indexof($h, @nowin) != -1;
}
if (!$in{'delete'}) {
- $whatfailed = $text{'ssub_failsave'};
+ &error_setup($text{'ssub_failsave'});
for($i=0; defined($low = $in{"range_low_$i"}); $i++) {
next if (!$low);
$hi = $in{"range_hi_$i"}; $dyn = $in{"range_dyn_$i"};
#!/usr/local/bin/perl
# start.cgi
# Attempt to start dhcpd
+
require './dhcpd-lib.pl';
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
&error("$text{'eacl_np'} $text{'eacl_papply'}") unless $access{'apply'};
-$whatfailed = $text{'start_failstart'};
+&error_setup($text{'start_failstart'});
$err = &start_dhcpd();
&error($err) if ($err);
&webmin_log("start");
require './dhcpd-lib.pl';
%access = &get_module_acl();
-&error_setup("<blink><font color=red>$text{'eacl_aviol'}</font></blink>");
+&error_setup($text{'eacl_aviol'});
&error("$text{'eacl_np'} $text{'eacl_papply'}") unless $access{'apply'};
-$whatfailed = $text{'stop_err'};
+&error_setup($text{'stop_err'});
$err = &stop_dhcpd();
&error($err) if ($err);
&webmin_log("stop");