Log Kerberos errors consistently
[mspang/pyceo.git] / src / util.c
1 #include <unistd.h>
2 #include <sys/wait.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <stdarg.h>
6 #include <syslog.h>
7 #include <errno.h>
8
9 #include "util.h"
10
11 static char message[4096];
12
13 static int log_stderr = 1;
14
15 void init_log(const char *ident, int option, int facility) {
16     openlog(ident, option, facility);
17     log_stderr = isatty(STDERR_FILENO);
18 }
19
20 static void errmsg(int prio, const char *prefix, const char *fmt, va_list args) {
21     char *msgp = message;
22
23     msgp +=  snprintf(msgp, sizeof(message) - 2 - (msgp - message), "%s: ", prefix);
24     if (msgp - message > sizeof(message) - 2)
25         fatal("error message overflowed");
26
27     msgp += vsnprintf(msgp, sizeof(message) - 2 - (msgp - message), fmt, args);
28     if (msgp - message > sizeof(message) - 2)
29         fatal("error message overflowed");
30
31     *msgp++ = '\n';
32     *msgp++ = '\0';
33
34     syslog(prio, "%s", message);
35     if (log_stderr)
36         fputs(message, stderr);
37 }
38
39 static void errmsgpe(int prio, const char *prefix, const char *fmt, va_list args) {
40     char *msgp = message;
41
42     msgp += snprintf(msgp, sizeof(message) - 2 - (msgp - message), "%s: ", prefix);
43     if (msgp - message > sizeof(message) - 2)
44         fatal("error message overflowed");
45
46     msgp += vsnprintf(msgp, sizeof(message) - 2 - (msgp - message), fmt, args);
47     if (msgp - message > sizeof(message) - 2)
48         fatal("error message overflowed");
49
50     msgp += snprintf(msgp, sizeof(message) - 2 - (msgp - message), ": %s", strerror(errno));
51     if (msgp - message > sizeof(message) - 2)
52         fatal("error message overflowed");
53
54     *msgp++ = '\n';
55     *msgp++ = '\0';
56
57     syslog(prio, "%s", message);
58     if (log_stderr)
59         fputs(message, stderr);
60 }
61
62 NORETURN static void die(int prio, const char *prefix, const char *msg, va_list args) {
63     errmsg(prio, prefix, msg, args);
64     exit(1);
65 }
66
67 NORETURN static void diepe(int prio, const char *prefix, const char *msg, va_list args) {
68     errmsgpe(prio, prefix, msg, args);
69     exit(1);
70 }
71
72 NORETURN void fatal(const char *msg, ...) {
73     va_list args;
74     va_start(args, msg);
75     die(LOG_CRIT, "fatal", msg, args);
76     va_end(args);
77 }
78
79 void error(const char *msg, ...) {
80     va_list args;
81     va_start(args, msg);
82     errmsg(LOG_ERR, "error", msg, args);
83     va_end(args);
84 }
85
86 void warn(const char *msg, ...) {
87     va_list args;
88     va_start(args, msg);
89     errmsg(LOG_WARNING, "warning", msg, args);
90     va_end(args);
91 }
92
93 void notice(const char *msg, ...) {
94     va_list args;
95     va_start(args, msg);
96     errmsg(LOG_NOTICE, "notice", msg, args);
97     va_end(args);
98 }
99
100 void debug(const char *msg, ...) {
101     va_list args;
102     va_start(args, msg);
103     errmsg(LOG_DEBUG, "debug", msg, args);
104     va_end(args);
105 }
106
107 void logmsg(int priority, const char *msg, ...) {
108     va_list args;
109     va_start(args, msg);
110     vsyslog(priority, msg, args);
111     va_end(args);
112     va_start(args, msg);
113     if (log_stderr) {
114         vfprintf(stderr, msg, args);
115         fputc('\n', stderr);
116     }
117     va_end(args);
118 }
119
120 NORETURN void deny(const char *msg, ...) {
121     va_list args;
122     va_start(args, msg);
123     die(LOG_ERR, "denied", msg, args);
124     va_end(args);
125 }
126
127 NORETURN void badconf(const char *msg, ...) {
128     va_list args;
129     va_start(args, msg);
130     die(LOG_CRIT, "configuration error", msg, args);
131     va_end(args);
132 }
133
134 NORETURN void fatalpe(const char *msg, ...) {
135     va_list args;
136     va_start(args, msg);
137     diepe(LOG_CRIT, "fatal", msg, args);
138     va_end(args);
139 }
140
141 void errorpe(const char *msg, ...) {
142     va_list args;
143     va_start(args, msg);
144     errmsgpe(LOG_ERR, "error", msg, args);
145     va_end(args);
146 }
147
148 void warnpe(const char *msg, ...) {
149     va_list args;
150     va_start(args, msg);
151     errmsgpe(LOG_WARNING, "warning", msg, args);
152     va_end(args);
153 }
154
155 int spawnv(const char *path, char *argv[]) {
156     int pid, status;
157     pid = fork();
158     if (pid == -1)
159         fatalpe("fork");
160     else if (pid)
161         waitpid(pid, &status, 0);
162     else
163         exit(execv(path, argv));
164     return status;
165 }