aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcus Brinkmann <[email protected]>2009-05-28 15:16:01 +0000
committerMarcus Brinkmann <[email protected]>2009-05-28 15:16:01 +0000
commitbdb7bcf93889c279c48acb0b75792ba310116074 (patch)
tree8cf57dce655b2572a08dca4ef70735c0bbedc57b
parentdoc/ (diff)
downloadgpgme-bdb7bcf93889c279c48acb0b75792ba310116074.tar.gz
gpgme-bdb7bcf93889c279c48acb0b75792ba310116074.zip
doc/
2009-05-28 Marcus Brinkmann <[email protected]> * gpgme.texi (Library Version Check): Document selftest error. (Creating Contexts): Likewise. src/ 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.
Diffstat (limited to '')
-rw-r--r--NEWS6
-rw-r--r--doc/ChangeLog5
-rw-r--r--doc/gpgme.texi15
-rw-r--r--src/ChangeLog13
-rw-r--r--src/context.h2
-rw-r--r--src/gpgme.c6
-rw-r--r--src/gpgme.def3
-rw-r--r--src/gpgme.h.in14
-rw-r--r--src/libgpgme.vers2
-rw-r--r--src/version.c40
10 files changed, 101 insertions, 5 deletions
diff --git a/NEWS b/NEWS
index f4c39098..55288b4e 100644
--- a/NEWS
+++ b/NEWS
@@ -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;
}