<commit_before># firewall-lib.pl
# Functions for parsing iptables-save format files
# - help pages

BEGIN { push(@INC, ".."); };
use WebminCore;
&init_config();
if ($config{'save_file'}) {
	# Force use of a different save file, and webmin's functions
	$iptables_save_file = $config{'save_file'};
	}
else {
	if (-r "$module_root_directory/$gconfig{'os_type'}-lib.pl") {
		# Use the operating system's save file and functions
		do "$gconfig{'os_type'}-lib.pl";
		}

	if (!$iptables_save_file) {
		# Use webmin's own save file
		$iptables_save_file = "$module_config_directory/iptables.save";
		}
	}

%access = &get_module_acl();

@known_tables = ( "filter", "mangle", "nat" );
@known_args =   ('-p', '-m', '-s', '-d', '-i', '-o', '-f',
		 '--dport', '--sport', '--tcp-flags', '--tcp-option',
		 '--icmp-type', '--mac-source', '--limit', '--limit-burst',
		 '--ports', '--uid-owner', '--gid-owner',
		 '--pid-owner', '--sid-owner', '--state', '--tos', '-j',
		 '--to-ports', '--to-destination', '--to-source',
		 '--reject-with', '--dports', '--sports',
		 '--comment', '--physdev-is-bridged');

# get_iptables_save([file])
# Parse the iptables save file into a list of tables 
# format seems to be:
#  *table
#  :chain defaultpolicy
#  -A chain options
#  -N chain
#  COMMIT
sub get_iptables_save
{
local (@rv, $table, %got);
local $lnum = 0;
open(FILE, $_[0] || ($config{'direct'} ? "iptables-save 2>/dev/null |"
				       : $iptables_save_file));
local $cmt;
while(<FILE>) {
        local $read_comment;
	s/\r|\n//g;
	if (s/#\s*(.*)$//) {
		$cmt .= " " if ($cmt);
		$cmt .= $1;
		$read_comment=1;
		}
	if (/^\*(\S+)/) {
		# Start of a new table
		$got{$1}++;
		push(@rv, $table = { 'line' => $lnum,
				     'eline' => $lnum,
				     'name' => $1,
				     'rules' => [ ],
				     'defaults' => { } });
		}
	elsif (/^:(\S+)\s+(\S+)/) {
		# Default policy definition
		$table->{'defaults'}->{$1} = $2;
		}
	elsif (/^(\[[^\]]*\]\s+)?-N\s+(\S+)(.*)/) {
		# New chain definition
		$table->{'defaults'}->{$2} = '-';
		}
	elsif (/^(\[[^\]]*\]\s+)?-(AI)\s+(\S+)(.*)/) {
		# Rule definition
		local $rule = { 'line' => $lnum,
				'eline' => $lnum,
				'index' => scalar(@{$table->{'rules'}}),
				'cmt' => $cmt,
				'chain' => $3,
				'args' => $4 };
		if ($2 eq "I") {
			unshift(@{$table->{'rules'}}, $rule);
			}
		else {
			push(@{$table->{'rules'}}, $rule);
			}

		# Parse arguments
		foreach $a (@known_args) {
			local @vl;
			while($rule->{'args'} =~
			       s/\s+(!?)\s*($a)\s+(!?)\s*("[^"]*")(\s+|$)/ / ||<commit_msg>Fix iptables parsing<commit_after># firewall-lib.pl
# Functions for parsing iptables-save format files
# - help pages

BEGIN { push(@INC, ".."); };
use WebminCore;
&init_config();
if ($config{'save_file'}) {
	# Force use of a different save file, and webmin's functions
	$iptables_save_file = $config{'save_file'};
	}
else {
	if (-r "$module_root_directory/$gconfig{'os_type'}-lib.pl") {
		# Use the operating system's save file and functions
		do "$gconfig{'os_type'}-lib.pl";
		}

	if (!$iptables_save_file) {
		# Use webmin's own save file
		$iptables_save_file = "$module_config_directory/iptables.save";
		}
	}

%access = &get_module_acl();

@known_tables = ( "filter", "mangle", "nat" );
@known_args =   ('-p', '-m', '-s', '-d', '-i', '-o', '-f',
		 '--dport', '--sport', '--tcp-flags', '--tcp-option',
		 '--icmp-type', '--mac-source', '--limit', '--limit-burst',
		 '--ports', '--uid-owner', '--gid-owner',
		 '--pid-owner', '--sid-owner', '--state', '--tos', '-j',
		 '--to-ports', '--to-destination', '--to-source',
		 '--reject-with', '--dports', '--sports',
		 '--comment', '--physdev-is-bridged');

# get_iptables_save([file])
# Parse the iptables save file into a list of tables 
# format seems to be:
#  *table
#  :chain defaultpolicy
#  -A chain options
#  -N chain
#  COMMIT
sub get_iptables_save
{
local (@rv, $table, %got);
local $lnum = 0;
open(FILE, $_[0] || ($config{'direct'} ? "iptables-save 2>/dev/null |"
				       : $iptables_save_file));
local $cmt;
while(<FILE>) {
        local $read_comment;
	s/\r|\n//g;
	if (s/#\s*(.*)$//) {
		$cmt .= " " if ($cmt);
		$cmt .= $1;
		$read_comment=1;
		}
	if (/^\*(\S+)/) {
		# Start of a new table
		$got{$1}++;
		push(@rv, $table = { 'line' => $lnum,
				     'eline' => $lnum,
				     'name' => $1,
				     'rules' => [ ],
				     'defaults' => { } });
		}
	elsif (/^:(\S+)\s+(\S+)/) {
		# Default policy definition
		$table->{'defaults'}->{$1} = $2;
		}
	elsif (/^(\[[^\]]*\]\s+)?-N\s+(\S+)(.*)/) {
		# New chain definition
		$table->{'defaults'}->{$2} = '-';
		}
	elsif (/^(\[[^\]]*\]\s+)?-(A|I)\s+(\S+)(.*)/) {
		# Rule definition
		local $rule = { 'line' => $lnum,
				'eline' => $lnum,
				'index' => scalar(@{$table->{'rules'}}),
				'cmt' => $cmt,
				'chain' => $3,
				'args' => $4 };
		if ($2 eq "I") {
			unshift(@{$table->{'rules'}}, $rule);
			}
		else {
			push(@{$table->{'rules'}}, $rule);
			}

		# Parse arguments
		foreach $a (@known_args) {
			local @vl;
			while($rule->{'args'} =~
			       s/\s+(!?)\s*($a)\s+(!?)\s*("[^"]*")(\s+|$)/ / ||
{'fraction_non_alphanumeric': 0.2805456702253855, 'fraction_numerical': 0.005140371688414393, 'mean_word_length': 2.9065637065637064, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '84549', 'n_tokens_mistral': 2268, 'n_tokens_neox': 2052, 'n_words': 422}