2003-01-30  Marcus Brinkmann  <marcus@g10code.de>

	* gpgme.texi (Engine Information): Rename member part to
	file_name.

gpgme/
2003-01-30  Marcus Brinkmann  <marcus@g10code.de>

	* engine-backend.h (struct engine_ops): Rename get_path to
	get_file_name.
	* gpgme.h (struct _gpgme_engine_info): Rename member path to
	file_name.
	* version.c: Do not include <stdio.h>, <stdlib.h>, context.h and
	util.h.  Other clean ups.
	(parse_version_number): Protect more seriously against
	overflow.
	(gpgme_get_engine_info): Move to ...
	* engine.c (gpgme_get_engine_info): ... here.
	(_gpgme_engine_get_info): Function removed.
	(_gpgme_engine_get_path): Make static and rename to ...
	(engine_get_file_name): .. this.
	(_gpgme_engine_get_version): Make static and rename to ...
	(engine_get_version): ... this.
	(_gpgme_engine_get_req_version): Make static and rename to ...
	(engine_get_req_version): ... this.
	* engine.h (_gpgme_engine_get_path, _gpgme_engine_get_version,
	_gpgme_engine_req_version, _gpgme_engine_get_info.): Remove
	prototypes.

tests/
2003-01-30  Marcus Brinkmann  <marcus@g10code.de>

	* t-engine-info.c: Use file_name instead path throughout.
This commit is contained in:
Marcus Brinkmann 2003-01-30 13:11:25 +00:00
parent feb78b25ec
commit d102681aef
10 changed files with 165 additions and 169 deletions

View File

@ -1,5 +1,8 @@
2003-01-30 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Engine Information): Rename member part to
file_name.
* gpgme.texi (Protocols and Engines): Document
gpgme_get_protocol_name.

View File

@ -632,8 +632,8 @@ This is the protocol for which the crypo engine is used. You can
convert this to a string with @code{gpgme_get_protocol_name} for
printing.
@item const char *path
This is a string holding the path to the executable of the crypto
@item const char *file_name
This is a string holding the file name of the executable of the crypto
engine. Currently, it is never @code{NULL}, but using @code{NULL} is
reserved for future use, so always check before you use it.

View File

@ -1,5 +1,26 @@
2003-01-30 Marcus Brinkmann <marcus@g10code.de>
* engine-backend.h (struct engine_ops): Rename get_path to
get_file_name.
* gpgme.h (struct _gpgme_engine_info): Rename member path to
file_name.
* version.c: Do not include <stdio.h>, <stdlib.h>, context.h and
util.h. Other clean ups.
(parse_version_number): Protect more seriously against
overflow.
(gpgme_get_engine_info): Move to ...
* engine.c (gpgme_get_engine_info): ... here.
(_gpgme_engine_get_info): Function removed.
(_gpgme_engine_get_path): Make static and rename to ...
(engine_get_file_name): .. this.
(_gpgme_engine_get_version): Make static and rename to ...
(engine_get_version): ... this.
(_gpgme_engine_get_req_version): Make static and rename to ...
(engine_get_req_version): ... this.
* engine.h (_gpgme_engine_get_path, _gpgme_engine_get_version,
_gpgme_engine_req_version, _gpgme_engine_get_info.): Remove
prototypes.
* gpgme.h (enum GpgmeProtocol): Remove GPGME_PROTOCOL_AUTO.
* gpgme.c (gpgme_set_protocol): Don't handle GPGME_PROTOCOL_AUTO.
(gpgme_get_protocol_name): New function.

View File

@ -32,7 +32,7 @@
struct engine_ops
{
/* Static functions. */
const char *(*get_path) (void);
const char *(*get_file_name) (void);
const char *(*get_version) (void);
const char *(*get_req_version) (void);
GpgmeError (*new) (void **r_engine);

View File

@ -50,24 +50,24 @@ static struct engine_ops *engine_ops[] =
#endif
};
/* Get the path of the engine for PROTOCOL. */
const char *
_gpgme_engine_get_path (GpgmeProtocol proto)
/* Get the file name of the engine for PROTOCOL. */
static const char *
engine_get_file_name (GpgmeProtocol proto)
{
if (proto > DIM (engine_ops))
return NULL;
if (engine_ops[proto] && engine_ops[proto]->get_path)
return (*engine_ops[proto]->get_path) ();
if (engine_ops[proto] && engine_ops[proto]->get_file_name)
return (*engine_ops[proto]->get_file_name) ();
else
return NULL;
}
/* Get the version number of the engine for PROTOCOL. */
const char *
_gpgme_engine_get_version (GpgmeProtocol proto)
static const char *
engine_get_version (GpgmeProtocol proto)
{
if (proto > DIM (engine_ops))
return NULL;
@ -80,8 +80,8 @@ _gpgme_engine_get_version (GpgmeProtocol proto)
/* Get the required version number of the engine for PROTOCOL. */
const char *
_gpgme_engine_get_req_version (GpgmeProtocol proto)
static const char *
engine_get_req_version (GpgmeProtocol proto)
{
if (proto > DIM (engine_ops))
return NULL;
@ -97,57 +97,68 @@ _gpgme_engine_get_req_version (GpgmeProtocol proto)
GpgmeError
gpgme_engine_check_version (GpgmeProtocol proto)
{
return _gpgme_compare_versions (_gpgme_engine_get_version (proto),
_gpgme_engine_get_req_version (proto))
return _gpgme_compare_versions (engine_get_version (proto),
engine_get_req_version (proto))
? 0 : GPGME_Invalid_Engine;
}
const char *
_gpgme_engine_get_info (GpgmeProtocol proto)
/* 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. */
GpgmeError
gpgme_get_engine_info (GpgmeEngineInfo *info)
{
static const char fmt[] = " <engine>\n"
" <protocol>%s</protocol>\n"
" <version>%s</version>\n"
" <path>%s</path>\n"
" </engine>\n";
static const char *const strproto[3] = { "OpenPGP", "CMS", NULL };
static const char *engine_info[3]; /* FIXME: MAX_PROTO + 1*/
static GpgmeEngineInfo engine_info;
DEFINE_STATIC_LOCK (engine_info_lock);
if (proto > 2 /* FIXME MAX_PROTO */ || !strproto[proto])
return NULL;
LOCK (engine_info_lock);
if (!engine_info[proto])
if (!engine_info)
{
const char *path = _gpgme_engine_get_path (proto);
const char *version = _gpgme_engine_get_version (proto);
GpgmeEngineInfo *lastp = &engine_info;
GpgmeProtocol proto_list[] = { GPGME_PROTOCOL_OpenPGP,
GPGME_PROTOCOL_CMS };
int proto;
if (path && version)
for (proto = 0; proto < DIM (proto_list); proto++)
{
char *info = malloc (strlen (fmt) + strlen (strproto[proto])
+ strlen (path) + strlen (version) + 1);
if (!info)
info = " <engine>\n"
" <error>Out of core</error>\n"
" </engine>";
else
sprintf (info, fmt, strproto[proto], version, path);
engine_info[proto] = info;
const char *file_name = engine_get_file_name (proto_list[proto]);
if (!file_name)
continue;
*lastp = malloc (sizeof (*engine_info));
if (!*lastp)
{
while (engine_info)
{
GpgmeEngineInfo next_info = engine_info->next;
free (engine_info);
engine_info = next_info;
}
UNLOCK (engine_info_lock);
return GPGME_Out_Of_Core;
}
(*lastp)->protocol = proto_list[proto];
(*lastp)->file_name = file_name;
(*lastp)->version = engine_get_version (proto_list[proto]);
(*lastp)->req_version = engine_get_req_version (proto_list[proto]);
lastp = &(*lastp)->next;
}
}
UNLOCK (engine_info_lock);
return engine_info[proto];
*info = engine_info;
return 0;
}
GpgmeError
_gpgme_engine_new (GpgmeProtocol proto, EngineObject *r_engine)
{
EngineObject engine;
const char *path;
const char *file_name;
const char *version;
if (proto > DIM (engine_ops))
@ -156,9 +167,9 @@ _gpgme_engine_new (GpgmeProtocol proto, EngineObject *r_engine)
if (!engine_ops[proto])
return GPGME_Invalid_Engine;
path = _gpgme_engine_get_path (proto);
version = _gpgme_engine_get_version (proto);
if (!path || !version)
file_name = engine_get_file_name (proto);
version = engine_get_version (proto);
if (!file_name || !version)
return GPGME_Invalid_Engine;
engine = calloc (1, sizeof *engine);

View File

@ -23,18 +23,6 @@
#include "types.h"
/* Get the path of the engine for PROTOCOL. */
const char *_gpgme_engine_get_path (GpgmeProtocol proto);
/* Get the version number of the engine for PROTOCOL. */
const char *_gpgme_engine_get_version (GpgmeProtocol proto);
/* Get the version number of the engine for PROTOCOL. */
const char *_gpgme_engine_req_version (GpgmeProtocol proto);
/* Verify the version requirement for the engine for PROTOCOL. */
const char *_gpgme_engine_get_info (GpgmeProtocol proto);
GpgmeError _gpgme_engine_new (GpgmeProtocol proto, EngineObject *r_engine);
void _gpgme_engine_release (EngineObject engine);
void _gpgme_engine_set_status_handler (EngineObject engine,

View File

@ -319,8 +319,8 @@ struct _gpgme_engine_info
/* The protocol ID. */
GpgmeProtocol protocol;
/* The path to the engine binary. */
const char *path;
/* The file name of the engine binary. */
const char *file_name;
/* The version string of the installed engine. */
const char *version;

View File

@ -21,19 +21,25 @@
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include "gpgme.h"
#include "context.h"
#include "sema.h"
#include "util.h"
#include "key.h" /* for key_cache_init */
#include "io.h"
/* For _gpgme_sema_subsystem_init (). */
#include "sema.h"
/* For _gpgme_key_cache_init (). */
#include "key.h"
/* Bootstrap the subsystems needed for concurrent operation. This
must be done once at startup. We can not guarantee this using a
lock, though, because the semaphore subsystem needs to be
initialized itself before it can be used. So we expect that the
user performs the necessary syncrhonization. */
static void
do_subsystem_inits (void)
{
@ -41,92 +47,106 @@ do_subsystem_inits (void)
if (done)
return;
_gpgme_sema_subsystem_init ();
_gpgme_key_cache_init ();
done = 1;
}
static const char*
parse_version_number (const char *s, int *number)
/* Read the next number in the version string STR and return it in
*NUMBER. Return a pointer to the tail of STR after parsing, or
*NULL if the version string was invalid. */
static const char *
parse_version_number (const char *str, int *number)
{
#define MAXVAL ((INT_MAX - 10) / 10)
int val = 0;
if (*s == '0' && isdigit(s[1]))
return NULL; /* Leading zeros are not allowed. */
for (; isdigit(*s); s++)
/* Leading zeros are not allowed. */
if (*str == '0' && isdigit(str[1]))
return NULL;
while (isdigit (*str) && val <= MAXVAL)
{
val *= 10;
val += *s - '0';
val += *(str++) - '0';
}
*number = val;
return val < 0 ? NULL : s;
return val > MAXVAL ? NULL : str;
}
/* Parse the version string STR in the format MAJOR.MINOR.MICRO (for
example, 9.3.2) and return the components in MAJOR, MINOR and MICRO
as integers. The function returns the tail of the string that
follows the version number. This might be te empty string if there
is nothing following the version number, or a patchlevel. The
function returns NULL if the version string is not valid. */
static const char *
parse_version_string (const char *s, int *major, int *minor, int *micro)
parse_version_string (const char *str, int *major, int *minor, int *micro)
{
s = parse_version_number (s, major);
if (!s || *s != '.')
str = parse_version_number (str, major);
if (!str || *str != '.')
return NULL;
s++;
s = parse_version_number (s, minor);
if (!s || *s != '.')
str++;
str = parse_version_number (str, minor);
if (!str || *str != '.')
return NULL;
s++;
s = parse_version_number (s, micro);
if (!s)
str++;
str = parse_version_number (str, micro);
if (!str)
return NULL;
return s; /* Patchlevel. */
/* A patchlevel might follow. */
return str;
}
const char *
_gpgme_compare_versions (const char *my_version,
const char *req_version)
const char *rq_version)
{
int my_major, my_minor, my_micro;
int rq_major, rq_minor, rq_micro;
const char *my_plvl, *rq_plvl;
if (!req_version)
if (!rq_version)
return my_version;
if (!my_version)
return NULL;
my_plvl = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
if (!my_plvl)
return NULL; /* Very strange: our own version is bogus. */
rq_plvl = parse_version_string(req_version,
&rq_major, &rq_minor, &rq_micro);
return NULL;
rq_plvl = parse_version_string (rq_version, &rq_major, &rq_minor, &rq_micro);
if (!rq_plvl)
return NULL; /* Requested version string is invalid. */
return NULL;
if (my_major > rq_major
|| (my_major == rq_major && my_minor > rq_minor)
|| (my_major == rq_major && my_minor > rq_minor)
|| (my_major == rq_major && my_minor == rq_minor
&& 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;
}
&& my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0))
return my_version;
return NULL;
}
/**
* gpgme_check_version:
* @req_version: A string with a version
*
* Check that the the version of the library is at minimum the requested one
* and return the version string; return NULL if the condition is not
* met. If a NULL is passed to this function, no check is done and
* the version string is simply returned. It is a pretty good idea to
* run this function as soon as possible, because it also intializes
* some subsystems. In a multithreaded environment if should be called
* before the first thread is created.
*
* Return value: The version string or NULL
**/
/* Check that the the version of the library is at minimum the
requested one and return the version string; return NULL if the
condition is not met. If a NULL is passed to this function, no
check is done and the version string is simply returned.
This function must be run once at startup, as it also initializes
some subsystems. Its invocation must be synchronized against
calling any of the other functions in a multi-threaded
environments. */
const char *
gpgme_check_version (const char *req_version)
{
@ -134,76 +154,27 @@ gpgme_check_version (const char *req_version)
return _gpgme_compare_versions (VERSION, req_version);
}
/* 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. */
GpgmeError
gpgme_get_engine_info (GpgmeEngineInfo *info)
{
static GpgmeEngineInfo engine_info;
DEFINE_STATIC_LOCK (engine_info_lock);
LOCK (engine_info_lock);
if (!engine_info)
{
GpgmeEngineInfo *lastp = &engine_info;
GpgmeProtocol proto_list[] = { GPGME_PROTOCOL_OpenPGP,
GPGME_PROTOCOL_CMS };
int proto;
for (proto = 0; proto < DIM (proto_list); proto++)
{
const char *path = _gpgme_engine_get_path (proto_list[proto]);
if (!path)
continue;
*lastp = malloc (sizeof (*engine_info));
if (!*lastp)
{
while (engine_info)
{
GpgmeEngineInfo next_info = engine_info->next;
free (engine_info);
engine_info = next_info;
}
UNLOCK (engine_info_lock);
return GPGME_Out_Of_Core;
}
(*lastp)->protocol = proto_list[proto];
(*lastp)->path = path;
(*lastp)->version = _gpgme_engine_get_version (proto_list[proto]);
(*lastp)->req_version
= _gpgme_engine_get_req_version (proto_list[proto]);
lastp = &(*lastp)->next;
}
}
UNLOCK (engine_info_lock);
*info = engine_info;
return 0;
}
#define LINELENGTH 80
/* Retrieve the version number from the --version output of the
program FILE_NAME. */
char *
_gpgme_get_program_version (const char *const path)
_gpgme_get_program_version (const char *const file_name)
{
char line[LINELENGTH] = "";
int linelen = 0;
char *mark = NULL;
int rp[2];
int nread;
char *argv[] = {NULL /* path */, "--version", 0};
char *argv[] = {NULL /* file_name */, "--version", 0};
struct spawn_fd_item_s pfd[] = { {0, -1}, {-1, -1} };
struct spawn_fd_item_s cfd[] = { {-1, 1 /* STDOUT_FILENO */}, {-1, -1} };
int status;
if (!path)
if (!file_name)
return NULL;
argv[0] = (char *) path;
argv[0] = (char *) file_name;
if (_gpgme_io_pipe (rp, 1) < 0)
return NULL;
@ -211,7 +182,7 @@ _gpgme_get_program_version (const char *const path)
pfd[0].fd = rp[1];
cfd[0].fd = rp[1];
status = _gpgme_io_spawn (path, argv, cfd, pfd);
status = _gpgme_io_spawn (file_name, argv, cfd, pfd);
if (status < 0)
{
_gpgme_io_close (rp[0]);

View File

@ -1,5 +1,7 @@
2003-01-30 Marcus Brinkmann <marcus@g10code.de>
* t-engine-info.c: Use file_name instead path throughout.
* Makefile.am (TESTS): Add t-engine-info.
* t-engine-info.c: New file.
* gpg/t-encrypt.c (main): Don't print engine info.

View File

@ -43,7 +43,7 @@
void
check_engine_info (GpgmeEngineInfo info, GpgmeProtocol protocol,
const char *path, const char *req_version)
const char *file_name, const char *req_version)
{
if (info->protocol != protocol)
{
@ -51,10 +51,10 @@ check_engine_info (GpgmeEngineInfo info, GpgmeProtocol protocol,
info->protocol, protocol);
exit (1);
}
if (strcmp (info->path, path))
if (strcmp (info->file_name, file_name))
{
fprintf (stderr, "Unexpected path to executable %s (expected %s instead)",
info->path, path);
fprintf (stderr, "Unexpected file name to executable %s (expected %s instead)",
info->file_name, file_name);
exit (1);
}
if (strcmp (info->req_version, req_version))