#!/usr/bin/perl -w

# ipfw preprocessor with varibles and labels support
# v0.1 - initial version (22.04.2005)

# use like : '/sbin/ipfw -p ./ipfw-pre ./ipfw.rules'
# example rules:
=for example

if = fxp0
ports="110,25"
target = "me $ports"

add skipto END all from me to any
add pass all from any to ${target}
:END
add pass all from any to any

=cut



use strict;

my $incr_step = 10;
my $debug = 0;

my %vars;
my %labels;
my $rules;
my $num;

while (<>) {
	chomp;
	s!^\s+!!;
	s!\s+#.*$!!;
	next if m!^#|^$!;

	print STDERR ">$_\n" if $debug;

	# expand variables
	s!\$(?:(\w+)|{(\w+)})!
		print STDERR " VAR $+(= $vars{$+})\n" if $debug;
		$vars{$+};
	!ge;

	# translate variables definitations
	s!^(\w+)\s*=\s*(?:"([^"]*)"|(\S+))!
		print STDERR " DEF $1 => $+\n" if $debug;
		$vars{$1}=$+;
		"";
	!ge;

	# compute label linenumber
	s!^:(\w+)!
		if (defined $labels{$1}) {
			"# Duplicate label '$1' on line ". ($num + $incr_step);
		} else {
			$labels{$1} = $num + $incr_step;
			"# label $1 on line ". ($num + $incr_step);
		}
	!e;

	s!^add !
		$num += $incr_step;
		"add $num ";
	!ie;

	$rules .= "$_\n";
}

foreach (keys %labels) {
	$rules =~ s!skipto\s+$_! "skipto ".$labels{$_} !ge;
}

print STDERR $rules if $debug;
print $rules;
