###############################################################################
# Code imported from /usr/share/shorewall/prog.footer
###############################################################################
#
# Give Usage Information
#
usage() {
    echo "Usage: $0 [ options ] <command>"
    echo
    echo "<command> is one of:"
    echo "   start"
    echo "   stop"
    echo "   clear"
    echo "   disable <interface>"
    echo "   down <interface>"
    echo "   enable <interface>"
    echo "   reset"
    echo "   reenable <interface>"
    echo "   refresh"
    echo "   reload"
    echo "   restart"
    echo "   run <command> [ <parameter> ... ]"
    echo "   status"
    echo "   up <interface>"
    echo "   savesets <file>"
    echo "   call <function> [ <parameter> ... ]"
    echo "   version"
    echo "   info"
    echo
    echo "Options are:"
    echo
    echo "   -v and -q        Standard Shorewall verbosity controls"
    echo "   -n               Don't update routing configuration"
    echo "   -p               Purge Conntrack Table"
    echo "   -t               Timestamp progress Messages"
    echo "   -c               Save/restore iptables counters"
    echo "   -V <verbosity>   Set verbosity explicitly"
    echo "   -R <file>        Override RESTOREFILE setting"
    exit $1
}

start_command() {
    if product_is_started; then
	error_message "$g_product is already Running"
	status=0
    else
	progress_message3 "Starting $g_product...."
	detect_configuration
	define_firewall
	status=$?
	if [ $status -eq 0 ]; then
	    [ -n "$SUBSYSLOCK" ] && touch $SUBSYSLOCK
	    progress_message3 "done."
	fi
    fi

    return $status
}

stop_command() {
    progress_message3 "Stopping $g_product...."
    detect_configuration
    stop_firewall
    [ -n "$SUBSYSLOCK" ] && rm -f $SUBSYSLOCK
    progress_message3 "done."
    return 0
}

reload_command() {
    if product_is_started; then
	progress_message3 "Reloading $g_product...."
    else
	error_message "$g_product is not running"
	progress_message3 "Starting $g_product...."
	COMMAND=start
    fi

    detect_configuration
    define_firewall
    status=$?
    if [ -n "$SUBSYSLOCK" ]; then
 	[ $status -eq 0 ] && touch $SUBSYSLOCK || rm -f $SUBSYSLOCK
    fi

    [ $status -eq 0 ] && progress_message3 "done."
}

################################################################################
# E X E C U T I O N    B E G I N S   H E R E				       #
################################################################################
#
# Start trace if first arg is "debug" or "trace"
#
g_debug_iptables=

if [ $# -gt 1 ]; then
    if [ "x$1" = "xtrace" ]; then
	set -x
	shift
    elif [ "x$1" = "xdebug" ]; then
	g_debug_iptables=Yes
	shift
    fi
fi
#
# Map VERBOSE to VERBOSITY for compatibility with old Shorewall[6]-lite installations
#
[ -z "$VERBOSITY" ] && [ -n "$VERBOSE" ] && VERBOSITY=$VERBOSE
#
# Map other old exported variables
#
g_purge=$PURGE
g_noroutes=$NOROUTES
g_timestamp=$TIMESTAMP
g_recovering=$RECOVERING
#
# These two variables contain the high-order and low-order parts respectively of
# an SHA1 digest of this file. The digest is generated before the two following
# lines are updated to contain the value of that digest.
#
g_sha1sum1=
g_sha1sum2=
#
# Other Globals
#
g_counters=
g_compiled=
g_file=
g_docker=
g_dockernetwork=
g_forcereload=

[ -n "$SERVICEDIR" ] && SUBSYSLOCK=

initialize

if [ -n "$STARTUP_LOG" ]; then
    touch $STARTUP_LOG
    chmod 0600 $STARTUP_LOG
    if [ ${SHOREWALL_INIT_SCRIPT:-0} -eq 1 ]; then
	#
	# We're being run by a startup script that isn't redirecting STDOUT
	# Redirect it to the log
	#
	exec 2>>$STARTUP_LOG
    fi
fi

finished=0

while [ $finished -eq 0 -a $# -gt 0 ]; do
    option=$1
    case $option in
	-*)
	    option=${option#-}

	    [ -z "$option" ] && usage 1

	    while [ -n "$option" ]; do
		case $option in
		    v*)
			[ $VERBOSITY -lt 2 ] && VERBOSITY=$(($VERBOSITY + 1 ))
			option=${option#v}
			;;
		    q*)
			[ $VERBOSITY -gt -1 ] && VERBOSITY=$(($VERBOSITY - 1 ))
			option=${option#q}
			;;
		    n*)
			g_noroutes=Yes
			option=${option#n}
			;;
		    t*)
			g_timestamp=Yes
			option=${option#t}
			;;
		    p*)
			g_purge=Yes
			option=${option#p}
			;;
		    r*)
			g_recovering=Yes
			option=${option#r}
			;;
		    c*)
			g_counters=Yes
			option=${option#c}
			;;
		    V*)
			option=${option#V}

			if [ -z "$option" -a $# -gt 0 ]; then
			    shift
			    option=$1
			fi

			if [ -n "$option" ]; then
			    case $option in
				-1|0|1|2)
				    VERBOSITY=$option
				    option=
				    ;;
				*)
				    startup_error "Invalid -V option value ($option)"
				    ;;
			    esac
			else
			    startup_error "Missing -V option value"
			fi
			;;
		    R*)
			option=${option#R}

			if [ -z "$option" -a $# -gt 0 ]; then
			    shift
			    option=$1
			fi

			if [ -n "$option" ]; then
			    case $option in
				*/*)
	    			    startup_error "-R must specify a simple file name: $option"
				    ;;
				.safe|.try|NONE)
				    ;;
				.*)
				    error_message "ERROR: Reserved File Name: $RESTOREFILE"
				    exit 2
				    ;;
			    esac
			else
			    startup_error "Missing -R option value"
			fi

			RESTOREFILE=$option
			option=
			;;
		    *)
			usage 1
			;;
		esac
	    done
	    shift
	    ;;
	*)
	    finished=1
            ;;
    esac
done

COMMAND="$1"

case "$COMMAND" in
    start)
	[ $# -ne 1 ] && usage 2
	start_command
	;;
    stop)
	[ $# -ne 1 ] && usage 2
	stop_command
	;;
    reset)
	if ! product_is_started ; then
	    error_message "$g_product is not running"
	    status=2
	elif [ $# -eq 1 ]; then
	    $g_tool -Z
	    $g_tool -t mangle -Z
	    date > ${VARDIR}/restarted
	    status=0
	    progress_message3 "$g_product Counters Reset"
	else
	    shift
	    status=0
	    table=filter
	    for chain in $@; do
	    	case $chain in
		    *:*)
			table=${chain%:*}
			chain=${chain#*:}
			case $table in
			    raw|nat|mangle|filter)
			        ;;
			    *)
				error_message "ERROR: Invalid table name ($table)"
				status=2
				;;
			esac
			;;
		    *)
			;;
		esac

		if [ $status -eq 0 ]; then
		    if chain_exists $chain $table; then
			if qt $g_tool -t $table -Z $chain; then
			    progress_message3 "Completed counter reset of $table chain $chain"
			else
			    error_message "ERROR: Reset of $table chain $chain failed"
			    status=2
			    break
			fi
		    else
			error_message "WARNING: $table chain $chain does not exist"
		    fi
		else
		    break;
		fi
	    done
	fi
	;;
    reload)
	[ $# -ne 1 ] && usage 2
	reload_command
	;;
    restart)
	[ $# -ne 1 ] && usage 2

	if [ "$RESTART" = restart ]; then
	    COMMAND=stop stop_command && COMMAND=start start_command
	else
	    COMMAND=reload
	    reload_command
	fi
	;;
    refresh)
	[ $# -ne 1 ] && usage 2
	if product_is_started; then
	    progress_message3 "Refreshing $g_product...."
	    detect_configuration
	    define_firewall
	    status=$?
	    [ $status -eq 0 ] && progress_message3 "done."
	else
	    echo "$g_product is not running" >&2
	    status=2
	fi
	;;
    restore)
	[ $# -ne 1 ] && usage 2
	detect_configuration
	define_firewall
	status=$?
	if [ -n "$SUBSYSLOCK" ]; then
 	    [ $status -eq 0 ] && touch $SUBSYSLOCK || rm -f $SUBSYSLOCK
        fi
	[ $status -eq 0 ] && progress_message3 "done."
	;;
    clear)
	[ $# -ne 1 ] && usage 2
	progress_message3 "Clearing $g_product...."
	clear_firewall
	status=0
	if [ -n "$SUBSYSLOCK" ]; then
	    rm -f $SUBSYSLOCK
	fi
	progress_message3 "done."
	;;
    status)
	[ $# -ne 1 ] && usage 2
	[ $VERBOSITY -ge 1 ] && echo "$g_product-$SHOREWALL_VERSION Status at $(hostname) - $(date)" &&	echo
	if product_is_started; then
	    [ $VERBOSITY -ge 1 ] && echo "$g_product is running"
	    status=0
	else
	    [ $VERBOSITY -ge 1 ] && echo "$g_product is stopped"
	    status=4
	fi

	if [ -f ${VARDIR}/state ]; then
	    state="$(cat ${VARDIR}/state)"
	    case $state in
		Stopped*|Clear*)
		    status=3
		    ;;
	    esac
	else
	    state=Unknown
	fi
	[ $VERBOSITY -ge 1 ] && echo "State:$state" && echo
	;;
    up|down)
	[ $# -eq 1 ] && exit 0
	shift
	[ $# -ne 1 ] && usage 2
	mutex_on
	( updown $1 )
	mutex_off
	status=0
	;;
    enable)
	[ $# -eq 1 ] && exit 0
	shift
	[ $# -ne 1 ] && usage 2
	mutex_on
	if product_is_started; then
	    detect_configuration $1
	    enable_provider $1 Yes
	fi
	mutex_off
	status=0
	;;
    disable)
	[ $# -eq 1 ] && exit 0
	shift
	[ $# -ne 1 ] && usage 2
	mutex_on
	if product_is_started; then
	    detect_configuration $1
	    disable_provider $1 Yes
	fi
	mutex_off
	status=0
	;;
    reenable)
	[ $# -eq 1 ] && exit 0
	shift
	[ $# -ne 1 ] && usage 2
	mutex_on
	if product_is_started; then
	    detect_configuration $1
	    COMMAND=enable  disable_provider $1 Yes
	    COMMAND=disable enable_provider  $1 Yes
	fi
	mutex_off
	status=0
	;;
    run)
	if [ $# -gt 1 ]; then
	    shift
	    detect_configuration
	    run_init_exit
	    eval $@
	    status=$?
	else
	    error_message "ERROR: Missing command"
	fi
	;;
    savesets)
	if [ $# -eq 2 ]; then
	    save_ipsets $2
	    status=$?
	else
	    usage 2
	fi
	;;
    call)
	#
	# Way to call functions in the generated script directly
	#
	detect_configuration

	shift

	if [ $# -gt 0 ]; then
	    #
	    # See what it is
	    #
	    if type $1 2> /dev/null | fgrep -q 'is a function'; then
		#
		# It's a shell function -- call it
		#
		$@
	    else
		fatal_error "$1 is not a known shell function"
	    fi
	else
	    usage 1
	fi
	;;
    version)
	[ $# -ne 1 ] && usage 2
	echo $SHOREWALL_VERSION
	status=0
	;;
    info)
	[ $# -ne 1 ] && usage 2
	info_command
	;;
    help)
	[ $# -ne 1 ] && usage 2
	usage 0
	;;
    *)
	usage 2
	;;
esac

exit $status