From 5526f469e76f5808b785da6cfabc038f9d64fafc Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Fri, 2 Nov 2007 23:30:41 +0000 Subject: [PATCH] Started work on new API to manage directive blocks --- apache/apache-lib.pl | 52 +++++++++++++++++++++++++++++++++++++++++- apache/create_virt.cgi | 41 +++++++++++++++++++++------------ 2 files changed, 78 insertions(+), 15 deletions(-) diff --git a/apache/apache-lib.pl b/apache/apache-lib.pl index 7d8b8928c..ca087a400 100644 --- a/apache/apache-lib.pl +++ b/apache/apache-lib.pl @@ -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 +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. diff --git a/apache/create_virt.cgi b/apache/create_virt.cgi index 5ad7c8c9a..cf7521dcf 100755 --- a/apache/create_virt.cgi +++ b/apache/create_virt.cgi @@ -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, ""); -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 section for the root - push(@$lref, ""); - push(@$lref, "allow from all"); - push(@$lref, "Options +Indexes"); - push(@$lref, ""); + push(@mems, { 'name' => 'Directory', + 'value' => "\"$in{'root'}\"", + 'type' => 1, + 'members' => [ + { 'name' => 'allow', + 'value' => 'from all' }, + { 'name' => 'Options', + 'value' => '+Indexes' }, + ] }); } -push(@$lref, ""); + +# Save to the file +&save_directive_struct(undef, $virt, $conf, $conf); &flush_file_lines(); &unlock_file($f); &unlock_apache_files();