From c62b79a1d6e576d94e08cb81c2f5dbcb42ecf8cf Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 25 Sep 2012 15:38:26 +0200 Subject: [PATCH] Add gpgme_set_global_flag to help debugging * src/gpgme.c (gpgme_set_global_flag): New. * src/gpgme.h.in (gpgme_set_global_flag): New. * src/gpgme.def, src/libgpgme.vers: Add new public function. * src/debug.c (envvar_override): New.: (_gpgme_debug_set_debug_envvar): New. (debug_init): Take ENVVAR_OVERRIDE in account. -- On Android envvars can't be used, thus we need another way to enable GPGME debugging. The new function allows this and may be used in the future to implement similar things. --- NEWS | 4 ++++ doc/gpgme.texi | 26 +++++++++++++++++++++++++- src/debug.c | 42 +++++++++++++++++++++++++++++++++++------- src/debug.h | 3 +++ src/gpgme.c | 21 ++++++++++++++++++++- src/gpgme.def | 2 ++ src/gpgme.h.in | 3 +++ src/libgpgme.vers | 4 +++- 8 files changed, 95 insertions(+), 10 deletions(-) diff --git a/NEWS b/NEWS index aa209dd4..b4b30869 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,10 @@ Noteworthy changes in version 1.3.3 (unreleased) ------------------------------------------------ + * Interface changes relative to the 1.3.1 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + gpgme_set_global_flag NEW. + Noteworthy changes in version 1.3.2 (2012-05-02) ------------------------------------------------ diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 61cdb379..d074b429 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -14,7 +14,7 @@ @copying Copyright @copyright{} 2002, 2003, 2004, 2005, 2006, 2007, -2008, 2010 g10 Code GmbH. +2008, 2010, 2012 g10 Code GmbH. @quotation Permission is granted to copy, distribute and/or modify this document @@ -616,6 +616,30 @@ does not return a detailed error code). @end deftypefun +@deftypefun {int} gpgme_set_global_flag @ + (@w{const char *@var{name}}, @ + @w{const char *@var{value}}) + +On some systems it is not easy to set environment variables and thus +hard to use @acronym{GPGME}'s internal trace facility for debugging. +This function has been introduced as an alternative way to enable +debugging. It is important to assure that only one thread accesses +@acronym{GPGME} functions between a call to this function and after +the return from the call to @code{gpgme_check_version}. + +To enable debugging, you need to call this function as early as +possible --- even before @code{gpgme_check_version} --- with the +string ``debug'' for @var{name} and @var{value} identical to the value +used with the environment variable @code{GPGME_DEBUG}. + +This function returns @code{0} on success. In contrast to other +functions the non-zero return value on failure does not convey any +error code. For setting ``debug'' the only possible error cause is an +out of memory condition; which would exhibit itself later anyway. +Thus the return value may be ignored. +@end deftypefun + + After initializing @acronym{GPGME}, you should set the locale information to the locale required for your output terminal. This locale information is needed for example for the curses and Gtk diff --git a/src/debug.c b/src/debug.c index 8e293b4e..56effa75 100644 --- a/src/debug.c +++ b/src/debug.c @@ -60,6 +60,12 @@ static int debug_level; /* The output stream for the debug messages. */ static FILE *errfp; +/* If not NULL, this malloced string is used instead of the + GPGME_DEBUG envvar. It must have been set before the debug + subsystem has been initialized. Using it later may or may not have + any effect. */ +static char *envvar_override; + #ifdef HAVE_TLS #define FRAME_NR @@ -109,6 +115,19 @@ trim_spaces (char *str) } +/* This is an internal function to set debug info. The caller must + assure that this function is called only by one thread at a time. + The function may have no effect if called after the debug system + has been initialized. Returns 0 on success. */ +int +_gpgme_debug_set_debug_envvar (const char *value) +{ + free (envvar_override); + envvar_override = strdup (value); + return !envvar_override; +} + + static void debug_init (void) { @@ -121,16 +140,25 @@ debug_init (void) char *e; const char *s1, *s2;; + if (envvar_override) + { + e = strdup (envvar_override); + free (envvar_override); + envvar_override = NULL; + } + else + { #ifdef HAVE_W32CE_SYSTEM - e = _gpgme_w32ce_get_debug_envvar (); + e = _gpgme_w32ce_get_debug_envvar (); #else /*!HAVE_W32CE_SYSTEM*/ - err = _gpgme_getenv ("GPGME_DEBUG", &e); - if (err) - { - UNLOCK (debug_lock); - return; - } + err = _gpgme_getenv ("GPGME_DEBUG", &e); + if (err) + { + UNLOCK (debug_lock); + return; + } #endif /*!HAVE_W32CE_SYSTEM*/ + } initialized = 1; errfp = stderr; diff --git a/src/debug.h b/src/debug.h index 7bd9ed78..ead92b24 100644 --- a/src/debug.h +++ b/src/debug.h @@ -54,6 +54,9 @@ _gpgme_debug_srcname (const char *file) return s? s+1:file; } +/* Initialization helper function; see debug.c. */ +int _gpgme_debug_set_debug_envvar (const char *value); + /* Called early to initialize the logging. */ void _gpgme_debug_subsystem_init (void); diff --git a/src/gpgme.c b/src/gpgme.c index 771fcc00..2c6ac875 100644 --- a/src/gpgme.c +++ b/src/gpgme.c @@ -1,6 +1,6 @@ /* gpgme.c - GnuPG Made Easy. Copyright (C) 2000 Werner Koch (dd9jn) - Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 g10 Code GmbH + Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2012 g10 Code GmbH This file is part of GPGME. @@ -51,6 +51,25 @@ gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL; accesses to a result structure are read only. */ DEFINE_STATIC_LOCK (result_ref_lock); + +/* Set the global flag NAME to VALUE. Return 0 on success. Note that + this function does use gpgme_error and thus a non-zero return value + merely means "error". Certain flags may be set before + gpgme_check_version is called. See the manual for a description of + supported flags. The caller must assure that this function is + called only by one thread at a time. */ +int +gpgme_set_global_flag (const char *name, const char *value) +{ + if (!name || !value) + return -1; + else if (!strcmp (name, "debug")) + return _gpgme_debug_set_debug_envvar (value); + else + return -1; +} + + /* Create a new context as an environment for GPGME crypto operations. */ diff --git a/src/gpgme.def b/src/gpgme.def index 9990b334..56a64280 100644 --- a/src/gpgme.def +++ b/src/gpgme.def @@ -202,5 +202,7 @@ EXPORTS gpgme_err_code_from_syserror @154 gpgme_err_set_errno @155 + gpgme_set_global_flag @156 + ; END diff --git a/src/gpgme.h.in b/src/gpgme.h.in index 7263d983..ce469dee 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -2026,6 +2026,9 @@ gpgme_error_t gpgme_key_from_uid (gpgme_key_t *key, const char *name); /* Various functions. */ +/* Set special global flags; consult the manual before use. */ +int gpgme_set_global_flag (const char *name, const char *value); + /* Check that the library fulfills the version requirement. Note: This is here only for the case where a user takes a pointer from the old version of this function. The new version and macro for diff --git a/src/libgpgme.vers b/src/libgpgme.vers index 3477d318..d59571e1 100644 --- a/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -1,5 +1,5 @@ # libgpgme.vers - List of symbols to export. -# Copyright (C) 2002, 2004, 2005, 2009 g10 Code GmbH +# Copyright (C) 2002, 2004, 2005, 2009, 2012 g10 Code GmbH # # This file is part of GPGME. # @@ -79,6 +79,8 @@ GPGME_1.1 { gpgme_op_passwd_start; gpgme_op_passwd; + + gpgme_set_global_flag; };