Branch data Line data Source code
1 : : /*
2 : : Authors:
3 : : Simo Sorce <ssorce@redhat.com>
4 : : Stephen Gallagher <sgallagh@redhat.com>
5 : :
6 : : Copyright (C) 2009 Red Hat
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 "config.h"
23 : :
24 : : #include <stdio.h>
25 : : #include <stdarg.h>
26 : : #include <stdlib.h>
27 : :
28 : : #include <sys/types.h>
29 : : #include <sys/stat.h>
30 : : #include <sys/time.h>
31 : :
32 : : #include "util/util.h"
33 : :
34 : : const char *debug_prg_name = "sssd";
35 : :
36 : : int debug_level = SSSDBG_UNRESOLVED;
37 : : int debug_timestamps = SSSDBG_TIMESTAMP_UNRESOLVED;
38 : : int debug_microseconds = SSSDBG_MICROSECONDS_UNRESOLVED;
39 : : int debug_to_file = 0;
40 : : const char *debug_log_file = "sssd";
41 : : FILE *debug_file = NULL;
42 : :
43 : 120 : errno_t set_debug_file_from_fd(const int fd)
44 : : {
45 : : FILE *dummy;
46 : : errno_t ret;
47 : :
48 : 120 : errno = 0;
49 : 120 : dummy = fdopen(fd, "a");
50 [ - + ]: 120 : if (dummy == NULL) {
51 : 0 : ret = errno;
52 [ # # ][ # # ]: 0 : DEBUG(1, ("fdopen failed [%d][%s].\n", ret, strerror(ret)));
[ # # ][ # # ]
[ # # ]
53 : 0 : sss_log(SSS_LOG_ERR,
54 : : "Could not open debug file descriptor [%d]. "
55 : : "Debug messages will not be written to the file "
56 : : "for this child process [%s][%s]\n",
57 : : fd, debug_prg_name, strerror(ret));
58 : 0 : return ret;
59 : : }
60 : :
61 : 120 : debug_file = dummy;
62 : :
63 : 120 : return EOK;
64 : : }
65 : :
66 : 36 : int debug_convert_old_level(int old_level)
67 : : {
68 [ + + ][ + + ]: 36 : if ((old_level != 0) && !(old_level & 0x000F))
69 : : return old_level;
70 : :
71 : 25 : int new_level = SSSDBG_FATAL_FAILURE;
72 : :
73 [ + + ]: 25 : if (old_level <= 0)
74 : : return new_level;
75 : :
76 [ + - ]: 9 : if (old_level >= 1)
77 : 9 : new_level |= SSSDBG_CRIT_FAILURE;
78 : :
79 [ + + ]: 9 : if (old_level >= 2)
80 : 8 : new_level |= SSSDBG_OP_FAILURE;
81 : :
82 [ + + ]: 9 : if (old_level >= 3)
83 : 7 : new_level |= SSSDBG_MINOR_FAILURE;
84 : :
85 [ + + ]: 9 : if (old_level >= 4)
86 : 6 : new_level |= SSSDBG_CONF_SETTINGS;
87 : :
88 [ + + ]: 9 : if (old_level >= 5)
89 : 5 : new_level |= SSSDBG_FUNC_DATA;
90 : :
91 [ + + ]: 9 : if (old_level >= 6)
92 : 4 : new_level |= SSSDBG_TRACE_FUNC;
93 : :
94 [ + + ]: 9 : if (old_level >= 7)
95 : 3 : new_level |= SSSDBG_TRACE_LIBS;
96 : :
97 [ + + ]: 9 : if (old_level >= 8)
98 : 2 : new_level |= SSSDBG_TRACE_INTERNAL;
99 : :
100 [ + + ]: 9 : if (old_level >= 9)
101 : 1 : new_level |= SSSDBG_TRACE_ALL;
102 : :
103 : 36 : return new_level;
104 : : }
105 : :
106 : 130 : void debug_fn(const char *format, ...)
107 : : {
108 : : va_list ap;
109 : :
110 : 130 : va_start(ap, format);
111 : :
112 [ + + ]: 130 : vfprintf(debug_file ? debug_file : stderr, format, ap);
113 [ + + ]: 130 : fflush(debug_file ? debug_file : stderr);
114 : :
115 : 130 : va_end(ap);
116 : 130 : }
117 : :
118 : 31612 : int debug_get_level(int old_level)
119 : : {
120 [ + + ][ + + ]: 31612 : if ((old_level != 0) && !(old_level & 0x000F))
121 : : return old_level;
122 : :
123 [ + - ]: 2153 : if ((old_level > 9) || (old_level < 0))
124 : : return SSSDBG_FATAL_FAILURE;
125 : :
126 : 2153 : int levels[] = {
127 : : SSSDBG_FATAL_FAILURE, /* 0 */
128 : : SSSDBG_CRIT_FAILURE,
129 : : SSSDBG_OP_FAILURE,
130 : : SSSDBG_MINOR_FAILURE,
131 : : SSSDBG_CONF_SETTINGS,
132 : : SSSDBG_FUNC_DATA,
133 : : SSSDBG_TRACE_FUNC,
134 : : SSSDBG_TRACE_LIBS,
135 : : SSSDBG_TRACE_INTERNAL,
136 : : SSSDBG_TRACE_ALL /* 9 */
137 : : };
138 : :
139 : 31612 : return levels[old_level];
140 : : }
141 : :
142 : 28814 : void ldb_debug_messages(void *context, enum ldb_debug_level level,
143 : : const char *fmt, va_list ap)
144 : : {
145 : 28814 : int loglevel = SSSDBG_UNRESOLVED;
146 : : int ret;
147 [ - + ]: 28814 : char * message = NULL;
148 : :
149 : : switch(level) {
150 : : case LDB_DEBUG_FATAL:
151 : : loglevel = SSSDBG_FATAL_FAILURE;
152 : : break;
153 : : case LDB_DEBUG_ERROR:
154 : : loglevel = SSSDBG_CRIT_FAILURE;
155 : : break;
156 : : case LDB_DEBUG_WARNING:
157 : : loglevel = SSSDBG_TRACE_FUNC;
158 : : break;
159 : : case LDB_DEBUG_TRACE:
160 : : loglevel = SSSDBG_TRACE_ALL;
161 : : break;
162 : : }
163 : :
164 : 28814 : ret = vasprintf(&message, fmt, ap);
165 [ + - ]: 28814 : if (ret < 0) {
166 : : /* ENOMEM */
167 : 28814 : return;
168 : : }
169 : :
170 [ + - ][ + - ]: 28814 : DEBUG_MSG(loglevel, "ldb", message);
[ - + ][ # # ]
[ # # ]
171 : :
172 : 28814 : free(message);
173 : : }
174 : :
175 : 0 : int open_debug_file_ex(const char *filename, FILE **filep)
176 : : {
177 : 0 : FILE *f = NULL;
178 : : char *logpath;
179 : : const char *log_file;
180 : : mode_t old_umask;
181 : : int ret;
182 : :
183 [ # # ]: 0 : if (filename == NULL) {
184 : 0 : log_file = debug_log_file;
185 : : } else {
186 : : log_file = filename;
187 : : }
188 : :
189 : 0 : ret = asprintf(&logpath, "%s/%s.log", LOG_PATH, log_file);
190 [ # # ]: 0 : if (ret == -1) {
191 : : return ENOMEM;
192 : : }
193 : :
194 [ # # ][ # # ]: 0 : if (debug_file && !filep) fclose(debug_file);
195 : :
196 : 0 : old_umask = umask(0177);
197 : 0 : errno = 0;
198 : 0 : f = fopen(logpath, "a");
199 [ # # ]: 0 : if (f == NULL) {
200 : 0 : sss_log(SSS_LOG_EMERG, "Could not open file [%s]. Error: [%d][%s]\n",
201 : : logpath, errno, strerror(errno));
202 : 0 : free(logpath);
203 : : return EIO;
204 : : }
205 : 0 : umask(old_umask);
206 : :
207 [ # # ]: 0 : if (filep == NULL) {
208 : 0 : debug_file = f;
209 : : } else {
210 : 0 : *filep = f;
211 : : }
212 : 0 : free(logpath);
213 : : return EOK;
214 : : }
215 : :
216 : 0 : int open_debug_file(void)
217 : : {
218 : 0 : return open_debug_file_ex(NULL, NULL);
219 : : }
220 : :
221 : 0 : int rotate_debug_files(void)
222 : : {
223 : : int ret;
224 : : errno_t error;
225 : :
226 [ # # ]: 0 : if (!debug_to_file) return EOK;
227 : :
228 : : do {
229 : 0 : error = 0;
230 : 0 : ret = fclose(debug_file);
231 [ # # ]: 0 : if (ret != 0) {
232 : 0 : error = errno;
233 : : }
234 : :
235 : : /* Check for EINTR, which means we should retry
236 : : * because the system call was interrupted by a
237 : : * signal
238 : : */
239 [ # # ]: 0 : } while (error == EINTR);
240 : :
241 [ # # ]: 0 : if (error != 0) {
242 : : /* Even if we were unable to close the debug log, we need to make
243 : : * sure that we open up a new one. Log rotation will remove the
244 : : * current file, so all debug messages will be disappearing.
245 : : *
246 : : * We should write an error to the syslog warning of the resource
247 : : * leak and then proceed with opening the new file.
248 : : */
249 : 0 : sss_log(SSS_LOG_ALERT, "Could not close debug file [%s]. [%d][%s]\n",
250 : : debug_log_file, error, strerror(error));
251 : 0 : sss_log(SSS_LOG_ALERT, "Attempting to open new file anyway. "
252 : : "Be aware that this is a resource leak\n");
253 : : }
254 : :
255 : 0 : debug_file = NULL;
256 : :
257 : 0 : return open_debug_file();
258 : : }
259 : :
260 : 0 : void talloc_log_fn(const char *message)
261 : : {
262 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_FATAL_FAILURE, (message));
[ # # ][ # # ]
[ # # ]
263 : 0 : }
|