Add usage

Add usage, improve GPL boilerplate, clean-ups
This commit is contained in:
Corwin Brust 2026-04-21 05:53:10 -05:00
parent c53c1299eb
commit 4ddef778c2

View file

@ -1,17 +1,37 @@
#!/usr/bin/perl -p #!/usr/bin/perl -p
#
# save-combine - filter and combine output from ipset(1) save # save-combine - filter and combine output from ipset(1) save
# Copyright (C)2026 Corwin Brust <corwin@bru.st>
# #
# (c)2026 Corwin Brust <corwin@bru.st> # 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 <https://www.gnu.org/licenses/>.
# #
# 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 # 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" # 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 # Input is expected on stdin in the same format as output by ipset save
# #
#################
sub usage {
my $message = shift;
$message .= "\n" if $message;
die <<END_OF_USAGE
${message}USAGE: ipset save >fil && \\
$0 [max-count-file] <fil
END_OF_USAGE
}
# return the first power of two larger than argument
sub max2 { sub max2 {
my $val = $_[0] || 1; my $val = $_[0] || 1;
my $rv = 2; my $rv = 2;
@ -19,36 +39,60 @@ sub max2 {
return $rv; return $rv;
} }
BEGIN { 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); my $SET_COUNTS = @ARGV ? shift : q(max-counts.txt);
open my$FH,q(<),$SET_COUNTS or die $!;
while(<$FH>) { 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; chomp;
my($k,$v)=split; my( $k, $v ) = split;
$m{$k}=max2( $v ) if $k and $v $m{ $k } = max2( $v )
if $k and $v
} }
} }
if(/^create (\S+)/) { if( /^create (\S+)/ )
if(exists $h{$1}) { {
$_ = ''; if( exists $h{$1} ) { # check if create issued
} elsif(exists $m{$1}) { $_ = ''; # don't print again
$h{$1} = 1; # don't reissue creates } elsif( exists $m{ $1 } ) {
$h{$1} = 1; # ensure this is the only printing
$n = $1; # grab the name $n = $1; # grab the name
$v = $m{$n}; # lookup max $v = $m{$n}; # lookup max
# mangle the create to inject maxelem from DB
s/^create $n (.*?maxelem) \d+ (.*)$/create $n $1 $v $2/ s/^create $n (.*?maxelem) \d+ (.*)$/create $n $1 $v $2/
and warn qq[set $n=$v] #and warn qq[set $n=$v]
} } else {
else {
$_ = ''; # skip create when no max defined $_ = ''; # skip create when no max defined
} }
} }
elsif(/^add (\S+)/) elsif( /^add (\S+)/ )
{ {
# $_ = '' unless exists $m{$1}; # $_ = '' unless exists $m{$1};
if (exists $m{$1}) { if (exists $m{$1}) {
s/$/ -exist/; # make dup-safe s/$/ -exist/; # make dup-safe
} else { } else {
$_ = ''; $_ = ''; # skip add for set we cannot create
} }
} }