NAME¶
Apache::Admin::Config - A module to read/write Apache like configuration files
SYNOPSIS¶
use Apache::Admin::Config;
# Parse an apache configuration file
my $conf = new Apache::Admin::Config "/path/to/config_file.conf"
or die $Apache::Admin::Config::ERROR;
my $directive = $conf->directive('documentroot');
print $directive->name; # "documentroot"
print $directive->value; # "/my/document/root"
print $directive->type; # "directive"
$directive->isin($conf); # true
$directive->delete;
# print the directive list
foreach($conf->directive())
{
print $_->name, "\n";
}
# print the virtualhost list
print $_->section('servername')->value(), "\n"
foreach $conf->section(-name => "virtualhost");
# add a directive in all virtualhosts
foreach($conf->section(-name => "virtualhost"))
{
$_->add_directive(php_admin_value => 'open_basedir "/path"');
}
# Deleting all "AddType" directives
$_->delete for $conf->directive("AddType");
# saving changes in place
$conf->save;
DESCRIPTION¶
"Apache::Admin::Config" provides an object oriented interface for
reading and writing Apache-like configuration files without affecting
comments, indentation, or truncated lines.
You can easily extract informations from the apache configuration, or manage
htaccess files.
I wrote this class because I work for an IPP, and we often manipulate apache
configuration files for adding new clients, activate some features or
un/locking directories using htaccess, etc. It can also be useful for writing
some one-shoot migrations scripts in few lines.
METHODES¶
new
$obj = new Apache::Admin::Config [/path/to/file|handle],
[-indent => $integer], ['-create'], ['-no-comment-grouping'],
['-no-blank-grouping']
Create or read, if given in argument, an apache like configuration file, and
return an Apache::Admin::Config instence.
Arguments:
- "/path/to/file"
- Path to the configuration file to parse. If none given,
create a new one.
- "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 $obj = new Apache::Admin::Config (\*MYHANDLE);
- -indent =>
$integer
- If greater than 0, activates the indentation on added
lines, the integer tell how many spaces you went per level of indentation
(suggest 4). A negative value means padding with tabulation(s).
- -create
- If present and path to an unexisting file is given, don't
return an error.
- -no-comment-grouping
- When there are several successive comment-lines, if comment
grouping is enabled only one comment item is created.
If present, disable comment grouping at parsing time. Enabled by
default.
- -no-blank-grouping
- Same as comment grouping but for blank lines.
save
$obj->save(['/path/to/file'|HANDLE], ['-reformat'])
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());
Note: If you invoke
save() on an object instantiated with a filehandle,
you should emptied it before. Keep in mind that the constructor don't seek the
FH to the begin neither before nor after reading it.
dump_raw
$obj->dump_raw
Returns the configuration file as same as it will be if it was saved in a file
with the
save() method. If you don't call this
method from the top level section, it returns the part of the configuration
file that is under the object's context.
dump_reformat
$obj->dump_raw
Same as
dump_raw(), but reformat each line. Usefull used with -indent
constructor parameter.
select
@result = $obj->select
(
[-type => $type],
[-name => $name],
[-value => $value],
[-which => $index],
);
@directives = $obj->select('directive');
@sections_foo = $obj->select('section', 'Foo');
This method search in the current context for items (directives, sections,
comments...) that correspond to a properties given by arguments. It returns a
list of matched nods.
This method can only be called on an object of type "section". This
method search only for elements in the section pointed by object, and isn't
recursive. So elements
in sub-sections of current section aren's seek
(it's not a bug).
Arguments:
- "type"
- Selects item(s) of "type" type.
- "name"
- Selects item(s) with "name" name.
- "value"
- Selects item(s) with "value" value.
- "which"
- Instead of returning a list of items, returns only a single
one pointed by index given to the -which option. Caution, returns an empty
string if none selected, so don't cascade your methodes calls like
$obj->select(-which=>0)->name. Index starts at 0.
Method returns a list of item(s) founds. Each items is an Apache::Admin::Config
object with same methods but pointing to a different part of the tree.
directive
@directives = $obj->directive(args...)
Same as calling select('directive', args...)
section
@sections = $obj->section(args...)
Same as calling select('section', args...)
comment
@comments = $obj->comment(args...)
Same as calling select('comment', args...)
blank
@blanks = $obj->blank(args...)
Same as calling select('blank', args...)
set_write_directive
$conf->set_write_directive($code);
Replace the directive writing engine by you own code. Code is call for adding
new directives, or when you tell Apache::Admin::Config to reformat the whole
configuration file. See
save() and
dump_reformat() methods for more details.
Your handler receives 3 arguments : $self, $name and $value. You can call the
"indent()" method to get the number of spaces to put before the
current line (see
indent() methods for more
details)
$conf->set_write_directive(sub
{
my($self, $name, $value) = @_;
return $self->indent . "$name $value\n";
}
set_write_section
$conf->set_write_section($code);
Same as
set_write_directive() but for section.
Your handler receives 3 arguments: $self, $name and $value. You can call the
"indent()" method to get the number of spaces to put before the
current line (see
indent() methods for more
details)
$conf->set_write_section(sub
{
my($self, $name, $value) = @_;
return $self->indent . "<$name $value>\n";
}
set_write_section_closing
$conf->set_write_section_closing($code);
Same as
set_write_directive() but for end of sections.
Your handler receives 2 arguments: $self and $name. You can call the
"indent()" method to get the number of spaces to put before the
current line (see
indent() methods for more
details)
$conf->set_write_section_closing(sub
{
my($self, $name) = @_;
return $self->indent . "</$name>\n";
}
set_write_comment
$conf->set_write_comment($code);
Same as
set_write_directive() but for comments.
Your handler receives 2 arguments: $self and $value. You can call the
"indent()" method to get the number of spaces to put before the
current line (see
indent() methods for more
details)
$conf->set_write_comment(sub
{
my($self, $value) = @_;
# handle comment grouping
$value =~ s/\n/\n# /g;
return $self->indent . join('#', split(/\n/, $value));
}
set_write_blank
$conf->set_write_blank($code);
Same as
set_write_directive() but for blank lines.
Your handler receives 2 arguments: $self and $number.
$conf->set_write_blank(sub
{
my($self, $number) = @_;
return $number x "\n";
}
add
$item = $obj->add
(
$type|$item, [$name], [$value],
[-before => $target | -after => $target | '-ontop' | '-onbottom']
);
$item = $obj->add('section', foo => 'bar', -after => $conf_item_object);
$item = $obj->add('comment', 'a simple comment', '-ontop');
Add a line of type
$type with name
foo and value
bar in the context pointed by
$object.
Aguments:
- "type"
- Type of object to add (directive, section, comment or
blank).
- "name"
- Only relevant for directives and sections.
- "value"
- For directive and section, it defines the value, for
comments it defined the text.
- "-before" =>
target
- Inserts item one line before target. target
_have_ to be in the same context
- "-after" =>
target
- Inserts item one line after target. target
_have_ to be in the same context
- "-ontop"
- Insert item on the fist line of current context;
- "-onbottom"
- Iinsert item on the last line of current context;
Returns the added item
add_section
$section = $obj->add_section($name, $value)
Same as calling add('section', $name, $value)
add_directive
$directive = $obj->add_directive($name, $value)
Same as calling add('directive', $name, $value)
add_comment
$comment = $obj->add_comment("string", [$group])
Same as calling add('comment', 'string', )
$group is a boolean value that control grouping of consecutive comment lines.
Disabled by default.
add_blank
$blank = $obj->add_blank([$group])
Same as calling add('blank')
$group is a boolean value that control grouping of consecutive blank lines.
Enabled by default.
set_value
$obj->set_value($newvalue)
Change the value of a directive or section. If no argument given, return the
value.
value
Returns the value of item pointed by the object if any.
(Actually "value" and "set_value" are the same method)
move
$obj->move
(
$dest_section,
-before => target |
-after => $target |
'-ontop' |
'-onbottom'
)
Move item into given section. See "add()" method for options
description.
copy
$item->copy
(
$dest_section,
-before => target |
-after => $target |
'-ontop' |
'-onbottom'
)
Copy item into given section. See "add()" method for options
description.
clone
$clone = $item->clone();
Clone item and all its children. Returns the cloned item.
first_line
last_line
count_lines
isin
$boolean = $obj->($section_obj, ['-recursif'])
Returns 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
$target_section->isin($target_section) => return true
name
Returns the name of the current pointed object if any
parent
Returns the parent context of object. This method on the top level object
returns "undef".
type
Returns the type of object.
remove
Synonym for unlink (deprecated). See
unlink().
unlink
$boolean = $item->unlink();
Unlinks item from the tree, resulting in two separate trees. The item to unlink
becomes the root of a new tree.
destroy
$boolean = $item->destroy();
Destroy item and its children. Caution, you should call
delete() method
instead if you want destroy a part of a tree. This method don't notice item's
parents of its death.
delete
$booleen = $item->delete;
Remove the current item from it's parent children list and destroy it and all
its children (
remove() +
destroy()).
error
Return the last appended error.
EXAMPLES¶
#
# Reindent configuration file properly
#
my $conf = Apache::Admin::Config
(
'/etc/apache/httpd.conf',
-indent => 2
);
$conf->save('-reformat');
#
# Managing virtual-hosts:
#
my $conf = new Apache::Admin::Config "/etc/apache/httpd.conf";
# adding a new virtual-host:
my $vhost = $conf->add_section(VirtualHost=>'127.0.0.1');
$vhost->add_directive(ServerAdmin=>'webmaster@localhost.localdomain');
$vhost->add_directive(DocumentRoot=>'/usr/share/www');
$vhost->add_directive(ServerName=>'www.localhost.localdomain');
$vhost->add_directive(ErrorLog=>'/var/log/apache/www-error.log');
my $location = $vhost->add_section(Location=>'/admin');
$location->add_directive(AuthType=>'basic');
$location->add_directive(Require=>'group admin');
$conf->save;
# selecting a virtual-host:
my $vhost;
foreach my $vh (@{$conf->section('VirtualHost')})
{
if($vh->directive('ServerName')->value eq 'www.localhost.localdomain')
{
$vhost = $vh;
last;
}
}
#
# Suppress all comments in the file
#
sub delete_comments
{
foreach(shift->comment)
{
$_->delete;
}
}
sub delete_all_comments
{
foreach($_[0]->section)
{
delete_all_comments($_);
}
delete_comments($_[0]);
}
delete_all_comments($conf);
#
# Transform configuration file into XML format
#
my $c = new Apache::Admin::Config "/path/to/file", -indent => 2
or die $Apache::Admin::Config::ERROR;
$c->set_write_directive(sub {
my($self, $name, $value) = @_;
return($self->indent.qq(<directive name="$name" value="$value />\n));
});
$c->set_write_section(sub {
my($self, $name, $value) = @_;
return($self->indent.qq(<section name="$name" value="$value">\n));
});
$c->set_write_section_closing(sub {
my($self, $name) = @_;
return($self->indent."</section>\n");
});
$c->set_write_comment(sub {
my($self, $value) = @_;
$value =~ s/\n//g;
return($self->indent."<!-- $value -->");
});
print $c->dump_reformat();
AUTHOR¶
Olivier Poitrey <rs@rhapsodyk.net>
AVAILABILITY¶
The official FTP location is:
ftp://ftp.rhapsodyk.net/pub/devel/perl/Apache-Admin-Config-current.tar.gz
Also available on CPAN.
anonymous CVS repository:
CVS_RSH=ssh cvs -d anonymous@cvs.rhapsodyk.net:/devel co Apache-Admin-Config
(supply an empty string as password)
CVS repository on the web:
http://www.rhapsodyk.net/cgi-bin/cvsweb/Apache-Admin-Config/
BUGS¶
Please send bug-reports to aac@list.rhapsodyk.net. You can subscribe to the list
by sending an empty mail to aac-subscribe@list.rhapsodyk.net.
LICENCE¶
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option)
any later version.
This library 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 Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc., 59
Temple Place, Suite 330, Boston, MA 02111-1307 USA
COPYRIGHT¶
Copyright (C) 2001 - Olivier Poitrey