#!/bin/sh

pfctl="/sbin/pfctl"

if [ $(/usr/bin/id -u) -ne 0 ]
then
        echo "Mortal user detected! Begging for root privs!"
        exec /usr/bin/su ${0} ${*}
fi

verbose="" # Default verbosity

# Parse command line
while [ -n "${1}" ]
do
        case "${1}" in
        -v)     # Louder!
                verbose="-v"
                ;;
        -q)     # Shh.. Quiet!
                verbose="-q"
                ;;
        *)
                file="${*}"
                break
                ;;
        esac
        shift
done

if [ ! -f "${file}" ]
then
        echo "Usage: $(/usr/bin/basename ${0}) {file.pf|file.table|file.list}"
        exit 64
fi

flush_pf(){
        # Compute anchor point and insert ruleset
        anchor="dynamic/$(/usr/bin/basename "${1}" .pf)"
        [ "${verbose}" = "-v" ] && echo pfctl -a "${anchor}" -F all
        pfctl ${verbose} -a "${anchor}" -F all
}

flush_table(){
        # Compute tablename and load IP list into table
        table="$(/usr/bin/basename "${1}" .table)"
        [ "${verbose}" = "-v" ] && echo pfctl -t "${table}" -T flush
        pfctl ${verbose} -t "${table}" -T flush
}

unload_list(){
        # Iterate through the lines in the list and load each rule file and table
        cmd="$(/bin/realpath "${0}")"
        cd "$(/usr/bin/dirname "$(/bin/realpath "${1}")")"
        /bin/cat "${1}" | sed -e 's@#.*@@' | while read line
        do
                if [ -f "${line}" ]
                then
                        "${cmd}" ${verbose} "${line}"
                fi
        done
}

case "${file}" in
*.pf)
        [ "${verbose}" != "-q" ] && echo "Flushing ruleset from $(/usr/bin/basename "${file}")"
        flush_pf "${file}"
        # Look for a table definition with the same name, for auto loading
        table="$(/usr/bin/dirname "${file}")/$(/usr/bin/basename "${file}" .pf).table"
        [ -f "${table}" ] && flush_table "${table}"
        ;;
*.table)
        [ "${verbose}" != "-q" ] && echo "Flushing table from $(/usr/bin/basename "${file}")"
        flush_table "${file}"
        ;;
*.list)
        [ "${verbose}" != "-q" ] && echo "Unloading all rulesets from $(/usr/bin/basename "${file}")"
        unload_list "${file}"
        ;;
*)
        echo "Unknown filetype: ${file}"
        exit 32
        ;;
esac