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 : 411 : debug_has_flag(int flag) 92 : : { 93 : 411 : 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 : 411 : debug(int flag, const char *fmt, ...) 104 : : { 105 : : va_list args; 106 : : 107 [ + + ]: 411 : if (!debug_has_flag(flag)) 108 : 213 : 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 : 371 : dpkg_debug_init(void) 122 : : { 123 : 371 : const char envvar[] = "DPKG_DEBUG"; 124 : : const char *env; 125 : : 126 : 371 : env = getenv(envvar); 127 [ + + ]: 371 : if (env == NULL) 128 : 173 : return; 129 : : 130 [ - + ]: 198 : if (debug_parse_mask(env) < 0) 131 : 0 : warning(_("cannot parse debug mask from environment variable %s"), 132 : : envvar); 133 : : }