summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-12-07 22:17:26 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2017-12-07 22:17:26 +0200
commit80da2c28a644a0640b8d167e31f28b43fc56a682 (patch)
treec1c7545065d3a81c93613b51483b50641fd84aaf
parent31a64151b3f675322eb8eadb8bae9887e0f82941 (diff)
downloadacpp-80da2c28a644a0640b8d167e31f28b43fc56a682.tar.gz
acpp-80da2c28a644a0640b8d167e31f28b43fc56a682.tar.bz2
Provide a way to pass arguments to the phase constructors
* Makefile.PL: Lower the required Perl version. Update prerequisites * lib/Apache/Config/Preproc.pm (new): Get rid of -server_root. Don't save filename along with options. (server_root): Remove. (_preproc): Handle optional arguments in the module list. (_preproc_section): Don't pass $self to expand. It should have been saved by new, if the need be. * lib/Apache/Config/Preproc/compact.pm (new): Update. * lib/Apache/Config/Preproc/ifmodule.pm (new): Update. New arguments: preloaded => [ list of loaded modules ], and probe => $val. * lib/Apache/Config/Preproc/include.pm (new): Optional argument server_root. (expand): Change signature. * lib/Apache/Config/Preproc/macro.pm (new, expand): Change signature.
-rw-r--r--Makefile.PL3
-rw-r--r--lib/Apache/Config/Preproc.pm65
-rw-r--r--lib/Apache/Config/Preproc/compact.pm4
-rw-r--r--lib/Apache/Config/Preproc/ifmodule.pm180
-rw-r--r--lib/Apache/Config/Preproc/include.pm29
-rw-r--r--lib/Apache/Config/Preproc/macro.pm4
6 files changed, 234 insertions, 51 deletions
diff --git a/Makefile.PL b/Makefile.PL
index f08c4f0..058045b 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -12,6 +12,7 @@ WriteMakefile(NAME => 'Apache::Config::Preproc',
'File::Spec' => '3.39_02',
'Text::ParseWords' => '3.27',
'File::Spec' => 0,
+ 'IPC::Open3' => 0
},
TEST_REQUIRES => {
'File::Basename' => 0,
@@ -20,7 +21,7 @@ WriteMakefile(NAME => 'Apache::Config::Preproc',
'Test' => 0,
'autodie' => 0
},
- MIN_PERL_VERSION => 5.016001,
+ MIN_PERL_VERSION => 5.014002,
META_MERGE => {
'meta-spec' => { version => 2 },
resources => {
diff --git a/lib/Apache/Config/Preproc.pm b/lib/Apache/Config/Preproc.pm
index 278519c..07cf61c 100644
--- a/lib/Apache/Config/Preproc.pm
+++ b/lib/Apache/Config/Preproc.pm
@@ -8,15 +8,13 @@ our $VERSION = '1.0';
sub new {
my $class = shift;
- my $server_root = Apache::Admin::Config::Tree::_get_arg(\@_,
- '-server_root');
+ my $file = shift;
my $explist = Apache::Admin::Config::Tree::_get_arg(\@_, '-expand')
|| [ qw(include) ];
- my $self = $class->SUPER::new(@_) or return;
+ my $self = $class->SUPER::new($file, @_) or return;
bless $self, $class;
$self->{_options} = \@_;
- $self->{_server_root} = $server_root;
eval {
return unless $self->_preproc($explist);
@@ -29,16 +27,6 @@ sub new {
return $self;
}
-sub server_root {
- my $self = shift;
- unless ($self->{_server_root}) {
- if (my $d = $self->directive('ServerRoot')) {
- $self->{_server_root} = $self->dequote($d->value);
- }
- }
- return $self->{_server_root};
-}
-
sub dequote {
my ($self, $str) = @_;
if ($str =~ s/^"(.*)"$/$1/) {
@@ -55,12 +43,22 @@ sub _preproc {
return 1 unless @$explist;
return $self->_preproc_section($self,
- [ map {
- my $mod = 'Apache::Config::Preproc::'.$_;
- (my $file = $mod) =~ s|::|/|g;
- require $file . '.pm';
- $mod->new
- } @$explist ]);
+ [ map {
+ my ($mod,@arg);
+ if (ref($_) eq 'HASH') {
+ ($mod,my $ref) = each %$_;
+ @arg = @$ref;
+ } elsif (ref($_) eq 'ARRAY') {
+ @arg = @$_;
+ $mod = shift @arg;
+ } else {
+ $mod = $_;
+ }
+ $mod = 'Apache::Config::Preproc::'.$mod;
+ (my $file = $mod) =~ s|::|/|g;
+ require $file . '.pm';
+ $mod->new($self, @arg)
+ } @$explist ]);
}
sub _preproc_section {
@@ -70,7 +68,7 @@ sub _preproc_section {
for (my $i = 0; defined(my $d = $section->select(-which => $i)); ) {
foreach my $mod (@$modlist) {
my @repl;
- if ($mod->expand($self, $d, \@repl)) {
+ if ($mod->expand($d, \@repl)) {
my $prev = $d;
foreach my $r (@repl) {
$prev = $section->add($r, -after => $prev);
@@ -146,8 +144,8 @@ Rest of module functionality is inherited from B<Apache::Admin::Config>.
=head2 new
- $obj = new Apache::Config::Preproc [/path/to/file|handle],
- [-expand => $modlist] [-server_root => $dirname]
+ $obj = new Apache::Config::Preproc /path/to/file|handle,
+ [-expand => $modlist]
[-indent => $integer], ['-create'], ['-no-comment-grouping'],
['-no-blank-grouping']
@@ -165,13 +163,6 @@ expansions.
If the B<-expand> argument is not supplied, only inlining of include files
is performed.
-=item B<-server_root> =E<gt> I<$dirname>
-
-Overrides the location of server root directory. By default, this
-location is obtained from the value of the B<ServerRoot> statement in the
-input configuration file. Use this keyword if the statement is absent (e.g.
-if you are parsing an include file separately).
-
=back
Rest of arguments is the same as for the B<Apache::Admin::Config> constructor:
@@ -256,25 +247,23 @@ Each keyword I<phase> listed in the B<-expand> array causes loading of the
module B<Apache::Config::Preproc::I<phase>>. This module must provide the
following methods:
-=head2 new
+=head2 new($conf, ...)
-Class constructor. Takes no arguments.
+Class constructor. The B<$conf> argument is the configuration file object
+(B<Apache::Config::Preproc>). Rest are arguments passed in the B<-expand>
+argument.
=head2 expand
This method must perform actual expansion of a subtree of the parse tree.
It is called as:
- $phase->expand($conf, $subtree, $repl)
+ $phase->expand($subtree, $repl)
Its arguments are:
=over 4
-=item $conf
-
-Configuration file object (B<Apache::Config::Preproc>).
-
=item $subtree
The subtree to be processed.
@@ -295,7 +284,7 @@ is the B<expand> method definition from the B<Apache::Config::Preproc::compact>
module:
sub expand {
- my ($self, $tree, $d, $repl) = @_;
+ my ($self, $d, $repl) = @_;
return $d->type eq 'blank' || $d->type eq 'comment';
}
diff --git a/lib/Apache/Config/Preproc/compact.pm b/lib/Apache/Config/Preproc/compact.pm
index fc6e8ed..22fccc7 100644
--- a/lib/Apache/Config/Preproc/compact.pm
+++ b/lib/Apache/Config/Preproc/compact.pm
@@ -1,13 +1,15 @@
package Apache::Config::Preproc::compact;
use strict;
use warnings;
+use Carp;
sub new {
+ croak "too many arguments" unless @_ == 2;
bless {}, shift
}
sub expand {
- my ($self, $tree, $d, $repl) = @_;
+ my ($self, $d, $repl) = @_;
return $d->type eq 'blank' || $d->type eq 'comment';
}
diff --git a/lib/Apache/Config/Preproc/ifmodule.pm b/lib/Apache/Config/Preproc/ifmodule.pm
index 033d20e..10cce3b 100644
--- a/lib/Apache/Config/Preproc/ifmodule.pm
+++ b/lib/Apache/Config/Preproc/ifmodule.pm
@@ -1,17 +1,46 @@
package Apache::Config::Preproc::ifmodule;
use strict;
use warnings;
+use Carp;
+use IPC::Open3;
sub new {
- bless {}, shift
+ my $class = shift;
+ my $conf = shift;
+ my $self = bless { conf => $conf }, $class;
+ local %_ = @_;
+ my $v;
+ if ($v = delete $_{preloaded}) {
+ croak "preloaded must be an arrayref" unless ref($v) eq 'ARRAY';
+ @{$self->{preloaded}}{@$v} = @$v;
+ }
+ if ($v = delete $_{probe}) {
+ if (ref($v) eq 'ARRAY') {
+ $self->probe(@$v);
+ } else {
+ $self->probe;
+ }
+ }
+ return $self;
+}
+
+sub conf { shift->{conf} }
+
+sub preloaded {
+ my $self = shift;
+ my $id = shift;
+ if (my $v = shift) {
+ $self->{preloaded}{$id} = $v;
+ }
+ return $self->{preloaded}{$id};
}
sub expand {
- my ($self, $tree, $d, $repl) = @_;
+ my ($self, $d, $repl) = @_;
if ($d->type eq 'section' && lc($d->name) eq 'ifmodule') {
my $id = $d->value;
my $negate = $id =~ s/^!//;
- my $res = $self->module_loaded($tree, $id);
+ my $res = $self->module_loaded($id);
if ($negate) {
$res = !$res;
}
@@ -24,10 +53,151 @@ sub expand {
}
sub module_loaded {
- my ($self, $tree, $id) = @_;
+ my ($self, $id) = @_;
+ return 1 if $self->preloaded($id);
return grep {
(split /\s+/, $_->value)[0] eq $id
- } $tree->directive('loadmodule');
+ } $self->conf->directive('loadmodule');
+}
+
+# FIXME: This list is largely speculative; check Apache sources
+my %modlist = (
+ 'mod_authn_file.c' => 'authn_file_module',
+ 'mod_authn_dbm.c' => 'authn_dbm_module',
+ 'mod_authn_anon.c' => 'authn_anon_module',
+ 'mod_authn_dbd.c' => 'authn_dbd_module',
+ 'mod_authn_socache.c' => 'authn_socache_module',
+ 'mod_authn_core.c' => 'authn_core_module',
+ 'mod_authz_host.c' => 'authz_host_module',
+ 'mod_authz_groupfile.c' => 'authz_groupfile_module',
+ 'mod_authz_user.c' => 'authz_user_module',
+ 'mod_authz_dbm.c' => 'authz_dbm_module',
+ 'mod_authz_owner.c' => 'authz_owner_module',
+ 'mod_authz_dbd.c' => 'authz_dbd_module',
+ 'mod_authz_core.c' => 'authz_core_module',
+ 'mod_authnz_ldap.c' => 'authnz_ldap_module',
+ 'mod_access_compat.c' => 'access_compat_module',
+ 'mod_auth_basic.c' => 'auth_basic_module',
+ 'mod_auth_form.c' => 'auth_form_module',
+ 'mod_auth_digest.c' => 'auth_digest_module',
+ 'mod_allowmethods.c' => 'allowmethods_module',
+ 'mod_file_cache.c' => 'file_cache_module',
+ 'mod_cache.c' => 'cache_module',
+ 'mod_cache_disk.c' => 'cache_disk_module',
+ 'mod_socache_shmcb.c' => 'socache_shmcb_module',
+ 'mod_socache_dbm.c' => 'socache_dbm_module',
+ 'mod_socache_memcache.c' => 'socache_memcache_module',
+ 'mod_watchdog.c' => 'watchdog_module',
+ 'mod_dbd.c' => 'dbd_module',
+ 'mod_dumpio.c' => 'dumpio_module',
+ 'mod_echo.c' => 'echo_module',
+ 'mod_buffer.c' => 'buffer_module',
+ 'mod_data.c' => 'data_module',
+ 'mod_ratelimit.c' => 'ratelimit_module',
+ 'mod_reqtimeout.c' => 'reqtimeout_module',
+ 'mod_ext_filter.c' => 'ext_filter_module',
+ 'mod_request.c' => 'request_module',
+ 'mod_include.c' => 'include_module',
+ 'mod_filter.c' => 'filter_module',
+ 'mod_reflector.c' => 'reflector_module',
+ 'mod_substitute.c' => 'substitute_module',
+ 'mod_sed.c' => 'sed_module',
+ 'mod_charset_lite.c' => 'charset_lite_module',
+ 'mod_deflate.c' => 'deflate_module',
+ 'mod_xml2enc.c' => 'xml2enc_module',
+ 'mod_proxy_html.c' => 'proxy_html_module',
+ 'mod_mime.c' => 'mime_module',
+ 'mod_ldap.c' => 'ldap_module',
+ 'mod_log_config.c' => 'log_config_module',
+ 'mod_log_debug.c' => 'log_debug_module',
+ 'mod_log_forensic.c' => 'log_forensic_module',
+ 'mod_logio.c' => 'logio_module',
+ 'mod_env.c' => 'env_module',
+ 'mod_mime_magic.c' => 'mime_magic_module',
+ 'mod_expires.c' => 'expires_module',
+ 'mod_headers.c' => 'headers_module',
+ 'mod_usertrack.c' => 'usertrack_module',
+ 'mod_unique_id.c' => 'unique_id_module',
+ 'mod_setenvif.c' => 'setenvif_module',
+ 'mod_version.c' => 'version_module',
+ 'mod_remoteip.c' => 'remoteip_module',
+ 'mod_proxy.c' => 'proxy_module',
+ 'mod_proxy_connect.c' => 'proxy_connect_module',
+ 'mod_proxy_ftp.c' => 'proxy_ftp_module',
+ 'mod_proxy_http.c' => 'proxy_http_module',
+ 'mod_proxy_fcgi.c' => 'proxy_fcgi_module',
+ 'mod_proxy_scgi.c' => 'proxy_scgi_module',
+ 'mod_proxy_fdpass.c' => 'proxy_fdpass_module',
+ 'mod_proxy_ajp.c' => 'proxy_ajp_module',
+ 'mod_proxy_balancer.c' => 'proxy_balancer_module',
+ 'mod_proxy_express.c' => 'proxy_express_module',
+ 'mod_session.c' => 'session_module',
+ 'mod_session_cookie.c' => 'session_cookie_module',
+ 'mod_session_dbd.c' => 'session_dbd_module',
+ 'mod_slotmem_shm.c' => 'slotmem_shm_module',
+ 'mod_slotmem_plain.c' => 'slotmem_plain_module',
+ 'mod_ssl.c' => 'ssl_module',
+ 'mod_dialup.c' => 'dialup_module',
+ 'mod_lbmethod_byrequests.c' => 'lbmethod_byrequests_module',
+ 'mod_lbmethod_bytraffic.c' => 'lbmethod_bytraffic_module',
+ 'mod_lbmethod_bybusyness.c' => 'lbmethod_bybusyness_module',
+ 'mod_lbmethod_heartbeat.c' => 'lbmethod_heartbeat_module',
+ 'event.c' => 'mpm_event_module',
+ 'prefork.c' => 'mpm_prefork_module',
+ 'mod_unixd.c' => 'unixd_module',
+ 'mod_heartbeat.c' => 'heartbeat_module',
+ 'mod_heartmonitor.c' => 'heartmonitor_module',
+ 'mod_dav.c' => 'dav_module',
+ 'mod_status.c' => 'status_module',
+ 'mod_autoindex.c' => 'autoindex_module',
+ 'mod_asis.c' => 'asis_module',
+ 'mod_info.c' => 'info_module',
+ 'mod_cgid.c' => 'cgid_module',
+ 'mod_cgi.c' => 'cgi_module',
+ 'mod_vhost_alias.c' => 'vhost_alias_module',
+ 'mod_negotiation.c' => 'negotiation_module',
+ 'mod_dir.c' => 'dir_module',
+ 'mod_actions.c' => 'actions_module',
+ 'mod_speling.c' => 'speling_module',
+ 'mod_userdir.c' => 'userdir_module',
+ 'mod_alias.c' => 'alias_module',
+ 'mod_rewrite.c' => 'rewrite_module',
+ 'mod_dav.c' => 'dav_module',
+ 'mod_dav_fs.c' => 'dav_fs_module',
+ 'mod_dav_lock.c' => 'dav_lock_module',
+ 'mod_dav_svn.c' => 'dav_svn_module',
+ 'mod_authz_svn.c' => 'authz_svn_module',
+ 'mod_fcgid.c' => 'fcgid_module',
+ 'mod_dav_svn.c' => 'dav_svn_module',
+ 'mod_authz_svn.c' => 'authz_svn_module'
+);
+
+sub probe {
+ my ($self, @servlist) = @_;
+ unless (@servlist) {
+ @servlist = qw(/usr/sbin/httpd /usr/sbin/apache2);
+ }
+
+ open(my $nullout, '>', File::Spec->devnull);
+ open(my $nullin, '<', File::Spec->devnull);
+ foreach my $serv (@servlist) {
+ use Symbol 'gensym';
+ my $fd = gensym;
+ eval {
+ if (my $pid = open3($nullin, $fd, $nullout, $serv, '-l')) {
+ while (<$fd>) {
+ chomp;
+ if (/^\s*(\S+\.c)$/ && exists($modlist{$1})) {
+ $self->preloaded($modlist{$1}, $1);
+ }
+ }
+ }
+ };
+ close $fd;
+ last unless ($@)
+ }
+ close $nullin;
+ close $nullout;
}
1;
diff --git a/lib/Apache/Config/Preproc/include.pm b/lib/Apache/Config/Preproc/include.pm
index 9959a59..f7e3142 100644
--- a/lib/Apache/Config/Preproc/include.pm
+++ b/lib/Apache/Config/Preproc/include.pm
@@ -7,18 +7,37 @@ use File::Spec;
use Carp;
sub new {
- bless { included => {} }, shift
+ my $class = shift;
+ my $conf = shift;
+ my $self = bless { included => {}, conf => $conf }, $class;
+ local %_ = @_;
+ $self->{server_root} = delete $_{server_root};
+ croak "unrecognized arguments" if keys(%_);
+ return $self;
}
+sub conf { shift->{conf} }
+
+sub server_root {
+ my $self = shift;
+ unless ($self->{server_root}) {
+ if (my $d = $self->conf->directive('ServerRoot')) {
+ $self->{server_root} = $self->conf->dequote($d->value);
+ }
+ }
+ return $self->{server_root};
+}
+
+
sub expand {
- my ($self, $tree, $d, $repl) = @_;
+ my ($self, $d, $repl) = @_;
if ($d->type eq 'directive' && $d->name =~ /^include(optional)?$/i) {
my $optional = $1;
- my $pat = $tree->dequote($d->value);
+ my $pat = $self->conf->dequote($d->value);
unless (File::Spec->file_name_is_absolute($pat)) {
- if (my $d = $tree->server_root) {
+ if (my $d = $self->server_root) {
$pat = File::Spec->catfile($d, $pat);
}
}
@@ -30,7 +49,7 @@ sub expand {
croak "file $file already included";
}
if (my $inc = new Apache::Admin::Config($file,
- @{$tree->options})) {
+ @{$self->conf->options})) {
# NOTE: make sure each item is cloned
push @$repl, map { $_->clone } $inc->select;
} else {
diff --git a/lib/Apache/Config/Preproc/macro.pm b/lib/Apache/Config/Preproc/macro.pm
index 34bdd2b..ab97b62 100644
--- a/lib/Apache/Config/Preproc/macro.pm
+++ b/lib/Apache/Config/Preproc/macro.pm
@@ -2,8 +2,10 @@ package Apache::Config::Preproc::macro;
use strict;
use warnings;
use Text::ParseWords;
+use Carp;
sub new {
+ croak "too many arguments" unless @_ == 2;
bless {}, shift
}
@@ -18,7 +20,7 @@ sub install_macro {
}
sub expand {
- my ($self, $tree, $d, $repl) = @_;
+ my ($self, $d, $repl) = @_;
if ($d->type eq 'section' && lc($d->name) eq 'macro') {
$self->install_macro(Apache::Config::Preproc::macro::defn->new($d));
return 1;

Return to:

Send suggestions and report system problems to the System administrator.