File Coverage

blib/lib/App/Info/HTTPD/Apache.pm
Criterion Covered Total %
statement 186 201 92.5
branch 102 160 63.7
condition 5 17 29.4
subroutine 43 48 89.5
pod 34 34 100.0
total 370 460 80.4


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