diff options
| -rw-r--r-- | NEWS | 6 | ||||
| -rw-r--r-- | doc/ChangeLog | 5 | ||||
| -rw-r--r-- | doc/gpgme.texi | 15 | ||||
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/context.h | 2 | ||||
| -rw-r--r-- | src/gpgme.c | 6 | ||||
| -rw-r--r-- | src/gpgme.def | 3 | ||||
| -rw-r--r-- | src/gpgme.h.in | 14 | ||||
| -rw-r--r-- | src/libgpgme.vers | 2 | ||||
| -rw-r--r-- | src/version.c | 40 | 
10 files changed, 101 insertions, 5 deletions
| @@ -4,6 +4,10 @@ Noteworthy changes in version 1.1.9   * New encryption flag GPGME_ENCRYPT_NO_ENCRYPT_TO to disable default     recipients. + * gpgme_new will fail if gpgme_check_version was not called, or a +   selftest failed (for example, if -mms-bitfields was not used on +   MingW32 targets). +   * Interface changes relative to the 1.1.7 release:   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   GPGME_KEYLIST_MODE_EPHEMERAL   NEW. @@ -16,6 +20,8 @@ Noteworthy changes in version 1.1.9   gpgme_op_assuan_result         NEW.   gpgme_subkey_t                 EXTENDED: New fields is_cardkey, card_number.   GPGME_ENCRYPT_NO_ENCRYPT_TO    NEW. + gpgme_check_version            CHANGED: Is now a macro. + gpgme_new                      EXTENDED: More failure codes.   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/ChangeLog b/doc/ChangeLog index e1f36225..e1bb4a59 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2009-05-28  Marcus Brinkmann  <[email protected]> + +	* gpgme.texi (Library Version Check): Document selftest error. +	(Creating Contexts): Likewise. +  2009-05-18  Marcus Brinkmann  <[email protected]>  	* gpgme.texi (Encrypting a Plaintext): Document diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 0d5435f9..871575a2 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -577,13 +577,13 @@ automatically by Libtool.  @cindex version check, of the library  @deftypefun {const char *} gpgme_check_version (@w{const char *@var{required_version}}) -The function @code{gpgme_check_version} has three purposes.  It can be +The function @code{gpgme_check_version} has four purposes.  It can be  used to retrieve the version number of the library.  In addition it  can verify that the version number is higher than a certain required  version number.  In either case, the function initializes some  sub-systems, and for this reason alone it must be invoked early in  your program, before you make use of the other functions in -@acronym{GPGME}.  +@acronym{GPGME}.  The last purpose is to run selftests.  As a side effect for W32 based systems, the socket layer will get  initialized. @@ -606,6 +606,11 @@ If you use a version of a library that is backwards compatible with  older releases, but contains additional interfaces which your program  uses, this function provides a run-time check if the necessary  features are provided by the installed version of the library. + +If a selftest fails, the function may still succeed.  Selftest errors +are returned later when invoking @code{gpgme_new}, so that a detailed +error code can be returned (historically, @code{gpgme_check_version} +does not return a detailed error code).  @end deftypefun @@ -1985,7 +1990,11 @@ and returns a handle for it in @var{ctx}.  The function returns the error code @code{GPG_ERR_NO_ERROR} if the  context was successfully created, @code{GPG_ERR_INV_VALUE} if  @var{ctx} is not a valid pointer, and @code{GPG_ERR_ENOMEM} if not -enough memory is available. +enough memory is available.  Also, it returns +@code{GPG_ERR_NOT_OPERATIONAL} if @code{gpgme_check_version} was not +called to initialize GPGME, and @code{GPG_ERR_SELFTEST_FAILED} if a +selftest failed.  Currently, the only selftest is for Windows MingW32 +targets to see if @code{-mms-bitfields} was used (as required).  @end deftypefun diff --git a/src/ChangeLog b/src/ChangeLog index 434c6802..7ee34395 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2009-05-28  Marcus Brinkmann  <[email protected]> + +	* gpgme.h.in (gpgme_check_version_internal): New prototype. +	(gpgme_check_version): New macro, overriding function of the same +	name. +	* libgpgme.vers, gpgme.def: Add gpgme_check_version_internal.o +	* context.h (_gpgme_selftest): New variable declaration. +	* version.c: Include "context.h". +	(gpgme_check_version): Set _gpgme_selftest on success. +	(gpgme_check_version_internal): New function. +	* gpgme.c (_gpgme_selftest): Define it. +	(gpgme_new): Check the selftest result. +  2009-05-18  Marcus Brinkmann  <[email protected]>  	* gpgme.h.in (gpgme_encrypt_flags_t): Add diff --git a/src/context.h b/src/context.h index 76aeb337..472b8beb 100644 --- a/src/context.h +++ b/src/context.h @@ -28,6 +28,8 @@  #include "sema.h" +extern gpgme_error_t _gpgme_selftest; +  /* Operations might require to remember arbitrary information and data     objects during invocations of the status handler.  The     ctx_op_data structure provides a generic framework to hook in diff --git a/src/gpgme.c b/src/gpgme.c index 99d27ce6..b76b3991 100644 --- a/src/gpgme.c +++ b/src/gpgme.c @@ -42,6 +42,9 @@ static char *def_lc_ctype;  static char *def_lc_messages; +gpgme_error_t _gpgme_selftest = GPG_ERR_NOT_OPERATIONAL; + +  /* Create a new context as an environment for GPGME crypto     operations.  */  gpgme_error_t @@ -50,6 +53,9 @@ gpgme_new (gpgme_ctx_t *r_ctx)    gpgme_ctx_t ctx;    TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx); +  if (_gpgme_selftest) +    return TRACE_ERR (gpgme_error (_gpgme_selftest)); +    ctx = calloc (1, sizeof *ctx);    if (!ctx)      return TRACE_ERR (gpg_error_from_errno (errno)); diff --git a/src/gpgme.def b/src/gpgme.def index 835177ef..14636d64 100644 --- a/src/gpgme.def +++ b/src/gpgme.def @@ -171,5 +171,8 @@ EXPORTS      gpgme_op_assuan_result                @132      gpgme_op_assuan_transact_start        @133      gpgme_op_assuan_transact              @134 + +    gpgme_check_version_internal	  @135 +  ; END diff --git a/src/gpgme.h.in b/src/gpgme.h.in index fb2b7363..a9a4a3f7 100644 --- a/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -1894,9 +1894,21 @@ gpgme_error_t gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp);  /* Various functions.  */ -/* Check that the library fulfills the version requirement.  */ +/* 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 +   run-time checks are below.  */  const char *gpgme_check_version (const char *req_version); +/* Check that the library fulfills the version requirement and check +   for struct layout mismatch involving bitfields.  */ +const char *gpgme_check_version_internal (const char *req_version, +					  size_t offset_sig_validity); + +#define gpgme_check_version(req_version)				\ +  gpgme_check_version_internal (req_version,				\ +				offsetof (struct _gpgme_signature, validity)) +  /* Get the information about the configured and installed engines.  A     pointer to the first engine in the statically allocated linked list     is returned in *INFO.  If an error occurs, it is returned.  The diff --git a/src/libgpgme.vers b/src/libgpgme.vers index 1653a63c..bc6eb7cd 100644 --- a/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -51,6 +51,8 @@ GPGME_1.1 {      gpgme_op_assuan_result;          gpgme_op_assuan_transact;          gpgme_op_assuan_transact_start;     + +    gpgme_check_version_internal;  }; diff --git a/src/version.c b/src/version.c index c6fb52b9..213df6de 100644 --- a/src/version.c +++ b/src/version.c @@ -32,6 +32,7 @@  #include "gpgme.h"  #include "priv-io.h"  #include "debug.h" +#include "context.h"  /* For _gpgme_sema_subsystem_init ().  */  #include "sema.h" @@ -44,6 +45,10 @@  #include "windows.h"  #endif +/* We implement this function, so we have to disable the overriding +   macro.  */ +#undef gpgme_check_version +  /* Bootstrap the subsystems needed for concurrent operation.  This     must be done once at startup.  We can not guarantee this using a @@ -183,6 +188,7 @@ _gpgme_compare_versions (const char *my_version,  const char *  gpgme_check_version (const char *req_version)  { +  char *result;    do_subsystem_inits ();    /* Catch-22: We need to get at least the debug subsystem ready @@ -193,7 +199,39 @@ gpgme_check_version (const char *req_version)  	  "req_version=%s, VERSION=%s",            req_version? req_version:"(null)", VERSION); -  return _gpgme_compare_versions (VERSION, req_version) ? VERSION : NULL; +  result = _gpgme_compare_versions (VERSION, req_version) ? VERSION : NULL; +  if (result != NULL) +    _gpgme_selftest = 0; + +  return result; +} + +/* Check the version and also at runtime if the struct layout of the +   library matches the one of the user.  This is particular useful for +   Windows targets (-mms-bitfields).  */ +const char * +gpgme_check_version_internal (const char *req_version, +			      size_t offset_sig_validity) +{ +  char *result; + +  TRACE2 (DEBUG_INIT, "gpgme_check_version_internal: ", 0, +	  "req_version=%s, offset_sig_validity=%i", +	  req_version ? req_version : "(null)", offset_sig_validity); + +  result = gpgme_check_version (req_version); +  if (result == NULL) +    return result; + +  if (offset_sig_validity != offsetof (struct _gpgme_signature, validity)) +    { +      TRACE1 (DEBUG_INIT, "gpgme_check_version_internal: ", 0, +	      "offset_sig_validity mismatch: expected %i", +	      offsetof (struct _gpgme_signature, validity)); +      _gpgme_selftest = GPG_ERR_SELFTEST_FAILED; +    } + +  return result;  } | 
