/* * error -- OpenVPN compatible error reporting API * https://community.openvpn.net/openvpn/wiki/Tapctl * * Copyright (C) 2002-2018 OpenVPN Inc * Copyright (C) 2018 Simon Rozman * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef ERROR_H #define ERROR_H #include #include #include /* * These globals should not be accessed directly, * but rather through macros or inline functions defined below. */ extern unsigned int x_debug_level; extern int x_msg_line_num; /* msg() flags */ #define M_DEBUG_LEVEL (0x0F) /* debug level mask */ #define M_FATAL (1<<4) /* exit program */ #define M_NONFATAL (1<<5) /* non-fatal error */ #define M_WARN (1<<6) /* call syslog with LOG_WARNING */ #define M_DEBUG (1<<7) #define M_ERRNO (1<<8) /* show errno description */ #define M_NOMUTE (1<<11) /* don't do mute processing */ #define M_NOPREFIX (1<<12) /* don't show date/time prefix */ #define M_USAGE_SMALL (1<<13) /* fatal options error, call usage_small */ #define M_MSG_VIRT_OUT (1<<14) /* output message through msg_status_output callback */ #define M_OPTERR (1<<15) /* print "Options error:" prefix */ #define M_NOLF (1<<16) /* don't print new line */ #define M_NOIPREFIX (1<<17) /* don't print instance prefix */ /* flag combinations which are frequently used */ #define M_ERR (M_FATAL | M_ERRNO) #define M_USAGE (M_USAGE_SMALL | M_NOPREFIX | M_OPTERR) #define M_CLIENT (M_MSG_VIRT_OUT | M_NOMUTE | M_NOIPREFIX) /** Check muting filter */ bool dont_mute(unsigned int flags); /* Macro to ensure (and teach static analysis tools) we exit on fatal errors */ #ifdef _MSC_VER #pragma warning(disable: 4127) /* EXIT_FATAL(flags) macro raises "warning C4127: conditional expression is constant" on each non M_FATAL invocation. */ #endif #define EXIT_FATAL(flags) do { if ((flags) & M_FATAL) {_exit(1);}} while (false) #define HAVE_VARARG_MACROS #define msg(flags, ...) do { if (msg_test(flags)) {x_msg((flags), __VA_ARGS__);} EXIT_FATAL(flags); } while (false) #ifdef ENABLE_DEBUG #define dmsg(flags, ...) do { if (msg_test(flags)) {x_msg((flags), __VA_ARGS__);} EXIT_FATAL(flags); } while (false) #else #define dmsg(flags, ...) #endif void x_msg(const unsigned int flags, const char *format, ...); /* should be called via msg above */ void x_msg_va(const unsigned int flags, const char *format, va_list arglist); /* Inline functions */ static inline bool check_debug_level(unsigned int level) { return (level & M_DEBUG_LEVEL) <= x_debug_level; } /** Return true if flags represent and enabled, not muted log level */ static inline bool msg_test(unsigned int flags) { return check_debug_level(flags) && dont_mute(flags); } #endif /* ifndef ERROR_H */