Started work on new API to manage directive blocks

This commit is contained in:
Jamie Cameron
2007-11-02 23:30:41 +00:00
parent acfebb7105
commit 5526f469e7
2 changed files with 78 additions and 15 deletions

View File

@@ -446,7 +446,7 @@ close(HTACCESS);
return \@conf;
}
# save_directive(name, &values, &directives, &config)
# save_directive(name, &values, &parent-directives, &config)
# Updates the config file(s) and the directives structure with new values
# for the given directives.
# If a directive's value is merely being changed, then its value only needs
@@ -520,6 +520,56 @@ for($i=0; $i<@old || $i<@{$_[1]}; $i++) {
}
}
# save_directive_struct(&old-directive, &directive, &parent-directives,
# &config, firstline-only)
# Updates, creates or removes only multi-line directive like a <virtualhost>
sub save_directive_struct
{
local ($olddir, $newdir, $pconf, $conf, $first) = @_;
return if (!$olddir && !$newdir); # Nothing to do
local $file = $olddir ? $olddir->{'file'} :
$newdir->{'file'} ? $newdir->{'file'} : $pconf->[0]->{'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) {
# 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);
}
elsif ($olddir && !$newdir) {
# Remove
splice(@$lref, $olddir->{'line'}, $oldlen);
local $idx = &indexof($olddir, @$pconf);
splice(@$pconf, $idx, 1) if ($idx >= 0);
&renumber($conf, $olddir->{'line'}, $olddir->{'file'}, -$oldlen);
}
elsif (!$olddir && $newdir) {
# Add to file, at end of specific file or parent section
local ($addline, $addpos);
if ($newdir->{'file'}) {
$addline = scalar(@$lref);
$addpos = scalar(@$pconf);
}
else {
for($addpos=0; $pconf->[$addpos]->{'file'} eq $file;$addpos++) {
# Find last parent directive in same file
}
$addline = $pconf->[$addpos]->{'eline'}+1;
}
$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);
}
}
# renumber(&config, line, file, offset)
# Recursively changes the line number of all directives from some file
# beyond the given line.

View File

@@ -15,7 +15,6 @@ if ($in{'clone'} ne '') {
$_->{'name'} ne 'Port' &&
$_->{'name'} ne 'DocumentRoot' &&
$_->{'name'} ne 'ServerAlias' } @{$clone->{'members'}};
@clines = &directive_lines(@cmems);
}
# Parse and find the specified address to listen on
@@ -189,33 +188,47 @@ foreach $a (@addrs) {
}
}
# Write out the file
$lref = &read_file_lines($f);
push(@$lref, "");
# Create the structure
if (@addrs) {
$ap = join(" ", map { $_.$port } @addrs);
}
else {
$ap = $addr.$port;
}
push(@$lref, "<VirtualHost $ap>");
push(@$lref, "DocumentRoot \"$in{'root'}\"") if ($in{'root'});
@mems = ( );
$virt = { 'name' => 'VirtualHost',
'value' => $ap,
'file' => $f,
'type' => 1,
'members' => \@mems };
push(@mems, { 'name' => 'DocumentRoot',
'value' => "\"$in{'root'}\"" }) if ($in{'root'});
if (@names) {
push(@$lref, "ServerName $names[0]");
push(@mems, { 'name' => 'ServerName',
'value' => $names[0] });
shift(@names);
foreach $sa (@names) {
push(@$lref, "ServerAlias $sa");
push(@mems, { 'name' => 'ServerAlias',
'value' => $sa });
}
}
push(@$lref, @clines);
push(@mems, @cmems);
if ($in{'adddir'} && $in{'root'}) {
# Add a <Directory> section for the root
push(@$lref, "<Directory \"$in{'root'}\">");
push(@$lref, "allow from all");
push(@$lref, "Options +Indexes");
push(@$lref, "</Directory>");
push(@mems, { 'name' => 'Directory',
'value' => "\"$in{'root'}\"",
'type' => 1,
'members' => [
{ 'name' => 'allow',
'value' => 'from all' },
{ 'name' => 'Options',
'value' => '+Indexes' },
] });
}
push(@$lref, "</VirtualHost>");
# Save to the file
&save_directive_struct(undef, $virt, $conf, $conf);
&flush_file_lines();
&unlock_file($f);
&unlock_apache_files();