summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2018-10-22 19:12:14 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2018-10-22 19:12:14 +0200
commitc387170f903a976922de970042f8fdb6ec93a0f8 (patch)
treed3c07aefadf8ebe5942be1ae9b7f839e9595e3ec
parent2a66a0df03788d8a7e95972847545de0ade0dd8e (diff)
Fix warning message handling
Warning messages were not printed and handled properly, the patch fixes the issue.
-rw-r--r--include/libipset/args.h2
-rw-r--r--include/libipset/parse.h10
-rw-r--r--include/libipset/session.h14
-rw-r--r--lib/args.c14
-rw-r--r--lib/ipset.c24
-rw-r--r--lib/parse.c26
-rw-r--r--lib/session.c47
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;
}