summaryrefslogtreecommitdiffstats
path: root/include/sudo_fatal.h
blob: 0819e634b2aa69672bee9f1891729eaedccd4b26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
/*
 * SPDX-License-Identifier: ISC
 *
 * Copyright (c) 2004, 2010-2015, 2017-2018 Todd C. Miller <Todd.Miller@sudo.ws>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef SUDO_FATAL_H
#define	SUDO_FATAL_H

#include <stdarg.h>
#ifdef HAVE_STDBOOL_H
# include <stdbool.h>
#else
# include "compat/stdbool.h"
#endif /* HAVE_STDBOOL_H */

#include "sudo_plugin.h"	/* for conversation function */

/* No output to debug files when fuzzing. */
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
# define SUDO_ERROR_WRAP 0
#endif

/*
 * We wrap fatal/fatalx and warn/warnx so that the same output can
 * go to the debug file, if there is one.
 */
#if (defined(SUDO_ERROR_WRAP) && SUDO_ERROR_WRAP == 0) || defined(NO_VARIADIC_MACROS)
# define sudo_fatal sudo_fatal_nodebug_v1
# define sudo_fatalx sudo_fatalx_nodebug_v1
# define sudo_gai_fatal sudo_gai_fatal_nodebug_v1
# define sudo_warn sudo_warn_nodebug_v1
# define sudo_warnx sudo_warnx_nodebug_v1
# define sudo_gai_warn sudo_gai_warn_nodebug_v1
# define sudo_vfatal(fmt, ap) sudo_vfatal_nodebug_v1((fmt), (ap))
# define sudo_vfatalx(fmt, ap) sudo_vfatalx_nodebug_v1((fmt), (ap))
# define sudo_gai_vfatal(en, fmt, ap) sudo_vfatal_nodebug_v1((en), (fmt), (ap))
# define sudo_vwarn(fmt, ap) sudo_vwarn_nodebug_v1((fmt), (ap))
# define sudo_vwarnx(fmt, ap) sudo_vwarnx_nodebug_v1((fmt), (ap))
# define sudo_gai_vwarn(en, fmt, ap) sudo_vwarn_nodebug_v1((en), (fmt), (ap))
#else /* SUDO_ERROR_WRAP */
# if defined(__GNUC__) && __GNUC__ == 2
#  define sudo_fatal(fmt...) do {					       \
    sudo_debug_printf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
	fmt);								       \
    sudo_fatal_nodebug_v1(fmt);						       \
} while (0)
#  define sudo_fatalx(fmt...) do {					       \
    sudo_debug_printf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt);	       \
    sudo_fatalx_nodebug_v1(fmt);					       \
} while (0)
#  define sudo_gai_fatal(en, fmt...) do {				       \
    sudo_debug_printf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt);	       \
    sudo_gai_fatal_nodebug_v1((en), fmt);				       \
} while (0)
#  define sudo_warn(fmt...) do {					       \
    sudo_debug_printf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
	fmt);								       \
    sudo_warn_nodebug_v1(fmt);						       \
} while (0)
#  define sudo_warnx(fmt...) do {					       \
    sudo_debug_printf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt);	       \
    sudo_warnx_nodebug_v1(fmt);						       \
} while (0)
#  define sudo_gai_warn(en, fmt...) do {				       \
    sudo_debug_printf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, fmt);	       \
    sudo_gai_warn_nodebug_v1((en), fmt);				       \
} while (0)
# else
#  define sudo_fatal(...) do {						       \
    sudo_debug_printf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
	__VA_ARGS__);							       \
    sudo_fatal_nodebug_v1(__VA_ARGS__);					       \
} while (0)
#  define sudo_fatalx(...) do {						       \
    sudo_debug_printf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__);    \
    sudo_fatalx_nodebug_v1(__VA_ARGS__);				       \
} while (0)
#  define sudo_gai_fatal(en, ...) do {					       \
    sudo_debug_printf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__);    \
    sudo_gai_fatal_nodebug_v1((en), __VA_ARGS__);			       \
} while (0)
#  define sudo_warn(...) do {						       \
    sudo_debug_printf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys,  \
	__VA_ARGS__);							       \
    sudo_warn_nodebug_v1(__VA_ARGS__);					       \
} while (0)
#  define sudo_warnx(...) do {						       \
    sudo_debug_printf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__);     \
    sudo_warnx_nodebug_v1(__VA_ARGS__);					       \
} while (0)
#  define sudo_gai_warn(en, ...) do {					       \
    sudo_debug_printf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, __VA_ARGS__);     \
    sudo_gai_warn_nodebug_v1((en), __VA_ARGS__);			       \
} while (0)
# endif /* __GNUC__ == 2 */
# define sudo_vfatal(fmt, ap) do {					       \
    va_list ap2;							       \
    va_copy(ap2, (ap));							       \
    sudo_debug_vprintf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys, \
	(fmt), ap2);							       \
    sudo_vfatal_nodebug_v1((fmt), (ap));					       \
} while (0)
# define sudo_vfatalx(fmt, ap) do {					       \
    va_list ap2;							       \
    va_copy(ap2, (ap));							       \
    sudo_debug_vprintf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2);     \
    sudo_vfatalx_nodebug_v1((fmt), (ap));				       \
} while (0)
# define sudo_gai_vfatal(en, fmt, ap) do {				       \
    va_list ap2;							       \
    va_copy(ap2, (ap));							       \
    sudo_debug_vprintf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2);     \
    sudo_gai_vfatal_nodebug_v1((en), (fmt), (ap));			       \
} while (0)
# define sudo_vwarn(fmt, ap) do {					       \
    va_list ap2;							       \
    va_copy(ap2, (ap));							       \
    sudo_debug_vprintf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO|sudo_debug_subsys,  \
	(fmt), ap2);							       \
    sudo_vwarn_nodebug_v1((fmt), (ap));					       \
} while (0)
# define sudo_vwarnx(fmt, ap) do {					       \
    va_list ap2;							       \
    va_copy(ap2, (ap));							       \
    sudo_debug_vprintf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2);      \
    sudo_vwarnx_nodebug_v1((fmt), (ap));				       \
} while (0)
# define sudo_gai_vwarn(en, fmt, ap) do {				       \
    va_list ap2;							       \
    va_copy(ap2, (ap));							       \
    sudo_debug_vprintf2(__func__, __FILE__, __LINE__,			       \
	SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|sudo_debug_subsys, (fmt), ap2);      \
    sudo_gai_vwarn_nodebug_v1((en), (fmt), (ap));			       \
} while (0)
#endif /* SUDO_ERROR_WRAP */

typedef void (*sudo_fatal_callback_t)(void);
typedef bool (*sudo_warn_setlocale_t)(bool, int *);

sudo_dso_public int  sudo_fatal_callback_deregister_v1(sudo_fatal_callback_t func);
sudo_dso_public int  sudo_fatal_callback_register_v1(sudo_fatal_callback_t func);
sudo_dso_public char *sudo_warn_gettext_v1(const char *domainname, const char *msgid) sudo_attr_fmt_arg(2);
sudo_dso_public void sudo_warn_set_locale_func_v1(sudo_warn_setlocale_t func);
sudo_noreturn sudo_dso_public void sudo_fatal_nodebug_v1(const char *fmt, ...) sudo_printf0like(1, 2);
sudo_noreturn sudo_dso_public void sudo_fatalx_nodebug_v1(const char *fmt, ...) sudo_printflike(1, 2);
sudo_noreturn sudo_dso_public void sudo_gai_fatal_nodebug_v1(int errnum, const char *fmt, ...) sudo_printflike(2, 3);
sudo_noreturn sudo_dso_public void sudo_vfatal_nodebug_v1(const char *fmt, va_list ap) sudo_printf0like(1, 0);
sudo_noreturn sudo_dso_public void sudo_vfatalx_nodebug_v1(const char *fmt, va_list ap) sudo_printflike(1, 0);
sudo_noreturn sudo_dso_public void sudo_gai_vfatal_nodebug_v1(int errnum, const char *fmt, va_list ap) sudo_printflike(2, 0);
sudo_dso_public void sudo_warn_nodebug_v1(const char *fmt, ...) sudo_printf0like(1, 2);
sudo_dso_public void sudo_warnx_nodebug_v1(const char *fmt, ...) sudo_printflike(1, 2);
sudo_dso_public void sudo_gai_warn_nodebug_v1(int errnum, const char *fmt, ...) sudo_printflike(2, 3);
sudo_dso_public void sudo_vwarn_nodebug_v1(const char *fmt, va_list ap) sudo_printf0like(1, 0);
sudo_dso_public void sudo_vwarnx_nodebug_v1(const char *fmt, va_list ap) sudo_printflike(1, 0);
sudo_dso_public void sudo_gai_vwarn_nodebug_v1(int errnum, const char *fmt, va_list ap) sudo_printflike(2, 0);
sudo_dso_public void sudo_warn_set_conversation_v1(sudo_conv_t conv);

#define sudo_fatal_callback_deregister(_a) sudo_fatal_callback_deregister_v1((_a))
#define sudo_fatal_callback_register(_a) sudo_fatal_callback_register_v1((_a))
#define sudo_warn_set_locale_func(_a) sudo_warn_set_locale_func_v1((_a))
#define sudo_fatal_nodebug sudo_fatal_nodebug_v1
#define sudo_fatalx_nodebug sudo_fatalx_nodebug_v1
#define sudo_gai_fatal_nodebug sudo_gai_fatal_nodebug_v1
#define sudo_vfatal_nodebug(_a, _b) sudo_vfatal_nodebug_v1((_a), (_b))
#define sudo_vfatalx_nodebug(_a, _b) sudo_vfatalx_nodebug_v1((_a), (_b))
#define sudo_gai_vfatal_nodebug(_a, _b, _c) sudo_gai_vfatal_nodebug_v1((_a), (_b), (_c))
#define sudo_warn_nodebug sudo_warn_nodebug_v1
#define sudo_warnx_nodebug sudo_warnx_nodebug_v1
#define sudo_gai_warn_nodebug sudo_gai_warn_nodebug_v1
#define sudo_vwarn_nodebug(_a, _b) sudo_vwarn_nodebug_v1((_a), (_b))
#define sudo_vwarnx_nodebug(_a, _b) sudo_vwarnx_nodebug_v1((_a), (_b))
#define sudo_gai_vwarn_nodebug(_a, _b, _c) sudo_gai_vwarn_nodebug_v1((_a), (_b), (_c))
#define sudo_warn_set_conversation(_a) sudo_warn_set_conversation_v1(_a)

#ifdef DEFAULT_TEXT_DOMAIN
# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(DEFAULT_TEXT_DOMAIN, (_a))
#else
# define sudo_warn_gettext(_a) sudo_warn_gettext_v1(NULL, (_a))
#endif

#endif /* SUDO_FATAL_H */