Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : Samba utility functions
4 : Copyright (C) Andrew Tridgell 1992-1998
5 : Copyright (C) Elrond 2002
6 : Copyright (C) Simo Sorce 2002
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "replace.h"
23 : #include <talloc.h>
24 : #include "system/filesys.h"
25 : #include "system/syslog.h"
26 : #include "system/locale.h"
27 : #include "time_basic.h"
28 : #include "close_low_fd.h"
29 : #include "memory.h"
30 : #include "util_strlist.h" /* LIST_SEP */
31 : #include "blocking.h"
32 : #include "debug.h"
33 : #include <assert.h>
34 :
35 : /* define what facility to use for syslog */
36 : #ifndef SYSLOG_FACILITY
37 : #define SYSLOG_FACILITY LOG_DAEMON
38 : #endif
39 :
40 : /* -------------------------------------------------------------------------- **
41 : * Defines...
42 : */
43 :
44 : /*
45 : * format_bufr[FORMAT_BUFR_SIZE - 1] should always be reserved
46 : * for a terminating null byte.
47 : */
48 : #define FORMAT_BUFR_SIZE 4096
49 :
50 : /* -------------------------------------------------------------------------- **
51 : * This module implements Samba's debugging utility.
52 : *
53 : * The syntax of a debugging log file is represented as:
54 : *
55 : * <debugfile> :== { <debugmsg> }
56 : *
57 : * <debugmsg> :== <debughdr> '\n' <debugtext>
58 : *
59 : * <debughdr> :== '[' TIME ',' LEVEL ']' [ [FILENAME ':'] [FUNCTION '()'] ]
60 : *
61 : * <debugtext> :== { <debugline> }
62 : *
63 : * <debugline> :== TEXT '\n'
64 : *
65 : * TEXT is a string of characters excluding the newline character.
66 : * LEVEL is the DEBUG level of the message (an integer in the range 0..10).
67 : * TIME is a timestamp.
68 : * FILENAME is the name of the file from which the debug message was generated.
69 : * FUNCTION is the function from which the debug message was generated.
70 : *
71 : * Basically, what that all means is:
72 : *
73 : * - A debugging log file is made up of debug messages.
74 : *
75 : * - Each debug message is made up of a header and text. The header is
76 : * separated from the text by a newline.
77 : *
78 : * - The header begins with the timestamp and debug level of the message
79 : * enclosed in brackets. The filename and function from which the
80 : * message was generated may follow. The filename is terminated by a
81 : * colon, and the function name is terminated by parenthesis.
82 : *
83 : * - The message text is made up of zero or more lines, each terminated by
84 : * a newline.
85 : */
86 :
87 : /* state variables for the debug system */
88 : static struct {
89 : bool initialized;
90 : enum debug_logtype logtype; /* The type of logging we are doing: eg stdout, file, stderr */
91 : char prog_name[255];
92 : bool reopening_logs;
93 : bool schedule_reopen_logs;
94 :
95 : struct debug_settings settings;
96 : debug_callback_fn callback;
97 : void *callback_private;
98 : } state = {
99 : .settings = {
100 : .timestamp_logs = true
101 : },
102 : };
103 :
104 : struct debug_class {
105 : /*
106 : * The debug loglevel of the class.
107 : */
108 : int loglevel;
109 :
110 : /*
111 : * An optional class specific logfile, may be NULL in which case the
112 : * "global" logfile is used and fd is -1.
113 : */
114 : char *logfile;
115 : int fd;
116 : /* inode number of the logfile to detect logfile rotation */
117 : ino_t ino;
118 : };
119 :
120 : static const char *default_classname_table[] = {
121 : [DBGC_ALL] = "all",
122 : [DBGC_TDB] = "tdb",
123 : [DBGC_PRINTDRIVERS] = "printdrivers",
124 : [DBGC_LANMAN] = "lanman",
125 : [DBGC_SMB] = "smb",
126 : [DBGC_RPC_PARSE] = "rpc_parse",
127 : [DBGC_RPC_SRV] = "rpc_srv",
128 : [DBGC_RPC_CLI] = "rpc_cli",
129 : [DBGC_PASSDB] = "passdb",
130 : [DBGC_SAM] = "sam",
131 : [DBGC_AUTH] = "auth",
132 : [DBGC_WINBIND] = "winbind",
133 : [DBGC_VFS] = "vfs",
134 : [DBGC_IDMAP] = "idmap",
135 : [DBGC_QUOTA] = "quota",
136 : [DBGC_ACLS] = "acls",
137 : [DBGC_LOCKING] = "locking",
138 : [DBGC_MSDFS] = "msdfs",
139 : [DBGC_DMAPI] = "dmapi",
140 : [DBGC_REGISTRY] = "registry",
141 : [DBGC_SCAVENGER] = "scavenger",
142 : [DBGC_DNS] = "dns",
143 : [DBGC_LDB] = "ldb",
144 : [DBGC_TEVENT] = "tevent",
145 : [DBGC_AUTH_AUDIT] = "auth_audit",
146 : [DBGC_AUTH_AUDIT_JSON] = "auth_json_audit",
147 : [DBGC_KERBEROS] = "kerberos",
148 : [DBGC_DRS_REPL] = "drs_repl",
149 : [DBGC_SMB2] = "smb2",
150 : [DBGC_SMB2_CREDITS] = "smb2_credits",
151 : [DBGC_DSDB_AUDIT] = "dsdb_audit",
152 : [DBGC_DSDB_AUDIT_JSON] = "dsdb_json_audit",
153 : [DBGC_DSDB_PWD_AUDIT] = "dsdb_password_audit",
154 : [DBGC_DSDB_PWD_AUDIT_JSON] = "dsdb_password_json_audit",
155 : [DBGC_DSDB_TXN_AUDIT] = "dsdb_transaction_audit",
156 : [DBGC_DSDB_TXN_AUDIT_JSON] = "dsdb_transaction_json_audit",
157 : [DBGC_DSDB_GROUP_AUDIT] = "dsdb_group_audit",
158 : [DBGC_DSDB_GROUP_AUDIT_JSON] = "dsdb_group_json_audit",
159 : };
160 :
161 : /*
162 : * This is to allow reading of dbgc_config before the debug
163 : * system has been initialized.
164 : */
165 : static struct debug_class debug_class_list_initial[ARRAY_SIZE(default_classname_table)] = {
166 : [DBGC_ALL] = { .fd = 2 },
167 : };
168 :
169 : static size_t debug_num_classes = 0;
170 : static struct debug_class *dbgc_config = debug_class_list_initial;
171 :
172 : static int current_msg_level = 0;
173 : static int current_msg_class = 0;
174 :
175 : #if defined(WITH_SYSLOG) || defined(HAVE_LIBSYSTEMD_JOURNAL) || defined(HAVE_LIBSYSTEMD)
176 423 : static int debug_level_to_priority(int level)
177 : {
178 : /*
179 : * map debug levels to syslog() priorities
180 : */
181 : static const int priority_map[] = {
182 : LOG_ERR, /* 0 */
183 : LOG_WARNING, /* 1 */
184 : LOG_NOTICE, /* 2 */
185 : LOG_NOTICE, /* 3 */
186 : LOG_NOTICE, /* 4 */
187 : LOG_NOTICE, /* 5 */
188 : LOG_INFO, /* 6 */
189 : LOG_INFO, /* 7 */
190 : LOG_INFO, /* 8 */
191 : LOG_INFO, /* 9 */
192 : };
193 : int priority;
194 :
195 423 : if (level < 0 || (size_t)level >= ARRAY_SIZE(priority_map))
196 0 : priority = LOG_DEBUG;
197 : else
198 423 : priority = priority_map[level];
199 :
200 423 : return priority;
201 : }
202 : #endif
203 :
204 : /* -------------------------------------------------------------------------- **
205 : * Debug backends. When logging to DEBUG_FILE, send the log entries to
206 : * all active backends.
207 : */
208 :
209 6364 : static void debug_file_log(int msg_level,
210 : const char *msg, const char *msg_no_nl)
211 : {
212 : ssize_t ret;
213 : int fd;
214 :
215 6364 : check_log_size();
216 :
217 6364 : if (dbgc_config[current_msg_class].fd != -1) {
218 2127 : fd = dbgc_config[current_msg_class].fd;
219 : } else {
220 4171 : fd = dbgc_config[DBGC_ALL].fd;
221 : }
222 :
223 : do {
224 6364 : ret = write(fd, msg, strlen(msg));
225 6364 : } while (ret == -1 && errno == EINTR);
226 6364 : }
227 :
228 : #ifdef WITH_SYSLOG
229 160578 : static void debug_syslog_reload(bool enabled, bool previously_enabled,
230 : const char *prog_name, char *option)
231 : {
232 160578 : if (enabled && !previously_enabled) {
233 8894 : const char *ident = NULL;
234 8894 : if ((prog_name != NULL) && (prog_name[0] != '\0')) {
235 4235 : ident = prog_name;
236 : }
237 : #ifdef LOG_DAEMON
238 8894 : openlog(ident, LOG_PID, SYSLOG_FACILITY);
239 : #else
240 : /* for old systems that have no facility codes. */
241 : openlog(ident, LOG_PID);
242 : #endif
243 8894 : return;
244 : }
245 :
246 151684 : if (!enabled && previously_enabled) {
247 0 : closelog();
248 : }
249 : }
250 :
251 423 : static void debug_syslog_log(int msg_level,
252 : const char *msg, const char *msg_no_nl)
253 : {
254 : int priority;
255 :
256 423 : priority = debug_level_to_priority(msg_level);
257 :
258 : /*
259 : * Specify the facility to interoperate with other syslog
260 : * callers (vfs_full_audit for example).
261 : */
262 423 : priority |= SYSLOG_FACILITY;
263 :
264 423 : syslog(priority, "%s", msg);
265 423 : }
266 : #endif /* WITH_SYSLOG */
267 :
268 : #if defined(HAVE_LIBSYSTEMD_JOURNAL) || defined(HAVE_LIBSYSTEMD)
269 : #include <systemd/sd-journal.h>
270 0 : static void debug_systemd_log(int msg_level,
271 : const char *msg, const char *msg_no_nl)
272 : {
273 0 : sd_journal_send("MESSAGE=%s", msg_no_nl,
274 : "PRIORITY=%d", debug_level_to_priority(msg_level),
275 : "LEVEL=%d", msg_level,
276 : NULL);
277 0 : }
278 : #endif
279 :
280 : #ifdef HAVE_LTTNG_TRACEF
281 : #include <lttng/tracef.h>
282 : static void debug_lttng_log(int msg_level,
283 : const char *msg, const char *msg_no_nl)
284 : {
285 : tracef(msg_no_nl);
286 : }
287 : #endif /* WITH_LTTNG_TRACEF */
288 :
289 : #ifdef HAVE_GPFS
290 : #include "gpfswrap.h"
291 160578 : static void debug_gpfs_reload(bool enabled, bool previously_enabled,
292 : const char *prog_name, char *option)
293 : {
294 160578 : gpfswrap_init();
295 :
296 160578 : if (enabled && !previously_enabled) {
297 0 : gpfswrap_init_trace();
298 0 : return;
299 : }
300 :
301 160578 : if (!enabled && previously_enabled) {
302 0 : gpfswrap_fini_trace();
303 0 : return;
304 : }
305 :
306 160578 : if (enabled) {
307 : /*
308 : * Trigger GPFS library to adjust state if necessary.
309 : */
310 0 : gpfswrap_query_trace();
311 : }
312 : }
313 :
314 0 : static void debug_gpfs_log(int msg_level,
315 : const char *msg, const char *msg_no_nl)
316 : {
317 0 : gpfswrap_add_trace(msg_level, msg_no_nl);
318 0 : }
319 : #endif /* HAVE_GPFS */
320 :
321 : #define DEBUG_RINGBUF_SIZE (1024 * 1024)
322 : #define DEBUG_RINGBUF_SIZE_OPT "size="
323 :
324 : static char *debug_ringbuf;
325 : static size_t debug_ringbuf_size;
326 : static size_t debug_ringbuf_ofs;
327 :
328 : /* We ensure in debug_ringbuf_log() that this is always \0 terminated */
329 0 : char *debug_get_ringbuf(void)
330 : {
331 0 : return debug_ringbuf;
332 : }
333 :
334 : /* Return the size of the ringbuf (including a \0 terminator) */
335 0 : size_t debug_get_ringbuf_size(void)
336 : {
337 0 : return debug_ringbuf_size;
338 : }
339 :
340 160578 : static void debug_ringbuf_reload(bool enabled, bool previously_enabled,
341 : const char *prog_name, char *option)
342 : {
343 : bool cmp;
344 160578 : size_t optlen = strlen(DEBUG_RINGBUF_SIZE_OPT);
345 :
346 160578 : debug_ringbuf_size = DEBUG_RINGBUF_SIZE;
347 160578 : debug_ringbuf_ofs = 0;
348 :
349 160578 : SAFE_FREE(debug_ringbuf);
350 :
351 160578 : if (!enabled) {
352 157061 : return;
353 : }
354 :
355 0 : if (option != NULL) {
356 0 : cmp = strncmp(option, DEBUG_RINGBUF_SIZE_OPT, optlen);
357 0 : if (cmp == 0) {
358 0 : debug_ringbuf_size = (size_t)strtoull(
359 0 : option + optlen, NULL, 10);
360 : }
361 : }
362 :
363 0 : debug_ringbuf = calloc(debug_ringbuf_size, sizeof(char));
364 0 : if (debug_ringbuf == NULL) {
365 0 : return;
366 : }
367 : }
368 :
369 0 : static void debug_ringbuf_log(int msg_level,
370 : const char *msg,
371 : const char *msg_no_nl)
372 : {
373 0 : size_t msglen = strlen(msg);
374 : size_t allowed_size;
375 :
376 0 : if (debug_ringbuf == NULL) {
377 0 : return;
378 : }
379 :
380 : /* Ensure the buffer is always \0 terminated */
381 0 : allowed_size = debug_ringbuf_size - 1;
382 :
383 0 : if (msglen > allowed_size) {
384 0 : return;
385 : }
386 :
387 0 : if ((debug_ringbuf_ofs + msglen) < debug_ringbuf_ofs) {
388 0 : return;
389 : }
390 :
391 0 : if ((debug_ringbuf_ofs + msglen) > allowed_size) {
392 0 : debug_ringbuf_ofs = 0;
393 : }
394 :
395 0 : memcpy(debug_ringbuf + debug_ringbuf_ofs, msg, msglen);
396 0 : debug_ringbuf_ofs += msglen;
397 : }
398 :
399 : static struct debug_backend {
400 : const char *name;
401 : int log_level;
402 : int new_log_level;
403 : void (*reload)(bool enabled, bool prev_enabled,
404 : const char *prog_name, char *option);
405 : void (*log)(int msg_level, const char *msg, const char *msg_no_nl);
406 : char *option;
407 : } debug_backends[] = {
408 : {
409 : .name = "file",
410 : .log = debug_file_log,
411 : },
412 : #ifdef WITH_SYSLOG
413 : {
414 : .name = "syslog",
415 : .reload = debug_syslog_reload,
416 : .log = debug_syslog_log,
417 : },
418 : #endif
419 :
420 : #if defined(HAVE_LIBSYSTEMD_JOURNAL) || defined(HAVE_LIBSYSTEMD)
421 : {
422 : .name = "systemd",
423 : .log = debug_systemd_log,
424 : },
425 : #endif
426 :
427 : #ifdef HAVE_LTTNG_TRACEF
428 : {
429 : .name = "lttng",
430 : .log = debug_lttng_log,
431 : },
432 : #endif
433 :
434 : #ifdef HAVE_GPFS
435 : {
436 : .name = "gpfs",
437 : .reload = debug_gpfs_reload,
438 : .log = debug_gpfs_log,
439 : },
440 : #endif
441 : {
442 : .name = "ringbuf",
443 : .log = debug_ringbuf_log,
444 : .reload = debug_ringbuf_reload,
445 : },
446 : };
447 :
448 223055 : static struct debug_backend *debug_find_backend(const char *name)
449 : {
450 : unsigned i;
451 :
452 256142 : for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
453 259048 : if (strcmp(name, debug_backends[i].name) == 0) {
454 229977 : return &debug_backends[i];
455 : }
456 : }
457 :
458 2 : return NULL;
459 : }
460 :
461 : /*
462 : * parse "backend[:option][@loglevel]
463 : */
464 189637 : static void debug_backend_parse_token(char *tok)
465 : {
466 : char *backend_name_option, *backend_name,*backend_level, *saveptr;
467 : char *backend_option;
468 : struct debug_backend *b;
469 :
470 : /*
471 : * First parse into backend[:option] and loglevel
472 : */
473 189637 : backend_name_option = strtok_r(tok, "@\0", &saveptr);
474 189637 : if (backend_name_option == NULL) {
475 2 : return;
476 : }
477 :
478 189637 : backend_level = strtok_r(NULL, "\0", &saveptr);
479 :
480 : /*
481 : * Now parse backend[:option]
482 : */
483 189637 : backend_name = strtok_r(backend_name_option, ":\0", &saveptr);
484 189637 : if (backend_name == NULL) {
485 0 : return;
486 : }
487 :
488 189637 : backend_option = strtok_r(NULL, "\0", &saveptr);
489 :
490 : /*
491 : * Find and update backend
492 : */
493 189637 : b = debug_find_backend(backend_name);
494 189637 : if (b == NULL) {
495 2 : return;
496 : }
497 :
498 189635 : if (backend_level == NULL) {
499 131515 : b->new_log_level = MAX_DEBUG_LEVEL;
500 : } else {
501 58120 : b->new_log_level = atoi(backend_level);
502 : }
503 :
504 189635 : if (backend_option != NULL) {
505 0 : b->option = strdup(backend_option);
506 0 : if (b->option == NULL) {
507 0 : return;
508 : }
509 : }
510 : }
511 :
512 : /*
513 : * parse "backend1[:option1][@loglevel1] backend2[option2][@loglevel2] ... "
514 : * and enable/disable backends accordingly
515 : */
516 160578 : static void debug_set_backends(const char *param)
517 160578 : {
518 160578 : size_t str_len = strlen(param);
519 160578 : char str[str_len+1];
520 : char *tok, *saveptr;
521 : unsigned i;
522 :
523 : /*
524 : * initialize new_log_level to detect backends that have been
525 : * disabled
526 : */
527 963468 : for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
528 802890 : SAFE_FREE(debug_backends[i].option);
529 802890 : debug_backends[i].new_log_level = -1;
530 : }
531 :
532 164095 : memcpy(str, param, str_len + 1);
533 :
534 160578 : tok = strtok_r(str, LIST_SEP, &saveptr);
535 160578 : if (tok == NULL) {
536 0 : return;
537 : }
538 :
539 486606 : while (tok != NULL) {
540 189637 : debug_backend_parse_token(tok);
541 189637 : tok = strtok_r(NULL, LIST_SEP, &saveptr);
542 : }
543 :
544 : /*
545 : * Let backends react to config changes
546 : */
547 959951 : for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
548 802890 : struct debug_backend *b = &debug_backends[i];
549 :
550 802890 : if (b->reload) {
551 481734 : bool enabled = b->new_log_level > -1;
552 481734 : bool previously_enabled = b->log_level > -1;
553 :
554 481734 : b->reload(enabled, previously_enabled, state.prog_name,
555 : b->option);
556 : }
557 802890 : b->log_level = b->new_log_level;
558 : }
559 : }
560 :
561 6364 : static void debug_backends_log(const char *msg, int msg_level)
562 : {
563 : char msg_no_nl[FORMAT_BUFR_SIZE];
564 : size_t i;
565 : size_t len;
566 :
567 : /*
568 : * Some backends already add an extra newline, so also provide
569 : * a buffer without the newline character.
570 : */
571 6364 : len = MIN(strlen(msg), FORMAT_BUFR_SIZE - 1);
572 6364 : if ((len > 0) && (msg[len - 1] == '\n')) {
573 6364 : len--;
574 : }
575 :
576 6364 : memcpy(msg_no_nl, msg, len);
577 6364 : msg_no_nl[len] = '\0';
578 :
579 38184 : for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
580 31820 : if (msg_level <= debug_backends[i].log_level) {
581 6787 : debug_backends[i].log(msg_level, msg, msg_no_nl);
582 : }
583 : }
584 6364 : }
585 :
586 964271937 : int debuglevel_get_class(size_t idx)
587 : {
588 964271937 : return dbgc_config[idx].loglevel;
589 : }
590 :
591 1965 : void debuglevel_set_class(size_t idx, int level)
592 : {
593 1965 : dbgc_config[idx].loglevel = level;
594 1965 : }
595 :
596 :
597 : /* -------------------------------------------------------------------------- **
598 : * Internal variables.
599 : *
600 : * debug_count - Number of debug messages that have been output.
601 : * Used to check log size.
602 : *
603 : * current_msg_level - Internal copy of the message debug level. Written by
604 : * dbghdr() and read by Debug1().
605 : *
606 : * format_bufr - Used to format debug messages. The dbgtext() function
607 : * prints debug messages to a string, and then passes the
608 : * string to format_debug_text(), which uses format_bufr
609 : * to build the formatted output.
610 : *
611 : * format_pos - Marks the first free byte of the format_bufr.
612 : *
613 : *
614 : * log_overflow - When this variable is true, never attempt to check the
615 : * size of the log. This is a hack, so that we can write
616 : * a message using DEBUG, from open_logs() when we
617 : * are unable to open a new log file for some reason.
618 : */
619 :
620 : static int debug_count = 0;
621 : static char format_bufr[FORMAT_BUFR_SIZE];
622 : static size_t format_pos = 0;
623 : static bool log_overflow = false;
624 :
625 : /*
626 : * Define all the debug class selection names here. Names *MUST NOT* contain
627 : * white space. There must be one name for each DBGC_<class name>, and they
628 : * must be in the table in the order of DBGC_<class name>..
629 : */
630 :
631 : static char **classname_table = NULL;
632 :
633 :
634 : /* -------------------------------------------------------------------------- **
635 : * Functions...
636 : */
637 :
638 : static void debug_init(void);
639 :
640 : /***************************************************************************
641 : Free memory pointed to by global pointers.
642 : ****************************************************************************/
643 :
644 1019 : void gfree_debugsyms(void)
645 : {
646 : unsigned i;
647 :
648 1019 : TALLOC_FREE(classname_table);
649 :
650 1019 : if ( dbgc_config != debug_class_list_initial ) {
651 1019 : TALLOC_FREE( dbgc_config );
652 1019 : dbgc_config = discard_const_p(struct debug_class,
653 : debug_class_list_initial);
654 : }
655 :
656 1019 : debug_num_classes = 0;
657 :
658 1019 : state.initialized = false;
659 :
660 6114 : for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
661 5095 : SAFE_FREE(debug_backends[i].option);
662 : }
663 1019 : }
664 :
665 : /****************************************************************************
666 : utility lists registered debug class names's
667 : ****************************************************************************/
668 :
669 0 : char *debug_list_class_names_and_levels(void)
670 : {
671 0 : char *buf = NULL;
672 : size_t i;
673 : /* prepare strings */
674 0 : for (i = 0; i < debug_num_classes; i++) {
675 0 : buf = talloc_asprintf_append(buf,
676 : "%s:%d%s",
677 0 : classname_table[i],
678 0 : dbgc_config[i].loglevel,
679 0 : i == (debug_num_classes - 1) ? "\n" : " ");
680 0 : if (buf == NULL) {
681 0 : return NULL;
682 : }
683 : }
684 0 : return buf;
685 : }
686 :
687 : /****************************************************************************
688 : Utility to translate names to debug class index's (internal version).
689 : ****************************************************************************/
690 :
691 1173699 : static int debug_lookup_classname_int(const char* classname)
692 : {
693 : size_t i;
694 :
695 1173699 : if (classname == NULL) {
696 0 : return -1;
697 : }
698 :
699 23369551 : for (i=0; i < debug_num_classes; i++) {
700 22218763 : char *entry = classname_table[i];
701 22218763 : if (entry != NULL && strcmp(classname, entry)==0) {
702 1 : return i;
703 : }
704 : }
705 1150789 : return -1;
706 : }
707 :
708 : /****************************************************************************
709 : Add a new debug class to the system.
710 : ****************************************************************************/
711 :
712 1173698 : int debug_add_class(const char *classname)
713 : {
714 : int ndx;
715 1173698 : struct debug_class *new_class_list = NULL;
716 : char **new_name_list;
717 : int default_level;
718 :
719 1173698 : if (classname == NULL) {
720 0 : return -1;
721 : }
722 :
723 : /* check the init has yet been called */
724 1173698 : debug_init();
725 :
726 1173698 : ndx = debug_lookup_classname_int(classname);
727 1173698 : if (ndx >= 0) {
728 0 : return ndx;
729 : }
730 1173698 : ndx = debug_num_classes;
731 :
732 1173698 : if (dbgc_config == debug_class_list_initial) {
733 : /* Initial loading... */
734 29619 : new_class_list = NULL;
735 : } else {
736 1143490 : new_class_list = dbgc_config;
737 : }
738 :
739 1173698 : default_level = dbgc_config[DBGC_ALL].loglevel;
740 :
741 1173698 : new_class_list = talloc_realloc(NULL,
742 : new_class_list,
743 : struct debug_class,
744 : ndx + 1);
745 1173698 : if (new_class_list == NULL) {
746 0 : return -1;
747 : }
748 :
749 1173698 : dbgc_config = new_class_list;
750 :
751 1173698 : dbgc_config[ndx] = (struct debug_class) {
752 : .loglevel = default_level,
753 : .fd = -1,
754 : };
755 :
756 1173698 : new_name_list = talloc_realloc(NULL, classname_table, char *, ndx + 1);
757 1173698 : if (new_name_list == NULL) {
758 0 : return -1;
759 : }
760 1173698 : classname_table = new_name_list;
761 :
762 1173698 : classname_table[ndx] = talloc_strdup(classname_table, classname);
763 1173698 : if (classname_table[ndx] == NULL) {
764 0 : return -1;
765 : }
766 :
767 1173698 : debug_num_classes = ndx + 1;
768 :
769 1173698 : return ndx;
770 : }
771 :
772 : /****************************************************************************
773 : Utility to translate names to debug class index's (public version).
774 : ****************************************************************************/
775 :
776 1 : static int debug_lookup_classname(const char *classname)
777 : {
778 : int ndx;
779 :
780 1 : if (classname == NULL || !*classname)
781 0 : return -1;
782 :
783 1 : ndx = debug_lookup_classname_int(classname);
784 :
785 1 : if (ndx != -1)
786 0 : return ndx;
787 :
788 0 : DBG_WARNING("Unknown classname[%s] -> adding it...\n", classname);
789 0 : return debug_add_class(classname);
790 : }
791 :
792 : /****************************************************************************
793 : Dump the current registered debug levels.
794 : ****************************************************************************/
795 :
796 228961 : static void debug_dump_status(int level)
797 : {
798 : size_t q;
799 :
800 228961 : DEBUG(level, ("INFO: Current debug levels:\n"));
801 8930696 : for (q = 0; q < debug_num_classes; q++) {
802 8705875 : const char *classname = classname_table[q];
803 8705875 : DEBUGADD(level, (" %s: %d\n",
804 : classname,
805 : dbgc_config[q].loglevel));
806 : }
807 228961 : }
808 :
809 1 : static bool debug_parse_param(char *param)
810 : {
811 : char *class_name;
812 1 : char *class_file = NULL;
813 : char *class_level;
814 1 : char *saveptr = NULL;
815 : int ndx;
816 :
817 1 : class_name = strtok_r(param, ":", &saveptr);
818 1 : if (class_name == NULL) {
819 0 : return false;
820 : }
821 :
822 1 : class_level = strtok_r(NULL, "@\0", &saveptr);
823 1 : if (class_level == NULL) {
824 0 : return false;
825 : }
826 :
827 1 : class_file = strtok_r(NULL, "\0", &saveptr);
828 :
829 1 : ndx = debug_lookup_classname(class_name);
830 1 : if (ndx == -1) {
831 0 : return false;
832 : }
833 :
834 2 : dbgc_config[ndx].loglevel = atoi(class_level);
835 :
836 1 : if (class_file == NULL) {
837 0 : return true;
838 : }
839 :
840 0 : TALLOC_FREE(dbgc_config[ndx].logfile);
841 :
842 0 : dbgc_config[ndx].logfile = talloc_strdup(NULL, class_file);
843 0 : if (dbgc_config[ndx].logfile == NULL) {
844 0 : return false;
845 : }
846 0 : return true;
847 : }
848 :
849 : /****************************************************************************
850 : Parse the debug levels from smb.conf. Example debug level string:
851 : 3 tdb:5 printdrivers:7
852 : Note: the 1st param has no "name:" preceding it.
853 : ****************************************************************************/
854 :
855 228961 : bool debug_parse_levels(const char *params_str)
856 228961 : {
857 228961 : size_t str_len = strlen(params_str);
858 228961 : char str[str_len+1];
859 : char *tok, *saveptr;
860 : size_t i;
861 :
862 : /* Just in case */
863 228961 : debug_init();
864 :
865 233101 : memcpy(str, params_str, str_len+1);
866 :
867 228961 : tok = strtok_r(str, LIST_SEP, &saveptr);
868 228961 : if (tok == NULL) {
869 0 : return true;
870 : }
871 :
872 : /* Allow DBGC_ALL to be specified w/o requiring its class name e.g."10"
873 : * v.s. "all:10", this is the traditional way to set DEBUGLEVEL
874 : */
875 228961 : if (isdigit(tok[0])) {
876 233101 : dbgc_config[DBGC_ALL].loglevel = atoi(tok);
877 228961 : tok = strtok_r(NULL, LIST_SEP, &saveptr);
878 : } else {
879 0 : dbgc_config[DBGC_ALL].loglevel = 0;
880 : }
881 :
882 : /* Array is debug_num_classes long */
883 8705875 : for (i = DBGC_ALL+1; i < debug_num_classes; i++) {
884 8476914 : dbgc_config[i].loglevel = dbgc_config[DBGC_ALL].loglevel;
885 8476914 : TALLOC_FREE(dbgc_config[i].logfile);
886 : }
887 :
888 426856 : while (tok != NULL) {
889 : bool ok;
890 :
891 1 : ok = debug_parse_param(tok);
892 1 : if (!ok) {
893 0 : DEBUG(0,("debug_parse_params: unrecognized debug "
894 : "class name or format [%s]\n", tok));
895 0 : return false;
896 : }
897 :
898 1 : tok = strtok_r(NULL, LIST_SEP, &saveptr);
899 : }
900 :
901 228961 : debug_dump_status(5);
902 :
903 228961 : return true;
904 : }
905 :
906 : /* setup for logging of talloc warnings */
907 0 : static void talloc_log_fn(const char *msg)
908 : {
909 0 : DEBUG(0,("%s", msg));
910 0 : }
911 :
912 42251 : void debug_setup_talloc_log(void)
913 : {
914 42251 : talloc_set_log_fn(talloc_log_fn);
915 42251 : }
916 :
917 :
918 : /****************************************************************************
919 : Init debugging (one time stuff)
920 : ****************************************************************************/
921 :
922 3619734 : static void debug_init(void)
923 : {
924 : size_t i;
925 :
926 3619734 : if (state.initialized)
927 3471683 : return;
928 :
929 30208 : state.initialized = true;
930 :
931 30208 : debug_setup_talloc_log();
932 :
933 1178112 : for (i = 0; i < ARRAY_SIZE(default_classname_table); i++) {
934 1147904 : debug_add_class(default_classname_table[i]);
935 : }
936 30208 : dbgc_config[DBGC_ALL].fd = 2;
937 :
938 181248 : for (i = 0; i < ARRAY_SIZE(debug_backends); i++) {
939 151040 : debug_backends[i].log_level = -1;
940 151040 : debug_backends[i].new_log_level = -1;
941 : }
942 : }
943 :
944 160578 : void debug_set_settings(struct debug_settings *settings,
945 : const char *logging_param,
946 : int syslog_level, bool syslog_only)
947 : {
948 : char fake_param[256];
949 160578 : size_t len = 0;
950 :
951 : /*
952 : * This forces in some smb.conf derived values into the debug
953 : * system. There are no pointers in this structure, so we can
954 : * just structure-assign it in
955 : */
956 160578 : state.settings = *settings;
957 :
958 : /*
959 : * If 'logging' is not set, create backend settings from
960 : * deprecated 'syslog' and 'syslog only' parameters
961 : */
962 160578 : if (logging_param != NULL) {
963 160578 : len = strlen(logging_param);
964 : }
965 160578 : if (len == 0) {
966 29061 : if (syslog_only) {
967 2 : snprintf(fake_param, sizeof(fake_param),
968 : "syslog@%d", syslog_level - 1);
969 : } else {
970 29059 : snprintf(fake_param, sizeof(fake_param),
971 : "syslog@%d file@%d", syslog_level -1,
972 : MAX_DEBUG_LEVEL);
973 : }
974 :
975 28562 : logging_param = fake_param;
976 : }
977 :
978 160578 : debug_set_backends(logging_param);
979 160578 : }
980 :
981 : /**
982 : control the name of the logfile and whether logging will be to stdout, stderr
983 : or a file, and set up syslog
984 :
985 : new_log indicates the destination for the debug log (an enum in
986 : order of precedence - once set to DEBUG_FILE, it is not possible to
987 : reset to DEBUG_STDOUT for example. This makes it easy to override
988 : for debug to stderr on the command line, as the smb.conf cannot
989 : reset it back to file-based logging
990 : */
991 24343 : void setup_logging(const char *prog_name, enum debug_logtype new_logtype)
992 : {
993 24343 : debug_init();
994 24343 : if (state.logtype < new_logtype) {
995 1364 : state.logtype = new_logtype;
996 : }
997 24343 : if (prog_name) {
998 24343 : const char *p = strrchr(prog_name, '/');
999 :
1000 24343 : if (p) {
1001 191 : prog_name = p + 1;
1002 : }
1003 :
1004 24343 : strlcpy(state.prog_name, prog_name, sizeof(state.prog_name));
1005 : }
1006 24343 : reopen_logs_internal();
1007 24343 : }
1008 :
1009 : /***************************************************************************
1010 : Set the logfile name.
1011 : **************************************************************************/
1012 :
1013 192086 : void debug_set_logfile(const char *name)
1014 : {
1015 192086 : if (name == NULL || *name == 0) {
1016 : /* this copes with calls when smb.conf is not loaded yet */
1017 64 : return;
1018 : }
1019 192022 : TALLOC_FREE(dbgc_config[DBGC_ALL].logfile);
1020 192022 : dbgc_config[DBGC_ALL].logfile = talloc_strdup(NULL, name);
1021 : }
1022 :
1023 1531912 : static void debug_close_fd(int fd)
1024 : {
1025 1642355 : if (fd > 2) {
1026 39850 : close(fd);
1027 : }
1028 1531912 : }
1029 :
1030 265 : enum debug_logtype debug_get_log_type(void)
1031 : {
1032 265 : return state.logtype;
1033 : }
1034 :
1035 4 : bool debug_get_output_is_stderr(void)
1036 : {
1037 4 : return (state.logtype == DEBUG_DEFAULT_STDERR) || (state.logtype == DEBUG_STDERR);
1038 : }
1039 :
1040 111 : bool debug_get_output_is_stdout(void)
1041 : {
1042 111 : return (state.logtype == DEBUG_DEFAULT_STDOUT) || (state.logtype == DEBUG_STDOUT);
1043 : }
1044 :
1045 52 : void debug_set_callback(void *private_ptr, debug_callback_fn fn)
1046 : {
1047 52 : debug_init();
1048 52 : if (fn) {
1049 34 : state.logtype = DEBUG_CALLBACK;
1050 34 : state.callback_private = private_ptr;
1051 34 : state.callback = fn;
1052 : } else {
1053 18 : state.logtype = DEBUG_DEFAULT_STDERR;
1054 18 : state.callback_private = NULL;
1055 18 : state.callback = NULL;
1056 : }
1057 52 : }
1058 :
1059 92 : static void debug_callback_log(const char *msg, int msg_level)
1060 92 : {
1061 92 : size_t msg_len = strlen(msg);
1062 92 : char msg_copy[msg_len];
1063 :
1064 92 : if ((msg_len > 0) && (msg[msg_len-1] == '\n')) {
1065 92 : memcpy(msg_copy, msg, msg_len-1);
1066 92 : msg_copy[msg_len-1] = '\0';
1067 92 : msg = msg_copy;
1068 : }
1069 :
1070 92 : state.callback(state.callback_private, msg_level, msg);
1071 92 : }
1072 :
1073 : /**************************************************************************
1074 : reopen the log files
1075 : note that we now do this unconditionally
1076 : We attempt to open the new debug fp before closing the old. This means
1077 : if we run out of fd's we just keep using the old fd rather than aborting.
1078 : Fix from dgibson@linuxcare.com.
1079 : **************************************************************************/
1080 :
1081 1522629 : static bool reopen_one_log(struct debug_class *config)
1082 : {
1083 1522629 : int old_fd = config->fd;
1084 1522629 : const char *logfile = config->logfile;
1085 : struct stat st;
1086 : int new_fd;
1087 : int ret;
1088 :
1089 1522629 : if (logfile == NULL) {
1090 1482287 : debug_close_fd(old_fd);
1091 1482287 : config->fd = -1;
1092 1482287 : return true;
1093 : }
1094 :
1095 40342 : new_fd = open(logfile, O_WRONLY|O_APPEND|O_CREAT, 0644);
1096 40342 : if (new_fd == -1) {
1097 315 : log_overflow = true;
1098 315 : DBG_ERR("Unable to open new log file '%s': %s\n",
1099 : logfile, strerror(errno));
1100 315 : log_overflow = false;
1101 315 : return false;
1102 : }
1103 :
1104 40027 : debug_close_fd(old_fd);
1105 40027 : smb_set_close_on_exec(new_fd);
1106 40027 : config->fd = new_fd;
1107 :
1108 40027 : ret = fstat(new_fd, &st);
1109 40027 : if (ret != 0) {
1110 0 : log_overflow = true;
1111 0 : DBG_ERR("Unable to fstat() new log file '%s': %s\n",
1112 : logfile, strerror(errno));
1113 0 : log_overflow = false;
1114 0 : return false;
1115 : }
1116 :
1117 40027 : config->ino = st.st_ino;
1118 40027 : return true;
1119 : }
1120 :
1121 : /**
1122 : reopen the log file (usually called because the log file name might have changed)
1123 : */
1124 160383 : bool reopen_logs_internal(void)
1125 : {
1126 160383 : struct debug_backend *b = NULL;
1127 : mode_t oldumask;
1128 160383 : int new_fd = 0;
1129 : size_t i;
1130 : bool ok;
1131 :
1132 160383 : if (state.reopening_logs) {
1133 0 : return true;
1134 : }
1135 :
1136 : /* Now clear the SIGHUP induced flag */
1137 160383 : state.schedule_reopen_logs = false;
1138 :
1139 160383 : switch (state.logtype) {
1140 0 : case DEBUG_CALLBACK:
1141 0 : return true;
1142 96924 : case DEBUG_STDOUT:
1143 : case DEBUG_DEFAULT_STDOUT:
1144 97001 : debug_close_fd(dbgc_config[DBGC_ALL].fd);
1145 96924 : dbgc_config[DBGC_ALL].fd = 1;
1146 96924 : return true;
1147 :
1148 23117 : case DEBUG_DEFAULT_STDERR:
1149 : case DEBUG_STDERR:
1150 23511 : debug_close_fd(dbgc_config[DBGC_ALL].fd);
1151 23117 : dbgc_config[DBGC_ALL].fd = 2;
1152 23117 : return true;
1153 :
1154 37434 : case DEBUG_FILE:
1155 40342 : b = debug_find_backend("file");
1156 40342 : assert(b != NULL);
1157 :
1158 40342 : b->log_level = MAX_DEBUG_LEVEL;
1159 40342 : break;
1160 : }
1161 :
1162 40342 : oldumask = umask( 022 );
1163 :
1164 40342 : for (i = DBGC_ALL; i < debug_num_classes; i++) {
1165 40342 : if (dbgc_config[i].logfile != NULL) {
1166 37434 : break;
1167 : }
1168 : }
1169 40342 : if (i == debug_num_classes) {
1170 0 : return false;
1171 : }
1172 :
1173 40342 : state.reopening_logs = true;
1174 :
1175 1562656 : for (i = DBGC_ALL; i < debug_num_classes; i++) {
1176 1522629 : ok = reopen_one_log(&dbgc_config[i]);
1177 1522629 : if (!ok) {
1178 301 : break;
1179 : }
1180 : }
1181 :
1182 : /* Fix from klausr@ITAP.Physik.Uni-Stuttgart.De
1183 : * to fix problem where smbd's that generate less
1184 : * than 100 messages keep growing the log.
1185 : */
1186 40342 : force_check_log_size();
1187 40342 : (void)umask(oldumask);
1188 :
1189 : /*
1190 : * If log file was opened or created successfully, take over stderr to
1191 : * catch output into logs.
1192 : */
1193 37434 : if (new_fd != -1) {
1194 40342 : if (dup2(dbgc_config[DBGC_ALL].fd, 2) == -1) {
1195 : /* Close stderr too, if dup2 can't point it -
1196 : at the logfile. There really isn't much
1197 : that can be done on such a fundamental
1198 : failure... */
1199 0 : close_low_fd(2);
1200 : }
1201 : }
1202 :
1203 40342 : state.reopening_logs = false;
1204 :
1205 40342 : return ok;
1206 : }
1207 :
1208 : /**************************************************************************
1209 : Force a check of the log size.
1210 : ***************************************************************************/
1211 :
1212 11765014 : void force_check_log_size( void )
1213 : {
1214 11765014 : debug_count = 100;
1215 11765014 : }
1216 :
1217 0 : _PUBLIC_ void debug_schedule_reopen_logs(void)
1218 : {
1219 0 : state.schedule_reopen_logs = true;
1220 0 : }
1221 :
1222 :
1223 : /***************************************************************************
1224 : Check to see if there is any need to check if the logfile has grown too big.
1225 : **************************************************************************/
1226 :
1227 11725325 : bool need_to_check_log_size(void)
1228 : {
1229 : int maxlog;
1230 : size_t i;
1231 :
1232 11725325 : if (debug_count < 100) {
1233 33405 : return false;
1234 : }
1235 :
1236 11691761 : maxlog = state.settings.max_log_size * 1024;
1237 11691761 : if (maxlog <= 0) {
1238 1880 : debug_count = 0;
1239 1880 : return false;
1240 : }
1241 :
1242 11689881 : if (dbgc_config[DBGC_ALL].fd > 2) {
1243 2460 : return true;
1244 : }
1245 :
1246 444094344 : for (i = DBGC_ALL + 1; i < debug_num_classes; i++) {
1247 432432135 : if (dbgc_config[i].fd != -1) {
1248 0 : return true;
1249 : }
1250 : }
1251 :
1252 11687355 : debug_count = 0;
1253 11687355 : return false;
1254 : }
1255 :
1256 : /**************************************************************************
1257 : Check to see if the log has grown to be too big.
1258 : **************************************************************************/
1259 :
1260 1768 : static void do_one_check_log_size(off_t maxlog, struct debug_class *config)
1261 1768 : {
1262 1768 : char name[strlen(config->logfile) + 5];
1263 : struct stat st;
1264 : int ret;
1265 1768 : bool reopen = false;
1266 : bool ok;
1267 :
1268 1768 : if (maxlog == 0) {
1269 1768 : return;
1270 : }
1271 :
1272 1804 : ret = stat(config->logfile, &st);
1273 1768 : if (ret != 0) {
1274 0 : return;
1275 : }
1276 1768 : if (st.st_size >= maxlog ) {
1277 0 : reopen = true;
1278 : }
1279 :
1280 1768 : if (st.st_ino != config->ino) {
1281 0 : reopen = true;
1282 : }
1283 :
1284 1768 : if (!reopen) {
1285 1732 : return;
1286 : }
1287 :
1288 : /* reopen_logs_internal() modifies *_fd */
1289 0 : (void)reopen_logs_internal();
1290 :
1291 0 : if (config->fd <= 2) {
1292 0 : return;
1293 : }
1294 0 : ret = fstat(config->fd, &st);
1295 0 : if (ret != 0) {
1296 0 : config->ino = (ino_t)0;
1297 0 : return;
1298 : }
1299 :
1300 0 : config->ino = st.st_ino;
1301 :
1302 0 : if (st.st_size < maxlog) {
1303 0 : return;
1304 : }
1305 :
1306 0 : snprintf(name, sizeof(name), "%s.old", config->logfile);
1307 :
1308 0 : (void)rename(config->logfile, name);
1309 :
1310 0 : ok = reopen_logs_internal();
1311 0 : if (ok) {
1312 0 : return;
1313 : }
1314 : /* We failed to reopen a log - continue using the old name. */
1315 0 : (void)rename(name, config->logfile);
1316 : }
1317 :
1318 1768 : static void do_check_log_size(off_t maxlog)
1319 : {
1320 : size_t i;
1321 :
1322 70567 : for (i = DBGC_ALL; i < debug_num_classes; i++) {
1323 68799 : if (dbgc_config[i].fd == -1) {
1324 67031 : continue;
1325 : }
1326 1768 : if (dbgc_config[i].logfile == NULL) {
1327 0 : continue;
1328 : }
1329 1768 : do_one_check_log_size(maxlog, &dbgc_config[i]);
1330 : }
1331 1768 : }
1332 :
1333 8040 : void check_log_size( void )
1334 : {
1335 : off_t maxlog;
1336 :
1337 : /*
1338 : * We need to be root to check/change log-file, skip this and let the main
1339 : * loop check do a new check as root.
1340 : */
1341 :
1342 : #if _SAMBA_BUILD_ == 3
1343 : if (geteuid() != sec_initial_uid())
1344 : #else
1345 8040 : if( geteuid() != 0)
1346 : #endif
1347 : {
1348 : /* We don't check sec_initial_uid() here as it isn't
1349 : * available in common code and we don't generally
1350 : * want to rotate and the possibly lose logs in
1351 : * make test or the build farm */
1352 1902 : return;
1353 : }
1354 :
1355 6124 : if(log_overflow || (!state.schedule_reopen_logs && !need_to_check_log_size())) {
1356 4298 : return;
1357 : }
1358 :
1359 1768 : maxlog = state.settings.max_log_size * 1024;
1360 :
1361 1768 : if (state.schedule_reopen_logs) {
1362 0 : (void)reopen_logs_internal();
1363 : }
1364 :
1365 1768 : do_check_log_size(maxlog);
1366 :
1367 : /*
1368 : * Here's where we need to panic if dbgc_config[DBGC_ALL].fd == 0 or -1
1369 : * (invalid values)
1370 : */
1371 :
1372 1768 : if (dbgc_config[DBGC_ALL].fd <= 0) {
1373 : /* This code should only be reached in very strange
1374 : * circumstances. If we merely fail to open the new log we
1375 : * should stick with the old one. ergo this should only be
1376 : * reached when opening the logs for the first time: at
1377 : * startup or when the log level is increased from zero.
1378 : * -dwg 6 June 2000
1379 : */
1380 0 : int fd = open( "/dev/console", O_WRONLY, 0);
1381 0 : if (fd != -1) {
1382 0 : smb_set_close_on_exec(fd);
1383 0 : dbgc_config[DBGC_ALL].fd = fd;
1384 0 : DBG_ERR("check_log_size: open of debug file %s failed "
1385 : "- using console.\n",
1386 : dbgc_config[DBGC_ALL].logfile);
1387 : } else {
1388 : /*
1389 : * We cannot continue without a debug file handle.
1390 : */
1391 0 : abort();
1392 : }
1393 : }
1394 1768 : debug_count = 0;
1395 : }
1396 :
1397 : /*************************************************************************
1398 : Write an debug message on the debugfile.
1399 : This is called by dbghdr() and format_debug_text().
1400 : ************************************************************************/
1401 :
1402 344550 : static void Debug1(const char *msg)
1403 : {
1404 344550 : int old_errno = errno;
1405 :
1406 344550 : debug_count++;
1407 :
1408 344550 : switch(state.logtype) {
1409 92 : case DEBUG_CALLBACK:
1410 92 : debug_callback_log(msg, current_msg_level);
1411 92 : break;
1412 338094 : case DEBUG_STDOUT:
1413 : case DEBUG_STDERR:
1414 : case DEBUG_DEFAULT_STDOUT:
1415 : case DEBUG_DEFAULT_STDERR:
1416 338094 : if (dbgc_config[DBGC_ALL].fd > 0) {
1417 : ssize_t ret;
1418 : do {
1419 338094 : ret = write(dbgc_config[DBGC_ALL].fd,
1420 : msg,
1421 : strlen(msg));
1422 338094 : } while (ret == -1 && errno == EINTR);
1423 : }
1424 330951 : break;
1425 6364 : case DEBUG_FILE:
1426 6364 : debug_backends_log(msg, current_msg_level);
1427 6364 : break;
1428 : };
1429 :
1430 344550 : errno = old_errno;
1431 344550 : }
1432 :
1433 : /**************************************************************************
1434 : Print the buffer content via Debug1(), then reset the buffer.
1435 : Input: none
1436 : Output: none
1437 : ****************************************************************************/
1438 :
1439 334270 : static void bufr_print( void )
1440 : {
1441 341454 : format_bufr[format_pos] = '\0';
1442 341454 : (void)Debug1(format_bufr);
1443 341454 : format_pos = 0;
1444 334270 : }
1445 :
1446 : /***************************************************************************
1447 : Format the debug message text.
1448 :
1449 : Input: msg - Text to be added to the "current" debug message text.
1450 :
1451 : Output: none.
1452 :
1453 : Notes: The purpose of this is two-fold. First, each call to syslog()
1454 : (used by Debug1(), see above) generates a new line of syslog
1455 : output. This is fixed by storing the partial lines until the
1456 : newline character is encountered. Second, printing the debug
1457 : message lines when a newline is encountered allows us to add
1458 : spaces, thus indenting the body of the message and making it
1459 : more readable.
1460 : **************************************************************************/
1461 :
1462 2192680 : static void format_debug_text( const char *msg )
1463 : {
1464 : size_t i;
1465 2192680 : bool timestamp = (state.logtype == DEBUG_FILE && (state.settings.timestamp_logs));
1466 :
1467 2192680 : debug_init();
1468 :
1469 25699589 : for( i = 0; msg[i]; i++ ) {
1470 : /* Indent two spaces at each new line. */
1471 23506909 : if(timestamp && 0 == format_pos) {
1472 3268 : format_bufr[0] = format_bufr[1] = ' ';
1473 3268 : format_pos = 2;
1474 : }
1475 :
1476 : /* If there's room, copy the character to the format buffer. */
1477 23506909 : if (format_pos < FORMAT_BUFR_SIZE - 1)
1478 23506909 : format_bufr[format_pos++] = msg[i];
1479 :
1480 : /* If a newline is encountered, print & restart. */
1481 23506909 : if( '\n' == msg[i] )
1482 334270 : bufr_print();
1483 :
1484 : /* If the buffer is full dump it out, reset it, and put out a line
1485 : * continuation indicator.
1486 : */
1487 23506909 : if (format_pos >= FORMAT_BUFR_SIZE - 1) {
1488 0 : bufr_print();
1489 0 : (void)Debug1( " +>\n" );
1490 : }
1491 : }
1492 :
1493 : /* Just to be safe... */
1494 2192680 : format_bufr[format_pos] = '\0';
1495 2192680 : }
1496 :
1497 : /***************************************************************************
1498 : Flush debug output, including the format buffer content.
1499 :
1500 : Input: none
1501 : Output: none
1502 : ***************************************************************************/
1503 :
1504 0 : void dbgflush( void )
1505 : {
1506 0 : bufr_print();
1507 0 : }
1508 :
1509 2169816 : bool dbgsetclass(int level, int cls)
1510 : {
1511 : /* Set current_msg_level. */
1512 2169816 : current_msg_level = level;
1513 :
1514 : /* Set current message class */
1515 2169816 : current_msg_class = cls;
1516 :
1517 2169816 : return true;
1518 : }
1519 :
1520 : /***************************************************************************
1521 : Print a Debug Header.
1522 :
1523 : Input: level - Debug level of the message (not the system-wide debug
1524 : level. )
1525 : cls - Debuglevel class of the calling module.
1526 : location - Pointer to a string containing the name of the file
1527 : from which this function was called, or an empty string
1528 : if the __FILE__ macro is not implemented.
1529 : func - Pointer to a string containing the name of the function
1530 : from which this function was called, or an empty string
1531 : if the __FUNCTION__ macro is not implemented.
1532 :
1533 : Output: Always true. This makes it easy to fudge a call to dbghdr()
1534 : in a macro, since the function can be called as part of a test.
1535 : Eg: ( (level <= DEBUGLEVEL) && (dbghdr(level,"",line)) )
1536 :
1537 : Notes: This function takes care of setting current_msg_level.
1538 :
1539 : ****************************************************************************/
1540 :
1541 103251 : bool dbghdrclass(int level, int cls, const char *location, const char *func)
1542 : {
1543 : /* Ensure we don't lose any real errno value. */
1544 103251 : int old_errno = errno;
1545 103251 : bool verbose = false;
1546 : char header_str[300];
1547 : size_t hs_len;
1548 : struct timeval tv;
1549 : struct timeval_buf tvbuf;
1550 :
1551 103251 : if( format_pos ) {
1552 : /* This is a fudge. If there is stuff sitting in the format_bufr, then
1553 : * the *right* thing to do is to call
1554 : * format_debug_text( "\n" );
1555 : * to write the remainder, and then proceed with the new header.
1556 : * Unfortunately, there are several places in the code at which
1557 : * the DEBUG() macro is used to build partial lines. That in mind,
1558 : * we'll work under the assumption that an incomplete line indicates
1559 : * that a new header is *not* desired.
1560 : */
1561 1576 : return( true );
1562 : }
1563 :
1564 101672 : dbgsetclass(level, cls);
1565 :
1566 : /* Don't print a header if we're logging to stdout. */
1567 101672 : if ( state.logtype != DEBUG_FILE ) {
1568 93817 : return( true );
1569 : }
1570 :
1571 : /* Print the header if timestamps are turned on. If parameters are
1572 : * not yet loaded, then default to timestamps on.
1573 : */
1574 3096 : if (!(state.settings.timestamp_logs ||
1575 0 : state.settings.debug_prefix_timestamp)) {
1576 0 : return true;
1577 : }
1578 :
1579 3096 : GetTimeOfDay(&tv);
1580 3096 : timeval_str_buf(&tv, false, state.settings.debug_hires_timestamp,
1581 : &tvbuf);
1582 :
1583 3096 : hs_len = snprintf(header_str, sizeof(header_str), "[%s, %2d",
1584 : tvbuf.buf, level);
1585 3096 : if (hs_len >= sizeof(header_str)) {
1586 0 : goto full;
1587 : }
1588 :
1589 3096 : if (unlikely(dbgc_config[cls].loglevel >= 10)) {
1590 0 : verbose = true;
1591 : }
1592 :
1593 3096 : if (verbose || state.settings.debug_pid) {
1594 652 : hs_len += snprintf(
1595 : header_str + hs_len, sizeof(header_str) - hs_len,
1596 652 : ", pid=%u", (unsigned int)getpid());
1597 652 : if (hs_len >= sizeof(header_str)) {
1598 0 : goto full;
1599 : }
1600 : }
1601 :
1602 3096 : if (verbose || state.settings.debug_uid) {
1603 0 : hs_len += snprintf(
1604 : header_str + hs_len, sizeof(header_str) - hs_len,
1605 : ", effective(%u, %u), real(%u, %u)",
1606 0 : (unsigned int)geteuid(), (unsigned int)getegid(),
1607 0 : (unsigned int)getuid(), (unsigned int)getgid());
1608 0 : if (hs_len >= sizeof(header_str)) {
1609 0 : goto full;
1610 : }
1611 : }
1612 :
1613 3096 : if ((verbose || state.settings.debug_class)
1614 0 : && (cls != DBGC_ALL)) {
1615 0 : hs_len += snprintf(
1616 : header_str + hs_len, sizeof(header_str) - hs_len,
1617 0 : ", class=%s", classname_table[cls]);
1618 0 : if (hs_len >= sizeof(header_str)) {
1619 0 : goto full;
1620 : }
1621 : }
1622 :
1623 : /*
1624 : * No +=, see man man strlcat
1625 : */
1626 3096 : hs_len = strlcat(header_str, "] ", sizeof(header_str));
1627 3096 : if (hs_len >= sizeof(header_str)) {
1628 0 : goto full;
1629 : }
1630 :
1631 3096 : if (!state.settings.debug_prefix_timestamp) {
1632 3133 : hs_len += snprintf(
1633 : header_str + hs_len, sizeof(header_str) - hs_len,
1634 : "%s(%s)\n", location, func);
1635 3059 : if (hs_len >= sizeof(header_str)) {
1636 0 : goto full;
1637 : }
1638 : }
1639 :
1640 5816 : full:
1641 3096 : (void)Debug1(header_str);
1642 :
1643 3096 : errno = old_errno;
1644 3096 : return( true );
1645 : }
1646 :
1647 : /***************************************************************************
1648 : Add text to the body of the "current" debug message via the format buffer.
1649 :
1650 : Input: format_str - Format string, as used in printf(), et. al.
1651 : ... - Variable argument list.
1652 :
1653 : ..or.. va_alist - Old style variable parameter list starting point.
1654 :
1655 : Output: Always true. See dbghdr() for more info, though this is not
1656 : likely to be used in the same way.
1657 :
1658 : ***************************************************************************/
1659 :
1660 : static inline bool __dbgtext_va(const char *format_str, va_list ap) PRINTF_ATTRIBUTE(1,0);
1661 2192680 : static inline bool __dbgtext_va(const char *format_str, va_list ap)
1662 : {
1663 2192680 : char *msgbuf = NULL;
1664 2192680 : bool ret = true;
1665 : int res;
1666 :
1667 2192680 : res = vasprintf(&msgbuf, format_str, ap);
1668 2192680 : if (res != -1) {
1669 2192680 : format_debug_text(msgbuf);
1670 : } else {
1671 0 : ret = false;
1672 : }
1673 2192680 : SAFE_FREE(msgbuf);
1674 2192680 : return ret;
1675 : }
1676 :
1677 0 : bool dbgtext_va(const char *format_str, va_list ap)
1678 : {
1679 0 : return __dbgtext_va(format_str, ap);
1680 : }
1681 :
1682 2192680 : bool dbgtext(const char *format_str, ... )
1683 : {
1684 : va_list ap;
1685 : bool ret;
1686 :
1687 2192680 : va_start(ap, format_str);
1688 2192680 : ret = __dbgtext_va(format_str, ap);
1689 2192680 : va_end(ap);
1690 :
1691 2192680 : return ret;
1692 : }
|