diff options
| -rw-r--r-- | doc/ChangeLog | 3 | ||||
| -rw-r--r-- | doc/gpgme.texi | 4 | ||||
| -rw-r--r-- | gpgme/ChangeLog | 21 | ||||
| -rw-r--r-- | gpgme/engine-backend.h | 2 | ||||
| -rw-r--r-- | gpgme/engine.c | 97 | ||||
| -rw-r--r-- | gpgme/engine.h | 12 | ||||
| -rw-r--r-- | gpgme/gpgme.h | 4 | ||||
| -rw-r--r-- | gpgme/version.c | 181 | ||||
| -rw-r--r-- | tests/ChangeLog | 2 | ||||
| -rw-r--r-- | tests/t-engine-info.c | 8 | 
10 files changed, 165 insertions, 169 deletions
| diff --git a/doc/ChangeLog b/doc/ChangeLog index 8487dc12..4b695d71 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,8 @@  2003-01-30  Marcus Brinkmann  <[email protected]> +	* gpgme.texi (Engine Information): Rename member part to +	file_name. +  	* gpgme.texi (Protocols and Engines): Document  	gpgme_get_protocol_name. diff --git a/doc/gpgme.texi b/doc/gpgme.texi index 96f9184f..88472cc3 100644 --- a/doc/gpgme.texi +++ b/doc/gpgme.texi @@ -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. diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index b143582e..cdeec938 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,5 +1,26 @@  2003-01-30  Marcus Brinkmann  <[email protected]> +	* 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. diff --git a/gpgme/engine-backend.h b/gpgme/engine-backend.h index b291f05a..c97297d7 100644 --- a/gpgme/engine-backend.h +++ b/gpgme/engine-backend.h @@ -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); diff --git a/gpgme/engine.c b/gpgme/engine.c index 131a0de8..fdadef7c 100644 --- a/gpgme/engine.c +++ b/gpgme/engine.c @@ -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); diff --git a/gpgme/engine.h b/gpgme/engine.h index 746de6f1..de782dad 100644 --- a/gpgme/engine.h +++ b/gpgme/engine.h @@ -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, diff --git a/gpgme/gpgme.h b/gpgme/gpgme.h index 341a32dd..dcc1eb04 100644 --- a/gpgme/gpgme.h +++ b/gpgme/gpgme.h @@ -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; diff --git a/gpgme/version.c b/gpgme/version.c index 1af91cf6..68f085e0 100644 --- a/gpgme/version.c +++ b/gpgme/version.c @@ -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]); diff --git a/tests/ChangeLog b/tests/ChangeLog index 425884b9..2ff2aff5 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,7 @@  2003-01-30  Marcus Brinkmann  <[email protected]> +	* 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. diff --git a/tests/t-engine-info.c b/tests/t-engine-info.c index e4d0eda9..ef69b1f5 100644 --- a/tests/t-engine-info.c +++ b/tests/t-engine-info.c @@ -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)) | 
