Apache::Admin::Config 0.14
==========================

INSTALLATION

To install this module type the following:

   perl Makefile.PL
   make
   make test
   make install

UPGRADING FROM PREVIOUS VERSIONS

* Upgrading from version 0.08 or earlier: read UPGRADE-0.10

CHANGES

0.15 Tue Dec 11 14:18:07 2001
        - Minor bugfix: add_(section|directive) with option -onbottom
          were dont work properly
        - Added dump_raw() method 

0.14 Sat Dec  8 14:14:50 2001
        - Major bugfix that cause an endless loop in the constructor
          with perl 5.005 and maybe 5.6
        - Some corrections in error messages

0.13 Thu Dec  6 11:26:05 2001
        - Fix compatibility problem with perl 5.005, thinks to 
          Anton Berezin
        - Bigfix, error when add_(directive|section) on an empty
          file

0.12 Sun Nov 11 10:49:40 2001
        - New feature: you now can pase a file handle to the constructor
          new() and the save() method instead of a path (thanks to
          Peter Suschlik for his patch).
        
0.11 Thu Oct 25 20:57:52 2001
        - Bugfix in add_section method. add_section will add entries
          before the last context's section line.

0.10 Thu Oct 12 02:36:17 2001
        - Bugfix in test scripts, that makes test fail randomly
        - Major feature enhancements
            (DIRECTIVE|SECTION) METHOD
            - directive() now returns full list of directives, sorted
              as it comes in the file. Each element of this list is
              an object that points to the directive entry.
            - directive(Foo) also returns a full list of value of all
              "Foo" directive in current context, also sorted as it comes
              in the file. Each list's element is also an object that
              points to the directive entry.
            - directive(Foo, Bar) returns an object that points to the
              last directive (if more than one) wich has the same
              directive's name/value. In list context, it returns the
              full list of same directive's name/value.
            - directive() can now takes the -which=>N parameter to
              select the entry's number to return (if exists).
            ADD_(DIRECTIVE|SECTION) METHOD
            - can take 4 parameters:
                - -before=>target  where target is an Apache::Admin::Config
                  object, that points to a section or directive of the same
                  context than add_directive() method's object caller. The
                  directive if added just before the target.
                - -after=>target idem but after the target.
                - -ontop  added on the top of current context.
                - -onbottom  added on the bottom of current context.
        - Internal parser modification that allows a section to have
          same name than a directive in the same context without no clash.
        - New methods (see documentation for more details):
            - first_line: return the first line of rule pointed by caller object
            - last_line: return the last
            - lines: return all lines occuped by the rule
            - dump_line: dump a line
            - isin: true if caller object is in the same context than one given in argument
            - type: return the type of caller object
            - name: return the name of caller object
        - API had change, so contructor can take the -oldapi=>1 argument for
          a backward compatibility

0.07  Thu Sep 20 02:36:17 2001
        - Major change, section and directive methods no any longer 
          return an arrayref in list context but a simple list.
          Documentation corrected (thanx to Nathan Wiger for this 
          suggestion).

0.06  Tue Sep 18 01:09:24 2001
        - Make a quick and dirty documentation
        - value() return the context value if no arguments given
        - new() can be called without argument, save() need an 
          argument in this case

0.05  Sat Aug 18 14:39:45 2001
        - Major bug fix, if config file wasn't exists, module won't work !
        - Bug fix, value method wasn't took the appropriate value for change
          it, resulted to an unchanged value
        - Bug fix, $master and $root value was undefined in value method,
          so value wasn't work at all

0.04  Fri Aug 17 01:42:16 2001
        - Fix a minor bug in directive method.

0.03  Fri Aug 17 01:07:17 2001
        - Fix a major bug in directive method.

0.02  Thu Aug 16 01:48:54 2001
        - Put module on CPAN
        - Fix a very major bug that cause "syntax error" from parser on 
          directives with no value like "clearmodulelist", thanx A2 for
          this report.

0.01  Sun Aug 12 11:58:10 2001
	- Original version; created by h2xs 1.21 with options -AX -n Apache::Admin

NAME
    Apache::Admin::Config - A common module to manipulate Apache
    configuration files

SYNOPSIS
        use Apache::Admin::Config;

        # Parse an apache configuration file
        my $obj = new Apache::Admin::Config ("/path/to/config_file.conf")
            or die $Apache::Admin::Config::ERROR;

        # or parse a filehandle
        open(ANHANDLE, "/path/to/a/file")...
        ...
        my $obj = new Apache::Admin::Config (\*ANHANDLE)
            or die $Apache::Admin::Config::ERROR;

        #
        # working with directives
        #

        # Getting the full list of directives in current context. 

        # Directive method called without any argument, return a list
        # of all directive located in the current context. The actual
        # context is called "top", because it haven't any parent.
        my @directives_list = $obj->directive;

        # The resulting array, is sorted by order of apparence in the
        # file. So you can easly figure directive's precedence.

        # Each item of @directives_list array is a "magic" string. If
        # you print one, it return the name of pointed directive.
        my $directive = $directives_list[3];
        print $directive; # return "DocumentRoot" for example

        # But this "magic" string is also an object, that have many
        # methods for manage this directive.
        print $directive->value;  # "/my/document/root"
        print $directive->type;   # "directive"
        $directive->isin($obj);   # true
        $directive->delete;
        ...
    
        # this print all current context's directives and it's associated
        # value :
        foreach my $directive ($obj->directive)
        {
            printf qq(%s: '%s' has value: '%s' at line %d\n), 
                $directive->type, $directive->name, $directive->value, $directive->first_line;
        }
    
        # possible output:
        directive: servertype has value: standalone at line 48
        directive: serverroot has value: "@@ServerRoot@@" at line 61
        directive: pidfile has value: logs/httpd.pid at line 78
        directive: scoreboardfile has value: logs/apache_runtime_status at line 86
        ...
    
        # you can select which directive you want
        my $directive = $obj->directive(-which=>8); # you'll get the 8th directive of
                                                    # the current context
    
        # getting the full list of directive who's name is "Foo" in the current context
        my @foo_directives = $obj->directive('Foo');
        # or just the 4th
        my $4th_foo_directive = $obj->directive('Foo', -which=>4);

        # you may want just directives named "Foo" with value "Bar", it return
        # a list of all directives with these name/value in list context
        my @foo_bar_directives = $obj->directive(Foo=>'Bar');
        # or just the last one in scalar context
        my $foo_bar_directive = $obj->directive(Foo=>'Bar');
        # or the second one if "-which" option is given.
        my $foo_bar_directive = $obj->directive(Foo=>'Bar', -which=>2);

        # working on directive "PidFile"
        my $pidfile = $obj->directive(PidFile=>'logs/httpd.pid');

        # changing value of directive "PidFile logs/httpd.pid" to "PidFile logs/apache.pid"
        $pidfile->set_value('logs/apache.pid');

        # deleting directive "PidFile logs/apache.pid"
        $pidfile->delete;

        # or deleting all directives "AddType"
        map($_->delete, $obj->directive(AddType)); # dangerous

        # adding directive "AddType text/html .shtml" just after the last AddType directive if any
        # or at the end of file (or section)
        $obj->add_directive(AddType=>'text/html .shtml', -after=>$obj->directive('AddType', -which=>-1))
        # only if "AddType text/html .shtml" doesn't exist
        unless($obj->directive(AddType=>'text/html .shtml'));

        #
        # working with sections
        #

        # you can get object to another context like this
        my $section_directive_foo = $obj->section(Foo=>'Bar');
        my @directives_list = $section_directive_foo->directive;

        # accessing the section "<file some_file>" in the section "<directory /some/dir>" 
        # of section "<virtualhost example.com>"
        my $subsubsubsection = $obj->section(virtualhost=>"example.com")->section(directory=>"/some/dir")->section(file=>"some_file")

        #
        # reordering lines
        # 

        # moving all directives "LoadModule" before directives "AddModule" in the current context
        my $first_addmodule = $obj->directive(AddModule, -which=>0):
        foreach my $loadmodule ($obj->directive('LoadModule'))
        {
            $loadmodule->move(-before=>$first_addmodule);
              if($loadmodule->line > $first_addmodule->line);
        }
    
        #
        # save
        #

        # save change in place
        $obj->save;
        # or in another file (sound like "save as...")
        $obj->save("/path/to/another/file");
        # or in an already openned file
        $obj->save(\*FILE_HANDLE);

DESCRIPTION
    "Apache::Admin::Config" provides an object interface to handling Apache
    like configuration files without modifying comments, identation, or
    truncated lines.

METHODES
  new ([*/path/to/file*|*handle*], -oldapi=>*0|1*)

    Create or read, if given in argument, an apache like configuration file.

    Arguments:

    *"/path/to/file"*
        Path to the configuration file to parse. If none given, create a new
        one.

        = item *"handle"*

        Instead of specify a path to a file, you can give a reference to an
        handle that point to an already openned file. You can do this like
        this :

            my $conf = new Apache::Admin::Config (\*MYHANDLE);

    *-oldapi*=>*0/1*
        If true, keep the old api backward compatibility. Read UPGRADE-0.10
        for more details. Default is false.

  save ([*/path/to/file*|*HANDLE*])

    Write modifications to the configuration file. If a path to a file is
    given, save the modification to this file instead. You also can give a
    reference to a filehandle like this :

        $conf->save(\*MYHANDLE) or die($conf->error);

  dump_raw

    Return the configuration file as same as it will be if it saved in a
    file with the save() method.

  add_section (*name*=>*'value'*, [-before=>*target* | -after=>*target* | -ontop | -onbottom])

        $obj->add_section(foo=>'bar', -after=>$obj->directive('oof', -which=>-1));

    Add the directive *foo* with value *bar* in the context pointed by $obj.

    Aguments:

    "name"
        Section's name to add.

    "value"
        Value associated with this section's name

    "-before"=>*target*
        insert section one line before *target* if is in same context;

    "-after"=>*target*
        insert section one line after *target* if is in same context;

    "-ontop"
        insert section on the fist line of current context;

    "-onbottom"
        insert section on the last line of current context;

    Return the added section

  section ([[*name*], *value*], [-which=>*number*])

        @sections_list      = $obj->section;
        @section_values     = $obj->section(SectionName);
        $section_object     = $obj->section(SectionName=>'value');

    arguments:

    - "name"
        the name of section, it's File in section <File "*/path/to/file*">

    - "value"
        the value of the section

    This method return :

    -   list of sections in current context if no argument is given.

    -   list of sections *foo*'s values if the only argument is *foo*.

        return a list in list context and a reference to an array in scalar
        context.

    -   an object for the context pointed by the section *foo* with value
        *bar* if arguments given was *foo* and *bar*.

  add_directive (*name*=>*'value'*, [-before=>*target* | -after=>*target* | -ontop | -onbottom])

        $obj->add_directive(foo=>'bar', -after=>$obj->directive('oof', -which=>-1));

    Add the directive *foo* with value *bar* in the context pointed by $obj.

    Aguments:

    "name"
        Directive's name to add.

    "value"
        Value associated with this directive's name

    "-before"=>*target*
        insert directive one line before *target* if is in same context;

    "-after"=>*target*
        insert directive one line after *target* if is in same context;

    "-ontop"
        insert directive on the fist line of current context;

    "-onbottom"
        insert directive on the last line of current context;

    Return the added directive.

  directive ([[*name*], *value*], [-which=>*number*])

        @directives_list    = $obj->directive;
        @directive_values   = $obj->directive(Foo);
        $directvie_object   = $obj->directive(Foo=>'bar');

    Arguments:

    "name"
        the name of directive.

    "value"
        value of the directive.

    This method return :

    -   list of directives in context pointed by $obj if no argument is
        given.

        return a list in list context and a reference to an array in scalar
        context.

    -   list of *foo* directive's values if the only argument is *foo*.

        return a list in list context and a reference to an array in scalar
        context.

    -   an object for handling directive called *foo* with value *bar* if
        arguments given was *foo* and *bar*. Warning, if several directive
        have the same name and value, the last one is taken, may change in
        future versions.

  delete ()

        $htconf->directive('AddType'=>'.pl')->delete;
        $htconf->section('File'=>'/path/to/file')->delete;

    Delete the current context pointed by object. Can be directive or
    section.

  set_value (*newvalue*)

        $htconf->directive('File'=>'/path/to/foo')->set_value('/path/to/bar');

    Change the value of a directive or section. If no argument given, return
    the value of object $htconf.

  value ()

    Return the value of rule pointed by the object if any.

    ("value" and "set_value" are the same method)

  move (-before=>*target* | -after=>*target* | -replace=>*target* | -tofirst | -tolast)

    under construction

  name ()

    Return the name of the current pointed directive or section. return
    undef if object point to the top context:

        my $obj = new Apache:Admin::Config ("/path/to/file");

        $obj->name; return undef
        $obj->directive(-which=>0)->name; return first directive's name
        $obj->section(Foo, -which=>0)->name; return "Foo"

  lines ()

    * If the caller object point to a directive :

      Return a list of lines'number occuped by the object's directive. If
      more than one line'number is return, that's mean the directive is
      truncated on serveral lines :

          18. DirectoryIndex  index.html \
          19.                 index.shtml \
          20.                 index.pl \
          ...

          $obj->directive(DirectoryIndex, -which=>x)->line # return (18, 19, 20)

    * If the caller object point to a section :

      Return a list of arrayref where all odd indexes are sections-opening
      and pair are sections-closing. Each arrayref conteints a list of
      lines'number occuped by the section rule (if section rule truncated).

          18. <VirtualHost 127.0.0.1 \
          19.              10.20.30.40 \
          20.              197.200.30.40>
          21.     ServerName example.com
          22. </VirtualHost>
          ...
          50. <VirtualHost 127.0.0.1 10.20.30.40 197.200.30.40>
          51.     ServerAlias www.example.com
          52.     User        rs
          53. </VirtualHost>

          $obj->directive(VirtualHost, -which=>x)->lines # return ([18, 19, 20], [22], [50], [53])

  first_line ()

  last_line ()

  dump_line *line_number*

        $obj->dump_line($directive->first_line);

    Dump the *line_number* line of current parsed configuration.

  isin ($section_obj, [-recursif])

    Return true if object point to a rule that is in the section represented
    by $section_obj. If "-recursif" option is present, true is also return
    if object is a sub-section of target.

        <section target>
            <sub section>
                directive test
            </sub>
        </section>

        $test_directive->isin($target_section)              => return false
        $test_directive->isin($sub_section)                 => return true
        $test_directive->isin($target_section, '-recursif') => return true

  parent ()

    Return the parent context of object.

    $obj is same as $obj->directive(-which=>0)->parent

  type ()

    Return the type of object. Types can be 'directive', 'section' or 'top'.

  error ()

    Return the last append error.

AUTHOR
    Olivier Poitrey <rs@rhapsodyk.net>

AVAILABILITY
    The official FTP location is :

    ftp://ftp.rhapsodyk.net/pub/devel/perl/Apache-Admin-Config-current.tar.g
    z

    Also available on CPAN.

LICENCE
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This program is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
    Public License for more details.

    You should have received a copy of the GNU General Public License along
    with the program; if not, write to the Free Software Foundation, Inc. :

    59 Temple Place, Suite 330, Boston, MA 02111-1307

COPYRIGHT
    Copyright (C) 2001 - Olivier Poitrey