|
Packit |
d7e8d0 |
/* debug.c - helpful output in desperate situations
|
|
Packit |
d7e8d0 |
Copyright (C) 2000 Werner Koch (dd9jn)
|
|
Packit |
d7e8d0 |
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009 g10 Code GmbH
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
This file is part of GPGME.
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
GPGME is free software; you can redistribute it and/or modify it
|
|
Packit |
d7e8d0 |
under the terms of the GNU Lesser General Public License as
|
|
Packit |
d7e8d0 |
published by the Free Software Foundation; either version 2.1 of
|
|
Packit |
d7e8d0 |
the License, or (at your option) any later version.
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
GPGME is distributed in the hope that it will be useful, but
|
|
Packit |
d7e8d0 |
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
d7e8d0 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
d7e8d0 |
Lesser General Public License for more details.
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
d7e8d0 |
License along with this program; if not, write to the Free Software
|
|
Packit |
d7e8d0 |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
Packit |
d7e8d0 |
MA 02110-1301, USA. */
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
#if HAVE_CONFIG_H
|
|
Packit |
d7e8d0 |
#include <config.h>
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
#include <stdio.h>
|
|
Packit |
d7e8d0 |
#include <stdlib.h>
|
|
Packit |
d7e8d0 |
#include <string.h>
|
|
Packit |
d7e8d0 |
#include <stdarg.h>
|
|
Packit |
d7e8d0 |
#ifdef HAVE_UNISTD_H
|
|
Packit |
d7e8d0 |
# include <unistd.h>
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
#include <ctype.h>
|
|
Packit |
d7e8d0 |
#include <errno.h>
|
|
Packit |
d7e8d0 |
#include <time.h>
|
|
Packit |
d7e8d0 |
#ifndef HAVE_DOSISH_SYSTEM
|
|
Packit |
d7e8d0 |
# ifdef HAVE_SYS_TYPES_H
|
|
Packit |
d7e8d0 |
# include <sys/types.h>
|
|
Packit |
d7e8d0 |
# endif
|
|
Packit |
d7e8d0 |
# ifdef HAVE_SYS_STAT_H
|
|
Packit |
d7e8d0 |
# include <sys/stat.h>
|
|
Packit |
d7e8d0 |
# endif
|
|
Packit |
d7e8d0 |
# include <fcntl.h>
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
#include <assert.h>
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
#include "util.h"
|
|
Packit |
d7e8d0 |
#include "ath.h"
|
|
Packit |
d7e8d0 |
#include "sema.h"
|
|
Packit |
d7e8d0 |
#include "sys-util.h"
|
|
Packit |
d7e8d0 |
#include "debug.h"
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* Lock to serialize initialization of the debug output subsystem and
|
|
Packit |
d7e8d0 |
output of actual debug messages. */
|
|
Packit |
d7e8d0 |
DEFINE_STATIC_LOCK (debug_lock);
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* The amount of detail requested by the user, per environment
|
|
Packit |
d7e8d0 |
variable GPGME_DEBUG. */
|
|
Packit |
d7e8d0 |
static int debug_level;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* The output stream for the debug messages. */
|
|
Packit |
d7e8d0 |
static FILE *errfp;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* If not NULL, this malloced string is used instead of the
|
|
Packit |
d7e8d0 |
GPGME_DEBUG envvar. It must have been set before the debug
|
|
Packit |
d7e8d0 |
subsystem has been initialized. Using it later may or may not have
|
|
Packit |
d7e8d0 |
any effect. */
|
|
Packit |
d7e8d0 |
static char *envvar_override;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
#ifdef HAVE_TLS
|
|
Packit |
d7e8d0 |
#define FRAME_NR
|
|
Packit |
d7e8d0 |
static __thread int frame_nr = 0;
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
void
|
|
Packit |
d7e8d0 |
_gpgme_debug_frame_begin (void)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
#ifdef FRAME_NR
|
|
Packit |
d7e8d0 |
frame_nr++;
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
int _gpgme_debug_frame_end (void)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
#ifdef FRAME_NR
|
|
Packit |
d7e8d0 |
frame_nr--;
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
return 0;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* Remove leading and trailing white spaces. */
|
|
Packit |
d7e8d0 |
static char *
|
|
Packit |
d7e8d0 |
trim_spaces (char *str)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
char *string, *p, *mark;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
string = str;
|
|
Packit |
d7e8d0 |
/* Find first non space character. */
|
|
Packit |
d7e8d0 |
for (p = string; *p && isspace (*(unsigned char *) p); p++)
|
|
Packit |
d7e8d0 |
;
|
|
Packit |
d7e8d0 |
/* Move characters. */
|
|
Packit |
d7e8d0 |
for (mark = NULL; (*string = *p); string++, p++)
|
|
Packit |
d7e8d0 |
if (isspace (*(unsigned char *) p))
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
if (!mark)
|
|
Packit |
d7e8d0 |
mark = string;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
else
|
|
Packit |
d7e8d0 |
mark = NULL;
|
|
Packit |
d7e8d0 |
if (mark)
|
|
Packit |
d7e8d0 |
*mark = '\0'; /* Remove trailing spaces. */
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
return str;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* This is an internal function to set debug info. The caller must
|
|
Packit |
d7e8d0 |
assure that this function is called only by one thread at a time.
|
|
Packit |
d7e8d0 |
The function may have no effect if called after the debug system
|
|
Packit |
d7e8d0 |
has been initialized. Returns 0 on success. */
|
|
Packit |
d7e8d0 |
int
|
|
Packit |
d7e8d0 |
_gpgme_debug_set_debug_envvar (const char *value)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
free (envvar_override);
|
|
Packit |
d7e8d0 |
envvar_override = strdup (value);
|
|
Packit |
d7e8d0 |
return !envvar_override;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
static void
|
|
Packit |
d7e8d0 |
debug_init (void)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
static int initialized;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
LOCK (debug_lock);
|
|
Packit |
d7e8d0 |
if (!initialized)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
gpgme_error_t err;
|
|
Packit |
d7e8d0 |
char *e;
|
|
Packit |
d7e8d0 |
const char *s1, *s2;;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
if (envvar_override)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
e = strdup (envvar_override);
|
|
Packit |
d7e8d0 |
free (envvar_override);
|
|
Packit |
d7e8d0 |
envvar_override = NULL;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
else
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
#ifdef HAVE_W32CE_SYSTEM
|
|
Packit |
d7e8d0 |
e = _gpgme_w32ce_get_debug_envvar ();
|
|
Packit |
d7e8d0 |
#else /*!HAVE_W32CE_SYSTEM*/
|
|
Packit |
d7e8d0 |
err = _gpgme_getenv ("GPGME_DEBUG", &e);
|
|
Packit |
d7e8d0 |
if (err)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
UNLOCK (debug_lock);
|
|
Packit |
d7e8d0 |
return;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
#endif /*!HAVE_W32CE_SYSTEM*/
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
initialized = 1;
|
|
Packit |
d7e8d0 |
errfp = stderr;
|
|
Packit |
d7e8d0 |
if (e)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
debug_level = atoi (e);
|
|
Packit |
d7e8d0 |
s1 = strchr (e, PATHSEP_C);
|
|
Packit |
d7e8d0 |
if (s1)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
#ifndef HAVE_DOSISH_SYSTEM
|
|
Packit |
d7e8d0 |
if (getuid () == geteuid ()
|
|
Packit |
d7e8d0 |
#if defined(HAVE_GETGID) && defined(HAVE_GETEGID)
|
|
Packit |
d7e8d0 |
&& getgid () == getegid ()
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
char *p;
|
|
Packit |
d7e8d0 |
FILE *fp;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
s1++;
|
|
Packit |
d7e8d0 |
if (!(s2 = strchr (s1, PATHSEP_C)))
|
|
Packit |
d7e8d0 |
s2 = s1 + strlen (s1);
|
|
Packit |
d7e8d0 |
p = malloc (s2 - s1 + 1);
|
|
Packit |
d7e8d0 |
if (p)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
memcpy (p, s1, s2 - s1);
|
|
Packit |
d7e8d0 |
p[s2-s1] = 0;
|
|
Packit |
d7e8d0 |
trim_spaces (p);
|
|
Packit |
d7e8d0 |
fp = fopen (p,"a");
|
|
Packit |
d7e8d0 |
if (fp)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
setvbuf (fp, NULL, _IOLBF, 0);
|
|
Packit |
d7e8d0 |
errfp = fp;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
free (p);
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
#ifndef HAVE_DOSISH_SYSTEM
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
free (e);
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
UNLOCK (debug_lock);
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
if (debug_level > 0)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
_gpgme_debug (DEBUG_INIT, "gpgme_debug: level=%d\n", debug_level);
|
|
Packit |
d7e8d0 |
#ifdef HAVE_W32_SYSTEM
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
const char *name = _gpgme_get_inst_dir ();
|
|
Packit |
d7e8d0 |
_gpgme_debug (DEBUG_INIT, "gpgme_debug: gpgme='%s'\n",
|
|
Packit |
d7e8d0 |
name? name: "?");
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* This should be called as soon as the locks are initialized. It is
|
|
Packit |
d7e8d0 |
required so that the assuan logging gets conncted to the gpgme log
|
|
Packit |
d7e8d0 |
stream as early as possible. */
|
|
Packit |
d7e8d0 |
void
|
|
Packit |
d7e8d0 |
_gpgme_debug_subsystem_init (void)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
debug_init ();
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* Log the formatted string FORMAT at debug level LEVEL or higher.
|
|
Packit |
d7e8d0 |
*
|
|
Packit |
d7e8d0 |
* Returns: 0
|
|
Packit |
d7e8d0 |
*
|
|
Packit |
d7e8d0 |
* Note that we always return 0 because the old TRACE macro evaluated
|
|
Packit |
d7e8d0 |
* to 0 which issues a warning with newer gcc version about an unused
|
|
Packit |
d7e8d0 |
* values. By using a return value of this function this can be
|
|
Packit |
d7e8d0 |
* avoided. Fixme: It might be useful to check whether the return
|
|
Packit |
d7e8d0 |
* value from the TRACE macros are actually used somewhere.
|
|
Packit |
d7e8d0 |
*/
|
|
Packit |
d7e8d0 |
int
|
|
Packit |
d7e8d0 |
_gpgme_debug (int level, const char *format, ...)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
va_list arg_ptr;
|
|
Packit |
d7e8d0 |
int saved_errno;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
saved_errno = errno;
|
|
Packit |
d7e8d0 |
if (debug_level < level)
|
|
Packit |
d7e8d0 |
return 0;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
va_start (arg_ptr, format);
|
|
Packit |
d7e8d0 |
LOCK (debug_lock);
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
#ifdef HAVE_W32CE_SYSTEM
|
|
Packit |
d7e8d0 |
SYSTEMTIME t;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
GetLocalTime (&t);
|
|
Packit |
d7e8d0 |
fprintf (errfp, "GPGME %04d-%02d-%02d %02d:%02d:%02d <0x%04llx> ",
|
|
Packit |
d7e8d0 |
t.wYear, t.wMonth, t.wDay,
|
|
Packit |
d7e8d0 |
t.wHour, t.wMinute, t.wSecond,
|
|
Packit |
d7e8d0 |
(unsigned long long) ath_self ());
|
|
Packit |
d7e8d0 |
#else
|
|
Packit |
d7e8d0 |
struct tm *tp;
|
|
Packit |
d7e8d0 |
time_t atime = time (NULL);
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
tp = localtime (&atime);
|
|
Packit |
d7e8d0 |
fprintf (errfp, "GPGME %04d-%02d-%02d %02d:%02d:%02d <0x%04llx> ",
|
|
Packit |
d7e8d0 |
1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
|
|
Packit |
d7e8d0 |
tp->tm_hour, tp->tm_min, tp->tm_sec,
|
|
Packit |
d7e8d0 |
(unsigned long long) ath_self ());
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
#ifdef FRAME_NR
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
int indent;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
indent = frame_nr > 0? (2 * (frame_nr - 1)):0;
|
|
Packit |
d7e8d0 |
fprintf (errfp, "%*s", indent < 40? indent : 40, "");
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
#endif
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
vfprintf (errfp, format, arg_ptr);
|
|
Packit |
d7e8d0 |
va_end (arg_ptr);
|
|
Packit |
d7e8d0 |
if(format && *format && format[strlen (format) - 1] != '\n')
|
|
Packit |
d7e8d0 |
putc ('\n', errfp);
|
|
Packit |
d7e8d0 |
UNLOCK (debug_lock);
|
|
Packit |
d7e8d0 |
fflush (errfp);
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
gpg_err_set_errno (saved_errno);
|
|
Packit |
d7e8d0 |
return 0;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* Start a new debug line in *LINE, logged at level LEVEL or higher,
|
|
Packit |
d7e8d0 |
and starting with the formatted string FORMAT. */
|
|
Packit |
d7e8d0 |
void
|
|
Packit |
d7e8d0 |
_gpgme_debug_begin (void **line, int level, const char *format, ...)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
va_list arg_ptr;
|
|
Packit |
d7e8d0 |
int res;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
if (debug_level < level)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
/* Disable logging of this line. */
|
|
Packit |
d7e8d0 |
*line = NULL;
|
|
Packit |
d7e8d0 |
return;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
va_start (arg_ptr, format);
|
|
Packit |
d7e8d0 |
res = gpgrt_vasprintf ((char **) line, format, arg_ptr);
|
|
Packit |
d7e8d0 |
va_end (arg_ptr);
|
|
Packit |
d7e8d0 |
if (res < 0)
|
|
Packit |
d7e8d0 |
*line = NULL;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* Add the formatted string FORMAT to the debug line *LINE. */
|
|
Packit |
d7e8d0 |
void
|
|
Packit |
d7e8d0 |
_gpgme_debug_add (void **line, const char *format, ...)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
va_list arg_ptr;
|
|
Packit |
d7e8d0 |
char *toadd;
|
|
Packit |
d7e8d0 |
char *result;
|
|
Packit |
d7e8d0 |
int res;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
if (!*line)
|
|
Packit |
d7e8d0 |
return;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
va_start (arg_ptr, format);
|
|
Packit |
d7e8d0 |
res = gpgrt_vasprintf (&toadd, format, arg_ptr);
|
|
Packit |
d7e8d0 |
va_end (arg_ptr);
|
|
Packit |
d7e8d0 |
if (res < 0)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
gpgrt_free (*line);
|
|
Packit |
d7e8d0 |
*line = NULL;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
res = gpgrt_asprintf (&result, "%s%s", *(char **) line, toadd);
|
|
Packit |
d7e8d0 |
gpgrt_free (toadd);
|
|
Packit |
d7e8d0 |
gpgrt_free (*line);
|
|
Packit |
d7e8d0 |
if (res < 0)
|
|
Packit |
d7e8d0 |
*line = NULL;
|
|
Packit |
d7e8d0 |
else
|
|
Packit |
d7e8d0 |
*line = result;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* Finish construction of *LINE and send it to the debug output
|
|
Packit |
d7e8d0 |
stream. */
|
|
Packit |
d7e8d0 |
void
|
|
Packit |
d7e8d0 |
_gpgme_debug_end (void **line)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
if (!*line)
|
|
Packit |
d7e8d0 |
return;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
/* The smallest possible level is 1, so force logging here by
|
|
Packit |
d7e8d0 |
using that. */
|
|
Packit |
d7e8d0 |
_gpgme_debug (1, "%s", *line);
|
|
Packit |
d7e8d0 |
gpgrt_free (*line);
|
|
Packit |
d7e8d0 |
*line = NULL;
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
#define TOHEX(val) (((val) < 10) ? ((val) + '0') : ((val) - 10 + 'a'))
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
void
|
|
Packit |
d7e8d0 |
_gpgme_debug_buffer (int lvl, const char *const fmt,
|
|
Packit |
d7e8d0 |
const char *const func, const char *const buffer,
|
|
Packit |
d7e8d0 |
size_t len)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
int idx = 0;
|
|
Packit |
d7e8d0 |
int j;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
if (!_gpgme_debug_trace ())
|
|
Packit |
d7e8d0 |
return;
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
while (idx < len)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
char str[51];
|
|
Packit |
d7e8d0 |
char *strp = str;
|
|
Packit |
d7e8d0 |
char *strp2 = &str[34];
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
for (j = 0; j < 16; j++)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
unsigned char val;
|
|
Packit |
d7e8d0 |
if (idx < len)
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
val = buffer[idx++];
|
|
Packit |
d7e8d0 |
*(strp++) = TOHEX (val >> 4);
|
|
Packit |
d7e8d0 |
*(strp++) = TOHEX (val % 16);
|
|
Packit |
d7e8d0 |
*(strp2++) = isprint (val) ? val : '.';
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
else
|
|
Packit |
d7e8d0 |
{
|
|
Packit |
d7e8d0 |
*(strp++) = ' ';
|
|
Packit |
d7e8d0 |
*(strp++) = ' ';
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
if (j == 7)
|
|
Packit |
d7e8d0 |
*(strp++) = ' ';
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
*(strp++) = ' ';
|
|
Packit |
d7e8d0 |
*(strp2) = '\0';
|
|
Packit |
d7e8d0 |
|
|
Packit |
d7e8d0 |
_gpgme_debug (lvl, fmt, func, str);
|
|
Packit |
d7e8d0 |
}
|
|
Packit |
d7e8d0 |
}
|