3d9f84cd64e0e11ab9430cb8ea4d306bb411d653
[debian/sudo] / plugins / sudoers / plugin_error.c
1 /*
2  * Copyright (c) 2004-2005, 2010 Todd C. Miller <Todd.Miller@courtesan.com>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <config.h>
18
19 #include <sys/types.h>
20
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <setjmp.h>
26
27 #include "missing.h"
28 #include "alloc.h"
29 #include "error.h"
30 #include "sudo_plugin.h"
31
32 #define DEFAULT_TEXT_DOMAIN     "sudoers"
33 #include "gettext.h"
34
35 static void _warning(int, const char *, va_list);
36        void plugin_cleanup(int);
37
38 sigjmp_buf error_jmp;
39
40 extern sudo_conv_t sudo_conv;
41
42 void
43 error(int eval, const char *fmt, ...)
44 {
45     va_list ap;
46
47     va_start(ap, fmt);
48     _warning(1, fmt, ap);
49     va_end(ap);
50     plugin_cleanup(0);
51     siglongjmp(error_jmp, eval);
52 }
53
54 void
55 errorx(int eval, const char *fmt, ...)
56 {
57     va_list ap;
58
59     va_start(ap, fmt);
60     _warning(0, fmt, ap);
61     va_end(ap);
62     plugin_cleanup(0);
63     siglongjmp(error_jmp, eval);
64 }
65
66 void
67 warning(const char *fmt, ...)
68 {
69     va_list ap;
70
71     va_start(ap, fmt);
72     _warning(1, fmt, ap);
73     va_end(ap);
74 }
75
76 void
77 warningx(const char *fmt, ...)
78 {
79     va_list ap;
80     va_start(ap, fmt);
81     _warning(0, fmt, ap);
82     va_end(ap);
83 }
84
85 static void
86 _warning(int use_errno, const char *fmt, va_list ap)
87 {
88     struct sudo_conv_message msg[6];
89     struct sudo_conv_reply repl[6];
90     char *str;
91     int nmsgs = 4;
92
93     evasprintf(&str, fmt, ap);
94
95     /* Call conversation function */
96     memset(&msg, 0, sizeof(msg));
97     msg[0].msg_type = SUDO_CONV_ERROR_MSG;
98     msg[0].msg = getprogname();
99     msg[1].msg_type = SUDO_CONV_ERROR_MSG;
100     msg[1].msg = _(": ");
101     msg[2].msg_type = SUDO_CONV_ERROR_MSG;
102     msg[2].msg = str;
103     if (use_errno) {
104         msg[3].msg_type = SUDO_CONV_ERROR_MSG;
105         msg[3].msg = _(": ");
106         msg[4].msg_type = SUDO_CONV_ERROR_MSG;
107         msg[4].msg = strerror(errno);
108         nmsgs = 6;
109     }
110     msg[nmsgs - 1].msg_type = SUDO_CONV_ERROR_MSG;
111     msg[nmsgs - 1].msg = "\n";
112     memset(&repl, 0, sizeof(repl));
113     sudo_conv(nmsgs, msg, repl);
114     efree(str);
115 }