]> git.ipfire.org Git - thirdparty/lldpd.git/blame - src/log.c
osx: also use /sbin/nologin as default shell
[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
VB
30/* By default, logging is done on stderr. */
31static int debug = 1;
32
33/* Logging can be modified by providing an appropriate log handler. */
34static void (*logh)(int severity, const char *msg) = NULL;
43c02e7b 35
26fa5d17 36static void vlog(int, const char *, const char *, va_list);
6f8925be 37static void logit(int, const char *, const char *, ...);
43c02e7b 38
9e5d99d4 39#define MAX_DBG_TOKENS 40
dcf5d2f7 40static const char *tokens[MAX_DBG_TOKENS + 1] = {NULL};
9e5d99d4 41
43c02e7b 42void
6bb9c4e0 43log_init(int n_debug, const char *progname)
43c02e7b 44{
43c02e7b
VB
45 debug = n_debug;
46
47 if (!debug)
6bb9c4e0 48 openlog(progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
43c02e7b
VB
49
50 tzset();
51}
52
2389d2cc
VB
53void
54log_level(int n_debug)
55{
56 if (debug > 0 && n_debug >= 1)
57 debug = n_debug;
58}
59
4b292b55
VB
60void
61log_register(void (*cb)(int, const char*))
62{
63 logh = cb;
64}
65
9e5d99d4
VB
66void
67log_accept(const char *token)
68{
69 int i;
70 for (i = 0; i < MAX_DBG_TOKENS; i++) {
71 if (tokens[i] == NULL) {
72 tokens[i+1] = NULL;
73 tokens[i] = token;
74 return;
75 }
76 }
77}
4b292b55 78
8888d191 79static void
6f8925be 80logit(int pri, const char *token, const char *fmt, ...)
43c02e7b
VB
81{
82 va_list ap;
83
84 va_start(ap, fmt);
6f8925be 85 vlog(pri, token, fmt, ap);
43c02e7b
VB
86 va_end(ap);
87}
88
c9429a42
VB
89static char *
90date()
91{
92 /* Return the current date as incomplete ISO 8601 (2012-12-12T16:13:30) */
93 static char date[] = "2012-12-12T16:13:30";
94 time_t t = time(NULL);
95 struct tm *tmp = localtime(&t);
96 strftime(date, sizeof(date), "%Y-%m-%dT%H:%M:%S", tmp);
97 return date;
98}
99
100static const char *
101translate(int fd, int priority)
102{
103 /* Translate a syslog priority to a string. With colors if the output is a terminal. */
104 int tty = isatty(fd);
105 switch (tty) {
106 case 1:
107 switch (priority) {
26fa5d17
VB
108 case LOG_EMERG: return "\033[1;37;41m[EMRG";
109 case LOG_ALERT: return "\033[1;37;41m[ALRT";
110 case LOG_CRIT: return "\033[1;37;41m[CRIT";
111 case LOG_ERR: return "\033[1;31m[ ERR";
112 case LOG_WARNING: return "\033[1;33m[WARN";
113 case LOG_NOTICE: return "\033[1;34m[NOTI";
114 case LOG_INFO: return "\033[1;34m[INFO";
115 case LOG_DEBUG: return "\033[1;30m[ DBG";
c9429a42
VB
116 }
117 break;
118 default:
119 switch (priority) {
26fa5d17
VB
120 case LOG_EMERG: return "[EMRG";
121 case LOG_ALERT: return "[ALRT";
122 case LOG_CRIT: return "[CRIT";
123 case LOG_ERR: return "[ ERR";
124 case LOG_WARNING: return "[WARN";
125 case LOG_NOTICE: return "[NOTI";
126 case LOG_INFO: return "[INFO";
127 case LOG_DEBUG: return "[ DBG";
c9429a42
VB
128 }
129 }
130 return "[UNKN]";
131}
132
8888d191 133static void
26fa5d17 134vlog(int pri, const char *token, const char *fmt, va_list ap)
43c02e7b 135{
4b292b55
VB
136 if (logh) {
137 char *result;
138 if (vasprintf(&result, fmt, ap) != -1) {
139 logh(pri, result);
bea70314 140 free(result);
4b292b55
VB
141 return;
142 }
143 /* Otherwise, fallback to output on stderr. */
144 }
145 if (debug || logh) {
146 char *nfmt;
43c02e7b 147 /* best effort in out of mem situations */
26fa5d17 148 if (asprintf(&nfmt, "%s %s%s%s]%s %s\n",
c9429a42
VB
149 date(),
150 translate(STDERR_FILENO, pri),
26fa5d17
VB
151 token ? "/" : "", token ? token : "",
152 isatty(STDERR_FILENO) ? "\033[0m" : "",
c9429a42 153 fmt) == -1) {
43c02e7b
VB
154 vfprintf(stderr, fmt, ap);
155 fprintf(stderr, "\n");
156 } else {
157 vfprintf(stderr, nfmt, ap);
158 free(nfmt);
159 }
160 fflush(stderr);
161 } else
162 vsyslog(pri, fmt, ap);
163}
164
165
166void
26fa5d17 167log_warn(const char *token, const char *emsg, ...)
43c02e7b
VB
168{
169 char *nfmt;
170 va_list ap;
171
172 /* best effort to even work in out of memory situations */
173 if (emsg == NULL)
c9429a42 174 logit(LOG_WARNING, "%s", strerror(errno));
43c02e7b
VB
175 else {
176 va_start(ap, emsg);
177
178 if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
179 /* we tried it... */
26fa5d17 180 vlog(LOG_WARNING, token, emsg, ap);
c9429a42 181 logit(LOG_WARNING, "%s", strerror(errno));
43c02e7b 182 } else {
26fa5d17 183 vlog(LOG_WARNING, token, nfmt, ap);
43c02e7b
VB
184 free(nfmt);
185 }
186 va_end(ap);
187 }
188}
189
190void
26fa5d17 191log_warnx(const char *token, const char *emsg, ...)
43c02e7b
VB
192{
193 va_list ap;
194
195 va_start(ap, emsg);
26fa5d17 196 vlog(LOG_WARNING, token, emsg, ap);
43c02e7b
VB
197 va_end(ap);
198}
199
200void
26fa5d17 201log_info(const char *token, const char *emsg, ...)
43c02e7b
VB
202{
203 va_list ap;
204
e595efb4
VB
205 if (!debug || debug > 1 || logh) {
206 va_start(ap, emsg);
207 vlog(LOG_INFO, token, emsg, ap);
208 va_end(ap);
209 }
43c02e7b
VB
210}
211
9e5d99d4
VB
212static int
213log_debug_accept_token(const char *token)
214{
215 int i;
216 if (tokens[0] == NULL) return 1;
217 for (i = 0;
218 (i < MAX_DBG_TOKENS) && (tokens[i] != NULL);
219 i++) {
220 if (!strcmp(tokens[i], token))
221 return 1;
222 }
223 return 0;
224}
225
43c02e7b 226void
26fa5d17 227log_debug(const char *token, const char *emsg, ...)
43c02e7b
VB
228{
229 va_list ap;
230
9e5d99d4 231 if ((debug > 2 && log_debug_accept_token(token)) || logh) {
43c02e7b 232 va_start(ap, emsg);
26fa5d17 233 vlog(LOG_DEBUG, token, emsg, ap);
43c02e7b
VB
234 va_end(ap);
235 }
236}
237
238void
6f8925be 239fatal(const char *token, const char *emsg)
43c02e7b
VB
240{
241 if (emsg == NULL)
6f8925be 242 logit(LOG_CRIT, token ? token : "fatal", "%s", strerror(errno));
43c02e7b
VB
243 else
244 if (errno)
6f8925be 245 logit(LOG_CRIT, token ? token : "fatal", "%s: %s",
43c02e7b
VB
246 emsg, strerror(errno));
247 else
6f8925be 248 logit(LOG_CRIT, token ? token : "fatal", "%s", emsg);
43c02e7b
VB
249
250 exit(1);
251}
252
253void
a87db231 254fatalx(const char *token, const char *emsg)
43c02e7b
VB
255{
256 errno = 0;
a87db231 257 fatal(token, emsg);
43c02e7b 258}