/*
 * ebtables-restore.c, October 2005
 *
 * Author: Bart De Schuymer
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <getopt.h>
#include "include/ebtables_u.h"

static const struct option options[] = {
	{.name = "noflush", .has_arg = 0, .val = 'n'},
	{ 0 }
};

static struct ebt_u_replace replace[3];
void ebt_early_init_once();

#define OPT_KERNELDATA  0x800 /* Also defined in ebtables.c */

static void print_usage()
{
	fprintf(stderr, "Usage: ebtables-restore [ --noflush ]\n");
	exit(1);
}

static void copy_table_names()
{
	strcpy(replace[0].name, "filter");
	strcpy(replace[1].name, "nat");
	strcpy(replace[2].name, "broute");
}

#define ebtrest_print_error(format, args...) do {fprintf(stderr, "ebtables-restore: "\
                                             "line %d: "format".\n", line, ##args); exit(-1);} while (0)
int main(int argc_, char *argv_[])
{
	char *argv[EBTD_ARGC_MAX], cmdline[EBTD_CMDLINE_MAXLN];
	int i, offset, quotemode = 0, argc, table_nr = -1, line = 0, whitespace, c, flush = 1;
	char ebtables_str[] = "ebtables";

	while ((c = getopt_long(argc_, argv_, "n", options, NULL)) != -1) {
		switch(c) {
			case 'n':
				flush = 0;
				break;
			default:
				print_usage();
				break;
		}
	}

	ebt_silent = 0;
	copy_table_names();
	ebt_early_init_once();
	argv[0] = ebtables_str;

	while (fgets(cmdline, EBTD_CMDLINE_MAXLN, stdin)) {
		line++;
		if (*cmdline == '#' || *cmdline == '\n')
			continue;
		*strchr(cmdline, '\n') = '\0';
		if (*cmdline == '*') {
			if (table_nr != -1) {
				ebt_deliver_table(&replace[table_nr]);
				ebt_deliver_counters(&replace[table_nr]);
			}
			for (i = 0; i < 3; i++)
				if (!strcmp(replace[i].name, cmdline+1))
					break;
			if (i == 3)
				ebtrest_print_error("table '%s' was not recognized", cmdline+1);
			table_nr = i;
			replace[table_nr].command = 11;
			ebt_get_kernel_table(&replace[table_nr], flush);
			replace[table_nr].command = 0;
			replace[table_nr].flags = OPT_KERNELDATA; /* Prevent do_command from initialising replace */
			continue;
		} else if (table_nr == -1)
			ebtrest_print_error("no table specified");
		if (*cmdline == ':') {
			int policy, chain_nr;
			char *ch;

			if (!(ch = strchr(cmdline, ' ')))
				ebtrest_print_error("no policy specified");
			*ch = '\0';
			for (i = 0; i < NUM_STANDARD_TARGETS; i++)
				if (!strcmp(ch+1, ebt_standard_targets[i])) {
					policy = -i -1;
					if (policy == EBT_CONTINUE)
						i = NUM_STANDARD_TARGETS;
					break;
				}
			if (i == NUM_STANDARD_TARGETS)
				ebtrest_print_error("invalid policy specified");
			/* No need to check chain name for consistency, since
			 * we're supposed to be reading an automatically generated
			 * file. */
			if ((chain_nr = ebt_get_chainnr(&replace[table_nr], cmdline+1)) == -1)
				ebt_new_chain(&replace[table_nr], cmdline+1, policy);
			else
				replace[table_nr].chains[chain_nr]->policy = policy;
			continue;
		}
		argv[1] = cmdline;
		offset = whitespace = 0;
		argc = 2;
		while (cmdline[offset] != '\0') {
			if (cmdline[offset] == '\"') {
				whitespace = 0;
				quotemode ^= 1;
				if (quotemode)
					argv[argc++] = &cmdline[offset+1];
				else if (cmdline[offset+1] != ' ' && cmdline[offset+1] != '\0')
					ebtrest_print_error("syntax error at \"");
				cmdline[offset] = '\0';
			} else if (!quotemode && cmdline[offset] == ' ') {
				whitespace = 1;
				cmdline[offset] = '\0';
			} else if (whitespace == 1) {
				argv[argc++] = &cmdline[offset];
				whitespace = 0;
			}
			offset++;
		}
		if (quotemode)
			ebtrest_print_error("wrong use of '\"'");
		optind = 0; /* Setting optind = 1 causes serious annoyances */
		do_command(argc, argv, EXEC_STYLE_DAEMON, &replace[table_nr]);
		ebt_reinit_extensions();
	}

	if (table_nr != -1) {
		ebt_deliver_table(&replace[table_nr]);
		ebt_deliver_counters(&replace[table_nr]);
	}
	return 0;
}
