pf-tools/pf-tools: 23 new changesets

parmelan-guest at users.alioth.debian.org parmelan-guest at users.alioth.debian.org
Sun Jan 2 18:50:52 UTC 2011


details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/404ae2d655c5
changeset: 1134:404ae2d655c5
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 07:49:35 2010 +0100
description:
perltidy

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/e3656764b022
changeset: 1135:e3656764b022
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 08:14:55 2010 +0100
description:
Rename get_site_config() to get_site_dhcp_config(), write new get_site_config(), and use it

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/37de5a0ac451
changeset: 1136:37de5a0ac451
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 15:07:15 2010 +0100
description:
Use get_site_config()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/fcb0ab1d9124
changeset: 1137:fcb0ab1d9124
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 15:32:05 2010 +0100
description:
make_preseed_file(): use check_*()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/504110bd9e8c
changeset: 1138:504110bd9e8c
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 15:42:44 2010 +0100
description:
make_pxe_boot_and_preseed_files(): use check_*()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/7c01b7c6229e
changeset: 1139:7c01b7c6229e
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 15:46:39 2010 +0100
description:
Unbreak tests for make_zone_file()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/3c04e534e168
changeset: 1140:3c04e534e168
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 15:48:16 2010 +0100
description:
Unbreak tests for make_resolv_conf_file()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/90ccfd404eb6
changeset: 1141:90ccfd404eb6
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 15:58:55 2010 +0100
description:
arguments_ref => args_ref

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/11abe7094e6b
changeset: 1142:11abe7094e6b
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 16:48:02 2010 +0100
description:
More check_*() uses

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/bec19ec6b767
changeset: 1143:bec19ec6b767
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 17:27:12 2010 +0100
description:
More check_*() uses

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/d2fe28137040
changeset: 1144:d2fe28137040
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 18:33:57 2010 +0100
description:
Use check_*() in make_resolv_conf_file()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/7026c9dd3903
changeset: 1145:7026c9dd3903
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 18:45:14 2010 +0100
description:
mk_sources_list: host defaults to the local host

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/7c7f7772e855
changeset: 1146:7c7f7772e855
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Tue Dec 28 19:00:50 2010 +0100
description:
style

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/03cd13ba7838
changeset: 1147:03cd13ba7838
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Dec 30 11:30:45 2010 +0100
description:
Use named arguments for check_args_type() + new check_mandatory_true_args_type() function

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/ac41b63dd71b
changeset: 1148:ac41b63dd71b
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Dec 30 11:44:16 2010 +0100
description:
Use check_mandatory_true_args_type(), start work on search_and_replace()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/5d1043649b1c
changeset: 1149:5d1043649b1c
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Dec 30 19:47:06 2010 +0100
description:
More work on search_and_replace() and __search_and_replace_*()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/5257fea46b95
changeset: 1150:5257fea46b95
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Dec 30 20:00:49 2010 +0100
description:
search_and_replace(): test the 'iface' filter

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/56434a57a0d4
changeset: 1151:56434a57a0d4
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Thu Dec 30 20:39:29 2010 +0100
description:
search_and_replace(): test the 'ip' filter

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/c670699c2aa6
changeset: 1152:c670699c2aa6
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Sat Jan 01 02:53:55 2011 +0100
description:
Style

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/0cd9e6ebc6f6
changeset: 1153:0cd9e6ebc6f6
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Sun Jan 02 12:56:06 2011 +0100
description:
search_and_replace() now handles the output file

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/3d661fde23a9
changeset: 1154:3d661fde23a9
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Sun Jan 02 13:28:17 2011 +0100
description:
filters/*: use the new search_and_replace()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/950038d9a60a
changeset: 1155:950038d9a60a
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Sun Jan 02 13:56:21 2011 +0100
description:
Resolv() renamed to resolve_hostname(), use check_*()

details:   http://hg.debian.org/hg/pf-tools/pf-tools/rev/badcfa737c2e
changeset: 1156:badcfa737c2e
user:      Thomas Parmelan <tom+pf-tools at ankh.fr.EU.org>
date:      Sun Jan 02 13:57:47 2011 +0100
description:
resolve_hostname() -> __resolve_hostname() + move with other private functions

diffstat:

31 files changed, 96 insertions(+), 88 deletions(-)
filters/filter_distrib                      |   22 ++++++++-----------
filters/filter_privateresolve               |   21 ++++++++++--------
filters/filter_vlan2if                      |   21 +++++++++---------
lib/PFTools/Conf.pm                         |    1 
lib/PFTools/Conf/Network.pm                 |    1 
lib/PFTools/Packages.pm                     |    1 
lib/PFTools/Packages/DEB.pm                 |   16 +++++++-------
lib/PFTools/Structqueries.pm                |    1 
lib/PFTools/Update.pm                       |    3 --
lib/PFTools/Update/ADDFILE.pm               |    1 
lib/PFTools/Update/ADDLINK.pm               |    1 
lib/PFTools/Update/ADDMOUNT.pm              |    1 
lib/PFTools/Update/CREATEFILE.pm            |    5 +---
lib/PFTools/Update/INSTALLPKG.pm            |    3 --
lib/PFTools/Utils.pm                        |    2 -
lib/PFTools/VCS.pm                          |    3 --
lib/PFTools/VCS/CVS.pm                      |    4 +--
sbin/fix_hosts                              |    7 +-----
sbin/mk_grubopt                             |    8 +------
sbin/mk_interfaces                          |    5 +---
sbin/mk_pxelinuxcfg                         |    4 +--
sbin/mk_resolvconf                          |    2 -
sbin/mk_sitezone                            |    1 
sbin/mk_sourceslist                         |    6 -----
t/13.conf.t                                 |   30 +++++++++++++++++++++++++++
t/20.files.search_and_replace.input.distrib |    1 
t/20.files.search_and_replace.input.iface   |    1 
t/20.files.search_and_replace.input.ip      |    3 ++
t/20.files.t                                |    2 -
tools/Display_IP_config                     |    4 +--
tools/Translate_old_config                  |    3 --

diffs (5250 lines):

diff -r d1af4c8d4e57 -r badcfa737c2e filters/filter_distrib
--- a/filters/filter_distrib	Wed Dec 22 16:45:36 2010 +0100
+++ b/filters/filter_distrib	Sun Jan 02 13:57:47 2011 +0100
@@ -27,34 +27,64 @@
 use Sys::Hostname;
 
 use PFTools::Structqueries;
-use PFTools::Utils;
-
-#################################
-# VARS
+use PFTools::Utils qw( Init_TOOLS search_and_replace );
 
 my @options_specs = (
+    'config|c=s',
     'help',
     'host|h=s',
-    'site|s=s',
-    'config|c=s',
-    'store=s',
     'input|i=s',
     'output|o=s',
+    'site|s=s',
+    'store=s',
 );
 
 my $options = {
-    'help'      => 0,
-    'host'      => hostname,
-    'output'    => '-',
+    'help'   => 0,
+    'host'   => hostname,
+    'input'  => q{-},
+    'output' => q{-},
 };
-
-my $PF_CONFIG         = {};
-my $GLOBAL_STRUCT     = {};
 
 my $program = basename $PROGRAM_NAME;
 
+GetOptions( $options, @options_specs )
+    or die qq{Didn't grok options (see --help).\n};
+
+if ( $options->{'help'} ) {
+    Do_help();
+    exit 0;
+}
+
+my ( $pf_config, $global_config )
+    = Init_TOOLS(
+    $options->{'host'}, $options->{'config'},
+    $options->{'store'}
+    );
+
+$options->{'site'} ||= $pf_config->{'location'}->{'site'}
+    || get_uniq_site_from_hostname( $options->{'host'}, $global_config );
+
+if ( not $options->{'input'} or not $options->{'output'} ) {
+    die q{ERROR: --input and --output are mandatory};
+}
+
+search_and_replace(
+    {
+        hostname        => $options->{'host'},
+        site_name       => $options->{'site'},
+        input_filename  => $options->{'input'},
+        output_filename => $options->{'output'},
+        filter_type     => 'distrib',
+        pf_config       => $pf_config,
+        global_config   => $global_config,
+    }
+);
+
+exit 0;
+
 ###################################
-# Funtions
+# Functions
 
 sub Do_help {
     print STDERR << "# ENDHELP";
@@ -65,52 +95,9 @@
 	-s --site	: site on which hostname is defined (optional)
 	-c --config	: file where pf-tools configuration is stored e.g. /etc/pf-tools.conf (optional)
 	--store		: file where global structure datas are in storable format (optional)
-	-i --input	: input file
-	-o --output	: output file
+	-i --input	: input file (default: STDIN)
+	-o --output	: output file (default: STDOUT)
     
 # ENDHELP
 }
 
-##################################
-### MAIN
-
-GetOptions( $options, @options_specs )
-    or die "Didn't grok options (see --help).\n";
-
-if ($options->{'help'}) {
-    Do_help();
-    exit 0;
-}
-
-( $PF_CONFIG, $GLOBAL_STRUCT ) = Init_TOOLS(
-    $options->{'host'},
-    $options->{'config'},
-    $options->{'store'}
-);
-
-unless( $options->{'site'} ) {
-    $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
-        || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
-}
-
-if ( $options->{'input'} eq '' || $options->{'output'} eq '' ) {
-    die "Source and/or destination file is(are) not defined on CLI";
-}
-
-my $filtered_src = Search_and_replace(
-    $options->{'host'}, $options->{'site'},
-    $options->{'input'}, 'distrib',
-    $PF_CONFIG, "", $GLOBAL_STRUCT
-);
-
-my $output_fh = IO::File->new ( ">" . $options->{'output'} )
-    or die "Unable to open destination $options->{'output'} : $OS_ERROR";
-
-$output_fh->print( join( "", @{$filtered_src} ) )
-    or die "Unable to write on destination $options->{'output'} : $OS_ERROR";
-
-$output_fh->close()
-    or die "Unable to close destination $options->{'output'} : $OS_ERROR";
-
-exit 0;
-
diff -r d1af4c8d4e57 -r badcfa737c2e filters/filter_privateresolve
--- a/filters/filter_privateresolve	Wed Dec 22 16:45:36 2010 +0100
+++ b/filters/filter_privateresolve	Sun Jan 02 13:57:47 2011 +0100
@@ -29,36 +29,78 @@
 use Sys::Hostname;
 
 use PFTools::Structqueries;
-use PFTools::Utils;
+use PFTools::Utils qw( Init_TOOLS search_and_replace );
 
-#<<< please, perltidy, don't mess with this (keep each entry on its own line)
 my @options_specifications = (
     'config|c=s',
     'help',
     'host|h=s',
     'input|i=s',
+    'ip=s',
     'output|o=s',
     'sep=s',
-    'ip=s',
     'site|s=s',
     'store=s',
     'type|t=s',
     'zone|z=s',
 );
-#>>>
+
 # default values
 my $options = {
-    'help'  => 0,
-    'host'  => hostname,
-    'sep'   => ' ',
-    'type'  => 'cnf',
-    'ip'    => 'ipv4',
+    'help'   => 0,
+    'host'   => hostname,
+    'input'  => q{-},
+    'ip'     => q{ipv4},
+    'output' => q{-},
+    'sep'    => q{ },
+    'type'   => 'cnf',
 };
 
 my $program = basename $PROGRAM_NAME;
 
+GetOptions( $options, @options_specifications )
+    or die "Didn't grok options (see --help).\n";
+
+if ( $options->{'help'} ) {
+    Do_help();
+    exit 0;
+}
+
+if ( not $options->{'input'} or not $options->{'output'} ) {
+    die q{ERROR: --input and --output are mandatory};
+}
+
+my ( $pf_config, $global_config ) = Init_TOOLS(
+    $options->{'host'},
+    $options->{'config'},
+    $options->{'store'}
+);
+
+$options->{'site'} ||= $pf_config->{'location'}->{'site'}
+    || get_uniq_site_from_hostname( $options->{'host'}, $global_config );
+
+$options->{'zone'}
+    ||= get_zone_from_site( $options->{'site'}, $global_config );
+
+search_and_replace(
+    {
+        hostname        => $options->{'host'},
+        site_name       => $options->{'site'},
+        input_filename  => $options->{'input'},
+        output_filename => $options->{'output'},
+        filter_type     => q{ip},
+        pf_config       => $pf_config,
+        global_config   => $global_config,
+        ip_type         => $options->{'ip'},
+        resolution_type => $options->{'type'},
+        separator       => $options->{'sep'},
+    }
+);
+
+exit 0;
+
 ###################################
-# Funtions
+# Functions
 
 sub Do_help {
     print STDERR << "# ENDHELP";
@@ -77,76 +119,9 @@
  -t --type                 : type for resolution. Allowed values are cnf
                              (from global configuration structure) and dns
  --sep                     : separator between resolved IPs [default: space]
- -i --input                : input file
- -o --output               : output file
+ -i --input                : input file [default: STDIN]
+ -o --output               : output file [default: STDOUT]
     
 # ENDHELP
 }
 
-##################################
-### MAIN
-
-GetOptions( $options, @options_specifications )
-    or die "Didn't grok options (see --help).\n";
-
-if ( $options->{'help'} ) {
-    Do_help();
-    exit 0;
-}
-
-unless ( $options->{'input'} and $options->{'output'} ) {
-    die "Source and/or destination file is(are) not defined on CLI";
-}
-
-my ( $PF_CONFIG, $GLOBAL_STRUCT ) = Init_TOOLS(
-    $options->{'host'},
-    $options->{'config'},
-    $options->{'store'}
-);
-
-unless ( $options->{'site'} ) {
-    $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
-        || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
-}
-
-unless ( $options->{'zone'} ) {
-    $options->{'zone'}
-        = get_zone_from_site( $options->{'site'}, $GLOBAL_STRUCT );
-}
-
-my $filtered_src = Search_and_replace(
-    $options->{'host'},
-    $options->{'site'},
-    $options->{'input'},
-    'resolver',
-    $PF_CONFIG,
-    $options->{'sep'},
-    $GLOBAL_STRUCT,
-    $options->{'type'},
-    $options->{'ip'}
-);
-
-# FIXME: functions with too many parameters should be converted
-# to named parameters, like this :
-#my $args_ref = {
-#    hostname       => $options->{'hostname'},
-#    site           => $options->{'site'},
-#    'input-file'   => $options->{'input-file'},
-#    resolver       => 'resolver',
-#    pf_config      => $PF_CONFIG,
-#    separator      => $options->{'separator'},
-#    global_struct  => $GLOBAL_STRUCT,
-#    'resolve-type' => $options->{'type-resolve'},
-#};
-#my $filtered_src = search_and_replace($args_ref);
-
-my $output_fh = IO::File->new( ">". $options->{'output'} )
-    or die "Unable to open destination $options->{'output'}: $OS_ERROR";
-
-$output_fh->print( join '', @{$filtered_src} )
-    or die "Unable to write to destination $options->{'output'}: $OS_ERROR";
-
-$output_fh->close()
-    or die "Unable to close destination file $options->{'output'}: $OS_ERROR";
-
-exit 0;
diff -r d1af4c8d4e57 -r badcfa737c2e filters/filter_vlan2if
--- a/filters/filter_vlan2if	Wed Dec 22 16:45:36 2010 +0100
+++ b/filters/filter_vlan2if	Sun Jan 02 13:57:47 2011 +0100
@@ -33,33 +33,64 @@
 use Sys::Hostname;
 
 use PFTools::Structqueries;
-use PFTools::Utils;
+use PFTools::Utils qw( Init_TOOLS search_and_replace );
 
-#################################
-# VARS
+my $program = basename $PROGRAM_NAME;
 
 my @options_specs = (
+    'config|c=s',
     'help',
     'host|h=s',
-    'site|s=s',
-    'config|c=s',
-    'store=s',
     'input|i=s',
     'output|o=s',
+    'site|s=s',
+    'store=s',
 );
 
 my $options = {
-    'help'  => 0,
-    'host'  => hostname,
+    'help'   => 0,
+    'host'   => hostname,
+    'input'  => q{-},
+    'output' => q{-},
 };
 
-my $PF_CONFIG         = {};
-my $GLOBAL_STRUCT     = {};
+GetOptions( $options, @options_specs )
+    or die "Didn't grok options (see --help).\n";
 
-my $program = basename $PROGRAM_NAME;
+if ( $options->{'help'} ) {
+    Do_help();
+    exit 0;
+}
 
-###################################
-# Funtions
+if ( not $options->{'input'} or not $options->{'output'} ) {
+    die q{ERROR: --input and --output are mandatory};
+}
+
+my ( $pf_config, $global_config ) = Init_TOOLS(
+    $options->{'host'},
+    $options->{'config'},
+    $options->{'store'}
+);
+
+$options->{'site'} ||= $pf_config->{'location'}->{'site'}
+    || get_uniq_site_from_hostname( $options->{'host'}, $global_config );
+
+search_and_replace(
+    {
+        hostname        => $options->{'host'},
+        site_name       => $options->{'site'},
+        input_filename  => $options->{'input'},
+        output_filename => $options->{'output'},
+        filter_type     => 'iface',
+        pf_config       => $pf_config,
+        global_config   => $global_config,
+    }
+);
+
+exit 0;
+
+
+# only functions after this line
 
 sub Do_help {
     print STDERR << "# ENDHELP";
@@ -70,54 +101,9 @@
 	-s --site	: site on which hostname is defined (optional)
 	-c --config	: file where pf-tools configuration is stored e.g. /etc/pf-tools.conf (optional)
 	--store		: file where global structure datas are in storable format (optional)
-	-i --input	: input file
-	-o --output	: output file
+	-i --input	: input file (default: STDIN)
+	-o --output	: output file (default: STDOUT)
     
 # ENDHELP
 }
 
-##################################
-### MAIN
-
-GetOptions( $options, @options_specs )
-    or die "Didn't grok options (see --help).\n";
-
-if ($options->{'help'}) {
-    Do_help();
-    exit 0;
-}
-
-( $PF_CONFIG, $GLOBAL_STRUCT ) = Init_TOOLS(
-    $options->{'host'},
-    $options->{'config'},
-    $options->{'store'}
-);
-
-unless( $options->{'site'} ) {
-    $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
-        || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
-}
-
-if ( $options->{'input'} eq '' || $options->{'output'} eq '' ) {
-    die "Source and/or destination file is(are) not defined on CLI";
-}
-
-my $filtered_src = Search_and_replace(
-    $options->{'host'},
-    $options->{'site'},
-    $options->{'input'},
-    'iface',
-    $PF_CONFIG,
-    "",
-    $GLOBAL_STRUCT
-);
-
-my $output_fh = IO::File->new( ">" . $options->{'output'} )
-    or die "Unable to open destination $options->{'output'} : $OS_ERROR";
-$output_fh->print( join( "", @{$filtered_src} ) )
-    or die "Unable to write on destination $options->{'output'} : $OS_ERROR";
-$output_fh->close()
-    or die "Unable to close destination $options->{'output'} : $OS_ERROR";
-
-exit 0;
-
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools.pm
--- a/lib/PFTools.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -27,6 +27,7 @@
 
 our @EXPORT = qw(
     check_mandatory_args_type
+    check_mandatory_true_args_type
     check_optional_args_type
     check_args_type
     check_args
@@ -38,13 +39,19 @@
 our $VERSION = '1.0.1-WIP';
 
 
-=head2 FIXME
-=head2 check_args_type( $args_ref, $mandatory, $type, $names_ref )
+=head2 check_args_type($args_ref)
 
-Checks that the %{$args_ref} keys listed in @{$names_ref} all have a I<type>
-reference value. If I<$mandatory> has a true value, the arguments are
-considered mandatory (ie: the keys must exist). The available types are the
-known return values of the ref() builtin function, for instance:
+Takes the following named arguments:
+
+Checks that the I<%{$args_ref}> keys listed in I<@{$keys_ref}> all have a
+I<type> reference value. It takes the following named arguments:
+
+=over
+
+=item I<args_ref> a reference to the named arguments to check
+
+=item I<type> the type to check for. The available types are
+the known return values of the ref() builtin function, for instance:
 
 =over
 
@@ -54,14 +61,38 @@
 
 =item I<HASH>: the value must be a hash reference
 
-=over
+=back
+
+=item I<mandatory> if true (not by default), the arguments are considered
+mandatory (ie: the keys must exist).
+
+=item I<must_be_true> if true (not by default, the arguments must evaluate to
+a true value
+
+=back
 
 =cut
 
 sub check_args_type {
-    my ($args_ref, $mandatory, $type, @keys) = @_;
+    my ($my_args_ref) = @_;
 
-    if ( ref $args_ref ne 'HASH' or ref $mandatory or ref $type or not defined $type or not @keys ) {
+    if ( ref $my_args_ref ne 'HASH' ) {
+        croak q{ERROR: BUG: Invalid non-hash reference my_args_ref};
+    }
+
+    my ( $args_ref, $type, $mandatory, $must_be_true, $keys_ref )
+        = @{$my_args_ref}{qw( args_ref type mandatory must_be_true keys_ref )};
+
+    if ( ref $args_ref ne 'HASH' ) {
+        croak q{ERROR: Invalid non-hash reference args_ref};
+    }
+
+    if ( ref $keys_ref ne 'ARRAY' ) {
+        croak q{ERROR: Invalid non-array reference keys_ref};
+    }
+    my @keys = @{$keys_ref};
+
+    if ( ref $type or ref $mandatory or ref $must_be_true or not defined $type or not @keys ) {
         confess q{ERROR: BUG: invalid args};
     }
 
@@ -81,6 +112,11 @@
         if ( ref $args_ref->{$key} ne $type ) {
             croak qq{ERROR: Invalid $type_string $key};
         }
+
+        if ( $must_be_true and not $args_ref->{$key} ) {
+            croak qq{ERROR: Invalid false argument $key};
+        }
+
     }
 
     return 1;
@@ -97,7 +133,14 @@
 sub check_mandatory_args_type {
     my ($args_ref, $type, @keys) = @_;
 
-    return check_args_type( $args_ref, 1, $type, @keys );
+    return check_args_type(
+        {
+            args_ref  => $args_ref,
+            type      => $type,
+            keys_ref  => \@keys,
+            mandatory => 1,
+        }
+    );
 }
 
 =head2 check_optional_args_type( $args_ref, $type, @keys )
@@ -110,9 +153,35 @@
 sub check_optional_args_type {
     my ($args_ref, $type, @keys) = @_;
 
-    return check_args_type( $args_ref, 0, $type, @keys );
+    return check_args_type(
+        {
+            args_ref  => $args_ref,
+            type      => $type,
+            keys_ref  => \@keys,
+        }
+    );
 }
 
+=head2 check_mandatory_true_args_type( $args_ref, $type, @keys )
+
+Checks the arguments, treating them as mandatory and must_be_true (see
+I<check_args_type() for details).
+
+=cut
+
+sub check_mandatory_true_args_type {
+    my ($args_ref, $type, @keys) = @_;
+
+    return check_args_type(
+        {
+            args_ref     => $args_ref,
+            type         => $type,
+            keys_ref     => \@keys,
+            mandatory    => 1,
+            must_be_true => 1,
+        }
+    );
+}
 
 =head2 check_args( $function_ref, $args_ref, @keys)
 
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Conf.pm
--- a/lib/PFTools/Conf.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Conf.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -908,9 +908,8 @@
 
     my $site_list = get_site_list_from_section( $section_ref, $global_config );
     foreach my $site ( @{$site_list} ) {
-        my $service_part
-            = $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'SERVICE'}
-            ->{'BY_NAME'};
+        my $site_ref = get_site_config( $site, $global_config );
+        my $service_part = $site_ref->{'SERVICE'}->{'BY_NAME'};
 
         foreach my $host ( @{ $section_ref->{'@host'} } ) {
             my $hostfile = Get_source( $host, q{}, $hash_subst, $pf_config );
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Conf/Host.pm
--- a/lib/PFTools/Conf/Host.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Conf/Host.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -104,7 +104,7 @@
     my $site_list = get_site_list_from_section( $host_ref->{'hostgroup'},
         $global_config );
     foreach my $site ( @{$site_list} ) {
-        my $site_part_ref = $global_config->{'SITE'}->{'BY_NAME'}->{$site};
+        my $site_part_ref = get_site_config( $site, $global_config );
 
         unless ( $site_part_ref->{'HOST'}->{'BY_NAME'}->{$hostclass} ) {
             $site_part_ref->{'HOST'}->{'BY_NAME'}->{$hostclass} = {};
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Conf/Network.pm
--- a/lib/PFTools/Conf/Network.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Conf/Network.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -397,7 +397,8 @@
         };
 
     # Adding entries for network, netmask, broadcast etc. into the DNS zone
-    my $zone      = $global_config->{'SITE'}->{'BY_NAME'}->{$site_name}->{'zone'};
+    my $site_ref  = get_site_config( $site_name, $global_config );
+    my $zone      = $site_ref->{'zone'};
     my $suffix    = get_suffix_from_ip_type($ip_type);
     my $zone_key  = qq{ZONE$suffix};
     my $zone_part = $global_config->{$zone_key}->{'BY_NAME'}->{$zone};
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Packages.pm
--- a/lib/PFTools/Packages.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Packages.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -1,4 +1,5 @@
 package PFTools::Packages;
+
 #
 #  Copyright (C) 2009-2010 Christophe Caillet <quadchris at free.fr>
 #
@@ -44,10 +45,10 @@
 
     return if not $pkg_type;
 
-    my $module_name = "PFTools::Packages::".uc( $pkg_type );
+    my $module_name = "PFTools::Packages::" . uc($pkg_type);
     my $module;
     eval { $module = use_module($module_name); };
-    if( $EVAL_ERROR ) {
+    if ($EVAL_ERROR) {
         croak qq{Unable to init package engine $module_name};
     }
     $module->import();
@@ -57,14 +58,14 @@
 sub Get_pkg_status {
     my ( $pkg_type, $pkg_name ) = @_;
 
-    return if not ( $pkg_type or $pkg_name );
+    return if not( $pkg_type or $pkg_name );
     my $result = {};
 
-    if( not Init_pkgtype_module ( $pkg_type ) ) {
+    if ( not Init_pkgtype_module($pkg_type) ) {
         carp qq{ERROR: Unable to init package engine $pkg_type};
         return;
     }
-    return Pkg_status ( $pkg_name );
+    return Pkg_status($pkg_name);
 }
 
 sub Update_pkg_repository {
@@ -72,71 +73,71 @@
 
     return if not $pkg_type;
 
-    if( not Init_pkgtype_module ( $pkg_type ) ) {
+    if ( not Init_pkgtype_module($pkg_type) ) {
         carp qq{ERROR: Unable to init package engine $pkg_type};
         return;
     }
-    return Pkg_update_repository ();
+    return Pkg_update_repository();
 }
 
 sub Purge_pkg {
     my ( $pkg_type, $pkg_name ) = @_;
 
-    return if not ( $pkg_type or $pkg_name );
+    return if not( $pkg_type or $pkg_name );
 
-    if( not Init_pkgtype_module ( $pkg_type ) ) {
+    if ( not Init_pkgtype_module($pkg_type) ) {
         carp qq{ERROR: Unable to init package engine $pkg_type};
         return;
     }
-    return Pkg_purge ( $pkg_name );
+    return Pkg_purge($pkg_name);
 }
 
 sub Get_pkg_depends {
     my ( $pkg_type, $pkg_name ) = @_;
 
-    return if not ( $pkg_type or $pkg_name );
+    return if not( $pkg_type or $pkg_name );
 
-    if( not Init_pkgtype_module ( $pkg_type ) ) {
+    if ( not Init_pkgtype_module($pkg_type) ) {
         carp qq{ERROR: Unable to init package engine $pkg_type};
         return;
     }
-    return Pkg_depends ( $pkg_name );
+    return Pkg_depends($pkg_name);
 }
 
 sub Get_pkg_policy {
     my ( $pkg_type, $pkg_name, $version ) = @_;
 
-    return if not ( $pkg_type or $pkg_name );
+    return if not( $pkg_type or $pkg_name );
 
-    if( not Init_pkgtype_module ( $pkg_type ) ) {
+    if ( not Init_pkgtype_module($pkg_type) ) {
         carp qq{ERROR: Unable to init package engine $pkg_type};
         return;
     }
-    return Pkg_policy ( $pkg_name, $version );
+    return Pkg_policy( $pkg_name, $version );
 }
 
 sub Cmp_pkg_version {
     my ( $pkg_type, $pkg_name, $version1, $version2 ) = @_;
 
-    return if not ( $pkg_type or $pkg_name or $version1 or $version2 );
+    return if not( $pkg_type or $pkg_name or $version1 or $version2 );
 
-    if( not Init_pkgtype_module ( $pkg_type ) ) {
+    if ( not Init_pkgtype_module($pkg_type) ) {
         carp qq{ERROR: Unable to init package engine $pkg_type};
         return;
     }
-    return Pkg_compare_versions ( $pkg_name, $version1, $version2 );
+    return Pkg_compare_versions( $pkg_name, $version1, $version2 );
 }
 
 sub Install_pkg {
     my ( $pkg_type, $pkg_name, $version ) = @_;
 
-    return if not ( $pkg_type or $pkg_name );
+    return if not( $pkg_type or $pkg_name );
 
-    if( ! Init_pkgtype_module ( $pkg_type ) ) {
+    if ( !Init_pkgtype_module($pkg_type) ) {
         carp qq{ERROR: Unable to init package engine $pkg_type};
         return;
     }
-    return Pkg_install ( $pkg_name, $version );
+    return Pkg_install( $pkg_name, $version );
 }
 
 1;
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Packages/DEB.pm
--- a/lib/PFTools/Packages/DEB.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Packages/DEB.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -41,50 +41,51 @@
 our @EXPORT_OK = qw();
 
 my $PKG_CMD = {
-    'status'    => 'LANG=C LC_ALL=C /usr/bin/dpkg -s',
-    'update'    => 'LANG=C LC_ALL=C /usr/bin/apt-get -y --force-yes update',
-    'depends'   => 'LANG=C LC_ALL=C /usr/bin/apt-cache show',
-    'install'   => 'LANG=C LC_ALL=C /usr/bin/apt-get -y --force-yes install',
-    'purge'     => 'LANG=C LC_ALL=C /usr/bin/dpkg --purge',
-    'policy'    => 'LANG=C LC_ALL=C /usr/bin/apt-cache policy',
-    'compare'   => 'LANG=C LC_ALL=C /usr/bin/dpkg --compare-versions',
+    'status'  => 'LANG=C LC_ALL=C /usr/bin/dpkg -s',
+    'update'  => 'LANG=C LC_ALL=C /usr/bin/apt-get -y --force-yes update',
+    'depends' => 'LANG=C LC_ALL=C /usr/bin/apt-cache show',
+    'install' => 'LANG=C LC_ALL=C /usr/bin/apt-get -y --force-yes install',
+    'purge'   => 'LANG=C LC_ALL=C /usr/bin/dpkg --purge',
+    'policy'  => 'LANG=C LC_ALL=C /usr/bin/apt-cache policy',
+    'compare' => 'LANG=C LC_ALL=C /usr/bin/dpkg --compare-versions',
 };
 
 my $VERBOSE = 1;
 
 sub Pkg_status {
-    my ( $pkg_name ) = @_;
+    my ($pkg_name) = @_;
 
     return unless $pkg_name;
 
     my $result = {};
     my $output_fh;
     unless (
-        $output_fh = IO::File->new( 
+        $output_fh = IO::File->new(
             "$PKG_CMD->{'status'} '$pkg_name' 2>/dev/null |"
         )
-    ) {
+        )
+    {
         carp qq{ERROR: while getting status for $pkg_name : $OS_ERROR}
-            if( $VERBOSE );
+            if ($VERBOSE);
         return;
     }
     while (<$output_fh>) {
-        if( m{\A Status:\s+}xms ) {
-            if ( ! m{\A Status:\s+install\s+ok\s+installed\s* \z}xms ) {
+        if (m{\A Status:\s+}xms) {
+            if ( !m{\A Status:\s+install\s+ok\s+installed\s* \z}xms ) {
                 $result->{'installed'} = 0;
             }
             else {
                 $result->{'installed'} = 1;
             }
         }
-        if ( m{\A Version:\s+(.+)\s* \z}xms ) {
+        if (m{\A Version:\s+(.+)\s* \z}xms) {
             $result->{'version'} = $1;
             last;
         }
     }
-    unless( $output_fh->close() ) {
+    unless ( $output_fh->close() ) {
         carp qq{ERROR: while closing pkg_status command : $OS_ERROR"}
-            if( $VERBOSE );
+            if ($VERBOSE);
         return;
     }
     return $result;
@@ -93,43 +94,44 @@
 sub Pkg_update_repository {
 
     if ( deferredlogsystem( $PKG_CMD->{'update'} ) ) {
-        carp q{ERROR: while updating repository !} if( $VERBOSE );
+        carp q{ERROR: while updating repository !} if ($VERBOSE);
         return;
     }
     return 1;
 }
 
 sub Pkg_purge {
-    my ( $pkg_name ) = @_;
+    my ($pkg_name) = @_;
 
     return unless $pkg_name;
 
-    if ( deferredlogsystem( "$PKG_CMD->{'purge'} '$pkg_name'" ) ) {
+    if ( deferredlogsystem("$PKG_CMD->{'purge'} '$pkg_name'") ) {
         carp qq{ERROR: while purging $pkg_name : $OS_ERROR"}
-            if( $VERBOSE );
+            if ($VERBOSE);
         return;
     }
     return 1;
 }
 
 sub Pkg_depends {
-    my ( $pkg_name ) = @_;
+    my ($pkg_name) = @_;
 
     return unless $pkg_name;
 
     my $dep_list;
     my $output_fh;
-    unless ( 
+    unless (
         $output_fh = IO::File->new(
             "$PKG_CMD->{'depends'} '$pkg_name' 2>/dev/null |"
         )
-    ) {
+        )
+    {
         carp qq{ERROR: while getting deps for $pkg_name : $OS_ERROR"}
-            if( $VERBOSE );
+            if ($VERBOSE);
         return;
     }
-    while( <$output_fh> ) {
-        if( m{\A Depends: (.*) \z}xms ) {
+    while (<$output_fh>) {
+        if (m{\A Depends: (.*) \z}xms) {
             foreach my $pkg ( split( m{,}, $1 ) ) {
                 if ( $pkg =~ m{|} ) {
                     $pkg =~ s{\([^\)]+\)}{}g;
@@ -146,11 +148,12 @@
             }
         }
     }
-    unless( $output_fh->close() ) {
+    unless ( $output_fh->close() ) {
         carp qq{ERROR: while closing depends command : $OS_ERROR"}
             if ($VERBOSE);
         return;
     }
+
     #Removing trailing spaces
     $dep_list =~ s{\A \s*}{}xms;
     $dep_list =~ s{\s* \z}{}xms;
@@ -164,7 +167,7 @@
     my ( $installed, $available, $specified_version, $output_fh );
 
     $specified_version = 0;
-    $output_fh = IO::File->new(
+    $output_fh         = IO::File->new(
         "$PKG_CMD->{'policy'} '$pkg_name' 2>/dev/null |"
     );
     unless ($output_fh) {
@@ -172,20 +175,21 @@
             if ($VERBOSE);
         return;
     }
-    while( <$output_fh> ) {
+    while (<$output_fh>) {
         chomp;
-        if( m{\A  \s+Installed: (.*) \z}xms ) {
+        if (m{\A  \s+Installed: (.*) \z}xms) {
             $installed = $1;
-            undef $installed if ( $installed eq '' or $installed eq "(none)" );
+            undef $installed
+                if ( $installed eq '' or $installed eq "(none)" );
         }
-        elsif( m{\A \s*Candidate: (.*) \z}xms ) {
+        elsif (m{\A \s*Candidate: (.*) \z}xms) {
             $available = $1;
         }
         elsif ( defined $version && m{\Q$version\E} ) {
             $specified_version = 1;
         }
     }
-    unless( $output_fh->close() ) {
+    unless ( $output_fh->close() ) {
         carp qq{ERROR: while closing policy command : $OS_ERROR"}
             if ($VERBOSE);
         return;
@@ -198,14 +202,19 @@
 
     return unless $pkg_name or $version1 or $version2;
 
-    if ( ! deferredlogsystem(
-        "$PKG_CMD->{'compare'} '$version1' lt '$version2'" )
-    ) {
+    if (!deferredlogsystem(
+            "$PKG_CMD->{'compare'} '$version1' lt '$version2'"
+        )
+        )
+    {
         return -1;
     }
-    elsif ( ! deferredlogsystem(
-        "$PKG_CMD->{'compare'} '$version1' eq '$version2'" )
-    ) {
+    elsif (
+        !deferredlogsystem(
+            "$PKG_CMD->{'compare'} '$version1' eq '$version2'"
+        )
+        )
+    {
         return 0;
     }
     else {
@@ -224,7 +233,7 @@
         : " '$pkg_name'";
     if ( deferredlogsystem($install_cmd) ) {
         carp qq{ERROR while installing $pkg_name : $OS_ERROR"}
-            if( $VERBOSE );
+            if ($VERBOSE);
         return;
     }
     return 1;
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Structqueries.pm
--- a/lib/PFTools/Structqueries.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Structqueries.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -29,8 +29,6 @@
 use English qw( -no_match_vars );    # Avoids regex performance penalty
 use List::MoreUtils qw( uniq );
 
-#use PFTools::Logger;
-
 our @EXPORT = qw(
     get_suffix_from_ip_type
     get_zone_from_hostname
@@ -45,6 +43,7 @@
     get_mode_from_host_ref
     get_pkgtype_from_hostname
     get_host_config
+    get_site_dhcp_config
     get_site_config
     get_vlan_config
     is_private_vlan
@@ -105,7 +104,8 @@
 
     $site ||= get_uniq_site_from_hostname( $hostname, $global_config );
 
-    return $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'zone'};
+    my $site_ref = get_site_config( $site, $global_config );
+    return $site_ref->{'zone'};
 }
 
 =head2
@@ -142,9 +142,8 @@
         : $global_config->{'SITE'}->{'__site_list'};
 
     foreach my $site ( @{$site_list} ) {
-        my $host_part
-            = $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'HOST'}
-            ->{'BY_NAME'};
+        my $site_ref = get_site_config( $site, $global_config);
+        my $host_part = $site_ref->{'HOST'}->{'BY_NAME'};
         foreach my $hostclass ( keys %{$host_part} ) {
             return $hostclass if $hostclass eq $hostname;
 
@@ -198,9 +197,8 @@
 
     my @site_list = ();
     foreach my $site ( @{ $global_config->{'SITE'}->{'__site_list'} } ) {
-        my $host_part
-            = $global_config->{'SITE'}->{'BY_NAME'}->{$site}->{'HOST'}
-            ->{'BY_NAME'};
+        my $site_ref = get_site_config( $site, $global_config );
+        my $host_part = $site_ref->{'HOST'}->{'BY_NAME'};
         foreach my $hostclass ( keys %{$host_part} ) {
             if ( $hostclass eq $hostname ) {
                 push @site_list, $site;
@@ -230,7 +228,8 @@
 sub get_zone_from_site {
     my ( $site_name, $global_config ) = @_;
 
-    return $global_config->{'SITE'}->{'BY_NAME'}->{$site_name}->{'zone'};
+    my $site_ref = get_site_config( $site_name, $global_config );
+    return $site_ref->{'zone'};
 }
 
 =head2 get_site_list_from_section ( $section_ref, $global_config )
@@ -270,8 +269,8 @@
     my $hosttype
         = get_hosttype_from_hostname( $hostname, $global_config, $site_name );
 
-    my $site_part = $global_config->{'SITE'}->{'BY_NAME'}->{$site_name};
-    my $zone      = $site_part->{'zone'};
+    my $site_ref = get_site_config( $site_name, $global_config );
+    my $zone      = $site_ref->{'zone'};
     my ($hostshort)
         = $hostname =~ m{
             \A
@@ -297,7 +296,7 @@
     }
 
     my $host_config
-        = $site_part->{'HOST'}->{'BY_NAME'}->{$hosttype}->{$hostshort};
+        = $site_ref->{'HOST'}->{'BY_NAME'}->{$hosttype}->{$hostshort};
 
     unless ($host_config) {
         croak qq{ERROR: hostname $hostname: no configuration found};
@@ -306,14 +305,14 @@
     return $host_config;
 }
 
-=head2 get_site_config( $site_name, $global_config )
+=head2 get_site_dhcp_config( $site_name, $global_config )
 
-This function returns a reference to the site configuration hash for
+This function returns a reference to the site DHCP configuration hash for
 I<$site_name>.
 
 =cut
 
-sub get_site_config {
+sub get_site_dhcp_config {
     my ( $site_name, $global_config ) = @_;
 
     if ( not $site_name or ref $site_name ) {
@@ -336,6 +335,36 @@
     return $site_ref;
 }
 
+=head2 get_site_config( $site_name, $global_config )
+
+This function returns a reference to the site configuration hash for
+I<$site_name>.
+
+=cut
+
+sub get_site_config {
+    my ( $site_name, $global_config ) = @_;
+
+    if ( not $site_name or ref $site_name ) {
+        croak q{ERROR: Invalid site_name};
+    }
+
+    if (ref $global_config ne 'HASH'
+        or not exists $global_config->{'SITE'}->{'BY_NAME'}
+        )
+    {
+        croak q{ERROR: Invalid global_config};
+    }
+
+    my $site_ref = $global_config->{'SITE'}->{'BY_NAME'}->{$site_name};
+
+    if ( not $site_ref ) {
+        croak qq{ERROR: Unknown site '$site_name'};
+    }
+
+    return $site_ref;
+}
+
 =head2 get_vlan_config( $vlan_name, $global_config, $site_name )
 
 This function returns a reference to the vlan config hash for I<$vlan_name>.
@@ -350,9 +379,9 @@
         croak q{ERROR: $site MUST BE defined};
     }
 
-    my $site_part = $global_config->{'SITE'}->{'BY_NAME'}->{$site_name};
+    my $site_ref = get_site_config( $site_name, $global_config );
 
-    return $site_part->{'NETWORK'}->{'BY_NAME'}->{$vlan_name};
+    return $site_ref->{'NETWORK'}->{'BY_NAME'}->{$vlan_name};
 }
 
 =head2 is_private_vlan( $vlan_name, $global_config, $site_name )
@@ -373,15 +402,15 @@
         croak q{ERROR: Invalid empty $site};
     }
 
-    my $site_part = $global_config->{'SITE'}->{'BY_NAME'}->{$site_name};
+    my $site_ref = get_site_config( $site_name, $global_config );
 
     # We really don't want to croak() here
-    unless ( $site_part->{'NETWORK'}->{'BY_NAME'}->{$vlan_name} ) {
+    unless ( $site_ref->{'NETWORK'}->{'BY_NAME'}->{$vlan_name} ) {
         carp qq{WARNING: unknown vlan $vlan_name on site $site_name};
         return;
     }
 
-    my $scope = $site_part->{'NETWORK'}->{'BY_NAME'}->{$vlan_name}->{'scope'};
+    my $scope = $site_ref->{'NETWORK'}->{'BY_NAME'}->{$vlan_name}->{'scope'};
 
     return $scope eq 'private';
 }
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Update.pm
--- a/lib/PFTools/Update.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Update.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -75,16 +75,17 @@
 my $APT_UPDATE = 1;
 
 sub __Init_action_engine {
-    my ( $action ) = @_;
+    my ($action) = @_;
 
     return unless $action;
 
-    my $module_name = "PFTools::Update::".uc( $action );
+    my $module_name = "PFTools::Update::" . uc($action);
     my $module;
     eval { $module = use_module($module_name); };
-    if( $EVAL_ERROR ) {
+    if ($EVAL_ERROR) {
         print "$EVAL_ERROR\n";
-        croak qq{ERROR: Unable to init action engine $module_name for $action};
+        croak
+            qq{ERROR: Unable to init action engine $module_name for $action};
         return;
     }
     $module->import();
@@ -94,18 +95,18 @@
 sub Get_depends_for_action ($$$$) {
     my ( $action, $ref_section, $dest, $options ) = @_;
 
-    __Init_action_engine ( $action );
+    __Init_action_engine($action);
 
     # Checking parameter
-    unless( ref( $ref_section ) eq 'HASH' ) {
+    unless ( ref($ref_section) eq 'HASH' ) {
         carp q{ERROR: non-hashref $ref_section};
         return;
     }
-    unless( ref( $options ) eq 'HASH' ) {
+    unless ( ref($options) eq 'HASH' ) {
         carp q{ERROR: non-hashref $options};
         return;
     }
-    if( ref( $action ) || ref( $dest ) ) {
+    if ( ref($action) || ref($dest) ) {
         carp q{ERROR: $action and/or $dest MUST be string(s)};
         return;
     }
@@ -117,13 +118,14 @@
     my ( $action, $ref_section, $dest, $options, $hash_subst, $global_config )
         = @_;
 
-    __Init_action_engine ( $action );
+    __Init_action_engine($action);
+
     # Adding some commons entries into substitution hash : $hash_subst
     $hash_subst->{'SECTIONNAME'} = $dest;
     return 1 if ( $action eq "ignore" );
     if ( $action eq "apt-get" || $action eq "installpkg" ) {
-        if($APT_UPDATE) {
-            if( !Update_pkg_repository( $options->{'pkg_type'} ) ) {
+        if ($APT_UPDATE) {
+            if ( !Update_pkg_repository( $options->{'pkg_type'} ) ) {
                 carp q{An error occured during updating packages lists};
                 return;
             }
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Update/ADDFILE.pm
--- a/lib/PFTools/Update/ADDFILE.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Update/ADDFILE.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -42,8 +42,8 @@
 sub Action_depends {
     my ( $ref_section, $dest, $options ) = @_;
 
-    while( $dest ne "/" && $dest ne "." ) {
-        my $new_dest = dirname( $dest );
+    while ( $dest ne "/" && $dest ne "." ) {
+        my $new_dest = dirname($dest);
         $ref_section->{'depends'} .= " " . $new_dest
             if ( $new_dest ne "." && $new_dest ne "/" );
         $dest = $new_dest;
@@ -56,13 +56,14 @@
 
     my $diff = 0;
     $hash_subst->{'SECTIONNAME'} = $dest;
-    $tmp                         = Get_tmp_dest( $dest );
+    $tmp = Get_tmp_dest($dest);
+
     # Removing trailing space from source
     $ref_section->{'source'} =~ s{\A\s*}{};
     $ref_section->{'source'} =~ s{\s*\z}{};
     if ( $ref_section->{'source'} =~ m{\s} ) {
         $source = Get_tmp_dest($dest) . ".merged";
-        unlink( $source );
+        unlink($source);
         my $splitsource;
         foreach $splitsource ( split( ' ', $ref_section->{'source'} ) ) {
             $splitsource = Get_source(
@@ -70,14 +71,15 @@
                 $options->{'host'},
                 $hash_subst
             );
-            if( !-f $splitsource ) {
+            if ( !-f $splitsource ) {
                 carp qq{ERROR: $splitsource no such file or directory};
                 return;
             }
-            if( deferredlogsystem(
+            if (deferredlogsystem(
                     "cat '" . $splitsource . "' >> " . $source
                 )
-            ) {
+                )
+            {
                 carp qq{ERROR: Unable to append $splitsource to $source};
                 return;
             }
@@ -89,38 +91,38 @@
         );
     }
 
-    if( !-e $source ) {
+    if ( !-e $source ) {
         carp qq{ERROR: $source no such file or directory};
         return;
     }
     $hash_subst->{'SOURCE'}      = $source;
     $hash_subst->{'DESTINATION'} = $tmp;
-    if( defined( $ref_section->{'filter'} ) ) {
+    if ( defined( $ref_section->{'filter'} ) ) {
         my $filter = Subst_vars( $ref_section->{'filter'}, $hash_subst );
-        if ( deferredlogsystem( $filter ) ) {
+        if ( deferredlogsystem($filter) ) {
             carp qq{ERROR: Unable to apply filter $filter};
             return;
         }
     }
     else {
-        unless( copy( $source, $tmp ) ) {
+        unless ( copy( $source, $tmp ) ) {
             carp qq{ERROR: Unable to copy $source to $tmp};
             return;
         }
     }
 
-    if( !-f $tmp ) {
+    if ( !-f $tmp ) {
         carp qq{ERROR: Unable to open $tmp};
         return;
     }
 
-    if( compare( $tmp, $dest ) ) {
+    if ( compare( $tmp, $dest ) ) {
         $diff = 1;
         if ( $options->{'verbose'} || $options->{'simul'} ) {
             Log("(action needed)");
         }
         if ( $options->{'diff'} ) {
-            if( !-e $dest ) {
+            if ( !-e $dest ) {
                 print diff ( [], $tmp, { STYLE => "Unified" } );
             }
             else {
@@ -131,22 +133,24 @@
         Do_on_config( $ref_section, $options, $hash_subst ) or return;
         print "before_change ...\n";
         Do_before_change( $ref_section, $options, $hash_subst ) or return;
-        if( ! $options->{'simul'} ) {
+        if ( !$options->{'simul'} ) {
+
             # Fuck dpkg conffiles
-            if (   $options->{'noaction'}
+            if ($options->{'noaction'}
                 && -e $dest
                 && !-e $dest . '.dpkg-dist'
-            ) {
+                )
+            {
                 copy( $dest, $dest . '.dpkg-dist' );
             }
             Do_moveold( $dest, $options );
-            if ( ! Mk_dest_dir( $dest ) || ! copy( $tmp, $dest ) ) {
+            if ( !Mk_dest_dir($dest) || !copy( $tmp, $dest ) ) {
                 carp qq{ERROR: Unable to copy file $tmp to $dest};
                 return;
             }
             Do_chownmod( $ref_section, $dest, $options );
         }
-        if( $diff ) {
+        if ($diff) {
             print "after_change ...\n";
             Do_after_change( $ref_section, $options, $hash_subst ) or return;
             print "on_noaction ...\n";
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Update/ADDLINK.pm
--- a/lib/PFTools/Update/ADDLINK.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Update/ADDLINK.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -40,8 +40,8 @@
     my ( $ref_section, $dest, $options ) = @_;
 
     while ( $dest ne "/" && $dest ne "." ) {
-        $ref_section->{'depends'} .= " " . dirname( $dest );
-        $dest = dirname( $dest );
+        $ref_section->{'depends'} .= " " . dirname($dest);
+        $dest = dirname($dest);
     }
 }
 
@@ -54,10 +54,10 @@
     # Need to check the source ...
     my $dep_src = $source;
     while ( $dep_src ne "/" && $dep_src ne "." ) {
-        $ref_section->{'depends'} .= " " . dirname( $dep_src );
-        $dep_src = dirname( $dep_src );
+        $ref_section->{'depends'} .= " " . dirname($dep_src);
+        $dep_src = dirname($dep_src);
     }
-    if ( ! -l $dest || ( -l $dest && readlink( $dest ) ne $source ) ) {
+    if ( !-l $dest || ( -l $dest && readlink($dest) ne $source ) ) {
         if ( $options->{'verbose'} || $options->{'simul'} ) {
             Log("(action needed)");
         }
@@ -73,7 +73,7 @@
         Do_before_change( $ref_section, $options, $hash_subst ) or return;
         if ( !$options->{'simul'} ) {
             Do_moveold( $dest, $options );
-            if ( ! Mk_dest_dir($dest) || ! ln_sfn( $source, $dest ) ) {
+            if ( !Mk_dest_dir($dest) || !ln_sfn( $source, $dest ) ) {
                 carp qq{ERROR: Unable to symlink $dest to $source};
                 return;
             }
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Update/ADDMOUNT.pm
--- a/lib/PFTools/Update/ADDMOUNT.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Update/ADDMOUNT.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -36,12 +36,14 @@
 use PFTools::Parser;
 use PFTools::Structqueries;
 use PFTools::Update::Common;
+
 #use PFTools::Update::Mkdir;
 
 our @EXPORT = qw(
     Action_depends
     Action_exec
 );
+
 #    Addmount_depends
 #    Addmount_action
 
@@ -60,8 +62,8 @@
     my ( $ref_section, $dest, $options ) = @_;
 
     while ( $dest ne "/" && $dest ne "." ) {
-        $ref_section->{'depends'} .= " " . dirname( $dest );
-        $dest = dirname( $dest );
+        $ref_section->{'depends'} .= " " . dirname($dest);
+        $dest = dirname($dest);
     }
 }
 
@@ -77,14 +79,15 @@
     my $hosttype = get_hosttype_from_hostname( $hostshort, $global_config );
     my $site_list = get_site_list_from_hostname( $hostshort, $global_config );
     my $site;
-    if ( ! defined $site_list || scalar @{$site_list} > 1 ) {
+
+    if ( !defined $site_list || scalar @{$site_list} > 1 ) {
         carp qq{ERROR: Unknown or multiple site for $host};
         return;
     }
     else {
         $site = shift @{$site_list};
     }
-    if( ! isipaddr( $ip ) ) {
+    if ( !isipaddr($ip) ) {
         my $resolved = resolve_hostname_from_global_config(
             {
                 hostname      => $ip,
@@ -96,7 +99,7 @@
                 # FIXME ip_type => ????,
             }
         );
-        if ( ! defined $resolved || scalar @{$resolved} > 1 ) {
+        if ( !defined $resolved || scalar @{$resolved} > 1 ) {
             carp qq{ERROR: Unknown or multiple IPs for $host};
             return;
         }
@@ -108,12 +111,13 @@
 }
 
 sub __Resolve_fstab_entry {
-    my ( $param ) = @_;
+    my ($param) = @_;
 
     my $pf_config = Init_PF_CONFIG();
     my $fs_entry  = $param->{'fs_entry'};
-    if ( $fs_entry->{'fstype'}
-        =~ m{\A $pf_config->{'regex'}->{'network_fstype'} \z}xms )
+    if ($fs_entry->{'fstype'}
+        =~ m{\A $pf_config->{'regex'}->{'network_fstype'} \z}xms
+        )
     {
         foreach my $key ( 'source', 'options' ) {
             my $value
@@ -126,10 +130,13 @@
                 ? '^(?<pre>.*,)?(ip=(?<ip>[^,]+))?(?<suf>,.*)?$'
                 : '^(?<ip>[^\:]+):(?<suf>.+)$';
             $val_addr =~ s{$regex}{$+{ip}};
+
             if ( defined $val_addr && $val_addr ne $value ) {
-                my $val_ip = __Get_ip_host_from_GLOBAL( $val_addr,
-                    $param->{'global_config'} );
-                return unless( $val_ip );
+                my $val_ip = __Get_ip_host_from_GLOBAL(
+                    $val_addr,
+                    $param->{'global_config'}
+                );
+                return unless ($val_ip);
                 $regex
                     = ( $key eq 'options' )
                     ? '^(?<pre>(.*,)?(ip=)?)(?<ip>[^,]+)?(?<suf>,.*)?$'
@@ -155,7 +162,7 @@
         'fs_entry'      => $fs_entry,
         'global_config' => $param->{'global_config'}
     };
-    if ( ! __Resolve_fstab_entry($resolve_param) ) {
+    if ( !__Resolve_fstab_entry($resolve_param) ) {
         return;
     }
     return $fs_entry;
@@ -174,7 +181,7 @@
             'ref_section'   => $ref_section
         }
     );
-    unless( $add_mount ) {
+    unless ($add_mount) {
         carp qq{ERROR: Unable to build addmount entry $dest};
         return;
     }
@@ -183,18 +190,18 @@
         = join( ',', sort split( ',', $add_mount->{'options'} ) );
     $hash_subst->{'FSTYPE'} = $ref_section->{'fstype'} || $DEFAULT_FSTYPE;
 
-    my $current_fstab = Build_structure_from_fstab( "/etc/fstab" );
-    unless( $current_fstab ) {
+    my $current_fstab = Build_structure_from_fstab("/etc/fstab");
+    unless ($current_fstab) {
         carp q{ERROR: Unable to build fstab structure from file /etc/fstab};
         return;
     }
-    my $current_proc = Build_structure_from_fstab( "/proc/mounts" );
-    unless( $current_fstab ) {
+    my $current_proc = Build_structure_from_fstab("/proc/mounts");
+    unless ($current_fstab) {
         carp q{ERROR: Unable to build fstab structure from file /proc/mounts};
         return;
     }
     my $addfstab = 0;
-    if ( ! defined $current_fstab->{$dest} ) {
+    if ( !defined $current_fstab->{$dest} ) {
         foreach
             my $key ( 'source', 'dest', 'fstype', 'options', 'dump', 'pass' )
         {
@@ -222,12 +229,14 @@
             if ( $key eq 'options' ) {
                 $addproc = 1
                     if (
-                    $add_mount->{$key} ne $current_fstab->{$dest}->{$key} );
+                    $add_mount->{$key} ne $current_fstab->{$dest}->{$key}
+                    );
             }
             else {
                 $addproc = 1
                     if (
-                    $add_mount->{$key} ne $current_proc->{$dest}->{$key} );
+                    $add_mount->{$key} ne $current_proc->{$dest}->{$key}
+                    );
             }
         }
     }
@@ -238,73 +247,79 @@
         }
         Do_on_config( $ref_section, $options, $hash_subst ) or return;
         Do_before_change( $ref_section, $options, $hash_subst ) or return;
-        if ( ! -d $dest && $dest ne 'none' ) {
-            unless( make_path( $dest ) ) {
+        if ( !-d $dest && $dest ne 'none' ) {
+            unless ( make_path($dest) ) {
                 carp qq{ERROR: while creating mountpoints $dest};
                 return;
             }
         }
-        if( $addfstab ) {
-            my $tmp = Get_tmp_dest( "/etc/fstab" );
+        if ($addfstab) {
+            my $tmp = Get_tmp_dest("/etc/fstab");
             my $output_fh;
-            unless( $output_fh = IO::File->new ( '>'. $tmp ) ) {
+            unless ( $output_fh = IO::File->new( '>' . $tmp ) ) {
                 carp qq{ERROR: Unable to create tmp $tmp : $OS_ERROR};
                 return;
             }
-            my $new_fstab = Build_fstab_from_structure( $current_fstab );
-            unless( print $output_fh join "\n", @{$new_fstab} ) {
+            my $new_fstab = Build_fstab_from_structure($current_fstab);
+            unless ( print $output_fh join "\n", @{$new_fstab} ) {
                 carp qq{ERROR: Unable to write on tmp $tmp : $OS_ERROR"};
                 return;
             }
-            unless( $output_fh->close() ) {
+            unless ( $output_fh->close() ) {
                 carp qq{ERROR: Unable to close tmp $tmp : $OS_ERROR"};
                 return;
             }
-            if( $options->{'diff'} ) {
+            if ( $options->{'diff'} ) {
                 print diff ( '/etc/fstab', $tmp, { STYLE => 'Unified' } );
             }
-            if( ! $options->{'simul'} ) {
-                if ( ! move( $tmp, "/etc/fstab" ) ) {
+            if ( !$options->{'simul'} ) {
+                if ( !move( $tmp, "/etc/fstab" ) ) {
                     carp qq{ERROR: Unable to move $tmp to /etc/fstab};
                     return;
                 }
             }
         }
-        if( $addproc ) {
+        if ($addproc) {
             my $remount = 1;
-            if( defined $current_proc->{$dest} ) {
+            if ( defined $current_proc->{$dest} ) {
                 foreach my $key ( 'source', 'dest', 'fstype' ) {
                     $remount = 0
-                        if ( $add_mount->{$key} ne
-                        $current_proc->{$dest}->{$key} );
+                        if (
+                        $add_mount->{$key} ne
+                        $current_proc->{$dest}->{$key}
+                        );
                 }
             }
-            if( $options->{'diff'} ) {
+            if ( $options->{'diff'} ) {
                 foreach my $key ( 'source', 'dest', 'fstype', 'options' ) {
                     my $value = $current_proc->{$dest}->{$key} || '?';
-                    if( $key eq 'options' ) {
-                        Log(      $key . " " 
+                    if ( $key eq 'options' ) {
+                        Log($key . " "
                                 . $value . " -> "
-                                . $add_mount->{$key} )
-                            if ( $current_fstab->{$dest}->{$key} ne
+                                . $add_mount->{$key}
+                            )
+                            if (
+                            $current_fstab->{$dest}->{$key} ne
                             $add_mount->{$key}
-                            || ! defined $current_proc->{$dest}->{$key} );
+                            || !defined $current_proc->{$dest}->{$key}
+                            );
                     }
                     else {
-                        Log(      $key . " " 
+                        Log($key . " "
                                 . $value . " -> "
-                                . $add_mount->{$key} )
+                                . $add_mount->{$key}
+                            )
                             if ( $value ne $add_mount->{$key} );
                     }
                 }
             }
-            if( ! $options->{'simul'} && !$options->{'noaction'} ) {
-                if( $remount ) {
+            if ( !$options->{'simul'} && !$options->{'noaction'} ) {
+                if ($remount) {
                     my $cmd
                         = "mount -o 'remount,"
                         . $add_mount->{'options'} . "' '"
                         . $dest . "'";
-                    if ( deferredlogsystem( $cmd ) ) {
+                    if ( deferredlogsystem($cmd) ) {
                         carp qq{ERROR: while remounting $dest with
                             $add_mount->{'options'}
                         };
@@ -313,8 +328,10 @@
                 }
                 else {
                     my $umount
-                        = ( $add_mount->{'source'} ne
-                            $current_proc->{$dest}->{'source'} )
+                        = (
+                        $add_mount->{'source'} ne
+                            $current_proc->{$dest}->{'source'}
+                        )
                         ? $current_proc->{$dest}->{'source'}
                         : $add_mount->{'source'};
                     if ( deferredlogsystem( "umount '" . $umount . "'" ) ) {
@@ -328,6 +345,7 @@
                         . $add_mount->{'options'} . "' '"
                         . $add_mount->{'source'} . "' '"
                         . $add_mount->{'dest'} . "'";
+
                     if ( deferredlogsystem($mount_cmd) ) {
                         carp qq{ERROR: while mounting $dest with $mount_cmd};
                         return;
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Update/CREATEFILE.pm
--- a/lib/PFTools/Update/CREATEFILE.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Update/CREATEFILE.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -50,15 +50,16 @@
     my ( $ref_section, $dest, $options, $hash_subst, $global_config ) = @_;
 
     $hash_subst->{'SECTIONNAME'} = $dest;
-    my $tmp = Get_tmp_dest( $dest );
+    my $tmp = Get_tmp_dest($dest);
     $hash_subst->{'DESTINATION'} = $tmp;
-    unless( -f $dest ) {
-        if( $options->{'verbose'} || $options->{'simul'} ) {
+    unless ( -f $dest ) {
+        if ( $options->{'verbose'} || $options->{'simul'} ) {
             Log("(action needed)");
         }
-        if( ! defined $ref_section->{'source'} ) {
+        if ( !defined $ref_section->{'source'} ) {
+
             # Creating an empty tmp destination
-            if( deferredlogsystem( "/usr/bin/touch '$tmp'" ) ) {
+            if ( deferredlogsystem("/usr/bin/touch '$tmp'") ) {
                 carp qq{ERROR: Unable to touch $tmp};
                 return;
             }
@@ -68,20 +69,22 @@
                 $ref_section->{'source'}, $hash_subst->{'HOSTNAME'},
                 $hash_subst
             );
+
             # Creating tmp destination from source
-            unless( -f $source ) {
+            unless ( -f $source ) {
                 carp qq{ERROR: Unable to open source $source};
                 return;
             }
             if ( defined( $ref_section->{'filter'} ) ) {
-                my $filter = Subst_vars( $ref_section->{'filter'}, $hash_subst );
-                if( deferredlogsystem( $filter ) ) {
+                my $filter
+                    = Subst_vars( $ref_section->{'filter'}, $hash_subst );
+                if ( deferredlogsystem($filter) ) {
                     carp qq{ERROR: Unable to apply filter $filter};
                     return;
                 }
             }
             else {
-                if( !copy( $source, $tmp ) ) {
+                if ( !copy( $source, $tmp ) ) {
                     carp qq{ERROR: Unable to copy $source to $tmp};
                     return;
                 }
@@ -89,7 +92,7 @@
         }
         Do_on_config( $ref_section, $options, $hash_subst ) or return;
         Do_before_change( $ref_section, $options, $hash_subst ) or return;
-        if ( ! $options->{'simul'} && ! copy ( $tmp, $dest ) ) {
+        if ( !$options->{'simul'} && !copy( $tmp, $dest ) ) {
             carp qq{ERROR: Unable to create $dest with $tmp};
             return;
         }
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Update/Common.pm
--- a/lib/PFTools/Update/Common.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Update/Common.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -61,7 +61,7 @@
 ###
 
 sub isipaddr {
-    my ( $ip ) = @_;
+    my ($ip) = @_;
 
     my @sub = split( m{\.}, $ip );
     return if ( $#sub != 3 );
@@ -78,22 +78,23 @@
     if ( $options->{'verbose'} || $options->{'simul'} ) {
         Log("(chown needed)");
     }
-    return 1 if( $options->{'simul'} );
-    my ( $dev, $ino, $mode, $nlink, $uid, $gid, @others ) = stat( $dest );
+    return 1 if ( $options->{'simul'} );
+    my ( $dev, $ino, $mode, $nlink, $uid, $gid, @others ) = stat($dest);
     if ( $type eq 'chown' ) {
-        my $newuid = getpwnam( $right1 );
-        my $newgid = getgrnam( $right2 );
-        if(    ( $uid && $uid == $newuid )
+        my $newuid = getpwnam($right1);
+        my $newgid = getgrnam($right2);
+        if (( $uid && $uid == $newuid )
             && ( $gid && $gid == $newgid )
-        ) {
-            print "Useless $type for $dest" if( $options->{'verbose'} );
+            )
+        {
+            print "Useless $type for $dest" if ( $options->{'verbose'} );
             return 1;
         }
         return chown( $newuid, $newgid, $dest );
     }
     elsif ( $type eq 'chmod' ) {
         if ( $mode && ( $mode & 07777 ) == $right1 ) {
-            print "Useless $type for $dest" if( $options->{'verbose'} );
+            print "Useless $type for $dest" if ( $options->{'verbose'} );
             return 1;
         }
         return chmod( $right1, $dest );
@@ -120,19 +121,19 @@
 sub ln_sfn {
     my ( $source, $dest ) = @_;
 
-    unlink( $dest );
-    rmdir( $dest );
+    unlink($dest);
+    rmdir($dest);
     return symlink( $source, $dest );
 }
 
 sub dirname {
-    my ( $file ) = @_;
+    my ($file) = @_;
 
     $file =~ s{//}{/}g;
 
     if ( $file =~ m{/} ) {
         $file =~ s{\A (.*)/[^/]+/? \z}{$1}xms;
-        $file = "." if( $file =~ m{\A \s* \z}xms );
+        $file = "." if ( $file =~ m{\A \s* \z}xms );
     }
     else {
         $file = '.';
@@ -145,14 +146,14 @@
     my ( $dest, $options ) = @_;
 
     my $pf_config = Init_PF_CONFIG();
-    if( -e $dest ) {
+    if ( -e $dest ) {
         my $old
-            = $pf_config->{'path'}->{'checkout_dir'} . "/old/" 
+            = $pf_config->{'path'}->{'checkout_dir'} . "/old/"
             . $dest . "."
             . $STARTTIME;
         Log( "(moving old to " . $old . ")" ) if ( $options->{'verbose'} );
         unless ( $options->{'simul'} ) {
-            Mk_dest_dir( $old );
+            Mk_dest_dir($old);
             return move( $old, $dest );
         }
     }
@@ -165,7 +166,7 @@
     my $owner = $ref_section->{'owner'} || $DEFAULT_OWNER;
     my $group = $ref_section->{'group'} || $DEFAULT_GROUP;
 
-    unless( fullchown( $owner, $group, $dest, $options ) ) {
+    unless ( fullchown( $owner, $group, $dest, $options ) ) {
         carp qq{ERROR: Unable to chown with $owner and/or $group for $dest};
         return;
     }
@@ -174,7 +175,7 @@
         || ( -d $dest ) ? $DEFAULT_DIRMODE : $DEFAULT_MODE;
     $mode =~ s{\A [^0]}{0$&}xms;
 
-    unless( fullchmod( eval($mode), $dest, $options ) ) {
+    unless ( fullchmod( eval($mode), $dest, $options ) ) {
         carp qq{ERROR: Unable to chmod to $mode for $dest};
         return;
     }
@@ -182,7 +183,7 @@
 }
 
 sub Exec_cmd {
-    my ( $cmd ) = @_;
+    my ($cmd) = @_;
 
     if ( deferredlogsystem($cmd) ) {
         carp qq{ERROR: Unable to execute [$cmd]};
@@ -199,8 +200,9 @@
             if ( $options->{'verbose'} );
         return 1;
     }
-    if ( ! $options->{'simul'}
-        && defined( $ref_section->{'on_config'} ) )
+    if (!$options->{'simul'}
+        && defined( $ref_section->{'on_config'} )
+        )
     {
         return Exec_cmd(
             Subst_vars( $ref_section->{'on_config'}, $hash_subst )
@@ -217,12 +219,14 @@
             if ( $options->{'verbose'} );
         return 1;
     }
-    if (   ! $options->{'simul'}
-        && ! $options->{'noaction'}
-        && defined( $ref_section->{'before_change'} ) )
+    if (!$options->{'simul'}
+        && !$options->{'noaction'}
+        && defined( $ref_section->{'before_change'} )
+        )
     {
         return Exec_cmd(
-            Subst_vars( $ref_section->{'before_change'}, $hash_subst ) );
+            Subst_vars( $ref_section->{'before_change'}, $hash_subst )
+        );
     }
     return 1;
 }
@@ -235,12 +239,14 @@
             if ( $options->{'verbose'} );
         return 1;
     }
-    if (   !$options->{'simul'}
+    if (!$options->{'simul'}
         && defined( $ref_section->{'after_change'} )
-        && !$options->{'noaction'} )
+        && !$options->{'noaction'}
+        )
     {
         return Exec_cmd(
-            Subst_vars( $ref_section->{'after_change'}, $hash_subst ) );
+            Subst_vars( $ref_section->{'after_change'}, $hash_subst )
+        );
     }
     return 1;
 }
@@ -253,12 +259,14 @@
             if ( $options->{'verbose'} );
         return 1;
     }
-    if (   !$options->{'simul'}
+    if (!$options->{'simul'}
         && defined( $ref_section->{'on_noaction'} )
-        && $options->{'noaction'} )
+        && $options->{'noaction'}
+        )
     {
         return Exec_cmd(
-            Subst_vars( $ref_section->{'on_noaction'}, $hash_subst ) );
+            Subst_vars( $ref_section->{'on_noaction'}, $hash_subst )
+        );
     }
     return 1;
 }
@@ -272,7 +280,7 @@
     return unless $dir;
 
     # FIXME rewrite this part, it's really unreadable!!
-    $dir =~ s{//}{/}g;        # supprimer // sinon ca marche moins bien
+    $dir =~ s{//}{/}g;             # supprimer // sinon ca marche moins bien
     $dir =~ s{/[^/]+/* \z}{}xms;
     my $dir2 = $dir;
     while ( $dir2 ne "" && !-e $dir2 ) {
@@ -283,7 +291,7 @@
     }
 
     eval { make_path($dir); };
-    if( $EVAL_ERROR ) {
+    if ($EVAL_ERROR) {
         carp qq{ERROR: make_path($dir): $EVAL_ERROR};
         return;
     }
@@ -298,10 +306,10 @@
     my $tmp       = $pf_config->{'path'}->{'checkout_dir'} . "/tmp/" . $dest;
     Mk_dest_dir($tmp);
     if ( -d $tmp ) {
-        rmdir( $tmp );
+        rmdir($tmp);
     }
     elsif ( -e $tmp ) {
-        unlink( $tmp );
+        unlink($tmp);
     }
     return $tmp;
 }
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Update/INSTALLPKG.pm
--- a/lib/PFTools/Update/INSTALLPKG.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Update/INSTALLPKG.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -49,13 +49,13 @@
 sub Action_depends {
     my ( $ref_section, $dest, $options ) = @_;
 
-    $options->{'pkg_type'} = 'deb' unless( $options->{'pkg_type'} );
+    $options->{'pkg_type'} = 'deb' unless ( $options->{'pkg_type'} );
     my $deps = Get_pkg_depends( $options->{'pkg_type'}, $dest );
-    unless( $deps ) {
+    unless ($deps) {
         carp qq{ERROR: Unable to get depends for $dest};
         return;
     }
-    if( $ref_section->{'depends'} ) {
+    if ( $ref_section->{'depends'} ) {
         $ref_section->{'depends'} .= $deps;
     }
     else {
@@ -66,14 +66,14 @@
 sub Action_exec {
     my ( $ref_section, $dest, $options, $hash_subst, $global_config ) = @_;
 
-    $options->{'pkg_type'} = 'deb' unless( $options->{'pkg_type'} );
+    $options->{'pkg_type'} = 'deb' unless ( $options->{'pkg_type'} );
     my $installed_version;
     my $available_version;
     my $specified_version = 0;
     my $install           = 0;
 
     my $name_filter = $ref_section->{'name_filter'};
-    if( $name_filter ) {
+    if ($name_filter) {
         my $newdest = deferredlogpipe(
             Subst_vars( $name_filter, $hash_subst )
         );
@@ -81,7 +81,7 @@
             carp qq{ERROR: Unable to apply name_filter $name_filter};
             return;
         }
-        unless( $newdest ) {
+        unless ($newdest) {
             carp qq{ERROR: Empty result for name_filter $name_filter};
             return;
         }
@@ -90,17 +90,17 @@
     $hash_subst->{'SECTIONNAME'} = $dest;
     ( $installed_version, $available_version, $specified_version )
         = Get_pkg_policy(
-            $options->{'pkg_type'}, $dest, $ref_section->{'version'}
+        $options->{'pkg_type'}, $dest, $ref_section->{'version'}
         );
-    unless( $available_version ) {
+    unless ($available_version) {
         carp qq{ERROR: Package $dest is unavailable};
         return;
     }
-    if( defined( $ref_section->{'version'} ) && ! $specified_version ) {
+    if ( defined( $ref_section->{'version'} ) && !$specified_version ) {
         carp qq{ERROR: $dest ($ref_section->{'version'}) is unavailable};
         return;
     }
-    if ( ! defined $installed_version ) {
+    if ( !defined $installed_version ) {
         $install++;
     }
     else {
@@ -110,7 +110,7 @@
         );
         $install++ if ( defined $compare && $compare < 0 );
     }
-    if( $install ) {
+    if ($install) {
         if ( $options->{'verbose'} || $options->{'simul'} ) {
             Log("(action needed)");
         }
@@ -130,13 +130,13 @@
                     . ")"
             );
         }
-        if( defined( $ref_section->{'delay'} ) && ! $options->{'noaction'} ) {
+        if ( defined( $ref_section->{'delay'} ) && !$options->{'noaction'} ) {
             $hash_subst->{'HOSTNAME'} =~ m{\d+ \z}xms;
             if ( $& ne "" ) {
                 sleep( 120 * $& );
             }
         }
-        if( !$options->{'simul'} ) {
+        if ( !$options->{'simul'} ) {
             my $debconf      = 0;
             my $debconf_vars = {};
             foreach my $key ( keys %{$ref_section} ) {
@@ -145,7 +145,7 @@
                 $key =~ m{\A debconf\.(.*) \z}xmso;
                 $debconf_vars->{$1} = $ref_section->{$key};
             }
-            if( $debconf ) {
+            if ($debconf) {
                 my ( $DEB, $conf, $pkg );
                 my $pf_config = Init_PF_CONFIG();
                 my $vcs_tpl_dir
@@ -171,20 +171,21 @@
         }
         Do_on_config( $ref_section, $options, $hash_subst ) or return;
         Do_before_change( $ref_section, $options, $hash_subst ) or return;
-        if( defined( $ref_section->{'reply'} ) ) {
+        if ( defined( $ref_section->{'reply'} ) ) {
             $install = $ref_section->{'reply'};
             eval "\$install = sprintf (\"echo '$install' |\")";
         }
         else {
             $install = '';
         }
-        if( !$options->{'simul'} ) {
-            if( 
+        if ( !$options->{'simul'} ) {
+            if (
                 !Install_pkg(
                     $options->{'pkg_type'}, $dest,
                     $ref_section->{'version'}
                 )
-            ) {
+                )
+            {
                 carp qq{ERROR: Unable to install $dest};
                 return;
             }
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Update/MKDIR.pm
--- a/lib/PFTools/Update/MKDIR.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Update/MKDIR.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -54,7 +54,7 @@
     my $cmp = 0;
 
     $hash_subst->{'SECTIONNAME'} = $dest;
-    unless( -d $dest ) {
+    unless ( -d $dest ) {
         $cmp = 1;
         if ( $options->{'verbose'} || $options->{'simul'} ) {
             Log("(action needed)");
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Update/PURGEPKG.pm
--- a/lib/PFTools/Update/PURGEPKG.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Update/PURGEPKG.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -38,6 +38,7 @@
 our @EXPORT_OK = qw();
 
 sub Action_depends {
+
     # Useless funciton but need to define
     return 1;
 }
@@ -45,9 +46,9 @@
 sub Action_exec {
     my ( $ref_section, $dest, $options, $hash_subst, $global_config ) = @_;
 
-    $options->{'pkg_type'} = 'deb' unless( $options->{'pkg_type'} );
+    $options->{'pkg_type'} = 'deb' unless ( $options->{'pkg_type'} );
     my $name_filter = $ref_section->{'name_filter'};
-    if( $name_filter ) {
+    if ($name_filter) {
         $hash_subst->{'SECTIONNAME'} = $dest;
         my $newdest = deferredlogpipe(
             Subst_vars( $name_filter, $hash_subst )
@@ -56,7 +57,7 @@
             carp qq{ERROR: Unable to apply name_filter $name_filter};
             return;
         }
-        unless( $newdest ) {
+        unless ($newdest) {
             carp qq{ERROR: Empty result for name_filter $name_filter};
             return;
         }
@@ -64,7 +65,7 @@
     }
 
     my $status = Get_pkg_status( $options->{'pkg_type'}, $dest );
-    unless( $status ) {
+    unless ($status) {
         carp qq{ERROR: Unable to retrieve status for $dest};
         return;
     }
@@ -75,9 +76,10 @@
         }
         Do_on_config( $ref_section, $options, $hash_subst ) or return;
         Do_before_change( $ref_section, $options, $hash_subst ) or return;
-        if(    ! $options->{'simul'}
-            && ! Purge_pkg( $options->{'pkg_type'}, $dest )
-        ) {
+        if (!$options->{'simul'}
+            && !Purge_pkg( $options->{'pkg_type'}, $dest )
+            )
+        {
             carp qq{ERROR: During purge for $dest};
             return;
         }
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Update/REMOVEDIR.pm
--- a/lib/PFTools/Update/REMOVEDIR.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Update/REMOVEDIR.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -44,7 +44,7 @@
     my ( $ref_section, $dest, $options, $hash_subst, $global_config ) = @_;
 
     # Is $options->{'simul'} necessary ?
-    if ( ! -d $dest && !$options->{'simul'} ) {
+    if ( !-d $dest && !$options->{'simul'} ) {
         carp qq{ERROR: $dest MUST BE a directory};
         return;
     }
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Update/REMOVEFILE.pm
--- a/lib/PFTools/Update/REMOVEFILE.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Update/REMOVEFILE.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -44,7 +44,7 @@
     my ( $ref_section, $dest, $options, $hash_subst, $global_config ) = @_;
 
     # Is $options->{'simul'} necessary ?
-    if( ! -f $dest && ! $options->{'simul'} ) {
+    if ( !-f $dest && !$options->{'simul'} ) {
         carp qq{ERROR: $dest MUST BE a file};
         return;
     }
@@ -53,7 +53,7 @@
     }
     Do_on_config( $ref_section, $options, $hash_subst ) or return;
     Do_before_change( $ref_section, $options, $hash_subst ) or return;
-    if ( ! $options->{'simul'} ) {
+    if ( !$options->{'simul'} ) {
         Do_moveold( $dest, $options );
     }
     Do_after_change( $ref_section, $options, $hash_subst ) or return;
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/Utils.pm
--- a/lib/PFTools/Utils.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/Utils.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -1,7 +1,4 @@
 package PFTools::Utils;
-
-# FIXME use check_* as much as possible
-# FIXME tests and documentation for all functions (at least the public ones)
 
 #
 #  Copyright (C) 2010 Christophe Caillet <quadchris at free.fr>
@@ -56,7 +53,6 @@
     Do_update_from_GLOBAL
     Change_kopt_for_hostname
 
-    Search_and_replace
 );
 
 our @EXPORT_OK = qw(
@@ -68,6 +64,7 @@
     make_resolv_conf_file
     make_sources_list_file
     make_zone_file
+    search_and_replace
 );
 
 ########################################################################
@@ -115,13 +112,13 @@
     return ( $pf_config, $global_struct );
 }
 
-=head2 make_preseed_file($arguments_ref)
+=head2 make_preseed_file($args_ref)
 
 Creates a preseed file for a given host. The preseed file is named
 "preseed_I<hostname>" and lies in the I<preseed_dir> directory as specified in
 the pf-tools configuration. This function returns the name (basename, not the
 complete path) of the written preseed file. It takes the following named
-arguments in %{$arguments_ref}:
+arguments in %{$args_ref}:
 
 =over
 
@@ -145,32 +142,26 @@
 =cut
 
 sub make_preseed_file {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
 
-    if ( ref $arguments_ref ne 'HASH' ) {
-        croak q{ERROR: Invalid $arguments_ref};
-    }
+    check_mandatory_true_args_type( $args_ref, q{},
+        qw( hostname site_name template_filename )
+    );
+
+    check_mandatory_args_type( $args_ref, q{HASH},
+        qw( global_config pf_config ) );
+
+    check_optional_args_type( $args_ref, q{HASH},
+        qw( host_ref) );
 
     my ($hostname, $site_name, $global_config,
         $pf_config, $template_filename, $host_ref
         )
-        = @{$arguments_ref}{
+        = @{$args_ref}{
         qw( hostname site_name global_config
             pf_config template_filename host_ref )
         };
 
-    $template_filename ||= $arguments_ref->{'preseed_template_filename'};
-
-    if ( not $hostname ) {
-        croak q{ERROR: Invalid empty $hostname};
-    }
-    if ( ref $hostname ) {
-        croak q{ERROR: Invalid non-scalar $hostname};
-    }
-
-    if ( ref $pf_config ne 'HASH' ) {
-        croak q{ERROR: Invalid non-hashref $pf_config};
-    }
     if ( not $pf_config->{'path'}->{'preseed_dir'} ) {
         croak q{ERROR: Invalid hashref $pf_config: no ->path->preseed_dir};
     }
@@ -191,7 +182,7 @@
 
     __make_file(
         {
-            %{$arguments_ref},
+            %{$args_ref},
             file_type         => q{preseed},
             filename          => $filename,
             template_filename => $template_filename,
@@ -202,7 +193,7 @@
     return $basename;
 }
 
-=head2 make_boot_and_preseed_files($arguments_ref)
+=head2 make_pxe_boot_and_preseed_files($args_ref)
 
 Creates a preseed file and a pxe boot file for a given host. The preseed
 file's name and MD5 hash are needed for the PXE boot file. The preseed file is
@@ -210,7 +201,7 @@
 here too.
 
 make_boot_and_preseed_files() returns a true value on success. It takes the
-following named arguments in %{$arguments_ref}:
+following named arguments in %{$args_ref}:
 
 =over
 
@@ -235,14 +226,23 @@
 =cut
 
 sub make_pxe_boot_and_preseed_files {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
 
-    if ( ref $arguments_ref ne 'HASH' ) {
-        croak q{ERROR: Invalid $arguments_ref};
-    }
+    check_mandatory_true_args_type( $args_ref, q{},
+        qw( hostname site_name preseed_template_filename pxe_template_filename )
+    );
 
-    my ( $hostname, $site_name, $global_config, $pf_config )
-        = @{$arguments_ref}{qw( hostname site_name global_config pf_config)};
+    check_mandatory_args_type( $args_ref, q{HASH},
+        qw( global_config pf_config ) );
+
+    my ($hostname,              $site_name,     $preseed_template_filename,
+        $pxe_template_filename, $global_config, $pf_config
+        )
+        = @{$args_ref}{
+        qw( hostname              site_name      preseed_template_filename
+            pxe_template_filename global_config  pf_config
+            )
+        };
 
     $site_name ||= get_uniq_site_from_hostname( $hostname, $global_config, $pf_config );
 
@@ -250,8 +250,9 @@
 
     my $preseed_filename = make_preseed_file(
         {
-            %{$arguments_ref},
-            host_ref         => $host_ref,
+            %{$args_ref},
+            template_filename => $preseed_template_filename,
+            host_ref          => $host_ref,
         }
     );
 
@@ -263,21 +264,22 @@
 
     __make_file(
         {
-            %{$arguments_ref},
-            file_type        => q{pxe_boot},
-            filename         => $pxe_boot_file,
-            site_name        => $site_name,
-            preseed_filename => $preseed_filename,
+            %{$args_ref},
+            file_type         => q{pxe_boot},
+            filename          => $pxe_boot_file,
+            site_name         => $site_name,
+            template_filename => $pxe_template_filename,
+            preseed_filename  => $preseed_filename,
         }
     );
 
     return 1;
 }
 
-=head2 make_zone_file($arguments_ref)
+=head2 make_zone_file($args_ref)
 
 This function creates a zone file. It takes the
-following named arguments in %{$arguments_ref}:
+following named arguments in %{$args_ref}:
 
 =over
 
@@ -292,13 +294,13 @@
 =cut
 
 sub make_zone_file {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
 
-    unless ( ref $arguments_ref eq 'HASH' ) {
-        croak q{ERROR: Invalid $arguments_ref};
+    unless ( ref $args_ref eq 'HASH' ) {
+        croak q{ERROR: Invalid non-hash reference args_ref};
     }
 
-    __make_file( { %{$arguments_ref}, file_type => q{zone} } );
+    __make_file( { %{$args_ref}, file_type => q{zone} } );
 
     return 1;
 }
@@ -312,137 +314,125 @@
 =cut
 
 sub make_resolv_conf_file {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
 
-    unless ( ref $arguments_ref eq 'HASH' ) {
-        croak q{ERROR: Invalid $arguments_ref};
+    unless ( ref $args_ref eq 'HASH' ) {
+        croak q{ERROR: Invalid non-hash reference args_ref};
     }
 
-    __make_file( { %{$arguments_ref}, file_type => q{resolv.conf} } );
+    __make_file( { %{$args_ref}, file_type => q{resolv.conf} } );
 
     return 1;
 }
 
-sub Resolv {
-    my ($type_resolve, $ip_type, $hostname, $global_config, $site_name,
-        $hosttype
+=head2 search_and_replace($args_ref)
+
+Reads a file, replaces some special keywords in its content and writes the
+result in (possibly another) file (this is the function behind the scene for
+the filter_* programs). It takes the following named arguments:
+
+=over
+
+=item I<hostname> the hostname
+
+=item I<site_name> the site name
+
+=item I<input_filename> the file to read from ('-' for STDIN)
+
+=item I<output_filename> the file to write to ('-' for STDOUT)
+
+=item I<filter_type> the type of filter wanted. The possible values are:
+
+=over
+
+=item I<distrib>: replace %DISTRIB% and %DISTSRC% (see the
+__search_and_replace_distrib() documentation for details)
+
+=item I<iface>: resolve network names to interface names (see the
+__search_and_replace_iface() documentation for details)
+
+=item I<ip>: resolve host names to IP addresses (see the
+__search_and_replace_ip() documentation for details)
+
+=back
+
+=item I<resolution_type> (optional, for the I<ip> filter only)
+
+=item I<ip_type> (optional, for the I<ip> filter only)
+
+=item I<separator> (optional, for the I<ip> filter only)
+
+=item I<global_config> as usual
+
+=item I<pf_config> as usual
+
+=back
+
+=cut
+
+my %filter_function_for = (
+    q{distrib}  => \&__search_and_replace_distrib,
+    q{iface}    => \&__search_and_replace_iface,
+    q{ip}       => \&__search_and_replace_ip,
+);
+sub search_and_replace {
+    my ($args_ref) = @_;
+
+    check_mandatory_true_args_type(
+        $args_ref, q{},
+        qw( hostname site_name input_filename output_filename filter_type )
+    );
+
+    # Only check these in __search_and_replace_ip()?
+    check_optional_args_type(
+        $args_ref, q{},
+        qw( ip_type resolution_type separator )
+    );
+
+    check_mandatory_args_type(
+        $args_ref, q{HASH},
+        qw( global_config pf_config )
+    );
+
+    my ($hostname, $site_name, $input_filename, $output_filename,
+        $filter_type, $global_config, $pf_config
         )
-        = @_;
+        = @{$args_ref}{
+        qw( hostname    site_name     input_filename   output_filename
+            filter_type global_config pf_config )
+        };
 
-    if ( $ip_type ne q{ipv4} and $ip_type ne q{ipv6} ) {
-        croak qq{ERROR: Invalid ip_type $ip_type};
+    if ( not exists $filter_function_for{$filter_type} ) {
+        croak qq{ERROR: Unknown filter_type $filter_type};
     }
 
-    if ( $type_resolve ne q{cnf} and $type_resolve ne q{dns} ) {
-        croak qq{ERROR: Invalid type_resolve $type_resolve};
+    my $hosttype
+        = get_hosttype_from_hostname( $hostname, $global_config, $site_name );
+    my $subst_ref = Init_SUBST( $hostname, $hosttype, $pf_config );
+    my $host_ref = get_host_config( $hostname, $global_config, $site_name );
+    my $site_ref = get_site_config( $site_name, $global_config );
+
+    my $filter_args_ref = {
+        %{$args_ref},
+        host_ref  => $host_ref,
+        site_ref  => $site_ref,
+        subst_ref => $subst_ref,
+    };
+
+    my $src = __read_file_in_array( $input_filename, 1 );
+
+    my @lines = ();
+    foreach my $line ( @{$src} ) {
+        $filter_args_ref->{'line'} = $line;
+
+        # Note: Multiple lines are possible if $separator eq q{DUPLICATE}
+        push @lines, $filter_function_for{$filter_type}->($filter_args_ref);
     }
 
-    unless ($hostname) {
-        croak q{ERROR: $hostname is mandatory};
-    }
-
-    if ( $type_resolve eq q{dns} ) {
-        return resolve_hostname_from_dns($hostname);
-    }
-
-    # $type_resolve eq q{cnf}
-    $site_name ||= get_uniq_site_from_hostname( $hostname, $global_config );
-    my $zone
-        = get_zone_from_hostname( $hostname, $global_config, $site_name );
-    $hostname =~ s{ [.] $zone \z}{}xms;
-
-    # FIXME this regexp is also used in
-    # PFTools::Structqueries::resolve_hostname_from_global_config()
-    my ( $hostshort, $hostvlan ) = $hostname =~ m{
-        \A
-            (               # $hostshort
-                [^.]+
-            )
-            (?:
-                [.]
-                (           # $hostvlan
-                    [^.]+
-                )
-            )?
-        \z
-    }xms;
-
-    if (not defined $hosttype
-        and $hostshort
-        !~ m{\A (network|netmask|broadcast|gateway|prefix)}xms
-        )
-    {
-        $hosttype
-            = get_hosttype_from_hostname(
-            $hostshort, $global_config,
-            $site_name
-            );
-    }
-    elsif ( $hostshort eq q{prefix} ) {
-        my $vlan_def
-            = get_vlan_config( $hostvlan, $global_config, $site_name );
-        my $subnet_ref = get_subnet_from_vlan( $ip_type, $vlan_def );
-        my $prefix = $subnet_ref->masklen();
-
-        return [$prefix];
-    }
-
-    return resolve_hostname_from_global_config(
-        {
-            hostname      => $hostname,
-            ip_type       => $ip_type,
-            global_config => $global_config,
-            site_name     => $site_name,
-            zone_name     => $zone,
-            hosttype      => $hosttype,
-        }
-    );
+    return __write_array_to_file( $output_filename, \@lines, qq{\n} );
 }
 
-sub Search_and_replace {
-    my ($hostname,      $site_name,    $input_file,
-        $type_replace,  $pf_config,    $separator,
-        $global_config, $type_resolve, $ip_type
-    ) = @_;
-
-    if ( $type_resolve && $type_resolve eq 'cnf' && !defined $global_config )
-    {
-        carp q{ERROR: Unable to resolve from configuration};
-        return;
-    }
-    my $hosttype
-        = get_hosttype_from_hostname( $hostname, $global_config, $site_name );
-    my $subst = Init_SUBST( $hostname, $hosttype, $pf_config );
-    my $host_props = get_host_config( $hostname, $global_config, $site_name );
-
-    my $src = __read_file_in_array( $input_file, 0 );
-
-    my @result = ();
-    foreach my $line ( @{$src} ) {
-        if ( $type_replace eq 'resolver' ) {
-            $line
-                = __search_and_resolve_ip(
-                $hostname,  $ip_type,      $site_name, $line,
-                $separator, $type_resolve, $subst,     $global_config
-                );
-        }
-        elsif ( $type_replace eq 'iface' ) {
-            $line = __search_and_resolve_iface( $line, $host_props, $subst );
-        }
-        elsif ( $type_replace eq 'distrib' ) {
-            $line
-                =~ s{ %DISTSRC% }{$host_props->{'deployment'}->{'mode'}}xmsg;
-            $line
-                =~ s{ %DISTRIB% }{$host_props->{'deployment'}->{'distrib'}}xmsg;
-        }
-
-        push @result, $line;
-    }
-
-    return \@result;
-}
-
-=head2 fix_etc_hosts($arguments_ref)
+=head2 fix_etc_hosts($args_ref)
 
 Fixes the IP address listed in an /etc/hosts-like file for a given hostname.
 This is useful when debian-installer puts there a localnet address, to replace
@@ -471,33 +461,26 @@
 =cut
 
 sub fix_etc_hosts {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
 
-    unless ( ref $arguments_ref eq 'HASH' ) {
-        croak q{ERROR: Invalid $arguments_ref};
-    }
-
-    check_mandatory_args_type( $arguments_ref, q{},
-        qw( input_filename output_filename ) );
-
-    check_true_args( $arguments_ref,
+    check_mandatory_true_args_type( $args_ref, q{},
         qw( input_filename output_filename ) );
 
     __make_file(
         {
-            %{$arguments_ref},
+            %{$args_ref},
             file_type => q{etc_hosts},
-            filename  => $arguments_ref->{'output_filename'},
+            filename  => $args_ref->{'output_filename'},
         }
     );
 
     return 1;
 }
 
-=head2 make_sources_list_file($arguments_ref)
+=head2 make_sources_list_file($args_ref)
 
 This function creates the I<sources.list> file. It takes the following named
-arguments in I<%{$arguments_ref}: 
+arguments in I<%{$args_ref}: 
 
 =over
 
@@ -521,17 +504,20 @@
 =cut
 
 sub make_sources_list_file {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
 
-    unless ( ref $arguments_ref eq 'HASH' ) {
-        croak q{ERROR: Invalid $arguments_ref};
+    unless ( ref $args_ref eq 'HASH' ) {
+        croak q{ERROR: Invalid non-hash reference args_ref};
     }
 
-    __make_file( { %{$arguments_ref}, file_type => q{sources.list} } );
+    __make_file( { %{$args_ref}, file_type => q{sources.list} } );
 
     return 1;
 }
 
+# FIXME tests
+# FIXME doc
+# FIXME named arguments
 # FIXME convert to __make_file()
 sub Change_kopt_for_hostname {
     my ($hostname, $site_name, $grub_src, $dst, $grub_version, $global_config,
@@ -588,10 +574,10 @@
     return 1;
 }
 
-=head2 make_interfaces_file($arguments_ref)
+=head2 make_interfaces_file($args_ref)
 
 This function writes the I<interfaces> configuration file. It takes the
-following named arguments in %{$arguments_ref}:
+following named arguments in %{$args_ref}:
 
 =over
 
@@ -610,13 +596,13 @@
 =cut
 
 sub make_interfaces_file {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
 
-    unless ( ref $arguments_ref eq 'HASH' ) {
-        croak q{ERROR: Invalid $arguments_ref};
+    unless ( ref $args_ref eq 'HASH' ) {
+        croak q{ERROR: Invalid non-hash reference args_ref};
     }
 
-    __make_file( { %{$arguments_ref}, file_type => q{interfaces} } );
+    __make_file( { %{$args_ref}, file_type => q{interfaces} } );
 
     return 1;
 }
@@ -641,18 +627,19 @@
 =cut
 
 sub make_dhcpd_conf_file {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
 
-    unless ( ref $arguments_ref eq 'HASH' ) {
-        croak q{ERROR: Invalid $arguments_ref};
+    unless ( ref $args_ref eq 'HASH' ) {
+        croak q{ERROR: Invalid non-hash reference args_ref};
     }
 
-    __make_file( { %{$arguments_ref}, file_type => q{dhcpd.conf} } );
+    __make_file( { %{$args_ref}, file_type => q{dhcpd.conf} } );
 
     return 1;
 }
 
 # FIXME documentation
+# FIXME s/options/args_ref/ and use check_*()
 sub Do_update_from_GLOBAL {
     my ( $options, $global_config, $pf_config ) = @_;
 
@@ -672,11 +659,11 @@
 
     my $hosttype
         = get_hosttype_from_hostname( $hostname, $global_config, $site_name );
-    my $hash_subst = Init_SUBST( $hostname, $hosttype, $pf_config );
-    my $host_props = get_host_config( $hostname, $global_config, $site_name );
+    my $subst_ref = Init_SUBST( $hostname, $hosttype, $pf_config );
+    my $host_ref = get_host_config( $hostname, $global_config, $site_name );
 
-    $hash_subst->{'DISTRIB'} = get_distrib_from_host_ref($host_props);
-    $hash_subst->{'MODE'}    = get_mode_from_host_ref($host_props);
+    $subst_ref->{'DISTRIB'} = get_distrib_from_host_ref($host_ref);
+    $subst_ref->{'MODE'}    = get_mode_from_host_ref($host_ref);
     $options->{'pkg_type'}
         ||= get_pkgtype_from_hostname(
         $hostname, $global_config,
@@ -684,7 +671,7 @@
         );
 
     my $host_config = Get_config_for_hostname_on_site(
-        $hostname, $site_name, $hash_subst, $global_config, $pf_config
+        $hostname, $site_name, $subst_ref, $global_config, $pf_config
     );
     unless ($host_config) {
         croak
@@ -700,7 +687,7 @@
 
     $| = 1;
     my $errorcount = __do_updateloop(
-        $host_config, $options, $hash_subst, $global_config, \@sortedkeys
+        $host_config, $options, $subst_ref, $global_config, \@sortedkeys
     );
 
     print qq{$errorcount error(s) detected.\n};
@@ -713,9 +700,122 @@
 # Only "private" functions after this line
 #
 
-# FIXME documentation + named arguments
+=head2 __resolve_hostname($args_ref)
+
+Wrapper around resolve_hostname_from_dns($hostname) and
+resolve_hostname_from_global_config(). Returns a reference to an array
+containing the resolved IP addresses. Takes the following named arguments:
+
+=over
+
+=item I<hostname> the hostname
+
+=item I<resolution_type> either I<cnf> or I<dns>
+
+=item I<site_name> the site name (only needed if I<resolution_type> is I<cnf>,
+optional if the hostname is defined only on one site)
+
+=item I<hosttype> the host type (only needed if I<resolution_type> is I<cnf>,
+optional)
+
+=item I<ip_type> either I<ipv4> or I<ipv6> (only needed if I<resolution_type>
+is I<cnf>)
+
+=item I<global_config> as usual
+
+=back
+
+=cut
+
+sub __resolve_hostname {
+    my ($args_ref) = @_;
+
+    check_mandatory_true_args_type( $args_ref, q{},
+        qw( hostname )
+    );
+
+    check_optional_args_type( $args_ref, q{},
+        qw( resolution_type site_name hosttype ip_type )
+    );
+
+    check_mandatory_args_type( $args_ref, q{HASH},
+        qw( global_config ) );
+
+    my ($hostname, $resolution_type, $site_name,
+        $hosttype, $ip_type,         $global_config
+        ) = @{$args_ref}{
+        qw( hostname resolution_type site_name
+            hosttype ip_type         global_config )
+        };
+
+    if ( $ip_type and $ip_type ne q{ipv4} and $ip_type ne q{ipv6} ) {
+        croak qq{ERROR: Invalid ip_type $ip_type};
+    }
+
+    $resolution_type ||= q{cnf};
+    if ( $resolution_type ne q{cnf} and $resolution_type ne q{dns} ) {
+        croak qq{ERROR: Invalid resolution_type $resolution_type};
+    }
+
+    if ( $resolution_type eq q{dns} ) {
+        return resolve_hostname_from_dns($hostname);
+    }
+
+    # $resolution_type eq q{cnf}
+    $site_name ||= get_uniq_site_from_hostname( $hostname, $global_config );
+    my $zone
+        = get_zone_from_hostname( $hostname, $global_config, $site_name );
+    $hostname =~ s{ [.] $zone \z}{}xms;
+
+    # FIXME this regexp is also used in
+    # PFTools::Structqueries::resolve_hostname_from_global_config()
+    my ( $hostshort, $hostvlan ) = $hostname =~ m{
+        \A
+            (               # $hostshort
+                [^.]+
+            )
+            (?:
+                [.]
+                (           # $hostvlan
+                    [^.]+
+                )
+            )?
+        \z
+    }xms;
+
+    if (not defined $hosttype
+        and $hostshort !~ m{\A (network|netmask|broadcast|gateway|prefix) }xms # \z ?
+        )
+    {
+        $hosttype = get_hosttype_from_hostname( $hostshort, $global_config,
+            $site_name );
+    }
+
+    if ( $hostshort eq q{prefix} ) {
+        my $vlan_ref
+            = get_vlan_config( $hostvlan, $global_config, $site_name );
+        my $subnet_ref = get_subnet_from_vlan( $ip_type, $vlan_ref );
+        my $prefix = $subnet_ref->masklen();
+
+        return [$prefix];
+    }
+
+    return resolve_hostname_from_global_config(
+        {
+            hostname      => $hostname,
+            ip_type       => $ip_type,
+            global_config => $global_config,
+            site_name     => $site_name,
+            zone_name     => $zone,
+            hosttype      => $hosttype,
+        }
+    );
+}
+
+# FIXME documentation
+# FIXME named arguments
 sub __do_updateloop {
-    my ( $host_config, $options, $hash_subst, $global_config, $sortedkeys )
+    my ( $host_config, $options, $subst_ref, $global_config, $sortedkeys )
         = @_;
 
     my $errorcount = 0;
@@ -765,7 +865,7 @@
                         print qq{<$section>} . join q{ }, @depends;
                     }
                     $errorcount += __do_updateloop(
-                        $host_config, $options, $hash_subst,
+                        $host_config, $options, $subst_ref,
                         $global_config, \@depends
                     );
                 }
@@ -780,7 +880,7 @@
                     $host_config->{$section},
                     $section,
                     $options,
-                    $hash_subst,
+                    $subst_ref,
                     $global_config
                 )
                 )
@@ -795,14 +895,114 @@
     return $errorcount;
 }
 
-sub __search_and_resolve_ip {
-    my ($hostname, $ip_type, $site_name, $line, $separator, $type_resolve,
-        $hash_subst, $global_config
+=head2 __search_and_replace_distrib($args_ref)
+
+Replace %DISTRIB% and %DISTSRC%. Take the following named arguments:
+
+=over
+
+=item I<line> the string to parse
+
+=item I<host_ref> a reference to the host configuration hash
+
+=back
+
+Return value: the modified string.
+
+=cut
+
+sub __search_and_replace_distrib {
+    my ($args_ref) = @_;
+
+    check_mandatory_args_type( $args_ref, q{},
+        qw( line ) );
+
+    check_mandatory_args_type( $args_ref, q{HASH},
+        qw( host_ref ) );
+
+    my ($line, $host_ref) = @{$args_ref}{qw( line host_ref )};
+
+    return $line unless $line; # no warnings if undef
+
+    $line =~ s{ %DISTSRC% }{$host_ref->{'deployment'}->{'mode'}}xmsg;
+    $line =~ s{ %DISTRIB% }{$host_ref->{'deployment'}->{'distrib'}}xmsg;
+
+    return $line;
+}
+
+=head2 __search_and_replace_ip($args_ref)
+
+Replace hostname specs by IP addresses in a given string:
+
+  HOSTNAME.vlan-systeme.private => 10.1.167.1
+  cbv4-rdeploy01.vlan-systeme.private => 10.1.167.1
+
+FIXME more documentation and usage samples here
+
+Take the following named arguments:
+
+=over
+
+=item I<line> the string to parse
+
+=item I<hostname> the hostname
+
+=item I<site_name> the site_name
+
+=item I<ip_type> the IP type: ipv4 or ipv6
+
+=item I<resolution_type> (optional, see the __resolve_hostname() documentation)
+
+=item I<separator> (optional) the separator to use when something resolves to
+multiple IP addresses. If undefined, a space will be used. The special value
+I<DUPLICATE> produces a copy of the entire line for each address.
+
+=item I<host_ref> a reference to the host configuration hash
+
+=item I<site_ref> a reference to the site configuration hash
+
+=item I<subst_ref> a reference to the substitution hash
+
+=back
+
+Return value: the modified string.
+
+=cut
+
+sub __search_and_replace_ip {
+    my ($args_ref) = @_;
+
+    check_mandatory_args_type( $args_ref, q{},
+        qw( line ) );
+
+    check_mandatory_true_args_type( $args_ref, q{},
+        qw( hostname site_name ip_type ) );
+
+    check_optional_args_type( $args_ref, q{},
+        qw( separator resolution_type ) );
+
+    check_mandatory_args_type( $args_ref, q{HASH},
+        qw( host_ref site_ref subst_ref global_config ) );
+
+    my ($line, $hostname, $site_name, $ip_type, $separator, $resolution_type,
+        $host_ref, $site_ref, $subst_ref, $global_config
         )
-        = @_;
+        = @{$args_ref}{
+        qw( line hostname site_name ip_type separator resolution_type
+            host_ref site_ref subst_ref global_config )
+        };
 
-    my $zone = $global_config->{'SITE'}->{'BY_NAME'}->{$site_name}->{'zone'};
+    return $line unless $line; # no warnings if undef
+
+    # $separator //= q{ };
+    if ( not defined $separator ) {
+        $separator = q{ };
+    }
+
+    my $zone = $site_ref->{'zone'};
     my $pos  = length $line;
+
+    my @lines = ();
 
     while (
         substr( $line, 0, $pos )
@@ -846,26 +1046,27 @@
 
         my $match2 = $match;
         $match2 =~ s{ HOSTNAME }{$hostname}xmsg;
-        $match2 =~ s{ POPNAME }{$hash_subst->{'POPNAME'}}xmsg;
+        $match2 =~ s{ POPNAME }{$subst_ref->{'POPNAME'}}xmsg;
 
-        my $resolved
-            = Resolv(
-            $type_resolve, $ip_type, $match2, $global_config,
-            $site_name
-            );
-        if ( @{$resolved} ) {
+        my $resolved_ref = __resolve_hostname(
+            {
+                hostname        => $match2,
+                resolution_type => $resolution_type,
+                ip_type         => $ip_type,
+                site_name       => $site_name,
+                global_config   => $global_config,
+            }
+        );
+        if (@{$resolved_ref}) {
             if ( $separator eq q{DUPLICATE} ) {
-                my $templine = q{};
-                foreach my $res ( @{$resolved} ) {
+                foreach my $res (@{$resolved_ref}) {
                     my $templine2 = $line;
                     substr( $templine2, $lengthbefore, length $match, $res );
-                    $templine .= $templine2;
+                    push @lines, $templine2;
                 }
-
-                $line = $templine;
             }
             else {
-                my $replacement = join $separator, @{$resolved};
+                my $replacement = join $separator, @{$resolved_ref};
                 substr( $line, $lengthbefore, length $match, $replacement );
             }
         }
@@ -873,11 +1074,49 @@
         $pos = $lengthbefore;
     }
 
-    return $line;
+    if ( not @lines ) {
+        push @lines, $line;
+    }
+
+    return @lines;
 }
 
-sub __search_and_resolve_iface {
-    my ( $line, $host_props, $hash_subst ) = @_;
+=head2 __search_and_replace_iface($args_ref)
+
+Replace iface specs by iface names in a given string:
+
+  eth.vlan-systeme.private => eth0
+  eth.vlan-foo-8021q.private => eth2.42
+
+Take the following named arguments:
+
+=over
+
+=item I<line> the string to parse
+
+=item I<host_ref> a reference to the host configuration hash
+
+=item I<subst_ref> a reference to the substitution hash
+
+=back
+
+Return value: the modified string.
+
+=cut
+
+sub __search_and_replace_iface {
+    my ($args_ref) = @_;
+
+    check_mandatory_args_type( $args_ref, q{},
+        qw( line ) );
+
+    check_mandatory_args_type( $args_ref, q{HASH},
+        qw( host_ref subst_ref ) );
+
+    my ( $line, $host_ref, $subst_ref )
+        = @{$args_ref}{qw( line host_ref subst_ref )};
+
+    return $line unless $line; # no warnings if undef
 
     my $pos = length $line;
     while (
@@ -914,9 +1153,9 @@
         my $lengthbefore = defined $before ? length $before : 0;
 
         ( my $real_vlan = $vlan )
-            =~ s{ POPNAME }{$hash_subst->{'POPNAME'}}xms;
+            =~ s{ POPNAME }{$subst_ref->{'POPNAME'}}xms;
 
-        my $eth = get_iface_vlan_from_hostname( $real_vlan, $host_props );
+        my $eth = get_iface_vlan_from_hostname( $real_vlan, $host_ref );
         if ( defined $eth ) {
             my $neweth = $eth;
             if ( $type eq q{.} ) {
@@ -937,10 +1176,10 @@
     return $line;
 }
 
-=head2 __build_preseed($arguments_ref)
+=head2 __build_preseed($args_ref)
 
 Builds the preseed file content for a host.
-I<$arguments_ref> is a reference to a hash of named parameters:
+I<$args_ref> is a reference to a hash of named parameters:
 
 =over
 
@@ -948,57 +1187,25 @@
 
 =item I<host_ref> a reference to the host configuration hash
 
-=item I<preseed_template_filename> the template file name. This argument can
-be passed as I<template_filename> for simplicity.
+=item I<template_filename> the template file name.
 
 =item I<pf_script> FIXME ???
-
-=item I<pf_config> a reference to the pf-tools configuration hash
-
-=item I<global_config> a reference to the global configuration hash
 
 =back
 
 =cut
 
 sub __build_preseed {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
 
-    my ($hostname, $host_ref, $template_filename,
-        $pf_script
-        )
-        = @{$arguments_ref}{
-        qw( hostname host_ref template_filename
-            pf_script
-            )
-        };
+    check_mandatory_true_args_type( $args_ref, q{},
+        qw( hostname template_filename pf_script ) );
 
-    $template_filename ||= $arguments_ref->{'preseed_template_filename'};
+    check_mandatory_args_type( $args_ref, q{HASH},
+        qw( host_ref ) );
 
-    if ( not $hostname ) {
-        croak q{ERROR: Invalid empty hostname};
-    }
-    if ( ref $hostname ) {
-        croak q{ERROR: Invalid non-scalar hostname};
-    }
-
-    if ( ref $host_ref ne 'HASH' ) {
-        croak q{ERROR: Invalid non-hashref host_ref};
-    }
-
-    if ( not $template_filename ) {
-        croak q{ERROR: Invalid empty template_filename};
-    }
-    if ( ref $template_filename ) {
-        croak q{ERROR: Invalid non-scalar template_filename};
-    }
-
-    if ( not $pf_script ) {
-        croak q{ERROR: Invalid empty pf_script};
-    }
-    if ( ref $pf_script ) {
-        croak q{ERROR: Invalid non-scalar pf_script};
-    }
+    my ( $hostname, $template_filename, $pf_script, $host_ref )
+        = @{$args_ref}{qw( hostname template_filename pf_script host_ref )};
 
     my $kernel_pkg = __get_kpkg_from_kernel(
         $host_ref->{'boot'}->{'kernel'},
@@ -1017,10 +1224,10 @@
     return [$content];
 }
 
-=head2 __build_pxe_boot($arguments_ref)
+=head2 __build_pxe_boot($args_ref)
 
 Builds the PXE boot file content for a host and returns a reference to the
-array of lines. I<$arguments_ref> is a reference to a hash of named
+array of lines. I<$args_ref> is a reference to a hash of named
 parameters:
 
 =over
@@ -1031,8 +1238,7 @@
 
 =item I<preseed_filename> the preseed file name
 
-=item I<pxe_template_filename> the pxe template file name. This argument can
-be passed as I<template_filename> for simplicity.
+=item I<template_filename> the pxe template file name.
 
 =item I<global_config> a reference to the global configuration hash
 
@@ -1043,40 +1249,26 @@
 =cut
 
 sub __build_pxe_boot {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
 
-    my ($hostname, $site_name, $global_config,
-        $pf_config, $preseed_filename, $template_filename
+    check_mandatory_true_args_type( $args_ref, q{},
+        qw( hostname site_name preseed_filename ) );
+
+    check_optional_args_type( $args_ref, q{},
+        qw( template_filename ) );
+
+    check_mandatory_args_type( $args_ref, q{HASH},
+        qw( global_config pf_config ) );
+
+    my ($hostname, $site_name, $preseed_filename, $template_filename,
+        $global_config, $pf_config
         )
-        = @{$arguments_ref}{
+        = @{$args_ref}{
         qw(
-            hostname site_name global_config
-            pf_config preseed_filename template_filename
+            hostname site_name preseed_filename template_filename
+            global_config pf_config
             )
         };
-
-    $template_filename = $arguments_ref->{'pxe_template_filename'};
-
-    if ( not $hostname ) {
-        croak q{ERROR: Invalid empty $hostname};
-    }
-    if ( ref $hostname ) {
-        croak q{ERROR: Invalid non-scalar $hostname};
-    }
-
-    if ( not $site_name ) {
-        croak q{ERROR: Invalid empty $site_name};
-    }
-    if ( ref $site_name ) {
-        croak q{ERROR: Invalid non-scalar $site_name};
-    }
-
-    if ( not $global_config ) {
-        croak q{ERROR: Invalid empty $global_config};
-    }
-    if ( ref $global_config ne 'HASH' ) {
-        croak q{ERROR: Invalid non-hashref $global_config};
-    }
 
     # This is not a complete check but it will catch obvious errors,
     # like $global_config referencing a non-config hash
@@ -1084,28 +1276,10 @@
         croak q{ERROR: Invalid $global_config hashref: no 'ZONE' key found};
     }
 
-    if ( not $pf_config ) {
-        croak q{ERROR: Invalid empty $pf_config};
-    }
-    if ( ref $pf_config ne 'HASH' ) {
-        croak q{ERROR: Invalid non-hashref $pf_config};
-    }
-
     # This is not a complete check but it will catch obvious errors,
     # like $pf_config referencing a non-config hash
     if ( not exists $pf_config->{'vcs'} ) {
         croak q{ERROR: Invalid $pf_config hashref: no 'vcs' key found};
-    }
-
-    if ( not $preseed_filename ) {
-        croak q{ERROR: Invalid empty $preseed_filename};
-    }
-    if ( ref $preseed_filename ) {
-        croak q{ERROR: Invalid non-scalar $preseed_filename};
-    }
-
-    if ( ref $template_filename ) {
-        croak q{ERROR: Invalid non-scalar $template_filename};
     }
 
     my $host_ref = get_host_config( $hostname, $global_config, $site_name );
@@ -1160,12 +1334,7 @@
 sub __build_interfaces {
     my ($args_ref) = @_;
 
-    check_mandatory_args_type(
-        $args_ref, q{},
-        qw( hostname site_name )
-    );
-    check_true_args(
-        $args_ref,
+    check_mandatory_true_args_type( $args_ref, q{},
         qw( hostname site_name )
     );
 
@@ -1296,7 +1465,7 @@
             qq{\tbroadcast\t} . $ip->broadcast()->addr();
 
         # Routes
-        # FIXME add tests cases for non-default routes
+        # FIXME add test cases in t/* for non-default routes
         my $suffix = get_suffix_from_ip_type($ip_type);
         foreach my $route ( @{ $if_part->{ '@route' . $suffix } } ) {
             if ( $route =~ m{ \A (\S+) \s* (?: via (?: \S+ ) )? \z }xms ) {
@@ -1350,11 +1519,9 @@
 sub __build_resolv_conf {
     my ($args_ref) = @_;
 
-    check_mandatory_args_type(
-        $args_ref, q{},
+    check_mandatory_true_args_type( $args_ref, q{},
         qw( hostname site_name template_filename )
     );
-    check_true_args( $args_ref, qw( hostname site_name template_filename ) );
 
     check_mandatory_args_type( $args_ref, q{HASH}, qw( global_config ) );
 
@@ -1368,18 +1535,25 @@
         croak q{ERROR: Invalid $global_config hashref: no 'ZONE' key found};
     }
 
-    my $host_props = get_host_config( $hostname, $global_config, $site_name );
+    my $host_ref = get_host_config( $hostname, $global_config, $site_name );
     my $domain
         = get_zone_from_hostname( $hostname, $global_config, $site_name );
 
-    my @dns = split qr{ \s* [,] \s* }xms, $host_props->{'dns'}->{'resolver'};
+    my @dns = split qr{ \s* [,] \s* }xms, $host_ref->{'dns'}->{'resolver'};
 
     my @nameservers = ();
     foreach my $ip_type (qw( ipv4 ipv6 )) {
         foreach my $dns (@dns) {
-            my $resolved = Resolv( q{cnf}, $ip_type, $dns, $global_config,
-                $site_name );
-            push @nameservers, @{$resolved};
+            my $resolved_ref = __resolve_hostname(
+                {
+                    hostname        => $dns,
+                    resolution_type => q{cnf},
+                    ip_type         => $ip_type,
+                    site_name       => $site_name,
+                    global_config   => $global_config,
+                }
+            );
+            push @nameservers, @{$resolved_ref};
         }
     }
 
@@ -1416,12 +1590,7 @@
 sub __build_zone {
     my ($args_ref) = @_;
 
-    check_mandatory_args_type(
-        $args_ref, q{},
-        qw( site_name zone_name template_filename )
-    );
-    check_true_args(
-        $args_ref,
+    check_mandatory_true_args_type( $args_ref, q{},
         qw( site_name zone_name template_filename )
     );
 
@@ -1538,11 +1707,11 @@
     return $lines_ref;
 }
 
-=head2 __build_sources_list($arguments_ref)
+=head2 __build_sources_list($args_ref)
 
 This function creates the I<sources.list> file content and returns a reference
 to the array of lines. It takes the following named arguments in
-I<%{$arguments_ref}: 
+I<%{$args_ref}: 
 
 =over
 
@@ -1565,38 +1734,42 @@
 =cut
 
 sub __build_sources_list {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
+
+    check_mandatory_true_args_type( $args_ref, q{},
+        qw( hostname site_name template )
+    );
+
+    check_mandatory_args_type( $args_ref, q{HASH},
+        qw( global_config pf_config)
+    );
+
+    check_mandatory_args_type( $args_ref, q{ARRAY},
+        qw( sections_ref )
+    );
+
+    check_optional_args_type( $args_ref, q{},
+        qw( backports )
+    );
 
     my ($hostname, $site_name, $sections_ref, $template, $backports,
         $global_config, $pf_config
         )
-        = @{$arguments_ref}{
+        = @{$args_ref}{
         qw(
             hostname site_name sections_ref template backports
             global_config pf_config
             )
         };
 
-    # NOTE: hostname and global_config are properly checked in
-    # get_host_config(), so there's no need to check them here.
-
-    if ( not $template ) {
-        croak q{ERROR: Invalid empty $template};
-    }
-    if ( ref $template ) {
-        croak q{ERROR: Invalid non-scalar $template};
+    # This is not a complete check but it will catch obvious errors,
+    # like $global_config referencing a non-config hash
+    if ( not exists $global_config->{'ZONE'} ) {
+        croak q{ERROR: Invalid $global_config hashref: no 'ZONE' key found};
     }
 
-    # FIXME is site_name optional or not?
-
-    if ( not $sections_ref ) {
-        croak q{ERROR: Invalid empty $sections_ref};
-    }
-    if ( ref $sections_ref ne 'ARRAY' ) {
-        croak q{ERROR: Invalid non-array-ref $sections_ref};
-    }
     if ( not @{$sections_ref} ) {
-        croak q{ERROR: Invalid empty-array-ref $sections_ref};
+        croak q{ERROR: Invalid empty-array reference sections_ref};
     }
 
     my @sections = ();
@@ -1606,26 +1779,11 @@
         $section =~ s{ \A \s* (\S*) \s* \z }{$1}xms;
         if ( not $section ) {
             croak
-                q{ERROR: Invalid empty or blank section in array-ref $sections_ref};
+                q{ERROR: Invalid empty or blank section in sections_ref};
         }
         push @sections, $section;
     }
     my $sections = join q{ }, @sections;
-
-    # $backports is optional
-    if ( ref $backports ) {
-        croak q{ERROR: Invalid non-scalar $backports};
-    }
-
-    if ( ref $global_config ne 'HASH' ) {
-        croak q{ERROR: Invalid non-hashref $global_config};
-    }
-
-    # This is not a complete check but it will catch obvious errors,
-    # like $global_config referencing a non-config hash
-    if ( not exists $global_config->{'ZONE'} ) {
-        croak q{ERROR: Invalid $global_config hashref: no 'ZONE' key found};
-    }
 
     my $host_ref = get_host_config( $hostname, $global_config, $site_name );
     my $deployment_mode = $host_ref->{'deployment'}->{'mode'};
@@ -1647,7 +1805,7 @@
     return [$content];
 }
 
-=head2 __fix_etc_hosts($arguments_ref)
+=head2 __fix_etc_hosts($args_ref)
 
 Reads an /etc/hosts-type file, fixes the IP address for a given hostname,
 returns a reference to the list of lines. THe named arguments are:
@@ -1658,7 +1816,7 @@
 
 =item I<site_name> (optional) the site name
 
-=item I<input_file> the file to read from (usually I</etc/hosts>)
+=item I<input_filename> the file to read from (usually I</etc/hosts>)
 
 =item I<ip_type> I<ipv4> or I<ipv6> (but only I<ipv4> is currently supported)
 
@@ -1673,28 +1831,28 @@
 # FIXME: what is the problem exactly, is this really necessary?
 
 sub __fix_etc_hosts {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
+
+    check_mandatory_true_args_type( $args_ref, q{},
+        qw( hostname input_filename ip_type )
+    );
+
+    check_optional_args_type( $args_ref, q{},
+        qw( site_name )
+    );
+
+    # FIXME pf_config is not actually used
+    check_mandatory_args_type( $args_ref, q{HASH},
+        qw( global_config pf_config )
+    );
 
     my ($hostname, $site_name,     $input_filename,
         $ip_type,  $global_config, $pf_config
         )
-        = @{$arguments_ref}
+        = @{$args_ref}
         {qw( hostname site_name input_filename
             ip_type global_config pf_config )};
 
-    # $hostname, $site_name and $global_config will be checked by
-    # get_host_config()
-
-    # input_filename will be checked by __read_file_in_array()
-
-    # FIXME pf_config is not used for the moment
-
-    if ( not $ip_type ) {
-        croak q{ERROR: Invalid empty ip_type};
-    }
-    if ( ref $ip_type ) {
-        croak q{ERROR: Invalid non-scalar ip_type};
-    }
     if ( $ip_type ne q{ipv4} ) {
         croak qq{ERROR: __fix_etc_hosts: ip_type '$ip_type' not implemented};
     }
@@ -1738,13 +1896,13 @@
 sub __build_dhcpd_conf {
     my ($args_ref) = @_;
 
-    check_mandatory_args_type(
+    check_mandatory_true_args_type(
         $args_ref, q{},
         qw( site_name template_filename )
     );
     check_mandatory_args_type( $args_ref, q{HASH}, qw( global_config ) );
 
-    my $site_ref = get_site_config(
+    my $site_ref = get_site_dhcp_config(
         $args_ref->{'site_name'},
         $args_ref->{'global_config'},
     );
@@ -1940,7 +2098,12 @@
         croak q{ERROR: Invalid non-scalar filename};
     }
 
-    my $fh = IO::File->new( $filename, q{<} );
+    # Correctly handle q{-} for STDIN
+    my @open_args = ($filename);
+    if ( $filename ne q{-} ) {
+        push @open_args, q{<};
+    }
+    my $fh = IO::File->new(@open_args);
     unless ($fh) {
         croak qq{ERROR: open $filename: $OS_ERROR};
     }
@@ -2006,10 +2169,57 @@
     }
 }
 
-=head2 __make_file($arguments_ref)
+=head2 __write_array_to_file( $filename, $lines_ref, $line_separator )
+
+Open a temporary output file (or STDOUT if $filename is '-'), call
+__write_array_to_filehandle(), and move to the real destination if the content
+has changed.
+
+=cut
+
+sub __write_array_to_file {
+    my ( $filename, $lines_ref, $line_separator ) = @_;
+
+    if ( not $filename ) {
+        croak q{ERROR: Invalid false filename};
+    }
+
+    if ( ref $lines_ref ne 'ARRAY' ) {
+        croak q{ERROR: Invalid non-scalar line_separator};
+    }
+
+    if ( ref $line_separator ) {
+        croak q{ERROR: Invalid non-scalar line_separator};
+    }
+
+    # Either STDOUT or a tempfile...
+    my ( $out_fh, $out_fn );
+    if ( $filename eq q{-} ) {
+        $out_fh = IO::File->new();
+        unless ( $out_fh->fdopen( fileno(STDOUT), q{>} ) ) {
+            croak qq{ERROR: fdopen STDOUT: $OS_ERROR};
+        }
+        $out_fn = $filename;
+    }
+    else {
+        $out_fh = File::Temp->new( unlink => 0 );    # will croak() on error
+        $out_fn = $out_fh->filename();
+    }
+
+    __write_array_to_filehandle( $out_fh, $out_fn, $lines_ref, $line_separator );
+
+    if ( $filename ne q{-} ) {
+        make_path( dirname($filename) );
+        __move_if_different( $out_fn, $filename );
+    }
+
+    return 1;
+}
+
+=head2 __make_file($args_ref)
 
 This function creates a specific file. It takes the
-following named arguments in %{$arguments_ref}:
+following named arguments in %{$args_ref}:
 
 =over
 
@@ -2041,53 +2251,25 @@
 );
 
 sub __make_file {
-    my ($arguments_ref) = @_;
+    my ($args_ref) = @_;
 
     # NOTE: all other parameters are properly checked by
     # __build_FOO() => no need to check them here
 
+    check_mandatory_true_args_type( $args_ref, q{},
+        qw( file_type filename )
+    );
+
     my ( $file_type, $filename )
-        = @{$arguments_ref}{qw( file_type filename )};
+        = @{$args_ref}{qw( file_type filename )};
 
-    if ( not $file_type ) {
-        croak q{ERROR: Invalid empty $file_type};
-    }
-    if ( ref $file_type ) {
-        croak q{ERROR: Invalid non-scalar $file_type};
-    }
     if ( not exists $build_content_for{$file_type} ) {
-        croak qq{ERROR: Unknown file_type: $file_type};
+        croak qq{ERROR: Unknown file_type $file_type};
     }
 
-    if ( not $filename ) {
-        croak q{ERROR: Invalid empty $filename};
-    }
-    if ( ref $filename ) {
-        croak q{ERROR: Invalid non-scalar $filename};
-    }
+    my $lines_ref = $build_content_for{$file_type}->($args_ref);
 
-    my $lines_ref = $build_content_for{$file_type}->($arguments_ref);
-
-    # Either STDOUT or a tempfile...
-    my ( $out_fh, $out_fn );
-    if ( $filename eq q{-} ) {
-        $out_fh = IO::File->new();
-        unless ( $out_fh->fdopen( fileno(STDOUT), q{>} ) ) {
-            croak qq{ERROR: fdopen STDOUT: $OS_ERROR};
-        }
-        $out_fn = $filename;
-    }
-    else {
-        $out_fh = File::Temp->new( unlink => 0 );    # will croak() on error
-        $out_fn = $out_fh->filename();
-    }
-
-    __write_array_to_filehandle( $out_fh, $out_fn, $lines_ref, qq{\n} );
-
-    if ( $filename ne q{-} ) {
-        make_path( dirname($filename) );
-        __move_if_different( $out_fn, $filename );
-    }
+    __write_array_to_file( $filename, $lines_ref, qq{\n} );
 
     return 1;
 }
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/VCS.pm
--- a/lib/PFTools/VCS.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/VCS.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -37,17 +37,17 @@
 sub VCS_checkout ($$$) {
     my ( $hostname, $pf_config, $options ) = @_;
 
-    unless( $pf_config ) {
+    unless ($pf_config) {
         carp q{ERROR: $pf_config is invalid};
         return;
     }
-    my $module_name = 'PFTools::VCS::'.uc($pf_config->{'vcs'}->{'type'});
+    my $module_name = 'PFTools::VCS::' . uc( $pf_config->{'vcs'}->{'type'} );
     my $module;
-    
+
     eval { $module = use_module($module_name); };
-    
+
     $module->import();
-    
+
     if ( !checkout( $hostname, $pf_config, $options ) ) {
         return 0
     }
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/VCS/CVS.pm
--- a/lib/PFTools/VCS/CVS.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/VCS/CVS.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -38,22 +38,23 @@
     my ( $hostname, $pf_config, $options ) = @_;
     my $cvs_cmd = $pf_config->{'vcs'}->{'command'};
 
-    if( ref $hostname ) {
+    if ( ref $hostname ) {
         carp q{ERROR: $hostname MUST BE a string};
         return;
     }
-    unless( $pf_config or $options ) {
+    unless ( $pf_config or $options ) {
         carp q{ERROR: invalid parameter};
         return;
     }
-    unless( ref $pf_config eq 'HASH' || ref $options eq 'HASH' ) {
+    unless ( ref $pf_config eq 'HASH' || ref $options eq 'HASH' ) {
         carp q{ERROR: non-ref $pf_config and/or $options};
         return;
     }
 
     if ( defined $options->{'branch'} && $options->{'branch'} ne '' ) {
         if ( $cvs_cmd ne '' ) {
-            carp qq{WARN: ingnoring $cvs_cmd with branch $options->{'branch'}};
+            carp
+                qq{WARN: ingnoring $cvs_cmd with branch $options->{'branch'}};
         }
     }
     elsif ( $pf_config->{'vcs'}->{'branch'} ) {
@@ -69,7 +70,7 @@
     $ENV{'CVS_RSH'} = $pf_config->{'vcs'}->{'rsh'}
         if ( $pf_config->{'vcs'}->{'method'} eq 'rsh' );
 
-    if( $cvs_cmd eq "" ) {
+    if ( $cvs_cmd eq "" ) {
         if ( $hostname =~ /^$pf_config->{'regex'}->{'deploy_hosts'}/ ) {
             $cvs_cmd = "/usr/bin/cvs -R -d '";
         }
@@ -99,11 +100,11 @@
         or croak qq{ERROR: Unable to create $co_dir : $OS_ERROR};
 
     my $exec = Proc::Reliable->new();
-    my( $stdout, $stderr, $status, $msg ) = $exec->run(
+    my ( $stdout, $stderr, $status, $msg ) = $exec->run(
         "cd '" . $co_dir . "';" . $cvs_cmd
     );
-    print $stdout if( $options->{'verbose'} );
-    if( $status ) {
+    print $stdout if ( $options->{'verbose'} );
+    if ($status) {
         carp qq{ERROR: unable to checkout : $stderr};
         return;
     }
diff -r d1af4c8d4e57 -r badcfa737c2e lib/PFTools/VCS/SVN.pm
--- a/lib/PFTools/VCS/SVN.pm	Wed Dec 22 16:45:36 2010 +0100
+++ b/lib/PFTools/VCS/SVN.pm	Sun Jan 02 13:57:47 2011 +0100
@@ -34,7 +34,7 @@
 
 sub checkout {
     my ( $hostname, $pf_config, $options ) = @_;
-    
+
     unless ($hostname) {
         croak q{ERROR: Invalid undefined or empty $hostname};
     }
@@ -53,7 +53,7 @@
     if ( ref $options ne 'HASH' ) {
         croak q{ERROR: Invalid non-hashref $options};
     }
-    
+
     my $svn_cmd = $pf_config->{'vcs'}->{'command'};
 
     if ( defined $options->{'branch'} && $options->{'branch'} ne '' ) {
@@ -91,13 +91,13 @@
     }
     make_path $co_dir
         or croak qq{ERROR: Unable to create $co_dir : $OS_ERROR};
-    
+
     my $exec = Proc::Reliable->new();
-    my( $stdout, $stderr, $status, $msg ) = $exec->run(
+    my ( $stdout, $stderr, $status, $msg ) = $exec->run(
         "cd '" . $co_dir . "';" . $svn_cmd
     );
-    print $stdout if( $options->{'verbose'} );
-    if( $status ) {
+    print $stdout if ( $options->{'verbose'} );
+    if ($status) {
         carp qq{ERROR: unable to checkout : $stderr};
         return;
     }
diff -r d1af4c8d4e57 -r badcfa737c2e sbin/fix_hosts
--- a/sbin/fix_hosts	Wed Dec 22 16:45:36 2010 +0100
+++ b/sbin/fix_hosts	Sun Jan 02 13:57:47 2011 +0100
@@ -46,15 +46,15 @@
 
 # Options default values
 my $options = {
-    'help'      => 0,
-    'host'      => hostname,
-    'type'      => 'ipv4',
-    'input'     => '/etc/hosts',
-    'output'    => '/etc/hosts',
+    'help'   => 0,
+    'host'   => hostname,
+    'type'   => 'ipv4',
+    'input'  => '/etc/hosts',
+    'output' => '/etc/hosts',
 };
 
-my $PF_CONFIG         = {};
-my $GLOBAL_STRUCT     = {};
+my $PF_CONFIG     = {};
+my $GLOBAL_STRUCT = {};
 
 my $program = basename $PROGRAM_NAME;
 
@@ -83,7 +83,7 @@
 GetOptions( $options, @options_specs )
     or die "Didn't grok options (see --help).\n";
 
-if ($options->{'help'}) {
+if ( $options->{'help'} ) {
     Do_help();
     exit 0;
 }
@@ -94,11 +94,11 @@
     $options->{'store'}
 );
 
-if ( !$PF_CONFIG->{'features'}->{$options->{'type'}} ) {
+if ( !$PF_CONFIG->{'features'}->{ $options->{'type'} } ) {
     die "Aborting because $options->{'type'} is not activated in PF-Tools";
 }
 
-unless( $options->{'site'} ) {
+unless ( $options->{'site'} ) {
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
         || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
 }
diff -r d1af4c8d4e57 -r badcfa737c2e sbin/mk_grubopt
--- a/sbin/mk_grubopt	Wed Dec 22 16:45:36 2010 +0100
+++ b/sbin/mk_grubopt	Sun Jan 02 13:57:47 2011 +0100
@@ -43,16 +43,16 @@
 );
 
 my $options = {
-    'config'    => '',
-    'host'      => hostname,
-    'help'      => 0,
-    'grub'      => 2,
-    'src'       => '',
-    'output'    => '-',
+    'config' => '',
+    'host'   => hostname,
+    'help'   => 0,
+    'grub'   => 2,
+    'src'    => '',
+    'output' => '-',
 };
 
-my $PF_CONFIG         = {};
-my $GLOBAL_STRUCT     = {};
+my $PF_CONFIG     = {};
+my $GLOBAL_STRUCT = {};
 
 my $program = basename $PROGRAM_NAME;
 
@@ -80,7 +80,7 @@
 GetOptions( $options, @options_specs )
     or die "Didn't grok options (see --help).\n";
 
-if ($options->{'help'}) {
+if ( $options->{'help'} ) {
     Do_help();
     exit 0;
 }
@@ -91,12 +91,13 @@
     $options->{'store'}
 );
 
-unless( $options->{'site'} ) {
+unless ( $options->{'site'} ) {
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
         || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
 }
 
-unless( $GLOBAL_STRUCT->{'DHCP'}->{'BY_SITE'}->{$options->{'site'}} ) {
+# FIXME get_site_dhcp_config()
+unless ( $GLOBAL_STRUCT->{'DHCP'}->{'BY_SITE'}->{ $options->{'site'} } ) {
     die "Unknown DHCP site $options->{'site'}";
 }
 
@@ -110,7 +111,8 @@
         $GLOBAL_STRUCT,
         $PF_CONFIG
     )
-) {
+    )
+{
     die "Unable to change kernel options(s) into file $options->{'src'}";
 }
 
diff -r d1af4c8d4e57 -r badcfa737c2e sbin/mk_interfaces
--- a/sbin/mk_interfaces	Wed Dec 22 16:45:36 2010 +0100
+++ b/sbin/mk_interfaces	Sun Jan 02 13:57:47 2011 +0100
@@ -46,13 +46,13 @@
 
 # Default options values
 my $options = {
-    'help'      => 0,
-    'host'      => hostname,
-    'output'    => '-',
+    'help'   => 0,
+    'host'   => hostname,
+    'output' => '-',
 };
 
-my $PF_CONFIG         = {};
-my $GLOBAL_STRUCT     = {};
+my $PF_CONFIG     = {};
+my $GLOBAL_STRUCT = {};
 
 my $program = basename $PROGRAM_NAME;
 
@@ -78,7 +78,7 @@
 GetOptions( $options, @options_specs )
     or die "Didn't grok options (see --help).\n";
 
-if ($options->{'help'}) {
+if ( $options->{'help'} ) {
     Do_help();
     exit 0;
 }
@@ -89,7 +89,7 @@
     $options->{'store'}
 );
 
-unless( $options->{'site'} ) {
+unless ( $options->{'site'} ) {
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
         || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
 }
diff -r d1af4c8d4e57 -r badcfa737c2e sbin/mk_pxelinuxcfg
--- a/sbin/mk_pxelinuxcfg	Wed Dec 22 16:45:36 2010 +0100
+++ b/sbin/mk_pxelinuxcfg	Sun Jan 02 13:57:47 2011 +0100
@@ -42,13 +42,13 @@
 );
 
 my $options = {
-    'help'      => 0,
-    'script'    => 'pf-tools-config.sh',
+    'help'   => 0,
+    'script' => 'pf-tools-config.sh',
 };
 
-my $PF_CONFIG         = {};
-my $GLOBAL_STRUCT     = {};
-my $DEFAULT_PRESEED   = '';
+my $PF_CONFIG       = {};
+my $GLOBAL_STRUCT   = {};
+my $DEFAULT_PRESEED = '';
 
 my $program = basename $PROGRAM_NAME;
 
@@ -75,7 +75,7 @@
 GetOptions( $options, @options_specs )
     or die "Didn't grok options (see --help).\n";
 
-if ($options->{'help'}) {
+if ( $options->{'help'} ) {
     Do_help();
     exit 0;
 }
@@ -93,17 +93,14 @@
     my $mode = '2750';
     chmod( oct($mode), $PF_CONFIG->{'path'}->{'preseed_dir'} );
 }
+
 #$DEFAULT_PRESEED
 #    = $PF_CONFIG->{'path'}->{'preseed_dir'} . "/default_preseed.txt";
-unless( $options->{'site'} ) {
-    unless( $PF_CONFIG->{'location'}->{'site'} ) {
+unless ( $options->{'site'} ) {
+    unless ( $PF_CONFIG->{'location'}->{'site'} ) {
         die "A site MUST BE defined for building DNS zone forward";
     }
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'};
-}
-
-unless( $GLOBAL_STRUCT->{'DHCP'}->{'BY_SITE'}->{$options->{'site'}} ) {
-    die "Unknown site $options->{'site'}";
 }
 
 =for FIXME
@@ -121,18 +118,18 @@
 
 =cut
 
-my $site_part = $GLOBAL_STRUCT->{'SITE'}->{'BY_NAME'}->{$options->{'site'}};
+my $site_part = get_site_config( $options->{'site'}, $global_config );
 my $host_part = $site_part->{'HOST'}->{'BY_NAME'};
 foreach my $hostclass ( @{ $site_part->{'HOST'}->{'__hostclass_pxe'} } ) {
     foreach my $host ( keys %{ $host_part->{$hostclass} } ) {
         next if ( ref $host_part->{$hostclass}->{$host} ne 'HASH' );
 
         my $args_ref = {
-            hostname              => $host,
-            site_name             => $options->{'site'},
-            global_config         => $GLOBAL_STRUCT,
-            pf_config             => $PF_CONFIG,
-            pf_script             => $options->{'script'},
+            hostname      => $host,
+            site_name     => $options->{'site'},
+            global_config => $GLOBAL_STRUCT,
+            pf_config     => $PF_CONFIG,
+            pf_script     => $options->{'script'},
         };
         make_pxe_boot_and_preseed_files($args_ref);
     }
diff -r d1af4c8d4e57 -r badcfa737c2e sbin/mk_resolvconf
--- a/sbin/mk_resolvconf	Wed Dec 22 16:45:36 2010 +0100
+++ b/sbin/mk_resolvconf	Sun Jan 02 13:57:47 2011 +0100
@@ -44,9 +44,9 @@
 );
 
 my $options = {
-    'host'      => hostname
-    'help'      => 0,
-    'output'    => '/etc/resolv.conf',
+    'host'     => hostname
+        'help' => 0,
+    'output' => '/etc/resolv.conf',
 };
 
 my $program = basename $PROGRAM_NAME;
@@ -75,7 +75,7 @@
 GetOptions( $options, @options_specs )
     or die "Didn't grok options (see --help).\n";
 
-if ($options->{'help'}) {
+if ( $options->{'help'} ) {
     Do_help();
     exit 0;
 }
diff -r d1af4c8d4e57 -r badcfa737c2e sbin/mk_sitezone
--- a/sbin/mk_sitezone	Wed Dec 22 16:45:36 2010 +0100
+++ b/sbin/mk_sitezone	Sun Jan 02 13:57:47 2011 +0100
@@ -42,8 +42,8 @@
 );
 
 my $options = {
-    'help'      => 0,
-    'output'    => '-',
+    'help'   => 0,
+    'output' => '-',
 };
 
 my $program = basename $PROGRAM_NAME;
@@ -71,7 +71,7 @@
 GetOptions( $options, @options_specs )
     or die "Didn't grok options (see --help).\n";
 
-if ($options->{'help'}) {
+if ( $options->{'help'} ) {
     Do_help();
     exit 0;
 }
@@ -83,12 +83,12 @@
 );
 
 $options->{'site'} ||= $pf_config->{'location'}->{'site'};
-unless( $options->{'site'} ) {
+unless ( $options->{'site'} ) {
     die q{ERROR: No site specified and no default site in configuration};
 }
 
-# NOTE: get_site_config() will croak if the site is unknown
-my $site_ref = get_site_config( $options->{'site'}, $global_config );
+# NOTE: get_site_dhcp_config() will croak if the site is unknown
+my $site_ref = get_site_dhcp_config( $options->{'site'}, $global_config );
 
 make_zone_file(
     {
diff -r d1af4c8d4e57 -r badcfa737c2e sbin/mk_sourceslist
--- a/sbin/mk_sourceslist	Wed Dec 22 16:45:36 2010 +0100
+++ b/sbin/mk_sourceslist	Sun Jan 02 13:57:47 2011 +0100
@@ -45,15 +45,14 @@
 );
 
 my $options = {
-    'help'      => 0,
-    'host'      => hostname,
-    'add'       => [],
-    'backport'  => 0,
-    'output'    => '-',
+    'help'     => 0,
+    'add'      => [],
+    'backport' => 0,
+    'output'   => '-',
 };
 
-my $PF_CONFIG         = {};
-my $GLOBAL_STRUCT     = {};
+my $pf_config     = {};
+my $global_config = {};
 
 my $program = basename $PROGRAM_NAME;
 
@@ -74,7 +73,7 @@
 
 	--help			Display this message and exit
 
-	-h | --host		Define here the hostname you want to build the sources.list
+	-h | --host		The hostname to build the sources.list for (defaults to localhost)
 
 	-s | --site		Define here the site on which the hostname is defined
 
@@ -113,25 +112,21 @@
 GetOptions( $options, @options_specs )
     or die "Didn't grok options (see --help).\n";
 
-if ($options->{'help'}) {
+if ( $options->{'help'} ) {
     Do_help();
     exit 0;
 }
 
-unless( $options->{'host'} ) {
-    die "Unable to build sources.list for an undefined hostname";
-}
+$options->{'host'} ||= hostname;
 
-( $PF_CONFIG, $GLOBAL_STRUCT ) = Init_TOOLS(
+( $pf_config, $global_config ) = Init_TOOLS(
     $options->{'host'},
     $options->{'config'},
     $options->{'store'}
 );
 
-unless( $options->{'site'} ) {
-    $options->{'site'} = $PF_CONFIG->{'location'}->{'site'}
-        || get_uniq_site_from_hostname( $options->{'host'}, $GLOBAL_STRUCT );
-}
+$options->{'site'} ||= $pf_config->{'location'}->{'site'}
+    || get_uniq_site_from_hostname( $options->{'host'}, $global_config );
 
 my @sections = (q{common});
 push @sections, split qr{ \s* [,] \s* }xms, join q{,}, @{ $options->{'add'} };
@@ -144,8 +139,8 @@
         sections      => \@sections,
         template      => $options->{'tpl'},
         backports     => $options->{'backport'},
-        global_config => $GLOBAL_STRUCT,
-        pf_config     => $PF_CONFIG,
+        global_config => $global_config,
+        pf_config     => $pf_config,
     }
 );
 
diff -r d1af4c8d4e57 -r badcfa737c2e t/13.conf.t
--- a/t/13.conf.t	Wed Dec 22 16:45:36 2010 +0100
+++ b/t/13.conf.t	Sun Jan 02 13:57:47 2011 +0100
@@ -1687,6 +1687,66 @@
 
 
 ########################################################################
+note('Testing PFTools::Structqueries::get_site_dhcp_config');
+can_ok( 'PFTools::Structqueries', qw( get_site_dhcp_config ) );
+
+# http://rt.perl.org/rt3/Public/Bug/Display.html?id=52610
+SKIP: {
+    skip q{Perl bug #52610}, 2; # only if Test::Exception < 0.31 ?
+
+throws_ok { get_site_dhcp_config() }
+qr{ \A ERROR: [ ] Invalid [ ] site_name }xms
+    => 'Dies if no site_name';
+
+throws_ok { get_site_dhcp_config( q{} ) }
+qr{ \A ERROR: [ ] Invalid [ ] site_name }xms
+    => q{Dies if empty site_name};
+}
+
+throws_ok { get_site_dhcp_config( {} ) }
+qr{ \A ERROR: [ ] Invalid [ ] site_name }xms
+    => q{Dies if non-scalar site_name};
+
+throws_ok { get_site_dhcp_config( q{site_name} ) }
+qr{ \A ERROR: [ ] Invalid [ ] global_config }xms
+    => 'Dies if no global_config';
+
+throws_ok { get_site_dhcp_config( q{site_name}, q{global_config} ) }
+qr{ \A ERROR: [ ] Invalid [ ] global_config }xms
+    => q{Dies if non-hashref global_config};
+
+throws_ok { get_site_dhcp_config( q{site_name}, $global_config ) }
+qr{ \A ERROR: [ ] Unknown [ ] site [ ] }xms
+    => q{Dies if unknown site_name};
+
+$result = get_site_dhcp_config( q{cbv4}, $global_config );
+
+$expected_result = {
+    'vlan-systeme' => {
+        'netmask'      => '255.255.0.0',
+        'subnet'       => '10.1.0.0',
+        'cbv4-rdeploy' => {
+            'cbv4-rdeploy01' => [
+                'hardware ethernet 00:1e:c9:ff:42:0b;',
+                'fixed-address 10.1.167.1;',
+                'filename pxelinux.0;',
+                'option domain-name-servers nsprivate.private;'
+            ],
+            'cbv4-rdeploy00' => [
+                'hardware ethernet 00:1e:c9:ff:08:e4;',
+                'fixed-address 10.1.167.0;',
+                'filename pxelinux.0;',
+                'option domain-name-servers nsprivate.private;'
+            ],
+        },
+    },
+};
+
+is_deeply $result, $expected_result
+    => q{Returns the correct site_ref for cbv4};
+
+
+########################################################################
 note('Testing PFTools::Structqueries::get_site_config');
 can_ok( 'PFTools::Structqueries', qw( get_site_config ) );
 
@@ -1722,30 +1782,125 @@
 $result = get_site_config( q{cbv4}, $global_config );
 
 $expected_result = {
-    'vlan-systeme' => {
-        'netmask'      => '255.255.0.0',
-        'subnet'       => '10.1.0.0',
-        'cbv4-rdeploy' => {
-            'cbv4-rdeploy01' => [
-                'hardware ethernet 00:1e:c9:ff:42:0b;',
-                'fixed-address 10.1.167.1;',
-                'filename pxelinux.0;',
-                'option domain-name-servers nsprivate.private;'
-            ],
-            'cbv4-rdeploy00' => [
-                'hardware ethernet 00:1e:c9:ff:08:e4;',
-                'fixed-address 10.1.167.0;',
-                'filename pxelinux.0;',
-                'option domain-name-servers nsprivate.private;'
-            ],
+    'HOST' => {
+        'BY_NAME' => {
+            'cbv4-rdeploy' => {
+                'ntp01'          => 'cbv4-rdeploy01',
+                'ntp'            => 'cbv4-rdeploy',
+                'nsprivate01'    => 'cbv4-rdeploy01',
+                'filer01'        => 'cbv4-rdeploy01',
+                'filer00'        => 'cbv4-rdeploy00',
+                'filer'          => 'cbv4-rdeploy',
+                'spawn00'        => 'cbv4-rdeploy00',
+                'cbv4-rdeploy00' => {
+                    'dns' => {
+                        'resolver' => 'nsprivate.private'
+                    },
+                    'boot' => {
+                        'kernel'    => 'vmlinuz-2.6.26.5-universal-grm2.1.12',
+                        'kerneluml' => 'linux-uml-elf-2.4.26-gr1.9.15',
+                        'pxefilename' => 'pxelinux.0',
+                        'console'     => 'default'
+                    },
+                    'interfaces' => {
+                        'eth0' => {
+                            'ipv4' => '10.1.167.0/16',
+                            'mac'  => '00:1e:c9:ff:08:e4',
+                            'vlan' => 'vlan-systeme'
+                            }
+                    },
+                    'deployment' => {
+                        'dhcpvlan'       => 'vlan-systeme',
+                        'hosttype'       => 'cbv4-rdeploy',
+                        'arch'           => 'amd64',
+                        'mode'           => 'debian',
+                        'order'          => '1',
+                        'distrib'        => 'lenny',
+                        'hostname_model' => 'cbv4-rdeploy%%'
+                        }
+                },
+                'spawn01'        => 'cbv4-rdeploy01',
+                'cbv4-rdeploy01' => {
+                    'dns' => {
+                        'resolver' => 'nsprivate.private'
+                    },
+                    'boot' => {
+                        'kernel'    => 'vmlinuz-2.6.26.5-universal-grm2.1.12',
+                        'kerneluml' => 'linux-uml-elf-2.4.26-gr1.9.15',
+                        'pxefilename' => 'pxelinux.0',
+                        'console'     => 'default'
+                    },
+                    'interfaces' => {
+                        'eth0' => {
+                            'ipv4' => '10.1.167.1/16',
+                            'mac'  => '00:1e:c9:ff:42:0b',
+                            'vlan' => 'vlan-systeme'
+                            }
+                    },
+                    'deployment' => {
+                        'dhcpvlan'       => 'vlan-systeme',
+                        'hosttype'       => 'cbv4-rdeploy',
+                        'arch'           => 'amd64',
+                        'mode'           => 'debian',
+                        'order'          => '1',
+                        'distrib'        => 'lenny',
+                        'hostname_model' => 'cbv4-rdeploy%%'
+                        }
+                },
+                'ntp00'       => 'cbv4-rdeploy00',
+                'nsprivate'   => 'cbv4-rdeploy',
+                'nsprivate00' => 'cbv4-rdeploy00',
+                'spawn'       => 'cbv4-rdeploy'
+                }
         },
+        '__hostclass_pxe' => [
+            'cbv4-rdeploy'
+        ],
+        'BY_ADDR' => {
+            '10.1.167.0/16' => 'cbv4-rdeploy00.vlan-systeme',
+            '10.1.167.1/16' => 'cbv4-rdeploy01.vlan-systeme'
+        },
+        'BY_MAC' => {
+            '00:1e:c9:ff:42:0b' => 'eth0.cbv4-rdeploy01.vlan-systeme',
+            '00:1e:c9:ff:08:e4' => 'eth0.cbv4-rdeploy00.vlan-systeme'
+            }
     },
+    'location' => 'Courbevoie',
+    'zone'     => 'private',
+    'console'  => 'default',
+    'SERVICE'  => {
+        'BY_NAME' => {
+            'admins-cbv4' => [
+                'CONFSITE_cbv4:/hostfile-cbv4-rdeploy'
+                ]
+            }
+    },
+    'room'     => 'CBV4 Room Name',
+    'state'    => 'EDGE',
+    'dhcpvlan' => 'vlan-systeme',
+    'comment'  => 'CBV4 POP',
+    'NETWORK'  => {
+        'BY_TAG' => {
+            '13' => 'vlan-systeme'
+        },
+        'BY_NAME' => {
+            'vlan-systeme' => {
+                'network' => '10.1.0.0',
+                'tag'     => 13,
+                'netmask' => '255.255.0.0',
+                'scope'   => 'private'
+                }
+        },
+        'BY_ADDR' => {
+            '10.1.0.0/16' => 'vlan-systeme'
+            }
+    },
+    'type' => 'site'
 };
 
 is_deeply $result, $expected_result
-    => q{Returns the correct site_ref for cbv4};
-
-
+    => q{Returns the correct site_ref for cbv4}
+    or note explain $result;
 
 #TODO: {
 #    local $TODO = 'Depends on other, still failing, tests';
diff -r d1af4c8d4e57 -r badcfa737c2e t/20.files.search_and_replace.input.distrib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/t/20.files.search_and_replace.input.distrib	Sun Jan 02 13:57:47 2011 +0100
@@ -0,0 +1,3 @@
+# This is a comment
+deb http://mirrors.example.org/%DISTSRC% %DISTRIB% main contrib non-free
+
diff -r d1af4c8d4e57 -r badcfa737c2e t/20.files.search_and_replace.input.iface
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/t/20.files.search_and_replace.input.iface	Sun Jan 02 13:57:47 2011 +0100
@@ -0,0 +1,3 @@
+eth.vlan-systeme
+eth.vlan-pfds-int
+
diff -r d1af4c8d4e57 -r badcfa737c2e t/20.files.search_and_replace.input.ip
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/t/20.files.search_and_replace.input.ip	Sun Jan 02 13:57:47 2011 +0100
@@ -0,0 +1,6 @@
+a HOSTNAME.vlan-systeme.private b
+a HOSTNAME.vlan-pfds-int.private b
+a cbv4-spawn00.vlan-systeme.private b
+a cbv4-spawn.vlan-systeme.private b
+# the end
+
diff -r d1af4c8d4e57 -r badcfa737c2e t/20.files.t
--- a/t/20.files.t	Wed Dec 22 16:45:36 2010 +0100
+++ b/t/20.files.t	Sun Jan 02 13:57:47 2011 +0100
@@ -39,11 +39,11 @@
 };
 
 throws_ok { PFTools::Utils::__build_zone(); }
-qr{ \A ERROR: [ ] BUG: [ ] invalid [ ] args }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-hash [ ] reference [ ] args_ref }xms
     => q{Dies if no args};
 
 throws_ok { PFTools::Utils::__build_zone($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] zone_name }xms
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] zone_name }xms
     => q{Dies if empty $zone_name};
 
 $args_ref->{'zone_name'} = { foo => 0 };
@@ -54,7 +54,7 @@
 $args_ref->{'zone_name'} = q{};
 $args_ref->{'site_name'} = q{};
 throws_ok { PFTools::Utils::__build_zone($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] site_name }xms
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] site_name }xms
     => q{Dies if empty $site_name};
 
 $args_ref->{'zone_name'} = q{name};
@@ -217,7 +217,7 @@
 can_ok( 'PFTools::Utils', qw( make_zone_file ) );
 
 throws_ok { make_zone_file(); }
-qr{ \A ERROR: [ ] Invalid [ ] [\$] arguments_ref }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-hash [ ] reference [ ] args_ref }xms
     => q{Dies if no args};
 
 my $test_output_file = q{test.zone};
@@ -247,7 +247,7 @@
 can_ok( 'PFTools::Utils', qw( make_resolv_conf_file ) );
 
 throws_ok { make_resolv_conf_file(); }
-qr{ \A ERROR: [ ] Invalid [ ] [\$] arguments_ref }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-hash [ ] reference [ ] args_ref }xms
     => q{Dies if no args};
 
 $template_filename = q{templates/resolv.conf.tpl};
@@ -258,12 +258,12 @@
     template_filename => $template_filename,
 };
 throws_ok { make_resolv_conf_file($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] filename }xms
-    => q{Dies if empty $filename};
+qr{ \A ERROR: [ ] Mandatory [ ] argument  [ ] filename [ ] not [ ] found }xms
+    => q{Dies if no $filename};
 
 $args_ref->{'filename'} = {};
 throws_ok { make_resolv_conf_file($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] filename }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] filename }xms
     => q{Dies if non-scalar $filename};
 
 $args_ref->{'filename'} = q{filename};
@@ -302,7 +302,7 @@
 $args_ref->{'global_config'} = $global_config;
 $args_ref->{'site_name'} = q{};
 throws_ok { make_resolv_conf_file($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] site_name }xms
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] site_name }xms
     => q{Dies if empty $site_name};
 
 $args_ref->{'site_name'} = {};
@@ -364,7 +364,7 @@
 
 $args_ref->{'hostname'} = q{};
 throws_ok { PFTools::Utils::__build_interfaces($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] hostname }xms
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] hostname }xms
     => q{Dies if empty $hostname};
 
 $args_ref->{'hostname'} = q{cbv4-spawn01};
@@ -420,8 +420,13 @@
 $args_ref->{'hostname'} = q{cbv4-spawn01};
 $args_ref->{'site_name'} = q{foo};
 throws_ok { PFTools::Utils::__build_interfaces($args_ref); }
-qr{ \A ERROR: [ ] Unknown [ ] hostname [ ] cbv4-spawn01 [ ] on [ ] site [ ] foo }xms
+qr{ \A ERROR: [ ] Unknown [ ] site [ ] 'foo' [ ] }xms
     => q{Dies if unknown $site_name};
+
+$args_ref->{'site_name'} = q{cbv4};
+throws_ok { PFTools::Utils::__build_interfaces($args_ref); }
+qr{ \A ERROR: [ ] Unknown [ ] hostname [ ] cbv4-spawn01 [ ] on [ ] site [ ] cbv4 }xms
+    => q{Dies if unknown $hostname};
 
 $args_ref->{'site_name'} = q{cbv4-pfds};
 $result = PFTools::Utils::__build_interfaces($args_ref);
@@ -482,7 +487,7 @@
 can_ok( 'PFTools::Utils', qw( make_interfaces_file ) );
 
 throws_ok { make_interfaces_file(); }
-qr{ \A ERROR: [ ] Invalid [ ] [\$] arguments_ref }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-hash [ ] reference [ ] args_ref }xms
     => q{Dies if no args};
 
 $test_output_file = q{test.interfaces};
@@ -511,134 +516,90 @@
 can_ok( 'PFTools::Utils', qw( __build_sources_list ) );
 
 throws_ok { PFTools::Utils::__build_sources_list(); }
-qr{ \A ERROR: }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-hash [ ] reference [ ] args_ref }xms
     => q{Dies if no $arguments_ref};
-
-throws_ok { PFTools::Utils::__build_sources_list( {} ); }
-qr{ \A ERROR: }xms
-    => q{Dies if empty $arguments_ref};
-
-throws_ok { PFTools::Utils::__build_sources_list( { template => q{} } ); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] template }xms
-    => q{Dies if empty $template};
-
-throws_ok { PFTools::Utils::__build_sources_list( { template => {} } ); }
-qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] template }xms
-    => q{Dies if non-scalar $template};
-
-throws_ok {
-    PFTools::Utils::__build_sources_list(
-        { template => q{template}, hostname => q{}, sections_ref => q{} }
-    );
-}
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] [\$] sections_ref }xms
-    => q{Dies if empty $sections_ref};
-
-throws_ok {
-    PFTools::Utils::__build_sources_list(
-        { template => q{template}, hostname => q{}, sections_ref => {} }
-    );
-}
-qr{ \A ERROR: [ ] Invalid [ ] non-array-ref [ ] [\$] sections_ref }xms
-    => q{Dies if non-array-ref $sections_ref};
-
-throws_ok {
-    PFTools::Utils::__build_sources_list(
-        { template => q{template}, hostname => q{}, sections_ref => [] }
-    );
-}
-qr{ \A ERROR: [ ] Invalid [ ] empty-array-ref [ ] [\$] sections_ref }xms
-    => q{Dies if empty-array-ref $sections_ref};
-
-throws_ok {
-    PFTools::Utils::__build_sources_list(
-        { template => q{template}, hostname => q{}, sections_ref => [q{}] }
-    );
-}
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] blank [ ] section [ ] in [ ] array-ref [ ] [\$] sections_ref }xms
-    => q{Dies if empty section in array-ref $sections_ref};
-
-throws_ok {
-    PFTools::Utils::__build_sources_list(
-        { template => q{template}, hostname => q{}, sections_ref => [q{ }] }
-    );
-}
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] blank [ ] section [ ] in [ ] array-ref [ ] [\$] sections_ref }xms
-    => q{Dies if blank section in array-ref $sections_ref};
-
-throws_ok {
-    PFTools::Utils::__build_sources_list(
-        {
-            template     => q{template},
-            sections_ref => [q{section}],
-            backports    => {}
-        }
-    );
-}
-qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] [\$] backports }xms
-    => q{Dies if non-scalar $backports};
-
-throws_ok {
-    PFTools::Utils::__build_sources_list(
-        {
-            template      => q{template},
-            sections_ref  => [q{section}],
-            hostname      => q{hostname},
-            global_config => q{foo},
-        }
-    );
-}
-qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] [\$] global_config }xms
-    => q{Dies if non-hashref $global_config};
-
-throws_ok {
-    PFTools::Utils::__build_sources_list(
-        {
-            template      => q{template},
-            sections_ref  => [q{section}],
-            hostname      => q{hostname},
-            global_config => {},
-        }
-    );
-}
-qr{ \A ERROR: [ ] Invalid [ ] [\$] global_config [ ] hashref: }xms
-    => q{Dies if non-config hashref $global_config};
-
-throws_ok {
-    PFTools::Utils::__build_sources_list(
-        {
-            template      => q{template},
-            sections_ref  => [q{section}],
-            global_config => $global_config,
-            hostname      => q{},
-        }
-    );
-}
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] hostname }xms
-    => q{Dies if empty $hostname};
-
-throws_ok {
-    PFTools::Utils::__build_sources_list(
-        {
-            template      => q{template},
-            sections_ref  => [q{section}],
-            global_config => $global_config,
-            hostname      => {},
-        }
-    );
-}
-qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] hostname }xms
-    => q{Dies if non-scalar $hostname};
 
 my $test_sections_ref = [qw(common uncommon)];
 $args_ref = {
-    hostname      => q{cbv4-rdeploy01},
+    hostname      => $hostname,
     site_name     => q{cbv4},
     sections_ref  => $test_sections_ref,
     template      => q{templates/sources.list.tpl},
     global_config => $global_config,
     pf_config     => $pf_config,
 };
+
+$args_ref->{'template'} = q{};
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] template }xms
+    => q{Dies if empty $template};
+
+$args_ref->{'template'} = {};
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] template }xms
+    => q{Dies if non-scalar $template};
+
+$args_ref->{'template'} = q{templates/sources.list.tpl};
+$args_ref->{'hostname'} = q{};
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] hostname }xms
+    => q{Dies if empty $hostname};
+
+$args_ref->{'hostname'} = q{cbv4-rdeploy01};
+$args_ref->{'sections_ref'} = q{};
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] non-array [ ] reference [ ] sections_ref }xms
+    => q{Dies if non-array-ref $sections_ref};
+
+$args_ref->{'sections_ref'} = [];
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] empty-array [ ] reference [ ] sections_ref }xms
+    => q{Dies if empty $sections_ref};
+
+$args_ref->{'sections_ref'} = [q{}];
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] blank [ ] section [ ] in [ ] sections_ref }xms
+    => q{Dies if empty section in array-ref $sections_ref};
+
+$args_ref->{'sections_ref'} = [q{ }];
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] empty [ ] or [ ] blank [ ] section [ ] in [ ] sections_ref }xms
+    => q{Dies if blank section in array-ref $sections_ref};
+
+$args_ref->{'sections_ref'} = $test_sections_ref;
+$args_ref->{'backports'} = {};
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] backports }xms
+    => q{Dies if non-scalar $backports};
+
+delete $args_ref->{'backports'};
+$args_ref->{'global_config'} = q{foo};
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] non-hash [ ] reference [ ] global_config }xms
+    => q{Dies if non-hashref $global_config};
+
+$args_ref->{'global_config'} = { foo => q{bar} };
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] [\$] global_config [ ] hashref: }xms
+    => q{Dies if non-config hashref $global_config};
+
+$args_ref->{'global_config'} = $global_config;
+delete $args_ref->{'hostname'};
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Mandatory [ ] argument [ ] hostname [ ] not [ ] found }xms
+    => q{Dies if no $hostname};
+
+$args_ref->{'hostname'} = q{};
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] hostname }xms
+    => q{Dies if empty $hostname};
+
+$args_ref->{'hostname'} = {};
+throws_ok { PFTools::Utils::__build_sources_list($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] hostname }xms
+    => q{Dies if non-scalar $hostname};
+
+$args_ref->{'hostname'} = q{cbv4-rdeploy01};
 $result = PFTools::Utils::__build_sources_list( $args_ref );
 
 my $expected_sources_list = <<'EOT';
@@ -675,7 +636,7 @@
 can_ok( 'PFTools::Utils', qw( make_sources_list_file ) );
 
 throws_ok { make_sources_list_file(); }
-qr{ \A ERROR: [ ] Invalid [ ] [\$] arguments_ref }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-hash [ ] reference [ ] args_ref }xms
     => q{Dies if no args};
 
 $expected_result = [ split qr{ \n }xms, $expected_sources_list, -1 ];
@@ -863,12 +824,13 @@
 
 my $preseed_file = make_preseed_file(
     {
-        hostname                  => $hostname,
-        host_ref                  => $host_ref,
-        site_name                 => $site_name,
-        preseed_template_filename => q{templates/standard-preseed},
-        pf_config                 => $pf_config,
-        pf_script                 => q{/path/to/some/script},
+        hostname          => $hostname,
+        host_ref          => $host_ref,
+        site_name         => $site_name,
+        template_filename => q{templates/standard-preseed},
+        global_config     => $global_config,
+        pf_config         => $pf_config,
+        pf_script         => q{/path/to/some/script},
     }
 );
 is $preseed_file, basename($test_output_file)
@@ -883,6 +845,10 @@
 ########################################################################
 note('Testing PFTools::Utils::make_pxe_boot_and_preseed_files');
 can_ok( 'PFTools::Utils', qw( make_pxe_boot_and_preseed_files ) );
+
+throws_ok { make_pxe_boot_and_preseed_files(); }
+qr{ \A ERROR: [ ] Invalid [ ] non-hash [ ] reference [ ] args_ref }xms
+    => q{Dies if no args};
 
 ok make_pxe_boot_and_preseed_files(
     {
@@ -933,25 +899,37 @@
 can_ok( 'PFTools::Utils', qw( __fix_etc_hosts ) );
 
 throws_ok { PFTools::Utils::__fix_etc_hosts(); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] ip_type }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-hash [ ] reference [ ] args_ref }xms
+    => q{Dies if no args};
+
+$args_ref = {
+    ip_type        => q{ipv4},
+    hostname       => $hostname,
+    site_name      => q{cbv4},
+    input_filename => q{/etc/hosts},
+    global_config  => $global_config,
+    pf_config      => $pf_config,
+};
+
+$args_ref->{'ip_type'} = q{};
+throws_ok { PFTools::Utils::__fix_etc_hosts($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] ip_type }xms
     => q{Dies if empty iptype};
 
-throws_ok { PFTools::Utils::__fix_etc_hosts( { ip_type => {} } ); }
+$args_ref->{'ip_type'} = {};
+throws_ok { PFTools::Utils::__fix_etc_hosts($args_ref); }
 qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] ip_type }xms
     => q{Dies if non-scalar iptype};
 
-$args_ref = {
-    ip_type       => q{ipv6},
-};
+$args_ref->{'ip_type'} = q{ipv6};
 throws_ok { PFTools::Utils::__fix_etc_hosts($args_ref); }
 qr{ \A ERROR: [ ] __fix_etc_hosts: [ ] ip_type [ ] 'ipv6' [ ] not [ ] implemented [ ] }xms
     => q{Dies if iptype eq 'ipv6'};
 
-$args_ref = {
-    ip_type       => q{ipv4},
-};
+$args_ref->{'ip_type'} = q{ipv4};
+$args_ref->{'hostname'} = q{};
 throws_ok { PFTools::Utils::__fix_etc_hosts($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] hostname }xms
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] hostname }xms
     => q{Dies if empty hostname};
 
 $args_ref->{'hostname'} = {};
@@ -960,23 +938,25 @@
     => q{Dies if non-scalar hostname};
 
 $args_ref->{'hostname'} = q{cbv4-rdeploy01};
+delete $args_ref->{'global_config'};
 throws_ok { PFTools::Utils::__fix_etc_hosts($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] global_config }xms
-    => q{Dies if empty global_config};
+qr{ \A ERROR: [ ] Mandatory [ ] argument [ ] global_config [ ] not [ ] found }xms
+    => q{Dies if no global_config};
 
 $args_ref->{'global_config'} = q{global_config};
 throws_ok { PFTools::Utils::__fix_etc_hosts($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] non-hashref [ ] global_config }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-hash [ ] reference [ ] global_config }xms
     => q{Dies if non-hashref global_config};
 
 $args_ref->{'global_config'} = $global_config;
+$args_ref->{'input_filename'} = q{};
 throws_ok { PFTools::Utils::__fix_etc_hosts($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] filename }xms
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] input_filename }xms
     => q{Dies if empty input_filename};
 
 $args_ref->{'input_filename'} = {};
 throws_ok { PFTools::Utils::__fix_etc_hosts($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] filename }xms
+qr{ \A ERROR: [ ] Invalid [ ] non-scalar [ ] input_filename }xms
     => q{Dies if non-scalar input_filename};
 
 my $input_filename = q{t/20.files.etc.hosts.input};
@@ -1008,7 +988,7 @@
 $args_ref->{'input_filename'} = undef;
 $args_ref->{'output_filename'} = undef;
 throws_ok { fix_etc_hosts($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] input_filename }xms
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] input_filename }xms
     => q{Dies if undefined input_filename};
 
 $args_ref->{'input_filename'} = {};
@@ -1019,7 +999,7 @@
 $args_ref->{'input_filename'} = $input_filename;
 
 throws_ok { fix_etc_hosts($args_ref); }
-qr{ \A ERROR: [ ] Invalid [ ] empty [ ] output_filename }xms
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] output_filename }xms
     => q{Dies if empty output_filename};
 
 $args_ref->{'output_filename'} = {};
@@ -1139,3 +1119,119 @@
 ok unlink($output_filename)
     => q{Removed test output file};
 
+########################################################################
+note('Testing PFTools::Utils::search_and_replace');
+can_ok( 'PFTools::Utils', qw( search_and_replace ) );
+
+$input_filename = q{t/20.files.search_and_replace.input.distrib};
+$output_filename = q{test.output};
+
+$args_ref = {
+    hostname        => q{cbv4-rdeploy01},
+    site_name       => q{cbv4},
+    input_filename  => $input_filename,
+    output_filename => $output_filename,
+    global_config   => $global_config,
+    pf_config       => $pf_config,
+};
+
+throws_ok { search_and_replace($args_ref); }
+qr{ \A ERROR: [ ] Mandatory [ ] argument [ ] filter_type [ ] not [ ] found [ ] }xms
+    => q{Dies if no filter_type};
+
+$args_ref->{'filter_type'} = q{};
+throws_ok { search_and_replace($args_ref); }
+qr{ \A ERROR: [ ] Invalid [ ] false [ ] argument [ ] filter_type }xms
+    => q{Dies if empty filter_type};
+
+$args_ref->{'filter_type'} = q{foo};
+throws_ok { search_and_replace($args_ref); }
+qr{ \A ERROR: [ ] Unknown [ ] filter_type [ ] foo }xms
+    => q{Dies if unknown filter_type};
+
+$args_ref->{'filter_type'} = q{distrib};
+ok search_and_replace($args_ref);
+$result = PFTools::Utils::__read_file_in_array($output_filename, 1);
+$expected_result = [ split qr{ \n }xms, <<"EOT", -1 ];
+# This is a comment
+deb http://mirrors.example.org/debian lenny main contrib non-free
+EOT
+
+is_deeply $result, $expected_result
+    => q{Correct result for filter_type 'distrib'}
+    or note explain $result;
+
+$args_ref->{'filter_type'} = q{iface};
+$args_ref->{'input_filename'}
+    = q{t/20.files.search_and_replace.input.iface};
+$args_ref->{'hostname'}  = q{cbv4-spawn00};
+$args_ref->{'site_name'} = q{cbv4-pfds};
+ok search_and_replace($args_ref);
+$result = PFTools::Utils::__read_file_in_array($output_filename, 1);
+$expected_result = [ split qr{ \n }xms, <<"EOT", -1 ];
+eth0
+eth0.39
+EOT
+
+is_deeply $result, $expected_result
+    => q{Correct result for filter_type 'iface'}
+    or note explain $result;
+
+$args_ref->{'filter_type'} = q{iface};
+$args_ref->{'input_filename'}
+    = q{t/20.files.search_and_replace.input.iface};
+$args_ref->{'hostname'}  = q{cbv4-spawn00};
+$args_ref->{'site_name'} = q{cbv4-pfds};
+ok search_and_replace($args_ref);
+$result = PFTools::Utils::__read_file_in_array($output_filename, 1);
+$expected_result = [ split qr{ \n }xms, <<"EOT", -1 ];
+eth0
+eth0.39
+EOT
+
+is_deeply $result, $expected_result
+    => q{Correct result for filter_type 'iface'}
+    or note explain $result;
+
+$args_ref->{'filter_type'} = q{ip};
+$args_ref->{'input_filename'}
+    = q{t/20.files.search_and_replace.input.ip};
+$args_ref->{'ip_type'} = q{ipv4};
+#$args_ref->{'separator'} = q{};
+ok search_and_replace($args_ref);
+$result = PFTools::Utils::__read_file_in_array($output_filename, 1);
+$expected_result = [ split qr{ \n }xms, <<"EOT", -1 ];
+a 10.1.167.0 b
+a 10.2.167.0 b
+a 10.1.167.0 b
+a 10.1.167.0 10.1.167.1 b
+# the end
+EOT
+
+is_deeply $result, $expected_result
+    => q{Correct result for filter_type 'ip' and no explicit separator}
+    or note explain $result;
+
+$args_ref->{'separator'} = q{ };
+ok search_and_replace($args_ref);
+$result = PFTools::Utils::__read_file_in_array($output_filename, 1);
+is_deeply $result, $expected_result
+    => q{Correct result for filter_type 'ip' and explicit space separator}
+    or note explain $result;
+
+$args_ref->{'separator'} = q{DUPLICATE};
+ok search_and_replace($args_ref);
+$result = PFTools::Utils::__read_file_in_array($output_filename, 1);
+$expected_result = [ split qr{ \n }xms, <<"EOT", -1 ];
+a 10.1.167.0 b
+a 10.2.167.0 b
+a 10.1.167.0 b
+a 10.1.167.0 b
+a 10.1.167.1 b
+# the end
+EOT
+
+is_deeply $result, $expected_result
+    => q{Correct result for filter_type 'ip' and DUPLICATE separator}
+    or note explain $result;
+
diff -r d1af4c8d4e57 -r badcfa737c2e tools/Display_IP_config
--- a/tools/Display_IP_config	Wed Dec 22 16:45:36 2010 +0100
+++ b/tools/Display_IP_config	Sun Jan 02 13:57:47 2011 +0100
@@ -47,12 +47,12 @@
 );
 
 my $options = {
-    'type'      => 'ipv4',
-    'output'    => '-',
+    'type'   => 'ipv4',
+    'output' => '-',
 };
 
-my $PF_CONFIG         = {};
-my $GLOBAL_STRUCT     = {};
+my $PF_CONFIG     = {};
+my $GLOBAL_STRUCT = {};
 
 my $program = basename $PROGRAM_NAME;
 
@@ -93,13 +93,14 @@
     my ($host_part) = @_;
     my $order;
     foreach my $hostclass ( keys %{$host_part} ) {
-        next if( ref $host_part->{$hostclass} ne 'HASH' );
-        foreach my $hostname ( keys %{$host_part->{$hostclass}} ) {
-            next if( ref $host_part->{$hostclass}->{$hostname} ne 'HASH' );
+        next if ( ref $host_part->{$hostclass} ne 'HASH' );
+        foreach my $hostname ( keys %{ $host_part->{$hostclass} } ) {
+            next if ( ref $host_part->{$hostclass}->{$hostname} ne 'HASH' );
             my $srv_order =
-                $host_part->{$hostclass}->{$hostname}->{'deployment'}->{'order'}
+                $host_part->{$hostclass}->{$hostname}->{'deployment'}
+                ->{'order'}
                 || 999;
-            if( ! $order->{$srv_order}->{$hostclass} ) {
+            if ( !$order->{$srv_order}->{$hostclass} ) {
                 $order->{$srv_order}->{$hostclass} = [];
             }
             push( @{ $order->{$srv_order}->{$hostclass} }, $hostname );
@@ -170,7 +171,7 @@
 GetOptions( $options, @options_specs )
     or die "Didn't grok options (see --help).\n";
 
-if ($options->{'help'}) {
+if ( $options->{'help'} ) {
     Do_help();
     exit 0;
 }
@@ -181,48 +182,53 @@
     $options->{'store'}
 );
 
-unless( $options->{'site'} ) {
-    unless( $PF_CONFIG->{'location'}->{'site'} ) {
+unless ( $options->{'site'} ) {
+    unless ( $PF_CONFIG->{'location'}->{'site'} ) {
         my $site_list = get_site_list_from_hostname(
             $options->{'host'}, $GLOBAL_STRUCT
         );
-        unless( $site_list ) {
+        unless ($site_list) {
             die qq{ERROR: Unknown hostclass $options->{'host'}};
         }
         if ( scalar @{$site_list} > 1 ) {
             die qq{ERROR: Multiple sites for hostclass $options->{'host'}};
         }
-        ($options->{'site'}) = @{$site_list};
+        ( $options->{'site'} ) = @{$site_list};
     }
     $options->{'site'} = $PF_CONFIG->{'location'}->{'site'};
 }
 
-my $host_part
-    = $GLOBAL_STRUCT->{'SITE'}->{'BY_NAME'}->{$options->{'site'}}->{'HOST'}->{'BY_NAME'};
+my $site_ref = get_site_config( $options->{'site'}, $GLOBAL_STRUCT );
+my $host_part = $site_ref->->{'HOST'}->{'BY_NAME'};
 
 if (
-    defined $options->{'host'} 
+    defined $options->{'host'}
     && $options->{'host'} ne ""
-    && !defined $host_part->{$options->{'host'}}
-) {
+    && !defined $host_part->{ $options->{'host'} }
+    )
+{
     die "Unexistant hostclass in global configuration";
 }
-if ($options->{'host'}) {
-    if ($options->{'read'}) {
-        foreach my $hostname ( sort keys %{ $host_part->{$options->{'host'}} } ) {
-            if( ! ref ( $host_part->{$options->{'host'}}->{$hostname} ) ) {
+if ( $options->{'host'} ) {
+    if ( $options->{'read'} ) {
+        foreach
+            my $hostname ( sort keys %{ $host_part->{ $options->{'host'} } } )
+        {
+            if ( !ref( $host_part->{ $options->{'host'} }->{$hostname} ) ) {
                 print "\t$hostname is an alias for "
-                    . $host_part->{$options->{'host'}}->{$hostname} . "\n";
+                    . $host_part->{ $options->{'host'} }->{$hostname} . "\n";
             }
             else {
                 print "\t" . $hostname . "\n";
-                my $srv_net = get_srv_iface( $options->{'type'}, $hostname,
-                    $host_part->{$options->{'host'}}->{$hostname} );
+                my $srv_net = get_srv_iface(
+                    $options->{'type'}, $hostname,
+                    $host_part->{ $options->{'host'} }->{$hostname}
+                );
                 if ( !defined $srv_net ) {
                     die "IP feature $options->{'type'} is deactivated";
                 }
                 foreach my $iface ( sort keys %{$srv_net} ) {
-                    print "\t\t" 
+                    print "\t\t"
                         . $iface . "("
                         . $srv_net->{$iface}->{'vlan'} . ")\t: "
                         . $srv_net->{$iface}->{'addr'} . "\n";
@@ -233,7 +239,7 @@
     else {
         my $srv_ip = get_srv_ip(
             $options->{'type'}, $options->{'host'},
-            $host_part->{$options->{'host'}}, $PF_CONFIG
+            $host_part->{ $options->{'host'} }, $PF_CONFIG
         );
         foreach my $ip ( sort { _ipcomp( $a, $b ) } keys %{$srv_ip} ) {
             print $ip. "\t"
@@ -243,22 +249,23 @@
     }
 }
 else {
-    if ($options->{'read'}) {
+    if ( $options->{'read'} ) {
         my $srv_type_list = order_servers($host_part);
         foreach my $prio ( sort keys %{$srv_type_list} ) {
             print "Server with deployment priority : " . $prio . "\n";
             foreach my $srv_type ( sort keys %{ $srv_type_list->{$prio} } ) {
-                print "srv type --> ".$srv_type."\n";
-                foreach my $srv ( @{ $srv_type_list->{$prio}->{$srv_type} } ) {
+                print "srv type --> " . $srv_type . "\n";
+                foreach my $srv ( @{ $srv_type_list->{$prio}->{$srv_type} } )
+                {
                     print "\t" . $srv . "\n";
-                    my $host_props = get_host_config((
+                    my $host_props = get_host_config(
                         $srv, $GLOBAL_STRUCT, $options->{'site'}
                     );
                     my $srv_net = get_srv_iface(
                         $options->{'type'}, $srv, $host_props
                     );
                     foreach my $iface ( sort keys %{$srv_net} ) {
-                        print "\t\t" 
+                        print "\t\t"
                             . $iface . "("
                             . $srv_net->{$iface}->{'vlan'} . ")\t: "
                             . $srv_net->{$iface}->{'addr'} . "\n";
@@ -270,11 +277,14 @@
         }
     }
     else {
-        my $ip_list = get_all_ip( $options->{'type'}, $host_part, $PF_CONFIG );
+        my $ip_list
+            = get_all_ip( $options->{'type'}, $host_part, $PF_CONFIG );
         foreach my $ip ( sort { _ipcomp( $a, $b ) } keys %{$ip_list} ) {
             print "$ip\t"
-                . join( ' ',
-                map {"$_->{'hostname'}($_->{'iface'})"} @{ $ip_list->{$ip} } )
+                . join(
+                ' ',
+                map {"$_->{'hostname'}($_->{'iface'})"} @{ $ip_list->{$ip} }
+                )
                 . "\n";
         }
     }
diff -r d1af4c8d4e57 -r badcfa737c2e tools/Translate_old_config
--- a/tools/Translate_old_config	Wed Dec 22 16:45:36 2010 +0100
+++ b/tools/Translate_old_config	Sun Jan 02 13:57:47 2011 +0100
@@ -46,10 +46,10 @@
 );
 
 my $options = {
-    'help'      => 0,
-    'output'    => '-',
-    'type'      => 'config',
-    'include'   => 0,
+    'help'    => 0,
+    'output'  => '-',
+    'type'    => 'config',
+    'include' => 0,
 };
 
 my $program = basename $PROGRAM_NAME;
@@ -76,12 +76,12 @@
 GetOptions( $options, @options_specs )
     or die "Didn't grok options (see --help).\n";
 
-if ($options->{'help'}) {
+if ( $options->{'help'} ) {
     Do_help();
     exit 0;
 }
 
-unless( -e $options->{'input'} ) {
+unless ( -e $options->{'input'} ) {
     die "File $options->{'input'} doesn't exist";
 }
 
@@ -92,7 +92,7 @@
 );
 my $trans = {};
 if ( $options->{'type'} eq 'config' ) {
-    $trans = Translate_old2new_config( $old_parsing );
+    $trans = Translate_old2new_config($old_parsing);
 }
 else {
     foreach my $section ( keys %{$old_parsing} ) {
@@ -104,6 +104,7 @@
         }
         elsif ( $old_parsing->{$section}->{'type'} =~ /-server$/ ) {
             my $pftools = 0;
+
             # Need to see if it is a "virtual pf-tools" host
             # or a "real pf-tools" host
             foreach my $key ( keys %{ $old_parsing->{$section} } ) {
@@ -112,12 +113,13 @@
                     last;
                 }
             }
-            if( $pftools ) {
+            if ($pftools) {
+
                 # We need to translate into a hostfile configuration
                 $trans->{'__hostfile'} = {
                     $section => Translate_old2new_host(
                         $old_parsing->{$section}, $section
-                    )
+                        )
                 };
             }
         }
@@ -133,9 +135,9 @@
         $output_fh->print( "[" . $section . "]\n" );
         foreach my $key ( keys %{ $trans->{$section} } ) {
             next if ( $key =~ m{\A__} );
-            $output_fh->print( "\t$key\t= $trans->{$section}->{$key}\n" );
+            $output_fh->print("\t$key\t= $trans->{$section}->{$key}\n");
         }
-        $output_fh->print( "\n" );
+        $output_fh->print("\n");
     }
 }
 else {



More information about the pf-tools-commits mailing list