File Coverage

blib/lib/App/Info/HTTPD/Apache.pm
Criterion Covered Total %
statement 169 186 90.9
branch 76 142 53.5
condition 5 17 29.4
subroutine 39 45 86.7
pod 31 31 100.0
total 320 421 76.0


line stmt bran cond sub pod time code
1             package App::Info::HTTPD::Apache;
2              
3             # $Id: Apache.pm 3154 2006-09-16 00:01:20Z theory $
4              
5             =head1 NAME
6            
7             App::Info::HTTPD::Apache - Information about Apache web server
8            
9             =head1 SYNOPSIS
10            
11             use App::Info::HTTPD::Apache;
12            
13             my $apache = App::Info::HTTPD::Apache->new;
14            
15             if ($apache->installed) {
16             print "App name: ", $apache->name, "\n";
17             print "Version: ", $apache->version, "\n";
18             print "Bin dir: ", $apache->bin_dir, "\n";
19             } else {
20             print "Apache is not installed. :-(\n";
21             }
22            
23             =head1 DESCRIPTION
24            
25             App::Info::HTTPD::Apache supplies information about the Apache web server
26             installed on the local system. It implements all of the methods defined by
27             App::Info::HTTPD. Methods that trigger events will trigger them only the first
28             time they're called (See L<App::Info|App::Info> for documentation on handling
29             events). To start over (after, say, someone has installed Apache) construct a
30             new App::Info::HTTPD::Apache object to aggregate new metadata.
31            
32             Some of the methods trigger the same events. This is due to cross-calling of
33             methods or of functions common to methods. However, any one event should be
34             triggered no more than once. For example, although the info event "Executing
35             `httpd -v`" is documented for the methods C<name()>, C<version()>,
36             C<major_version()>, C<minor_version()>, and C<patch_version()>, rest assured
37             that it will only be triggered once, by whichever of those four methods is
38             called first.
39            
40             =cut
41              
42 2     2   54 use strict;
  2         18  
  2         78  
43 2     2   55 use App::Info::HTTPD;
  2         20  
  2         41  
44 2     2   68 use App::Info::Util;
  2         21  
  2         118  
45 2     2   37 use vars qw(@ISA $VERSION);
  2         19  
  2         33  
46             @ISA = qw(App::Info::HTTPD);
47             $VERSION = '0.51';
48 2     2   81 use constant WIN32 => $^O eq 'MSWin32';
  2         19  
  2         37  
49              
50             my $u = App::Info::Util->new;
51             my @EXES = qw(ab apachectl apxs htdigest htpasswd logresolve rotatelogs);
52              
53             =head1 INTERFACE
54            
55             =head2 Constructor
56            
57             =head3 new
58            
59             my $apache = App::Info::HTTPD::Apache->new(@params);
60            
61             Returns an App::Info::HTTPD::Apache object. See L<App::Info|App::Info> for a
62             complete description of argument parameters.
63            
64             When called, C<new()> searches the the directories returned by
65             C<search_bin_dirs()> for an executable with a name returned by
66             C<search_exe_names()>. If found, the executable (hereafer referred to as
67             F<httpd>, regardless of how it was actually found to be named) will be called
68             by the object methods below to gather the data necessary for each. If F<httpd>
69             cannot be found, then Apache is assumed not to be installed, and each of the
70             object methods will return C<undef>.
71            
72             In addition to the parameters supported by the parent classes,
73             L<App::Info|App::Info> and L<App::Info::HTTPD|App::Info::HTTPD>,
74             this class' C<new()> method also supports:
75            
76             =over 4
77            
78             =item search_conf_names
79            
80             An array reference of possible names for Apache configuration files. These
81             will be returned by the C<search_conf_names()> method before the default
82             names, and may be used by C<conf_file()> to search for the configuration file.
83            
84             =item search_conf_dirs
85            
86             An array reference of possible directories in which to search for Apache
87             configuration files. These will be returned by the C<search_conf_dirs()>
88             method before the default directories, and may be used by C<conf_file()> to
89             search for the configuration file.
90            
91             =back
92            
93             As well as these parameters to specify alternate names for Apache executables
94             (other than F<httpd>, which you specify via the C<search_exe_names> parameter):
95            
96             =over
97            
98             =item search_ab_names
99            
100             =item search_apachectl_names
101            
102             =item search_apxs_names
103            
104             =item search_htdigest_names
105            
106             =item search_htpasswd_names
107            
108             =item search_logresolve_names
109            
110             =item search_rotatelogs_names
111            
112             =back
113            
114             B<Events:>
115            
116             =over 4
117            
118             =item info
119            
120             Looking for Apache executable
121            
122             =item confirm
123            
124             Path to your httpd executable?
125            
126             =item unknown
127            
128             Path to your httpd executable?
129            
130             =back
131            
132             =cut
133              
134             sub new {
135             # Construct the object.
136 2     2 1 75     my $self = shift->SUPER::new(@_);
137              
138 2         23     for my $exe (qw(search_conf_dirs search_conf_names),
  14         146  
139                              map { "search_$_\_names" } @EXES
140                 ) {
141 18 100       177         if (exists $self->{$exe}) {
142 4 50       92             $self->{$exe} = [$self->{$exe}] unless ref $self->{$exe} eq 'ARRAY';
143                     } else {
144 14         230             $self->{$exe} = [];
145                     }
146                 }
147              
148             # Find Apache executable.
149 2         45     $self->info("Looking for Apache executable");
150              
151 2         53     my @paths = $self->search_bin_dirs;
152 2         223     my @exes = $self->search_exe_names;
153              
154 2 50       36     if (my $exe = $u->first_cat_exe(\@exes, @paths)) {
155             # We found httpd. Confirm.
156                     $self->{executable} = $self->confirm(
157                         key => 'path to httpd',
158                         prompt => 'Path to your httpd executable?',
159                         value => $exe,
160 0     0   0             callback => sub { -x },
161 2         45             error => 'Not an executable',
162                     );
163                 } else {
164             # Handle an unknown value.
165                     $self->{executable} = $self->unknown(
166                         key => 'path to httpd',
167                         prompt => 'Path to your httpd executable?',
168 0     0   0             callback => sub { -x },
169 0         0             error => 'Not an executable',
170                     );
171                 }
172 2         45     return $self;
173             };
174              
175             ##############################################################################
176              
177             =head2 Class Method
178            
179             =head3 key_name
180            
181             my $key_name = App::Info::HTTPD::Apache->key_name;
182            
183             Returns the unique key name that describes this class. The value returned is
184             the string "Apache".
185            
186             =cut
187              
188 2     2 1 32 sub key_name { 'Apache' }
189              
190             ##############################################################################
191              
192             =head2 Object Methods
193            
194             =head3 installed
195            
196             print "apache is ", ($apache->installed ? '' : 'not '),
197             "installed.\n";
198            
199             Returns true if Apache is installed, and false if it is not.
200             App::Info::HTTPD::Apache determines whether Apache is installed based on the
201             presence or absence of the F<httpd> application on the file system, as found
202             when C<new()> constructed the object. If Apache does not appear to be
203             installed, then all of the other object methods will return empty values.
204            
205             =cut
206              
207 2 50   2 1 34 sub installed { return $_[0]->{executable} ? 1 : undef }
208              
209             ##############################################################################
210              
211             =head3 name
212            
213             my $name = $apache->name;
214            
215             Returns the name of the application. App::Info::HTTPD::Apache parses the name
216             from the system call C<`httpd -v`>.
217            
218             B<Events:>
219            
220             =over 4
221            
222             =item info
223            
224             Executing `httpd -v`
225            
226             =item error
227            
228             Failed to find Apache version data with `httpd -v`
229            
230             Failed to parse Apache name and version from string
231            
232             =item unknown
233            
234             Enter a valid Apache name
235            
236             =back
237            
238             =cut
239              
240             my $get_version = sub {
241                 my $self = shift;
242                 $self->{-v} = 1;
243                 $self->info(qq{Executing `"$self->{executable}" -v`});
244                 my $version = `"$self->{executable}" -v`;
245                 unless ($version) {
246                     $self->error("Failed to find Apache version data with ",
247                                  qq{`"$self->{executable}" -v`});
248                     return;
249                 }
250              
251                 chomp $version;
252                 my ($n, $x, $y, $z) = $version =~
253                   /Server\s+version:\s+([^\/]*)\/(\d+)\.(\d+).(\d+)/;
254                 unless ($n and $x and defined $y and defined $z) {
255                     $self->error("Failed to parse Apache name and ",
256                                      "version from string '$version'");
257                     return;
258                 }
259              
260                 @{$self}{qw(name version major minor patch)} =
261                   ($n, "$x.$y.$z", $x, $y, $z);
262             };
263              
264             sub name {
265 2     2 1 23     my $self = shift;
266 2 50       27     return unless $self->{executable};
267              
268             # Load data.
269 2 50       37     $get_version->($self) unless exists $self->{-v};
270              
271             # Handle an unknown name.
272 2   50     86     $self->{name} ||= $self->unknown( key => 'apache name' );
273              
274             # Return the name.
275 2         424     return $self->{name};
276             }
277              
278             ##############################################################################
279              
280             =head3 version
281            
282             my $version = $apache->version;
283            
284             Returns the apache version number. App::Info::HTTPD::Apache parses the version
285             number from the system call C<`httpd -v`>.
286            
287             B<Events:>
288            
289             =over 4
290            
291             =item info
292            
293             Executing `httpd -v`
294            
295             =item error
296            
297             Failed to find Apache version data with `httpd -v`
298            
299             Failed to parse Apache name and version from string
300            
301             =item unknown
302            
303             Enter a valid Apache version number
304            
305             =back
306            
307             =cut
308              
309             sub version {
310 2     2 1 883     my $self = shift;
311 2 50       76     return unless $self->{executable};
312              
313             # Load data.
314 2 50       86     $get_version->($self) unless exists $self->{-v};
315              
316             # Handle an unknown value.
317 2 50       45     unless ($self->{version}) {
318             # Create a validation code reference.
319                     my $chk_version = sub {
320             # Try to get the version number parts.
321 0     0   0             my ($x, $y, $z) = /^(\d+)\.(\d+).(\d+)$/;
322             # Return false if we didn't get all three.
323 0 0 0     0             return unless $x and defined $y and defined $z;
      0        
324             # Save all three parts.
325 0         0             @{$self}{qw(major minor patch)} = ($x, $y, $z);
  0         0  
326             # Return true.
327 0         0             return 1;
328 0         0         };
329 0         0         $self->{version} = $self->unknown( key => 'apache version number',
330                                                        callback => $chk_version);
331                 }
332              
333             # Return the version number.
334 2         52     return $self->{version};
335             }
336              
337             ##############################################################################
338              
339             =head3 major_version
340            
341             my $major_version = $apache->major_version;
342            
343             Returns the Apache major version number. App::Info::HTTPD::Apache parses the
344             version number from the system call C<`httpd --v`>. For example, if
345             C<version()> returns "1.3.24", then this method returns "1".
346            
347             B<Events:>
348            
349             =over 4
350            
351             =item info
352            
353             Executing `httpd -v`
354            
355             =item error
356            
357             Failed to find Apache version data with `httpd -v`
358            
359             Failed to parse Apache name and version from string
360            
361             =item unknown
362            
363             Enter a valid Apache major version number
364            
365             =back
366            
367             =cut
368              
369             # This code reference is used by major_version(), minor_version(), and
370             # patch_version() to validate a version number entered by a user.
371             my $is_int = sub { /^\d+$/ };
372              
373             sub major_version {
374 2     2 1 21     my $self = shift;
375 2 50       26     return unless $self->{executable};
376             # Load data.
377 2 50       28     $get_version->($self) unless exists $self->{-v};
378             # Handle an unknown value.
379 2 50       26     $self->{major} = $self->unknown( key => 'apache major version number',
380                                                  callback => $is_int)
381                   unless $self->{major};
382 2         71     return $self->{major};
383             }
384              
385             ##############################################################################
386              
387             =head3 minor_version
388            
389             my $minor_version = $apache->minor_version;
390            
391             Returns the Apache minor version number. App::Info::HTTPD::Apache parses the
392             version number from the system call C<`httpd --v`>. For example, if
393             C<version()> returns "1.3.24", then this method returns "3". See the
394             L<version|"version"> method for a list of possible errors.
395            
396             B<Events:>
397            
398             =over 4
399            
400             =item info
401            
402             Executing `httpd -v`
403            
404             =item error
405            
406             Failed to find Apache version data with `httpd -v`
407            
408             Failed to parse Apache name and version from string
409            
410             =item unknown
411            
412             Enter a valid Apache minor version number
413            
414             =back
415            
416             =cut
417              
418             sub minor_version {
419 2     2 1 23     my $self = shift;
420 2 50       30     return unless $self->{executable};
421             # Load data.
422 2 50       52     $get_version->($self) unless exists $self->{-v};
423             # Handle an unknown value.
424 2 50       44     $self->{minor} = $self->unknown( key => 'apache minor version number',
425                                                  callback => $is_int)
426                   unless defined $self->{minor};
427 2         32     return $self->{minor};
428             }
429              
430             ##############################################################################
431              
432             =head3 patch_version
433            
434             my $patch_version = $apache->patch_version;
435            
436             Returns the Apache patch version number. App::Info::HTTPD::Apache parses the
437             version number from the system call C<`httpd --v`>. For example, if
438             C<version()> returns "1.3.24", then this method returns "24".
439            
440             B<Events:>
441            
442             =over 4
443            
444             =item info
445            
446             Executing `httpd -v`
447            
448             =item error
449            
450             Failed to find Apache version data with `httpd -v`
451            
452             Failed to parse Apache name and version from string
453            
454             =item unknown
455            
456             Enter a valid Apache patch version number
457            
458             =back
459            
460             =cut
461              
462             sub patch_version {
463 2     2 1 79     my $self = shift;
464 2 50       51     return unless $self->{executable};
465             # Load data.
466 2 50       65     $get_version->($self) unless exists $self->{-v};
467             # Handle an unknown value.
468 2 50       25     $self->{patch} = $self->unknown( key => 'apache patch version number',
469                                                  callback => $is_int)
470                   unless defined $self->{patch};
471 2         32     return $self->{patch};
472             }
473              
474             ##############################################################################
475              
476             =head3 httpd_root
477            
478             my $httpd_root = $apache->httpd_root;
479            
480             Returns the HTTPD root directory path. This path is defined at compile time,
481             and App::Info::HTTPD::Apache parses it from the system call C<`httpd -V`>.
482            
483             B<Events:>
484            
485             =over 4
486            
487             =item info
488            
489             Executing `httpd -V`
490            
491             =item error
492            
493             Unable to extract compile settings from `httpd -V`
494            
495             Cannot parse HTTPD root from `httpd -V`
496            
497             =item unknown
498            
499             Enter a valid HTTPD root
500            
501             =back
502            
503             =cut
504              
505             # This code ref takes care of processing the compile settings. It is used by
506             # httpd_root(), magic_number(), or compile_option(), whichever is called
507             # first.
508             my $get_compile_settings = sub {
509                 my $self = shift;
510                 $self->{-V} = 1;
511                 $self->info(qq{Executing `"$self->{executable}" -V`});
512             # Get the compile settings.
513                 my $data = `"$self->{executable}" -V`;
514                 unless ($data) {
515                     $self->error("Unable to extract compile settings from ",
516                                  qq{`"$self->{executable}" -V`});
517                     return;
518                 }
519              
520             # Split out the parts.
521                 foreach (split /\s*\n\s*/, $data) {
522                     if (/magic\s+number:\s+(.*)$/i) {
523                         $self->{magic_number} = $1;
524                     } elsif (/=/) {
525                         $_ =~ s/^-D\s+//;
526                         $_ =~ s/"$//;
527                         my ($k, $v) = split /\s*=\s*"/, $_;
528                         $self->{lc $k} = $v;
529                         if (WIN32) {
530                             if ($k eq 'SUEXEC_BIN') {
531                                 $self->{lc $k} = 0;
532                             } elsif ($k eq 'HTTPD_ROOT') {
533                                 $self->{lc $k} =
534                                   join('\\', (split /\\/, $self->{executable} )[0 .. 1]);
535                              }
536                         }
537                     } elsif (/-D/) {
538                         $_ =~ s/^-D\s+//;
539                         $self->{lc $_} = 1;
540                     }
541                 }
542             # Issue a warning if no httpd root was found.
543                 $self->error("Cannot parse HTTPD root from ",
544                              qq{`"$self->{executable}" -V`}) unless $self->{httpd_root};
545             };
546              
547             # This code reference is used by httpd_root(), lib_dir(), bin_dir(), and
548             # so_lib_dir() to validate a directory entered by the user.
549             my $is_dir = sub { -d };
550              
551             sub httpd_root {
552 12     12 1 110     my $self = shift;
553 12 50       284     return unless $self->{executable};
554             # Get the compile settings.
555 12 100       162     $get_compile_settings->($self) unless $self->{-V};
556             # Handle an unknown value.
557 12 50       126     $self->{httpd_root} = $self->unknown( key => 'apache httpd root',
558                                                       callback => $is_dir)
559                   unless defined $self->{httpd_root};
560 12         608     return $self->{httpd_root};
561             }
562              
563             ##############################################################################
564              
565             =head3 magic_number
566            
567             my $magic_number = $apache->magic_number;
568            
569             Returns the "Magic Number" for the Apache installation. This number is defined
570             at compile time, and App::Info::HTTPD::Apache parses it from the system call
571             C<`httpd -V`>.
572            
573             B<Events:>
574            
575             =over 4
576            
577             =item info
578            
579             Executing `httpd -V`
580            
581             =item error
582            
583             Unable to extract compile settings from `httpd -V`
584            
585             Cannot parse HTTPD root from `httpd -V`
586            
587             =item unknown
588            
589             Enter a valid magic number
590            
591             =back
592            
593             =cut
594              
595             sub magic_number {
596 2     2 1 21     my $self = shift;
597 2 50       26     return unless $self->{executable};
598             # Get the compile settings.
599 2 50       29     $get_compile_settings->($self) unless $self->{-V};
600             # Handle an unknown value.
601 2 50       25     $self->{magic_number} = $self->unknown( key => 'apache magic number' )
602                   unless defined $self->{magic_number};
603 2         30     return $self->{magic_number};
604             }
605              
606             ##############################################################################
607              
608             =head3 compile_option
609            
610             my $compile_option = $apache->compile_option($option);
611            
612             Returns the value of the Apache compile option C<$option>. The compile option
613             is looked up case-insensitively. All of the Apache compile options are
614             collected from the system call C<`httpd -V`>. For compile options that contain
615             a corresponding value (such as "SUEXEC_BIN" or "DEFAULT_PIDLOG"),
616             C<compile_option()> returns the value of the option if the option exists. For
617             other options, it returns true (1) if the option was included, and
618             false(C<undef>) if it was not. Returns C<undef> if Apache is not installed or
619             if the option could not be parsed. See the L<httpd_root|"httpd_root"> method
620             for a list of possible errors.
621            
622             See the Apache documentation at L<http://httpd.apache.org/docs-project/> to
623             learn about all the possible compile options.
624            
625             B<Events:>
626            
627             =over 4
628            
629             =item info
630            
631             Executing `httpd -V`
632            
633             =item error
634            
635             Unable to extract compile settings from `httpd -V`
636            
637             Cannot parse HTTPD root from `httpd -V`
638            
639             =item unknown
640            
641             Enter a valid option
642            
643             =back
644            
645             =cut
646              
647             sub compile_option {
648 4     4 1 41     my $self = shift;
649 4 50       167     return unless $self->{executable};
650             # Get the compile settings.
651 4 50       53     $get_compile_settings->($self) unless $self->{-V};
652             # Handle an unknown value.
653 4         40     my $option = lc $_[0];
654 4 50       107     $self->{$option} = $self->unknown( key => "apache option $option" )
655                   unless defined $self->{$option};
656 4         53     return $self->{$option};
657             }
658              
659             ##############################################################################
660              
661             =head3 conf_file
662            
663             Returns the full path to the Apache configuration file. C<conf_file()> looks
664             for the configuration file in a number of locations and under a number of
665             names. First it tries to use the file specifed by the C<SERVER_CONFIG_FILE>
666             compile option (as returned by a call to C<compile_option()>) -- and if it's a
667             relative file name, it gets appended to the directory returned by
668             C<httpd_root()>. If that file isn't found, C<conf_file()> then looks for a
669             file with one of the names returned by C<search_conf_names()> in the F<conf>
670             subdirectory of the HTTPD root directory. Failing that, it searches for them
671             in each of the directories returned by C<search_conf_dirs()> until it finds a
672             match.
673            
674             B<Events:>
675            
676             =over 4
677            
678             =item info
679            
680             Searching for Apache configuration file
681            
682             =item error
683            
684             No Apache config file found
685            
686             =item unknown
687            
688             Location of httpd.conf file?
689            
690             =back
691            
692             =cut
693              
694             sub conf_file {
695 4     4 1 83     my $self = shift;
696 4 50       85     return unless $self->{executable};
697 4 100       64     unless (exists $self->{conf_file}) {
698 2         164         $self->info("Searching for Apache configuration file");
699 2         66         my $root = $self->httpd_root;
700 2         44         my $conf = $self->compile_option('SERVER_CONFIG_FILE');
701 2 50       522         $conf = $u->file_name_is_absolute($conf) ?
    50          
702                       $conf : $u->catfile($root, $conf) if $conf;
703 2 50 33     131         if ($conf && -f $conf) {
704 0         0             $self->{conf_file} = $conf;
705                     } else {
706             # Paths to search.
707 2         137             my @confs = $self->search_conf_names;
708              
709 2 50       28             $self->{conf_file} = $u->first_cat_path(\@confs, $self->search_conf_dirs)
710                           or $self->error("No Apache config file found");
711                     }
712                 }
713              
714             # Handle an unknown value.
715                 $self->{conf_file} =
716                   $self->unknown( key => 'apache conf file',
717                                   prompt => "Location of httpd.conf file?",
718 0     0   0                       callback => sub { -f },
719 4 50       292                       error => "Not a file")
720                   unless defined $self->{conf_file};
721 4         140     return $self->{conf_file};
722             }
723              
724             ##############################################################################
725              
726             =head3 user
727            
728             my $user = $apache->user;
729            
730             Returns the name of the Apache user. This value is collected from the Apache
731             configuration file as returned by C<conf_file()>.
732            
733             B<Events:>
734            
735             =over 4
736            
737             =item info
738            
739             Searching for Apache configuration file
740            
741             Executing `httpd -V`
742            
743             Parsing Apache configuration file
744            
745             =item error
746            
747             No Apache config file found
748            
749             Cannot parse user from file
750            
751             Cannot parse group from file
752            
753             Cannot parse port from file
754            
755             =item unknown
756            
757             Location of httpd.conf file?
758            
759             Enter Apache user name
760            
761             =back
762            
763             =cut
764              
765             # This code reference parses the Apache configuration file. It is called by
766             # user(), group(), or port(), whichever gets called first.
767             my $parse_conf_file = sub {
768                 my $self = shift;
769                 return if exists $self->{user};
770                 $self->{user} = undef;
771             # Find the configuration file.
772                 my $conf = $self->conf_file or return;
773              
774                 $self->info("Parsing Apache configuration file");
775              
776             # This is the place to add more regexes to collect stuff from the
777             # config file in the future.
778                 my @regexen = (qr/^\s*User\s+(.*)$/,
779                                qr/^\s*Group\s+(.*)$/,
780                                qr/^\s*Port\s+(.*)$/ );
781                 my ($usr, $grp, $prt) = $u->multi_search_file($conf, @regexen);
782             # Issue a warning if we couldn't find the user and group.
783                 $self->error("Cannot parse user from file '$conf'") unless $usr;
784                 $self->error("Cannot parse group from file '$conf'") unless $grp;
785                 $self->error("Cannot parse port from file '$conf'") unless $prt;
786             # Assign them anyway.
787                 @{$self}{qw(user group port)} = ($usr, $grp, $prt);
788             };
789              
790             sub user {
791 2     2 1 120     my $self = shift;
792 2 50       29     return unless $self->{executable};
793 2 50       151     $parse_conf_file->($self) unless exists $self->{user};
794             # Handle an unknown value.
795                 $self->{user} = $self->unknown( key => 'apache user',
796                                                 prompt => 'Enter Apache user name',
797 0     0   0                                     callback => sub { getpwnam $_ },
798 2 50       28                                     error => "Not a user")
799                   unless $self->{user};
800 2         33     return $self->{user};
801             }
802              
803             ##############################################################################
804              
805             =head3 group
806            
807             Returns the name of the Apache user group. This value is collected from the
808             Apache configuration file as returned by C<conf_file()>.
809            
810             B<Events:>
811            
812             =over 4
813            
814             =item info
815            
816             Searching for Apache configuration file
817            
818             Executing `httpd -V`
819            
820             Parsing Apache configuration file
821            
822             =item error
823            
824             No Apache config file found
825            
826             Cannot parse user from file
827            
828             Cannot parse group from file
829            
830             Cannot parse port from file
831            
832             =item unknown
833            
834             Location of httpd.conf file?
835            
836             Enter Apache user group name
837            
838             =back
839            
840             =cut
841              
842             sub group {
843 2     2 1 22     my $self = shift;
844 2 50       28     return unless $self->{executable};
845 2 50       26     $parse_conf_file->($self) unless exists $self->{group};
846             # Handle an unknown value.
847                 $self->{group} =
848                   $self->unknown( key => 'apache group',
849                                   prompt => 'Enter Apache user group name',
850 0     0   0                       callback => sub { getgrnam $_ },
851 2 50       28                       error => "Not a user group")
852                   unless $self->{group};
853 2         31     return $self->{group};
854             }
855              
856             ##############################################################################
857              
858             =head3 port
859            
860             Returns the port number on which Apache listens. This value is collected from
861             Apache configuration file as returned by C<conf_file()>.
862            
863             B<Events:>
864            
865             =over 4
866            
867             =item info
868            
869             Searching for Apache configuration file
870            
871             Executing `httpd -V`
872            
873             Parsing Apache configuration file
874            
875             =item error
876            
877             No Apache config file found
878            
879             Cannot parse user from file
880            
881             Cannot parse group from file
882            
883             Cannot parse port from file
884            
885             =item unknown
886            
887             Location of httpd.conf file?
888            
889             Enter Apache TCP/IP port number
890            
891             =back
892            
893             =cut
894              
895             sub port {
896 2     2 1 32     my $self = shift;
897 2 50       28     return unless $self->{executable};
898 2 50       28     $parse_conf_file->($self) unless exists $self->{port};
899             # Handle an unknown value.
900 2 50       26     $self->{port} =
901                   $self->unknown( key => 'apache port',
902                                   prompt => 'Enter Apache TCP/IP port number',
903                                   callback => $is_int,
904                                   error => "Not a valid port number")
905                   unless $self->{port};
906 2         32     return $self->{port};
907             }
908              
909             ##############################################################################
910              
911             =head3 executable
912            
913             my $executable = $apache->executable;
914            
915             Returns the path to the Apache executable, which will be defined by one of the
916             names returned by C<search_exe_names()>. The executable is searched for in
917             C<new()>, so there are no events for this method.
918            
919             =head3 httpd
920            
921             my $httpd = $apache->httpd;
922            
923             An alias for C<executable()>.
924            
925             =cut
926              
927 4     4 1 69 sub executable { shift->{executable} }
928              
929             ##############################################################################
930              
931             =head3 bin_dir
932            
933             my $bin_dir = $apache->bin_dir;
934            
935             Returns the SQLite binary directory path. App::Info::HTTPD::Apache simply
936             retreives it as the directory part of the path to the HTTPD executable.
937            
938             =cut
939              
940             sub bin_dir {
941 4     4 1 47     my $self = shift;
942 4 50       319     return unless $self->{executable};
943 4 100       50     unless (exists $self->{bin_dir} ) {
944 2         329         my @parts = $u->splitpath($self->{executable});
945 2 50       378         $self->{bin_dir} = $u->catdir(
946                         ($parts[0] eq '' ? () : $parts[0]),
947                         $u->splitdir($parts[1])
948                     );
949                 }
950 4         67     return $self->{bin_dir};
951             }
952              
953             ##############################################################################
954              
955             =head3 inc_dir
956            
957             my $inc_dir = $apache->inc_dir;
958            
959             Returns the Apache include directory path. App::Info::HTTPD::Apache simply
960             looks for the F<include> or F<inc> directory under the F<httpd_root>
961             directory, as returned by C<httpd_root()>.
962            
963             B<Events:>
964            
965             =over 4
966            
967             =item info
968            
969             Executing `httpd -V`
970            
971             Searching for include directory
972            
973             =item error
974            
975             Unable to extract compile settings from `httpd -V`
976            
977             Cannot parse HTTPD root from `httpd -V`
978            
979             Cannot find include directory
980            
981             =item unknown
982            
983             Enter a valid HTTPD root
984            
985             Enter a valid Apache include directory
986            
987             =back
988            
989             =cut
990              
991             sub inc_dir {
992 2     2 1 22     my $self = shift;
993 2 50       26     return unless $self->{executable};
994 2 50 33     28     unless (exists $self->{inc_dir}) {{
  2         25  
995 2         20         my $root = $self->httpd_root || last; # Double braces allow this.
996 2         33         $self->info("Searching for include directory");
997 2 50       32         $self->{inc_dir} = $u->first_dir($self->search_inc_dirs)
998                       or $self->error("Cannot find include directory");
999                 }}
1000             # Handle unknown value.
1001 2 50       28     $self->{inc_dir} = $self->unknown( key => 'apache inc dir',
1002                                                    callback => $is_dir)
1003                   unless $self->{inc_dir};
1004 2         30     return $self->{inc_dir};
1005             }
1006              
1007             ##############################################################################
1008              
1009             =head3 lib_dir
1010            
1011             my $lib_dir = $apache->lib_dir;
1012            
1013             Returns the Apache library directory path. App::Info::HTTPD::Apache simply
1014             looks for the F<lib>, F<modules>, or F<libexec> directory under the HTTPD
1015             root> directory, as returned by C<httpd_root()>.
1016            
1017             B<Events:>
1018            
1019             =over 4
1020            
1021             =item info
1022            
1023             Executing `httpd -V`
1024            
1025             Searching for library directory
1026            
1027             =item error
1028            
1029             Unable to extract compile settings from `httpd -V`
1030            
1031             Cannot parse HTTPD root from `httpd -V`
1032            
1033             Cannot find library directory
1034            
1035             =item unknown
1036            
1037             Enter a valid HTTPD root
1038            
1039             Enter a valid Apache library directory
1040            
1041             =back
1042            
1043             =cut
1044              
1045             sub lib_dir {
1046 4     4 1 42     my $self = shift;
1047 4 50       51     return unless $self->{executable};
1048 4 100       51     unless (exists $self->{lib_dir}) {
1049 2 50       27         if ($self->httpd_root) {
1050 2         30             $self->info("Searching for library directory");
1051 2 50       74             if (my $d = $u->first_dir($self->search_lib_dirs)) {
1052 2         23                 $self->{lib_dir} = $d;
1053                         } else {
1054 0         0                 $self->error("Cannot find library direcory");
1055                         }
1056                     } else {
1057             # Handle unknown value.
1058 0         0             $self->{lib_dir} = $self->unknown(
1059                             key => 'apache lib dir',
1060                             callback => $is_dir
1061                         );
1062                     }
1063              
1064                 }
1065 4         65     return $self->{lib_dir};
1066             }
1067              
1068             ##############################################################################
1069              
1070             =head3 so_lib_dir
1071            
1072             my $so_lib_dir = $apache->so_lib_dir;
1073            
1074             Returns the Apache shared object library directory path. Currently, this
1075             directory is assumed to be the same as the lib directory, so this method is
1076             simply an alias for C<lib_dir>.
1077            
1078             B<Events:>
1079            
1080             =over 4
1081            
1082             =item info
1083            
1084             Executing `httpd -V`
1085            
1086             Searching for library directory
1087            
1088             =item error
1089            
1090             Unable to extract compile settings from `httpd -V`
1091            
1092             Cannot parse HTTPD root from `httpd -V`
1093            
1094             Cannot find library directory
1095            
1096             =item unknown
1097            
1098             Enter a valid HTTPD root
1099            
1100             Enter a valid Apache library directory
1101            
1102             =back
1103            
1104             =cut
1105              
1106             # For now, at least, these seem to be the same.
1107             *so_lib_dir = \&lib_dir;
1108              
1109             ##############################################################################
1110              
1111             =head3 static_mods
1112            
1113             Returns a list (in an array context) or an anonymous array (in a scalar
1114             context) of all of the modules statically compiled into Apache. These are
1115             collected from the system call C<`httpd -l`>. If Apache is not installed,
1116             C<static_mods()> returns an empty list in an array context or an empty
1117             anonymous array in a scalar context.
1118            
1119             B<Events:>
1120            
1121             =over 4
1122            
1123             =item info
1124            
1125             Executing `httpd -l`
1126            
1127             =item error
1128            
1129             Unable to extract needed data from `httpd -l`
1130            
1131             =back
1132            
1133             =cut
1134              
1135             # This code reference collects the list of static modules from Apache. Used by
1136             # static_mods(), mod_perl(), or mod_so(), whichever gets called first.
1137             my $get_static_mods = sub {
1138                 my $self = shift;
1139                 $self->{static_mods} = undef;
1140                 $self->info(qq{Executing `"$self->{executable}" -l`});
1141                 my $data = `"$self->{executable}" -l`;
1142                 unless ($data) {
1143                     $self->error("Unable to extract needed data from ".
1144                                  qq{`"$self->{executable}" -l`});
1145                     return;
1146                 }
1147              
1148             # Parse out the modules.
1149                 my @mods;
1150                 while ($data =~ /^\s*(\w+)\.c\s*$/mg) {
1151                     push @mods, $1;
1152                     $self->{mod_so} = 1 if $1 eq 'mod_so';
1153                     $self->{mod_perl} = 1 if $1 eq 'mod_perl';
1154                 }
1155                 $self->{static_mods} = \@mods if @mods;
1156             };
1157              
1158             sub static_mods {
1159 2     2 1 22     my $self = shift;
1160 2 50       27     return unless $self->{executable};
1161 2 50       25     $get_static_mods->($self) unless exists $self->{static_mods};
1162 2 50       26     return unless $self->{static_mods};
1163 2 50       133     return wantarray ? @{$self->{static_mods}} : $self->{static_mods};
  0         0  
1164             }
1165              
1166             ##############################################################################
1167              
1168             =head3 shared_mods
1169            
1170             Returns a list (in an array context) or an anonymous array (in a scalar
1171             context) of all of the shared modules compiled for Apache. These are collected
1172             by searching for all files ending in F<.so> in the directory returned from the
1173             system call C<`apxs -q LIBEXECDIR`>. If Apache is not installed,
1174             C<shared_mods()> returns an empty list in an array context or an empty
1175             anonymous array in a scalar context.
1176            
1177             B<Events:>
1178            
1179             =over 4
1180            
1181             =item info
1182            
1183             Looking for apxs
1184            
1185             Executing `apxs -q LIBEXECDIR`
1186            
1187             =item error
1188            
1189             Unable to extract module directory name from `apxs -q LIBEXECDIR`
1190            
1191             =back
1192            
1193             =cut
1194              
1195             # This code reference collects the list of static modules from Apache. Used by
1196             # static_mods() and mod_perl(), whichever gets called first.
1197             my $get_shared_mods = sub {
1198                 my $self = shift;
1199                 my $apxs = $self->apxs or return;
1200              
1201                 $self->info(qq{Executing `"$apxs" -q LIBEXECDIR`});
1202                 my $mod_dir = `"$apxs" -q LIBEXECDIR`;
1203                 chomp $mod_dir;
1204              
1205                 return $self->error(
1206                     qq{Unable to extract module directory name `"$apxs" -q LIBEXECDIR`}
1207                 ) unless $mod_dir && -d $mod_dir;
1208              
1209                 $self->{so_mods} = $u->files_in_dir( $mod_dir, sub { s/\.so$//} );
1210                 $self->{mod_perl} ||= grep { /perl/ } @{ $self->{so_mods} };
1211             };
1212              
1213             sub shared_mods {
1214 1     1 1 10     my $self = shift;
1215 1 50       15     return unless $self->{executable};
1216 1 50       14     $get_shared_mods->($self) unless exists $self->{so_mods};
1217 1 50       13     return unless $self->{static_mods};
1218 1 50       12     return wantarray ? @{$self->{so_mods}} : $self->{so_mods};
  1         69  
1219             }
1220              
1221             ##############################################################################
1222              
1223             =head3 mod_so
1224            
1225             Boolean method that returns true when mod_so has been compiled into Apache,
1226             and false if it has not. The presence or absence of mod_so is determined by
1227             the system call C<`httpd -l`>.
1228            
1229             B<Events:>
1230            
1231             =over 4
1232            
1233             =item info
1234            
1235             Executing `httpd -l`
1236            
1237             =item error
1238            
1239             Unable to extract needed data from `httpd -l`
1240            
1241             =back
1242            
1243             =cut
1244              
1245             sub mod_so {
1246 2     2 1 23     my $self = shift;
1247 2 50       26     return unless $self->{executable};
1248 2 50       28     $get_static_mods->($self) unless exists $self->{static_mods};
1249 2         31     return $self->{mod_so};
1250             }
1251              
1252             ##############################################################################
1253              
1254             =head3 mod_perl
1255            
1256             Boolean method that returns true when mod_perl has been statically compiled
1257             into Apache, and false if it has not. The presence or absence of mod_perl is
1258             determined by the system call C<`httpd -l`> or, for a dynamic mod_perl, by the
1259             contents of the directory returned by the system call C<`apxs -q LIBEXECDIR`>.
1260            
1261             B<Events:>
1262            
1263             =over 4
1264            
1265             =item info
1266            
1267             Executing `httpd -l`
1268            
1269             Looking for apxs
1270            
1271             Executing `apxs -q LIBEXECDIR`
1272            
1273             =item error
1274            
1275             Unable to extract needed data from `httpd -l`
1276            
1277             =back
1278            
1279             =cut
1280              
1281             sub mod_perl {
1282 2     2 1 22     my $self = shift;
1283 2 50       28     return unless $self->{executable};
1284 2 50       93     $get_static_mods->($self) unless exists $self->{static_mods};
1285 2 100 66     232     $get_shared_mods->($self)
1286                     unless $self->{mod_perl} || exists $self->{so_mods};
1287 2         563     return $self->{mod_perl};
1288             }
1289              
1290             ##############################################################################
1291              
1292             =head3 home_url
1293            
1294             my $home_url = $apache->home_url;
1295            
1296             Returns the Apache home page URL.
1297            
1298             =cut
1299              
1300 2     2 1 32 sub home_url { "http://httpd.apache.org/" }
1301              
1302             ##############################################################################
1303              
1304             =head3 download_url
1305            
1306             my $download_url = $apache->download_url;
1307            
1308             Returns the Apache download URL.
1309            
1310             =cut
1311              
1312 2     2 1 30 sub download_url { "http://www.apache.org/dist/httpd/" }
1313              
1314             ##############################################################################
1315              
1316             =head3 search_exe_names
1317            
1318             my @search_exe_names = $apache->search_exe_names;
1319            
1320             Returns a list of possible names for the Apache executabl; F<.exe> is appended
1321             to each on Win32. By default, the names are:
1322            
1323             =over
1324            
1325             =item httpd
1326            
1327             =item httpd2
1328            
1329             =item apache-perl
1330            
1331             =item apache
1332            
1333             =item apache2
1334            
1335             =back
1336            
1337             =cut
1338              
1339             sub search_exe_names {
1340 2     2 1 21     my $self = shift;
1341 2         23     my @exes = qw(httpd httpd2 apache-perl apache apache2);
1342 2         18     if (WIN32) { $_ .= ".exe" for @exes }
1343 2         47     return ( $self->SUPER::search_exe_names, @exes );
1344             }
1345              
1346             ##############################################################################
1347              
1348             =head3 search_bin_dirs
1349            
1350             my @search_bin_dirs = $apache->search_bin_dirs;
1351            
1352             Returns a list of possible directories in which to search an executable. Used
1353             by the C<new()> constructor to find an executable to execute and collect
1354             application info. The found directory will also be returned by the C<bin_dir>
1355             method.
1356            
1357             The list of directories by default consists of the path as defined by C<<
1358             File::Spec->path >> and the value returned by
1359             C<< Apache2::BuildConfig->new->{APXS_BINDIR} >> (if Apache2::BuildConfig is
1360             installed), as well as the following directories:
1361            
1362             =over 4
1363            
1364             =item /usr/local/apache/bin
1365            
1366             =item /usr/local/apache2/bin
1367            
1368             =item /opt/apache/bin
1369            
1370             =item /opt/apache2/bin
1371            
1372             =item /usr/local/bin
1373            
1374             =item /usr/local/sbin
1375            
1376             =item /usr/bin
1377            
1378             =item /usr/sbin
1379            
1380             =item /bin
1381            
1382             =item /etc/httpd/bin
1383            
1384             =item /etc/apache/bin
1385            
1386             =item /etc/apache2/bin
1387            
1388             =item /home/httpd/bin
1389            
1390             =item /home/apache/bin
1391            
1392             =item /home/apache2/bin
1393            
1394             =item /sw/bin
1395            
1396             =item /sw/sbin
1397            
1398             =item /web/httpd
1399            
1400             =back
1401            
1402             =cut
1403              
1404             sub search_bin_dirs {
1405             # See if mod_perl2 knows where Apache is installed.
1406 2     2 1 213     eval { require Apache2::BuildConfig };
  2         64  
1407 2 50       49     my @path = $@ ? () : Apache2::BuildConfig->new->{APXS_BINDIR};
1408                 return (
1409                     shift->SUPER::search_bin_dirs,
1410 2         26         $u->path,
1411                     @path,
1412                     qw(
1413             /usr/local/apache/bin
1414             /usr/local/apache2/bin
1415             /opt/apache/bin
1416             /opt/apache2/bin
1417             /usr/local/bin
1418             /usr/local/sbin
1419             /usr/bin
1420             /usr/sbin
1421             /bin
1422             /etc/httpd/bin
1423             /etc/apache/bin
1424             /etc/apache2/bin
1425             /home/httpd/bin
1426             /home/apache2/bin
1427             /home/apache/bin
1428             /sw/bin
1429             /sw/sbin
1430             /web/httpd
1431             )
1432                 );
1433             }
1434              
1435             ##############################################################################
1436              
1437             =head3 search_lib_dirs
1438            
1439             my @search_lib_dirs = $apache->search_lib_dirs;
1440            
1441             Returns a list of possible directories in which to search for Apache
1442             libraries. By default, it returns this list of directories, each appended to
1443             the name of the directory returned by C<httpd_root()>:
1444            
1445             =over 4
1446            
1447             =item lib
1448            
1449             =item modules
1450            
1451             =item libexec
1452            
1453             =back
1454            
1455             =cut
1456              
1457             sub search_lib_dirs {
1458 2     2 1 22     my $self = shift;
1459 2         24     my $root = $self->httpd_root;
1460                 return (
1461 6         280         $self->SUPER::search_lib_dirs,
1462                     ( $root
1463 2 50       129           ? map { $u->catdir($root, $_) } qw(lib libexec modules)
1464                       : ()
1465                     ),
1466                     '/usr/lib/apache/1.3',
1467                     '/usr/lib/apache/2.0',
1468                 );
1469             }
1470              
1471             ##############################################################################
1472              
1473             =head3 search_inc_dirs
1474            
1475             my @search_inc_dirs = $apache->search_inc_dirs;
1476            
1477             Returns a list of possible directories in which to search for Apache include
1478             files. By default, it returns this list of directories, each appended to the
1479             name of the directory returned by C<httpd_root()>:
1480            
1481             =over 4
1482            
1483             =item include
1484            
1485             =item inc
1486            
1487             =back
1488            
1489             =cut
1490              
1491             sub search_inc_dirs {
1492 2     2 1 19     my $self = shift;
1493 2         24     my $root = $self->httpd_root;
1494                 return (
1495 4         170       $self->SUPER::search_inc_dirs,
1496                   ( $root
1497 2 50       171         ? map { $u->catdir($root, $_) } qw(include inc)
1498                     : ()
1499                   ),
1500                 );
1501             }
1502              
1503             ##############################################################################
1504              
1505             =head3 search_conf_names
1506            
1507             my @search_conf_dirs = $apache->search_conf_dirs;
1508            
1509             Returns a list of possible names for Apache configuration files. These will be
1510             used bye the C<conf_file()> method to search for Apache configuration files.
1511             By Default, the possible configuration file names are:
1512            
1513             =over 4
1514            
1515             =item F<httpd.conf>
1516            
1517             =item F<httpd.conf.default>
1518            
1519             =back
1520            
1521             =cut
1522              
1523             sub search_conf_names {
1524                 return (
1525 2     2 1 21       @{ shift->{search_conf_names} },
  2         33  
1526                   qw(httpd.conf httpd.conf.default)
1527                 );
1528             }
1529              
1530             ##############################################################################
1531              
1532             =head3 search_conf_dirs
1533            
1534             my @search_conf_dirs = $apache->search_conf_dirs;
1535            
1536             Returns a list of directories in which the C<conf_file()> method will search
1537             for Apache configuration files.
1538            
1539             =over 4
1540            
1541             =item /usr/share/doc/apache-perl
1542            
1543             =item /etc/httpd
1544            
1545             =back
1546            
1547             =cut
1548              
1549             sub search_conf_dirs {
1550                 return (
1551 2     2 1 20       @{ shift->{search_conf_dirs} },
  2         90  
1552                   qw(/usr/share/doc/apache-perl /etc/httpd)
1553                 );
1554             }
1555              
1556             ##############################################################################
1557              
1558             =head2 Other Executable Methods
1559            
1560             These methods return the complete paths to their like-named executables.
1561             Apache comes with a fair number of them; we provide these methods to provide a
1562             path to a subset of them. Each method, when called, checks for an executable
1563             in the directory returned by C<bin_dir()>. The name of the executable must be
1564             one of the names returned by the corresponding C<search_*_names> method.
1565            
1566             The available executable methods are:
1567            
1568             =over
1569            
1570             =item ab
1571            
1572             =item apachectl
1573            
1574             =item apxs
1575            
1576             =item htdigest
1577            
1578             =item htpasswd
1579            
1580             =item logresolve
1581            
1582             =item rotatelogs
1583            
1584             =back
1585            
1586             And the corresponding search names methods are:
1587            
1588             =over
1589            
1590             =item search_ab_names
1591            
1592             =item search_apachectl_names
1593            
1594             =item search_apxs_names
1595            
1596             =item search_htdigest_names
1597            
1598             =item search_htpasswd_names
1599            
1600             =item search_logresolve_names
1601            
1602             =item search_rotatelogs_names
1603            
1604             =back
1605            
1606             B<Events:>
1607            
1608             =over 4
1609            
1610             =item info
1611            
1612             Looking for executable
1613            
1614             =item confirm
1615            
1616             Path to executable?
1617            
1618             =item unknown
1619            
1620             Path to executable?
1621            
1622             =back
1623            
1624             =cut
1625              
1626             my $find_exe = sub {
1627                 my ($self, $key) = @_;
1628                 my $exe = $key . (WIN32 ? '.exe' : '');
1629                 my $meth = "search_$key\_names";
1630              
1631             # Find executable.
1632                 $self->info("Looking for $key");
1633              
1634                 unless ($self->{$key}) {
1635                     my $bin = $self->bin_dir or return;
1636                     if (my $exe = $u->first_cat_exe([$self->$meth(), $exe], $bin)) {
1637             # We found it. Confirm.
1638                         $self->{$key} = $self->confirm(
1639                             key => "path to $key",
1640                             prompt => "Path to $key executable?",
1641                             value => $exe,
1642                             callback => sub { -x },
1643                             error => 'Not an executable'
1644                         );
1645                     } else {
1646             # Handle an unknown value.