doc/
authorMarcus Brinkmann <mb@g10code.com>
Thu, 30 Jan 2003 13:11:25 +0000 (13:11 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Thu, 30 Jan 2003 13:11:25 +0000 (13:11 +0000)
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.

doc/ChangeLog
doc/gpgme.texi
gpgme/ChangeLog
gpgme/engine-backend.h
gpgme/engine.c
gpgme/engine.h
gpgme/gpgme.h
gpgme/version.c
tests/ChangeLog
tests/t-engine-info.c

index 8487dc12c89352bf9e77b7e63061bd0194e33aea..4b695d71ff168ea257d312d0d786441bb920d0dd 100644 (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.
 
index 96f9184f37cd7d0a23e90db15574f75d50b9c59a..88472cc3abc88aad2baffc9076197de2216b7a2d 100644 (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.
 
index b143582e8de85cd91e7d4a5083b7f465491da0df..cdeec938604128a7b627cfd0417bf38e5ceaa31b 100644 (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.
index b291f05a6ec5b22d0961539a022da582d1a1d384..c97297d7b6dabfda735647a21871deeac17ea926 100644 (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);
index 131a0de86c5eb59a5d544fe04d9af5d9db9b4c1c..fdadef7c9431d2f38b7fddb8e67ca8817aeb72b2 100644 (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)
+\f
+/* 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;
 }
 
-
+\f
 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);
index 746de6f1ee36c7c80ae02815d2bdadcd9d396cbf..de782dad2c1a4cff833186d1012ad29f08b1c153 100644 (file)
 
 #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,
index 341a32ddd5c295cc6cb361eba334fe8b5cf5f8ec..dcc1eb0461bd1b7612611e89161d4244d711363a 100644 (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;
index 1af91cf67d1aa5282733d1f3d404f4f561c77064..68f085e0223e499275606f2766f2572a9fc0c2c1 100644 (file)
 #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"
 
+\f
+/* 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;
-}
-
 \f
 #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]);
index 425884b9123b880ca0407cbd16ec9ea5e842fa34..2ff2aff5cb5f246ababadf4cf1f1b482270f931d 100644 (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.
index e4d0eda9e4e27dd5d9eda2fed689e419cf0ebc5e..ef69b1f55cf6a83ab7d0256fca15eecdc2d907fe 100644 (file)
@@ -43,7 +43,7 @@
 \f
 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))