Hello,

pfctl diff bellow enables me to relax err(3) and errx(3) to warnings
where needed. The idea is to introduce PF_OPT_IGNFAIL and pfctl_err()
and pfctl_errx() wrappers around err(3) and errx(3) functions.

the wrappers, when acting in warning mode (PF_OPT_IGNFAIL set), would
also set exit_val global variable so main() can report error.

thanks and
regards
sashan

--------8<---------------8<---------------8<------------------8<--------

diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index d1a309d919f..cf91b435121 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -54,6 +54,8 @@
 
 #include <syslog.h>
 
+#include <stdarg.h>
+
 #include "pfctl_parser.h"
 #include "pfctl.h"
 
@@ -125,6 +127,7 @@ char                *state_kill[2];
 int             dev = -1;
 int             first_title = 1;
 int             labels = 0;
+int             exit_val = 0;
 
 #define INDENT(d, o)   do {                                            \
                                if (o) {                                \
@@ -251,6 +254,40 @@ usage(void)
        exit(1);
 }
 
+void
+pfctl_err(int opts, int eval, const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+
+       if ((opts & PF_OPT_IGNFAIL) == 0)
+               verr(eval, fmt, ap);
+       else
+               vwarn(fmt, ap);
+
+       va_end(ap);
+
+       exit_val = eval;
+}
+
+void
+pfctl_errx(int opts, int eval, const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start(ap, fmt);
+
+       if ((opts & PF_OPT_IGNFAIL) == 0)
+               verrx(eval, fmt, ap);
+       else
+               vwarnx(fmt, ap);
+
+       va_end(ap);
+
+       exit_val = eval;
+}
+
 int
 pfctl_enable(int dev, int opts)
 {
@@ -289,10 +326,10 @@ pfctl_clear_stats(int dev, const char *iface, int opts)
        memset(&pi, 0, sizeof(pi));
        if (iface != NULL && strlcpy(pi.pfiio_name, iface,
            sizeof(pi.pfiio_name)) >= sizeof(pi.pfiio_name))
-               errx(1, "invalid interface: %s", iface);
+               pfctl_errx(opts, 1, "invalid interface: %s", iface);
 
        if (ioctl(dev, DIOCCLRSTATUS, &pi) == -1)
-               err(1, "DIOCCLRSTATUS");
+               pfctl_err(opts, 1, "DIOCCLRSTATUS");
        if ((opts & PF_OPT_QUIET) == 0) {
                fprintf(stderr, "pf: statistics cleared");
                if (iface != NULL)
@@ -311,32 +348,36 @@ pfctl_clear_interface_flags(int dev, int opts)
                pi.pfiio_flags = PFI_IFLAG_SKIP;
 
                if (ioctl(dev, DIOCCLRIFFLAG, &pi) == -1)
-                       err(1, "DIOCCLRIFFLAG");
+                       pfctl_err(opts, 1, "DIOCCLRIFFLAG");
                if ((opts & PF_OPT_QUIET) == 0)
                        fprintf(stderr, "pf: interface flags reset\n");
        }
 }
 
-void
+int
 pfctl_clear_rules(int dev, int opts, char *anchorname)
 {
        struct pfr_buffer t;
+       int                     rv = 0;
 
        memset(&t, 0, sizeof(t));
        t.pfrb_type = PFRB_TRANS;
        if (pfctl_add_trans(&t, PF_TRANS_RULESET, anchorname) ||
            pfctl_trans(dev, &t, DIOCXBEGIN, 0) ||
-           pfctl_trans(dev, &t, DIOCXCOMMIT, 0))
-               err(1, "pfctl_clear_rules");
-       if ((opts & PF_OPT_QUIET) == 0)
+           pfctl_trans(dev, &t, DIOCXCOMMIT, 0)) {
+               pfctl_err(opts, 1, "%s", __func__);
+               rv = 1;
+       } else if ((opts & PF_OPT_QUIET) == 0)
                fprintf(stderr, "rules cleared\n");
+
+       return (rv);
 }
 
 void
 pfctl_clear_src_nodes(int dev, int opts)
 {
        if (ioctl(dev, DIOCCLRSRCNODES) == -1)
-               err(1, "DIOCCLRSRCNODES");
+               pfctl_err(opts, 1, "DIOCCLRSRCNODES");
        if ((opts & PF_OPT_QUIET) == 0)
                fprintf(stderr, "source tracking entries cleared\n");
 }
@@ -349,10 +390,10 @@ pfctl_clear_states(int dev, const char *iface, int opts)
        memset(&psk, 0, sizeof(psk));
        if (iface != NULL && strlcpy(psk.psk_ifname, iface,
            sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname))
-               errx(1, "invalid interface: %s", iface);
+               pfctl_errx(opts, 1, "invalid interface: %s", iface);
 
        if (ioctl(dev, DIOCCLRSTATES, &psk) == -1)
-               err(1, "DIOCCLRSTATES");
+               pfctl_err(opts, 1, "DIOCCLRSTATES");
        if ((opts & PF_OPT_QUIET) == 0)
                fprintf(stderr, "%d states cleared\n", psk.psk_killed);
 }
diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h
index 7981cf66fdb..669ffcb3784 100644
--- a/sbin/pfctl/pfctl.h
+++ b/sbin/pfctl/pfctl.h
@@ -96,5 +96,7 @@ u_int32_t
 int     pfctl_trans(int, struct pfr_buffer *, u_long, int);
 
 int     pfctl_show_queues(int, const char *, int, int);
+void    pfctl_err(int, int, const char *, ...);
+void    pfctl_errx(int, int, const char *, ...);
 
 #endif /* _PFCTL_H_ */
diff --git a/sbin/pfctl/pfctl_osfp.c b/sbin/pfctl/pfctl_osfp.c
index 79abfd1a7ab..8c0ea24171b 100644
--- a/sbin/pfctl/pfctl_osfp.c
+++ b/sbin/pfctl/pfctl_osfp.c
@@ -260,7 +260,7 @@ void
 pfctl_clear_fingerprints(int dev, int opts)
 {
        if (ioctl(dev, DIOCOSFPFLUSH) == -1)
-               err(1, "DIOCOSFPFLUSH");
+               pfctl_err(opts, 1, "DIOCOSFPFLUSH");
 }
 
 /* flush pfctl's view of the fingerprints */
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index be0ccee1897..993b1fe1c77 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -36,21 +36,22 @@
 
 #define PF_OSFP_FILE           "/etc/pf.os"
 
-#define PF_OPT_DISABLE         0x0001
-#define PF_OPT_ENABLE          0x0002
-#define PF_OPT_VERBOSE         0x0004
-#define PF_OPT_NOACTION                0x0008
-#define PF_OPT_QUIET           0x0010
-#define PF_OPT_CLRRULECTRS     0x0020
-#define PF_OPT_USEDNS          0x0040
-#define PF_OPT_VERBOSE2                0x0080
-#define PF_OPT_DUMMYACTION     0x0100
-#define PF_OPT_DEBUG           0x0200
-#define PF_OPT_SHOWALL         0x0400
-#define PF_OPT_OPTIMIZE                0x0800
-#define PF_OPT_NODNS           0x1000
-#define PF_OPT_RECURSE         0x4000
-#define PF_OPT_PORTNAMES       0x8000
+#define PF_OPT_DISABLE         0x00001
+#define PF_OPT_ENABLE          0x00002
+#define PF_OPT_VERBOSE         0x00004
+#define PF_OPT_NOACTION                0x00008
+#define PF_OPT_QUIET           0x00010
+#define PF_OPT_CLRRULECTRS     0x00020
+#define PF_OPT_USEDNS          0x00040
+#define PF_OPT_VERBOSE2                0x00080
+#define PF_OPT_DUMMYACTION     0x00100
+#define PF_OPT_DEBUG           0x00200
+#define PF_OPT_SHOWALL         0x00400
+#define PF_OPT_OPTIMIZE                0x00800
+#define PF_OPT_NODNS           0x01000
+#define PF_OPT_RECURSE         0x04000
+#define PF_OPT_PORTNAMES       0x08000
+#define PF_OPT_IGNFAIL         0x10000
 
 #define PF_TH_ALL              0xFF
 

Reply via email to