include $(IPTABLES_APPS_DIR)/common.mk

ifeq ($(strip $(IPTABLES_APPS_EXT_OPTIONS)),)
$(error You must specify IPTABLES_APPS_EXT_OPTIONS first)
endif

ifeq ($(strip $(IPTABLES_APPS_EXT_XT_OPTIONS)),)
$(error You must specify IPTABLES_APPS_EXT_XT_OPTIONS first)
endif

ifneq ($(strip $(IPTABLES_APPS_IPV6_SUPPORT)),0)
ifeq ($(strip $(IPTABLES_APPS_EXT6_OPTIONS)),)
$(error You must specify IPTABLES_APPS_EXT6_OPTIONS first)
endif
endif

APPL_SUB_BLDDIR := $(IPTABLES_APPS_BLDDIR)/extensions

PF_EXT_SLIB := $(IPTABLES_APPS_EXT_OPTIONS)
PF6_EXT_SLIB := $(IPTABLES_APPS_EXT6_OPTIONS)
PFX_EXT_SLIB := $(IPTABLES_APPS_EXT_XT_OPTIONS)
PF_EXT_ALL_SLIB := $(PF_EXT_SLIB)
PF6_EXT_ALL_SLIB := $(PF6_EXT_SLIB)
PFX_EXT_ALL_SLIB := $(PFX_EXT_SLIB)

# libipt*.c with libipt*.man
PF_EXT_MAN_ALL_MATCHES := $(foreach T,$(PF_EXT_ALL_SLIB),$(shell test -f libipt_$(T).man && grep -q register_match libipt_$(T).c  && echo $(T)))
PF_EXT_MAN_ALL_TARGETS := $(foreach T,$(PF_EXT_ALL_SLIB),$(shell test -f libipt_$(T).man && grep -q register_target libipt_$(T).c && echo $(T)))
PF6_EXT_MAN_ALL_MATCHES := $(foreach T,$(PF6_EXT_ALL_SLIB),$(shell test -f libip6t_$(T).man && grep -q register_match6 libip6t_$(T).c  && echo $(T)))
PF6_EXT_MAN_ALL_TARGETS := $(foreach T,$(PF6_EXT_ALL_SLIB),$(shell test -f libip6t_$(T).man && grep -q register_target6 libip6t_$(T).c && echo $(T)))

# libxt*.c with libipt*.man
PF_EXT_MAN_ALL_MATCHES += $(foreach T,$(PFX_EXT_ALL_SLIB),$(shell test -f libipt_$(T).man && grep -q xtables_register_match libxt_$(T).c  && echo $(T)))
PF_EXT_MAN_ALL_TARGETS += $(foreach T,$(PFX_EXT_ALL_SLIB),$(shell test -f libipt_$(T).man && grep -q xtables_register_target libxt_$(T).c && echo $(T)))
PF6_EXT_MAN_ALL_MATCHES += $(foreach T,$(PFX_EXT_ALL_SLIB),$(shell test -f libip6t_$(T).man && grep -q xtables_register_match libxt_$(T).c  && echo $(T)))
PF6_EXT_MAN_ALL_TARGETS += $(foreach T,$(PFX_EXT_ALL_SLIB),$(shell test -f libip6t_$(T).man && grep -q xtables_register_target libxt_$(T).c && echo $(T)))

# libxt*.c with libxt*.man
PFX_EXT_MAN_ALL_MATCHES := $(foreach T,$(PFX_EXT_ALL_SLIB),$(shell test -f libxt_$(T).man && grep -q xtables_register_match libxt_$(T).c  && echo $(T)))
PFX_EXT_MAN_ALL_TARGETS := $(foreach T,$(PFX_EXT_ALL_SLIB),$(shell test -f libxt_$(T).man && grep -q xtables_register_target libxt_$(T).c && echo $(T)))

# libipt*.man
PF_EXT_MAN_MATCHES := $(filter $(PF_EXT_SLIB), $(PF_EXT_MAN_ALL_MATCHES))
PF_EXT_MAN_MATCHES += $(filter $(PFX_EXT_SLIB), $(PF_EXT_MAN_ALL_MATCHES))
PF_EXT_MAN_MATCHES += $(filter $(PF_EXT_SE_SLIB), $(PF_EXT_MAN_ALL_MATCHES))
PF_EXT_MAN_MATCHES += $(filter $(PFX_EXT_SE_SLIB), $(PF_EXT_MAN_ALL_MATCHES))

# libipt*.man
PF_EXT_MAN_TARGETS := $(filter $(PF_EXT_SLIB), $(PF_EXT_MAN_ALL_TARGETS))
PF_EXT_MAN_TARGETS += $(filter $(PFX_EXT_SLIB), $(PF_EXT_MAN_ALL_TARGETS))
PF_EXT_MAN_TARGETS += $(filter $(PF_EXT_SE_SLIB), $(PF_EXT_MAN_ALL_TARGETS))
PF_EXT_MAN_TARGETS += $(filter $(PFX_EXT_SE_SLIB), $(PF_EXT_MAN_ALL_TARGETS))

# libipt*.man
PF_EXT_MAN_EXTRA_MATCHES := $(filter-out $(PF_EXT_MAN_MATCHES), $(PF_EXT_MAN_ALL_MATCHES))
PF_EXT_MAN_EXTRA_TARGETS := $(filter-out $(PF_EXT_MAN_TARGETS), $(PF_EXT_MAN_ALL_TARGETS))

# libip6t*.man
PF6_EXT_MAN_MATCHES := $(filter $(PF6_EXT_SLIB), $(PF6_EXT_MAN_ALL_MATCHES))
PF6_EXT_MAN_MATCHES += $(filter $(PFX_EXT_SLIB), $(PF6_EXT_MAN_ALL_MATCHES))

# libip6t*.man
PF6_EXT_MAN_TARGETS := $(filter $(PF6_EXT_SLIB), $(PF6_EXT_MAN_ALL_TARGETS))
PF6_EXT_MAN_TARGETS += $(filter $(PFX_EXT_SLIB), $(PF6_EXT_MAN_ALL_TARGETS))

# libip6t*.man
PF6_EXT_MAN_EXTRA_MATCHES := $(filter-out $(PF6_EXT_MAN_MATCHES), $(PF6_EXT_MAN_ALL_MATCHES))
PF6_EXT_MAN_EXTRA_TARGETS := $(filter-out $(PF6_EXT_MAN_TARGETS), $(PF6_EXT_MAN_ALL_TARGETS))

# libxt*.man
PFX_EXT_MAN_MATCHES := $(filter $(PFX_EXT_SLIB), $(PFX_EXT_MAN_ALL_MATCHES))
PFX_EXT_MAN_TARGETS := $(filter $(PFX_EXT_SLIB), $(PFX_EXT_MAN_ALL_TARGETS))

# libxt*.man
PFX_EXT_MAN_EXTRA_MATCHES := $(filter-out $(PFX_EXT_MAN_MATCHES), $(PFX_EXT_MAN_ALL_MATCHES))
PFX_EXT_MAN_EXTRA_TARGETS := $(filter-out $(PFX_EXT_MAN_TARGETS), $(PFX_EXT_MAN_ALL_TARGETS))

# extra man pages requires this (really _A_ll)
PFA4_EXT_MAN_EXTRA_MATCHES := $(PF_EXT_MAN_EXTRA_MATCHES) $(PFX_EXT_MAN_EXTRA_MATCHES)
PFA4_EXT_MAN_EXTRA_TARGETS := $(PF_EXT_MAN_EXTRA_TARGETS) $(PFX_EXT_MAN_EXTRA_TARGETS)
PFA6_EXT_MAN_EXTRA_MATCHES := $(PF6_EXT_MAN_EXTRA_MATCHES) $(PFX_EXT_MAN_EXTRA_MATCHES)
PFA6_EXT_MAN_EXTRA_TARGETS := $(PF6_EXT_MAN_EXTRA_TARGETS) $(PFX_EXT_MAN_EXTRA_TARGETS)

EXT_OBJS := $(foreach T,$(PF_EXT_SLIB),$(APPL_SUB_BLDDIR)/libipt_$(T).o)
EXT_OBJS += $(foreach T,$(PFX_EXT_SLIB),$(APPL_SUB_BLDDIR)/libxt_$(T).o)
EXT_FUNC += $(foreach T,$(PF_EXT_SLIB),ipt_$(T))
EXT_FUNC += $(foreach T,$(PFX_EXT_SLIB),xt_$(T))
EXT_BOBJS := $(EXT_OBJS)
EXT_BOBJS += $(APPL_SUB_BLDDIR)/initext.o
ifneq ($(strip $(IPTABLES_APPS_IPV6_SUPPORT)),0)
EXT6_OBJS := $(foreach T,$(PF6_EXT_SLIB),$(APPL_SUB_BLDDIR)/libip6t_$(T).o)
EXT6_OBJS += $(foreach T,$(PFX_EXT_SLIB),$(APPL_SUB_BLDDIR)/libxt_$(T).o)
EXT6_FUNC += $(foreach T,$(PF6_EXT_SLIB),ip6t_$(T))
EXT6_FUNC += $(foreach T,$(PFX_EXT_SLIB),xt_$(T))
EXT6_BOBJS := $(EXT6_OBJS)
EXT6_BOBJS += $(APPL_SUB_BLDDIR)/initext6.o
endif

SO_LIB := $(APPL_SUB_BLDDIR)/libipt_ext.so
ifneq ($(strip $(IPTABLES_APPS_IPV6_SUPPORT)),0)
SO_LIB += $(APPL_SUB_BLDDIR)/libipt_ext6.so
endif
STATIC_LIB := $(foreach T,$(SO_LIB),$(basename $(T))_pic.a)

all: $(SO_LIB) $(STATIC_LIB)
	@echo 'ALL_SLIB (IPv4):' $(PF_EXT_ALL_SLIB)
	@echo 'ALL_SLIB (IPv6):' $(PF6_EXT_ALL_SLIB)
	@echo 'ALL_SLIB (both):' $(PFX_EXT_ALL_SLIB)
	@echo 'ALL_MATCH (IPv4):' $(PF_EXT_MAN_ALL_MATCHES)
	@echo 'ALL_MATCH (IPv6):' $(PF6_EXT_MAN_ALL_MATCHES)
	@echo 'ALL_MATCH (both):' $(PFX_EXT_MAN_ALL_MATCHES)
	@echo 'ALL_TARGET (IPv4):' $(PF_EXT_MAN_ALL_TARGETS)
	@echo 'ALL_TARGET (IPv6):' $(PF6_EXT_MAN_ALL_TARGETS)
	@echo 'ALL_TARGET (both):' $(PFX_EXT_MAN_ALL_TARGETS)
	
$(APPL_SUB_BLDDIR)/libipt_ext.so: $(EXT_BOBJS)
	@$(CC) -shared -Wl,-soname,$(notdir $@) $(CFLAGS) -o $@ $^
	
$(APPL_SUB_BLDDIR)/libipt_ext6.so: $(EXT6_BOBJS)
	@$(CC) -shared -Wl,-soname,$(notdir $@) $(CFLAGS) -o $@ $^

$(APPL_SUB_BLDDIR)/libipt_ext_pic.a: $(EXT_BOBJS)
	@$(AR) rcs $@ $^
	@$(RANLIB) $@

$(APPL_SUB_BLDDIR)/libipt_ext6_pic.a: $(EXT6_BOBJS)
	@$(AR) rcs $@ $^
	@$(RANLIB) $@

$(APPL_SUB_BLDDIR)/initext.o: $(APPL_SUB_BLDDIR)/initext.c
$(APPL_SUB_BLDDIR)/initext6.o: $(APPL_SUB_BLDDIR)/initext6.c

$(APPL_SUB_BLDDIR)/initext.c: Makefile
	-@if [ ! -d $(APPL_SUB_BLDDIR)  ]; then mkdir -p $(APPL_SUB_BLDDIR); fi
	echo "" > $@
	for i in $(EXT_FUNC); do \
		echo "extern void $${i}_init(void);" >> $@; \
	done
	echo "void init_extensions(void) {" >> $@
	for i in $(EXT_FUNC); do \
		echo "	$${i}_init();" >> $@; \
	done
	echo "}" >> $@

$(APPL_SUB_BLDDIR)/initext6.c: Makefile
	-@if [ ! -d $(APPL_SUB_BLDDIR)  ]; then mkdir -p $(APPL_SUB_BLDDIR); fi
	echo "" > $@
	for i in $(EXT6_FUNC); do \
		echo "extern void $${i}_init(void);" >> $@; \
	done
	echo "void init_extensions(void) {" >> $@
	for i in $(EXT6_FUNC); do \
		echo "	$${i}_init();" >> $@; \
	done
	echo "}" >> $@

$(APPL_SUB_BLDDIR)/lib%.o: lib%.c
	@echo "Compiling $<"
	@$(CC) $(CFLAGS) -D_INIT=$*_init -c -o $@ $<
	
clean:
	@rm -f $(EXT_OBJS:.o=.d)
	@rm -f $(EXT_BOBJS)
	@rm -f $(APPL_SUB_BLDDIR)/initext.c
	@rm -f $(EXT6_OBJS:.o=.d)
	@rm -f $(EXT6_BOBJS)
	@rm -f $(APPL_SUB_BLDDIR)/initext6.c
	@rm -f $(APPL_SUB_BLDDIR)/libipt_ext_pic.a
	@rm -f $(APPL_SUB_BLDDIR)/libipt_ext6_pic.a
	@rm -f $(APPL_SUB_BLDDIR)/libipt_ext.so
	@rm -f $(APPL_SUB_BLDDIR)/libipt_ext6.so

ifeq (,$(findstring clean,$(MAKECMDGOALS)))
-include $(addsuffix .d,$(basename $(EXT_OBJS)))
ifneq ($(strip $(IPTABLES_APPS_IPV6_SUPPORT)),0)
-include $(addsuffix .d,$(basename $(EXT6_OBJS)))
endif
$(APPL_SUB_BLDDIR)/%.d: %.c
	-@if [ ! -d $(APPL_SUB_BLDDIR)  ]; then mkdir -p $(APPL_SUB_BLDDIR); fi
	@$(CC) -M $(CFLAGS) $< >$@.tmp; \
	echo "$@ \\" > $@; \
	sed 's,\($*\)\.o[ :]*,$$(APPL_SUB_BLDDIR)\/\1.o: ,g' < $@.tmp >> $@; \
	rm -f $@.tmp
endif
 
EXTRAS += extensions/libipt_targets.man
extensions/libipt_targets.man: $(patsubst %,extensions/libipt_%.man,$(PF_EXT_MAN_ALL_TARGETS)) $(patsubst %,extensions/libxt_%.man,$(PFX_EXT_MAN_ALL_TARGETS))
	@for ext in `echo $(PF_EXT_MAN_TARGETS) $(PFX_EXT_MAN_TARGETS) | sed 's/ /\n/g' | sort`; do \
	    echo ".SS $$ext" ;\
	    if test -f extensions/libipt_$$ext.man; then \
		cat extensions/libipt_$$ext.man ;\
	    else \
		cat extensions/libxt_$$ext.man ;\
	    fi; \
	done >extensions/libipt_targets.man
	@if [ -n "$(PFA4_EXT_MAN_EXTRA_TARGETS)" ]; then \
	    extra="$(PFA4_EXT_MAN_EXTRA_TARGETS)" ;\
	    for ext in `echo $${extra:-""} | sed 's/ /\n/g' | sort`; do \
		echo ".SS $$ext (not supported, see Patch-O-Matic)" ;\
		if test -f extensions/libipt_$$ext.man; then \
		    cat extensions/libipt_$$ext.man ;\
		else \
		    cat extensions/libxt_$$ext.man ;\
		fi; \
	    done ;\
       	fi >>extensions/libipt_targets.man

EXTRAS += extensions/libipt_matches.man
extensions/libipt_matches.man: $(patsubst %,extensions/libipt_%.man,$(PF_EXT_MAN_ALL_MATCHES)) $(patsubst %,extensions/libxt_%.man,$(PFX_EXT_MAN_ALL_MATCHES))
	@for ext in `echo $(PF_EXT_MAN_MATCHES) $(PFX_EXT_MAN_MATCHES) | sed 's/ /\n/g' | sort`; do \
	    echo ".SS $$ext" ;\
	    if test -f extensions/libipt_$$ext.man; then \
		cat extensions/libipt_$$ext.man ;\
	    else \
		cat extensions/libxt_$$ext.man ;\
	    fi; \
	done >extensions/libipt_matches.man
	@if [ -n "$(PFA4_EXT_MAN_EXTRA_MATCHES)" ]; then \
	    extra="$(PFA4_EXT_MAN_EXTRA_MATCHES)" ;\
	    for ext in `echo $${extra:-""} | sed 's/ /\n/g' | sort`; do \
		echo ".SS $$ext (not supported, see Patch-O-Matic)" ;\
		if test -f extensions/libipt_$$ext.man; then \
		    cat extensions/libipt_$$ext.man ;\
		else \
		    cat extensions/libxt_$$ext.man ;\
		fi; \
	    done ;\
       	fi >>extensions/libipt_matches.man

EXTRAS += extensions/libip6t_targets.man
extensions/libip6t_targets.man: $(patsubst %, extensions/libip6t_%.man, $(PF6_EXT_MAN_ALL_TARGETS)) $(patsubst %,extensions/libxt_%.man,$(PFX_EXT_MAN_ALL_TARGETS))
	@for ext in `echo $(PF6_EXT_MAN_TARGETS) $(PFX_EXT_MAN_TARGETS) | sed 's/ /\n/g' | sort`; do \
	    echo ".SS $$ext" ;\
	    if test -f extensions/libip6t_$$ext.man; then \
		cat extensions/libip6t_$$ext.man ;\
	    else \
		cat extensions/libxt_$$ext.man ;\
	    fi; \
	done >extensions/libip6t_targets.man
	@if [ -n "$(PFA6_EXT_MAN_EXTRA_TARGETS)" ]; then \
	    extra="$(PFA6_EXT_MAN_EXTRA_TARGETS)" ;\
	    for ext in `echo $${extra:-""} | sed 's/ /\n/g' | sort`; do \
		echo ".SS $$ext (not supported, see Patch-O-Matic)" ;\
		if test -f extensions/libip6t_$$ext.man; then \
		    cat extensions/libip6t_$$ext.man ;\
		else \
		    cat extensions/libxt_$$ext.man ;\
		fi; \
	    done ;\
       	fi >>extensions/libip6t_targets.man

EXTRAS += extensions/libip6t_matches.man
extensions/libip6t_matches.man: $(patsubst %, extensions/libip6t_%.man, $(PF6_EXT_MAN_ALL_MATCHES)) $(patsubst %,extensions/libxt_%.man,$(PFX_EXT_MAN_ALL_MATCHES))
	@for ext in `echo $(PF6_EXT_MAN_MATCHES) $(PFX_EXT_MAN_MATCHES) | sed 's/ /\n/g' | sort`; do \
	    echo ".SS $$ext" ;\
	    if test -f extensions/libip6t_$$ext.man; then \
		cat extensions/libip6t_$$ext.man ;\
	    else \
		cat extensions/libxt_$$ext.man ;\
	    fi; \
	done >extensions/libip6t_matches.man
	@if [ -n "$(PFA6_EXT_MAN_EXTRA_MATCHES)" ]; then \
	    extra="$(PFA6_EXT_MAN_EXTRA_MATCHES)" ;\
	    for ext in `echo $${extra:-""} | sed 's/ /\n/g' | sort`; do \
		echo ".SS $$ext (not supported, see Patch-O-Matic)" ;\
		if test -f extensions/libip6t_$$ext.man; then \
		    cat extensions/libip6t_$$ext.man ;\
		else \
		    cat extensions/libxt_$$ext.man ;\
		fi; \
	    done ;\
       	fi >>extensions/libip6t_matches.man
