From f9b1fb2b171bb8d460a2c72adfe3c3d18002cff1 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 30 Mar 2016 12:22:20 +0200 Subject: [PATCH] add function @glob --- Makefile | 1 + NEWS | 2 +- doc/ferm.pod | 10 ++++++++++ src/ferm | 22 +++++++++++++++++++++- test/glob/abc.foo | 0 test/glob/bar.include | 1 + test/glob/def.foo | 0 test/glob/foo.include | 1 + test/glob/glob.ferm | 6 ++++++ test/glob/glob.result | 4 ++++ 10 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 test/glob/abc.foo create mode 100644 test/glob/bar.include create mode 100644 test/glob/def.foo create mode 100644 test/glob/foo.include create mode 100644 test/glob/glob.ferm create mode 100644 test/glob/glob.result diff --git a/Makefile b/Makefile index 2897420..b188448 100644 --- a/Makefile +++ b/Makefile @@ -48,6 +48,7 @@ STAMPDIR_20 = $(TOPDIR)/build/test2 FERM_SCRIPTS = FERM_SCRIPTS += $(wildcard test/modules/*.ferm) $(wildcard test/targets/*.ferm) FERM_SCRIPTS += $(wildcard test/protocols/*.ferm) $(wildcard test/misc/*.ferm) +FERM_SCRIPTS += $(wildcard test/glob/*.ferm) FERM_SCRIPTS += $(wildcard test/ipv6/*.ferm) FERM_SCRIPTS += $(wildcard test/arptables/*.ferm) $(wildcard test/ebtables/*.ferm) diff --git a/NEWS b/NEWS index be7dfaf..8418bd5 100644 --- a/NEWS +++ b/NEWS @@ -8,7 +8,7 @@ v2.2.1 - not yet released - - new function @defined + - new functions @defined, @glob - support netfilter match modules: * bpf * connlabel diff --git a/doc/ferm.pod b/doc/ferm.pod index f721736..8d0327d 100644 --- a/doc/ferm.pod +++ b/doc/ferm.pod @@ -1689,6 +1689,10 @@ directory are included, sorted alphabetically: @include 'ferm.d/'; +The function @glob can be used to expand wild cards: + + @include @glob('*.include'); + With a trailing pipe symbol, B executes a shell command and parses its output: @@ -1825,6 +1829,12 @@ Return the base name of the file for a given path Return the name of the last directory for a given path, assuming the last component is a file name (File::Spec::splitpath). +=head2 @glob(path) + +Expand shell wildcards in the given paths (assumed to be relative to +the current script). Returns a list of matching files. This function +is useful as parameter of @include. + =head2 @ipfilter(list) Filters out the IP addresses that obviously do not match the current diff --git a/src/ferm b/src/ferm index 7cdcae4..199379d 100755 --- a/src/ferm +++ b/src/ferm @@ -1328,6 +1328,22 @@ sub getvalues { error('String expected') if ref $params[0]; my($volume,$path,$file) = File::Spec->splitpath( $params[0] ); return $path; + } elsif ($token eq '@glob') { + my @params = get_function_params(); + error('Usage: @glob(string)') unless @params == 1; + + # determine the current script's parent directory for relative + # file names + die unless defined $script; + my $parent_dir = $script->{filename} =~ m,^(.*/), + ? $1 : './'; + + my @result = map { + my $path = $_; + $path = $parent_dir . $path unless $path =~ m,^/,; + glob($path); + } to_array($params[0]); + return @result == 1 ? $result[0] : \@result; } elsif ($token eq '@ipfilter') { my @params = get_function_params(); error('Usage: @ipfilter((ip1 ip2 ...))') unless @params == 1; @@ -1963,7 +1979,11 @@ sub enter($$) { # include another file if ($keyword eq '@include' or $keyword eq 'include') { - my @files = collect_filenames to_array getvalues; + # don't call collect_filenames() if the file names + # have been expanded already by @glob() + my @files = peek_token() eq '@glob' + ? to_array(getvalues) + : collect_filenames(to_array(getvalues)); $keyword = next_token; error('Missing ";" - "include FILENAME" must be the last command in a rule') unless defined $keyword and $keyword eq ';'; diff --git a/test/glob/abc.foo b/test/glob/abc.foo new file mode 100644 index 0000000..e69de29 diff --git a/test/glob/bar.include b/test/glob/bar.include new file mode 100644 index 0000000..2caf236 --- /dev/null +++ b/test/glob/bar.include @@ -0,0 +1 @@ +chain FORWARD proto udp ACCEPT; diff --git a/test/glob/def.foo b/test/glob/def.foo new file mode 100644 index 0000000..e69de29 diff --git a/test/glob/foo.include b/test/glob/foo.include new file mode 100644 index 0000000..beef446 --- /dev/null +++ b/test/glob/foo.include @@ -0,0 +1 @@ +chain FORWARD proto tcp REJECT; diff --git a/test/glob/glob.ferm b/test/glob/glob.ferm new file mode 100644 index 0000000..66a3fb4 --- /dev/null +++ b/test/glob/glob.ferm @@ -0,0 +1,6 @@ +chain INPUT { + saddr @glob('*.foo') ACCEPT; + daddr @glob('doesnt_exist.*') ACCEPT; +} + +@include @glob('*.include'); diff --git a/test/glob/glob.result b/test/glob/glob.result new file mode 100644 index 0000000..0d5b29e --- /dev/null +++ b/test/glob/glob.result @@ -0,0 +1,4 @@ +iptables -t filter -A INPUT -s test/glob/abc.foo -j ACCEPT +iptables -t filter -A INPUT -s test/glob/def.foo -j ACCEPT +iptables -t filter -A FORWARD -p udp -j ACCEPT +iptables -t filter -A FORWARD -p tcp -j REJECT -- 2.11.4.GIT