/*
 * pfanchordrill
 *
 * part of pfSense (https://www.pfsense.org)
 * Copyright (c) 2016 Electric Sheep Fencing
 * Copyright (c) 2016-2026 Rubicon Communications, LLC (Netgate)
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/* Recursively check anchors for rules/nat and also for anchors inside anchors (like those used by UPnP) */

include_once('globals.inc');

function wrap_comment(string $comment, bool $add_header = false): string {
	$text = explode("\n", wordwrap($comment));
	array_walk($text, function (&$string) {
		$string = "# {$string}";
	});
	$header_wrap = str_pad('', max(array_map('strlen', $text)), '#');
	$text = implode(PHP_EOL, $text);
	if (!$add_header) {
		return $text;
	}
	$text = $header_wrap . PHP_EOL . $text . PHP_EOL . $header_wrap;
	return $text;
}

function anchor_list() {
	$anchor_rules = [
		'ethernet' => [],
		'translation' => [],
		'filter' => [],
	];
	$result = [];

	exec("/sbin/pfctl -a '*' -se 2>/dev/null", $anchor_rules['ethernet']);
	exec("/sbin/pfctl -a '*' -sn 2>/dev/null", $anchor_rules['translation']);
	exec("/sbin/pfctl -a '*' -sr 2>/dev/null", $anchor_rules['filter']);

	foreach ($anchor_rules as $type => &$rules) {
		$add_header = true;
		foreach ($rules as &$rule) {
			if (empty($rule)) {
				continue;
			}
			if (!str_starts_with($rule, ' ') &&
				!str_starts_with($rule, '}') &&
				!str_ends_with($rule, '{')) {
				continue;
			}
			if ($add_header) {
				$result[] = wrap_comment("{$type} rules", true);
				$add_header = false;
			}
			$result[] = &$rule;
		}
	}

	print(implode(PHP_EOL, $result));
}

anchor_list();
print(PHP_EOL);
