]> git.ipfire.org Git - thirdparty/lldpd.git/blame - src/log.c
log: don't use black for coloring DBG
[thirdparty/lldpd.git] / src / log.c
CommitLineData
4b292b55 1/* -*- mode: c; c-file-style: "openbsd" -*- */
43c02e7b
VB
2/* $OpenBSD: log.c,v 1.11 2007/12/07 17:17:00 reyk Exp $ */
3
4/*
5 * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
6 *
51434125 7 * Permission to use, copy, modify, and/or distribute this software for any
43c02e7b
VB
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
16 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
17 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
c9429a42 20#include <unistd.h>
43c02e7b 21#include <stdio.h>
4b292b55
VB
22#include <stdlib.h>
23#include <stdarg.h>
43c02e7b 24#include <syslog.h>
4b292b55
VB
25#include <sys/types.h>
26#include <string.h>
27#include <errno.h>
43c02e7b
VB
28#include <time.h>
29
4b292b55 30/* By default, logging is done on stderr. */
9856f279
VB
31static int use_syslog = 0;
32/* Default debug level */
33static int debug = 0;
4b292b55
VB
34
35/* Logging can be modified by providing an appropriate log handler. */
36static void (*logh)(int severity, const char *msg) = NULL;
43c02e7b 37
26fa5d17 38static void vlog(int, const char *, const char *, va_list);
6f8925be 39static void logit(int, const char *, const char *, ...);
43c02e7b 40
9e5d99d4 41#define MAX_DBG_TOKENS 40
dcf5d2f7 42static const char *tokens[MAX_DBG_TOKENS + 1] = {NULL};
9e5d99d4 43
43c02e7b 44void
9856f279 45log_init(int n_syslog, int n_debug, const char *progname)
43c02e7b 46{
9856f279 47 use_syslog = n_syslog;
43c02e7b
VB
48 debug = n_debug;
49
9856f279 50 if (use_syslog)
6bb9c4e0 51 openlog(progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
43c02e7b
VB
52
53 tzset();
54}
55
2389d2cc
VB
56void
57log_level(int n_debug)
58{
9856f279 59 if (n_debug >= 0)
2389d2cc
VB
60 debug = n_debug;
61}
62
4b292b55
VB
63void
64log_register(void (*cb)(int, const char*))
65{
66 logh = cb;
67}
68
9e5d99d4
VB
69void
70log_accept(const char *token)
71{
72 int i;
73 for (i = 0; i < MAX_DBG_TOKENS; i++) {
74 if (tokens[i] == NULL) {
75 tokens[i+1] = NULL;
76 tokens[i] = token;
77 return;
78 }
79 }
80}
4b292b55 81
8888d191 82static void
6f8925be 83logit(int pri, const char *token, const char *fmt, ...)
43c02e7b
VB
84{
85 va_list ap;
86
87 va_start(ap, fmt);
6f8925be 88 vlog(pri, token, fmt, ap);
43c02e7b
VB
89 va_end(ap);
90}
91
c9429a42
VB
92static char *
93date()
94{
95 /* Return the current date as incomplete ISO 8601 (2012-12-12T16:13:30) */
96 static char date[] = "2012-12-12T16:13:30";
97 time_t t = time(NULL);
98 struct tm *tmp = localtime(&t);
99 strftime(date, sizeof(date), "%Y-%m-%dT%H:%M:%S", tmp);
100 return date;
101}
102
103static const char *
104translate(int fd, int priority)
105{
106 /* Translate a syslog priority to a string. With colors if the output is a terminal. */
107 int tty = isatty(fd);
108 switch (tty) {
109 case 1:
110 switch (priority) {
26fa5d17
VB
111 case LOG_EMERG: return "\033[1;37;41m[EMRG";
112 case LOG_ALERT: return "\033[1;37;41m[ALRT";
113 case LOG_CRIT: return "\033[1;37;41m[CRIT";
114 case LOG_ERR: return "\033[1;31m[ ERR";
115 case LOG_WARNING: return "\033[1;33m[WARN";
116 case LOG_NOTICE: return "\033[1;34m[NOTI";
117 case LOG_INFO: return "\033[1;34m[INFO";
5c969283 118 case LOG_DEBUG: return "\033[36m[ DBG";
c9429a42
VB
119 }
120 break;
121 default:
122 switch (priority) {
26fa5d17
VB
123 case LOG_EMERG: return "[EMRG";
124 case LOG_ALERT: return "[ALRT";
125 case LOG_CRIT: return "[CRIT";
126 case LOG_ERR: return "[ ERR";
127 case LOG_WARNING: return "[WARN";
128 case LOG_NOTICE: return "[NOTI";
129 case LOG_INFO: return "[INFO";
130 case LOG_DEBUG: return "[ DBG";
c9429a42
VB
131 }
132 }
133 return "[UNKN]";
134}
135
8888d191 136static void
26fa5d17 137vlog(int pri, const char *token, const char *fmt, va_list ap)
43c02e7b 138{
4b292b55
VB
139 if (logh) {
140 char *result;
141 if (vasprintf(&result, fmt, ap) != -1) {
142 logh(pri, result);
bea70314 143 free(result);
4b292b55
VB
144 return;
145 }
5aae2522
VB
146 /* Otherwise, abort. We don't know if "ap" is still OK. We could
147 * have made a copy, but this is too much overhead for a
148 * situation that shouldn't happen. */
149 return;
150 }
151
ae8e632a
VB
152 /* Log to syslog if requested */
153 if (use_syslog) {
154 va_list ap2;
155 va_copy(ap2, ap);
156 vsyslog(pri, fmt, ap2);
157 va_end(ap2);
4b292b55 158 }
b5463687
VB
159
160 /* Log to standard error in all cases */
161 char *nfmt;
162 /* best effort in out of mem situations */
163 if (asprintf(&nfmt, "%s %s%s%s]%s %s\n",
164 date(),
165 translate(STDERR_FILENO, pri),
166 token ? "/" : "", token ? token : "",
167 isatty(STDERR_FILENO) ? "\033[0m" : "",
168 fmt) == -1) {
169 vfprintf(stderr, fmt, ap);
170 fprintf(stderr, "\n");
171 } else {
172 vfprintf(stderr, nfmt, ap);
173 free(nfmt);
174 }
175 fflush(stderr);
43c02e7b
VB
176}
177
178
179void
26fa5d17 180log_warn(const char *token, const char *emsg, ...)
43c02e7b
VB
181{
182 char *nfmt;
183 va_list ap;
184
185 /* best effort to even work in out of memory situations */
186 if (emsg == NULL)
c9429a42 187 logit(LOG_WARNING, "%s", strerror(errno));
43c02e7b
VB
188 else {
189 va_start(ap, emsg);
190
191 if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
192 /* we tried it... */
26fa5d17 193 vlog(LOG_WARNING, token, emsg, ap);
c9429a42 194 logit(LOG_WARNING, "%s", strerror(errno));
43c02e7b 195 } else {
26fa5d17 196 vlog(LOG_WARNING, token, nfmt, ap);
43c02e7b
VB
197 free(nfmt);
198 }
199 va_end(ap);
200 }
201}
202
203void
26fa5d17 204log_warnx(const char *token, const char *emsg, ...)
43c02e7b
VB
205{
206 va_list ap;
207
208 va_start(ap, emsg);
26fa5d17 209 vlog(LOG_WARNING, token, emsg, ap);
43c02e7b
VB
210 va_end(ap);
211}
212
213void
26fa5d17 214log_info(const char *token, const char *emsg, ...)
43c02e7b
VB
215{
216 va_list ap;
217
9856f279 218 if (use_syslog || debug > 0 || logh) {
e595efb4
VB
219 va_start(ap, emsg);
220 vlog(LOG_INFO, token, emsg, ap);
221 va_end(ap);
222 }
43c02e7b
VB
223}
224
9e5d99d4
VB
225static int
226log_debug_accept_token(const char *token)
227{
228 int i;
229 if (tokens[0] == NULL) return 1;
230 for (i = 0;
231 (i < MAX_DBG_TOKENS) && (tokens[i] != NULL);
232 i++) {
233 if (!strcmp(tokens[i], token))
234 return 1;
235 }
236 return 0;
237}
238
43c02e7b 239void
26fa5d17 240log_debug(const char *token, const char *emsg, ...)
43c02e7b
VB
241{
242 va_list ap;
243
9856f279 244 if ((debug > 1 && log_debug_accept_token(token)) || logh) {
43c02e7b 245 va_start(ap, emsg);
26fa5d17 246 vlog(LOG_DEBUG, token, emsg, ap);
43c02e7b
VB
247 va_end(ap);
248 }
249}
250
251void
6f8925be 252fatal(const char *token, const char *emsg)
43c02e7b
VB
253{
254 if (emsg == NULL)
6f8925be 255 logit(LOG_CRIT, token ? token : "fatal", "%s", strerror(errno));
43c02e7b
VB
256 else
257 if (errno)
6f8925be 258 logit(LOG_CRIT, token ? token : "fatal", "%s: %s",
43c02e7b
VB
259 emsg, strerror(errno));
260 else
6f8925be 261 logit(LOG_CRIT, token ? token : "fatal", "%s", emsg);
43c02e7b
VB
262
263 exit(1);
264}
265
266void
a87db231 267fatalx(const char *token, const char *emsg)
43c02e7b
VB
268{
269 errno = 0;
a87db231 270 fatal(token, emsg);
43c02e7b 271}