diff --git a/syslog-ng/save_destination.cgi b/syslog-ng/save_destination.cgi index 4d56c8bcd..9ddc0dd3c 100755 --- a/syslog-ng/save_destination.cgi +++ b/syslog-ng/save_destination.cgi @@ -19,7 +19,7 @@ else { 'members' => [ ] }; } -&lock_file($config{'syslogng_conf'}); +&lock_all_files($conf); if ($in{'delete'}) { # Just delete it! &check_dependencies('destination', $in{'old'}) && @@ -174,7 +174,7 @@ else { } } -&unlock_file($config{'syslogng_conf'}); +&unlock_all_files(); &webmin_log($in{'delete'} ? 'delete' : $in{'new'} ? 'create' : 'modify', 'destination', $in{'old'} || $in{'name'}); &redirect("list_destinations.cgi"); diff --git a/syslog-ng/save_filter.cgi b/syslog-ng/save_filter.cgi index d3ebef4f9..0da3816dc 100755 --- a/syslog-ng/save_filter.cgi +++ b/syslog-ng/save_filter.cgi @@ -19,7 +19,7 @@ else { 'members' => [ ] }; } -&lock_file($config{'syslogng_conf'}); +&lock_all_files($conf); if ($in{'delete'}) { # Just delete it! &check_dependencies('filter', $in{'old'}) && @@ -133,7 +133,7 @@ else { } } -&unlock_file($config{'syslogng_conf'}); +&unlock_all_files(); &webmin_log($in{'delete'} ? 'delete' : $in{'new'} ? 'create' : 'modify', 'filter', $in{'old'} || $in{'name'}); &redirect("list_filters.cgi"); diff --git a/syslog-ng/save_log.cgi b/syslog-ng/save_log.cgi index 0168568d2..df43e8bef 100755 --- a/syslog-ng/save_log.cgi +++ b/syslog-ng/save_log.cgi @@ -19,7 +19,7 @@ else { 'members' => [ ] }; } -&lock_file($config{'syslogng_conf'}); +&lock_all_files($conf); if ($in{'delete'}) { # Just delete it! &save_directive($conf, undef, $log, undef, 0); @@ -73,7 +73,7 @@ else { &save_directive($conf, undef, $old, $log, 0); } -&unlock_file($config{'syslogng_conf'}); +&unlock_all_files(); &webmin_log($in{'delete'} ? 'delete' : $in{'new'} ? 'create' : 'modify', 'log'); &redirect("list_logs.cgi"); diff --git a/syslog-ng/save_options.cgi b/syslog-ng/save_options.cgi index 36ef06a34..4f14f5b2c 100755 --- a/syslog-ng/save_options.cgi +++ b/syslog-ng/save_options.cgi @@ -43,9 +43,9 @@ $mems = $options->{'members'}; &save_yesno_option("sanitize_filenames"); # Write out options section -&lock_file($config{'syslogng_conf'}); +&lock_all_files($conf); &save_directive($conf, undef, "options", $options, 0); -&unlock_file($config{'syslogng_conf'}); +&unlock_all_files(); &webmin_log("options"); &redirect(""); diff --git a/syslog-ng/save_source.cgi b/syslog-ng/save_source.cgi index 25514f77a..eb540642c 100755 --- a/syslog-ng/save_source.cgi +++ b/syslog-ng/save_source.cgi @@ -19,7 +19,7 @@ else { 'members' => [ ] }; } -&lock_file($config{'syslogng_conf'}); +&lock_all_files($conf); if ($in{'delete'}) { # Just delete it! &check_dependencies('source', $in{'old'}) && @@ -229,7 +229,7 @@ else { } } -&unlock_file($config{'syslogng_conf'}); +&unlock_all_files(); &webmin_log($in{'delete'} ? 'delete' : $in{'new'} ? 'create' : 'modify', 'source', $in{'old'} || $in{'name'}); &redirect("list_sources.cgi"); diff --git a/syslog-ng/syslog-ng-lib.pl b/syslog-ng/syslog-ng-lib.pl index 28b7e238e..c0fa58fdf 100755 --- a/syslog-ng/syslog-ng-lib.pl +++ b/syslog-ng/syslog-ng-lib.pl @@ -36,17 +36,30 @@ sub read_config_file { local ($file) = @_; local (@rv, @tok, @ltok, @lnum); -&open_readfile(CONF, $file); -local $lnum = 0; +local $lref = &read_file_lines($file, 1); local $cmode; -while($line = ) { +local @allincs; +for(my $lnum=0; $lnum<@$lref; $lnum++) { # strip comments + my $line = $lref->[$lnum]; $line =~ s/\r|\n//g; $line =~ s/#.*$//g; # Remove hash comment $line =~ s/\/\/.*$//g if ($line !~ /".*\/\/.*"/); $line =~ s/\/\*.*\*\///g; # Remove multi-line comment - $line =~ s/^\s*@.*$//g; # Remove @version line - next if ($line =~ /^\s*include\s.*/); + if ($line =~ /^\@include\s+"(.*)"/) { + # Found an include .. replace with contents of the file(s) + local $incs = $1; + if ($incs !~ /^\//) { + $file =~ /^(.*)\//; + $incs = $1."/".$incs; + } + foreach my $inc (glob($incs)) { + push(@allincs, &read_config_file($inc)); + } + $lnum++; + next; + } + $line =~ s/^\s*@.*$//g; # Remove lines like @version while(1) { if (!$cmode && $line =~ /\/\*/) { # start of a C-style comment @@ -97,7 +110,6 @@ while($line = ) { push(@tok, $t); push(@lnum, $lnum); } - $lnum++; } # parse tokens into data structures @@ -109,7 +121,7 @@ while($i < @tok) { push(@rv, $str); } } -close(CONF); +push(@rv, @allincs); return @rv; } @@ -242,8 +254,6 @@ local $new = !$value ? undef : ref($value) ? $value : 'type' => 0 }; # Read the config file and work out the lines used -local $lref; -$lref = &read_file_lines($config{'syslogng_conf'}) if (!$nowrite); local ($mems, $memseline); if ($parent) { $mems = $parent->{'members'}; @@ -263,6 +273,10 @@ if ($old) { $idx >= 0 || &error("Failed to find $old in array of ",scalar(@$mems)); $oldlen = $old->{'eline'} - $old->{'line'} + 1; } +local $file = $old ? $old->{'file'} : + $parent ? $parent->{'file'} : + $config{'syslogng_conf'}; +local $lref = $nowrite ? undef : &read_file_lines($file); if ($new) { @lines = &directive_lines($new); $newlen = scalar(@lines); @@ -279,7 +293,7 @@ if ($old && $new) { } if (!$nowrite) { # Update it in the file - &renumber($conf, $new->{'line'}, $newlen - $oldlen); + &renumber($conf, $new->{'line'}, $newlen - $oldlen, $file); splice(@$lref, $old->{'line'}, $oldlen, @lines); } $mems[$idx] = $new; @@ -289,7 +303,7 @@ elsif ($old && !$new) { splice(@$mems, $idx, 1); if (!$nowrite) { # Remove from the file - &renumber($conf, $old->{'line'}, -$oldlen); + &renumber($conf, $old->{'line'}, -$oldlen, $file); splice(@$lref, $old->{'line'}, $oldlen); } } @@ -304,7 +318,9 @@ elsif (!$old && $new) { } push(@$mems, $new); } -&flush_file_lines($config{'syslogng_conf'}) if (!$nowrite); +if (!$nowrite) { + &flush_file_lines($file); + } } # save_multiple_directives(&conf, &parent, &oldlist, &newlist, no-write) @@ -319,15 +335,17 @@ for(my $i=0; $i<@$oldlist || $i<@$newlist; $i++) { } } -# renumber(&conf, line, offset) -# Changes the line numbers of all directives AFTER the given line +# renumber(&conf, line, offset, file) +# Changes the line numbers of all directives AFTER the given line in the file sub renumber { -local ($conf, $line, $offset) = @_; +local ($conf, $line, $offset, $file) = @_; foreach my $c (@$conf) { - $c->{'line'} += $offset if ($c->{'line'} > $line); - $c->{'eline'} += $offset if ($c->{'eline'} > $line); - &renumber($c->{'members'}, $line, $offset) if ($c->{'members'}); + $c->{'line'} += $offset + if ($c->{'file'} eq $file && $c->{'line'} > $line); + $c->{'eline'} += $offset + if ($c->{'file'} eq $file && $c->{'eline'} > $line); + &renumber($c->{'members'}, $line, $offset, $file) if ($c->{'members'}); } } @@ -554,7 +572,7 @@ return @rv; sub rename_dependencies { local ($type, $oldname, $newname) = @_; -#return if ($oldname eq $newname); +return if ($oldname eq $newname); local $conf = &get_config(); local @logs = &find("log", $conf); local @rv; @@ -564,7 +582,6 @@ foreach my $l (@logs) { foreach my $d (@deps) { if ($d->{'value'} eq $oldname) { $d->{'values'} = [ $newname ]; - #&save_directive($conf, $l, $d, $d, 1); $changed = 1; } } @@ -776,5 +793,27 @@ foreach my $l (@rv) { return @rv; } +# lock_all_files([&config]) +# Takes a lock on all config files +sub lock_all_files +{ +my ($conf) = @_; +$conf ||= &get_config(); +@all_locked_files = &unique(map { $_->{'file'} } @$conf); +foreach my $f (@all_locked_files) { + &lock_file($f); + } +} + +# unlock_all_files() +# Releases all config locks +sub unlock_all_files +{ +foreach my $f (@all_locked_files) { + &unlock_file($f); + } +@all_locked_files = ( ); +} + 1;