More structure update support

This commit is contained in:
Jamie Cameron
2007-11-03 00:31:04 +00:00
parent 5526f469e7
commit ade41db897
3 changed files with 76 additions and 50 deletions

View File

@@ -521,7 +521,7 @@ for($i=0; $i<@old || $i<@{$_[1]}; $i++) {
}
# save_directive_struct(&old-directive, &directive, &parent-directives,
# &config, firstline-only)
# &config, [firstline-only])
# Updates, creates or removes only multi-line directive like a <virtualhost>
sub save_directive_struct
{
@@ -532,15 +532,31 @@ local $file = $olddir ? $olddir->{'file'} :
local $lref = &read_file_lines($file);
local $oldlen = $olddir ? $olddir->{'eline'}-$olddir->{'line'}+1 : undef;
local @newlines = $newdir ? &directive_lines($newdir) : ( );
if ($oldir && $newdir) {
if ($olddir && $newdir) {
# Update in place
&renumber($conf, $olddir->{'eline'}+1, $file,
scalar(@newlines)-$oldlen);
local $idx = &indexof($olddir, @$pconf);
$pconf->[$idx] = $newdir if ($idx >= 0);
$newdir->{'line'} = $oldir->{'line'};
$newdir->{'eline'} = $oldir->{'line'}+scalar(@newlines)-1;
splice(@$lref, $olddir->{'line'}, $oldlen, @newlines);
if ($first) {
# Just changing first line, like virtualhost IP
$lref->[$olddir->{'line'}] = $newlines[0];
$olddir->{'value'} = $newdir->{'value'};
}
else {
# Re-writing whole block
&renumber($conf, $olddir->{'eline'}+1, $file,
scalar(@newlines)-$oldlen);
local $idx = &indexof($olddir, @$pconf);
$pconf->[$idx] = $newdir if ($idx >= 0);
$newdir->{'file'} = $olddir->{'file'};
$newdir->{'line'} = $olddir->{'line'};
$newdir->{'eline'} = $olddir->{'line'}+scalar(@newlines)-1;
splice(@$lref, $olddir->{'line'}, $oldlen, @newlines);
# Update sub-directive lines and files too
if ($newdir->{'type'}) {
&recursive_set_lines_files($newdir->{'members'},
$newdir->{'line'}+1,
$newdir->{'file'});
}
}
}
elsif ($olddir && !$newdir) {
# Remove
@@ -562,14 +578,57 @@ elsif (!$olddir && $newdir) {
}
$addline = $pconf->[$addpos]->{'eline'}+1;
}
$newdir->{'file'} = $file;
$newdir->{'line'} = $addline;
$newdir->{'eline'} = $addline + scalar(@newlines) - 1;
&renumber($conf, $addline, $file, scalar(@newlines));
splice(@$pconf, $addpos, 0, $newdir);
splice(@$lref, $addline, 0, @newlines);
# Update sub-directive lines and files too
if ($newdir->{'type'}) {
&recursive_set_lines_files($newdir->{'members'},
$newdir->{'line'}+1,
$newdir->{'file'});
}
}
}
# recursive_set_lines_files(&directives, first-line, file)
# Update the line numbers and filenames in a list of directives
sub recursive_set_lines_files
{
local ($dirs, $line, $file) = @_;
foreach my $d (@$dirs) {
$dir->{'line'} = $line;
$dir->{'file'} = $file;
if ($dir->{'type'}) {
# Do sub-members too
&recursive_set_lines_files($dir->{'members'}, $line+1, $file);
$line += scalar(@{$dir->{'members'}})+1;
$dir->{'eline'} = $line;
}
else {
$dir->{'eline'} = $line;
}
$line++;
}
return $line;
}
# delete_file_if_empty(file)
# If a virtual host file is now empty, delete it (and any link to it)
sub delete_file_if_empty
{
local ($file) = @_;
local $lref = &read_file_lines($file);
foreach my $l (@$lref) {
return 0 if ($l =~ /\S/);
}
unlink($file);
&delete_webfile_link($file);
}
# renumber(&config, line, file, offset)
# Recursively changes the line number of all directives from some file
# beyond the given line.

View File

@@ -10,36 +10,19 @@ $conf = &get_config();
@d || &error($text{'delete_enone'});
# Get them all
foreach $d (sort { $b <=> $a } @d) {
foreach $d (@d) {
($vmembers, $vconf) = &get_virtual_config($d);
&can_edit_virt($vconf) || &error(&text('delete_ecannot2',
&virtual_name($vconf)));
push(@virts, $vconf);
}
# Take them out of their files
# Delete their structures
&before_changing();
foreach $vconf (@virts) {
&lock_file($vconf->{'file'});
$lref = &read_file_lines($vconf->{'file'});
if ($vconf->{'line'} && $lref->[$vconf->{'line'}-1] !~ /\S/) {
# Remove one blank line before vserv
$vconf->{'line'}--;
}
splice(@$lref, $vconf->{'line'},
$vconf->{'eline'} - $vconf->{'line'} + 1);
$nonblank = 0;
foreach $l (@$lref) {
$nonblank++ if ($l =~ /\S/);
}
&flush_file_lines();
if (!$nonblank) {
# Can lose the entire file
unlink($vconf->{'file'});
# Delete the link too
&delete_webfile_link($vconf->{'file'});
}
&save_directive_struct($vconf, undef, $conf, $conf);
&delete_file_if_empty($vconf->{'file'});
}
&unlock_all_files();
&after_changing();

View File

@@ -14,24 +14,8 @@ if ($in{'delete'}) {
%vnames = map { $_, 1 } &virt_acl_name($vconf);
&lock_file($vconf->{'file'});
&before_changing();
$lref = &read_file_lines($vconf->{'file'});
if ($vconf->{'line'} && $lref->[$vconf->{'line'}-1] !~ /\S/) {
# Remove one blank line before vserv
$vconf->{'line'}--;
}
splice(@$lref, $vconf->{'line'},
$vconf->{'eline'} - $vconf->{'line'} + 1);
foreach $l (@$lref) {
$nonblank++ if ($l =~ /\S/);
}
&flush_file_lines();
if (!$nonblank) {
# Can lose the entire file
unlink($vconf->{'file'});
# Delete the link too
&delete_webfile_link($vconf->{'file'});
}
&save_directive_struct($vconf, undef, $conf, $conf);
&delete_file_if_empty($virt->{'file'});
&unlock_file($vconf->{'file'});
&after_changing();
@@ -112,8 +96,8 @@ else {
# Update <VirtualHost> directive
&lock_file($vconf->{'file'});
&before_changing();
$lref = &read_file_lines($vconf->{'file'});
$lref->[$vconf->{'line'}] = "<VirtualHost $addr$port>";
$vconf->{'value'} = "$addr$port";
&save_directive_struct($vconf, $vconf, $conf, $conf, 1);
# Update DocumentRoot and ServerName
&save_directive("DocumentRoot", $root ? [ $root ] : [ ],