log.c revision 1.3 1 /* $NetBSD: log.c,v 1.3 2019/01/09 16:55:14 christos Exp $ */
2
3 /*
4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 *
10 * See the COPYRIGHT file distributed with this work for additional
11 * information regarding copyright ownership.
12 */
13
14 /*! \file */
15
16 #include <config.h>
17
18 #include <errno.h>
19 #include <inttypes.h>
20 #include <stdbool.h>
21 #include <stdlib.h>
22 #include <limits.h>
23 #include <time.h>
24
25 #include <sys/types.h> /* dev_t FreeBSD 2.1 */
26
27 #include <isc/dir.h>
28 #include <isc/file.h>
29 #include <isc/log.h>
30 #include <isc/magic.h>
31 #include <isc/mem.h>
32 #include <isc/msgs.h>
33 #include <isc/print.h>
34 #include <isc/stat.h>
35 #include <isc/stdio.h>
36 #include <isc/string.h>
37 #include <isc/time.h>
38 #include <isc/util.h>
39
40 #define LCTX_MAGIC ISC_MAGIC('L', 'c', 't', 'x')
41 #define VALID_CONTEXT(lctx) ISC_MAGIC_VALID(lctx, LCTX_MAGIC)
42
43 #define LCFG_MAGIC ISC_MAGIC('L', 'c', 'f', 'g')
44 #define VALID_CONFIG(lcfg) ISC_MAGIC_VALID(lcfg, LCFG_MAGIC)
45
46 /*
47 * XXXDCL make dynamic?
48 */
49 #define LOG_BUFFER_SIZE (8 * 1024)
50
51 #ifndef PATH_MAX
52 #define PATH_MAX 1024 /* WIN32 and others don't define this. */
53 #endif
54
55 /*!
56 * This is the structure that holds each named channel. A simple linked
57 * list chains all of the channels together, so an individual channel is
58 * found by doing strcmp()s with the names down the list. Their should
59 * be no performance penalty from this as it is expected that the number
60 * of named channels will be no more than a dozen or so, and name lookups
61 * from the head of the list are only done when isc_log_usechannel() is
62 * called, which should also be very infrequent.
63 */
64 typedef struct isc_logchannel isc_logchannel_t;
65
66 struct isc_logchannel {
67 char * name;
68 unsigned int type;
69 int level;
70 unsigned int flags;
71 isc_logdestination_t destination;
72 ISC_LINK(isc_logchannel_t) link;
73 };
74
75 /*!
76 * The logchannellist structure associates categories and modules with
77 * channels. First the appropriate channellist is found based on the
78 * category, and then each structure in the linked list is checked for
79 * a matching module. It is expected that the number of channels
80 * associated with any given category will be very short, no more than
81 * three or four in the more unusual cases.
82 */
83 typedef struct isc_logchannellist isc_logchannellist_t;
84
85 struct isc_logchannellist {
86 const isc_logmodule_t * module;
87 isc_logchannel_t * channel;
88 ISC_LINK(isc_logchannellist_t) link;
89 };
90
91 /*!
92 * This structure is used to remember messages for pruning via
93 * isc_log_[v]write1().
94 */
95 typedef struct isc_logmessage isc_logmessage_t;
96
97 struct isc_logmessage {
98 char * text;
99 isc_time_t time;
100 ISC_LINK(isc_logmessage_t) link;
101 };
102
103 /*!
104 * The isc_logconfig structure is used to store the configurable information
105 * about where messages are actually supposed to be sent -- the information
106 * that could changed based on some configuration file, as opposed to the
107 * the category/module specification of isc_log_[v]write[1] that is compiled
108 * into a program, or the debug_level which is dynamic state information.
109 */
110 struct isc_logconfig {
111 unsigned int magic;
112 isc_log_t * lctx;
113 ISC_LIST(isc_logchannel_t) channels;
114 ISC_LIST(isc_logchannellist_t) *channellists;
115 unsigned int channellist_count;
116 unsigned int duplicate_interval;
117 int highest_level;
118 char * tag;
119 bool dynamic;
120 };
121
122 /*!
123 * This isc_log structure provides the context for the isc_log functions.
124 * The log context locks itself in isc_log_doit, the internal backend to
125 * isc_log_write. The locking is necessary both to provide exclusive access
126 * to the buffer into which the message is formatted and to guard against
127 * competing threads trying to write to the same syslog resource. (On
128 * some systems, such as BSD/OS, stdio is thread safe but syslog is not.)
129 * Unfortunately, the lock cannot guard against a _different_ logging
130 * context in the same program competing for syslog's attention. Thus
131 * There Can Be Only One, but this is not enforced.
132 * XXXDCL enforce it?
133 *
134 * Note that the category and module information is not locked.
135 * This is because in the usual case, only one isc_log_t is ever created
136 * in a program, and the category/module registration happens only once.
137 * XXXDCL it might be wise to add more locking overall.
138 */
139 struct isc_log {
140 /* Not locked. */
141 unsigned int magic;
142 isc_mem_t * mctx;
143 isc_logcategory_t * categories;
144 unsigned int category_count;
145 isc_logmodule_t * modules;
146 unsigned int module_count;
147 int debug_level;
148 isc_mutex_t lock;
149 /* Locked by isc_log lock. */
150 isc_logconfig_t * logconfig;
151 char buffer[LOG_BUFFER_SIZE];
152 ISC_LIST(isc_logmessage_t) messages;
153 };
154
155 /*!
156 * Used when ISC_LOG_PRINTLEVEL is enabled for a channel.
157 */
158 static const char *log_level_strings[] = {
159 "debug",
160 "info",
161 "notice",
162 "warning",
163 "error",
164 "critical"
165 };
166
167 /*!
168 * Used to convert ISC_LOG_* priorities into syslog priorities.
169 * XXXDCL This will need modification for NT.
170 */
171 static const int syslog_map[] = {
172 LOG_DEBUG,
173 LOG_INFO,
174 LOG_NOTICE,
175 LOG_WARNING,
176 LOG_ERR,
177 LOG_CRIT
178 };
179
180 /*!
181 * When adding new categories, a corresponding ISC_LOGCATEGORY_foo
182 * definition needs to be added to <isc/log.h>.
183 *
184 * The default category is provided so that the internal default can
185 * be overridden. Since the default is always looked up as the first
186 * channellist in the log context, it must come first in isc_categories[].
187 */
188 LIBISC_EXTERNAL_DATA isc_logcategory_t isc_categories[] = {
189 { "default", 0 }, /* "default" must come first. */
190 { "general", 0 },
191 { NULL, 0 }
192 };
193
194 /*!
195 * See above comment for categories on LIBISC_EXTERNAL_DATA, and apply it to modules.
196 */
197 LIBISC_EXTERNAL_DATA isc_logmodule_t isc_modules[] = {
198 { "socket", 0 },
199 { "time", 0 },
200 { "interface", 0 },
201 { "timer", 0 },
202 { "file", 0 },
203 { "other", 0 },
204 { NULL, 0 }
205 };
206
207 /*!
208 * This essentially constant structure must be filled in at run time,
209 * because its channel member is pointed to a channel that is created
210 * dynamically with isc_log_createchannel.
211 */
212 static isc_logchannellist_t default_channel;
213
214 /*!
215 * libisc logs to this context.
216 */
217 LIBISC_EXTERNAL_DATA isc_log_t *isc_lctx = NULL;
218
219 /*!
220 * Forward declarations.
221 */
222 static isc_result_t
223 assignchannel(isc_logconfig_t *lcfg, unsigned int category_id,
224 const isc_logmodule_t *module, isc_logchannel_t *channel);
225
226 static isc_result_t
227 sync_channellist(isc_logconfig_t *lcfg);
228
229 static isc_result_t
230 greatest_version(isc_logfile_t *file, int versions, int *greatest);
231
232 static void
233 isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
234 isc_logmodule_t *module, int level, bool write_once,
235 isc_msgcat_t *msgcat, int msgset, int msg,
236 const char *format, va_list args)
237 ISC_FORMAT_PRINTF(9, 0);
238
239 /*@{*/
240 /*!
241 * Convenience macros.
242 */
243
244 #define FACILITY(channel) (channel->destination.facility)
245 #define FILE_NAME(channel) (channel->destination.file.name)
246 #define FILE_STREAM(channel) (channel->destination.file.stream)
247 #define FILE_VERSIONS(channel) (channel->destination.file.versions)
248 #define FILE_SUFFIX(channel) (channel->destination.file.suffix)
249 #define FILE_MAXSIZE(channel) (channel->destination.file.maximum_size)
250 #define FILE_MAXREACHED(channel) (channel->destination.file.maximum_reached)
251
252 /*@}*/
253 /****
254 **** Public interfaces.
255 ****/
256
257 /*
258 * Establish a new logging context, with default channels.
259 */
260 isc_result_t
261 isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp) {
262 isc_log_t *lctx;
263 isc_logconfig_t *lcfg = NULL;
264 isc_result_t result;
265
266 REQUIRE(mctx != NULL);
267 REQUIRE(lctxp != NULL && *lctxp == NULL);
268 REQUIRE(lcfgp == NULL || *lcfgp == NULL);
269
270 lctx = isc_mem_get(mctx, sizeof(*lctx));
271 if (lctx != NULL) {
272 lctx->mctx = NULL;
273 isc_mem_attach(mctx, &lctx->mctx);
274 lctx->categories = NULL;
275 lctx->category_count = 0;
276 lctx->modules = NULL;
277 lctx->module_count = 0;
278 lctx->debug_level = 0;
279
280 ISC_LIST_INIT(lctx->messages);
281
282 isc_mutex_init(&lctx->lock);
283
284 /*
285 * Normally setting the magic number is the last step done
286 * in a creation function, but a valid log context is needed
287 * by isc_log_registercategories and isc_logconfig_create.
288 * If either fails, the lctx is destroyed and not returned
289 * to the caller.
290 */
291 lctx->magic = LCTX_MAGIC;
292
293 isc_log_registercategories(lctx, isc_categories);
294 isc_log_registermodules(lctx, isc_modules);
295 result = isc_logconfig_create(lctx, &lcfg);
296
297 } else
298 result = ISC_R_NOMEMORY;
299
300 if (result == ISC_R_SUCCESS)
301 result = sync_channellist(lcfg);
302
303 if (result == ISC_R_SUCCESS) {
304 lctx->logconfig = lcfg;
305
306 *lctxp = lctx;
307 if (lcfgp != NULL)
308 *lcfgp = lcfg;
309
310 } else {
311 if (lcfg != NULL)
312 isc_logconfig_destroy(&lcfg);
313 if (lctx != NULL)
314 isc_log_destroy(&lctx);
315 }
316
317 return (result);
318 }
319
320 isc_result_t
321 isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp) {
322 isc_logconfig_t *lcfg;
323 isc_logdestination_t destination;
324 isc_result_t result = ISC_R_SUCCESS;
325 int level = ISC_LOG_INFO;
326
327 REQUIRE(lcfgp != NULL && *lcfgp == NULL);
328 REQUIRE(VALID_CONTEXT(lctx));
329
330 lcfg = isc_mem_get(lctx->mctx, sizeof(*lcfg));
331
332 if (lcfg != NULL) {
333 lcfg->lctx = lctx;
334 lcfg->channellists = NULL;
335 lcfg->channellist_count = 0;
336 lcfg->duplicate_interval = 0;
337 lcfg->highest_level = level;
338 lcfg->tag = NULL;
339 lcfg->dynamic = false;
340
341 ISC_LIST_INIT(lcfg->channels);
342
343 /*
344 * Normally the magic number is the last thing set in the
345 * structure, but isc_log_createchannel() needs a valid
346 * config. If the channel creation fails, the lcfg is not
347 * returned to the caller.
348 */
349 lcfg->magic = LCFG_MAGIC;
350
351 } else
352 result = ISC_R_NOMEMORY;
353
354 /*
355 * Create the default channels:
356 * default_syslog, default_stderr, default_debug and null.
357 */
358 if (result == ISC_R_SUCCESS) {
359 destination.facility = LOG_DAEMON;
360 result = isc_log_createchannel(lcfg, "default_syslog",
361 ISC_LOG_TOSYSLOG, level,
362 &destination, 0);
363 }
364
365 if (result == ISC_R_SUCCESS) {
366 destination.file.stream = stderr;
367 destination.file.name = NULL;
368 destination.file.versions = ISC_LOG_ROLLNEVER;
369 destination.file.suffix = isc_log_rollsuffix_increment;
370 destination.file.maximum_size = 0;
371 result = isc_log_createchannel(lcfg, "default_stderr",
372 ISC_LOG_TOFILEDESC,
373 level,
374 &destination,
375 ISC_LOG_PRINTTIME);
376 }
377
378 if (result == ISC_R_SUCCESS) {
379 /*
380 * Set the default category's channel to default_stderr,
381 * which is at the head of the channels list because it was
382 * just created.
383 */
384 default_channel.channel = ISC_LIST_HEAD(lcfg->channels);
385
386 destination.file.stream = stderr;
387 destination.file.name = NULL;
388 destination.file.versions = ISC_LOG_ROLLNEVER;
389 destination.file.suffix = isc_log_rollsuffix_increment;
390 destination.file.maximum_size = 0;
391 result = isc_log_createchannel(lcfg, "default_debug",
392 ISC_LOG_TOFILEDESC,
393 ISC_LOG_DYNAMIC,
394 &destination,
395 ISC_LOG_PRINTTIME);
396 }
397
398 if (result == ISC_R_SUCCESS)
399 result = isc_log_createchannel(lcfg, "null",
400 ISC_LOG_TONULL,
401 ISC_LOG_DYNAMIC,
402 NULL, 0);
403
404 if (result == ISC_R_SUCCESS)
405 *lcfgp = lcfg;
406
407 else
408 if (lcfg != NULL)
409 isc_logconfig_destroy(&lcfg);
410
411 return (result);
412 }
413
414 isc_logconfig_t *
415 isc_logconfig_get(isc_log_t *lctx) {
416 REQUIRE(VALID_CONTEXT(lctx));
417
418 ENSURE(lctx->logconfig != NULL);
419
420 return (lctx->logconfig);
421 }
422
423 isc_result_t
424 isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg) {
425 isc_logconfig_t *old_cfg;
426 isc_result_t result;
427
428 REQUIRE(VALID_CONTEXT(lctx));
429 REQUIRE(VALID_CONFIG(lcfg));
430 REQUIRE(lcfg->lctx == lctx);
431
432 /*
433 * Ensure that lcfg->channellist_count == lctx->category_count.
434 * They won't be equal if isc_log_usechannel has not been called
435 * since any call to isc_log_registercategories.
436 */
437 result = sync_channellist(lcfg);
438 if (result != ISC_R_SUCCESS)
439 return (result);
440
441 LOCK(&lctx->lock);
442
443 old_cfg = lctx->logconfig;
444 lctx->logconfig = lcfg;
445
446 UNLOCK(&lctx->lock);
447
448 isc_logconfig_destroy(&old_cfg);
449
450 return (ISC_R_SUCCESS);
451 }
452
453 void
454 isc_log_destroy(isc_log_t **lctxp) {
455 isc_log_t *lctx;
456 isc_logconfig_t *lcfg;
457 isc_mem_t *mctx;
458 isc_logmessage_t *message;
459
460 REQUIRE(lctxp != NULL && VALID_CONTEXT(*lctxp));
461
462 lctx = *lctxp;
463 mctx = lctx->mctx;
464
465 if (lctx->logconfig != NULL) {
466 lcfg = lctx->logconfig;
467 lctx->logconfig = NULL;
468 isc_logconfig_destroy(&lcfg);
469 }
470
471 isc_mutex_destroy(&lctx->lock);
472
473 while ((message = ISC_LIST_HEAD(lctx->messages)) != NULL) {
474 ISC_LIST_UNLINK(lctx->messages, message, link);
475
476 isc_mem_put(mctx, message,
477 sizeof(*message) + strlen(message->text) + 1);
478 }
479
480 lctx->buffer[0] = '\0';
481 lctx->debug_level = 0;
482 lctx->categories = NULL;
483 lctx->category_count = 0;
484 lctx->modules = NULL;
485 lctx->module_count = 0;
486 lctx->mctx = NULL;
487 lctx->magic = 0;
488
489 isc_mem_putanddetach(&mctx, lctx, sizeof(*lctx));
490
491 *lctxp = NULL;
492 }
493
494 void
495 isc_logconfig_destroy(isc_logconfig_t **lcfgp) {
496 isc_logconfig_t *lcfg;
497 isc_mem_t *mctx;
498 isc_logchannel_t *channel;
499 isc_logchannellist_t *item;
500 char *filename;
501 unsigned int i;
502
503 REQUIRE(lcfgp != NULL && VALID_CONFIG(*lcfgp));
504
505 lcfg = *lcfgp;
506
507 /*
508 * This function cannot be called with a logconfig that is in
509 * use by a log context.
510 */
511 REQUIRE(lcfg->lctx != NULL && lcfg->lctx->logconfig != lcfg);
512
513 mctx = lcfg->lctx->mctx;
514
515 while ((channel = ISC_LIST_HEAD(lcfg->channels)) != NULL) {
516 ISC_LIST_UNLINK(lcfg->channels, channel, link);
517
518 if (channel->type == ISC_LOG_TOFILE) {
519 /*
520 * The filename for the channel may have ultimately
521 * started its life in user-land as a const string,
522 * but in isc_log_createchannel it gets copied
523 * into writable memory and is not longer truly const.
524 */
525 DE_CONST(FILE_NAME(channel), filename);
526 isc_mem_free(mctx, filename);
527
528 if (FILE_STREAM(channel) != NULL)
529 (void)fclose(FILE_STREAM(channel));
530 }
531
532 isc_mem_free(mctx, channel->name);
533 isc_mem_put(mctx, channel, sizeof(*channel));
534 }
535
536 for (i = 0; i < lcfg->channellist_count; i++)
537 while ((item = ISC_LIST_HEAD(lcfg->channellists[i])) != NULL) {
538 ISC_LIST_UNLINK(lcfg->channellists[i], item, link);
539 isc_mem_put(mctx, item, sizeof(*item));
540 }
541
542 if (lcfg->channellist_count > 0)
543 isc_mem_put(mctx, lcfg->channellists,
544 lcfg->channellist_count *
545 sizeof(ISC_LIST(isc_logchannellist_t)));
546
547 lcfg->dynamic = false;
548 if (lcfg->tag != NULL)
549 isc_mem_free(lcfg->lctx->mctx, lcfg->tag);
550 lcfg->tag = NULL;
551 lcfg->highest_level = 0;
552 lcfg->duplicate_interval = 0;
553 lcfg->magic = 0;
554
555 isc_mem_put(mctx, lcfg, sizeof(*lcfg));
556
557 *lcfgp = NULL;
558 }
559
560 void
561 isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]) {
562 isc_logcategory_t *catp;
563
564 REQUIRE(VALID_CONTEXT(lctx));
565 REQUIRE(categories != NULL && categories[0].name != NULL);
566
567 /*
568 * XXXDCL This somewhat sleazy situation of using the last pointer
569 * in one category array to point to the next array exists because
570 * this registration function returns void and I didn't want to have
571 * change everything that used it by making it return an isc_result_t.
572 * It would need to do that if it had to allocate memory to store
573 * pointers to each array passed in.
574 */
575 if (lctx->categories == NULL)
576 lctx->categories = categories;
577
578 else {
579 /*
580 * Adjust the last (NULL) pointer of the already registered
581 * categories to point to the incoming array.
582 */
583 for (catp = lctx->categories; catp->name != NULL; )
584 if (catp->id == UINT_MAX)
585 /*
586 * The name pointer points to the next array.
587 * Ick.
588 */
589 DE_CONST(catp->name, catp);
590 else
591 catp++;
592
593 catp->name = (void *)categories;
594 catp->id = UINT_MAX;
595 }
596
597 /*
598 * Update the id number of the category with its new global id.
599 */
600 for (catp = categories; catp->name != NULL; catp++)
601 catp->id = lctx->category_count++;
602 }
603
604 isc_logcategory_t *
605 isc_log_categorybyname(isc_log_t *lctx, const char *name) {
606 isc_logcategory_t *catp;
607
608 REQUIRE(VALID_CONTEXT(lctx));
609 REQUIRE(name != NULL);
610
611 for (catp = lctx->categories; catp->name != NULL; )
612 if (catp->id == UINT_MAX)
613 /*
614 * catp is neither modified nor returned to the
615 * caller, so removing its const qualifier is ok.
616 */
617 DE_CONST(catp->name, catp);
618 else {
619 if (strcmp(catp->name, name) == 0)
620 return (catp);
621 catp++;
622 }
623
624 return (NULL);
625 }
626
627 void
628 isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]) {
629 isc_logmodule_t *modp;
630
631 REQUIRE(VALID_CONTEXT(lctx));
632 REQUIRE(modules != NULL && modules[0].name != NULL);
633
634 /*
635 * XXXDCL This somewhat sleazy situation of using the last pointer
636 * in one category array to point to the next array exists because
637 * this registration function returns void and I didn't want to have
638 * change everything that used it by making it return an isc_result_t.
639 * It would need to do that if it had to allocate memory to store
640 * pointers to each array passed in.
641 */
642 if (lctx->modules == NULL)
643 lctx->modules = modules;
644
645 else {
646 /*
647 * Adjust the last (NULL) pointer of the already registered
648 * modules to point to the incoming array.
649 */
650 for (modp = lctx->modules; modp->name != NULL; )
651 if (modp->id == UINT_MAX)
652 /*
653 * The name pointer points to the next array.
654 * Ick.
655 */
656 DE_CONST(modp->name, modp);
657 else
658 modp++;
659
660 modp->name = (void *)modules;
661 modp->id = UINT_MAX;
662 }
663
664 /*
665 * Update the id number of the module with its new global id.
666 */
667 for (modp = modules; modp->name != NULL; modp++)
668 modp->id = lctx->module_count++;
669 }
670
671 isc_logmodule_t *
672 isc_log_modulebyname(isc_log_t *lctx, const char *name) {
673 isc_logmodule_t *modp;
674
675 REQUIRE(VALID_CONTEXT(lctx));
676 REQUIRE(name != NULL);
677
678 for (modp = lctx->modules; modp->name != NULL; )
679 if (modp->id == UINT_MAX)
680 /*
681 * modp is neither modified nor returned to the
682 * caller, so removing its const qualifier is ok.
683 */
684 DE_CONST(modp->name, modp);
685 else {
686 if (strcmp(modp->name, name) == 0)
687 return (modp);
688 modp++;
689 }
690
691 return (NULL);
692 }
693
694 isc_result_t
695 isc_log_createchannel(isc_logconfig_t *lcfg, const char *name,
696 unsigned int type, int level,
697 const isc_logdestination_t *destination,
698 unsigned int flags)
699 {
700 isc_logchannel_t *channel;
701 isc_mem_t *mctx;
702 unsigned int permitted = ISC_LOG_PRINTALL | ISC_LOG_DEBUGONLY |
703 ISC_LOG_BUFFERED | ISC_LOG_ISO8601 |
704 ISC_LOG_UTC;
705
706 REQUIRE(VALID_CONFIG(lcfg));
707 REQUIRE(name != NULL);
708 REQUIRE(type == ISC_LOG_TOSYSLOG || type == ISC_LOG_TOFILE ||
709 type == ISC_LOG_TOFILEDESC || type == ISC_LOG_TONULL);
710 REQUIRE(destination != NULL || type == ISC_LOG_TONULL);
711 REQUIRE(level >= ISC_LOG_CRITICAL);
712 REQUIRE((flags & ~permitted) == 0);
713
714 /* XXXDCL find duplicate names? */
715
716 mctx = lcfg->lctx->mctx;
717
718 channel = isc_mem_get(mctx, sizeof(*channel));
719 if (channel == NULL)
720 return (ISC_R_NOMEMORY);
721
722 channel->name = isc_mem_strdup(mctx, name);
723 if (channel->name == NULL) {
724 isc_mem_put(mctx, channel, sizeof(*channel));
725 return (ISC_R_NOMEMORY);
726 }
727
728 channel->type = type;
729 channel->level = level;
730 channel->flags = flags;
731 ISC_LINK_INIT(channel, link);
732
733 switch (type) {
734 case ISC_LOG_TOSYSLOG:
735 FACILITY(channel) = destination->facility;
736 break;
737
738 case ISC_LOG_TOFILE:
739 /*
740 * The file name is copied because greatest_version wants
741 * to scribble on it, so it needs to be definitely in
742 * writable memory.
743 */
744 FILE_NAME(channel) =
745 isc_mem_strdup(mctx, destination->file.name);
746 FILE_STREAM(channel) = NULL;
747 FILE_VERSIONS(channel) = destination->file.versions;
748 FILE_SUFFIX(channel) = destination->file.suffix;
749 FILE_MAXSIZE(channel) = destination->file.maximum_size;
750 FILE_MAXREACHED(channel) = false;
751 break;
752
753 case ISC_LOG_TOFILEDESC:
754 FILE_NAME(channel) = NULL;
755 FILE_STREAM(channel) = destination->file.stream;
756 FILE_MAXSIZE(channel) = 0;
757 FILE_VERSIONS(channel) = ISC_LOG_ROLLNEVER;
758 FILE_SUFFIX(channel) = isc_log_rollsuffix_increment;
759 break;
760
761 case ISC_LOG_TONULL:
762 /* Nothing. */
763 break;
764
765 default:
766 isc_mem_free(mctx, channel->name);
767 isc_mem_put(mctx, channel, sizeof(*channel));
768 return (ISC_R_UNEXPECTED);
769 }
770
771 ISC_LIST_PREPEND(lcfg->channels, channel, link);
772
773 /*
774 * If default_stderr was redefined, make the default category
775 * point to the new default_stderr.
776 */
777 if (strcmp(name, "default_stderr") == 0)
778 default_channel.channel = channel;
779
780 return (ISC_R_SUCCESS);
781 }
782
783 isc_result_t
784 isc_log_usechannel(isc_logconfig_t *lcfg, const char *name,
785 const isc_logcategory_t *category,
786 const isc_logmodule_t *module)
787 {
788 isc_log_t *lctx;
789 isc_logchannel_t *channel;
790 isc_result_t result = ISC_R_SUCCESS;
791 unsigned int i;
792
793 REQUIRE(VALID_CONFIG(lcfg));
794 REQUIRE(name != NULL);
795
796 lctx = lcfg->lctx;
797
798 REQUIRE(category == NULL || category->id < lctx->category_count);
799 REQUIRE(module == NULL || module->id < lctx->module_count);
800
801 for (channel = ISC_LIST_HEAD(lcfg->channels); channel != NULL;
802 channel = ISC_LIST_NEXT(channel, link))
803 if (strcmp(name, channel->name) == 0)
804 break;
805
806 if (channel == NULL)
807 return (ISC_R_NOTFOUND);
808
809 if (category != NULL)
810 result = assignchannel(lcfg, category->id, module, channel);
811
812 else
813 /*
814 * Assign to all categories. Note that this includes
815 * the default channel.
816 */
817 for (i = 0; i < lctx->category_count; i++) {
818 result = assignchannel(lcfg, i, module, channel);
819 if (result != ISC_R_SUCCESS)
820 break;
821 }
822
823 return (result);
824 }
825
826 void
827 isc_log_write(isc_log_t *lctx, isc_logcategory_t *category,
828 isc_logmodule_t *module, int level, const char *format, ...)
829 {
830 va_list args;
831
832 /*
833 * Contract checking is done in isc_log_doit().
834 */
835
836 va_start(args, format);
837 isc_log_doit(lctx, category, module, level, false,
838 NULL, 0, 0, format, args);
839 va_end(args);
840 }
841
842 void
843 isc_log_vwrite(isc_log_t *lctx, isc_logcategory_t *category,
844 isc_logmodule_t *module, int level,
845 const char *format, va_list args)
846 {
847 /*
848 * Contract checking is done in isc_log_doit().
849 */
850 isc_log_doit(lctx, category, module, level, false,
851 NULL, 0, 0, format, args);
852 }
853
854 void
855 isc_log_write1(isc_log_t *lctx, isc_logcategory_t *category,
856 isc_logmodule_t *module, int level, const char *format, ...)
857 {
858 va_list args;
859
860 /*
861 * Contract checking is done in isc_log_doit().
862 */
863
864 va_start(args, format);
865 isc_log_doit(lctx, category, module, level, true,
866 NULL, 0, 0, format, args);
867 va_end(args);
868 }
869
870 void
871 isc_log_vwrite1(isc_log_t *lctx, isc_logcategory_t *category,
872 isc_logmodule_t *module, int level,
873 const char *format, va_list args)
874 {
875 /*
876 * Contract checking is done in isc_log_doit().
877 */
878 isc_log_doit(lctx, category, module, level, true,
879 NULL, 0, 0, format, args);
880 }
881
882 void
883 isc_log_iwrite(isc_log_t *lctx, isc_logcategory_t *category,
884 isc_logmodule_t *module, int level,
885 isc_msgcat_t *msgcat, int msgset, int msg,
886 const char *format, ...)
887 {
888 va_list args;
889
890 /*
891 * Contract checking is done in isc_log_doit().
892 */
893
894 va_start(args, format);
895 isc_log_doit(lctx, category, module, level, false,
896 msgcat, msgset, msg, format, args);
897 va_end(args);
898 }
899
900 void
901 isc_log_ivwrite(isc_log_t *lctx, isc_logcategory_t *category,
902 isc_logmodule_t *module, int level,
903 isc_msgcat_t *msgcat, int msgset, int msg,
904 const char *format, va_list args)
905 {
906 /*
907 * Contract checking is done in isc_log_doit().
908 */
909 isc_log_doit(lctx, category, module, level, false,
910 msgcat, msgset, msg, format, args);
911 }
912
913 void
914 isc_log_iwrite1(isc_log_t *lctx, isc_logcategory_t *category,
915 isc_logmodule_t *module, int level,
916 isc_msgcat_t *msgcat, int msgset, int msg,
917 const char *format, ...)
918 {
919 va_list args;
920
921 /*
922 * Contract checking is done in isc_log_doit().
923 */
924
925 va_start(args, format);
926 isc_log_doit(lctx, category, module, level, true,
927 msgcat, msgset, msg, format, args);
928 va_end(args);
929 }
930
931 void
932 isc_log_ivwrite1(isc_log_t *lctx, isc_logcategory_t *category,
933 isc_logmodule_t *module, int level,
934 isc_msgcat_t *msgcat, int msgset, int msg,
935 const char *format, va_list args)
936 {
937 /*
938 * Contract checking is done in isc_log_doit().
939 */
940 isc_log_doit(lctx, category, module, level, true,
941 msgcat, msgset, msg, format, args);
942 }
943
944 void
945 isc_log_setcontext(isc_log_t *lctx) {
946 isc_lctx = lctx;
947 }
948
949 void
950 isc_log_setdebuglevel(isc_log_t *lctx, unsigned int level) {
951 isc_logchannel_t *channel;
952
953 REQUIRE(VALID_CONTEXT(lctx));
954
955 LOCK(&lctx->lock);
956
957 lctx->debug_level = level;
958 /*
959 * Close ISC_LOG_DEBUGONLY channels if level is zero.
960 */
961 if (lctx->debug_level == 0)
962 for (channel = ISC_LIST_HEAD(lctx->logconfig->channels);
963 channel != NULL;
964 channel = ISC_LIST_NEXT(channel, link))
965 if (channel->type == ISC_LOG_TOFILE &&
966 (channel->flags & ISC_LOG_DEBUGONLY) != 0 &&
967 FILE_STREAM(channel) != NULL) {
968 (void)fclose(FILE_STREAM(channel));
969 FILE_STREAM(channel) = NULL;
970 }
971 UNLOCK(&lctx->lock);
972 }
973
974 unsigned int
975 isc_log_getdebuglevel(isc_log_t *lctx) {
976 REQUIRE(VALID_CONTEXT(lctx));
977
978 return (lctx->debug_level);
979 }
980
981 void
982 isc_log_setduplicateinterval(isc_logconfig_t *lcfg, unsigned int interval) {
983 REQUIRE(VALID_CONFIG(lcfg));
984
985 lcfg->duplicate_interval = interval;
986 }
987
988 unsigned int
989 isc_log_getduplicateinterval(isc_logconfig_t *lcfg) {
990 REQUIRE(VALID_CONTEXT(lcfg));
991
992 return (lcfg->duplicate_interval);
993 }
994
995 isc_result_t
996 isc_log_settag(isc_logconfig_t *lcfg, const char *tag) {
997 REQUIRE(VALID_CONFIG(lcfg));
998
999 if (tag != NULL && *tag != '\0') {
1000 if (lcfg->tag != NULL)
1001 isc_mem_free(lcfg->lctx->mctx, lcfg->tag);
1002 lcfg->tag = isc_mem_strdup(lcfg->lctx->mctx, tag);
1003 if (lcfg->tag == NULL)
1004 return (ISC_R_NOMEMORY);
1005
1006 } else {
1007 if (lcfg->tag != NULL)
1008 isc_mem_free(lcfg->lctx->mctx, lcfg->tag);
1009 lcfg->tag = NULL;
1010 }
1011
1012 return (ISC_R_SUCCESS);
1013 }
1014
1015 char *
1016 isc_log_gettag(isc_logconfig_t *lcfg) {
1017 REQUIRE(VALID_CONFIG(lcfg));
1018
1019 return (lcfg->tag);
1020 }
1021
1022 /* XXXDCL NT -- This interface will assuredly be changing. */
1023 void
1024 isc_log_opensyslog(const char *tag, int options, int facility) {
1025 (void)openlog(tag, options, facility);
1026 }
1027
1028 void
1029 isc_log_closefilelogs(isc_log_t *lctx) {
1030 isc_logchannel_t *channel;
1031
1032 REQUIRE(VALID_CONTEXT(lctx));
1033
1034 LOCK(&lctx->lock);
1035 for (channel = ISC_LIST_HEAD(lctx->logconfig->channels);
1036 channel != NULL;
1037 channel = ISC_LIST_NEXT(channel, link))
1038
1039 if (channel->type == ISC_LOG_TOFILE &&
1040 FILE_STREAM(channel) != NULL) {
1041 (void)fclose(FILE_STREAM(channel));
1042 FILE_STREAM(channel) = NULL;
1043 }
1044 UNLOCK(&lctx->lock);
1045 }
1046
1047 /****
1048 **** Internal functions
1049 ****/
1050
1051 static isc_result_t
1052 assignchannel(isc_logconfig_t *lcfg, unsigned int category_id,
1053 const isc_logmodule_t *module, isc_logchannel_t *channel)
1054 {
1055 isc_logchannellist_t *new_item;
1056 isc_log_t *lctx;
1057 isc_result_t result;
1058
1059 REQUIRE(VALID_CONFIG(lcfg));
1060
1061 lctx = lcfg->lctx;
1062
1063 REQUIRE(category_id < lctx->category_count);
1064 REQUIRE(module == NULL || module->id < lctx->module_count);
1065 REQUIRE(channel != NULL);
1066
1067 /*
1068 * Ensure lcfg->channellist_count == lctx->category_count.
1069 */
1070 result = sync_channellist(lcfg);
1071 if (result != ISC_R_SUCCESS)
1072 return (result);
1073
1074 new_item = isc_mem_get(lctx->mctx, sizeof(*new_item));
1075 if (new_item == NULL)
1076 return (ISC_R_NOMEMORY);
1077
1078 new_item->channel = channel;
1079 new_item->module = module;
1080 ISC_LIST_INITANDPREPEND(lcfg->channellists[category_id],
1081 new_item, link);
1082
1083 /*
1084 * Remember the highest logging level set by any channel in the
1085 * logging config, so isc_log_doit() can quickly return if the
1086 * message is too high to be logged by any channel.
1087 */
1088 if (channel->type != ISC_LOG_TONULL) {
1089 if (lcfg->highest_level < channel->level)
1090 lcfg->highest_level = channel->level;
1091 if (channel->level == ISC_LOG_DYNAMIC)
1092 lcfg->dynamic = true;
1093 }
1094
1095 return (ISC_R_SUCCESS);
1096 }
1097
1098 /*
1099 * This would ideally be part of isc_log_registercategories(), except then
1100 * that function would have to return isc_result_t instead of void.
1101 */
1102 static isc_result_t
1103 sync_channellist(isc_logconfig_t *lcfg) {
1104 unsigned int bytes;
1105 isc_log_t *lctx;
1106 void *lists;
1107
1108 REQUIRE(VALID_CONFIG(lcfg));
1109
1110 lctx = lcfg->lctx;
1111
1112 REQUIRE(lctx->category_count != 0);
1113
1114 if (lctx->category_count == lcfg->channellist_count)
1115 return (ISC_R_SUCCESS);
1116
1117 bytes = lctx->category_count * sizeof(ISC_LIST(isc_logchannellist_t));
1118
1119 lists = isc_mem_get(lctx->mctx, bytes);
1120
1121 if (lists == NULL)
1122 return (ISC_R_NOMEMORY);
1123
1124 memset(lists, 0, bytes);
1125
1126 if (lcfg->channellist_count != 0) {
1127 bytes = lcfg->channellist_count *
1128 sizeof(ISC_LIST(isc_logchannellist_t));
1129 memmove(lists, lcfg->channellists, bytes);
1130 isc_mem_put(lctx->mctx, lcfg->channellists, bytes);
1131 }
1132
1133 lcfg->channellists = lists;
1134 lcfg->channellist_count = lctx->category_count;
1135
1136 return (ISC_R_SUCCESS);
1137 }
1138
1139 static isc_result_t
1140 greatest_version(isc_logfile_t *file, int versions, int *greatestp) {
1141 char *bname, *digit_end;
1142 const char *dirname;
1143 int version, greatest = -1;
1144 size_t bnamelen;
1145 isc_dir_t dir;
1146 isc_result_t result;
1147 char sep = '/';
1148 #ifdef _WIN32
1149 char *bname2;
1150 #endif
1151
1152 /*
1153 * It is safe to DE_CONST the file.name because it was copied
1154 * with isc_mem_strdup().
1155 */
1156 bname = strrchr(file->name, sep);
1157 #ifdef _WIN32
1158 bname2 = strrchr(file->name, '\\');
1159 if ((bname != NULL && bname2 != NULL && bname2 > bname) ||
1160 (bname == NULL && bname2 != NULL)) {
1161 bname = bname2;
1162 sep = '\\';
1163 }
1164 #endif
1165 if (bname != NULL) {
1166 *bname++ = '\0';
1167 dirname = file->name;
1168 } else {
1169 DE_CONST(file->name, bname);
1170 dirname = ".";
1171 }
1172 bnamelen = strlen(bname);
1173
1174 isc_dir_init(&dir);
1175 result = isc_dir_open(&dir, dirname);
1176
1177 /*
1178 * Replace the file separator if it was taken out.
1179 */
1180 if (bname != file->name)
1181 *(bname - 1) = sep;
1182
1183 /*
1184 * Return if the directory open failed.
1185 */
1186 if (result != ISC_R_SUCCESS)
1187 return (result);
1188
1189 while (isc_dir_read(&dir) == ISC_R_SUCCESS) {
1190 if (dir.entry.length > bnamelen &&
1191 strncmp(dir.entry.name, bname, bnamelen) == 0 &&
1192 dir.entry.name[bnamelen] == '.')
1193 {
1194 version = strtol(&dir.entry.name[bnamelen + 1],
1195 &digit_end, 10);
1196 /*
1197 * Remove any backup files that exceed versions.
1198 */
1199 if (*digit_end == '\0' && version >= versions) {
1200 result = isc_file_remove(dir.entry.name);
1201 if (result != ISC_R_SUCCESS &&
1202 result != ISC_R_FILENOTFOUND)
1203 syslog(LOG_ERR, "unable to remove "
1204 "log file '%s': %s",
1205 dir.entry.name,
1206 isc_result_totext(result));
1207 } else if (*digit_end == '\0' && version > greatest)
1208 greatest = version;
1209 }
1210 }
1211 isc_dir_close(&dir);
1212
1213 *greatestp = greatest;
1214
1215 return (ISC_R_SUCCESS);
1216 }
1217
1218 static isc_result_t
1219 remove_old_tsversions(isc_logfile_t *file, int versions) {
1220 isc_result_t result;
1221 char *bname, *digit_end;
1222 const char *dirname;
1223 int64_t version, last = INT64_MAX;
1224 int64_t to_keep[ISC_LOG_MAX_VERSIONS];
1225 size_t bnamelen;
1226 isc_dir_t dir;
1227 char sep = '/';
1228 #ifdef _WIN32
1229 char *bname2;
1230 #endif
1231 /*
1232 * It is safe to DE_CONST the file.name because it was copied
1233 * with isc_mem_strdup().
1234 */
1235 bname = strrchr(file->name, sep);
1236 #ifdef _WIN32
1237 bname2 = strrchr(file->name, '\\');
1238 if ((bname != NULL && bname2 != NULL && bname2 > bname) ||
1239 (bname == NULL && bname2 != NULL)) {
1240 bname = bname2;
1241 sep = '\\';
1242 }
1243 #endif
1244 if (bname != NULL) {
1245 *bname++ = '\0';
1246 dirname = file->name;
1247 } else {
1248 DE_CONST(file->name, bname);
1249 dirname = ".";
1250 }
1251 bnamelen = strlen(bname);
1252
1253 isc_dir_init(&dir);
1254 result = isc_dir_open(&dir, dirname);
1255
1256 /*
1257 * Replace the file separator if it was taken out.
1258 */
1259 if (bname != file->name) {
1260 *(bname - 1) = sep;
1261 }
1262
1263 /*
1264 * Return if the directory open failed.
1265 */
1266 if (result != ISC_R_SUCCESS)
1267 return (result);
1268
1269 if (versions > 0) {
1270 /*
1271 * First we fill 'to_keep' structure using insertion sort
1272 */
1273 memset(to_keep, 0, versions * sizeof(long long));
1274 while (isc_dir_read(&dir) == ISC_R_SUCCESS) {
1275 if (dir.entry.length > bnamelen &&
1276 strncmp(dir.entry.name, bname, bnamelen) == 0 &&
1277 dir.entry.name[bnamelen] == '.')
1278 {
1279 char *ename = &dir.entry.name[bnamelen + 1];
1280 version = strtoull(ename, &digit_end, 10);
1281 if (*digit_end == '\0') {
1282 int i = 0;
1283 while (i < versions &&
1284 version < to_keep[i])
1285 {
1286 i++;
1287 }
1288 if (i < versions) {
1289 memmove(&to_keep[i + 1],
1290 &to_keep[i],
1291 sizeof(long long) *
1292 versions - i - 1);
1293 to_keep[i] = version;
1294 }
1295 }
1296 }
1297 }
1298
1299 /*
1300 * to_keep[versions - 1] is the last one we want to keep
1301 */
1302 last = to_keep[versions - 1];
1303 isc_dir_reset(&dir);
1304 }
1305
1306 /*
1307 * Then we remove all files that we don't want to_keep
1308 */
1309 while (isc_dir_read(&dir) == ISC_R_SUCCESS) {
1310 if (dir.entry.length > bnamelen &&
1311 strncmp(dir.entry.name, bname, bnamelen) == 0 &&
1312 dir.entry.name[bnamelen] == '.')
1313 {
1314 char *ename = &dir.entry.name[bnamelen + 1];
1315 version = strtoull(ename, &digit_end, 10);
1316 /*
1317 * Remove any backup files that exceed versions.
1318 */
1319 if (*digit_end == '\0' && version < last) {
1320 result = isc_file_remove(dir.entry.name);
1321 if (result != ISC_R_SUCCESS &&
1322 result != ISC_R_FILENOTFOUND)
1323 syslog(LOG_ERR, "unable to remove "
1324 "log file '%s': %s",
1325 dir.entry.name,
1326 isc_result_totext(result));
1327 }
1328 }
1329 }
1330
1331 isc_dir_close(&dir);
1332
1333 return (ISC_R_SUCCESS);
1334 }
1335
1336 static isc_result_t
1337 roll_increment(isc_logfile_t *file) {
1338 int i, n, greatest;
1339 char current[PATH_MAX + 1];
1340 char newpath[PATH_MAX + 1];
1341 const char *path;
1342 isc_result_t result = ISC_R_SUCCESS;
1343
1344 REQUIRE(file != NULL);
1345 REQUIRE(file->versions != 0);
1346
1347 path = file->name;
1348
1349 if (file->versions == ISC_LOG_ROLLINFINITE) {
1350 /*
1351 * Find the first missing entry in the log file sequence.
1352 */
1353 for (greatest = 0; greatest < INT_MAX; greatest++) {
1354 n = snprintf(current, sizeof(current),
1355 "%s.%u", path, (unsigned)greatest) ;
1356 if (n >= (int)sizeof(current) || n < 0 ||
1357 !isc_file_exists(current))
1358 {
1359 break;
1360 }
1361 }
1362 } else {
1363 /*
1364 * Get the largest existing version and remove any
1365 * version greater than the permitted version.
1366 */
1367 result = greatest_version(file, file->versions, &greatest);
1368 if (result != ISC_R_SUCCESS) {
1369 return (result);
1370 }
1371
1372 /*
1373 * Increment if greatest is not the actual maximum value.
1374 */
1375 if (greatest < file->versions - 1) {
1376 greatest++;
1377 }
1378 }
1379
1380 for (i = greatest; i > 0; i--) {
1381 result = ISC_R_SUCCESS;
1382 n = snprintf(current, sizeof(current), "%s.%u", path,
1383 (unsigned)(i - 1));
1384 if (n >= (int)sizeof(current) || n < 0) {
1385 result = ISC_R_NOSPACE;
1386 }
1387 if (result == ISC_R_SUCCESS) {
1388 n = snprintf(newpath, sizeof(newpath), "%s.%u",
1389 path, (unsigned)i);
1390 if (n >= (int)sizeof(newpath) || n < 0) {
1391 result = ISC_R_NOSPACE;
1392 }
1393 }
1394 if (result == ISC_R_SUCCESS) {
1395 result = isc_file_rename(current, newpath);
1396 }
1397 if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
1398 syslog(LOG_ERR,
1399 "unable to rename log file '%s.%u' to "
1400 "'%s.%u': %s", path, i - 1, path, i,
1401 isc_result_totext(result));
1402 }
1403 }
1404
1405 n = snprintf(newpath, sizeof(newpath), "%s.0", path);
1406 if (n >= (int)sizeof(newpath) || n < 0) {
1407 result = ISC_R_NOSPACE;
1408 } else {
1409 result = isc_file_rename(path, newpath);
1410 }
1411 if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
1412 syslog(LOG_ERR,
1413 "unable to rename log file '%s' to '%s.0': %s",
1414 path, path, isc_result_totext(result));
1415 }
1416
1417 return (ISC_R_SUCCESS);
1418 }
1419
1420 static isc_result_t
1421 roll_timestamp(isc_logfile_t *file) {
1422 int n;
1423 char newts[PATH_MAX + 1];
1424 char newpath[PATH_MAX + 1];
1425 const char *path;
1426 isc_time_t now;
1427 isc_result_t result = ISC_R_SUCCESS;
1428
1429 REQUIRE(file != NULL);
1430 REQUIRE(file->versions != 0);
1431
1432 path = file->name;
1433
1434 /*
1435 * First find all the logfiles and remove the oldest ones
1436 * Save one fewer than file->versions because we'll be renaming
1437 * the existing file to a timestamped version after this.
1438 */
1439 if (file->versions != ISC_LOG_ROLLINFINITE) {
1440 remove_old_tsversions(file, file->versions - 1);
1441 }
1442
1443 /* Then just rename the current logfile */
1444 isc_time_now(&now);
1445 isc_time_formatshorttimestamp(&now, newts, PATH_MAX + 1);
1446 n = snprintf(newpath, sizeof(newpath), "%s.%s", path, newts);
1447 if (n >= (int)sizeof(newpath) || n < 0) {
1448 result = ISC_R_NOSPACE;
1449 } else {
1450 result = isc_file_rename(path, newpath);
1451 }
1452 if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
1453 syslog(LOG_ERR,
1454 "unable to rename log file '%s' to '%s.0': %s",
1455 path, path, isc_result_totext(result));
1456 }
1457
1458 return (ISC_R_SUCCESS);
1459 }
1460
1461
1462 isc_result_t
1463 isc_logfile_roll(isc_logfile_t *file) {
1464 isc_result_t result;
1465
1466 REQUIRE(file != NULL);
1467
1468 /*
1469 * Do nothing (not even excess version trimming) if ISC_LOG_ROLLNEVER
1470 * is specified. Apparently complete external control over the log
1471 * files is desired.
1472 */
1473 if (file->versions == ISC_LOG_ROLLNEVER) {
1474 return (ISC_R_SUCCESS);
1475 } else if (file->versions == 0) {
1476 result = isc_file_remove(file->name);
1477 if (result != ISC_R_SUCCESS &&
1478 result != ISC_R_FILENOTFOUND)
1479 syslog(LOG_ERR, "unable to remove log file '%s': %s",
1480 file->name, isc_result_totext(result));
1481 return (ISC_R_SUCCESS);
1482 }
1483
1484 switch (file->suffix) {
1485 case isc_log_rollsuffix_increment:
1486 return (roll_increment(file));
1487 case isc_log_rollsuffix_timestamp:
1488 return (roll_timestamp(file));
1489 default:
1490 return (ISC_R_UNEXPECTED);
1491 }
1492 }
1493
1494 static isc_result_t
1495 isc_log_open(isc_logchannel_t *channel) {
1496 struct stat statbuf;
1497 bool regular_file;
1498 bool roll = false;
1499 isc_result_t result = ISC_R_SUCCESS;
1500 const char *path;
1501
1502 REQUIRE(channel->type == ISC_LOG_TOFILE);
1503 REQUIRE(FILE_STREAM(channel) == NULL);
1504
1505 path = FILE_NAME(channel);
1506
1507 REQUIRE(path != NULL && *path != '\0');
1508
1509 /*
1510 * Determine type of file; only regular files will be
1511 * version renamed, and only if the base file exists
1512 * and either has no size limit or has reached its size limit.
1513 */
1514 if (stat(path, &statbuf) == 0) {
1515 regular_file = S_ISREG(statbuf.st_mode) ? true : false;
1516 /* XXXDCL if not regular_file complain? */
1517 if ((FILE_MAXSIZE(channel) == 0 &&
1518 FILE_VERSIONS(channel) != ISC_LOG_ROLLNEVER) ||
1519 (FILE_MAXSIZE(channel) > 0 &&
1520 statbuf.st_size >= FILE_MAXSIZE(channel)))
1521 roll = regular_file;
1522 } else if (errno == ENOENT) {
1523 regular_file = true;
1524 POST(regular_file);
1525 } else
1526 result = ISC_R_INVALIDFILE;
1527
1528 /*
1529 * Version control.
1530 */
1531 if (result == ISC_R_SUCCESS && roll) {
1532 if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER)
1533 return (ISC_R_MAXSIZE);
1534 result = isc_logfile_roll(&channel->destination.file);
1535 if (result != ISC_R_SUCCESS) {
1536 if ((channel->flags & ISC_LOG_OPENERR) == 0) {
1537 syslog(LOG_ERR,
1538 "isc_log_open: isc_logfile_roll '%s' "
1539 "failed: %s",
1540 FILE_NAME(channel),
1541 isc_result_totext(result));
1542 channel->flags |= ISC_LOG_OPENERR;
1543 }
1544 return (result);
1545 }
1546 }
1547
1548 result = isc_stdio_open(path, "a", &FILE_STREAM(channel));
1549
1550 return (result);
1551 }
1552
1553 bool
1554 isc_log_wouldlog(isc_log_t *lctx, int level) {
1555 /*
1556 * Try to avoid locking the mutex for messages which can't
1557 * possibly be logged to any channels -- primarily debugging
1558 * messages that the debug level is not high enough to print.
1559 *
1560 * If the level is (mathematically) less than or equal to the
1561 * highest_level, or if there is a dynamic channel and the level is
1562 * less than or equal to the debug level, the main loop must be
1563 * entered to see if the message should really be output.
1564 *
1565 * NOTE: this is UNLOCKED access to the logconfig. However,
1566 * the worst thing that can happen is that a bad decision is made
1567 * about returning without logging, and that's not a big concern,
1568 * because that's a risk anyway if the logconfig is being
1569 * dynamically changed.
1570 */
1571
1572 if (lctx == NULL || lctx->logconfig == NULL)
1573 return (false);
1574
1575 return (level <= lctx->logconfig->highest_level ||
1576 (lctx->logconfig->dynamic && level <= lctx->debug_level));
1577 }
1578
1579 static void
1580 isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
1581 isc_logmodule_t *module, int level, bool write_once,
1582 isc_msgcat_t *msgcat, int msgset, int msg,
1583 const char *format, va_list args)
1584 {
1585 int syslog_level;
1586 const char *time_string;
1587 char local_time[64];
1588 char iso8601z_string[64];
1589 char iso8601l_string[64];
1590 char level_string[24];
1591 const char *iformat;
1592 struct stat statbuf;
1593 bool matched = false;
1594 bool printtime, iso8601, utc, printtag, printcolon;
1595 bool printcategory, printmodule, printlevel, buffered;
1596 isc_logconfig_t *lcfg;
1597 isc_logchannel_t *channel;
1598 isc_logchannellist_t *category_channels;
1599 isc_result_t result;
1600
1601 REQUIRE(lctx == NULL || VALID_CONTEXT(lctx));
1602 REQUIRE(category != NULL);
1603 REQUIRE(module != NULL);
1604 REQUIRE(level != ISC_LOG_DYNAMIC);
1605 REQUIRE(format != NULL);
1606
1607 /*
1608 * Programs can use libraries that use this logging code without
1609 * wanting to do any logging, thus the log context is allowed to
1610 * be non-existent.
1611 */
1612 if (lctx == NULL)
1613 return;
1614
1615 REQUIRE(category->id < lctx->category_count);
1616 REQUIRE(module->id < lctx->module_count);
1617
1618 if (! isc_log_wouldlog(lctx, level))
1619 return;
1620
1621 if (msgcat != NULL)
1622 iformat = isc_msgcat_get(msgcat, msgset, msg, format);
1623 else
1624 iformat = format;
1625
1626 local_time[0] = '\0';
1627 iso8601l_string[0] = '\0';
1628 iso8601z_string[0] = '\0';
1629 level_string[0] = '\0';
1630
1631 LOCK(&lctx->lock);
1632
1633 lctx->buffer[0] = '\0';
1634
1635 lcfg = lctx->logconfig;
1636
1637 category_channels = ISC_LIST_HEAD(lcfg->channellists[category->id]);
1638
1639 /*
1640 * XXXDCL add duplicate filtering? (To not write multiple times to
1641 * the same source via various channels).
1642 */
1643 do {
1644 /*
1645 * If the channel list end was reached and a match was made,
1646 * everything is finished.
1647 */
1648 if (category_channels == NULL && matched)
1649 break;
1650
1651 if (category_channels == NULL && ! matched &&
1652 category_channels != ISC_LIST_HEAD(lcfg->channellists[0]))
1653 /*
1654 * No category/module pair was explicitly configured.
1655 * Try the category named "default".
1656 */
1657 category_channels =
1658 ISC_LIST_HEAD(lcfg->channellists[0]);
1659
1660 if (category_channels == NULL && ! matched)
1661 /*
1662 * No matching module was explicitly configured
1663 * for the category named "default". Use the internal
1664 * default channel.
1665 */
1666 category_channels = &default_channel;
1667
1668 if (category_channels->module != NULL &&
1669 category_channels->module != module) {
1670 category_channels = ISC_LIST_NEXT(category_channels,
1671 link);
1672 continue;
1673 }
1674
1675 matched = true;
1676
1677 channel = category_channels->channel;
1678 category_channels = ISC_LIST_NEXT(category_channels, link);
1679
1680 if (((channel->flags & ISC_LOG_DEBUGONLY) != 0) &&
1681 lctx->debug_level == 0)
1682 continue;
1683
1684 if (channel->level == ISC_LOG_DYNAMIC) {
1685 if (lctx->debug_level < level)
1686 continue;
1687 } else if (channel->level < level)
1688 continue;
1689
1690 if ((channel->flags & ISC_LOG_PRINTTIME) != 0 &&
1691 local_time[0] == '\0')
1692 {
1693 isc_time_t isctime;
1694
1695 TIME_NOW(&isctime);
1696
1697 isc_time_formattimestamp(&isctime,
1698 local_time,
1699 sizeof(local_time));
1700 isc_time_formatISO8601ms(&isctime,
1701 iso8601z_string,
1702 sizeof(iso8601z_string));
1703 isc_time_formatISO8601Lms(&isctime,
1704 iso8601l_string,
1705 sizeof(iso8601l_string));
1706 }
1707
1708 if ((channel->flags & ISC_LOG_PRINTLEVEL) != 0 &&
1709 level_string[0] == '\0') {
1710 if (level < ISC_LOG_CRITICAL)
1711 snprintf(level_string, sizeof(level_string),
1712 isc_msgcat_get(isc_msgcat,
1713 ISC_MSGSET_LOG,
1714 ISC_MSG_LEVEL,
1715 "level %d: "),
1716 level);
1717 else if (level > ISC_LOG_DYNAMIC)
1718 snprintf(level_string, sizeof(level_string),
1719 "%s %d: ", log_level_strings[0],
1720 level);
1721 else
1722 snprintf(level_string, sizeof(level_string),
1723 "%s: ", log_level_strings[-level]);
1724 }
1725
1726 /*
1727 * Only format the message once.
1728 */
1729 if (lctx->buffer[0] == '\0') {
1730 (void)vsnprintf(lctx->buffer, sizeof(lctx->buffer),
1731 iformat, args);
1732
1733 /*
1734 * Check for duplicates.
1735 */
1736 if (write_once) {
1737 isc_logmessage_t *message, *next;
1738 isc_time_t oldest;
1739 isc_interval_t interval;
1740 size_t size;
1741
1742 isc_interval_set(&interval,
1743 lcfg->duplicate_interval, 0);
1744
1745 /*
1746 * 'oldest' is the age of the oldest messages
1747 * which fall within the duplicate_interval
1748 * range.
1749 */
1750 TIME_NOW(&oldest);
1751 if (isc_time_subtract(&oldest, &interval,
1752 &oldest)
1753 != ISC_R_SUCCESS)
1754 /*
1755 * Can't effectively do the checking
1756 * without having a valid time.
1757 */
1758 message = NULL;
1759 else
1760 message = ISC_LIST_HEAD(lctx->messages);
1761
1762 while (message != NULL) {
1763 if (isc_time_compare(&message->time,
1764 &oldest) < 0) {
1765 /*
1766 * This message is older
1767 * than the duplicate_interval,
1768 * so it should be dropped from
1769 * the history.
1770 *
1771 * Setting the interval to be
1772 * to be longer will obviously
1773 * not cause the expired
1774 * message to spring back into
1775 * existence.
1776 */
1777 next = ISC_LIST_NEXT(message,
1778 link);
1779
1780 ISC_LIST_UNLINK(lctx->messages,
1781 message, link);
1782
1783 isc_mem_put(lctx->mctx,
1784 message,
1785 sizeof(*message) + 1 +
1786 strlen(message->text));
1787
1788 message = next;
1789 continue;
1790 }
1791
1792 /*
1793 * This message is in the duplicate
1794 * filtering interval ...
1795 */
1796 if (strcmp(lctx->buffer, message->text)
1797 == 0) {
1798 /*
1799 * ... and it is a duplicate.
1800 * Unlock the mutex and
1801 * get the hell out of Dodge.
1802 */
1803 UNLOCK(&lctx->lock);
1804 return;
1805 }
1806
1807 message = ISC_LIST_NEXT(message, link);
1808 }
1809
1810 /*
1811 * It wasn't in the duplicate interval,
1812 * so add it to the message list.
1813 */
1814 size = sizeof(isc_logmessage_t) +
1815 strlen(lctx->buffer) + 1;
1816 message = isc_mem_get(lctx->mctx, size);
1817 if (message != NULL) {
1818 /*
1819 * Put the text immediately after
1820 * the struct. The strcpy is safe.
1821 */
1822 message->text = (char *)(message + 1);
1823 size -= sizeof(isc_logmessage_t);
1824 strlcpy(message->text, lctx->buffer,
1825 size);
1826
1827 TIME_NOW(&message->time);
1828
1829 ISC_LINK_INIT(message, link);
1830 ISC_LIST_APPEND(lctx->messages,
1831 message, link);
1832 }
1833 }
1834 }
1835
1836 utc = ((channel->flags & ISC_LOG_UTC) != 0);
1837 iso8601 = ((channel->flags & ISC_LOG_ISO8601) != 0);
1838 printtime = ((channel->flags & ISC_LOG_PRINTTIME) != 0);
1839 printtag = ((channel->flags &
1840 (ISC_LOG_PRINTTAG|ISC_LOG_PRINTPREFIX)) != 0 &&
1841 lcfg->tag != NULL);
1842 printcolon = ((channel->flags & ISC_LOG_PRINTTAG) != 0 &&
1843 lcfg->tag != NULL);
1844 printcategory = ((channel->flags & ISC_LOG_PRINTCATEGORY) != 0);
1845 printmodule = ((channel->flags & ISC_LOG_PRINTMODULE) != 0);
1846 printlevel = ((channel->flags & ISC_LOG_PRINTLEVEL) != 0);
1847 buffered = ((channel->flags & ISC_LOG_BUFFERED) != 0);
1848
1849 if (printtime) {
1850 if (iso8601) {
1851 if (utc) {
1852 time_string = iso8601z_string;
1853 } else {
1854 time_string = iso8601l_string;
1855 }
1856 } else {
1857 time_string = local_time;
1858 }
1859 } else
1860 time_string = "";
1861
1862 switch (channel->type) {
1863 case ISC_LOG_TOFILE:
1864 if (FILE_MAXREACHED(channel)) {
1865 /*
1866 * If the file can be rolled, OR
1867 * If the file no longer exists, OR
1868 * If the file is less than the maximum size,
1869 * (such as if it had been renamed and
1870 * a new one touched, or it was truncated
1871 * in place)
1872 * ... then close it to trigger reopening.
1873 */
1874 if (FILE_VERSIONS(channel) !=
1875 ISC_LOG_ROLLNEVER ||
1876 (stat(FILE_NAME(channel), &statbuf) != 0 &&
1877 errno == ENOENT) ||
1878 statbuf.st_size < FILE_MAXSIZE(channel)) {
1879 (void)fclose(FILE_STREAM(channel));
1880 FILE_STREAM(channel) = NULL;
1881 FILE_MAXREACHED(channel) = false;
1882 } else
1883 /*
1884 * Eh, skip it.
1885 */
1886 break;
1887 }
1888
1889 if (FILE_STREAM(channel) == NULL) {
1890 result = isc_log_open(channel);
1891 if (result != ISC_R_SUCCESS &&
1892 result != ISC_R_MAXSIZE &&
1893 (channel->flags & ISC_LOG_OPENERR) == 0) {
1894 syslog(LOG_ERR,
1895 "isc_log_open '%s' failed: %s",
1896 FILE_NAME(channel),
1897 isc_result_totext(result));
1898 channel->flags |= ISC_LOG_OPENERR;
1899 }
1900 if (result != ISC_R_SUCCESS)
1901 break;
1902 channel->flags &= ~ISC_LOG_OPENERR;
1903 }
1904 /* FALLTHROUGH */
1905
1906 case ISC_LOG_TOFILEDESC:
1907 fprintf(FILE_STREAM(channel),
1908 "%s%s%s%s%s%s%s%s%s%s\n",
1909 printtime ? time_string : "",
1910 printtime ? " " : "",
1911 printtag ? lcfg->tag : "",
1912 printcolon ? ": " : "",
1913 printcategory ? category->name : "",
1914 printcategory ? ": " : "",
1915 printmodule ? (module != NULL ? module->name
1916 : "no_module")
1917 : "",
1918 printmodule ? ": " : "",
1919 printlevel ? level_string : "",
1920 lctx->buffer);
1921
1922 if (!buffered)
1923 fflush(FILE_STREAM(channel));
1924
1925 /*
1926 * If the file now exceeds its maximum size
1927 * threshold, note it so that it will not be logged
1928 * to any more.
1929 */
1930 if (FILE_MAXSIZE(channel) > 0) {
1931 INSIST(channel->type == ISC_LOG_TOFILE);
1932
1933 /* XXXDCL NT fstat/fileno */
1934 /* XXXDCL complain if fstat fails? */
1935 if (fstat(fileno(FILE_STREAM(channel)),
1936 &statbuf) >= 0 &&
1937 statbuf.st_size > FILE_MAXSIZE(channel))
1938 FILE_MAXREACHED(channel) = true;
1939 }
1940
1941 break;
1942
1943 case ISC_LOG_TOSYSLOG:
1944 if (level > 0)
1945 syslog_level = LOG_DEBUG;
1946 else if (level < ISC_LOG_CRITICAL)
1947 syslog_level = LOG_CRIT;
1948 else
1949 syslog_level = syslog_map[-level];
1950
1951 (void)syslog(FACILITY(channel) | syslog_level,
1952 "%s%s%s%s%s%s%s%s%s%s",
1953 printtime ? time_string : "",
1954 printtime ? " " : "",
1955 printtag ? lcfg->tag : "",
1956 printcolon ? ": " : "",
1957 printcategory ? category->name : "",
1958 printcategory ? ": " : "",
1959 printmodule ? (module != NULL
1960 ? module->name
1961 : "no_module")
1962 : "",
1963 printmodule ? ": " : "",
1964 printlevel ? level_string : "",
1965 lctx->buffer);
1966 break;
1967
1968 case ISC_LOG_TONULL:
1969 break;
1970
1971 }
1972
1973 } while (1);
1974
1975 UNLOCK(&lctx->lock);
1976 }
1977