]> granicus.if.org Git - ipset/commitdiff
Fix warning message handling
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Mon, 22 Oct 2018 17:12:14 +0000 (19:12 +0200)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Mon, 22 Oct 2018 17:12:14 +0000 (19:12 +0200)
Warning messages were not printed and handled properly, the patch
fixes the issue.

include/libipset/args.h
include/libipset/parse.h
include/libipset/session.h
lib/args.c
lib/ipset.c
lib/parse.c
lib/session.c

index cdec180c68a64381f522d00eb58819aafb2bada5..dce4190a55a2312af3ba5a0ac77cd5d7eb55226e 100644 (file)
@@ -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
index 4bd5df509e5c46f45f61b5de0c62cc689624a280..8b68618091d16ff9915205c74bf0d438f0e7a322 100644 (file)
@@ -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,
index 825d2c8b1fd2901c461fd55c999faf9c94703078..861840269a97e96f72864695b254da4bed327b2d 100644 (file)
@@ -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)
index 5376ed034870f24de736fe641cd4272983dc6cac..f9327198e44eaeae6cac298dc01fc56acf68be85 100644 (file)
@@ -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 "";
+}
index a52f3d6754756cd13dc5878edf2f34b6223d7c24..70189f96e2a06b0cd36aae76ce15c846246b4174 100644 (file)
@@ -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;
index a88b9e289e1213fdb5f7c486b69272755bad8aa7..5943f05c2dfc727560fd73d8356523231423d5cf 100644 (file)
@@ -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);
 
index e782573575de77bb1824ceeac30487202d86e140..a5a93da7a8516b20713bb671e5d09e62c1ab2ada 100644 (file)
@@ -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;
        }