From fac10ea799fe9b6158d74f66d6ad46536d38a545 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 18 Mar 2009 04:55:00 +0100 Subject: Initial commit --- src/main.c | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 src/main.c (limited to 'src/main.c') diff --git a/src/main.c b/src/main.c new file mode 100644 index 00000000..f7686ae3 --- /dev/null +++ b/src/main.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2008 Patrick McHardy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Development of this code funded by Astaro AG (http://www.astaro.com/) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +unsigned int numeric_output; + +const char *include_paths[INCLUDE_PATHS_MAX] = { DEFAULT_INCLUDE_PATH }; +static unsigned int num_include_paths = 1; + +enum opt_vals { + OPT_HELP = 'h', + OPT_VERSION = 'v', + OPT_FILE = 'f', + OPT_INTERACTIVE = 'i', + OPT_INCLUDEPATH = 'I', + OPT_NUMERIC = 'n', + OPT_INVALID = '?', +}; + +#define OPTSTRING "hvf:iI:vn" + +static const struct option options[] = { + { + .name = "help", + .val = OPT_HELP, + }, + { + .name = "version", + .val = OPT_VERSION, + }, + { + .name = "file", + .val = OPT_FILE, + .has_arg = 1, + }, + { + .name = "interactive", + .val = OPT_INTERACTIVE, + }, + { + .name = "numeric", + .val = OPT_NUMERIC, + }, + { + .name = "includepath", + .val = OPT_INCLUDEPATH, + .has_arg = 1, + }, + { + .name = NULL + } +}; + +static void show_help(const char *name) +{ + printf( +"Usage: %s [ options ] [ cmds... ]\n" +"\n" +"Options:\n" +" -h/--help Show this help\n" +" -v/--version Show version information\n" +"\n" +" -f/--file Read input from \n" +" -i/--interactive Read input from interactive CLI\n" +"\n" +" -n/--numeric When specified once, show network addresses numerically.\n" +" When specified twice, also show Internet protocols,\n" +" Internet services, user IDs and group IDs numerically.\n" +" -i/--includepath Add to the paths searched for include files.\n" +"\n", + name); +} + +static const struct input_descriptor indesc_cmdline = { + .type = INDESC_BUFFER, + .name = "", +}; + +int main(int argc, char * const *argv) +{ + struct parser_state state; + struct eval_ctx ctx; + void *scanner; + LIST_HEAD(msgs); + char *buf = NULL, *filename = NULL; + unsigned int len; + bool interactive = false; + int i, val; + int ret; + + while (1) { + val = getopt_long(argc, argv, OPTSTRING, options, NULL); + if (val == -1) + break; + + switch (val) { + case OPT_HELP: + show_help(argv[0]); + exit(NFT_EXIT_SUCCESS); + case OPT_VERSION: + printf("%s v%s (%s)\n", + PACKAGE_NAME, PACKAGE_VERSION, RELEASE_NAME); + exit(NFT_EXIT_SUCCESS); + case OPT_FILE: + filename = optarg; + break; + case OPT_INTERACTIVE: + interactive = true; + break; + case OPT_INCLUDEPATH: + if (num_include_paths >= INCLUDE_PATHS_MAX) { + fprintf(stderr, "Too many include paths " + "specified, max. %u\n", + INCLUDE_PATHS_MAX - 1); + exit(NFT_EXIT_FAILURE); + } + include_paths[num_include_paths++] = optarg; + break; + case OPT_NUMERIC: + numeric_output++; + break; + case OPT_INVALID: + exit(NFT_EXIT_FAILURE); + } + } + + parser_init(&state, &msgs); + scanner = scanner_init(&state); + + if (optind != argc) { + for (len = 0, i = optind; i < argc; i++) + len += strlen(argv[i]) + strlen(" "); + + buf = xzalloc(len + 1); + for (i = optind; i < argc; i++) { + strcat(buf, argv[i]); + if (i + 1 < argc) + strcat(buf, " "); + } + + scanner_push_buffer(scanner, &indesc_cmdline, buf); + } else if (filename != NULL) { + if (scanner_read_file(scanner, filename, &internal_location) < 0) + goto out; + } else if (interactive) { + cli_init(scanner, &state); + } else { + fprintf(stderr, "%s: no command specified\n", argv[0]); + exit(NFT_EXIT_FAILURE); + } + + ret = nft_parse(scanner, &state); + if (ret < 0) + goto out; + + memset(&ctx, 0, sizeof(ctx)); + ctx.msgs = &msgs; + if (evaluate(&ctx, &state.cmds) < 0) + goto out; + + { + struct netlink_ctx ctx; + struct cmd *cmd; + + list_for_each_entry(cmd, &state.cmds, list) { + memset(&ctx, 0, sizeof(ctx)); + ctx.msgs = &msgs; + init_list_head(&ctx.list); + if (do_command(&ctx, cmd) < 0) + goto out; + } + } +out: + scanner_destroy(scanner); + erec_print_list(stdout, &msgs); + + xfree(buf); + return 0; +} -- cgit v1.2.3