mirror of
https://git.netfilter.org/nftables
synced 2026-01-26 10:34:27 +00:00
1) This removes former Makefiles and install-sh (which is now
automagically imported via autoreconf).
Makefile.defs.in
Makefile.in
Makefile.rules.in
src/Makefile.in
install-sh (now automagically imported via autoreconf).
2) CFLAGS are left almost same, they are integrated into Make_global.am.
Use AM_CPPFLAGS to set the CFLAGS set by pkgconfig.
3) Add m4 directory to the tree which only contains the .gitignore
file. Update .gitignore file to skip autogenerated files.
4) include <config.h> whenever required.
5) Minor adjustments to scanner.l and parser_bison.y to compile cleanly
with autotools.
6) Add %option outfile=lex.yy.c to scanner.l, otherwise I hit this error
here:
gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DDEFAULT_INCLUDE_PATH="\"/usr/etc\"" -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wdeclaration-after-statement -Wsign-compare -Winit-self -Wformat-nonliteral -Wformat-security -Wmissing-format-attribute -Wcast-align -Wundef -Wbad-function-cast -g -O2 -MT mnl.o -MD -MP -MF $depbase.Tpo -c -o mnl.o mnl.c &&\
mv -f $depbase.Tpo $depbase.Po
/bin/sh ../build-aux/ylwrap scanner.l lex.yy.c scanner.c -- flex
make[3]: *** [scanner.c] Error 1
make[3]: Leaving directory `/home/pablo/devel/scm/git-netfilter/nftables/src'
make[2]: *** [all] Error 2
make[2]: Leaving directory `/home/pablo/devel/scm/git-netfilter/nftables/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/pablo/devel/scm/git-netfilter/nftables'
make: *** [all] Error 2
7) Add Makefile.am for include/ (contributed by Giorgio Dal Molin).
The doc/ and files/ conversion to automake will come in follow up
patches but 'make distcheck' already works.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
192 lines
3.5 KiB
C
192 lines
3.5 KiB
C
/*
|
|
* Asynchronous readline-based interactive interface
|
|
*
|
|
* Actually not asynchronous so far, but intended to be.
|
|
*
|
|
* Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
|
|
*
|
|
* 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 <config.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <limits.h>
|
|
#include <readline/readline.h>
|
|
#include <readline/history.h>
|
|
|
|
#include <nftables.h>
|
|
#include <parser.h>
|
|
#include <erec.h>
|
|
#include <utils.h>
|
|
#include <cli.h>
|
|
|
|
#define CMDLINE_HISTFILE ".nft.history"
|
|
|
|
static const struct input_descriptor indesc_cli = {
|
|
.type = INDESC_CLI,
|
|
.name = "<cli>",
|
|
};
|
|
|
|
static struct parser_state *state;
|
|
static void *scanner;
|
|
|
|
static char histfile[PATH_MAX];
|
|
static char *multiline;
|
|
static bool eof;
|
|
|
|
static char *cli_append_multiline(char *line)
|
|
{
|
|
bool complete = false;
|
|
size_t len;
|
|
char *s;
|
|
|
|
if (line == NULL && multiline == NULL) {
|
|
eof = true;
|
|
return NULL;
|
|
}
|
|
|
|
len = strlen(line);
|
|
if (line[len - 1] == '\\') {
|
|
line[len - 1] = '\0';
|
|
len--;
|
|
} else if (multiline == NULL)
|
|
return line;
|
|
else
|
|
complete = 1;
|
|
|
|
if (multiline == NULL) {
|
|
multiline = line;
|
|
rl_save_prompt();
|
|
rl_clear_message();
|
|
rl_set_prompt(".... ");
|
|
} else {
|
|
len += strlen(multiline);
|
|
s = xmalloc(len + 1);
|
|
snprintf(s, len + 1, "%s%s", multiline, line);
|
|
xfree(multiline);
|
|
multiline = s;
|
|
}
|
|
line = NULL;
|
|
|
|
if (complete) {
|
|
line = multiline;
|
|
multiline = NULL;
|
|
rl_restore_prompt();
|
|
}
|
|
return line;
|
|
}
|
|
|
|
static void cli_complete(char *line)
|
|
{
|
|
const HIST_ENTRY *hist;
|
|
const char *c;
|
|
LIST_HEAD(msgs);
|
|
|
|
if (line == NULL) {
|
|
printf("\n");
|
|
cli_exit();
|
|
exit(0);
|
|
}
|
|
|
|
line = cli_append_multiline(line);
|
|
if (line == NULL)
|
|
return;
|
|
|
|
for (c = line; *c != '\0'; c++)
|
|
if (!isspace(*c))
|
|
break;
|
|
if (*c == '\0')
|
|
return;
|
|
|
|
if (!strcmp(line, "quit")) {
|
|
cli_exit();
|
|
exit(0);
|
|
}
|
|
|
|
/* avoid duplicate history entries */
|
|
hist = history_get(history_length);
|
|
if (hist == NULL || strcmp(hist->line, line))
|
|
add_history(line);
|
|
|
|
parser_init(state, &msgs);
|
|
scanner_push_buffer(scanner, &indesc_cli, line);
|
|
nft_run(scanner, state, &msgs);
|
|
erec_print_list(stdout, &msgs);
|
|
xfree(line);
|
|
}
|
|
|
|
static char **cli_completion(const char *text, int start, int end)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
void __fmtstring(1, 0) cli_display(const char *fmt, va_list ap)
|
|
{
|
|
int point, end;
|
|
char *buf;
|
|
|
|
point = rl_point;
|
|
end = rl_end;
|
|
rl_point = rl_end = 0;
|
|
|
|
rl_save_prompt();
|
|
rl_clear_message();
|
|
|
|
if (vasprintf(&buf, fmt, ap) < 0)
|
|
fprintf(rl_outstream, "cli_display: out of memory\n");
|
|
else {
|
|
fprintf(rl_outstream, "%s\n", buf);
|
|
xfree(buf);
|
|
}
|
|
|
|
rl_restore_prompt();
|
|
|
|
rl_point = point;
|
|
rl_end = end;
|
|
rl_forced_update_display();
|
|
}
|
|
|
|
int cli_init(struct parser_state *_state)
|
|
{
|
|
const char *home;
|
|
|
|
rl_readline_name = "nft";
|
|
rl_instream = stdin;
|
|
rl_outstream = stdout;
|
|
|
|
rl_callback_handler_install("nft> ", cli_complete);
|
|
rl_attempted_completion_function = cli_completion;
|
|
|
|
home = getenv("HOME");
|
|
if (home == NULL)
|
|
home = "";
|
|
snprintf(histfile, sizeof(histfile), "%s/%s", home, CMDLINE_HISTFILE);
|
|
|
|
read_history(histfile);
|
|
history_set_pos(history_length);
|
|
|
|
state = _state;
|
|
scanner = scanner_init(state);
|
|
|
|
while (!eof)
|
|
rl_callback_read_char();
|
|
return 0;
|
|
}
|
|
|
|
void cli_exit(void)
|
|
{
|
|
rl_callback_handler_remove();
|
|
rl_deprep_terminal();
|
|
write_history(histfile);
|
|
}
|