1 /* debug.c - helpful output in desperate situations
2 Copyright (C) 2000 Werner Koch (dd9jn)
3 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009 g10 Code GmbH
5 This file is part of GPGME.
7 GPGME is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of
10 the License, or (at your option) any later version.
12 GPGME is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 MA 02110-1301, USA. */
33 #ifndef HAVE_DOSISH_SYSTEM
34 # include <sys/types.h>
35 # include <sys/stat.h>
46 /* Lock to serialize initialization of the debug output subsystem and
47 output of actual debug messages. */
48 DEFINE_STATIC_LOCK (debug_lock);
50 /* The amount of detail requested by the user, per environment
51 variable GPGME_DEBUG. */
52 static int debug_level;
54 /* The output stream for the debug messages. */
60 static __thread int frame_nr = 0;
64 _gpgme_debug_frame_begin (void)
71 void _gpgme_debug_frame_end (void)
80 /* Remove leading and trailing white spaces. */
82 trim_spaces (char *str)
84 char *string, *p, *mark;
87 /* Find first non space character. */
88 for (p = string; *p && isspace (*(unsigned char *) p); p++)
90 /* Move characters. */
91 for (mark = NULL; (*string = *p); string++, p++)
92 if (isspace (*(unsigned char *) p))
100 *mark = '\0'; /* Remove trailing spaces. */
109 static int initialized;
116 const char *s1, *s2;;
118 err = _gpgme_getenv ("GPGME_DEBUG", &e);
129 debug_level = atoi (e);
130 s1 = strchr (e, PATHSEP_C);
133 #ifndef HAVE_DOSISH_SYSTEM
134 if (getuid () == geteuid ())
141 if (!(s2 = strchr (s1, PATHSEP_C)))
142 s2 = s1 + strlen (s1);
143 p = malloc (s2 - s1 + 1);
146 memcpy (p, s1, s2 - s1);
152 setvbuf (fp, NULL, _IOLBF, 0);
157 #ifndef HAVE_DOSISH_SYSTEM
167 _gpgme_debug (DEBUG_INIT, "gpgme_debug: level=%d\n", debug_level);
172 /* This should be called as soon as the locks are intialized. It is
173 required so that the assuan logging gets conncted to the gpgme log
174 stream as early as possible. */
176 _gpgme_debug_subsystem_init (void)
184 /* Log the formatted string FORMAT at debug level LEVEL or higher. */
186 _gpgme_debug (int level, const char *format, ...)
192 if (debug_level < level)
195 va_start (arg_ptr, format);
199 time_t atime = time (NULL);
201 tp = localtime (&atime);
202 fprintf (errfp, "GPGME %04d-%02d-%02d %02d:%02d:%02d <0x%04llx> ",
203 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
204 tp->tm_hour, tp->tm_min, tp->tm_sec,
205 (unsigned long long) ath_self ());
210 int nr_spaces = sizeof (spaces) - 1;
213 nr_columns = 2 * (frame_nr - 1);
214 if (nr_columns > nr_spaces)
215 nr_columns = nr_spaces;
218 spaces[nr_columns] = '\0';
219 fprintf (errfp, "%s", spaces);
223 vfprintf (errfp, format, arg_ptr);
225 if(format && *format && format[strlen (format) - 1] != '\n')
234 /* Start a new debug line in *LINE, logged at level LEVEL or higher,
235 and starting with the formatted string FORMAT. */
237 _gpgme_debug_begin (void **line, int level, const char *format, ...)
242 if (debug_level < level)
244 /* Disable logging of this line. */
249 va_start (arg_ptr, format);
250 res = vasprintf ((char **) line, format, arg_ptr);
257 /* Add the formatted string FORMAT to the debug line *LINE. */
259 _gpgme_debug_add (void **line, const char *format, ...)
269 va_start (arg_ptr, format);
270 res = vasprintf (&toadd, format, arg_ptr);
277 res = asprintf (&result, "%s%s", *(char **) line, toadd);
287 /* Finish construction of *LINE and send it to the debug output
290 _gpgme_debug_end (void **line)
295 /* The smallest possible level is 1, so force logging here by
297 _gpgme_debug (1, "%s", *line);
303 #define TOHEX(val) (((val) < 10) ? ((val) + '0') : ((val) - 10 + 'a'))
306 _gpgme_debug_buffer (int lvl, const char *const fmt,
307 const char *const func, const char *const buffer,
313 if (!_gpgme_debug_trace ())
320 char *strp2 = &str[34];
322 for (j = 0; j < 16; j++)
328 *(strp++) = TOHEX (val >> 4);
329 *(strp++) = TOHEX (val % 16);
330 *(strp2++) = isprint (val) ? val : '.';
343 _gpgme_debug (lvl, fmt, func, str);