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