Hi,
please find attached a patch that implements domain specific hooks.
It would be great if this patch made it into a new release of ferm.
Thanks for maintaining ferm im Debian
Peter
PS: Now that 2.0.7 is out fixing a few - IMHO - important bugs,
what about a new Debian release?
--
Peter Marschall
[email protected]
From e4ea33b742a89d432e52088159bbb03d9029d047 Mon Sep 17 00:00:00 2001
From: Peter Marschall <[email protected]>
Date: Sun, 24 Jan 2010 19:04:35 +0100
Subject: [PATCH] support domain-specific hooks
Allow hooks to be defined either globally or within a domain block.
The hooks defined within a domain specific block get called at the
start resp. end of the domain.
These domain-specific hooks allow calling external programs that are
specific to one domain only when ferm updates this domain.
Consider e.g. the case of routing IPv4 but not IPv6 addresses.
Signed-off-by: Peter Marschall <[email protected]>
---
doc/ferm.pod | 4 ++++
src/ferm | 38 +++++++++++++++++++++++++++-----------
2 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/doc/ferm.pod b/doc/ferm.pod
index adcef03..0248aee 100644
--- a/doc/ferm.pod
+++ b/doc/ferm.pod
@@ -1614,6 +1614,10 @@ the command afterwards. "flush" hooks are run after ferm has flushed
the firewall rules (option --flush). You may install any number of
hooks.
+Hooks can be either global or domain-specific. In the latter case
+simply define them directly within a domain block.
+
+
=head1 BUILT-IN FUNCTIONS
There are several built-in functions which you might find useful.
diff --git a/src/ferm b/src/ferm
index 7973340..6c5e5d1 100755
--- a/src/ferm
+++ b/src/ferm
@@ -54,7 +54,7 @@ $VERSION .= '~git';
use vars qw(%option);
## hooks
-use vars qw(@pre_hooks @post_hooks @flush_hooks);
+use vars qw(%pre_hooks %post_hooks %flush_hooks);
## parser variables
# $script: current script file
@@ -521,29 +521,44 @@ die unless @stack == 2;
# enable/disable hooks depending on --flush
if ($option{flush}) {
- undef @pre_hooks;
- undef @post_hooks;
+ undef %pre_hooks;
+ undef %post_hooks;
} else {
- undef @flush_hooks;
+ undef %flush_hooks;
}
# execute all generated rules
my $status;
-foreach my $cmd (@pre_hooks) {
+# call global pre hooks
+foreach my $cmd (@{$pre_hooks{''}}) {
print LINES "$cmd\n" if $option{lines};
system($cmd) unless $option{noexec};
}
while (my ($domain, $domain_info) = each %domains) {
next unless $domain_info->{enabled};
+
+ # call domain-specific pre hooks
+ foreach my $cmd (@{$pre_hooks{$domain}}) {
+ print LINES "$cmd\n" if $option{lines};
+ system($cmd) unless $option{noexec};
+ }
+
my $s = $option{fast} &&
defined $domain_info->{tools}{'tables-restore'}
? execute_fast($domain_info) : execute_slow($domain_info);
$status = $s if defined $s;
+
+ # call domain-specific post/flush hooks
+ foreach my $cmd (@{$post_hooks{$domain}}, @{$flush_hooks{$domain}}) {
+ print LINES "$cmd\n" if $option{lines};
+ system($cmd) unless $option{noexec};
+ }
}
-foreach my $cmd (@post_hooks, @flush_hooks) {
+# call global post/flush hooks
+foreach my $cmd (@{$post_hooks{''}}, @{$flush_hooks{''}}) {
print LINES "$cmd\n" if $option{lines};
system($cmd) unless $option{noexec};
}
@@ -1593,21 +1608,22 @@ sub enter($$) {
if ($keyword eq '@hook') {
error('"hook" must be the first token in a command')
- if exists $rule{domain};
+ if (exists $rule{table});
+ my $domain = $rule{domain} ? $rule{domain} : '';
my $position = getvar();
my $hooks;
if ($position eq 'pre') {
- $hooks = \...@pre_hooks;
+ $hooks = \$pre_hooks{$domain};
} elsif ($position eq 'post') {
- $hooks = \...@post_hooks;
+ $hooks = \$post_hooks{$domain};
} elsif ($position eq 'flush') {
- $hooks = \...@flush_hooks;
+ $hooks = \$flush_hooks{$domain};
} else {
error("Invalid hook position: '$position'");
}
- push @$hooks, getvar();
+ push @{$$hooks}, getvar();
expect_token(';');
next;
--
1.6.5