File Coverage

blib/lib/Config/ApacheFormat.pm
Criterion Covered Total %
statement 229 253 90.5
branch 114 158 72.1
condition 39 57 68.4
subroutine 19 21 90.4
pod 5 6 83.3
total 406 495 82.0


line stmt bran cond sub pod time code
1             package Config::ApacheFormat;
2 12     12   480693 use 5.006001;
  12         48  
  12         542  
3 12     12   69 use strict;
  12         23  
  12         448  
4 12     12   58 use warnings;
  12         27  
  12         1724  
5             our $VERSION = '1.2';
6              
7             =head1 NAME
8              
9             Config::ApacheFormat - use Apache format config files
10              
11             =head1 SYNOPSIS
12              
13             Config files used with this module are in Apache's format:
14              
15             # comment here
16             RootDir /path/foo
17             LogDir /path/foo/log
18             Colors red green orange blue \
19             black teal
20              
21             <Directory /path/foo>
22             # override Colors inside block
23             Colors red blue black
24             </Directory>
25            
26             Code to use this config file might look like:
27              
28             use Config::ApacheFormat;
29              
30             # load a conf file
31             my $config = Config::ApacheFormat->new();
32             $config->read("my.conf");
33              
34             # access some parameters
35             $root_dir = $config->get("RootDir");
36             $log_dir = $config->get("LogDir");
37             @colors = $config->get("colors");
38              
39             # using the autoloaded methods
40             $config->autoload_support(1);
41             $root_dir = $config->RootDir;
42             $log_dir = $config->logdir;
43              
44             # access parameters inside a block
45             my $block = $config->block(Directory => "/path/foo");
46             @colors = $block->get("colors");
47             $root_dir = $block->get("root_dir");
48              
49             =head1 DESCRIPTION
50              
51             This module is designed to parse a configuration file in the same
52             syntax used by the Apache web server (see http://httpd.apache.org for
53             details). This allows you to build applications which can be easily
54             managed by experienced Apache admins. Also, by using this module,
55             you'll benefit from the support for nested blocks with built-in
56             parameter inheritance. This can greatly reduce the amount or repeated
57             information in your configuration files.
58              
59             A good reference to the Apache configuration file format can be found
60             here:
61              
62             http://httpd.apache.org/docs-2.0/configuring.html
63              
64             To quote from that document, concerning directive syntax:
65              
66             Apache configuration files contain one directive per line. The
67             back-slash "\" may be used as the last character on a line to
68             indicate that the directive continues onto the next line. There must
69             be no other characters or white space between the back-slash and the
70             end of the line.
71              
72             Directives in the configuration files are case-insensitive, but
73             arguments to directives are often case sensitive. Lines that begin
74             with the hash character "#" are considered comments, and are
75             ignored. Comments may not be included on a line after a configuration
76             directive. Blank lines and white space occurring before a directive
77             are ignored, so you may indent directives for clarity.
78              
79             And block notation:
80              
81             Directives placed in the main configuration files apply to the entire
82             server. If you wish to change the configuration for only a part of the
83             server, you can scope your directives by placing them in <Directory>,
84             <DirectoryMatch>, <Files>, <FilesMatch>, <Location>, and
85             <LocationMatch> sections. These sections limit the application of the
86             directives which they enclose to particular filesystem locations or
87             URLs. They can also be nested, allowing for very fine grained
88             configuration.
89              
90             This module will parse actual Apache configuration files, but you will need to set some options to non-default values. See L<"Parsing a Real Apache Config File">.
91              
92             =head1 METHODS
93              
94             =item $config = Config::ApacheFormat->new(opt => "value")
95              
96             This method creates an object that can then be used to read configuration
97             files. It does not actually read any files; for that, use the C<read()>
98             method below. The object supports the following attributes, all of which
99             may be set through C<new()>:
100              
101             =over 4
102              
103             =item inheritance_support
104              
105             Set this to 0 to turn off the inheritance feature. Block inheritance
106             means that variables declared outside a block are available from
107             inside the block unless overriden. Defaults to 1.
108              
109             =item include_support
110              
111             When this is set to 1, the directive "Include" will be treated
112             specially by the parser. It will cause the value to be treated as a
113             filename and that filename will be read in. If you use "Include"
114             with a directory, every file in that directory will be included.
115             This matches Apache's behavior and allows users to break up
116             configuration files into multiple, possibly shared, pieces.
117             Defaults to 1.
118              
119             =item autoload_support
120              
121             Set this to 1 and all your directives will be available as object
122             methods. So instead of:
123              
124             $config->get("foo");
125              
126             You can write:
127              
128             $config->foo;
129              
130             Defaults to 0.
131              
132             =item case_sensitive
133              
134             Set this to 1 to preserve the case of directive names. Otherwise, all
135             names will be C<lc()>ed and matched case-insensitively. Defaults to 0.
136              
137             =item fix_booleans
138              
139             If set to 1, then during parsing, the strings "Yes", "On", and "True"
140             will be converted to 1, and the strings "No", "Off", and "False" will
141             be converted to 0. This allows you to more easily use C<get()> in
142             conditional statements.
143              
144             For example:
145              
146             # httpd.conf
147             UseCanonicalName On
148              
149             Then in Perl:
150              
151             $config = Config::ApacheFormat->new(fix_booleans => 1);
152             $config->read("httpd.conf");
153              
154             if ($config->get("UseCanonicalName")) {
155             # this will get executed if set to Yes/On/True
156             }
157              
158             This option defaults to 0.
159              
160             =item expand_vars
161              
162             If set, then you can use variable expansion in your config file by
163             prefixing directives with a C<$>. Hopefully this seems logical to you:
164              
165             Website http://my.own.dom
166             JScript $Website/js
167             Images $Website/images
168              
169             Undefined variables in your config file will result in an error. To
170             use a literal C<$>, simply prefix it with a C<\> (backslash). Like
171             in Perl, you can use brackets to delimit the variables more precisely:
172              
173             Nickname Rob
174             Fullname ${Nickname}ert
175              
176             Since only scalars are supported, if you use a multi-value, you will
177             only get back the first one:
178              
179             Options Plus Minus "About the Same"
180             Values $Options
181              
182             In this examples, "Values" will become "Plus". This is seldom a limitation
183             since in most cases, variable subsitution is used like the first example
184             shows. This option defaults to 0.
185              
186             =item setenv_vars
187              
188             If this is set to 1, then the special C<SetEnv> directive will be set
189             values in the environment via C<%ENV>. Also, the special C<UnSetEnv>
190             directive will delete environment variables.
191              
192             For example:
193              
194             # $ENV{PATH} = "/usr/sbin:/usr/bin"
195             SetEnv PATH "/usr/sbin:/usr/bin"
196              
197             # $ENV{MY_SPECIAL_VAR} = 10
198             SetEnv MY_SPECIAL_VAR 10
199              
200             # delete $ENV{THIS}
201             UnsetEnv THIS
202              
203             This option defaults to 0.
204              
205             =item valid_directives
206              
207             If you provide an array of directive names then syntax errors will be
208             generated during parsing for invalid directives. Otherwise, any
209             directive name will be accepted. For exmaple, to only allow
210             directives called "Bar" and "Bif":
211              
212             $config = Config::ApacheFormat->new(
213             valid_directives => [qw(Bar Bif)],
214             );
215              
216             =item valid_blocks
217              
218             If you provide an array of block names then syntax errors will be
219             generated during parsing for invalid blocks. Otherwise, any block
220             name will be accepted. For exmaple, to only allow "Directory" and
221             "Location" blocks in your config file:
222              
223             $config = Config::ApacheFormat->new(
224             valid_blocks => [qw(Directory Location)],
225             );
226              
227             =item include_directives
228              
229             This directive controls the name of the include directive. By default
230             it is C<< ['Include'] >>, but you can set it to any list of directive
231             names.
232              
233             =item root_directive
234              
235             This controls what the root directive is, if any. If you set this to
236             the name of a directive it will be used as a base directory for
237             C<Include> processing. This mimics the behavior of C<ServerRoot> in
238             real Apache config files, and as such you'll want to set it to
239             'ServerRoot' when parsing an Apache config. The default is C<undef>.
240              
241             =item hash_directives
242              
243             This determines which directives (if any) should be parsed so that the
244             first value is actually a key into the remaining values. For example,
245             C<AddHandler> is such a directive.
246              
247             AddHandler cgi-script .cgi .sh
248             AddHandler server-parsed .shtml
249              
250             To parse this correctly, use:
251              
252             $config = Config::ApacheFormat->new(
253             hash_directives => [qw(AddHandler PerlSetVar)]
254             );
255              
256             Then, use the two-argument form of C<get()>:
257              
258             @values = $config->get(AddHandler => 'cgi-script');
259              
260             This allows you to access each directive individually, which is needed
261             to correctly handle certain special-case Apache settings.
262              
263             =item duplicate_directives
264              
265             This option controls how duplicate directives are handled. By default,
266             if multiple directives of the same name are encountered, the last one
267             wins:
268              
269             Port 8080
270             # ...
271             Port 5053
272              
273             In this case, the directive C<Port> would be set to the last value, C<5053>.
274             This is useful because it allows you to include other config files, which
275             you can then override:
276              
277             # default setup
278             Include /my/app/defaults.conf
279              
280             # override port
281             Port 5053
282              
283             In addition to this default behavior, C<Config::ApacheFormat> also supports
284             the following modes:
285              
286             last - the value from the last one is kept (default)
287             error - duplicate directives result in an error
288             combine - combine values of duplicate directives together
289              
290             These should be self-explanatory. If set to C<error>, any duplicates
291             will result in an error. If set to C<last> (the default), the last
292             value wins. If set to C<combine>, then duplicate directives are
293             combined together, just like they had been specified on the same line.
294              
295             =back
296              
297             All of the above attributes are also available as accessor methods. Thus,
298             this:
299              
300             $config = Config::ApacheFormat->new(inheritance_support => 0,
301             include_support => 1);
302              
303             Is equivalent to:
304              
305             $config = Config::ApacheFormat->new();
306             $config->inheritance_support(0);
307             $config->include_support(1);
308              
309             =over 4
310              
311             =cut
312              
313 12     12   68 use File::Spec;
  12         21  
  12         640  
314 12     12   76 use Carp qw(croak);
  12         25  
  12         1041  
315 12     12   25863 use Text::Balanced qw(extract_delimited extract_variable);
  12         482501  
  12         2087  
316 12     12   127 use Scalar::Util qw(weaken);
  12         24  
  12         2006  
317              
318             # this "placeholder" is used to handle escaped variables (\$)
319             # if it conflicts with a define in your config file somehow, simply
320             # override it with "$Config::ApacheFormat::PLACEHOLDER = 'whatever';"
321             our $PLACEHOLDER = "~PLaCE_h0LDeR_$$~";
322              
323             # declare generated methods
324             use Class::MethodMaker
325 12         203 new_with_init => "new",
326             new_hash_init => "hash_init",
327             get_set => [ -noclear => qw/
328             inheritance_support
329             include_support
330             autoload_support
331             case_sensitive
332             expand_vars
333             setenv_vars
334             valid_directives
335             valid_blocks
336             duplicate_directives
337             hash_directives
338             fix_booleans
339             root_directive
340             include_directives
341             _parent
342             _data
343             _block_vals
344 12     12   15069 /];
  12         359484  
345              
346             # setup defaults
347             sub init {
348 2267     2267 0 183230 my $self = shift;
349 2267         43464 my %args = (
350             inheritance_support => 1,
351             include_support => 1,
352             autoload_support => 0,
353             case_sensitive => 0,
354             expand_vars => 0,
355             setenv_vars => 0,
356             valid_directives => undef,
357             valid_blocks => undef,
358             duplicate_directives=> 'last',
359             include_directives => ['Include'],
360             hash_directives => undef,
361             fix_booleans => 0,
362             root_directive => undef,
363             _data => {},
364             @_);
365              
366             # could probably use a few more of these...
367 2267 0 33     10911 croak("Invalid duplicate_directives option '$self->{duplicate_directives}' - must be 'last', 'error', or 'combine'")
      33        
368             unless $args{duplicate_directives} eq 'last' or
369             $args{duplicate_directives} eq 'error' or
370             $args{duplicate_directives} eq 'combine';
371              
372 2267         94770 return $self->hash_init(%args);
373             }
374              
375             =item $config->read("my.conf");
376              
377             =item $config->read(\*FILE);
378              
379             Reads a configuration file into the config object. You must pass
380             either the path of the file to be read or a reference to an open
381             filehandle. If an error is encountered while reading the file, this
382             method will die().
383              
384             Calling read() more than once will add the new configuration values
385             from another source, overwriting any conflicting values. Call clear()
386             first if you want to read a new set from scratch.
387              
388             =cut
389              
390             # read the configuration file, optionally ending at block_name
391             sub read {
392 119     119 1 247019 my ($self, $file) = @_;
393              
394 119         231 my @fstack;
395              
396             # open the file if needed and setup file stack
397             my $fh;
398 119 50       671 if (ref $file) {
399 0         0 @fstack = { fh => $file,
400             filename => "",
401             line_num => 0 };
402             } else {
403 119 50       20708 open($fh, "<", $file) or croak("Unable to open file '$file': $!");
404 119         898 @fstack = { fh => $fh,
405             filename => $file,
406             line_num => 0 };
407             }
408            
409 119         631 return $self->_read(\@fstack);
410             }
411              
412             # underlying _read, called recursively an block name for
413             # nested block objects
414             sub _read {
415 2269     2269   24372 my ($self, $fstack, $block_name) = @_;
416              
417             # pre-fetch for loop
418 2269         4826 my $case_sensitive = $self->{case_sensitive};
419 2269         4244 my $data = $self->{_data};
420              
421             # pre-compute lookups for validation lists, if they exists
422 2269         3408 my ($validate_blocks, %valid_blocks,
423             $validate_directives, %valid_directives);
424 2269 100       6958 if ($self->{valid_directives}) {
425 5 50       19 %valid_directives = map { ($case_sensitive ? $_ : lc($_)), 1 }
  2         4  
426 2         2 @{$self->{valid_directives}};
427 2         3 $validate_directives = 1;
428             }
429 2269 100       5847 if ($self->{valid_blocks}) {
430 20 50       72 %valid_blocks = map { ($case_sensitive ? $_ : lc($_)), 1 }
  8         15  
431 8         13 @{$self->{valid_blocks}};
432 8         16 $validate_blocks = 1;
433             }
434              
435             # pre-compute a regex to recognize the include directives
436 2269         8865 my $re = '^(?:' .
437 2269         6750 join('|', @{$self->{include_directives}}) . ')$';
438 2269         3379 my $include_re;
439 2269 50       5139 if ($self->{case_sensitive}) {
440 0         0 $include_re = qr/$re/;
441             } else {
442 2269         20154 $include_re = qr/$re/i;
443             }
444              
445             # parse through the file, line by line
446 2269         3689 my ($name, $values, $line, $orig);
447 2269         8072 my ($fh, $filename) =
448 2269         3779 @{$fstack->[-1]}{qw(fh filename)};
449 2269         5551 my $line_num = \$fstack->[-1]{line_num};
450              
451             LINE:
452 2269         3013 while(1) {
453             # done with current file?
454 18593 100       59350 if (eof $fh) {
455 120 100       494 last LINE if @$fstack == 1;
456 7         11 pop @$fstack;
457 7         23 ($fh, $filename) =
458 7         21 @{$fstack->[-1]}{qw(fh filename)};
459 7         104 $line_num = \$fstack->[-1]{line_num};
460             }
461              
462             # accumulate a full line, dealing with line-continuation
463 18480         35738 $line = "";
464 18480   66     25321 do {
465 12     12   473090 no warnings 'uninitialized'; # blank warnings
  12         35  
  12         71015  
466 18483         70611 $_ = <$fh>;
467 18483         24648 ${$line_num}++;
  18483         42218  
468 18483         88543 s/^\s+//; # strip leading space
469 18483 100       51984 next LINE if /^#/; # skip comments
470 18017         64993 s/\s+$//; # strip trailing space
471 18017         76269 $line .= $_;
472             } while ($line =~ s/\\$// and not eof($fh));
473            
474             # skip blank lines
475 18014 100       41883 next LINE unless length $line;
476              
477             # parse line
478 16855 100       110805 if ($line =~ /^<\/(\w+)>$/) {
    100          
    100          
479             # end block
480 2149         4856 $orig = $name = $1;
481 2149 50       6218 $name = lc $name unless $case_sensitive; # lc($1) breaks on 5.6.1!
482              
483 2149 50 66     12978 croak("Error in config file $filename, line $$line_num: " .
    100          
484             "Unexpected end to block '$orig' found" .
485             (defined $block_name ?
486             "\nI was waiting for </$block_name>\n" : ""))
487             unless defined $block_name and $block_name eq $name;
488              
489             # this is our cue to return
490 2147         4388 last LINE;
491              
492             } elsif ($line =~ /^<(\w+)\s*(.*)>$/) {
493             # open block
494 2151         5247 $orig = $name = $1;
495 2151         4006 $values = $2;
496 2151 50       7210 $name = lc $name unless $case_sensitive;
497              
498 2151 100 100     5685 croak("Error in config file $filename, line $$line_num: " .
499             "block '<$orig>' is not a valid block name")
500             unless not $validate_blocks or
501             exists $valid_blocks{$name};
502            
503 2150         5050 my $val = [];
504 2150 100       10556 $val = _parse_value_list($values) if $values;
505              
506             # create new object for block, inheriting options from
507             # this object, with this object set as parent (using
508             # weaken() to avoid creating a circular reference that
509             # would leak memory)
510 2150         3400 my $parent = $self;
511 2150         7087 weaken($parent);
512 2150 50       102642 my $block = ref($self)->new(
513             inheritance_support => $self->{inheritance_support},
514             include_support => $self->{include_support},
515             autoload_support => $self->{autoload_support},
516             case_sensitive => $case_sensitive,
517             expand_vars => $self->{expand_vars},
518             setenv_vars => $self->{setenv_vars},
519             valid_directives => $self->{valid_directives},
520             valid_blocks => $self->{valid_blocks},
521             duplicate_directives=> $self->{duplicate_directives},
522             hash_directives => $self->{hash_directives},
523             fix_booleans => $self->{fix_booleans},
524             root_directive => $self->{root_directive},
525             include_directives => $self->{include_directives},
526             _parent => $parent,
527             _block_vals => ref $val ? $val : [ $val ],
528             );
529            
530             # tell the block to read from $fh up to the closing tag
531             # for this block
532 2150         4729689 $block->_read($fstack, $name);
533              
534             # store block for get() and block()
535 2147         2738 push @{$data->{$name}}, $block;
  2147         9453  
536              
537             } elsif ($line =~ /^(\w+)(?:\s+(.+))?$/) {
538             # directive
539 12554         31408 $orig = $name = $1;
540 12554         24498 $values = $2;
541 12554 100       28739 $values = 1 unless defined $values;
542 12554 50       47738 $name = lc $name unless $case_sensitive;
543              
544 12554 100 100     31418 croak("Error in config file $filename, line $$line_num: " .
545             "directive '$name' is not a valid directive name")
546             unless not $validate_directives or
547             exists $valid_directives{$name};
548              
549             # parse out values, handling any strings or arrays
550 12553         25494 my @val;
551 12553         31424 eval {
552 12553         38056 @val = _parse_value_list($values);
553             };
554 12553 50       33006 croak("Error in config file $filename, line $$line_num: $@")
555             if $@;
556              
557             # expand_vars if set
558 12553         16880 eval {
559 12553 100       59967 @val = $self->_expand_vars(@val) if $self->{expand_vars};
560             };
561 12553 50       23362 croak("Error in config file $filename, line $$line_num: $@")
562             if $@;
563              
564             # and then setenv too (allowing PATH "$BASEDIR/bin")
565 12553 100       41211 if ($self->{setenv_vars}) {
566 7 100       40 if ($name =~ /^setenv$/i) {
    100          
567 1 50       29 croak("Error in config file $filename, line $$line_num: ".
568             " can't use setenv_vars " .
569             "with malformed SetEnv directive") if @val != 2;
570 1         9 $ENV{"$val[0]"} = $val[1];
571             } elsif ($name =~ /^unsetenv$/i) {
572 1 50       3 croak("Error in config file $filename, line $$line_num: ".
573             "can't use setenv_vars " .
574             "with malformed UnsetEnv directive") unless @val;
575 1         10 delete $ENV{$_} for @val;
576             }
577             }
578              
579             # Include processing
580             # because of the way our inheritance works, we navigate multiple files in reverse
581 12553 100       62292 if ($name =~ /$include_re/) {
582 6         15 for my $f (reverse @val) {
583             # if they specified a root_directive (ServerRoot) and
584             # it is defined, prefix that to relative paths
585 7 50       830 my $root = $self->{case_sensitive} ? $self->{root_directive}
586             : lc $self->{root_directive};
587 7 100 66     128 if (! File::Spec->file_name_is_absolute($f) && exists $data->{$root}) {
588             # looks odd; but only reliable method is construct UNIX-style
589             # then deconstruct
590 1         18 my @parts = File::Spec->splitpath("$data->{$root}[0]/$f");
591 1         11 $f = File::Spec->catpath(@parts);
592             }
593              
594             # this handles directory includes (i.e. will include all files in a directory)
595 7         21 my @files;
596 7 100       624 if (-d $f) {
597 1 50       49 opendir(INCD, $f)
598             || croak("Cannot open include directory '$f' at $filename ",
599             "line $$line_num: $!");
600 1         51 @files = map { "$f/$_" } sort grep { -f "$f/$_" } readdir INCD;
  3         9  
  5         67  
601 1         15 closedir(INCD);
602             } else {
603 6         17 @files = $f;
604             }
605              
606 7         17 for my $values (reverse @files) {
607             # just try to open it as-is
608 9         11 my $include_fh;
609 9 100       263 unless (open($include_fh, "<", $values)) {
610 4 50       15 if ($fstack->[0]{filename}) {
611             # try opening it relative to the enclosing file
612             # using File::Spec
613 4         77 my @parts = File::Spec->splitpath($filename);
614 4         11 $parts[-1] = $values;
615 4 100       578 open($include_fh, "<", File::Spec->catpath(@parts)) or
616             croak("Unable to open include file '$values' ",
617             "at $filename line $$line_num: $!");
618             } else {
619 0         0 croak("Unable to open include file '$values' ",
620             "at $filename line $$line_num: $!");
621             }
622             }
623              
624             # push a new record onto the @fstack for this file
625 8         51 push(@$fstack, { fh => $fh = $include_fh,
626             filename => $filename = $values,
627             line_number => 0 });
628              
629             # hook up line counter
630 8         43 $line_num = \$fstack->[-1]{line_num};
631             }
632             }
633 5         15 next LINE;
634             }
635              
636             # for each @val, "fix" booleans if so requested
637             # do this *after* include processing so "include yes.conf" works
638 12547 100       28725 if ($self->{fix_booleans}) {
639 6         11 for (@val) {
640 6 100 100     75 if (/^true$/i or /^on$/i or /^yes$/i) {
    50 100        
      100        
      66        
641 3         9 $_ = 1;
642             } elsif (/^false$/i or /^off$/i or /^no$/i) {
643 3         9 $_ = 0;
644             }
645             }
646             }
647              
648             # how to handle repeated values
649             # this is complicated because we have to allow a semi-union of
650             # the hash_directives and duplicate_directives options
651              
652 12547 100 100     59126 if ($self->{hash_directives}
653             && _member($orig,
654             $self->{hash_directives}, $self->{case_sensitive})){
655 510         1209 my $k = shift @val;
656 510 50       2220 if ($self->{duplicate_directives} eq 'error') {
    50          
657             # must check for a *specific* dup
658 0 0       0 croak "Duplicate directive '$orig $k' at $filename line $$line_num"
659             if $data->{$name}{$k};
660 0         0 push @{$data->{$name}{$k}}, @val;
  0         0  
661             }
662             elsif ($self->{duplicate_directives} eq 'last') {
663 510         2380 $data->{$name}{$k} = \@val;
664             }
665             else {
666             # push onto our struct to allow repeated declarations
667 0         0 push @{$data->{$name}{$k}}, @val;
  0         0  
668             }
669             } else {
670 12037 50       41075 if ($self->{duplicate_directives} eq 'error') {
    50          
671             # not a hash_directive, so all dups are errors
672 0 0       0 croak "Duplicate directive '$orig' at $filename line $$line_num"
673             if $data->{$name};
674 0         0 push @{$data->{$name}}, @val;
  0         0  
675             }
676             elsif ($self->{duplicate_directives} eq 'last') {
677 12037         43394 $data->{$name} = \@val;
678             }
679             else {
680             # push onto our struct to allow repeated declarations
681 0         0 push @{$data->{$name}}, @val;
  0         0  
682             }
683             }
684              
685             } else {
686 1         219 croak("Error in config file $filename, line $$line_num: ".
687             "unable to parse line");
688             }
689             }
690              
691 2260         19346 return $self;
692             }
693              
694             # given a string returns a list of tokens, allowing for quoted strings
695             # and otherwise splitting on whitespace
696             sub _parse_value_list {
697 14596     14596   27110 my $values = shift;
698              
699 14596         19497 my @val;
700 14596 100       74432 if ($values !~ /['"\s]/) {
    100          
701             # handle the common case of a single unquoted string
702 7719         17986 @val = ($values);
703             } elsif ($values !~ /['"]/) {
704             # strings without any quote characters can be parsed with split
705 6751         23751 @val = split /\s+/, $values;
706             } else {
707             # break apart line, allowing for quoted strings with
708             # escaping
709 126         337 while($values) {
710 212         236 my $val;
711 212 100       651 if ($values !~ /^["']/) {
712             # strip off a value and put it where it belongs
713 86         497 ($val, $values) = $values =~ /^(\S+)\s*(.*)$/;
714             } else {
715             # starts with a quote, bring in the big guns
716 126         510 $val = extract_delimited($values, q{"'});
717 126 50       20039 die "value string '$values' not properly formatted\n"
718             unless length $val;
719            
720             # remove quotes and fixup escaped characters
721 126         250 $val = substr($val, 1, length($val) - 2);
722 126         269 $val =~ s/\\(['"])/$1/g;
723              
724             # strip off any leftover space
725 126         502 $values =~ s/^\s*//;
726             }
727 212         697 push(@val, $val);
728             }
729             }
730 14596 50       34896 die "no value found for directive\n" unless @val;
731              
732 14596 100       77531 return wantarray ? @val : \@val;
733             }
734              
735             # expand any $var stuff if expand_vars is set
736             sub _expand_vars {
737 23     23   31 my $self = shift;
738 23         51 my @vals = @_;
739 23         42 for (@vals) {
740 26         68 local $^W = 0; # shuddup uninit
741 26         47 s/\\\$/$PLACEHOLDER/g; # kludge but works (Text::Balanced broken)
742 26         70 s/\$\{?(\w+)\}?/
743 16         30 my $var = $1;
744 16         37 my $val = $self->get($var);
745 16 50       44 die "undefined variable '\$$var' seen\n" unless defined $val;
746 16         63 $val;
747             /ge;
748 26         122 s/$PLACEHOLDER/\$/g; # redo placeholders, removing escaping
749             }
750 23         133 return @vals;
751             }
752              
753             sub _member {
754             # simple "in" style sub
755 11751     11751   28606 my($name, $hdir, $case) = @_;
756 11751 50       37983 $name = lc $name unless $case;
757 11751 50 33     62918 return unless $hdir && ref $hdir eq 'ARRAY';
758 11751         32991 for (@$hdir) {
759 11751 50       28709 $_ = lc $_ unless $case;
760 11751 100       40061 return 1 if $name eq $_;
761             }
762 11241         59567 return;
763             }
764              
765             =item C<< $value = $config->get("var_name") >>
766              
767             =item C<< @vals = $config->get("list_name") >>
768              
769             =item C<< $value = $config->get("hash_var_name", "key") >>
770              
771             Returns values from the configuration file. If the directive contains
772             a single value, it will be returned. If the directive contains a list
773             of values then they will be returned as a list. If the directive does
774             not exist in the configuration file then nothing will be returned
775             (undef in scalar context, empty list in list context).
776              
777             For example, given this confiuration file:
778              
779             Foo 1
780             Bar bif baz bop
781              
782             The following code would work as expected:
783              
784             my $foo = $config->get("Foo"); # $foo = 1
785             my @bar = $config->get("Bar"); # @bar = ("bif", "baz", "bop")
786              
787             If the name is the name of a block tag in the configuration file then
788             a list of available block specifiers will be returned. For example,
789             given this configuration file:
790              
791             <Site big>
792             Size 10
793             </Site>
794              
795             <Site small>
796             Size 1
797             </Site>
798              
799             This call:
800              
801             @sites = $config->get("Site");
802              
803             Will return C<([ Site => "big"], [ Site => "small" ])>. These arrays
804             can then be used with the block() method described below.
805              
806             If the directive was included in the file but did not have a value,
807             1 is returned by get().
808              
809             Calling get() with no arguments will return the names of all available
810             directives.
811              
812             Directives declared in C<hash_directives> require a key value:
813              
814             $handler = $config->get("AddHandler", "cgi-script");
815              
816             C<directive()> is available as an alias for C<get()>.
817              
818             =cut
819              
820             # get a value from the config file.
821             *directive = \&get;
822             sub get {
823 205     205 1 73139 my ($self, $name, $srch) = @_;
824              
825             # handle empty param call
826 205 100       646 return keys %{$self->{_data}} if @_ == 1;
  2         16  
827              
828             # lookup name in _data
829 203 50       848 $name = lc $name unless $self->{case_sensitive};
830 203         533 my $val = $self->{_data}{$name};
831              
832             # Search through up the tree if inheritence is on and we have a
833             # parent. Simulated recursion terminates either when $val is
834             # found or when the root is reached and _parent is undef.
835 203 50 66     704 if (not defined $val and
      66        
836             $self->{_parent} and
837             $self->{inheritance_support}) {
838 3         6 my $ptr = $self;
839 3   33     11 do {
840 3         7 $ptr = $ptr->{_parent};
841 3         18 $val = $ptr->{_data}{$name};
842             } while (not defined $val and $ptr->{_parent});
843             }
844              
845             # didn't find it?
846 203 50       400 return unless defined $val;
847            
848             # for blocks, return a list of valid block identifiers
849 203         345 my $type = ref $val;
850 203         243 my @ret; # tmp to avoid screwing up $val
851 203 50       897 if ($type) {
852 203 100 100     3418 if ($type eq 'ARRAY' and
    100          
853             ref($val->[0]) eq ref($self)) {
854 1         4 @ret = map { [ $name, @{$_->{_block_vals}} ] } @$val;
  2         4  
  2         13  
855 1         4 $val = \@ret;
856             } elsif ($type eq 'HASH') {
857             # hash_directive
858 1 50       4 if ($srch) {
859             # return the specific one
860 1         4 $val = $val->{$srch};
861             } else {
862             # return valid keys
863 0         0 $val = [ keys %$val ];
864             }
865            
866             }
867             }
868            
869             # return all vals in list ctxt, or just the first in scalar
870 203 100       997 return wantarray ? @$val : $val->[0];
871             }
872              
873             =item $block = $config->block("BlockName")
874              
875             =item $block = $config->block(Directory => "/foo/bar")
876              
877             =item $block = $config->block(Directory => "~" => "^.*/bar")
878              
879             This method returns a Config::ApacheFormat object used to access the
880             values inside a block. Parameters specified within the block will be
881             available. Also, if inheritance is turned on (the default), values
882             set outside the block that are not overwritten inside the block will
883             also be available. For example, given this file:
884              
885             MaxSize 100
886              
887             <Site "big">
888             Size 10
889             </Site>
890              
891             <Site "small">
892             Size 1
893             </Site>
894              
895             this code:
896              
897             print "Max: ", $config->get("MaxSize"), "\n";
898              
899             $block = $config->block(Site => "big");
900             print "Big: ", $block->get("Size"), " / ",
901             $block->get("MaxSize"), "\n";
902              
903             $block = $config->block(Site => "small");
904             print "Small: ", $block->get("Size"), " / ",
905             $block->get("MaxSize"), "\n";
906              
907             will print:
908              
909             Max: 100
910             Big: 10 / 100
911             Small: 1 / 100
912              
913             Note that C<block()> does not require any particular number of
914             parameters. Any number will work, as long as they uniquely identify a
915             block in the configuration file. To get a list of available blocks,
916             use get() with the name of the block tag.
917              
918             This method will die() if no block can be found matching the specifier
919             passed in.
920              
921             =cut
922              
923             # get object for a given block specifier
924             sub block {
925 10     10 1 3609 my $self = shift;
926 10 50       50 my($name, @vals) = ref $_[0] eq 'ARRAY' ? @{$_[0]} : @_;
  0         0  
927 10 50       46 $name = lc $name unless $self->{case_sensitive};
928 10         19 my $data = $self->{_data};
929              
930             # make sure we have at least one block named $name
931 10         15 my $block_array;
932 10 50 33     121 croak("No such block named '$name' in config file")
      33        
933             unless ($block_array = $data->{$name} and
934             ref($block_array) eq 'ARRAY' and
935             ref($block_array->[0]) eq ref($self));
936              
937             # find a block matching @vals. If Perl supported arbitrary
938             # structures as hash keys this could be more efficient.
939 10         16 my @ret;
940 10         24 BLOCK:
941 10         16 foreach my $block (@{$block_array}) {
942 170 100       205 if (@vals == @{$block->{_block_vals}}) {
  170         618  
943 156         378 for (local $_ = 0; $_ < @vals; $_++) {
944 289 100       1366 next BLOCK unless $vals[$_] eq $block->{_block_vals}[$_];
945             }
946 127 100       393 return $block unless wantarray; # saves time
947 118         249 push @ret, $block;
948             }
949             }
950 1 50       24 return @ret if @ret;
951              
952             # redispatch to get() if just given block type ($config->block('location'))
953             #return $self->get(@_) unless @vals;
954              
955 0         0 croak("No such block named '$name' with values ",
956 0         0 join(', ', map { "'$_'" } @vals), " in config file");
957             }
958              
959             =item $config->clear()
960              
961             Clears out all data in $config. Call before re-calling
962             $config->read() for a fresh read.
963              
964             =cut
965              
966             sub clear {
967 0     0 1 0 my $self = shift;
968 0         0 delete $self->{_data};
969 0         0 $self->{_data} = {};
970             }
971              
972             =item $config->dump()
973              
974             This returns a dumped copy of the current configuration. It can be
975             used on a block object as well. Since it returns a string, you should
976             say:
977              
978             print $config->dump;
979              
980             Or:
981              
982             for ($config->block(VirtualHost => '10.1.65.1')) {
983             print $_->dump;
984             }
985              
986             If you want to see any output.
987              
988             =cut
989              
990             sub dump {
991 0     0 1 0 my $self = shift;
992 0         0 require Data::Dumper;
993 0         0 $Data::Dumper::Indent = 1;
994 0         0 return Data::Dumper::Dumper($self);
995             }
996              
997             # handle autoload_support feature
998 14     14   7654 sub DESTROY { 1 }
999             sub AUTOLOAD {
1000 4     4   32 our $AUTOLOAD;
1001              
1002 4         7 my $self = shift;
1003 4         35 my ($name) = $AUTOLOAD =~ /([^:]+)$/;
1004 4 50       16 croak(qq(Can't locate object method "$name" via package ") .
1005             ref($self) . '"')
1006             unless $self->{autoload_support};
1007              
1008 4         13 return $self->get($name);
1009             }
1010              
1011              
1012             1;
1013             __END__
1014              
1015             =back
1016              
1017             =head1 Parsing a Real Apache Config File
1018              
1019             To parse a real Apache config file (ex. C<httpd.conf>) you'll need to
1020             use some non-default options. Here's a reasonable starting point:
1021              
1022             $config = Config::ApacheFormat->new(
1023             root_directive => 'ServerRoot',
1024             hash_directives => [ 'AddHandler' ],
1025             include_directives => [ 'Include',
1026             'AccessConfig',
1027             'ResourceConfig' ],
1028             setenv_vars => 1,
1029             fix_booleans => 1);
1030              
1031            
1032              
1033             =head1 TODO
1034              
1035             Some possible ideas for future development:
1036              
1037             =over 4
1038              
1039             =item *
1040              
1041             Add a set() method. (useless?)
1042              
1043             =item *
1044              
1045             Add a write() method to create a new configuration file. (useless?)
1046              
1047             =back
1048              
1049             =head1 BUGS
1050              
1051             I know of no bugs in this software. If you find one, please create a
1052             bug report at:
1053              
1054             http://rt.cpan.org/
1055              
1056             Include the version of the module you're using and a small piece of
1057             code that I can run which demonstrates the problem.
1058              
1059             =head1 COPYRIGHT AND LICENSE
1060              
1061             Copyright (C) 2002-2003 Sam Tregar
1062              
1063             This program is free software; you can redistribute it and/or modify
1064             it under the same terms as Perl 5 itself.
1065              
1066             =head1 AUTHORS
1067              
1068             =item Sam Tregar <sam@tregar.com>
1069              
1070             Original author and maintainer
1071              
1072             =item Nathan Wiger <nate@wiger.org>
1073              
1074             Porting of features from L<Apache::ConfigFile|Apache::ConfigFile>
1075              
1076             =head1 SEE ALSO
1077              
1078             L<Apache::ConfigFile|Apache::ConfigFile>
1079              
1080             L<Apache::ConfigParser|Apache::ConfigParser>
1081              
1082             =cut
1083