From 4ddef778c2954df225dacfc918d295e48ed5fe83 Mon Sep 17 00:00:00 2001 From: corwin Date: Tue, 21 Apr 2026 05:53:10 -0500 Subject: [PATCH] Add usage Add usage, improve GPL boilerplate, clean-ups --- combine-saves.pl | 98 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 71 insertions(+), 27 deletions(-) diff --git a/combine-saves.pl b/combine-saves.pl index f93d3b5..4ae5ac8 100755 --- a/combine-saves.pl +++ b/combine-saves.pl @@ -1,17 +1,37 @@ #!/usr/bin/perl -p -# # save-combine - filter and combine output from ipset(1) save +# Copyright (C)2026 Corwin Brust # -# (c)2026 Corwin Brust +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . # -# You may use this program under the terms of the GNU Public License version three (3) or, at your option, any later version of that license. (GPLv3+) +################# # # Use a flat-file "DB" of ipset per row in the form NAME MAX -# Drop create/add lines for any set not mentioned in the DB # Take DB file-name from first program arg, otherwise "ipset-counts.txt" +# Drop create/add lines for any set not mentioned in the DB # Input is expected on stdin in the same format as output by ipset save # +################# +sub usage { + my $message = shift; + $message .= "\n" if $message; + die <fil && \\ + $0 [max-count-file] ) { - chomp; - my($k,$v)=split; - $m{$k}=max2( $v ) if $k and $v - } +BEGIN # program is a filter so we must wrap start-up processing +{ + # avoid extra "BEGIN faile--" messages + local $SIG{__DIE__} = sub {warn @_; exit 1}; + + # display usage if requested + usage() if grep /^-+[?h]/, @ARGV; + + # and unless we have input + die usage( + qq(ERROR: STDIN is non a pipe or redirection) + ) if -t STDIN; + + # take max-count-file from args, if any + my $SET_COUNTS = @ARGV ? shift : q(max-counts.txt); + + open my$FH,q(<),$SET_COUNTS + or usage( + q(ERROR: cannot open max-count-file) + . qq( "$SET_COUNTS": $!) + . ' ('.(0+$!).')' + ); + + # load hash of set => max + while(<$FH>) + { + chomp; + my( $k, $v ) = split; + $m{ $k } = max2( $v ) + if $k and $v + } } -if(/^create (\S+)/) { - if(exists $h{$1}) { - $_ = ''; - } elsif(exists $m{$1}) { - $h{$1} = 1; # don't reissue creates - $n = $1; # grab the name - $v = $m{$n}; # lookup max - s/^create $n (.*?maxelem) \d+ (.*)$/create $n $1 $v $2/ - and warn qq[set $n=$v] - } - else { - $_ = ''; # skip create when no max defined - } +if( /^create (\S+)/ ) +{ + if( exists $h{$1} ) { # check if create issued + $_ = ''; # don't print again + } elsif( exists $m{ $1 } ) { + $h{$1} = 1; # ensure this is the only printing + $n = $1; # grab the name + $v = $m{$n}; # lookup max + # mangle the create to inject maxelem from DB + s/^create $n (.*?maxelem) \d+ (.*)$/create $n $1 $v $2/ + #and warn qq[set $n=$v] + } else { + $_ = ''; # skip create when no max defined + } } -elsif(/^add (\S+)/) +elsif( /^add (\S+)/ ) { # $_ = '' unless exists $m{$1}; if (exists $m{$1}) { s/$/ -exist/; # make dup-safe } else { - $_ = ''; + $_ = ''; # skip add for set we cannot create } }