1/*	$NetBSD$	*/
2
3/*
4 * Copyright (c) 1997 - 2001 Kungliga Tekniska H��gskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the Institute nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#include "krb5_locl.h"
37#include <err.h>
38
39static krb5_error_code _warnerr(krb5_context context, int do_errtext,
40	 krb5_error_code code, int level, const char *fmt, va_list ap)
41	__attribute__((__format__(__printf__, 5, 0)));
42
43static krb5_error_code
44_warnerr(krb5_context context, int do_errtext,
45	 krb5_error_code code, int level, const char *fmt, va_list ap)
46{
47    char xfmt[7] = "";
48    const char *args[2], **arg;
49    char *msg = NULL;
50    const char *err_str = NULL;
51    krb5_error_code ret;
52
53    args[0] = args[1] = NULL;
54    arg = args;
55    if(fmt){
56	strlcat(xfmt, "%s", sizeof(xfmt));
57	if(do_errtext)
58	    strlcat(xfmt, ": ", sizeof(xfmt));
59	ret = vasprintf(&msg, fmt, ap);
60	if(ret < 0 || msg == NULL)
61	    return ENOMEM;
62	*arg++ = msg;
63    }
64    if(context && do_errtext){
65	strlcat(xfmt, "%s", sizeof(xfmt));
66
67	err_str = krb5_get_error_message(context, code);
68	if (err_str != NULL) {
69	    *arg = err_str;
70	} else {
71	    *arg= "<unknown error>";
72	}
73    }
74
75    if(context && context->warn_dest)
76	krb5_log(context, context->warn_dest, level, xfmt, args[0], args[1]);
77    else
78	warnx(xfmt, args[0], args[1]);
79    free(msg);
80    krb5_free_error_message(context, err_str);
81    return 0;
82}
83
84#define FUNC(ETEXT, CODE, LEVEL)					\
85    krb5_error_code ret;						\
86    va_list ap;								\
87    va_start(ap, fmt);							\
88    ret = _warnerr(context, ETEXT, CODE, LEVEL, fmt, ap); 		\
89    va_end(ap);
90
91#undef __attribute__
92#define __attribute__(X)
93
94/**
95 * Log a warning to the log, default stderr, include the error from
96 * the last failure.
97 *
98 * @param context A Kerberos 5 context.
99 * @param code error code of the last error
100 * @param fmt message to print
101 * @param ap arguments
102 *
103 * @ingroup krb5_error
104 */
105
106KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
107krb5_vwarn(krb5_context context, krb5_error_code code,
108	   const char *fmt, va_list ap)
109     __attribute__ ((format (printf, 3, 0)))
110{
111    return _warnerr(context, 1, code, 1, fmt, ap);
112}
113
114/**
115 * Log a warning to the log, default stderr, include the error from
116 * the last failure.
117 *
118 * @param context A Kerberos 5 context.
119 * @param code error code of the last error
120 * @param fmt message to print
121 *
122 * @ingroup krb5_error
123 */
124
125KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
126krb5_warn(krb5_context context, krb5_error_code code, const char *fmt, ...)
127     __attribute__ ((format (printf, 3, 4)))
128{
129    FUNC(1, code, 1);
130    return ret;
131}
132
133/**
134 * Log a warning to the log, default stderr.
135 *
136 * @param context A Kerberos 5 context.
137 * @param fmt message to print
138 * @param ap arguments
139 *
140 * @ingroup krb5_error
141 */
142
143KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
144krb5_vwarnx(krb5_context context, const char *fmt, va_list ap)
145     __attribute__ ((format (printf, 2, 0)))
146{
147    return _warnerr(context, 0, 0, 1, fmt, ap);
148}
149
150/**
151 * Log a warning to the log, default stderr.
152 *
153 * @param context A Kerberos 5 context.
154 * @param fmt message to print
155 *
156 * @ingroup krb5_error
157 */
158
159KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
160krb5_warnx(krb5_context context, const char *fmt, ...)
161     __attribute__ ((format (printf, 2, 3)))
162{
163    FUNC(0, 0, 1);
164    return ret;
165}
166
167/**
168 * Log a warning to the log, default stderr, include bthe error from
169 * the last failure and then exit.
170 *
171 * @param context A Kerberos 5 context
172 * @param eval the exit code to exit with
173 * @param code error code of the last error
174 * @param fmt message to print
175 * @param ap arguments
176 *
177 * @ingroup krb5_error
178 */
179
180KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
181krb5_verr(krb5_context context, int eval, krb5_error_code code,
182	  const char *fmt, va_list ap)
183     __attribute__ ((noreturn, format (printf, 4, 0)))
184{
185    _warnerr(context, 1, code, 0, fmt, ap);
186    exit(eval);
187    UNREACHABLE(return 0);
188}
189
190/**
191 * Log a warning to the log, default stderr, include bthe error from
192 * the last failure and then exit.
193 *
194 * @param context A Kerberos 5 context
195 * @param eval the exit code to exit with
196 * @param code error code of the last error
197 * @param fmt message to print
198 *
199 * @ingroup krb5_error
200 */
201
202KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
203krb5_err(krb5_context context, int eval, krb5_error_code code,
204	 const char *fmt, ...)
205     __attribute__ ((noreturn, format (printf, 4, 5)))
206{
207    FUNC(1, code, 0);
208    exit(eval);
209    UNREACHABLE(return 0);
210}
211
212/**
213 * Log a warning to the log, default stderr, and then exit.
214 *
215 * @param context A Kerberos 5 context
216 * @param eval the exit code to exit with
217 * @param fmt message to print
218 * @param ap arguments
219 *
220 * @ingroup krb5_error
221 */
222
223KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
224krb5_verrx(krb5_context context, int eval, const char *fmt, va_list ap)
225     __attribute__ ((noreturn, format (printf, 3, 0)))
226{
227    _warnerr(context, 0, 0, 0, fmt, ap);
228    exit(eval);
229    UNREACHABLE(return 0);
230}
231
232/**
233 * Log a warning to the log, default stderr, and then exit.
234 *
235 * @param context A Kerberos 5 context
236 * @param eval the exit code to exit with
237 * @param fmt message to print
238 *
239 * @ingroup krb5_error
240 */
241
242KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
243krb5_errx(krb5_context context, int eval, const char *fmt, ...)
244     __attribute__ ((noreturn, format (printf, 3, 4)))
245{
246    FUNC(0, 0, 0);
247    exit(eval);
248    UNREACHABLE(return 0);
249}
250
251/**
252 * Log a warning to the log, default stderr, include bthe error from
253 * the last failure and then abort.
254 *
255 * @param context A Kerberos 5 context
256 * @param code error code of the last error
257 * @param fmt message to print
258 * @param ap arguments
259 *
260 * @ingroup krb5_error
261 */
262
263KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
264krb5_vabort(krb5_context context, krb5_error_code code,
265	    const char *fmt, va_list ap)
266     __attribute__ ((noreturn, format (printf, 3, 0)))
267{
268    _warnerr(context, 1, code, 0, fmt, ap);
269    abort();
270    UNREACHABLE(return 0);
271}
272
273/**
274 * Log a warning to the log, default stderr, include the error from
275 * the last failure and then abort.
276 *
277 * @param context A Kerberos 5 context
278 * @param code error code of the last error
279 * @param fmt message to print
280 *
281 * @ingroup krb5_error
282 */
283
284KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
285krb5_abort(krb5_context context, krb5_error_code code, const char *fmt, ...)
286     __attribute__ ((noreturn, format (printf, 3, 4)))
287{
288    FUNC(1, code, 0);
289    abort();
290    UNREACHABLE(return 0);
291}
292
293KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
294krb5_vabortx(krb5_context context, const char *fmt, va_list ap)
295     __attribute__ ((noreturn, format (printf, 2, 0)))
296{
297    _warnerr(context, 0, 0, 0, fmt, ap);
298    abort();
299    UNREACHABLE(return 0);
300}
301
302/**
303 * Log a warning to the log, default stderr, and then abort.
304 *
305 * @param context A Kerberos 5 context
306 * @param code error code of the last error
307 * @param fmt message to print
308 *
309 * @ingroup krb5_error
310 */
311
312KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
313krb5_abortx(krb5_context context, const char *fmt, ...)
314     __attribute__ ((noreturn, format (printf, 2, 3)))
315{
316    FUNC(0, 0, 0);
317    abort();
318    UNREACHABLE(return 0);
319}
320
321/**
322 * Set the default logging facility.
323 *
324 * @param context A Kerberos 5 context
325 * @param fac Facility to use for logging.
326 *
327 * @ingroup krb5_error
328 */
329
330KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
331krb5_set_warn_dest(krb5_context context, krb5_log_facility *fac)
332{
333    context->warn_dest = fac;
334    return 0;
335}
336
337/**
338 * Get the default logging facility.
339 *
340 * @param context A Kerberos 5 context
341 *
342 * @ingroup krb5_error
343 */
344
345KRB5_LIB_FUNCTION krb5_log_facility * KRB5_LIB_CALL
346krb5_get_warn_dest(krb5_context context)
347{
348    return context->warn_dest;
349}
350