Branch data Line data Source code
1 : : /*
2 : : * libdpkg - Debian packaging suite library routines
3 : : * debug.c - debugging support
4 : : *
5 : : * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 : : * Copyright © 2011 Guillem Jover <guillem@debian.org>
7 : : *
8 : : * This 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 2 of the License, or
11 : : * (at your option) any later version.
12 : : *
13 : : * This 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 <https://www.gnu.org/licenses/>.
20 : : */
21 : :
22 : : #include <config.h>
23 : : #include <compat.h>
24 : :
25 : : #include <errno.h>
26 : : #include <stdarg.h>
27 : : #include <stdlib.h>
28 : : #include <stdio.h>
29 : :
30 : : #include <dpkg/dpkg.h>
31 : : #include <dpkg/i18n.h>
32 : : #include <dpkg/report.h>
33 : : #include <dpkg/debug.h>
34 : :
35 : : static int debug_mask = 0;
36 : : static FILE *debug_output = NULL;
37 : :
38 : : /**
39 : : * Set the debugging output file.
40 : : *
41 : : * Marks the file descriptor as close-on-exec.
42 : : */
43 : : void
44 : 0 : debug_set_output(FILE *output, const char *filename)
45 : : {
46 : 0 : setcloexec(fileno(output), filename);
47 : 0 : dpkg_set_report_buffer(output);
48 : 0 : debug_output = output;
49 : 0 : }
50 : :
51 : : /**
52 : : * Set the debugging mask.
53 : : *
54 : : * The mask determines what debugging flags are going to take effect at
55 : : * run-time. The output will be set to stderr if it has not been set before.
56 : : */
57 : : void
58 : 198 : debug_set_mask(int mask)
59 : : {
60 : 198 : debug_mask = mask;
61 [ + - ]: 198 : if (!debug_output)
62 : 198 : debug_output = stderr;
63 : 198 : }
64 : :
65 : : /**
66 : : * Parse the debugging mask.
67 : : *
68 : : * The mask is parsed from the specified string and sets the global debugging
69 : : * mask. If there is any error while parsing a negative number is returned.
70 : : */
71 : : int
72 : 198 : debug_parse_mask(const char *str)
73 : : {
74 : : char *endp;
75 : : long mask;
76 : :
77 : 198 : errno = 0;
78 : 198 : mask = strtol(str, &endp, 8);
79 [ + - + - : 198 : if (str == endp || *endp || mask < 0 || errno == ERANGE)
+ - - + ]
80 : 0 : return -1;
81 : :
82 : 198 : debug_set_mask(mask);
83 : :
84 : 198 : return mask;
85 : : }
86 : :
87 : : /**
88 : : * Check if a debugging flag is currently set on the debugging mask.
89 : : */
90 : : bool
91 : 435 : debug_has_flag(int flag)
92 : : {
93 : 435 : return debug_mask & flag;
94 : : }
95 : :
96 : : /**
97 : : * Output a debugging message.
98 : : *
99 : : * The message will be printed to the previously specified output if the
100 : : * specified flag is present in the current debugging mask.
101 : : */
102 : : void
103 : 435 : debug(int flag, const char *fmt, ...)
104 : : {
105 : : va_list args;
106 : :
107 [ + + ]: 435 : if (!debug_has_flag(flag))
108 : 237 : return;
109 : :
110 : 198 : fprintf(debug_output, "D0%05o: ", flag);
111 : 198 : va_start(args, fmt);
112 : 198 : vfprintf(debug_output, fmt, args);
113 : 198 : va_end(args);
114 : 198 : putc('\n', debug_output);
115 : : }
116 : :
117 : : /**
118 : : * Initialize the debugging support.
119 : : */
120 : : void
121 : 417 : dpkg_debug_init(void)
122 : : {
123 : 417 : const char envvar[] = "DPKG_DEBUG";
124 : : const char *env;
125 : :
126 : 417 : env = getenv(envvar);
127 [ + + ]: 417 : if (env == NULL)
128 : 219 : return;
129 : :
130 [ - + ]: 198 : if (debug_parse_mask(env) < 0)
131 : 0 : warning(_("cannot parse debug mask from environment variable %s"),
132 : : envvar);
133 : : }
|