1# Apache::ConfigParser::Directive: A single Apache directive or start context. 2# 3# Copyright (C) 2001-2005 Blair Zajac. All rights reserved. 4 5package Apache::ConfigParser::Directive; 6 7require 5.004_05; 8 9use strict; 10use Exporter; 11use Carp; 12use File::Spec 0.82; 13use Tree::DAG_Node 1.04; 14 15use vars qw(@EXPORT_OK @ISA $VERSION); 16@ISA = qw(Tree::DAG_Node Exporter); 17$VERSION = '1.02'; 18 19# Determine if the filenames are case sensitive. 20use constant CASE_SENSITIVE_PATH => (! File::Spec->case_tolerant); 21 22# This is a utility subroutine to determine if the specified path is 23# the /dev/null equivalent on this operating system. 24use constant DEV_NULL => File::Spec->devnull; 25use constant DEV_NULL_LC => lc(File::Spec->devnull); 26sub is_dev_null { 27 if (CASE_SENSITIVE_PATH) { 28 return $_[0] eq DEV_NULL; 29 } else { 30 return lc($_[0]) eq DEV_NULL_LC; 31 } 32} 33push(@EXPORT_OK, qw(DEV_NULL DEV_NULL_LC is_dev_null)); 34 35# This constant is used throughout the module. 36my $INCORRECT_NUMBER_OF_ARGS = "passed incorrect number of arguments.\n"; 37 38# These are declared now but defined and documented below. 39use vars qw(%directive_value_takes_abs_path 40 %directive_value_takes_rel_path 41 %directive_value_path_element_pos); 42push(@EXPORT_OK, qw(%directive_value_takes_abs_path 43 %directive_value_takes_rel_path 44 %directive_value_path_element_pos)); 45 46=head1 NAME 47 48 Apache::ConfigParser::Directive - An Apache directive or start context 49 50=head1 SYNOPSIS 51 52 use Apache::ConfigParser::Directive; 53 54 # Create a new empty directive. 55 my $d = Apache::ConfigParser::Directive->new; 56 57 # Make it a ServerRoot directive. 58 # ServerRoot /etc/httpd 59 $d->name('ServerRoot'); 60 $d->value('/etc/httpd'); 61 62 # A more complicated directive. Value automatically splits the 63 # argument into separate elements. It treats elements in "'s as a 64 # single element. 65 # LogFormat "%h %l %u %t \"%r\" %>s %b" common 66 $d->name('LogFormat'); 67 $d->value('"%h %l %u %t \"%r\" %>s %b" common'); 68 69 # Get a string form of the name. 70 # Prints 'logformat'. 71 print $d->name, "\n"; 72 73 # Get a string form of the value. 74 # Prints '"%h %l %u %t \"%r\" %>s %b" common'. 75 print $d->value, "\n"; 76 77 # Get the values separated into individual elements. Whitespace 78 # separated elements that are enclosed in "'s are treated as a 79 # single element. Protected quotes, \", are honored to not begin or 80 # end a value element. In this form protected "'s, \", are no 81 # longer protected. 82 my @value = $d->get_value_array; 83 scalar @value == 2; # There are two elements in this array. 84 $value[0] eq '%h %l %u %t \"%r\" %>s %b'; 85 $value[1] eq 'common'; 86 87 # The array form can also be set. Change style of LogFormat from a 88 # common to a referer style log. 89 $d->set_value_array('%{Referer}i -> %U', 'referer'); 90 91 # This is equivalent. 92 $d->value('"%{Referer}i -> %U" referer'); 93 94 # There are also an equivalent pair of values that are called 95 # 'original' that can be accessed via orig_value, 96 # get_orig_value_array and set_orig_value_array. 97 $d->orig_value('"%{User-agent}i" agent'); 98 $d->set_orig_value_array('%{User-agent}i', 'agent'); 99 @value = $d->get_orig_value_array; 100 scalar @value == 2; # There are two elements in this array. 101 $value[0] eq '%{User-agent}i'; 102 $value[1] eq 'agent'; 103 104 # You can set undef values for the strings. 105 $d->value(undef); 106 107=head1 DESCRIPTION 108 109The C<Apache::ConfigParser::Directive> module is a subclass of 110C<Tree::DAG_Node>, which provides methods to represents nodes in a 111tree. Each node is a single Apache configuration directive or root 112node for a context, such as <Directory> or <VirtualHost>. All of the 113methods in that module are available here. This module adds some 114additional methods that make it easier to represent Apache directives 115and contexts. 116 117This module holds a directive or context: 118 119 name 120 value in string form 121 value in array form 122 a separate value termed 'original' in string form 123 a separate value termed 'original' in array form 124 the filename where the directive was set 125 the line number in the filename where the directive was set 126 127The 'original' value is separate from the non-'original' value and the 128methods to operate on the two sets of values have distinct names. The 129'original' value can be used to store the original value of a 130directive while the non-'directive' value can be a modified form, such 131as changing the CustomLog filename to make it absolute. The actual 132use of these two distinct values is up to the caller as this module 133does not link the two in any way. 134 135=head1 METHODS 136 137The following methods are available: 138 139=over 140 141=cut 142 143=item $d = Apache::ConfigParser::Directive->new; 144 145This creates a brand new C<Apache::ConfigParser::Directive> object. 146 147It is not recommended to pass any arguments to C<new> to set the 148internal state and instead use the following methods. 149 150There actually is no C<new> method in the 151C<Apache::ConfigParser::Directive> module. Instead, due to 152C<Apache::ConfigParser::Directive> being a subclass of 153C<Tree::DAG_Node>, C<Tree::DAG_Node::new> will be used. 154 155=cut 156 157# The Apache::ConfigParser::Directive object still needs to be 158# initialized. This is done here. Tree::DAG_Node->new calls 159# Apache::ConfigParser::Directive->_init, which will call 160# Tree::DAG_Node->_init. 161sub _init { 162 my $self = shift; 163 $self->SUPER::_init; 164 $self->{name} = ''; 165 $self->{value} = ''; 166 $self->{value_array} = []; 167 $self->{orig_value} = ''; 168 $self->{orig_value_array} = []; 169 $self->{filename} = ''; 170 $self->{line_number} = -1; 171} 172 173=item $d->name 174 175=item $d->name($name) 176 177In the first form get the directive or context's name. In the second 178form set the new name of the directive or context to the lowercase 179version of I<$name> and return the original name. 180 181=cut 182 183sub name { 184 unless (@_ < 3) { 185 confess "$0: Apache::ConfigParser::Directive::name ", 186 $INCORRECT_NUMBER_OF_ARGS; 187 } 188 189 my $self = shift; 190 if (@_) { 191 my $old = $self->{name}; 192 $self->{name} = lc($_[0]); 193 return $old; 194 } else { 195 return $self->{name}; 196 } 197} 198 199=item $d->value 200 201=item $d->value($value) 202 203In the first form get the directive's value in string form. In the 204second form, return the previous directive value in string form and 205set the new directive value to I<$value>. I<$value> can be set to 206undef. 207 208If the value is being set, then I<$value> is saved so another call to 209C<value> will return I<$value>. If I<$value> is defined, then 210I<$value> is also parsed into an array of elements that can be 211retrieved with the C<value_array_ref> or C<get_value_array> methods. 212The parser separates elements by whitespace, unless whitespace 213separated elements are enclosed by "'s. Protected quotes, \", are 214honored to not begin or end a value element. 215 216=item $d->orig_value 217 218=item $d->orig_value($value) 219 220Identical behavior as C<value>, except that this applies to a the 221'original' value. Use C<orig_value_ref> or C<get_orig_value_array> to 222get the value elements. 223 224=cut 225 226# This function manages getting and setting the string value for 227# either the 'value' or 'orig_value' hash keys. 228sub _get_set_value_string { 229 unless (@_ > 1 and @_ < 4) { 230 confess "$0: Apache::ConfigParser::Directive::_get_set_value_string ", 231 $INCORRECT_NUMBER_OF_ARGS; 232 } 233 234 my $self = shift; 235 my $string_var_name = pop; 236 my $old_value = $self->{$string_var_name}; 237 unless (@_) { 238 return $old_value; 239 } 240 241 my $value = shift; 242 my $array_var_name = "${string_var_name}_array"; 243 244 if (defined $value) { 245 # Keep the value as a string and also create an array of values. 246 # Keep content inside " as a single value and also protect \". 247 my @values; 248 if (length $value) { 249 my $v = $value; 250 $v =~ s/\\"/\200/g; 251 while (defined $v and length $v) { 252 if ($v =~ s/^"//) { 253 my $quote_index = index($v, '"'); 254 if ($quote_index < 0) { 255 $v =~ s/\200/"/g; 256 push(@values, $v); 257 last; 258 } else { 259 my $v1 = substr($v, 0, $quote_index, ''); 260 $v =~ s/^"\s*//; 261 $v1 =~ s/\200/"/g; 262 push(@values, $v1); 263 } 264 } else { 265 my ($v1, $v2) = $v =~ /^(\S+)(?:\s+(.*))?$/; 266 $v = $v2; 267 $v1 =~ s/\200/"/g; 268 push(@values, $v1); 269 } 270 } 271 } 272 $self->{$string_var_name} = $value; 273 $self->{$array_var_name} = \@values; 274 } else { 275 $self->{$string_var_name} = undef; 276 $self->{$array_var_name} = undef; 277 } 278 279 $old_value; 280} 281 282sub value { 283 unless (@_ and @_ < 3) { 284 confess "$0: Apache::ConfigParser::Directive::value ", 285 $INCORRECT_NUMBER_OF_ARGS; 286 } 287 288 return _get_set_value_string(@_, 'value'); 289} 290 291sub orig_value { 292 unless (@_ and @_ < 3) { 293 confess "$0: Apache::ConfigParser::Directive::orig_value ", 294 $INCORRECT_NUMBER_OF_ARGS; 295 } 296 297 return _get_set_value_string(@_, 'orig_value'); 298} 299 300=item $d->value_array_ref 301 302=item $d->value_array_ref(\@array) 303 304In the first form get a reference to the value array. This can return 305an undefined value if an undefined value was passed to C<value> or an 306undefined reference was passed to C<value_array_ref>. In the second 307form C<value_array_ref> sets the value array and value string. Both 308forms of C<value_array_ref> return the original array reference. 309 310If you modify the value array reference after getting it and do not 311use C<value_array_ref> C<set_value_array> to set the value, then the 312string returned from C<value> will not be consistent with the array. 313 314=item $d->orig_value_array_ref 315 316=item $d->orig_value_array_ref(\@array) 317 318Identical behavior as C<value_array_ref>, except that this applies to 319the 'original' value. 320 321=cut 322 323# This is a utility function that takes the hash key name to place the 324# value elements into, saves the array and creates a value string 325# suitable for placing into an Apache configuration file. 326sub _set_value_array { 327 unless (@_ > 1) { 328 confess "$0: Apache::ConfigParser::Directive::_set_value_array ", 329 $INCORRECT_NUMBER_OF_ARGS; 330 } 331 332 my $self = shift; 333 my $string_var_name = pop; 334 my $array_var_name = "${string_var_name}_array"; 335 my @values = @_; 336 337 my $value = ''; 338 foreach my $s (@values) { 339 next unless length $s; 340 341 $value .= ' ' if length $value; 342 343 # Make a copy of the string so that the regex doesn't modify the 344 # contents of @values. 345 my $substring = $s; 346 $substring =~ s/(["\\])/\\$1/g; 347 if ($substring =~ /\s/) { 348 $value .= "\"$substring\""; 349 } else { 350 $value .= $substring; 351 } 352 } 353 354 my $old_array_ref = $self->{$array_var_name}; 355 356 $self->{$string_var_name} = $value; 357 $self->{$array_var_name} = \@values; 358 359 $old_array_ref ? @$old_array_ref : (); 360} 361 362sub value_array_ref { 363 unless (@_ and @_ < 3) { 364 confess "$0: Apache::ConfigParser::Directive::value_array_ref ", 365 $INCORRECT_NUMBER_OF_ARGS; 366 } 367 368 my $self = shift; 369 370 my $old = $self->{value_array}; 371 372 if (@_) { 373 my $ref = shift; 374 if (defined $ref) { 375 $self->_set_value_array(@$ref, 'value'); 376 } else { 377 $self->{value} = undef; 378 $self->{value_array} = undef; 379 } 380 } 381 382 $old; 383} 384 385sub orig_value_array_ref { 386 unless (@_ and @_ < 3) { 387 confess "$0: Apache::ConfigParser::Directive::orig_value_array_ref ", 388 $INCORRECT_NUMBER_OF_ARGS; 389 } 390 391 my $self = shift; 392 393 my $old = $self->{orig_value_array}; 394 395 if (@_) { 396 my $ref = shift; 397 if (defined $ref) { 398 $self->_set_value_array(@$ref, 'orig_value'); 399 } else { 400 $self->{value} = undef; 401 $self->{value_array} = undef; 402 } 403 } 404 405 $old; 406} 407 408=item $d->get_value_array 409 410Get the value array elements. If the value was set to an undefined 411value using C<value>, then C<get_value_array> will return an empty 412list in a list context, an undefined value in a scalar context, or 413nothing in a void context. 414 415=item $d->get_orig_value_array 416 417This has the same behavior of C<get_value_array> except that it 418operates on the 'original' value. 419 420=cut 421 422sub get_value_array { 423 unless (@_ == 1) { 424 confess "$0: Apache::ConfigParser::Directive::get_value_array ", 425 $INCORRECT_NUMBER_OF_ARGS; 426 } 427 428 my $ref = shift->{value_array}; 429 430 if ($ref) { 431 return @$ref; 432 } else { 433 return; 434 } 435} 436 437sub get_orig_value_array { 438 unless (@_ == 1) { 439 confess "$0: Apache::ConfigParser::Directive::get_orig_value_array ", 440 $INCORRECT_NUMBER_OF_ARGS; 441 } 442 443 my $ref = shift->{orig_value_array}; 444 445 if ($ref) { 446 return @$ref; 447 } else { 448 return; 449 } 450} 451 452=item $d->set_value_array(@values) 453 454Set the value array elements. If no elements are passed in, then the 455value will be defined but empty and a following call to 456C<get_value_array> will return an empty array. This returns the value 457of the array before this method was called. 458 459After setting the value elements with this method, the string returned 460from calling C<value> is a concatenation of each of the elements so 461that the output could be used for an Apache configuration file. If 462any elements contain whitespace, then the "'s are placed around the 463element as the element is being concatenated into the value string and 464if any elements contain a " or a \, then a copy of the element is made 465and the character is protected, i.e. \" or \\, and then copied into 466the value string. 467 468=item $d->set_orig_value_array(@values) 469 470This has the same behavior as C<set_value_array> except that it 471operates on the 'original' value. 472 473=cut 474 475sub set_value_array { 476 return _set_value_array(@_, 'value'); 477} 478 479sub set_orig_value_array { 480 return _set_value_array(@_, 'orig_value'); 481} 482 483=item Note on $d->value_is_path, $d->value_is_abs_path, 484$d->value_is_rel_path, $d->orig_value_is_path, 485$d->orig_value_is_abs_path and $d->orig_value_is_rel_path 486 487These six methods are very similar. They all check if the directive 488can take a file or directory path value argument in the appropriate 489index in the value array and then check the value. For example, the 490C<LoadModule> directive, i.e. 491 492=over 4 493 494LoadModule cgi_module libexec/mod_cgi.so 495 496=back 497 498does not take a path element in its first (index 0) value array 499element. 500 501If there is no argument supplied to the method call, then the 502directive checks the first element of the value array that can legally 503contain path. For C<LoadModule>, it would check element 1. You could 504pass 0 to the method to check the first indexed value of 505C<LoadModule>, but it would always return false, because index 0 does 506not contain a path. 507 508These are the differences between the methods: 509 510=over 4 511 5121) The methods beginning with the string 'value_is' apply to the 513current value in the directive while the methods beginning with the 514string 'orig_value_is' apply to the original value of the directive. 515 5162) The methods '*value_is_path' test if the directive value is a path, 517either absolute or relative. The methods '*value_is_abs_path' test if 518the path if an absolute path, and the methods '*value_is_rel_path' 519test if the path is not an absolute path. 520 521=back 522 523=item $d->value_is_path 524 525=item $d->value_is_path($index_into_value_array) 526 527Returns true if C<$d>'s directive can take a file or directory path in 528the specified value array element (indexed by $index_into_value_array 529or the first path element for the particular directive if 530$index_into_value_array is not provided) and if the value is either an 531absolute or relative file or directory path. Both the directive name 532and the value is checked, because some directives such as ErrorLog, 533can take values that are not paths (i.e. a piped command or 534syslog:facility). The /dev/null equivalent for the operating system 535is not treated as a path, since on some operating systems the 536/dev/null equivalent is not a file, such as nul on Windows. 537 538The method actually does not check if its value is a path, rather it 539checks if the value does not match all of the other possible non-path 540values for the specific directive because different operating systems 541have different path formats, such as Unix, Windows and Macintosh. 542 543=cut 544 545# Define these constant subroutines as the different types of paths to 546# check for in _value_is_path_or_abs_path_or_rel_path. 547sub CHECK_TYPE_ABS () { 'abs' } 548sub CHECK_TYPE_REL () { 'rel' } 549sub CHECK_TYPE_ABS_OR_REL () { 'abs_or_rel' } 550 551# This is a function that does the work for value_is_path, 552# orig_value_is_path, value_is_abs_path, orig_value_is_abs_path, 553# value_is_rel_path and orig_value_is_rel_path. 554sub _value_is_path_or_abs_path_or_rel_path { 555 unless (@_ == 4) { 556 confess "$0: Apache::ConfigParser::Directive::", 557 "_value_is_path_or_abs_path_or_rel_path ", 558 $INCORRECT_NUMBER_OF_ARGS; 559 } 560 561 my ($self, 562 $check_type, 563 $array_var_name, 564 $value_path_index) = @_; 565 566 unless ($check_type eq CHECK_TYPE_ABS or 567 $check_type eq CHECK_TYPE_REL or 568 $check_type eq CHECK_TYPE_ABS_OR_REL) { 569 confess "$0: Apache::ConfigParser::Directive::", 570 "_value_is_path_or_abs_path_or_rel_path ", 571 "passed invalid check_type value '$check_type'.\n"; 572 } 573 574 if (defined $value_path_index and $value_path_index !~ /^\d+$/) { 575 confess "$0: Apache::ConfigParser::Directive::", 576 "_value_is_path_or_abs_path_or_rel_path ", 577 "passed invalid value_path_index value '$value_path_index'.\n"; 578 } 579 580 my $array_ref = $self->{$array_var_name}; 581 582 unless ($array_ref) { 583 return 0; 584 } 585 586 my $directive_name = $self->name; 587 588 unless (defined $directive_name and length $directive_name) { 589 return 0; 590 } 591 592 # Check if there is an index into the value array that can take a 593 # path. 594 my $first_value_path_index = 595 $directive_value_path_element_pos{$directive_name}; 596 unless (defined $first_value_path_index and length $first_value_path_index) { 597 return 0; 598 } 599 600 # If the index into the value array was specified, then check if the 601 # value in the index can take a path. If the index was not 602 # specified, then use the first value index that can contain a path. 603 if (defined $value_path_index) { 604 if (substr($first_value_path_index, 0, 1) eq '-') { 605 return 0 if $value_path_index < abs($first_value_path_index); 606 } else { 607 return 0 if $value_path_index != $first_value_path_index; 608 } 609 } else { 610 $value_path_index = abs($first_value_path_index); 611 } 612 my $path = $array_ref->[$value_path_index]; 613 614 unless (defined $path and length $path) { 615 return 0; 616 } 617 618 if (is_dev_null($path)) { 619 return 0; 620 } 621 622 # Get the subroutine that will check if the directive value is a 623 # path. If there is no subroutine for the directive, then it 624 # doesn't take a path. 625 my $sub_ref; 626 if ($check_type eq CHECK_TYPE_ABS) { 627 $sub_ref = $directive_value_takes_abs_path{$directive_name}; 628 } elsif ($check_type eq CHECK_TYPE_REL) { 629 $sub_ref = $directive_value_takes_rel_path{$directive_name}; 630 } elsif ($check_type eq CHECK_TYPE_ABS_OR_REL) { 631 $sub_ref = $directive_value_takes_abs_path{$directive_name}; 632 unless (defined $sub_ref) { 633 $sub_ref = $directive_value_takes_rel_path{$directive_name}; 634 } 635 } else { 636 confess "$0: internal error: check_type case '$check_type' not handled.\n"; 637 } 638 639 unless ($sub_ref) { 640 return 0; 641 } 642 643 my $result = &$sub_ref($path); 644 if ($result) { 645 return 1 if $check_type eq CHECK_TYPE_ABS_OR_REL; 646 647 if ($check_type eq CHECK_TYPE_ABS) { 648 return File::Spec->file_name_is_absolute($path) ? 1 : 0; 649 } elsif ($check_type eq CHECK_TYPE_REL) { 650 return File::Spec->file_name_is_absolute($path) ? 0 : 1; 651 } else { 652 confess "$0: internal error: check_type case ", 653 "'$check_type' not handled.\n"; 654 } 655 } else { 656 return 0; 657 } 658} 659 660sub value_is_path { 661 unless (@_ < 3) { 662 confess "$0: Apache::ConfigParser::Directive::value_is_path ", 663 $INCORRECT_NUMBER_OF_ARGS; 664 } 665 666 _value_is_path_or_abs_path_or_rel_path($_[0], 667 CHECK_TYPE_ABS_OR_REL, 668 'value_array', 669 $_[1]); 670} 671 672=item $d->orig_value_is_path 673 674=item $d->orig_value_is_path($index_into_value_array) 675 676This has the same behavior as C<< $d->value_is_path >> except the results 677are applicable to C<$d>'s 'original' value array. 678 679=cut 680 681sub orig_value_is_path { 682 unless (@_ < 3) { 683 confess "$0: Apache::ConfigParser::Directive::orig_value_is_path ", 684 $INCORRECT_NUMBER_OF_ARGS; 685 } 686 687 _value_is_path_or_abs_path_or_rel_path($_[0], 688 CHECK_TYPE_ABS_OR_REL, 689 'orig_value_array', 690 $_[1]); 691} 692 693=item $d->value_is_abs_path 694 695=item $d->value_is_abs_path($index_into_value_array) 696 697Returns true if C<$d>'s directive can take a file or directory path in 698the specified value array element (indexed by $index_into_value_array 699or the first path element for the particular directive if 700$index_into_value_array is not provided) and if the value is an 701absolute file or directory path. Both the directive name and the 702value is checked, because some directives such as ErrorLog, can take 703values that are not paths (i.e. a piped command or syslog:facility). 704The /dev/null equivalent for the operating system is not treated as a 705path, since on some operating systems the /dev/null equivalent is not 706a file, such as nul on Windows. 707 708The method actually does not check if its value is a path, rather it 709checks if the value does not match all of the other possible non-path 710values for the specific directive because different operating systems 711have different path formats, such as Unix, Windows and Macintosh. 712 713=cut 714 715sub value_is_abs_path { 716 unless (@_ < 3) { 717 confess "$0: Apache::ConfigParser::Directive::value_is_abs_path ", 718 $INCORRECT_NUMBER_OF_ARGS; 719 } 720 721 _value_is_path_or_abs_path_or_rel_path($_[0], 722 CHECK_TYPE_ABS, 723 'value_array', 724 $_[1]); 725} 726 727=item $d->orig_value_is_abs_path 728 729=item $d->orig_value_is_abs_path($index_into_value_array) 730 731This has the same behavior as C<< $d->value_is_abs_path >> except the 732results are applicable to C<$d>'s 'original' value array. 733 734=cut 735 736sub orig_value_is_abs_path { 737 unless (@_ < 3) { 738 confess "$0: Apache::ConfigParser::Directive::orig_value_is_abs_path ", 739 $INCORRECT_NUMBER_OF_ARGS; 740 } 741 742 _value_is_path_or_abs_path_or_rel_path($_[0], 743 CHECK_TYPE_ABS, 744 'orig_value_array', 745 $_[1]); 746} 747 748=item $d->value_is_rel_path 749 750=item $d->value_is_rel_path($index_into_value_array) 751 752Returns true if C<$d>'s directive can take a file or directory path in 753the specified value array element (indexed by $index_into_value_array 754or the first path element for the particular directive if 755$index_into_value_array is not provided) and if the value is a 756relative file or directory path. Both the directive name and the 757value is checked, because some directives such as ErrorLog, can take 758values that are not paths (i.e. a piped command or syslog:facility). 759The /dev/null equivalent for the operating system is not treated as a 760path, since on some operating systems the /dev/null equivalent is not 761a file, such as nul on Windows. 762 763The method actually does not check if its value is a path, rather it 764checks if the value does not match all of the other possible non-path 765values for the specific directive because different operating systems 766have different path formats, such as Unix, Windows and Macintosh. 767 768=cut 769 770sub value_is_rel_path { 771 unless (@_ < 3) { 772 confess "$0: Apache::ConfigParser::Directive::value_is_rel_path ", 773 $INCORRECT_NUMBER_OF_ARGS; 774 } 775 776 _value_is_path_or_abs_path_or_rel_path($_[0], 777 CHECK_TYPE_REL, 778 'value_array', 779 $_[1]); 780} 781 782=item $d->orig_value_is_rel_path 783 784=item $d->orig_value_is_rel_path($index_into_value_array) 785 786This has the same behavior as C<< $d->value_is_rel_path >> except the 787results are applicable to C<$d>'s 'original' value array. 788 789=cut 790 791sub orig_value_is_rel_path { 792 unless (@_ < 3) { 793 confess "$0: Apache::ConfigParser::Directive::orig_value_is_rel_path ", 794 $INCORRECT_NUMBER_OF_ARGS; 795 } 796 797 _value_is_path_or_abs_path_or_rel_path($_[0], 798 CHECK_TYPE_REL, 799 'orig_value_array', 800 $_[1]); 801} 802 803=item $d->filename 804 805=item $d->filename($filename) 806 807In the first form get the filename where this particular directive or 808context appears. In the second form set the new filename of the 809directive or context and return the original filename. 810 811=cut 812 813sub filename { 814 unless (@_ < 3) { 815 confess "$0: Apache::ConfigParser::Directive::filename ", 816 $INCORRECT_NUMBER_OF_ARGS; 817 } 818 819 my $self = shift; 820 if (@_) { 821 my $old = $self->{filename}; 822 $self->{filename} = $_[0]; 823 return $old; 824 } else { 825 return $self->{filename}; 826 } 827} 828 829=item $d->line_number 830 831=item $d->line_number($line_number) 832 833In the first form get the line number where the directive or context 834appears in a filename. In the second form set the new line number of 835the directive or context and return the original line number. 836 837=cut 838 839sub line_number { 840 unless (@_ < 3) { 841 confess "$0: Apache::ConfigParser::Directive::line_number ", 842 $INCORRECT_NUMBER_OF_ARGS; 843 } 844 845 my $self = shift; 846 if (@_) { 847 my $old = $self->{line_number}; 848 $self->{line_number} = $_[0]; 849 return $old; 850 } else { 851 return $self->{line_number}; 852 } 853} 854 855=back 856 857=head1 EXPORTED VARIABLES 858 859The following variables are exported via C<@EXPORT_OK>. 860 861=over 4 862 863=item DEV_NULL 864 865The string representation of the null device on this operating system. 866 867=item DEV_NULL_LC 868 869The lowercase version of DEV_NULL. 870 871=item is_dev_null($path) 872 873On a case sensitive system, compares $path to DEV_NULL and on a case 874insensitive system, compares lc($path) to DEV_NULL_LC. 875 876=item %directive_value_takes_abs_path 877 878This hash is keyed by the lowercase version of a directive name. This 879hash is keyed by all directives that accept a file or directory path 880value as its first value array element. The hash value is a subroutine 881reference to pass the value array element containing the file, 882directory, pipe or syslog entry to. If a hash entry exists for a 883particular entry, then the directive name can take either a relative 884or absolute path to either a file or directory. The hash does not 885distinguish between directives that take only filenames, only 886directories or both, and it does not distinguish if the directive 887takes only absolute, only relative or both types of paths. 888 889The hash value for the lowercase directive name is a subroutine 890reference. The subroutine returns 1 if its only argument is a path 891and 0 otherwise. The /dev/null equivalent (C<< File::Spec->devnull >>) 892for the operating system being used is not counted as a path, since on 893some operating systems the /dev/null equivalent is not a filename, 894such as nul on Windows. 895 896The subroutine actually does not check if its argument is a path, 897rather it checks if the argument does not match one of the other 898possible non-path values for the specific directive because different 899operating systems have different path formats, such as Unix, Windows 900and Macintosh. For example, ErrorLog can take a filename, such as 901 902 ErrorLog /var/log/httpd/error_log 903 904or a piped command, such as 905 906 ErrorLog "| cronolog /var/log/httpd/%Y/%m/%d/error.log" 907 908or a syslog entry of the two forms: 909 910 ErrorLog syslog 911 ErrorLog syslog:local7 912 913The particular subroutine for ErrorLog checks if the value is not 914equal to C<< File::Spec->devnull >>, does not begin with a | or does not 915match syslog(:[a-zA-Z0-9]+)?. 916 917These subroutines do not remove any "'s before checking on the type of 918value. 919 920This hash is used by C<value_is_path> and C<orig_value_is_path>. 921 922This is a list of directives and any special values to check for as of 923Apache 1.3.20 with the addition of IncludeOptional from 2.4.x. 924 925 AccessConfig 926 AgentLog check for "| prog" 927 AuthDBGroupFile 928 AuthDBMGroupFile 929 AuthDBMUserFile 930 AuthDBUserFile 931 AuthDigestFile 932 AuthGroupFile 933 AuthUserFile 934 CacheRoot 935 CookieLog 936 CoreDumpDirectory 937 CustomLog check for "| prog" 938 Directory 939 DocumentRoot 940 ErrorLog check for "| prog", or syslog or syslog:facility 941 Include 942 IncludeOptional 943 LoadFile 944 LoadModule 945 LockFile 946 MimeMagicFile 947 MMapFile 948 PidFile 949 RefererLog check for "| prog" 950 ResourceConfig 951 RewriteLock 952 ScoreBoardFile 953 ScriptLog 954 ServerRoot 955 TransferLog check for "| prog" 956 TypesConfig 957 958=item %directive_value_takes_rel_path 959 960This hash is keyed by the lowercase version of a directive name. This 961hash contains only those directive names that can accept both relative 962and absolute file or directory names. The hash value is a subroutine 963reference to pass the value array element containing the file, 964directory, pipe or syslog entry to. The hash does not distinguish 965between directives that take only filenames, only directories or both. 966 967The hash value for the lowercase directive name is a subroutine 968reference. The subroutine returns 1 if its only argument is a path 969and 0 otherwise. The /dev/null equivalent (C<< File::Spec->devnull >>) 970for the operating system being used is not counted as a path, since on 971some operating systems the /dev/null equivalent is not a filename, 972such as nul on Windows. 973 974The subroutine actually does not check if its argument is a path, 975rather it checks if the argument does not match one of the other 976possible non-path values for the specific directive because different 977operating systems have different path formats, such as Unix, Windows 978and Macintosh. For example, ErrorLog can take a filename, such as 979 980 ErrorLog /var/log/httpd/error_log 981 982or a piped command, such as 983 984 ErrorLog "| cronolog /var/log/httpd/%Y/%m/%d/error.log" 985 986or a syslog entry of the two forms: 987 988 ErrorLog syslog 989 ErrorLog syslog:local7 990 991The particular subroutine for ErrorLog checks if the value is not 992equal to C<< File::Spec->devnull >>, does not begin with a | or does not 993match syslog(:[a-zA-Z0-9]+)?. 994 995These subroutines do not remove any "'s before checking on the type of 996value. 997 998This hash is used by C<value_is_rel_path> and 999C<orig_value_is_rel_path>. 1000 1001This is a list of directives and any special values to check for as of 1002Apache 1.3.20 with the addition of IncludeOptional from 2.4.x. 1003 1004AccessFileName is not a key in the hash because, while its value is 1005one or more relative paths, the ServerRoot is never prepended to it as 1006the AccessFileName values are looked up in every directory of the path 1007to the document being requested. 1008 1009 AccessConfig 1010 AuthGroupFile 1011 AuthUserFile 1012 CookieLog 1013 CustomLog check for "| prog" 1014 ErrorLog check for "| prog", or syslog or syslog:facility 1015 Include 1016 IncludeOptional 1017 LoadFile 1018 LoadModule 1019 LockFile 1020 MimeMagicFile 1021 PidFile 1022 RefererLog check for "| prog" 1023 ResourceConfig 1024 ScoreBoardFile 1025 ScriptLog 1026 TransferLog check for "| prog" 1027 TypesConfig 1028 1029=item %directive_value_path_element_pos 1030 1031This hash holds the indexes into the directive value array for the 1032value or values that can contain either absolute or relative file or 1033directory paths. This hash is keyed by the lowercase version of a 1034directive name. The hash value is a string representing an integer. 1035The string can take two forms: 1036 1037 /^\d+$/ The directive has only one value element indexed by \d+ 1038 that takes a file or directory path. 1039 1040 /^-\d+$/ The directive takes any number of file or directory path 1041 elements beginning with the abs(\d+) element. 1042 1043For example: 1044 1045 # CustomLog logs/access_log common 1046 $directive_value_path_element_pos{customlog} eq '0'; 1047 1048 # LoadFile modules/mod_env.so libexec/mod_mime.so 1049 $directive_value_path_element_pos{loadfile} eq '-0'; 1050 1051 # LoadModule env_module modules/mod_env.so 1052 $directive_value_path_element_pos{loadmodule} eq '1'; 1053 1054 # PidFile logs/httpd.pid 1055 $directive_value_path_element_pos{pidfile} eq '0'; 1056 1057=back 1058 1059=cut 1060 1061sub directive_value_is_not_dev_null { 1062 !is_dev_null($_[0]); 1063} 1064 1065sub directive_value_is_not_dev_null_and_pipe { 1066 if (is_dev_null($_[0])) { 1067 return 0; 1068 } 1069 1070 return $_[0] !~ /^\s*\|/; 1071} 1072 1073sub directive_value_is_not_dev_null_and_pipe_and_syslog { 1074 if (is_dev_null($_[0])) { 1075 return 0; 1076 } 1077 1078 return $_[0] !~ /^\s*(?:(?:\|)|(?:syslog(?::[a-zA-Z0-9]+)?))/; 1079} 1080 1081# This is a hash keyed by directive name and the value is an array 1082# reference. The array element are 1083# array array 1084# index value 1085# 0 A string containing an integer that describes the element 1086# position(s) that contains the file or directory path. 1087# string =~ /^\d+/ a single element that contains a path 1088# string =~ /^-\d+/ multiple elements, first is abs(\d+) 1089# 1 1 if the paths the directive accepts can be absolute and 1090# relative, 0 if they can only be absolute 1091# 2 a subroutine reference to directive_value_is_not_dev_null, 1092# directive_value_is_not_dev_null_and_pipe or 1093# directive_value_is_not_dev_null_and_pipe_and_syslog. 1094 1095my %directive_info = ( 1096 AccessConfig => ['0', 1097 1, 1098 \&directive_value_is_not_dev_null], 1099 AuthDBGroupFile => ['0', 1100 0, 1101 \&directive_value_is_not_dev_null], 1102 AuthDBMGroupFile => ['0', 1103 0, 1104 \&directive_value_is_not_dev_null], 1105 AuthDBMUserFile => ['0', 1106 0, 1107 \&directive_value_is_not_dev_null], 1108 AuthDBUserFile => ['0', 1109 0, 1110 \&directive_value_is_not_dev_null], 1111 AuthDigestFile => ['0', 1112 0, 1113 \&directive_value_is_not_dev_null], 1114 AgentLog => ['0', 1115 0, 1116 \&directive_value_is_not_dev_null_and_pipe], 1117 AuthGroupFile => ['0', 1118 1, 1119 \&directive_value_is_not_dev_null], 1120 AuthUserFile => ['0', 1121 1, 1122 \&directive_value_is_not_dev_null], 1123 CacheRoot => ['0', 1124 0, 1125 \&directive_value_is_not_dev_null], 1126 CookieLog => ['0', 1127 1, 1128 \&directive_value_is_not_dev_null], 1129 CoreDumpDirectory => ['0', 1130 0, 1131 \&directive_value_is_not_dev_null], 1132 CustomLog => ['0', 1133 1, 1134 \&directive_value_is_not_dev_null_and_pipe], 1135 Directory => ['0', 1136 0, 1137 \&directive_value_is_not_dev_null], 1138 DocumentRoot => ['0', 1139 0, 1140 \&directive_value_is_not_dev_null], 1141 ErrorLog => ['0', 1142 1, 1143 \&directive_value_is_not_dev_null_and_pipe_and_syslog], 1144 Include => ['0', 1145 1, 1146 \&directive_value_is_not_dev_null], 1147 IncludeOptional => ['0', 1148 1, 1149 \&directive_value_is_not_dev_null], 1150 LoadFile => ['-0', 1151 1, 1152 \&directive_value_is_not_dev_null], 1153 LoadModule => ['1', 1154 1, 1155 \&directive_value_is_not_dev_null], 1156 LockFile => ['0', 1157 1, 1158 \&directive_value_is_not_dev_null], 1159 MMapFile => ['0', 1160 0, 1161 \&directive_value_is_not_dev_null], 1162 MimeMagicFile => ['0', 1163 1, 1164 \&directive_value_is_not_dev_null], 1165 PidFile => ['0', 1166 1, 1167 \&directive_value_is_not_dev_null], 1168 RefererLog => ['0', 1169 1, 1170 \&directive_value_is_not_dev_null_and_pipe], 1171 ResourceConfig => ['0', 1172 1, 1173 \&directive_value_is_not_dev_null], 1174 RewriteLock => ['0', 1175 0, 1176 \&directive_value_is_not_dev_null], 1177 ScoreBoardFile => ['0', 1178 1, 1179 \&directive_value_is_not_dev_null], 1180 ScriptLog => ['0', 1181 1, 1182 \&directive_value_is_not_dev_null], 1183 ServerRoot => ['0', 1184 0, 1185 \&directive_value_is_not_dev_null], 1186 TransferLog => ['0', 1187 1, 1188 \&directive_value_is_not_dev_null_and_pipe], 1189 TypesConfig => ['0', 1190 1, 1191 \&directive_value_is_not_dev_null]); 1192 1193# Set up the three exported hashes using the information in 1194# %directive_info. Use lowercase directive names. 1195foreach my $key (keys %directive_info) { 1196 my $ref = $directive_info{$key}; 1197 my $lc_key = lc($key); 1198 my ($index, $abs_and_rel, $sub_ref) = @$ref; 1199 if ($abs_and_rel) { 1200 $directive_value_takes_rel_path{$lc_key} = $sub_ref; 1201 } 1202 $directive_value_takes_abs_path{$lc_key} = $sub_ref; 1203 $directive_value_path_element_pos{$lc_key} = $index; 1204} 1205 1206=head1 SEE ALSO 1207 1208L<Apache::ConfigParser::Directive> and L<Tree::DAG_Node>. 1209 1210=head1 AUTHOR 1211 1212Blair Zajac <blair@orcaware.com>. 1213 1214=head1 COPYRIGHT 1215 1216Copyright (C) 2001-2005 Blair Zajac. All rights reserved. This 1217program is free software; you can redistribute it and/or modify it 1218under the same terms as Perl itself. 1219 1220=cut 1221 12221; 1223