gpgme (14 files)
cvs user marcus
cvs at cvs.gnupg.org
Tue Dec 7 19:17:49 CET 2004
Date: Tuesday, December 7, 2004 @ 19:25:54
Author: marcus
Path: /cvs/gpgme/gpgme
Modified: NEWS gpgme/ChangeLog gpgme/context.h gpgme/engine-backend.h
gpgme/engine-gpgsm.c gpgme/engine.c gpgme/engine.h gpgme/gpgme.c
gpgme/gpgme.h gpgme/libgpgme.vers gpgme/op-support.c gpgme/ops.h
gpgme/rungpg.c gpgme/version.c
2004-12-07 Marcus Brinkmann <marcus at g10code.de>
* libgpgme.vers (GPGME_1.1): New version.
* engine-backend.h (struct engine_ops): Add argument FILE_NAME to
member get_version(). Add arguments FILE_NAME and HOME_DIR to
member new(). Change return type of get_file_name and get_version
to char *.
* engine-gpgsm.c (gpgsm_get_version): Change return type to char
pointer. Do not cache result.
(gpgsm_new): Add file_name and home_dir argument, and use them
instead of the defaults, if set.
* rungpg.c (struct engine_gpg): New member file_name.
(gpg_get_version): Change return type to char pointer, and do not
cache result.
(gpg_release): Free gpg->file_name.
(gpg_new): Take new arguments file_name and home_dir. Set the
--homedir argument if HOME_DIR is not NULL. Set gpg->file_name.
(start): Use gpg->file_name instead _gpgme_get_gpg_path, if set.
* engine.h (_gpgme_engine_info_copy, _gpgme_engine_info_release):
New prototypes.
(_gpgme_engine_new): Change first argument to gpgme_engine_info_t
info.
* engine.c: Include <assert.h>.
(gpgme_get_engine_info): Set *INFO within the lock. Move
ENGINE_INFO and ENGINE_INFO_LOCK to ....
(engine_info, engine_info_lock): ... here. New static variables.
(engine_get_version): Add file_name argument to
get_version invocation. Change return type to char pointer.
(gpgme_engine_check_version): Rewritten to free() the return value
of engine_get_version after using it.
(_gpgme_engine_info_release): New function.
(gpgme_get_engine_info): Rewritten.
(_gpgme_engine_info_copy): New function.
(_gpgme_set_engine_info): New function.
(gpgme_set_engine_info): New function.
(_gpgme_engine_new): Change first argument to gpgme_engine_info_t
info, and use that.
* gpgme.h (struct _gpgme_engine_info): Change type of file_name
and version to char * (remove the const). New member home_dir.
(gpgme_set_engine_info, gpgme_ctx_get_engine_info,
gpgme_ctx_set_engine_info): New prototypes.
* context.h (struct gpgme_context): New member engine_info.
* gpgme.c (gpgme_new): Allocate CTX->engine_info.
(gpgme_release): Deallocate CTX->engine_info.
(gpgme_ctx_get_engine_info, gpgme_ctx_set_engine_info): New
functions.
* op-support.c (_gpgme_op_reset): Look for correct engine info and
pass it to _gpgme_engine_new.
* version.c (gpgme_check_version): Adjust to
_gpgme_compare_versions returning an int.
(_gpgme_compare_versions): Return an int value, not a const char
pointer.
* ops.h (_gpgme_compare_versions): Same for prototype.
------------------------+
NEWS | 13 ++
gpgme/ChangeLog | 54 +++++++++
gpgme/context.h | 3
gpgme/engine-backend.h | 15 ++
gpgme/engine-gpgsm.c | 36 +++---
gpgme/engine.c | 273 ++++++++++++++++++++++++++++++++++++++++-------
gpgme/engine.h | 9 +
gpgme/gpgme.c | 34 +++++
gpgme/gpgme.h | 33 ++++-
gpgme/libgpgme.vers | 9 +
gpgme/op-support.c | 15 ++
gpgme/ops.h | 6 -
gpgme/rungpg.c | 47 +++++---
gpgme/version.c | 18 +--
14 files changed, 478 insertions(+), 87 deletions(-)
Index: gpgme/NEWS
diff -u gpgme/NEWS:1.136 gpgme/NEWS:1.137
--- gpgme/NEWS:1.136 Fri Oct 22 20:11:33 2004
+++ gpgme/NEWS Tue Dec 7 19:25:54 2004
@@ -1,3 +1,16 @@
+Noteworthy changes in version 1.1.0 (unreleased)
+------------------------------------------------
+
+ * You can now configure the backend engine file name and home
+ directory to be used, as default and per context.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gpgme_set_engine_info NEW
+gpgme_ctx_get_engine_info NEW
+gpgme_ctx_set_engine_info NEW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
Noteworthy changes in version 1.0.1 (2004-10-22)
------------------------------------------------
Index: gpgme/gpgme/ChangeLog
diff -u gpgme/gpgme/ChangeLog:1.386 gpgme/gpgme/ChangeLog:1.387
--- gpgme/gpgme/ChangeLog:1.386 Fri Oct 22 19:57:56 2004
+++ gpgme/gpgme/ChangeLog Tue Dec 7 19:25:53 2004
@@ -1,3 +1,57 @@
+2004-12-07 Marcus Brinkmann <marcus at g10code.de>
+
+ * libgpgme.vers (GPGME_1.1): New version.
+ * engine-backend.h (struct engine_ops): Add argument FILE_NAME to
+ member get_version(). Add arguments FILE_NAME and HOME_DIR to
+ member new(). Change return type of get_file_name and get_version
+ to char *.
+ * engine-gpgsm.c (gpgsm_get_version): Change return type to char
+ pointer. Do not cache result.
+ (gpgsm_new): Add file_name and home_dir argument, and use them
+ instead of the defaults, if set.
+ * rungpg.c (struct engine_gpg): New member file_name.
+ (gpg_get_version): Change return type to char pointer, and do not
+ cache result.
+ (gpg_release): Free gpg->file_name.
+ (gpg_new): Take new arguments file_name and home_dir. Set the
+ --homedir argument if HOME_DIR is not NULL. Set gpg->file_name.
+ (start): Use gpg->file_name instead _gpgme_get_gpg_path, if set.
+ * engine.h (_gpgme_engine_info_copy, _gpgme_engine_info_release):
+ New prototypes.
+ (_gpgme_engine_new): Change first argument to gpgme_engine_info_t
+ info.
+ * engine.c: Include <assert.h>.
+ (gpgme_get_engine_info): Set *INFO within the lock. Move
+ ENGINE_INFO and ENGINE_INFO_LOCK to ....
+ (engine_info, engine_info_lock): ... here. New static variables.
+ (engine_get_version): Add file_name argument to
+ get_version invocation. Change return type to char pointer.
+ (gpgme_engine_check_version): Rewritten to free() the return value
+ of engine_get_version after using it.
+ (_gpgme_engine_info_release): New function.
+ (gpgme_get_engine_info): Rewritten.
+ (_gpgme_engine_info_copy): New function.
+ (_gpgme_set_engine_info): New function.
+ (gpgme_set_engine_info): New function.
+ (_gpgme_engine_new): Change first argument to gpgme_engine_info_t
+ info, and use that.
+ * gpgme.h (struct _gpgme_engine_info): Change type of file_name
+ and version to char * (remove the const). New member home_dir.
+ (gpgme_set_engine_info, gpgme_ctx_get_engine_info,
+ gpgme_ctx_set_engine_info): New prototypes.
+ * context.h (struct gpgme_context): New member engine_info.
+ * gpgme.c (gpgme_new): Allocate CTX->engine_info.
+ (gpgme_release): Deallocate CTX->engine_info.
+ (gpgme_ctx_get_engine_info, gpgme_ctx_set_engine_info): New
+ functions.
+ * op-support.c (_gpgme_op_reset): Look for correct engine info and
+ pass it to _gpgme_engine_new.
+ * version.c (gpgme_check_version): Adjust to
+ _gpgme_compare_versions returning an int.
+ (_gpgme_compare_versions): Return an int value, not a const char
+ pointer.
+ * ops.h (_gpgme_compare_versions): Same for prototype.
+
2004-10-03 Marcus Brinkmann <marcus at g10code.de>
* verify.c (parse_trust): If no reason is provided, set
Index: gpgme/gpgme/context.h
diff -u gpgme/gpgme/context.h:1.56 gpgme/gpgme/context.h:1.57
--- gpgme/gpgme/context.h:1.56 Sun Sep 14 02:02:40 2003
+++ gpgme/gpgme/context.h Tue Dec 7 19:25:53 2004
@@ -62,6 +62,9 @@
be performed (sequentially). */
struct gpgme_context
{
+ /* The engine info for this context. */
+ gpgme_engine_info_t engine_info;
+
/* The protocol used by this context. */
gpgme_protocol_t protocol;
Index: gpgme/gpgme/engine-backend.h
diff -u gpgme/gpgme/engine-backend.h:1.15 gpgme/gpgme/engine-backend.h:1.16
--- gpgme/gpgme/engine-backend.h:1.15 Wed Feb 25 00:08:46 2004
+++ gpgme/gpgme/engine-backend.h Tue Dec 7 19:25:53 2004
@@ -30,10 +30,21 @@
struct engine_ops
{
/* Static functions. */
- const char *(*get_file_name) (void);
- const char *(*get_version) (void);
+
+ /* Return the default file name for the binary of this engine. */
+ char *(*get_file_name) (void);
+
+ /* Returns a malloced string containing the version of the engine
+ with the given binary file name (or the default if FILE_NAME is
+ NULL. */
+ char *(*get_version) (const char *file_name);
+
+ /* Returns a statically allocated string containing the required
+ version. */
const char *(*get_req_version) (void);
+
gpgme_error_t (*new) (void **r_engine,
+ const char *file_name, const char *home_dir,
const char *lc_ctype, const char *lc_messages);
/* Member functions. */
Index: gpgme/gpgme/engine-gpgsm.c
diff -u gpgme/gpgme/engine-gpgsm.c:1.100 gpgme/gpgme/engine-gpgsm.c:1.101
--- gpgme/gpgme/engine-gpgsm.c:1.100 Fri Oct 22 18:55:16 2004
+++ gpgme/gpgme/engine-gpgsm.c Tue Dec 7 19:25:53 2004
@@ -95,18 +95,11 @@
typedef struct engine_gpgsm *engine_gpgsm_t;
-static const char *
-gpgsm_get_version (void)
+static char *
+gpgsm_get_version (const char *file_name)
{
- static const char *gpgsm_version;
- DEFINE_STATIC_LOCK (gpgsm_version_lock);
-
- LOCK (gpgsm_version_lock);
- if (!gpgsm_version)
- gpgsm_version = _gpgme_get_program_version (_gpgme_get_gpgsm_path ());
- UNLOCK (gpgsm_version_lock);
-
- return gpgsm_version;
+ return _gpgme_get_program_version (file_name ? file_name
+ : _gpgme_get_gpgsm_path ());
}
@@ -319,11 +312,13 @@
static gpgme_error_t
-gpgsm_new (void **engine, const char *lc_ctype, const char *lc_messages)
+gpgsm_new (void **engine, const char *file_name, const char *home_dir,
+ const char *lc_ctype, const char *lc_messages)
{
gpgme_error_t err = 0;
engine_gpgsm_t gpgsm;
- char *argv[3];
+ char *argv[5];
+ int argc;
int fds[2];
int child_fds[4];
char *dft_display = NULL;
@@ -395,12 +390,19 @@
child_fds[2] = gpgsm->message_fd_server;
child_fds[3] = -1;
- argv[0] = "gpgsm";
- argv[1] = "--server";
- argv[2] = NULL;
+ argc = 0;
+ argv[argc++] = "gpgsm";
+ if (home_dir)
+ {
+ argv[argc++] = "--homedir";
+ argv[argc++] = home_dir;
+ }
+ argv[argc++] = "--server";
+ argv[argc++] = NULL;
err = assuan_pipe_connect (&gpgsm->assuan_ctx,
- _gpgme_get_gpgsm_path (), argv, child_fds);
+ file_name ? file_name : _gpgme_get_gpgsm_path (),
+ argv, child_fds);
/* FIXME: Check error. */
/* We need to know the fd used by assuan for reads. We do this by
Index: gpgme/gpgme/engine.c
diff -u gpgme/gpgme/engine.c:1.44 gpgme/gpgme/engine.c:1.45
--- gpgme/gpgme/engine.c:1.44 Wed Feb 25 00:08:46 2004
+++ gpgme/gpgme/engine.c Tue Dec 7 19:25:53 2004
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
+#include <assert.h>
#include "gpgme.h"
#include "util.h"
@@ -51,9 +52,14 @@
#endif
};
+
+/* The engine info. */
+static gpgme_engine_info_t engine_info;
+DEFINE_STATIC_LOCK (engine_info_lock);
+
/* Get the file name of the engine for PROTOCOL. */
-static const char *
+static char *
engine_get_file_name (gpgme_protocol_t proto)
{
if (proto > DIM (engine_ops))
@@ -66,15 +72,16 @@
}
-/* Get the version number of the engine for PROTOCOL. */
-static const char *
-engine_get_version (gpgme_protocol_t proto)
+/* Get a malloced string containing the version number of the engine
+ for PROTOCOL. */
+static char *
+engine_get_version (gpgme_protocol_t proto, const char *file_name)
{
if (proto > DIM (engine_ops))
return NULL;
if (engine_ops[proto] && engine_ops[proto]->get_version)
- return (*engine_ops[proto]->get_version) ();
+ return (*engine_ops[proto]->get_version) (file_name);
else
return NULL;
}
@@ -98,21 +105,45 @@
gpgme_error_t
gpgme_engine_check_version (gpgme_protocol_t proto)
{
- return _gpgme_compare_versions (engine_get_version (proto),
- engine_get_req_version (proto))
- ? 0 : gpg_error (GPG_ERR_INV_ENGINE);
+ int result;
+ char *engine_version = engine_get_version (proto, NULL);
+
+ result = _gpgme_compare_versions (engine_version,
+ engine_get_req_version (proto));
+ if (engine_version)
+ free (engine_version);
+
+ return result ? 0 : gpg_error (GPG_ERR_INV_ENGINE);
+}
+
+
+/* Release the engine info INFO. */
+void
+_gpgme_engine_info_release (gpgme_engine_info_t info)
+{
+ while (info)
+ {
+ gpgme_engine_info_t next_info = info->next;
+
+ assert (info->file_name);
+ free (info->file_name);
+ if (info->home_dir)
+ free (info->home_dir);
+ if (info->version)
+ free (info->version);
+ free (info);
+ info = next_info;
+ }
}
/* 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. */
+ is returned in *INFO. If an error occurs, it is returned. The
+ returned data is valid until the next gpgme_set_engine_info. */
gpgme_error_t
gpgme_get_engine_info (gpgme_engine_info_t *info)
{
- static gpgme_engine_info_t engine_info;
- DEFINE_STATIC_LOCK (engine_info_lock);
-
LOCK (engine_info_lock);
if (!engine_info)
{
@@ -123,70 +154,238 @@
for (proto = 0; proto < DIM (proto_list); proto++)
{
- const char *file_name = engine_get_file_name (proto_list[proto]);
+ char *file_name = engine_get_file_name (proto_list[proto]);
if (!file_name)
continue;
+ file_name = strdup (file_name);
+
*lastp = malloc (sizeof (*engine_info));
- if (!*lastp)
+ if (!*lastp || !file_name)
{
int saved_errno = errno;
- while (engine_info)
- {
- gpgme_engine_info_t next_info = engine_info->next;
- free (engine_info);
- engine_info = next_info;
- }
+ _gpgme_engine_info_release (engine_info);
+ engine_info = NULL;
+
+ if (file_name)
+ free (file_name);
+
UNLOCK (engine_info_lock);
return gpg_error_from_errno (saved_errno);
}
(*lastp)->protocol = proto_list[proto];
(*lastp)->file_name = file_name;
- (*lastp)->version = engine_get_version (proto_list[proto]);
+ (*lastp)->home_dir = NULL;
+ (*lastp)->version = engine_get_version (proto_list[proto], NULL);
(*lastp)->req_version = engine_get_req_version (proto_list[proto]);
(*lastp)->next = NULL;
lastp = &(*lastp)->next;
}
}
- UNLOCK (engine_info_lock);
+
*info = engine_info;
+ UNLOCK (engine_info_lock);
return 0;
}
-
+
+/* Get a deep copy of the engine info and return it in INFO. */
gpgme_error_t
-_gpgme_engine_new (gpgme_protocol_t proto, engine_t *r_engine,
- const char *lc_ctype, const char *lc_messages)
+_gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
{
- engine_t engine;
+ gpgme_error_t err = 0;
+ gpgme_engine_info_t info;
+ gpgme_engine_info_t new_info;
+ gpgme_engine_info_t *lastp;
+
+ LOCK (engine_info_lock);
+ info = engine_info;
+ if (!info)
+ {
+ /* Make sure it is initialized. */
+ UNLOCK (engine_info_lock);
+ err = gpgme_get_engine_info (&info);
+ if (err)
+ return err;
+
+ LOCK (engine_info_lock);
+ }
+
+ new_info = NULL;
+ lastp = &new_info;
+
+ while (info)
+ {
+ char *file_name;
+ char *home_dir;
+ char *version;
+
+ assert (info->file_name);
+ file_name = strdup (info->file_name);
+
+ if (info->home_dir)
+ {
+ home_dir = strdup (info->home_dir);
+ if (!home_dir)
+ err = gpg_error_from_errno (errno);
+ }
+ else
+ home_dir = NULL;
+
+ if (info->version)
+ {
+ version = strdup (info->version);
+ if (!version)
+ err = gpg_error_from_errno (errno);
+ }
+ else
+ version = NULL;
+
+ *lastp = malloc (sizeof (*engine_info));
+ if (!*lastp || !file_name || err)
+ {
+ int saved_errno = errno;
+
+ _gpgme_engine_info_release (new_info);
+
+ if (file_name)
+ free (file_name);
+ if (home_dir)
+ free (home_dir);
+ if (version)
+ free (version);
+
+ UNLOCK (engine_info_lock);
+ return gpg_error_from_errno (saved_errno);
+ }
+
+ (*lastp)->protocol = info->protocol;
+ (*lastp)->file_name = file_name;
+ (*lastp)->home_dir = home_dir;
+ (*lastp)->version = version;
+ (*lastp)->req_version = info->req_version;
+ (*lastp)->next = NULL;
+ lastp = &(*lastp)->next;
+
+ info = info->next;
+ }
+
+ *r_info = new_info;
+ UNLOCK (engine_info_lock);
+ return 0;
+}
+
- const char *file_name;
- const char *version;
+/* Set the engine info for the info list INFO, protocol PROTO, to the
+ file name FILE_NAME and the home directory HOME_DIR. */
+gpgme_error_t
+_gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto,
+ const char *file_name, const char *home_dir)
+{
+ char *new_file_name;
+ char *new_home_dir;
+ /* FIXME: Use some PROTO_MAX definition. */
if (proto > DIM (engine_ops))
return gpg_error (GPG_ERR_INV_VALUE);
- if (!engine_ops[proto])
+ while (info && info->protocol != proto)
+ info = info->next;
+
+ if (!info)
return gpg_error (GPG_ERR_INV_ENGINE);
- file_name = engine_get_file_name (proto);
- version = engine_get_version (proto);
- if (!file_name || !version)
+ /* Prepare new members. */
+ if (file_name)
+ new_file_name = strdup (file_name);
+ else
+ {
+ new_file_name = engine_get_file_name (proto);
+ assert (file_name);
+ new_file_name = strdup (new_file_name);
+ }
+ if (!new_file_name)
+ return gpg_error_from_errno (errno);
+
+ if (home_dir)
+ {
+ new_home_dir = strdup (home_dir);
+ if (!new_home_dir)
+ {
+ free (new_file_name);
+ return gpg_error_from_errno (errno);
+ }
+ }
+ else
+ new_home_dir = NULL;
+
+ /* Remove the old members. */
+ assert (info->file_name);
+ free (info->file_name);
+ if (info->home_dir)
+ free (info->home_dir);
+ if (info->version)
+ free (info->version);
+
+ /* Install the new members. */
+ info->file_name = new_file_name;
+ info->home_dir = new_home_dir;
+ info->version = engine_get_version (proto, file_name);
+
+ return 0;
+}
+
+
+/* Set the default engine info for the protocol PROTO to the file name
+ FILE_NAME and the home directory HOME_DIR. */
+gpgme_error_t
+gpgme_set_engine_info (gpgme_protocol_t proto,
+ const char *file_name, const char *home_dir)
+{
+ gpgme_error_t err;
+ gpgme_engine_info_t info;
+
+ LOCK (engine_info_lock);
+ info = engine_info;
+ if (!info)
+ {
+ /* Make sure it is initialized. */
+ UNLOCK (engine_info_lock);
+ err = gpgme_get_engine_info (&info);
+ if (err)
+ return err;
+
+ LOCK (engine_info_lock);
+ }
+
+ err = _gpgme_set_engine_info (info, proto, file_name, home_dir);
+ UNLOCK (engine_info_lock);
+ return err;
+}
+
+
+gpgme_error_t
+_gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine,
+ const char *lc_ctype, const char *lc_messages)
+{
+ engine_t engine;
+
+ if (!info->file_name || !info->version)
return gpg_error (GPG_ERR_INV_ENGINE);
engine = calloc (1, sizeof *engine);
if (!engine)
return gpg_error_from_errno (errno);
- engine->ops = engine_ops[proto];
- if (engine_ops[proto]->new)
+ engine->ops = engine_ops[info->protocol];
+ if (engine->ops->new)
{
- gpgme_error_t err = (*engine_ops[proto]->new) (&engine->engine,
- lc_ctype,
- lc_messages);
+ gpgme_error_t err = (*engine->ops->new) (&engine->engine,
+ info->file_name, info->home_dir,
+ lc_ctype, lc_messages);
if (err)
{
free (engine);
Index: gpgme/gpgme/engine.h
diff -u gpgme/gpgme/engine.h:1.34 gpgme/gpgme/engine.h:1.35
--- gpgme/gpgme/engine.h:1.34 Wed Feb 25 00:08:46 2004
+++ gpgme/gpgme/engine.h Tue Dec 7 19:25:53 2004
@@ -35,7 +35,14 @@
const char *keyword,
int fd);
-gpgme_error_t _gpgme_engine_new (gpgme_protocol_t proto,
+/* Get a deep copy of the engine info and return it in INFO. */
+gpgme_error_t _gpgme_engine_info_copy (gpgme_engine_info_t *r_info);
+
+/* Release the engine info INFO. */
+void _gpgme_engine_info_release (gpgme_engine_info_t info);
+
+
+gpgme_error_t _gpgme_engine_new (gpgme_engine_info_t info,
engine_t *r_engine,
const char *lc_ctype,
const char *lc_messages);
Index: gpgme/gpgme/gpgme.c
diff -u gpgme/gpgme/gpgme.c:1.76 gpgme/gpgme/gpgme.c:1.77
--- gpgme/gpgme/gpgme.c:1.76 Wed Feb 25 00:08:46 2004
+++ gpgme/gpgme/gpgme.c Tue Dec 7 19:25:53 2004
@@ -50,6 +50,14 @@
ctx = calloc (1, sizeof *ctx);
if (!ctx)
return gpg_error_from_errno (errno);
+
+ _gpgme_engine_info_copy (&ctx->engine_info);
+ if (!ctx->engine_info)
+ {
+ free (ctx);
+ return gpg_error_from_errno (errno);
+ }
+
ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
ctx->include_certs = 1;
ctx->protocol = GPGME_PROTOCOL_OpenPGP;
@@ -62,6 +70,7 @@
if (!ctx->lc_ctype)
{
UNLOCK (def_lc_lock);
+ _gpgme_engine_info_release (ctx->engine_info);
free (ctx);
return gpg_error_from_errno (errno);
}
@@ -77,6 +86,7 @@
UNLOCK (def_lc_lock);
if (ctx->lc_ctype)
free (ctx->lc_ctype);
+ _gpgme_engine_info_release (ctx->engine_info);
free (ctx);
return gpg_error_from_errno (errno);
}
@@ -120,6 +130,7 @@
free (ctx->lc_ctype);
if (ctx->lc_messages)
free (ctx->lc_messages);
+ _gpgme_engine_info_release (ctx->engine_info);
free (ctx);
}
@@ -390,6 +401,29 @@
}
+/* Get the information about the configured engines. A pointer to the
+ first engine in the statically allocated linked list is returned.
+ The returned data is valid until the next gpgme_ctx_set_engine_info. */
+gpgme_engine_info_t
+gpgme_ctx_get_engine_info (gpgme_ctx_t ctx)
+{
+ return ctx->engine_info;
+}
+
+
+/* Set the engine info for the context CTX, protocol PROTO, to the
+ file name FILE_NAME and the home directory HOME_DIR. */
+gpgme_error_t
+gpgme_ctx_set_engine_info (gpgme_ctx_t ctx, gpgme_protocol_t proto,
+ const char *file_name, const char *home_dir)
+{
+ /* FIXME: Make sure to reset the context if we are running in daemon
+ mode. */
+ return _gpgme_set_engine_info (ctx->engine_info, proto,
+ file_name, home_dir);
+}
+
+
const char *
gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
{
Index: gpgme/gpgme/gpgme.h
diff -u gpgme/gpgme/gpgme.h:1.149 gpgme/gpgme/gpgme.h:1.150
--- gpgme/gpgme/gpgme.h:1.149 Tue Dec 7 16:27:11 2004
+++ gpgme/gpgme/gpgme.h Tue Dec 7 19:25:53 2004
@@ -412,13 +412,16 @@
gpgme_protocol_t protocol;
/* The file name of the engine binary. */
- const char *file_name;
-
+ char *file_name;
+
/* The version string of the installed engine. */
- const char *version;
+ char *version;
/* The minimum version required for GPGME. */
const char *req_version;
+
+ /* The home directory used, or NULL if default. */
+ char *home_dir;
};
typedef struct _gpgme_engine_info *gpgme_engine_info_t;
@@ -741,6 +744,19 @@
locale if CTX is a null pointer. */
gpgme_error_t gpgme_set_locale (gpgme_ctx_t ctx, int category,
const char *value);
+
+/* Get the information about the configured engines. A pointer to the
+ first engine in the statically allocated linked list is returned.
+ The returned data is valid until the next gpgme_ctx_set_engine_info. */
+gpgme_engine_info_t gpgme_ctx_get_engine_info (gpgme_ctx_t ctx);
+
+/* Set the engine info for the context CTX, protocol PROTO, to the
+ file name FILE_NAME and the home directory HOME_DIR. */
+gpgme_error_t gpgme_ctx_set_engine_info (gpgme_ctx_t ctx,
+ gpgme_protocol_t proto,
+ const char *file_name,
+ const char *home_dir);
+
/* Return a statically allocated string with the name of the public
key algorithm ALGO, or NULL if that name is not known. */
@@ -1501,9 +1517,18 @@
/* Check that the library fulfills the version requirement. */
const char *gpgme_check_version (const char *req_version);
-/* Retrieve information about the backend engines. */
+/* 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
+ returned data is valid until the next gpgme_set_engine_info. */
gpgme_error_t gpgme_get_engine_info (gpgme_engine_info_t *engine_info);
+/* Set the default engine info for the protocol PROTO to the file name
+ FILE_NAME and the home directory HOME_DIR. */
+gpgme_error_t gpgme_set_engine_info (gpgme_protocol_t proto,
+ const char *file_name,
+ const char *home_dir);
+
/* Engine support functions. */
Index: gpgme/gpgme/libgpgme.vers
diff -u gpgme/gpgme/libgpgme.vers:1.3 gpgme/gpgme/libgpgme.vers:1.4
--- gpgme/gpgme/libgpgme.vers:1.3 Wed Jun 2 16:18:03 2004
+++ gpgme/gpgme/libgpgme.vers Tue Dec 7 19:25:53 2004
@@ -18,6 +18,15 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+GPGME_1.1 {
+ global:
+ gpgme_set_engine_info;
+
+ gpgme_ctx_get_engine_info;
+ gpgme_ctx_set_engine_info;
+};
+
+
GPGME_1.0 {
global:
gpgme_check_version;
Index: gpgme/gpgme/op-support.c
diff -u gpgme/gpgme/op-support.c:1.15 gpgme/gpgme/op-support.c:1.16
--- gpgme/gpgme/op-support.c:1.15 Tue Oct 5 17:08:45 2004
+++ gpgme/gpgme/op-support.c Tue Dec 7 19:25:53 2004
@@ -66,17 +66,26 @@
_gpgme_op_reset (gpgme_ctx_t ctx, int type)
{
gpgme_error_t err = 0;
+ gpgme_engine_info_t info;
struct gpgme_io_cbs io_cbs;
+ info = ctx->engine_info;
+ while (info && info->protocol != ctx->protocol)
+ info = info->next;
+
+ if (!info)
+ return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
+
_gpgme_release_result (ctx);
- /* Create an engine object. */
- if (ctx->engine)
+ if (ctx->engine)
{
_gpgme_engine_release (ctx->engine);
ctx->engine = NULL;
}
- err = _gpgme_engine_new (ctx->protocol, &ctx->engine,
+
+ /* Create an engine object. */
+ err = _gpgme_engine_new (info, &ctx->engine,
ctx->lc_ctype, ctx->lc_messages);
if (err)
return err;
Index: gpgme/gpgme/ops.h
diff -u gpgme/gpgme/ops.h:1.55 gpgme/gpgme/ops.h:1.56
--- gpgme/gpgme/ops.h:1.55 Fri Jun 6 02:55:42 2003
+++ gpgme/gpgme/ops.h Tue Dec 7 19:25:53 2004
@@ -136,8 +136,10 @@
/*-- version.c --*/
-const char *_gpgme_compare_versions (const char *my_version,
- const char *req_version);
+/* Return true if MY_VERSION is at least REQ_VERSION, and false
+ otherwise. */
+int _gpgme_compare_versions (const char *my_version,
+ const char *req_version);
char *_gpgme_get_program_version (const char *const path);
#endif /* OPS_H */
Index: gpgme/gpgme/rungpg.c
diff -u gpgme/gpgme/rungpg.c:1.101 gpgme/gpgme/rungpg.c:1.102
--- gpgme/gpgme/rungpg.c:1.101 Thu Sep 30 02:24:58 2004
+++ gpgme/gpgme/rungpg.c Tue Dec 7 19:25:53 2004
@@ -66,6 +66,8 @@
struct engine_gpg
{
+ char *file_name;
+
struct arg_and_data_s *arglist;
struct arg_and_data_s **argtail;
@@ -224,17 +226,11 @@
}
-static const char *
-gpg_get_version (void)
+static char *
+gpg_get_version (const char *file_name)
{
- static const char *gpg_version;
- DEFINE_STATIC_LOCK (gpg_version_lock);
-
- LOCK (gpg_version_lock);
- if (!gpg_version)
- gpg_version = _gpgme_get_program_version (_gpgme_get_gpg_path ());
- UNLOCK (gpg_version_lock);
- return gpg_version;
+ return _gpgme_get_program_version (file_name ? file_name
+ : _gpgme_get_gpg_path ());
}
@@ -313,6 +309,9 @@
gpg_cancel (engine);
+ if (gpg->file_name)
+ free (gpg->file_name);
+
while (gpg->arglist)
{
struct arg_and_data_s *next = gpg->arglist->next;
@@ -336,7 +335,8 @@
static gpgme_error_t
-gpg_new (void **engine, const char *lc_ctype, const char *lc_messages)
+gpg_new (void **engine, const char *file_name, const char *home_dir,
+ const char *lc_ctype, const char *lc_messages)
{
engine_gpg_t gpg;
gpgme_error_t rc = 0;
@@ -345,6 +345,16 @@
if (!gpg)
return gpg_error_from_errno (errno);
+ if (file_name)
+ {
+ gpg->file_name = strdup (file_name);
+ if (!gpg->file_name)
+ {
+ rc = gpg_error_from_errno (errno);
+ goto leave;
+ }
+ }
+
gpg->argtail = &gpg->arglist;
gpg->status.fd[0] = -1;
gpg->status.fd[1] = -1;
@@ -380,6 +390,16 @@
goto leave;
}
gpg->status.eof = 0;
+
+ if (home_dir)
+ {
+ rc = add_arg (gpg, "--homedir");
+ if (!rc)
+ rc = add_arg (gpg, home_dir);
+ if (rc)
+ goto leave;
+ }
+
rc = add_arg (gpg, "--status-fd");
if (rc)
goto leave;
@@ -1043,7 +1063,7 @@
if (!gpg)
return gpg_error (GPG_ERR_INV_VALUE);
- if (! _gpgme_get_gpg_path ())
+ if (!gpg->file_name && !_gpgme_get_gpg_path ())
return gpg_error (GPG_ERR_INV_ENGINE);
rc = build_argv (gpg);
@@ -1101,7 +1121,8 @@
fd_parent_list[n].fd = -1;
fd_parent_list[n].dup_to = -1;
- status = _gpgme_io_spawn (_gpgme_get_gpg_path (),
+ status = _gpgme_io_spawn (gpg->file_name ? gpg->file_name :
+ _gpgme_get_gpg_path (),
gpg->argv, fd_child_list, fd_parent_list);
saved_errno = errno;
free (fd_child_list);
Index: gpgme/gpgme/version.c
diff -u gpgme/gpgme/version.c:1.25 gpgme/gpgme/version.c:1.26
--- gpgme/gpgme/version.c:1.25 Mon Oct 6 18:17:13 2003
+++ gpgme/gpgme/version.c Tue Dec 7 19:25:53 2004
@@ -103,7 +103,9 @@
}
-const char *
+/* Return true if MY_VERSION is at least REQ_VERSION, and false
+ otherwise. */
+int
_gpgme_compare_versions (const char *my_version,
const char *rq_version)
{
@@ -112,17 +114,17 @@
const char *my_plvl, *rq_plvl;
if (!rq_version)
- return my_version;
+ return 1;
if (!my_version)
- return NULL;
+ return 0;
my_plvl = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
if (!my_plvl)
- return NULL;
+ return 0;
rq_plvl = parse_version_string (rq_version, &rq_major, &rq_minor, &rq_micro);
if (!rq_plvl)
- return NULL;
+ return 0;
if (my_major > rq_major
|| (my_major == rq_major && my_minor > rq_minor)
@@ -130,9 +132,9 @@
&& my_micro > rq_micro)
|| (my_major == rq_major && my_minor == rq_minor
&& my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0))
- return my_version;
+ return 1;
- return NULL;
+ return 0;
}
@@ -149,7 +151,7 @@
gpgme_check_version (const char *req_version)
{
do_subsystem_inits ();
- return _gpgme_compare_versions (VERSION, req_version);
+ return _gpgme_compare_versions (VERSION, req_version) ? VERSION : NULL;
}
More information about the Gnupg-commits
mailing list