#!/usr/bin/perl
# modulify v1.0.3  (c) 31.8.2011 by Andreas Ley  (u) 25.2.2026
# Add appropriate IfModule directives

# Old: https://metacpan.org/release/NWIGER/Apache-ConfigFile-1.23
# Use: https://packages.debian.org/search?keywords=libapache-admin-config-perl&arch=amd64

use Getopt::Std;

$modules = '/etc/apache2/myapacheconf.modules';
$phpini_directives = '/etc/apache2/myapacheconf.phpini.directives';
#$php_fpm_pools = '/etc/php/7.3/fpm/pool.d';
my $php_version = readlink('/etc/alternatives/php') =~ s/^\/usr\/bin\/php//r;
$php_fpm_pools = "/etc/php/${php_version}/fpm/pool.d";

if (-d $php_fpm_pools) {
	for my $key (keys %valid) {
		if ($key =~ /^php_/) {
			delete $valid{$key};
			$invalid{$key} = undef;
		}
	}
}

sub usage
{
	my $image = $0;
	$image =~ s!.*/!!;
	print STDERR "Usage: $image [-m] [-f] [filename]\n";
	print STDERR "-m  Replace source file in IfModule by module identifier\n";
	print STDERR "-f  force (ignore unknown directives)\n";
	exit(1);
}

getopts('TDL:hxvmf') or &usage;

# Compile check
exit(0) if (defined($opt_T));

&usage if (defined($opt_h) || $#ARGV > 0);

$opt_D = $opt_L if (defined($opt_L));
if (defined($opt_v) || defined($opt_D)) {
	$|=1;
	select((select(STDERR),$|=1)[0]);
}

open(MODULES,$modules) or die "Can't read $modules: $!\n";
while (<MODULES>) {
	chomp;
	my ($directive,$module_identifier,$source_file) = split;
	$module_identifier{lc($directive)} = $module_identifier;
	$source_file{lc($directive)} = $source_file;
	$source_to_identifier{$source_file} = $module_identifier;
}
close(MODULES);

unless (-d $php_fpm_pools) {
	open(PHPINI_DIRECTIVES,$phpini_directives) or die "Can't read $phpini_directives: $!\n";
	while (<PHPINI_DIRECTIVES>) {
		chomp;
		$phpini_valid{lc($_)} = '';
	}
	close(PHPINI_DIRECTIVES);
}
	
################################################################################
#
# Parse input configuration
#

my $at = " $ARGV[0]" unless ($#ARGV <0);
my ($config,$module,@modules);
while (<>) {
	# FIXME: Handle continuation lines
	chomp;
	warn "\"$_\"" if ($opt_D>2);
	s/\s+$//;
	# Does this look like a directive?
	# Comments can't be placed on the same line as directives, so no need to trim them first
	# http://httpd.apache.org/docs/2.2/configuring.html#syntax
	if (/^\s*([^#\s]\S*)\s*/) {
		my $directive = $1;
		$directive = $1 if ($directive =~ /^(<[^\/]\S*)>$/);
		my $lc_directive = lc($directive);
		warn "[$.] \"$lc_directive\"" if ($opt_D>1);
		if (/^(\s*<IfModule\s+)(\S+)(>)$/i) {
			warn "$2: \"$_\"" if ($opt_D);
			push(@modules,defined($source_to_identifier{$2})?$source_to_identifier{$2}:$2);
			$_ = $1.$source_to_identifier{$2}.$3 if (defined($opt_m) && defined($source_to_identifier{$2}));
		}
		elsif ($lc_directive eq '</ifmodule>') {
			pop(@modules);
		}
		elsif (!$opt_f && !exists($module_identifier{$lc_directive})) {
			die "Invalid directive '$directive' at$at line $..\nSee $url.\n";
		}
		# Directive has passed all tests
		warn $module_identifier{$lc_directive},": ",join(',',@modules),"" if ($opt_D);
		unless (grep($_ eq $module_identifier{$lc_directive},@modules,$module)) {
			$config .= "</IfModule>\n" if (defined($module));
			$module = $module_identifier{$lc_directive};
			$config .= "<IfModule $module>\n" if (defined($module));
		}
	}
	$config .= $_."\n";
}
$config .= "</IfModule>\n" if (defined($module));

print $config;
