From c387170f903a976922de970042f8fdb6ec93a0f8 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Mon, 22 Oct 2018 19:12:14 +0200 Subject: Fix warning message handling Warning messages were not printed and handled properly, the patch fixes the issue. --- include/libipset/args.h | 2 +- include/libipset/parse.h | 10 +++++----- include/libipset/session.h | 14 ++++++++++---- lib/args.c | 14 +++++++++++++- lib/ipset.c | 24 +++++++++++------------ lib/parse.c | 26 +++++++++++++------------ lib/session.c | 47 ++++++++++++++++++++++------------------------ 7 files changed, 76 insertions(+), 61 deletions(-) diff --git a/include/libipset/args.h b/include/libipset/args.h index cdec180..dce4190 100644 --- a/include/libipset/args.h +++ b/include/libipset/args.h @@ -63,7 +63,7 @@ extern "C" { #endif extern const struct ipset_arg * ipset_keyword(enum ipset_keywords i); - +extern const char * ipset_ignored_optname(int opt); #ifdef __cplusplus } #endif diff --git a/include/libipset/parse.h b/include/libipset/parse.h index 4bd5df5..8b68618 100644 --- a/include/libipset/parse.h +++ b/include/libipset/parse.h @@ -51,7 +51,7 @@ extern int ipset_parse_icmpv6(struct ipset_session *session, extern int ipset_parse_proto_port(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_tcp_udp_port(struct ipset_session *session, - enum ipset_opt opt, const char *str); + enum ipset_opt opt, const char *str); extern int ipset_parse_family(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_ip(struct ipset_session *session, @@ -69,7 +69,7 @@ extern int ipset_parse_iprange(struct ipset_session *session, extern int ipset_parse_ipnet(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_ip4_single6(struct ipset_session *session, - enum ipset_opt opt, const char *str); + enum ipset_opt opt, const char *str); extern int ipset_parse_ip4_net6(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_name(struct ipset_session *session, @@ -99,11 +99,11 @@ extern int ipset_parse_typename(struct ipset_session *session, extern int ipset_parse_iface(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_comment(struct ipset_session *session, - enum ipset_opt opt, const char *str); + enum ipset_opt opt, const char *str); extern int ipset_parse_skbmark(struct ipset_session *session, - enum ipset_opt opt, const char *str); + enum ipset_opt opt, const char *str); extern int ipset_parse_skbprio(struct ipset_session *session, - enum ipset_opt opt, const char *str); + enum ipset_opt opt, const char *str); extern int ipset_parse_ignored(struct ipset_session *session, enum ipset_opt opt, const char *str); extern int ipset_parse_elem(struct ipset_session *session, diff --git a/include/libipset/session.h b/include/libipset/session.h index 825d2c8..8618402 100644 --- a/include/libipset/session.h +++ b/include/libipset/session.h @@ -35,8 +35,10 @@ extern void ipset_session_lineno(struct ipset_session *session, extern void * ipset_session_printf_private(struct ipset_session *session); enum ipset_err_type { - IPSET_ERROR, - IPSET_WARNING, + IPSET_NO_ERROR, + IPSET_WARNING, /* Success code when exit */ + IPSET_NOTICE, /* Error code and exit in non interactive mode */ + IPSET_ERROR, /* Error code and exit */ }; extern int ipset_session_report(struct ipset_session *session, @@ -50,14 +52,18 @@ extern int ipset_session_warning_as_error(struct ipset_session *session); #define ipset_warn(session, fmt, args...) \ ipset_session_report(session, IPSET_WARNING, fmt , ## args) +#define ipset_notice(session, fmt, args...) \ + ipset_session_report(session, IPSET_NOTICE, fmt , ## args) + #define ipset_errptr(session, fmt, args...) ({ \ ipset_session_report(session, IPSET_ERROR, fmt , ## args); \ NULL; \ }) extern void ipset_session_report_reset(struct ipset_session *session); -extern const char *ipset_session_error(const struct ipset_session *session); -extern const char *ipset_session_warning(const struct ipset_session *session); +extern const char *ipset_session_report_msg(const struct ipset_session *session); +extern enum ipset_err_type ipset_session_report_type( + const struct ipset_session *session); #define ipset_session_data_set(session, opt, value) \ ipset_data_set(ipset_session_data(session), opt, value) diff --git a/lib/args.c b/lib/args.c index 5376ed0..f932719 100644 --- a/lib/args.c +++ b/lib/args.c @@ -278,8 +278,20 @@ static const struct ipset_arg ipset_args[] = { }, }; -const struct ipset_arg * ipset_keyword(enum ipset_keywords i) +const struct ipset_arg * +ipset_keyword(enum ipset_keywords i) { return (i > IPSET_ARG_NONE && i < IPSET_ARG_MAX) ? &ipset_args[i] : NULL; } + +const char * +ipset_ignored_optname(int opt) +{ + enum ipset_keywords i; + + for (i = IPSET_ARG_NONE + 1 ; i < IPSET_ARG_MAX; i++) + if (ipset_args[i].opt == opt) + return ipset_args[i].name[0]; + return ""; +} diff --git a/lib/ipset.c b/lib/ipset.c index a52f3d6..70189f9 100644 --- a/lib/ipset.c +++ b/lib/ipset.c @@ -498,19 +498,22 @@ default_standard_error(struct ipset *ipset, void *p) { struct ipset_session *session = ipset_session(ipset); bool is_interactive = ipset_is_interactive(ipset); + enum ipset_err_type err_type = ipset_session_report_type(session); - if (ipset_session_warning(session) && + if ((err_type == IPSET_WARNING || err_type == IPSET_NOTICE) && !ipset_envopt_test(session, IPSET_ENV_QUIET)) - fprintf(stderr, "Warning: %s\n", - ipset_session_warning(session)); - if (ipset_session_error(session)) + fprintf(stderr, "%s%s", + err_type == IPSET_WARNING ? "Warning: " : "", + ipset_session_report_msg(session)); + if (err_type == IPSET_ERROR) return ipset->custom_error(ipset, p, IPSET_SESSION_PROBLEM, "%s", - ipset_session_error(session)); + ipset_session_report_msg(session)); if (!is_interactive) { ipset_fini(ipset); - exit(IPSET_OTHER_PROBLEM); + /* Warnings are not errors */ + exit(err_type <= IPSET_WARNING ? 0 : IPSET_OTHER_PROBLEM); } ipset_session_report_reset(session); @@ -1267,13 +1270,8 @@ ipset_parse_argv(struct ipset *ipset, int oargc, char *oargv[]) "Unknown argument %s", argv[1]); ret = ipset_cmd(session, cmd, ipset->restore_line); D("ret %d", ret); - /* Special case for TEST and non-quiet mode */ - if (cmd == IPSET_CMD_TEST && ipset_session_warning(session)) { - if (!ipset_envopt_test(session, IPSET_ENV_QUIET)) - fprintf(stderr, "%s", ipset_session_warning(session)); - ipset_session_report_reset(session); - } - if (ret < 0) + /* In the case of warning, the return code is success */ + if (ret < 0 || ipset_session_report_type(session) > IPSET_NO_ERROR) ipset->standard_error(ipset, p); return ret; diff --git a/lib/parse.c b/lib/parse.c index a88b9e2..5943f05 100644 --- a/lib/parse.c +++ b/lib/parse.c @@ -443,7 +443,7 @@ ipset_parse_tcp_port(struct ipset_session *session, */ int ipset_parse_single_tcp_port(struct ipset_session *session, - enum ipset_opt opt, const char *str) + enum ipset_opt opt, const char *str) { assert(session); assert(opt == IPSET_OPT_PORT || opt == IPSET_OPT_PORT_TO); @@ -759,7 +759,7 @@ print_warn(struct ipset_session *session) { if (!ipset_envopt_test(session, IPSET_ENV_QUIET)) fprintf(stderr, "Warning: %s", - ipset_session_warning(session)); + ipset_session_report_msg(session)); ipset_session_report_reset(session); } @@ -1306,8 +1306,9 @@ ipset_parse_ip4_net6(struct ipset_session *session, ipset_data_set(data, IPSET_OPT_FAMILY, &family); } - return family == NFPROTO_IPV4 ? parse_ip(session, opt, str, IPADDR_ANY) - : ipset_parse_ipnet(session, opt, str); + return family == NFPROTO_IPV4 ? + parse_ip(session, opt, str, IPADDR_ANY) : + ipset_parse_ipnet(session, opt, str); } @@ -1540,7 +1541,7 @@ ipset_parse_before(struct ipset_session *session, */ int ipset_parse_after(struct ipset_session *session, - enum ipset_opt opt, const char *str) + enum ipset_opt opt, const char *str) { struct ipset_data *data; @@ -1809,7 +1810,7 @@ ipset_parse_iface(struct ipset_session *session, * Returns 0 on success or a negative error code. */ int ipset_parse_comment(struct ipset_session *session, - enum ipset_opt opt, const char *str) + enum ipset_opt opt, const char *str) { struct ipset_data *data; @@ -1850,7 +1851,7 @@ ipset_parse_skbmark(struct ipset_session *session, " MARK/MASK or MARK (see manpage)"); } result = ((uint64_t)(mark) << 32) | (mask & 0xffffffff); - return ipset_data_set(data, IPSET_OPT_SKBMARK, &result); + return ipset_data_set(data, opt, &result); } int @@ -1872,7 +1873,7 @@ ipset_parse_skbprio(struct ipset_session *session, return syntax_err("Invalid skbprio format, it should be:"\ "MAJOR:MINOR (see manpage)"); major = ((uint32_t)maj << 16) | (min & 0xffff); - return ipset_data_set(data, IPSET_OPT_SKBPRIO, &major); + return ipset_data_set(data, opt, &major); } /** @@ -1895,8 +1896,9 @@ ipset_parse_ignored(struct ipset_session *session, if (!ipset_data_ignored(ipset_session_data(session), opt)) ipset_warn(session, - "Option %s is ignored. " - "Please upgrade your syntax.", str); + "Option '--%s %s' is ignored. " + "Please upgrade your syntax.", + ipset_ignored_optname(opt), str); return 0; } @@ -1916,8 +1918,8 @@ ipset_parse_ignored(struct ipset_session *session, */ int ipset_call_parser(struct ipset_session *session, - const struct ipset_arg *arg, - const char *str) + const struct ipset_arg *arg, + const char *str) { struct ipset_data *data = ipset_session_data(session); diff --git a/lib/session.c b/lib/session.c index e782573..a5a93da 100644 --- a/lib/session.c +++ b/lib/session.c @@ -55,8 +55,7 @@ struct ipset_session { FILE *istream, *ostream; /* Session input/output stream */ /* Error/warning reporting */ char report[IPSET_ERRORBUFLEN]; /* Error/report buffer */ - char *errmsg; - char *warnmsg; + enum ipset_err_type err_type; /* ERROR/WARNING/NOTICE */ uint8_t envopts; /* Session env opts */ /* Kernel message buffer */ size_t bufsize; @@ -227,6 +226,10 @@ ipset_session_report(struct ipset_session *session, assert(session); assert(fmt); + /* Suppress warning/notice when more important message is required */ + if (session->err_type > IPSET_NO_ERROR && session->err_type < type) + session->report[0] = '\0'; + if (session->lineno != 0 && type == IPSET_ERROR) { sprintf(session->report, "Error in line %u: ", session->lineno); @@ -244,14 +247,10 @@ ipset_session_report(struct ipset_session *session, if (strlen(session->report) < IPSET_ERRORBUFLEN - 1) strcat(session->report, "\n"); - if (type == IPSET_ERROR) { - session->errmsg = session->report; - session->warnmsg = NULL; + session->err_type = type; + if (type == IPSET_ERROR) ipset_data_reset(ipset_session_data(session)); - } else { - session->errmsg = NULL; - session->warnmsg = session->report; - } + return -1; } @@ -264,8 +263,7 @@ ipset_session_report(struct ipset_session *session, int ipset_session_warning_as_error(struct ipset_session *session) { - session->errmsg = session->report; - session->warnmsg = NULL; + session->err_type = IPSET_ERROR; ipset_data_reset(ipset_session_data(session)); return -1; } @@ -281,37 +279,36 @@ ipset_session_report_reset(struct ipset_session *session) { assert(session); session->report[0] = '\0'; - session->errmsg = session->warnmsg = NULL; + session->err_type = IPSET_NO_ERROR; } /** - * ipset_session_error - return the report buffer as error + * ipset_session_report_msg - return the report buffer * @session: session structure * - * Return the pointer to the report buffer as an error report. - * If there is no error message in the buffer, NULL returned. + * Return the pointer to the report buffer. + * If there is no error message, the buffer is empty. */ const char * -ipset_session_error(const struct ipset_session *session) +ipset_session_report_msg(const struct ipset_session *session) { assert(session); - return session->errmsg; + return session->report; } /** - * ipset_session_warning - return the report buffer as warning + * ipset_session_report_type - return the type of the report * @session: session structure * - * Return the pointer to the report buffer as a warning report. - * If there is no warning message in the buffer, NULL returned. + * Return the type of the message in the report buffer. */ -const char * -ipset_session_warning(const struct ipset_session *session) +enum ipset_err_type +ipset_session_report_type(const struct ipset_session *session) { assert(session); - return session->warnmsg; + return session->err_type; } /* @@ -1462,8 +1459,8 @@ callback_error(const struct nlmsghdr *nlh, void *cbdata) if (!(session->envopts & IPSET_ENV_QUIET)) { ipset_print_elem(session->report, IPSET_ERRORBUFLEN, session->data, IPSET_OPT_NONE, 0); - ipset_warn(session, " is NOT in set %s.", - ipset_data_setname(data)); + ipset_notice(session, " is NOT in set %s.", + ipset_data_setname(data)); } return ret; } -- cgit v1.2.3