2004-12-07 Marcus Brinkmann <marcus@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.
This commit is contained in:
parent
e8e4400785
commit
0ebb858f1e
13
NEWS
13
NEWS
@ -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)
|
Noteworthy changes in version 1.0.1 (2004-10-22)
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
|
@ -1,3 +1,57 @@
|
|||||||
|
2004-12-07 Marcus Brinkmann <marcus@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@g10code.de>
|
2004-10-03 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* verify.c (parse_trust): If no reason is provided, set
|
* verify.c (parse_trust): If no reason is provided, set
|
||||||
|
@ -62,6 +62,9 @@ typedef struct ctx_op_data *ctx_op_data_t;
|
|||||||
be performed (sequentially). */
|
be performed (sequentially). */
|
||||||
struct gpgme_context
|
struct gpgme_context
|
||||||
{
|
{
|
||||||
|
/* The engine info for this context. */
|
||||||
|
gpgme_engine_info_t engine_info;
|
||||||
|
|
||||||
/* The protocol used by this context. */
|
/* The protocol used by this context. */
|
||||||
gpgme_protocol_t protocol;
|
gpgme_protocol_t protocol;
|
||||||
|
|
||||||
|
@ -30,10 +30,21 @@
|
|||||||
struct engine_ops
|
struct engine_ops
|
||||||
{
|
{
|
||||||
/* Static functions. */
|
/* 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);
|
const char *(*get_req_version) (void);
|
||||||
|
|
||||||
gpgme_error_t (*new) (void **r_engine,
|
gpgme_error_t (*new) (void **r_engine,
|
||||||
|
const char *file_name, const char *home_dir,
|
||||||
const char *lc_ctype, const char *lc_messages);
|
const char *lc_ctype, const char *lc_messages);
|
||||||
|
|
||||||
/* Member functions. */
|
/* Member functions. */
|
||||||
|
@ -95,18 +95,11 @@ struct engine_gpgsm
|
|||||||
typedef struct engine_gpgsm *engine_gpgsm_t;
|
typedef struct engine_gpgsm *engine_gpgsm_t;
|
||||||
|
|
||||||
|
|
||||||
static const char *
|
static char *
|
||||||
gpgsm_get_version (void)
|
gpgsm_get_version (const char *file_name)
|
||||||
{
|
{
|
||||||
static const char *gpgsm_version;
|
return _gpgme_get_program_version (file_name ? file_name
|
||||||
DEFINE_STATIC_LOCK (gpgsm_version_lock);
|
: _gpgme_get_gpgsm_path ());
|
||||||
|
|
||||||
LOCK (gpgsm_version_lock);
|
|
||||||
if (!gpgsm_version)
|
|
||||||
gpgsm_version = _gpgme_get_program_version (_gpgme_get_gpgsm_path ());
|
|
||||||
UNLOCK (gpgsm_version_lock);
|
|
||||||
|
|
||||||
return gpgsm_version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -319,11 +312,13 @@ gpgsm_release (void *engine)
|
|||||||
|
|
||||||
|
|
||||||
static gpgme_error_t
|
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;
|
gpgme_error_t err = 0;
|
||||||
engine_gpgsm_t gpgsm;
|
engine_gpgsm_t gpgsm;
|
||||||
char *argv[3];
|
char *argv[5];
|
||||||
|
int argc;
|
||||||
int fds[2];
|
int fds[2];
|
||||||
int child_fds[4];
|
int child_fds[4];
|
||||||
char *dft_display = NULL;
|
char *dft_display = NULL;
|
||||||
@ -395,12 +390,19 @@ gpgsm_new (void **engine, const char *lc_ctype, const char *lc_messages)
|
|||||||
child_fds[2] = gpgsm->message_fd_server;
|
child_fds[2] = gpgsm->message_fd_server;
|
||||||
child_fds[3] = -1;
|
child_fds[3] = -1;
|
||||||
|
|
||||||
argv[0] = "gpgsm";
|
argc = 0;
|
||||||
argv[1] = "--server";
|
argv[argc++] = "gpgsm";
|
||||||
argv[2] = NULL;
|
if (home_dir)
|
||||||
|
{
|
||||||
|
argv[argc++] = "--homedir";
|
||||||
|
argv[argc++] = home_dir;
|
||||||
|
}
|
||||||
|
argv[argc++] = "--server";
|
||||||
|
argv[argc++] = NULL;
|
||||||
|
|
||||||
err = assuan_pipe_connect (&gpgsm->assuan_ctx,
|
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. */
|
/* FIXME: Check error. */
|
||||||
|
|
||||||
/* We need to know the fd used by assuan for reads. We do this by
|
/* We need to know the fd used by assuan for reads. We do this by
|
||||||
|
279
gpgme/engine.c
279
gpgme/engine.c
@ -24,6 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "gpgme.h"
|
#include "gpgme.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -51,9 +52,14 @@ static struct engine_ops *engine_ops[] =
|
|||||||
#endif
|
#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. */
|
/* Get the file name of the engine for PROTOCOL. */
|
||||||
static const char *
|
static char *
|
||||||
engine_get_file_name (gpgme_protocol_t proto)
|
engine_get_file_name (gpgme_protocol_t proto)
|
||||||
{
|
{
|
||||||
if (proto > DIM (engine_ops))
|
if (proto > DIM (engine_ops))
|
||||||
@ -66,15 +72,16 @@ engine_get_file_name (gpgme_protocol_t proto)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get the version number of the engine for PROTOCOL. */
|
/* Get a malloced string containing the version number of the engine
|
||||||
static const char *
|
for PROTOCOL. */
|
||||||
engine_get_version (gpgme_protocol_t proto)
|
static char *
|
||||||
|
engine_get_version (gpgme_protocol_t proto, const char *file_name)
|
||||||
{
|
{
|
||||||
if (proto > DIM (engine_ops))
|
if (proto > DIM (engine_ops))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (engine_ops[proto] && engine_ops[proto]->get_version)
|
if (engine_ops[proto] && engine_ops[proto]->get_version)
|
||||||
return (*engine_ops[proto]->get_version) ();
|
return (*engine_ops[proto]->get_version) (file_name);
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -98,21 +105,45 @@ engine_get_req_version (gpgme_protocol_t proto)
|
|||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
gpgme_engine_check_version (gpgme_protocol_t proto)
|
gpgme_engine_check_version (gpgme_protocol_t proto)
|
||||||
{
|
{
|
||||||
return _gpgme_compare_versions (engine_get_version (proto),
|
int result;
|
||||||
engine_get_req_version (proto))
|
char *engine_version = engine_get_version (proto, NULL);
|
||||||
? 0 : gpg_error (GPG_ERR_INV_ENGINE);
|
|
||||||
|
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
|
/* Get the information about the configured and installed engines. A
|
||||||
pointer to the first engine in the statically allocated linked list
|
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_error_t
|
||||||
gpgme_get_engine_info (gpgme_engine_info_t *info)
|
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);
|
LOCK (engine_info_lock);
|
||||||
if (!engine_info)
|
if (!engine_info)
|
||||||
{
|
{
|
||||||
@ -123,70 +154,238 @@ gpgme_get_engine_info (gpgme_engine_info_t *info)
|
|||||||
|
|
||||||
for (proto = 0; proto < DIM (proto_list); proto++)
|
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)
|
if (!file_name)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
file_name = strdup (file_name);
|
||||||
|
|
||||||
*lastp = malloc (sizeof (*engine_info));
|
*lastp = malloc (sizeof (*engine_info));
|
||||||
if (!*lastp)
|
if (!*lastp || !file_name)
|
||||||
{
|
{
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
|
|
||||||
while (engine_info)
|
_gpgme_engine_info_release (engine_info);
|
||||||
{
|
engine_info = NULL;
|
||||||
gpgme_engine_info_t next_info = engine_info->next;
|
|
||||||
free (engine_info);
|
if (file_name)
|
||||||
engine_info = next_info;
|
free (file_name);
|
||||||
}
|
|
||||||
UNLOCK (engine_info_lock);
|
UNLOCK (engine_info_lock);
|
||||||
return gpg_error_from_errno (saved_errno);
|
return gpg_error_from_errno (saved_errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
(*lastp)->protocol = proto_list[proto];
|
(*lastp)->protocol = proto_list[proto];
|
||||||
(*lastp)->file_name = file_name;
|
(*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)->req_version = engine_get_req_version (proto_list[proto]);
|
||||||
(*lastp)->next = NULL;
|
(*lastp)->next = NULL;
|
||||||
lastp = &(*lastp)->next;
|
lastp = &(*lastp)->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UNLOCK (engine_info_lock);
|
|
||||||
*info = engine_info;
|
*info = engine_info;
|
||||||
|
UNLOCK (engine_info_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
while (info && info->protocol != proto)
|
||||||
|
info = info->next;
|
||||||
|
|
||||||
|
if (!info)
|
||||||
|
return gpg_error (GPG_ERR_INV_ENGINE);
|
||||||
|
|
||||||
|
/* 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_error_t
|
||||||
_gpgme_engine_new (gpgme_protocol_t proto, engine_t *r_engine,
|
_gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine,
|
||||||
const char *lc_ctype, const char *lc_messages)
|
const char *lc_ctype, const char *lc_messages)
|
||||||
{
|
{
|
||||||
engine_t engine;
|
engine_t engine;
|
||||||
|
|
||||||
const char *file_name;
|
if (!info->file_name || !info->version)
|
||||||
const char *version;
|
|
||||||
|
|
||||||
if (proto > DIM (engine_ops))
|
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
|
||||||
|
|
||||||
if (!engine_ops[proto])
|
|
||||||
return gpg_error (GPG_ERR_INV_ENGINE);
|
|
||||||
|
|
||||||
file_name = engine_get_file_name (proto);
|
|
||||||
version = engine_get_version (proto);
|
|
||||||
if (!file_name || !version)
|
|
||||||
return gpg_error (GPG_ERR_INV_ENGINE);
|
return gpg_error (GPG_ERR_INV_ENGINE);
|
||||||
|
|
||||||
engine = calloc (1, sizeof *engine);
|
engine = calloc (1, sizeof *engine);
|
||||||
if (!engine)
|
if (!engine)
|
||||||
return gpg_error_from_errno (errno);
|
return gpg_error_from_errno (errno);
|
||||||
|
|
||||||
engine->ops = engine_ops[proto];
|
engine->ops = engine_ops[info->protocol];
|
||||||
if (engine_ops[proto]->new)
|
if (engine->ops->new)
|
||||||
{
|
{
|
||||||
gpgme_error_t err = (*engine_ops[proto]->new) (&engine->engine,
|
gpgme_error_t err = (*engine->ops->new) (&engine->engine,
|
||||||
lc_ctype,
|
info->file_name, info->home_dir,
|
||||||
lc_messages);
|
lc_ctype, lc_messages);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
free (engine);
|
free (engine);
|
||||||
|
@ -35,7 +35,14 @@ typedef gpgme_error_t (*engine_command_handler_t) (void *priv,
|
|||||||
const char *keyword,
|
const char *keyword,
|
||||||
int fd);
|
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,
|
engine_t *r_engine,
|
||||||
const char *lc_ctype,
|
const char *lc_ctype,
|
||||||
const char *lc_messages);
|
const char *lc_messages);
|
||||||
|
@ -50,6 +50,14 @@ gpgme_new (gpgme_ctx_t *r_ctx)
|
|||||||
ctx = calloc (1, sizeof *ctx);
|
ctx = calloc (1, sizeof *ctx);
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return gpg_error_from_errno (errno);
|
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->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
|
||||||
ctx->include_certs = 1;
|
ctx->include_certs = 1;
|
||||||
ctx->protocol = GPGME_PROTOCOL_OpenPGP;
|
ctx->protocol = GPGME_PROTOCOL_OpenPGP;
|
||||||
@ -62,6 +70,7 @@ gpgme_new (gpgme_ctx_t *r_ctx)
|
|||||||
if (!ctx->lc_ctype)
|
if (!ctx->lc_ctype)
|
||||||
{
|
{
|
||||||
UNLOCK (def_lc_lock);
|
UNLOCK (def_lc_lock);
|
||||||
|
_gpgme_engine_info_release (ctx->engine_info);
|
||||||
free (ctx);
|
free (ctx);
|
||||||
return gpg_error_from_errno (errno);
|
return gpg_error_from_errno (errno);
|
||||||
}
|
}
|
||||||
@ -77,6 +86,7 @@ gpgme_new (gpgme_ctx_t *r_ctx)
|
|||||||
UNLOCK (def_lc_lock);
|
UNLOCK (def_lc_lock);
|
||||||
if (ctx->lc_ctype)
|
if (ctx->lc_ctype)
|
||||||
free (ctx->lc_ctype);
|
free (ctx->lc_ctype);
|
||||||
|
_gpgme_engine_info_release (ctx->engine_info);
|
||||||
free (ctx);
|
free (ctx);
|
||||||
return gpg_error_from_errno (errno);
|
return gpg_error_from_errno (errno);
|
||||||
}
|
}
|
||||||
@ -120,6 +130,7 @@ gpgme_release (gpgme_ctx_t ctx)
|
|||||||
free (ctx->lc_ctype);
|
free (ctx->lc_ctype);
|
||||||
if (ctx->lc_messages)
|
if (ctx->lc_messages)
|
||||||
free (ctx->lc_messages);
|
free (ctx->lc_messages);
|
||||||
|
_gpgme_engine_info_release (ctx->engine_info);
|
||||||
free (ctx);
|
free (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,6 +400,29 @@ gpgme_set_locale (gpgme_ctx_t ctx, int category, const char *value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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 *
|
const char *
|
||||||
gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
|
gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
|
||||||
|
@ -412,13 +412,16 @@ struct _gpgme_engine_info
|
|||||||
gpgme_protocol_t protocol;
|
gpgme_protocol_t protocol;
|
||||||
|
|
||||||
/* The file name of the engine binary. */
|
/* The file name of the engine binary. */
|
||||||
const char *file_name;
|
char *file_name;
|
||||||
|
|
||||||
/* The version string of the installed engine. */
|
/* The version string of the installed engine. */
|
||||||
const char *version;
|
char *version;
|
||||||
|
|
||||||
/* The minimum version required for GPGME. */
|
/* The minimum version required for GPGME. */
|
||||||
const char *req_version;
|
const char *req_version;
|
||||||
|
|
||||||
|
/* The home directory used, or NULL if default. */
|
||||||
|
char *home_dir;
|
||||||
};
|
};
|
||||||
typedef struct _gpgme_engine_info *gpgme_engine_info_t;
|
typedef struct _gpgme_engine_info *gpgme_engine_info_t;
|
||||||
|
|
||||||
@ -741,6 +744,19 @@ void gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *cb,
|
|||||||
locale if CTX is a null pointer. */
|
locale if CTX is a null pointer. */
|
||||||
gpgme_error_t gpgme_set_locale (gpgme_ctx_t ctx, int category,
|
gpgme_error_t gpgme_set_locale (gpgme_ctx_t ctx, int category,
|
||||||
const char *value);
|
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
|
/* Return a statically allocated string with the name of the public
|
||||||
key algorithm ALGO, or NULL if that name is not known. */
|
key algorithm ALGO, or NULL if that name is not known. */
|
||||||
@ -1501,9 +1517,18 @@ int gpgme_trust_item_get_int_attr (gpgme_trust_item_t item, _gpgme_attr_t what,
|
|||||||
/* Check that the library fulfills the version requirement. */
|
/* Check that the library fulfills the version requirement. */
|
||||||
const char *gpgme_check_version (const char *req_version);
|
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);
|
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. */
|
/* Engine support functions. */
|
||||||
|
|
||||||
|
@ -18,6 +18,15 @@
|
|||||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
# 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 {
|
GPGME_1.0 {
|
||||||
global:
|
global:
|
||||||
gpgme_check_version;
|
gpgme_check_version;
|
||||||
|
@ -66,17 +66,26 @@ gpgme_error_t
|
|||||||
_gpgme_op_reset (gpgme_ctx_t ctx, int type)
|
_gpgme_op_reset (gpgme_ctx_t ctx, int type)
|
||||||
{
|
{
|
||||||
gpgme_error_t err = 0;
|
gpgme_error_t err = 0;
|
||||||
|
gpgme_engine_info_t info;
|
||||||
struct gpgme_io_cbs io_cbs;
|
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);
|
_gpgme_release_result (ctx);
|
||||||
|
|
||||||
/* Create an engine object. */
|
|
||||||
if (ctx->engine)
|
if (ctx->engine)
|
||||||
{
|
{
|
||||||
_gpgme_engine_release (ctx->engine);
|
_gpgme_engine_release (ctx->engine);
|
||||||
ctx->engine = NULL;
|
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);
|
ctx->lc_ctype, ctx->lc_messages);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
@ -136,7 +136,9 @@ void _gpgme_op_trustlist_event_cb (void *data, gpgme_event_io_t type,
|
|||||||
|
|
||||||
|
|
||||||
/*-- version.c --*/
|
/*-- version.c --*/
|
||||||
const char *_gpgme_compare_versions (const char *my_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);
|
const char *req_version);
|
||||||
char *_gpgme_get_program_version (const char *const path);
|
char *_gpgme_get_program_version (const char *const path);
|
||||||
|
|
||||||
|
@ -66,6 +66,8 @@ struct fd_data_map_s
|
|||||||
|
|
||||||
struct engine_gpg
|
struct engine_gpg
|
||||||
{
|
{
|
||||||
|
char *file_name;
|
||||||
|
|
||||||
struct arg_and_data_s *arglist;
|
struct arg_and_data_s *arglist;
|
||||||
struct arg_and_data_s **argtail;
|
struct arg_and_data_s **argtail;
|
||||||
|
|
||||||
@ -224,17 +226,11 @@ add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *
|
static char *
|
||||||
gpg_get_version (void)
|
gpg_get_version (const char *file_name)
|
||||||
{
|
{
|
||||||
static const char *gpg_version;
|
return _gpgme_get_program_version (file_name ? file_name
|
||||||
DEFINE_STATIC_LOCK (gpg_version_lock);
|
: _gpgme_get_gpg_path ());
|
||||||
|
|
||||||
LOCK (gpg_version_lock);
|
|
||||||
if (!gpg_version)
|
|
||||||
gpg_version = _gpgme_get_program_version (_gpgme_get_gpg_path ());
|
|
||||||
UNLOCK (gpg_version_lock);
|
|
||||||
return gpg_version;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -313,6 +309,9 @@ gpg_release (void *engine)
|
|||||||
|
|
||||||
gpg_cancel (engine);
|
gpg_cancel (engine);
|
||||||
|
|
||||||
|
if (gpg->file_name)
|
||||||
|
free (gpg->file_name);
|
||||||
|
|
||||||
while (gpg->arglist)
|
while (gpg->arglist)
|
||||||
{
|
{
|
||||||
struct arg_and_data_s *next = gpg->arglist->next;
|
struct arg_and_data_s *next = gpg->arglist->next;
|
||||||
@ -336,7 +335,8 @@ gpg_release (void *engine)
|
|||||||
|
|
||||||
|
|
||||||
static gpgme_error_t
|
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;
|
engine_gpg_t gpg;
|
||||||
gpgme_error_t rc = 0;
|
gpgme_error_t rc = 0;
|
||||||
@ -345,6 +345,16 @@ gpg_new (void **engine, const char *lc_ctype, const char *lc_messages)
|
|||||||
if (!gpg)
|
if (!gpg)
|
||||||
return gpg_error_from_errno (errno);
|
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->argtail = &gpg->arglist;
|
||||||
gpg->status.fd[0] = -1;
|
gpg->status.fd[0] = -1;
|
||||||
gpg->status.fd[1] = -1;
|
gpg->status.fd[1] = -1;
|
||||||
@ -380,6 +390,16 @@ gpg_new (void **engine, const char *lc_ctype, const char *lc_messages)
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
gpg->status.eof = 0;
|
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");
|
rc = add_arg (gpg, "--status-fd");
|
||||||
if (rc)
|
if (rc)
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -1043,7 +1063,7 @@ start (engine_gpg_t gpg)
|
|||||||
if (!gpg)
|
if (!gpg)
|
||||||
return gpg_error (GPG_ERR_INV_VALUE);
|
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);
|
return gpg_error (GPG_ERR_INV_ENGINE);
|
||||||
|
|
||||||
rc = build_argv (gpg);
|
rc = build_argv (gpg);
|
||||||
@ -1101,7 +1121,8 @@ start (engine_gpg_t gpg)
|
|||||||
fd_parent_list[n].fd = -1;
|
fd_parent_list[n].fd = -1;
|
||||||
fd_parent_list[n].dup_to = -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);
|
gpg->argv, fd_child_list, fd_parent_list);
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
free (fd_child_list);
|
free (fd_child_list);
|
||||||
|
@ -103,7 +103,9 @@ parse_version_string (const char *str, int *major, int *minor, int *micro)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *
|
/* Return true if MY_VERSION is at least REQ_VERSION, and false
|
||||||
|
otherwise. */
|
||||||
|
int
|
||||||
_gpgme_compare_versions (const char *my_version,
|
_gpgme_compare_versions (const char *my_version,
|
||||||
const char *rq_version)
|
const char *rq_version)
|
||||||
{
|
{
|
||||||
@ -112,17 +114,17 @@ _gpgme_compare_versions (const char *my_version,
|
|||||||
const char *my_plvl, *rq_plvl;
|
const char *my_plvl, *rq_plvl;
|
||||||
|
|
||||||
if (!rq_version)
|
if (!rq_version)
|
||||||
return my_version;
|
return 1;
|
||||||
if (!my_version)
|
if (!my_version)
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
my_plvl = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
|
my_plvl = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
|
||||||
if (!my_plvl)
|
if (!my_plvl)
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
rq_plvl = parse_version_string (rq_version, &rq_major, &rq_minor, &rq_micro);
|
rq_plvl = parse_version_string (rq_version, &rq_major, &rq_minor, &rq_micro);
|
||||||
if (!rq_plvl)
|
if (!rq_plvl)
|
||||||
return NULL;
|
return 0;
|
||||||
|
|
||||||
if (my_major > rq_major
|
if (my_major > rq_major
|
||||||
|| (my_major == rq_major && my_minor > rq_minor)
|
|| (my_major == rq_major && my_minor > rq_minor)
|
||||||
@ -130,9 +132,9 @@ _gpgme_compare_versions (const char *my_version,
|
|||||||
&& my_micro > rq_micro)
|
&& my_micro > rq_micro)
|
||||||
|| (my_major == rq_major && my_minor == rq_minor
|
|| (my_major == rq_major && my_minor == rq_minor
|
||||||
&& my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0))
|
&& my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0))
|
||||||
return my_version;
|
return 1;
|
||||||
|
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -149,7 +151,7 @@ const char *
|
|||||||
gpgme_check_version (const char *req_version)
|
gpgme_check_version (const char *req_version)
|
||||||
{
|
{
|
||||||
do_subsystem_inits ();
|
do_subsystem_inits ();
|
||||||
return _gpgme_compare_versions (VERSION, req_version);
|
return _gpgme_compare_versions (VERSION, req_version) ? VERSION : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user