File Coverage

lib/Apache/Config/Preproc/ifmodule.pm
Criterion Covered Total %
statement 46 71 64.7
branch 11 28 39.2
condition 3 6 50.0
subroutine 10 11 90.9
pod 3 5 60.0
total 73 121 60.3


line stmt bran cond sub pod time code
1             package Apache::Config::Preproc::ifmodule;
2 4     4   28 use parent 'Apache::Config::Preproc::Expand';
  4         8  
  4         22  
3 4     4   209 use strict;
  4         8  
  4         76  
4 4     4   16 use warnings;
  4         14  
  4         97  
5 4     4   21 use Carp;
  4         5  
  4         225  
6 4     4   1408 use IPC::Open3;
  4         8398  
  4         3265  
7              
8             our $VERSION = '1.03';
9              
10             sub new {
11 7     7 0 16 my $class = shift;
12 7         11 my $conf = shift;
13 7         41 my $self = bless $class->SUPER::new($conf), $class;
14 7         54 local %_ = @_;
15 7         10 my $v;
16 7 50       26 if ($v = delete $_{preloaded}) {
17 0 0       0 croak "preloaded must be an arrayref" unless ref($v) eq 'ARRAY';
18 0         0 @{$self->{preloaded}}{@$v} = @$v;
  0         0  
19             }
20 7 50       17 if ($v = delete $_{probe}) {
21 0 0       0 if (ref($v) eq 'ARRAY') {
22 0         0 $self->probe(@$v);
23             } else {
24 0         0 $self->probe;
25             }
26             }
27 7         60 return $self;
28             }
29              
30             sub preloaded {
31 32     32 1 40 my $self = shift;
32 32         40 my $id = shift;
33 32 50       58 if (my $v = shift) {
34 0         0 $self->{preloaded}{$id} = $v;
35             }
36 32         83 return $self->{preloaded}{$id};
37             }
38              
39             sub expand {
40 387     387 1 552 my ($self, $d, $repl) = @_;
41 387 100 100     643 if ($d->type eq 'section' && lc($d->name) eq 'ifmodule') {
42 32         287 my $id = $d->value;
43 32         194 my $negate = $id =~ s/^!//;
44 32         51 my $res = $self->module_loaded($id);
45 32 100       309 if ($negate) {
46 3         7 $res = !$res;
47             }
48 32 100       59 if ($res) {
49 13         42 push @$repl, $d->select;
50             }
51 32         838 return 1;
52             }
53 355         1586 return 0;
54             }
55              
56             # List of module sources and corresponding identifiers, obtained from the
57             # httpd-2.4.6 source.
58             my %modlist = (
59             'event.c' => 'mpm_event_module',
60             'prefork.c' => 'mpm_prefork_module',
61             'worker.c' => 'mpm_worker_module',
62             'mod_access_compat.c' => 'access_compat_module',
63             'mod_actions.c' => 'actions_module',
64             'mod_alias.c' => 'alias_module',
65             'mod_allowmethods.c' => 'allowmethods_module',
66             'mod_asis.c' => 'asis_module',
67             'mod_auth_basic.c' => 'auth_basic_module',
68             'mod_auth_digest.c' => 'auth_digest_module',
69             'mod_auth_form.c' => 'auth_form_module',
70             'mod_authn_anon.c' => 'authn_anon_module',
71             'mod_authn_core.c' => 'authn_core_module',
72             'mod_authn_dbd.c' => 'authn_dbd_module',
73             'mod_authn_dbm.c' => 'authn_dbm_module',
74             'mod_authn_file.c' => 'authn_file_module',
75             'mod_authn_socache.c' => 'authn_socache_module',
76             'mod_authnz_ldap.c' => 'authnz_ldap_module',
77             'mod_authz_core.c' => 'authz_core_module',
78             'mod_authz_dbd.c' => 'authz_dbd_module',
79             'mod_authz_dbm.c' => 'authz_dbm_module',
80             'mod_authz_groupfile.c' => 'authz_groupfile_module',
81             'mod_authz_host.c' => 'authz_host_module',
82             'mod_authz_owner.c' => 'authz_owner_module',
83             'mod_authz_user.c' => 'authz_user_module',
84             'mod_autoindex.c' => 'autoindex_module',
85             'mod_buffer.c' => 'buffer_module',
86             'mod_cache.c' => 'cache_module',
87             'mod_cache_disk.c' => 'cache_disk_module',
88             'mod_cache_socache.c' => 'cache_socache_module',
89             'mod_cern_meta.c' => 'cern_meta_module',
90             'mod_cgi.c' => 'cgi_module',
91             'mod_cgid.c' => 'cgid_module',
92             'mod_charset_lite.c' => 'charset_lite_module',
93             'mod_data.c' => 'data_module',
94             'mod_dav.c' => 'dav_module',
95             'mod_dav_fs.c' => 'dav_fs_module',
96             'mod_dav_lock.c' => 'dav_lock_module',
97             'mod_dbd.c' => 'dbd_module',
98             'mod_deflate.c' => 'deflate_module',
99             'mod_dialup.c' => 'dialup_module',
100             'mod_dir.c' => 'dir_module',
101             'mod_dumpio.c' => 'dumpio_module',
102             'mod_echo.c' => 'echo_module',
103             'mod_env.c' => 'env_module',
104             'mod_example.c' => 'example_module',
105             'mod_expires.c' => 'expires_module',
106             'mod_ext_filter.c' => 'ext_filter_module',
107             'mod_file_cache.c' => 'file_cache_module',
108             'mod_filter.c' => 'filter_module',
109             'mod_headers.c' => 'headers_module',
110             'mod_heartbeat' => 'heartbeat_module',
111             'mod_heartmonitor.c' => 'heartmonitor_module',
112             'mod_ident.c' => 'ident_module',
113             'mod_imagemap.c' => 'imagemap_module',
114             'mod_include.c' => 'include_module',
115             'mod_info.c' => 'info_module',
116             'mod_isapi.c' => 'isapi_module',
117             'mod_lbmethod_bybusyness.c' => 'lbmethod_bybusyness_module',
118             'mod_lbmethod_byrequests.c' => 'lbmethod_byrequests_module',
119             'mod_lbmethod_bytraffic.c' => 'lbmethod_bytraffic_module',
120             'mod_lbmethod_heartbeat.c' => 'lbmethod_heartbeat_module',
121             'util_ldap.c' => 'ldap_module',
122             'mod_log_config.c' => 'log_config_module',
123             'mod_log_debug.c' => 'log_debug_module',
124             'mod_log_forensic.c' => 'log_forensic_module',
125             'mod_logio.c' => 'logio_module',
126             'mod_lua.c' => 'lua_module',
127             'mod_macro.c' => 'macro_module',
128             'mod_mime.c' => 'mime_module',
129             'mod_mime_magic.c' => 'mime_magic_module',
130             'mod_negotiation.c' => 'negotiation_module',
131             'mod_nw_ssl.c' => 'nwssl_module',
132             'mod_privileges.c' => 'privileges_module',
133             'mod_proxy.c' => 'proxy_module',
134             'mod_proxy_ajp.c' => 'proxy_ajp_module',
135             'mod_proxy_balancer.c' => 'proxy_balancer_module',
136             'mod_proxy_connect.c' => 'proxy_connect_module',
137             'mod_proxy_express.c' => 'proxy_express_module',
138             'mod_proxy_fcgi.c' => 'proxy_fcgi_module',
139             'mod_proxy_fdpass.c' => 'proxy_fdpass_module',
140             'mod_proxy_ftp.c' => 'proxy_ftp_module',
141             'mod_proxy_html.c' => 'proxy_html_module',
142             'mod_proxy_http.c' => 'proxy_http_module',
143             'mod_proxy_scgi.c' => 'proxy_scgi_module',
144             'mod_proxy_wstunnel.c' => 'proxy_wstunnel_module',
145             'mod_ratelimit.c' => 'ratelimit_module',
146             'mod_reflector.c' => 'reflector_module',
147             'mod_remoteip.c' => 'remoteip_module',
148             'mod_reqtimeout.c' => 'reqtimeout_module',
149             'mod_request.c' => 'request_module',
150             'mod_rewrite.c' => 'rewrite_module',
151             'mod_sed.c' => 'sed_module',
152             'mod_session.c' => 'session_module',
153             'mod_session_cookie.c' => 'session_cookie_module',
154             'mod_session_crypto.c' => 'session_crypto_module',
155             'mod_session_dbd.c' => 'session_dbd_module',
156             'mod_setenvif.c' => 'setenvif_module',
157             'mod_slotmem_plain.c' => 'slotmem_plain_module',
158             'mod_slotmem_shm.c' => 'slotmem_shm_module',
159             'mod_so.c' => 'so_module',
160             'mod_socache_dbm.c' => 'socache_dbm_module',
161             'mod_socache_dc.c' => 'socache_dc_module',
162             'mod_socache_memcache.c' => 'socache_memcache_module',
163             'mod_socache_shmcb.c' => 'socache_shmcb_module',
164             'mod_speling.c' => 'speling_module',
165             'mod_ssl.c' => 'ssl_module',
166             'mod_status.c' => 'status_module',
167             'mod_substitute.c' => 'substitute_module',
168             'mod_suexec.c' => 'suexec_module',
169             'mod_unique_id.c' => 'unique_id_module',
170             'mod_unixd.c' => 'unixd_module',
171             'mod_userdir.c' => 'userdir_module',
172             'mod_usertrack.c' => 'usertrack_module',
173             'mod_version.c' => 'version_module',
174             'mod_vhost_alias.c' => 'vhost_alias_module',
175             'mod_watchdog.c' => 'watchdog_module',
176             'mod_xml2enc.c' => 'xml2enc_module'
177             );
178              
179             sub module_loaded {
180 32     32 0 58 my ($self, $id) = @_;
181 32 50       71 if (exists($modlist{$id})) {
182 0         0 $id = $modlist{$id};
183             }
184 32 50       57 return 1 if $self->preloaded($id);
185             return grep {
186 32         95 (split /\s+/, $_->value)[0] eq $id
  70         8333  
187             } $self->conf->directive('loadmodule');
188             }
189              
190             sub probe {
191 0     0 1   my ($self, @servlist) = @_;
192 0 0         unless (@servlist) {
193 0           @servlist = qw(/usr/sbin/httpd /usr/sbin/apache2);
194             }
195              
196 0           open(my $nullout, '>', File::Spec->devnull);
197 0           open(my $nullin, '<', File::Spec->devnull);
198 0           foreach my $serv (@servlist) {
199 4     4   31 use Symbol 'gensym';
  4         8  
  4         957  
200 0           my $fd = gensym;
201 0           eval {
202 0 0         if (my $pid = open3($nullin, $fd, $nullout, $serv, '-l')) {
203 0           while (<$fd>) {
204 0           chomp;
205 0 0 0       if (/^\s*(\S+\.c)$/ && exists($modlist{$1})) {
206 0           $self->preloaded($modlist{$1}, $1);
207             }
208             }
209             }
210             };
211 0           close $fd;
212 0 0         last unless ($@)
213             }
214 0           close $nullin;
215 0           close $nullout;
216             }
217              
218             1;
219             __END__