1 /* 2 * SPDX-License-Identifier: ISC 3 * 4 * Copyright (c) 2004, 2010-2015, 2017-2018 Todd C. Miller <Todd.Miller@sudo.ws> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #ifndef SUDO_FATAL_H 20 #define SUDO_FATAL_H 21 22 #include <stdarg.h> 23 #ifdef HAVE_STDBOOL_H 24 # include <stdbool.h> 25 #else 26 # include "compat/stdbool.h" 27 #endif /* HAVE_STDBOOL_H */ 28 29 #include "sudo_plugin.h" /* for conversation function */ 30 31 /* 32 * We wrap fatal/fatalx and warn/warnx so that the same output can 33 * go to the debug file, if there is one. 34 */ 35 #if (defined(SUDO_ERROR_WRAP) && SUDO_ERROR_WRAP == 0) || defined(NO_VARIADIC_MACROS) 36 # define sudo_fatal sudo_fatal_nodebug_v1 37 # define sudo_fatalx sudo_fatalx_nodebug_v1 38 # define sudo_gai_fatal sudo_gai_fatal_nodebug_v1 39 # define sudo_warn sudo_warn_nodebug_v1 40 # define sudo_warnx sudo_warnx_nodebug_v1 41 # define sudo_gai_warn sudo_gai_warn_nodebug_v1 42 # define sudo_vfatal(fmt, ap) sudo_vfatal_nodebug_v1((fmt), (ap)) 43 # define sudo_vfatalx(fmt, ap) sudo_vfatalx_nodebug_v1((fmt), (ap)) 44 # define sudo_gai_vfatal(en, fmt, ap) sudo_vfatal_nodebug_v1((en), (fmt), (ap)) 45 # define sudo_vwarn(fmt, ap) sudo_vwarn_nodebug_v1((fmt), (ap)) 46 # define sudo_vwarnx(fmt, ap) sudo_vwarnx_nodebug_v1((fmt), (ap)) 47 # define sudo_gai_vwarn(en, fmt, ap) sudo_vwarn_nodebug_v1((en), (fmt), (ap)) 48 #else /* SUDO_ERROR_WRAP */ 49 # if defined(__GNUC__) && __GNUC__ == 2 50 # define sudo_fatal(fmt...) do { \ 51 sudo_debug_printf2(__func__, __FILE__, __LINE__, \ 52 SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \ 53 fmt); \ 54 sudo_fatal_nodebug_v1(fmt); \ 55 } while (0) 56 # define sudo_fatalx(fmt...) do { \ 57 sudo_debug_printf2(__func__, __FILE__, __LINE__, \ 58 SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \ 59 sudo_fatalx_nodebug_v1(fmt); \ 60 } while (0) 61 # define sudo_gai_fatal(en, fmt...) do { \ 62 sudo_debug_printf2(__func__, __FILE__, __LINE__, \ 63 SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \ 64 sudo_gai_fatal_nodebug_v1((en), fmt); \ 65 } while (0) 66 # define sudo_warn(fmt...) do { \ 67 sudo_debug_printf2(__func__, __FILE__, __LINE__, \ 68 SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \ 69 fmt); \ 70 sudo_warn_nodebug_v1(fmt); \ 71 } while (0) 72 # define sudo_warnx(fmt...) do { \ 73 sudo_debug_printf2(__func__, __FILE__, __LINE__, \ 74 SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \ 75 sudo_warnx_nodebug_v1(fmt); \ 76 } while (0) 77 # define sudo_gai_warn(en, fmt...) do { \ 78 sudo_debug_printf2(__func__, __FILE__, __LINE__, \ 79 SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt); \ 80 sudo_gai_warn_nodebug_v1((en), fmt); \ 81 } while (0) 82 # else 83 # define sudo_fatal(...) do { \ 84 sudo_debug_printf2(__func__, __FILE__, __LINE__, \ 85 SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \ 86 __VA_ARGS__); \ 87 sudo_fatal_nodebug_v1(__VA_ARGS__); \ 88 } while (0) 89 # define sudo_fatalx(...) do { \ 90 sudo_debug_printf2(__func__, __FILE__, __LINE__, \ 91 SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \ 92 sudo_fatalx_nodebug_v1(__VA_ARGS__); \ 93 } while (0) 94 # define sudo_gai_fatal(en, ...) do { \ 95 sudo_debug_printf2(__func__, __FILE__, __LINE__, \ 96 SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \ 97 sudo_gai_fatal_nodebug_v1((en), __VA_ARGS__); \ 98 } while (0) 99 # define sudo_warn(...) do { \ 100 sudo_debug_printf2(__func__, __FILE__, __LINE__, \ 101 SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \ 102 __VA_ARGS__); \ 103 sudo_warn_nodebug_v1(__VA_ARGS__); \ 104 } while (0) 105 # define sudo_warnx(...) do { \ 106 sudo_debug_printf2(__func__, __FILE__, __LINE__, \ 107 SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \ 108 sudo_warnx_nodebug_v1(__VA_ARGS__); \ 109 } while (0) 110 # define sudo_gai_warn(en, ...) do { \ 111 sudo_debug_printf2(__func__, __FILE__, __LINE__, \ 112 SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__); \ 113 sudo_gai_warn_nodebug_v1((en), __VA_ARGS__); \ 114 } while (0) 115 # endif /* __GNUC__ == 2 */ 116 # define sudo_vfatal(fmt, ap) do { \ 117 va_list ap2; \ 118 va_copy(ap2, (ap)); \ 119 sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ 120 SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \ 121 (fmt), ap2); \ 122 sudo_vfatal_nodebug_v1((fmt), (ap)); \ 123 } while (0) 124 # define sudo_vfatalx(fmt, ap) do { \ 125 va_list ap2; \ 126 va_copy(ap2, (ap)); \ 127 sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ 128 SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2); \ 129 sudo_vfatalx_nodebug_v1((fmt), (ap)); \ 130 } while (0) 131 # define sudo_gai_vfatal(en, fmt, ap) do { \ 132 va_list ap2; \ 133 va_copy(ap2, (ap)); \ 134 sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ 135 SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2); \ 136 sudo_gai_vfatal_nodebug_v1((en), (fmt), (ap)); \ 137 } while (0) 138 # define sudo_vwarn(fmt, ap) do { \ 139 va_list ap2; \ 140 va_copy(ap2, (ap)); \ 141 sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ 142 SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \ 143 (fmt), ap2); \ 144 sudo_vwarn_nodebug_v1((fmt), (ap)); \ 145 } while (0) 146 # define sudo_vwarnx(fmt, ap) do { \ 147 va_list ap2; \ 148 va_copy(ap2, (ap)); \ 149 sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ 150 SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2); \ 151 sudo_vwarnx_nodebug_v1((fmt), (ap)); \ 152 } while (0) 153 # define sudo_gai_vwarn(en, fmt, ap) do { \ 154 va_list ap2; \ 155 va_copy(ap2, (ap)); \ 156 sudo_debug_vprintf2(__func__, __FILE__, __LINE__, \ 157 SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2); \ 158 sudo_gai_vwarn_nodebug_v1((en), (fmt), (ap)); \ 159 } while (0) 160 #endif /* SUDO_ERROR_WRAP */ 161 162 typedef void (*sudo_fatal_callback_t)(void); 163 typedef bool (*sudo_warn_setlocale_t)(bool, int *); 164 165 sudo_dso_public int sudo_fatal_callback_deregister_v1(sudo_fatal_callback_t func); 166 sudo_dso_public int sudo_fatal_callback_register_v1(sudo_fatal_callback_t func); 167 sudo_dso_public char *sudo_warn_gettext_v1(const char *domainname, const char *msgid) __format_arg(2); 168 sudo_dso_public void sudo_warn_set_locale_func_v1(sudo_warn_setlocale_t func); 169 sudo_dso_public void sudo_fatal_nodebug_v1(const char *fmt, ...) __printf0like(1, 2) __attribute__((__noreturn__)); 170 sudo_dso_public void sudo_fatalx_nodebug_v1(const char *fmt, ...) __printflike(1, 2) __attribute__((__noreturn__)); 171 sudo_dso_public void sudo_gai_fatal_nodebug_v1(int errnum, const char *fmt, ...) __printflike(2, 3) __attribute__((__noreturn__)); 172 sudo_dso_public void sudo_vfatal_nodebug_v1(const char *fmt, va_list ap) __printf0like(1, 0) __attribute__((__noreturn__)); 173 sudo_dso_public void sudo_vfatalx_nodebug_v1(const char *fmt, va_list ap) __printflike(1, 0) __attribute__((__noreturn__)); 174 sudo_dso_public void sudo_gai_vfatal_nodebug_v1(int errnum, const char *fmt, va_list ap) __printflike(2, 0) __attribute__((__noreturn__)); 175 sudo_dso_public void sudo_warn_nodebug_v1(const char *fmt, ...) __printf0like(1, 2); 176 sudo_dso_public void sudo_warnx_nodebug_v1(const char *fmt, ...) __printflike(1, 2); 177 sudo_dso_public void sudo_gai_warn_nodebug_v1(int errnum, const char *fmt, ...) __printflike(2, 3); 178 sudo_dso_public void sudo_vwarn_nodebug_v1(const char *fmt, va_list ap) __printf0like(1, 0); 179 sudo_dso_public void sudo_vwarnx_nodebug_v1(const char *fmt, va_list ap) __printflike(1, 0); 180 sudo_dso_public void sudo_gai_vwarn_nodebug_v1(int errnum, const char *fmt, va_list ap) __printflike(2, 0); 181 sudo_dso_public void sudo_warn_set_conversation_v1(sudo_conv_t conv); 182 183 #define sudo_fatal_callback_deregister(_a) sudo_fatal_callback_deregister_v1((_a)) 184 #define sudo_fatal_callback_register(_a) sudo_fatal_callback_register_v1((_a)) 185 #define sudo_warn_set_locale_func(_a) sudo_warn_set_locale_func_v1((_a)) 186 #define sudo_fatal_nodebug sudo_fatal_nodebug_v1 187 #define sudo_fatalx_nodebug sudo_fatalx_nodebug_v1 188 #define sudo_gai_fatal_nodebug sudo_gai_fatal_nodebug_v1 189 #define sudo_vfatal_nodebug(_a, _b) sudo_vfatal_nodebug_v1((_a), (_b)) 190 #define sudo_vfatalx_nodebug(_a, _b) sudo_vfatalx_nodebug_v1((_a), (_b)) 191 #define sudo_gai_vfatal_nodebug(_a, _b, _c) sudo_gai_vfatal_nodebug_v1((_a), (_b), (_c)) 192 #define sudo_warn_nodebug sudo_warn_nodebug_v1 193 #define sudo_warnx_nodebug sudo_warnx_nodebug_v1 194 #define sudo_gai_warn_nodebug sudo_gai_warn_nodebug_v1 195 #define sudo_vwarn_nodebug(_a, _b) sudo_vwarn_nodebug_v1((_a), (_b)) 196 #define sudo_vwarnx_nodebug(_a, _b) sudo_vwarnx_nodebug_v1((_a), (_b)) 197 #define sudo_gai_vwarn_nodebug(_a, _b, _c) sudo_gai_vwarn_nodebug_v1((_a), (_b), (_c)) 198 #define sudo_warn_set_conversation(_a) sudo_warn_set_conversation_v1(_a) 199 200 #ifdef DEFAULT_TEXT_DOMAIN 201 # define sudo_warn_gettext(_a) sudo_warn_gettext_v1(DEFAULT_TEXT_DOMAIN, (_a)) 202 #else 203 # define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a)) 204 #endif 205 206 #endif /* SUDO_FATAL_H */ 207