]> git.ipfire.org Git - thirdparty/bird.git/blob - sysdep/unix/log.c
6bbb64452d58d14bebf1915bd295e696a7279752
[thirdparty/bird.git] / sysdep / unix / log.c
1 /*
2 * BIRD Library -- Logging Functions
3 *
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
9 /**
10 * DOC: Logging
11 *
12 * The Logging module offers a simple set of functions for writing
13 * messages to system logs and to the debug output.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdarg.h>
19 #include <sys/time.h>
20
21 #include "nest/bird.h"
22 #include "nest/cli.h"
23 #include "lib/string.h"
24 #include "lib/lists.h"
25 #include "lib/unix.h"
26
27 static FILE *dbgf = NULL;
28 static list *current_log_list;
29 static list init_log_list;
30
31 #ifdef HAVE_SYSLOG
32 #include <sys/syslog.h>
33
34 static int syslog_priorities[] = {
35 LOG_DEBUG,
36 LOG_DEBUG,
37 LOG_DEBUG,
38 LOG_INFO,
39 LOG_ERR,
40 LOG_WARNING,
41 LOG_ERR,
42 LOG_ERR,
43 LOG_CRIT,
44 LOG_CRIT
45 };
46 #endif
47
48 static char *class_names[] = {
49 "???",
50 "DBG",
51 "TRACE",
52 "INFO",
53 "RMT",
54 "WARN",
55 "ERR",
56 "AUTH",
57 "FATAL",
58 "BUG"
59 };
60
61 static void
62 vlog(int class, char *msg, va_list args)
63 {
64 char buf[1024];
65 struct log_config *l;
66
67 if (bvsnprintf(buf, sizeof(buf)-1, msg, args) < 0)
68 bsprintf(buf + sizeof(buf) - 100, " ... <too long>");
69
70 WALK_LIST(l, *current_log_list)
71 {
72 if (!(l->mask & (1 << class)))
73 continue;
74 if (l->fh)
75 {
76 time_t now = time(NULL);
77 struct tm *tm = localtime(&now);
78
79 if (l->terminal_flag)
80 fputs("bird: ", l->fh);
81 else
82 {
83 fprintf(l->fh, "%02d-%02d-%04d %02d:%02d:%02d <%s> ",
84 tm->tm_mday,
85 tm->tm_mon+1,
86 tm->tm_year+1900,
87 tm->tm_hour,
88 tm->tm_min,
89 tm->tm_sec,
90 class_names[class]);
91 }
92 fputs(buf, l->fh);
93 fputc('\n', l->fh);
94 fflush(l->fh);
95 }
96 #ifdef HAVE_SYSLOG
97 else
98 syslog(syslog_priorities[class], "%s", buf);
99 #endif
100 }
101 cli_echo(class, buf);
102 }
103
104 /**
105 * log - log a message
106 * @msg: printf-like formatting string with message class information
107 * prepended (%L_DEBUG to %L_BUG, see |lib/birdlib.h|)
108 *
109 * This function formats a message according to the format string @msg
110 * and writes it to the corresponding log file (as specified in the
111 * configuration). Please note that the message is automatically
112 * formatted as a full line, no need to include |\n| inside.
113 */
114 void
115 log(char *msg, ...)
116 {
117 int class = 1;
118 va_list args;
119
120 va_start(args, msg);
121 if (*msg >= 1 && *msg <= 8)
122 class = *msg++;
123 vlog(class, msg, args);
124 va_end(args);
125 }
126
127 /**
128 * bug - report an internal error
129 * @msg: a printf-like error message
130 *
131 * This function logs an internal error and aborts execution
132 * of the program.
133 */
134 void
135 bug(char *msg, ...)
136 {
137 va_list args;
138
139 va_start(args, msg);
140 vlog(L_BUG[0], msg, args);
141 abort();
142 }
143
144 /**
145 * bug - report a fatal error
146 * @msg: a printf-like error message
147 *
148 * This function logs a fatal error and aborts execution
149 * of the program.
150 */
151 void
152 die(char *msg, ...)
153 {
154 va_list args;
155
156 va_start(args, msg);
157 vlog(L_FATAL[0], msg, args);
158 exit(1);
159 }
160
161 /**
162 * debug - write to debug output
163 * @msg: a printf-like message
164 *
165 * This function formats the message @msg and prints it out
166 * to the debugging output. No newline character is appended.
167 */
168 void
169 debug(char *msg, ...)
170 {
171 va_list args;
172 char buf[1024];
173
174 va_start(args, msg);
175 if (dbgf)
176 {
177 if (bvsnprintf(buf, sizeof(buf), msg, args) < 0)
178 bsprintf(buf + sizeof(buf) - 100, " ... <too long>\n");
179 fputs(buf, dbgf);
180 }
181 va_end(args);
182 }
183
184 void
185 log_init(int debug)
186 {
187 static struct log_config lc_stderr = { mask: ~0, terminal_flag: 1 };
188
189 init_list(&init_log_list);
190 current_log_list = &init_log_list;
191
192 #ifdef HAVE_SYSLOG
193 if (!debug)
194 {
195 static struct log_config lc_syslog = { mask: ~0 };
196 openlog("bird", LOG_CONS | LOG_NDELAY, LOG_DAEMON);
197 add_tail(current_log_list, &lc_syslog.n);
198 }
199 #endif
200
201 lc_stderr.fh = stderr;
202 add_tail(current_log_list, &lc_stderr.n);
203 }
204
205 void
206 log_switch(list *l)
207 {
208 if (EMPTY_LIST(*l))
209 current_log_list = &init_log_list;
210 else
211 current_log_list = l;
212 }
213
214 void
215 log_init_debug(char *f)
216 {
217 if (dbgf && dbgf != stderr)
218 fclose(dbgf);
219 if (!f)
220 dbgf = NULL;
221 else if (!*f)
222 dbgf = stderr;
223 else if (!(dbgf = fopen(f, "a")))
224 log(L_ERR "Error opening debug file `%s': %m", f);
225 if (dbgf)
226 setvbuf(dbgf, NULL, _IONBF, 0);
227 }