diff options
| author | Marcus Brinkmann <[email protected]> | 2008-11-03 17:24:09 +0000 | 
|---|---|---|
| committer | Marcus Brinkmann <[email protected]> | 2008-11-03 17:24:09 +0000 | 
| commit | 66d0fa1973e5e1a1bff619de8b595673d1b76cc5 (patch) | |
| tree | 4b1f8e470fa455cbe3d9b5c4ab6fb4fa77f20ba3 /src/debug.c | |
| parent | assuan/ (diff) | |
| download | gpgme-66d0fa1973e5e1a1bff619de8b595673d1b76cc5.tar.gz gpgme-66d0fa1973e5e1a1bff619de8b595673d1b76cc5.zip | |
008-11-03  Marcus Brinkmann  <[email protected]>
        * configure.ac: Replace gpgme paths with src.
        * gpgme: Move to ...
        * src: ... this new directory.
assuan/
2008-11-03  Marcus Brinkmann  <[email protected]>
	* Makefile.am (INCLUDES): Replace gpgme path with src.
tests/
2008-11-03  Marcus Brinkmann  <[email protected]>
        * gpgsm/Makefile.am (INCLUDES, LDADD): Replace gpgme path with src.
        * gpg/Makefile.am (INCLUDES, LDADD, t_thread1_LDADD): Likewise.
	* Makefile.am (LDADD): Likewise.
Diffstat (limited to 'src/debug.c')
| -rw-r--r-- | src/debug.c | 295 | 
1 files changed, 295 insertions, 0 deletions
| diff --git a/src/debug.c b/src/debug.c new file mode 100644 index 00000000..bf1ca18c --- /dev/null +++ b/src/debug.c @@ -0,0 +1,295 @@ +/* debug.c - helpful output in desperate situations +   Copyright (C) 2000 Werner Koch (dd9jn) +   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 g10 Code GmbH +  +   This file is part of GPGME. + +   GPGME is free software; you can redistribute it and/or modify it +   under the terms of the GNU Lesser General Public License as +   published by the Free Software Foundation; either version 2.1 of +   the License, or (at your option) any later version. +    +   GPGME is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   Lesser General Public License for more details. +    +   You should have received a copy of the GNU Lesser General Public +   License along with this program; if not, write to the Free Software +   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,  +   MA 02110-1301, USA.  */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <unistd.h> +#include <ctype.h> +#include <errno.h> +#ifndef HAVE_DOSISH_SYSTEM +#  include <sys/types.h> +#  include <sys/stat.h> +#  include <fcntl.h> +#endif +#include <assert.h> + +#ifdef HAVE_ASSUAN_H +#include "assuan.h" +#endif + +#include "util.h" +#include "sema.h" +#include "debug.h" + + +/* Lock to serialize initialization of the debug output subsystem and +   output of actual debug messages.  */ +DEFINE_STATIC_LOCK (debug_lock); + +/* The amount of detail requested by the user, per environment +   variable GPGME_DEBUG.  */ +static int debug_level; + +/* The output stream for the debug messages.  */ +static FILE *errfp; + + +/* Remove leading and trailing white spaces.  */ +static char * +trim_spaces (char *str) +{ +  char *string, *p, *mark; + +  string = str; +  /* Find first non space character.  */ +  for (p = string; *p && isspace (*(unsigned char *) p); p++) +    ; +  /* Move characters.  */ +  for (mark = NULL; (*string = *p); string++, p++) +    if (isspace (*(unsigned char *) p)) +      { +	if (!mark) +	  mark = string; +      } +    else +      mark = NULL; +  if (mark) +    *mark = '\0';	/* Remove trailing spaces.  */ + +  return str; +} + + +static void +debug_init (void) +{ +  static int initialized; + +  LOCK (debug_lock); +  if (!initialized) +    { +      gpgme_error_t err; +      char *e; +      const char *s1, *s2;; + +      err = _gpgme_getenv ("GPGME_DEBUG", &e); +      if (err) +	{ +	  UNLOCK (debug_lock); +	  return; +	} + +      initialized = 1; +      errfp = stderr; +      if (e) +	{ +	  debug_level = atoi (e); +	  s1 = strchr (e, PATHSEP_C); +	  if (s1) +	    { +#ifndef HAVE_DOSISH_SYSTEM +	      if (getuid () == geteuid ()) +		{ +#endif +		  char *p; +		  FILE *fp; + +		  s1++; +		  if (!(s2 = strchr (s1, PATHSEP_C))) +		    s2 = s1 + strlen (s1); +		  p = malloc (s2 - s1 + 1); +		  if (p) +		    { +		      memcpy (p, s1, s2 - s1); +		      p[s2-s1] = 0; +		      trim_spaces (p); +		      fp = fopen (p,"a"); +		      if (fp) +			{ +			  setvbuf (fp, NULL, _IOLBF, 0); +			  errfp = fp; +			} +		      free (p); +		    } +#ifndef HAVE_DOSISH_SYSTEM +		} +#endif +	    } +	  free (e); +        } + +      if (debug_level > 0) +        fprintf (errfp, "gpgme_debug: level=%d\n", debug_level); +#ifdef HAVE_ASSUAN_H +      assuan_set_assuan_log_prefix ("gpgme-assuan"); +      assuan_set_assuan_log_stream (errfp); +      assuan_set_assuan_log_level (debug_level >= 0? debug_level:0); +#endif /* HAVE_ASSUAN_H*/ +    } +  UNLOCK (debug_lock); +} + + + +/* This should be called as soon as the locks are intialized.  It is +   required so that the assuan logging gets conncted to the gpgme log +   stream as early as possible.  */ +void +_gpgme_debug_subsystem_init (void) +{ +  debug_init (); +} + + + + +/* Log the formatted string FORMAT at debug level LEVEL or higher.  */ +void +_gpgme_debug (int level, const char *format, ...) +{ +  va_list arg_ptr; +  int saved_errno; + +  saved_errno = errno; + +  debug_init (); +  if (debug_level < level) +    return; +     +  va_start (arg_ptr, format); +  LOCK (debug_lock); +  vfprintf (errfp, format, arg_ptr); +  va_end (arg_ptr); +  if(format && *format && format[strlen (format) - 1] != '\n') +    putc ('\n', errfp); +  UNLOCK (debug_lock); +  fflush (errfp); + +  errno = saved_errno; +} + + +/* Start a new debug line in *LINE, logged at level LEVEL or higher, +   and starting with the formatted string FORMAT.  */ +void +_gpgme_debug_begin (void **line, int level, const char *format, ...) +{ +  va_list arg_ptr; + +  debug_init (); +  if (debug_level < level) +    { +      /* Disable logging of this line.  */ +      *line = NULL; +      return; +    } + +  va_start (arg_ptr, format); +  vasprintf ((char **) line, format, arg_ptr); +  va_end (arg_ptr); +} + + +/* Add the formatted string FORMAT to the debug line *LINE.  */ +void +_gpgme_debug_add (void **line, const char *format, ...) +{ +  va_list arg_ptr; +  char *toadd; +  char *result; + +  if (!*line) +    return; + +  va_start (arg_ptr, format); +  vasprintf (&toadd, format, arg_ptr); +  va_end (arg_ptr); +  asprintf (&result, "%s%s", *(char **) line, toadd); +  free (*line); +  free (toadd); +  *line = result; +} + + +/* Finish construction of *LINE and send it to the debug output +   stream.  */ +void +_gpgme_debug_end (void **line) +{ +  if (!*line) +    return; + +  /* The smallest possible level is 1, so force logging here by +     using that.  */ +  _gpgme_debug (1, "%s", *line); +  free (*line); +  *line = NULL; +} + + +#define TOHEX(val) (((val) < 10) ? ((val) + '0') : ((val) - 10 + 'a')) + +void +_gpgme_debug_buffer (int lvl, const char *const fmt, +		     const char *const func, const char *const tagname, +		     void *tag, const char *const buffer, size_t len) +{ +  int idx = 0; +  int j; + +  if (!_gpgme_debug_trace ()) +    return; + +  while (idx < len) +    { +      char str[51]; +      char *strp = str; +      char *strp2 = &str[34]; +       +      for (j = 0; j < 16; j++) +	{ +	  unsigned char val; +	  if (idx < len) +	    { +	      val = buffer[idx++]; +	      *(strp++) = TOHEX (val >> 4); +	      *(strp++) = TOHEX (val % 16); +	      *(strp2++) = isprint (val) ? val : '.'; +	    } +	  else +	    { +	      *(strp++) = ' '; +	      *(strp++) = ' '; +	    } +	  if (j == 7) +	    *(strp++) = ' '; +	} +      *(strp++) = ' '; +      *(strp2) = '\0'; + +      _gpgme_debug (lvl, fmt, func, tagname, tag, str); +    } +} | 
