diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2018-02-21 11:44:04 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2018-02-21 11:44:04 +0200 |
commit | 3c71a4b3c78a8b25258e858135cd239d22bd83c9 (patch) | |
tree | 4da1c6f630b29e42208966c1381f258164e4c946 /lib/Apache/Defaults.pm | |
download | apache-defaults-3c71a4b3c78a8b25258e858135cd239d22bd83c9.tar.gz apache-defaults-3c71a4b3c78a8b25258e858135cd239d22bd83c9.tar.bz2 |
Initial commit
Diffstat (limited to 'lib/Apache/Defaults.pm')
-rw-r--r-- | lib/Apache/Defaults.pm | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/lib/Apache/Defaults.pm b/lib/Apache/Defaults.pm new file mode 100644 index 0000000..13c729e --- /dev/null +++ b/lib/Apache/Defaults.pm | |||
@@ -0,0 +1,292 @@ | |||
1 | package Apache::Defaults; | ||
2 | use strict; | ||
3 | use warnings; | ||
4 | use File::Spec; | ||
5 | use IPC::Open3; | ||
6 | use Shell::GetEnv; | ||
7 | use DateTime::Format::Strptime; | ||
8 | use Symbol 'gensym'; | ||
9 | use Carp; | ||
10 | |||
11 | our $VERSION = '0.10'; | ||
12 | |||
13 | sub new { | ||
14 | my $class = shift; | ||
15 | my $self = bless {}, $class; | ||
16 | local %_ = @_; | ||
17 | my $v; | ||
18 | my @servlist; | ||
19 | if ($v = delete $_{server}) { | ||
20 | if (ref($v) eq 'ARRAY') { | ||
21 | @servlist = @$v; | ||
22 | } else { | ||
23 | @servlist = ( $v ); | ||
24 | } | ||
25 | } else { | ||
26 | @servlist = qw(/usr/sbin/httpd /usr/sbin/apache2); | ||
27 | } | ||
28 | |||
29 | if (my @select = grep { -x $_ } @servlist) { | ||
30 | $self->{server} = shift @select; | ||
31 | } else { | ||
32 | croak "No suitable httpd binary found"; | ||
33 | } | ||
34 | |||
35 | if ($v = delete $_{environ}) { | ||
36 | $self->{environ} = Shell::GetEnv->new('sh', ". $v", startup => 0) | ||
37 | ->envs; | ||
38 | } | ||
39 | |||
40 | croak "unrecognized arguments" if keys(%_); | ||
41 | return $self; | ||
42 | } | ||
43 | |||
44 | sub server { shift->{server} } | ||
45 | sub environ { shift->{environ} } | ||
46 | |||
47 | sub probe { | ||
48 | my ($self, $cb, @opt) = @_; | ||
49 | |||
50 | open(my $nullout, '>', File::Spec->devnull); | ||
51 | open(my $nullin, '<', File::Spec->devnull); | ||
52 | |||
53 | my $fd = gensym; | ||
54 | local %ENV = %{$self->{environ}} if $self->{environ}; | ||
55 | if (my $pid = open3($nullin, $fd, $nullout, $self->server, @opt)) { | ||
56 | while (<$fd>) { | ||
57 | chomp; | ||
58 | last unless &{$cb}($_); | ||
59 | } | ||
60 | } | ||
61 | close $fd; | ||
62 | close $nullin; | ||
63 | close $nullout; | ||
64 | } | ||
65 | |||
66 | sub dequote { | ||
67 | my ($self, $arg) = @_; | ||
68 | if ($arg =~ s{^"(.*?)"$}{$1}) { | ||
69 | $arg =~ s{\\([\\"])}{$1}g; | ||
70 | } | ||
71 | return $arg; | ||
72 | } | ||
73 | |||
74 | sub _get_version_info { | ||
75 | my $self = shift; | ||
76 | unless ($self->{has_version_info}) { | ||
77 | $self->probe(sub { | ||
78 | local $_ = shift; | ||
79 | if (m{^Server version:\s+(.+?)/(\S+)\s+\((.*?)\)}) { | ||
80 | $self->{name} = $1; | ||
81 | $self->{version} = $2; | ||
82 | $self->{platform} = $3; | ||
83 | } elsif (/^Server built:\s+(.+)/) { | ||
84 | $self->{built} = | ||
85 | DateTime::Format::Strptime->new( | ||
86 | pattern => '%b %d %Y %H:%M%S', | ||
87 | strict => 1, | ||
88 | locale => 'en_US', | ||
89 | time_zone => 'UTC', | ||
90 | on_error => 'undef' | ||
91 | )->parse_datetime($1); | ||
92 | |||
93 | } elsif (/^Server loaded:\s+(.+)$/) { | ||
94 | $self->{loaded_with} = $1; | ||
95 | } elsif (/^Compiled using:\s+(.+)$/) { | ||
96 | $self->{compiled_with} = $1; | ||
97 | } elsif (/^Architecture:\s+(.+)$/) { | ||
98 | $self->{architecture} = $1; | ||
99 | } elsif (/^Server MPM:\s+(.+)$/) { | ||
100 | $self->{MPM} = $1; | ||
101 | } elsif (/^\s+threaded:\s+(?<b>yes|no)/) { | ||
102 | $self->{MPM_threaded} = $+{b} eq 'yes'; | ||
103 | } elsif (/^\s+forked:\s+(?<b>yes|no)/) { | ||
104 | $self->{MPM_forked} = $+{b} eq 'yes'; | ||
105 | } elsif (/^\s+-D\s+(?<name>.+?)=(?<val>.+)$/) { | ||
106 | $self->{defines}{$+{name}} = $self->dequote($+{val}); | ||
107 | } elsif (/^\s+-D\s+(?<name>.+?)(?:\s*(?<com>.+))?$/) { | ||
108 | $self->{defines}{$+{name}} = 1; | ||
109 | } | ||
110 | return 1; | ||
111 | }, '-V'); | ||
112 | } | ||
113 | $self->{has_version_info} = 1; | ||
114 | } | ||
115 | |||
116 | my @ATTRIBUTES = qw(name | ||
117 | version | ||
118 | platform | ||
119 | built | ||
120 | loaded_with | ||
121 | compiled_with | ||
122 | architecture | ||
123 | MPM | ||
124 | MPM_threaded | ||
125 | MPM_forked); | ||
126 | { | ||
127 | no strict 'refs'; | ||
128 | foreach my $attribute (@ATTRIBUTES) { | ||
129 | *{ __PACKAGE__ . '::' . $attribute } = sub { | ||
130 | my $self = shift; | ||
131 | $self->_get_version_info; | ||
132 | $self->{$attribute}; | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | |||
137 | sub server_root { shift->defines('HTTPD_ROOT') } | ||
138 | |||
139 | sub defines { | ||
140 | my $self = shift; | ||
141 | $self->_get_version_info; | ||
142 | return @{$self->{defines}}{@_}; | ||
143 | } | ||
144 | |||
145 | # List of module sources and corresponding identifiers, obtained from the | ||
146 | # httpd-2.4.6 source. | ||
147 | my %modlist = ( | ||
148 | 'event.c' => 'mpm_event_module', | ||
149 | 'prefork.c' => 'mpm_prefork_module', | ||
150 | 'worker.c' => 'mpm_worker_module', | ||
151 | 'mod_access_compat.c' => 'access_compat_module', | ||
152 | 'mod_actions.c' => 'actions_module', | ||
153 | 'mod_alias.c' => 'alias_module', | ||
154 | 'mod_allowmethods.c' => 'allowmethods_module', | ||
155 | 'mod_asis.c' => 'asis_module', | ||
156 | 'mod_auth_basic.c' => 'auth_basic_module', | ||
157 | 'mod_auth_digest.c' => 'auth_digest_module', | ||
158 | 'mod_auth_form.c' => 'auth_form_module', | ||
159 | 'mod_authn_anon.c' => 'authn_anon_module', | ||
160 | 'mod_authn_core.c' => 'authn_core_module', | ||
161 | 'mod_authn_dbd.c' => 'authn_dbd_module', | ||
162 | 'mod_authn_dbm.c' => 'authn_dbm_module', | ||
163 | 'mod_authn_file.c' => 'authn_file_module', | ||
164 | 'mod_authn_socache.c' => 'authn_socache_module', | ||
165 | 'mod_authnz_ldap.c' => 'authnz_ldap_module', | ||
166 | 'mod_authz_core.c' => 'authz_core_module', | ||
167 | 'mod_authz_dbd.c' => 'authz_dbd_module', | ||
168 | 'mod_authz_dbm.c' => 'authz_dbm_module', | ||
169 | 'mod_authz_groupfile.c' => 'authz_groupfile_module', | ||
170 | 'mod_authz_host.c' => 'authz_host_module', | ||
171 | 'mod_authz_owner.c' => 'authz_owner_module', | ||
172 | 'mod_authz_user.c' => 'authz_user_module', | ||
173 | 'mod_autoindex.c' => 'autoindex_module', | ||
174 | 'mod_buffer.c' => 'buffer_module', | ||
175 | 'mod_cache.c' => 'cache_module', | ||
176 | 'mod_cache_disk.c' => 'cache_disk_module', | ||
177 | 'mod_cache_socache.c' => 'cache_socache_module', | ||
178 | 'mod_cern_meta.c' => 'cern_meta_module', | ||
179 | 'mod_cgi.c' => 'cgi_module', | ||
180 | 'mod_cgid.c' => 'cgid_module', | ||
181 | 'mod_charset_lite.c' => 'charset_lite_module', | ||
182 | 'mod_data.c' => 'data_module', | ||
183 | 'mod_dav.c' => 'dav_module', | ||
184 | 'mod_dav_fs.c' => 'dav_fs_module', | ||
185 | 'mod_dav_lock.c' => 'dav_lock_module', | ||
186 | 'mod_dbd.c' => 'dbd_module', | ||
187 | 'mod_deflate.c' => 'deflate_module', | ||
188 | 'mod_dialup.c' => 'dialup_module', | ||
189 | 'mod_dir.c' => 'dir_module', | ||
190 | 'mod_dumpio.c' => 'dumpio_module', | ||
191 | 'mod_echo.c' => 'echo_module', | ||
192 | 'mod_env.c' => 'env_module', | ||
193 | 'mod_example.c' => 'example_module', | ||
194 | 'mod_expires.c' => 'expires_module', | ||
195 | 'mod_ext_filter.c' => 'ext_filter_module', | ||
196 | 'mod_file_cache.c' => 'file_cache_module', | ||
197 | 'mod_filter.c' => 'filter_module', | ||
198 | 'mod_headers.c' => 'headers_module', | ||
199 | 'mod_heartbeat' => 'heartbeat_module', | ||
200 | 'mod_heartmonitor.c' => 'heartmonitor_module', | ||
201 | 'mod_ident.c' => 'ident_module', | ||
202 | 'mod_imagemap.c' => 'imagemap_module', | ||
203 | 'mod_include.c' => 'include_module', | ||
204 | 'mod_info.c' => 'info_module', | ||
205 | 'mod_isapi.c' => 'isapi_module', | ||
206 | 'mod_lbmethod_bybusyness.c' => 'lbmethod_bybusyness_module', | ||
207 | 'mod_lbmethod_byrequests.c' => 'lbmethod_byrequests_module', | ||
208 | 'mod_lbmethod_bytraffic.c' => 'lbmethod_bytraffic_module', | ||
209 | 'mod_lbmethod_heartbeat.c' => 'lbmethod_heartbeat_module', | ||
210 | 'util_ldap.c' => 'ldap_module', | ||
211 | 'mod_log_config.c' => 'log_config_module', | ||
212 | 'mod_log_debug.c' => 'log_debug_module', | ||
213 | 'mod_log_forensic.c' => 'log_forensic_module', | ||
214 | 'mod_logio.c' => 'logio_module', | ||
215 | 'mod_lua.c' => 'lua_module', | ||
216 | 'mod_macro.c' => 'macro_module', | ||
217 | 'mod_mime.c' => 'mime_module', | ||
218 | 'mod_mime_magic.c' => 'mime_magic_module', | ||
219 | 'mod_negotiation.c' => 'negotiation_module', | ||
220 | 'mod_nw_ssl.c' => 'nwssl_module', | ||
221 | 'mod_privileges.c' => 'privileges_module', |