[git] GnuPG - branch, master, updated. gnupg-2.1.15-314-g0ed6a6d

by Werner Koch cvs at cvs.gnupg.org
Wed Nov 2 18:02:24 CET 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  0ed6a6df5aa421a9c5cdb1e63867f0deee79af9e (commit)
       via  488b183811fc25c1ae49b4730491accf1adf518e (commit)
      from  60ad1a7f37ffc10e601e69a3e2d2bb14af510257 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 0ed6a6df5aa421a9c5cdb1e63867f0deee79af9e
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Nov 2 17:54:32 2016 +0100

    gpgconf: Add command --query-swdb.
    
    * tools/gpgconf.c (aQuerySWDB): New.
    (opts): Add --query-swdb.
    (valid_swdb_name_p): New.
    (query_swdb): New.
    (main): Implement command --query-swdb.
    --
    
    Right now this command is not very useful because dimngr has not yet
    been changed to create the swdb.lst.  For manual tests the swdb.lst
    file from the Net can be used with these additional lines:
    
      .filedate 20161102T130337
      .verified 20161102T150000

diff --git a/doc/tools.texi b/doc/tools.texi
index 199b11e..2d2ccef 100644
--- a/doc/tools.texi
+++ b/doc/tools.texi
@@ -250,6 +250,7 @@ throughout this section.
 * Listing options::        List all options of a component.
 * Changing options::       Changing options of a component.
 * Listing global options:: List all global options.
+* Querying versions::      Get and compare software versions.
 * Files used by gpgconf::  What files are used by gpgconf.
 @end menu
 
@@ -302,6 +303,13 @@ List the global configuration file in a colon separated format.  If
 Run a syntax check on the global configuration file.  If @var{filename}
 is given, check that file instead.
 
+
+ at item --query-swdb @var{package_name} [@var{version_string}]
+Returns the current version for @var{package_name} and if
+ at var{version_string} is given also an indicator on whether an update
+is available.
+
+
 @item --reload [@var{component}]
 @opindex reload
 Reload all or the given component. This is basically the same as sending
@@ -953,6 +961,80 @@ Unknown record types should be ignored.  Note that there is intentionally
 no feature to change the global option file through @command{gpgconf}.
 
 
+ at node Querying versions
+ at subsection Get and compare software versions.
+
+The GnuPG Project operates a server to query the current versions of
+software packages related to GnuPG.  @command{gpgconf} can be used to
+access this online database.  To allow for offline operations, this
+feature works by having @command{dirmngr} download a file from
+ at code{https://versions.gnupg.org}, checking the signature of that file
+and storing the file in the GnuPG home directory.  If
+ at command{gpgconf} is used and @command{dirmngr} is running, it may ask
+ at command{dirmngr} to refresh that file before itself uses the file.
+
+The command @option{--query-swdb} returns information for the given
+package in a colon delimited format:
+
+ at table @var
+
+ at item name
+This is the name of the package as requested.  Note that "gnupg" is a
+special name which is replaced by the actual package implementing this
+version of GnuPG.  For this name it is also not required to specify a
+version because @command{gpgconf} takes its own version in this case.
+
+ at item status
+The status of the software package according to this table:
+ at table @code
+ at item -
+No information available.  This is either because no current version
+has been specified or due to an error.
+ at item ?
+The given name is not known in the online database.
+ at item u
+An update of the software is available.
+ at item c
+The specified version of the software is current.
+ at item n
+The specified version is already newer than the released version.
+ at end table
+
+ at item urgency
+If the value (the empty string should be considered as zero) is
+greater than zero an important update is available.
+
+ at item error
+This returns an @command{gpg-error} error code to distinguish between
+various failure modes.
+
+ at item filedate
+This gives the date of the file with the version numbers in standard
+ISO format (@code{yyyymmddThhmmss}).  The date has been extracted by
+ at command{dirmngr} from the signature of the file.
+
+ at item verified
+This gives the date in ISO format the file was downloaded.  This value
+can be used to evaluate the freshness of the information.
+
+ at item version
+This returns the version string for the requested software from the
+file.
+
+ at item reldate
+This returns the release date in ISO format.
+
+ at item size
+This returns the size of the package as decimal number of bytes.
+
+ at item hash
+This returns a hexified SHA-2 hash of the package.
+
+ at end table
+
+ at noindent
+More fields may be added in future to the output.
+
 
 @mansect files
 @node Files used by gpgconf
@@ -965,6 +1047,12 @@ no feature to change the global option file through @command{gpgconf}.
   If this file exists, it is processed as a global configuration file.
   A commented example can be found in the @file{examples} directory of
   the distribution.
+
+ at item @var{GNUPGHOME}/swdb.lst
+ at cindex swdb.lst
+  A file with current software versions.  @command{dirmngr} creates
+  this file on demand from an online resource.
+
 @end table
 
 
diff --git a/tools/gpgconf.c b/tools/gpgconf.c
index a1ca79f..1f00418 100644
--- a/tools/gpgconf.c
+++ b/tools/gpgconf.c
@@ -1,5 +1,6 @@
 /* gpgconf.c - Configuration utility for GnuPG
  * Copyright (C) 2003, 2007, 2009, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2016 g10 Code GmbH.
  *
  * This file is part of GnuPG.
  *
@@ -52,6 +53,7 @@ enum cmd_and_opt_values
     aApplyDefaults,
     aListConfig,
     aCheckConfig,
+    aQuerySWDB,
     aListDirs,
     aLaunch,
     aKill,
@@ -79,6 +81,8 @@ static ARGPARSE_OPTS opts[] =
       N_("list global configuration file") },
     { aCheckConfig,   "check-config", 256,
       N_("check global configuration file") },
+    { aQuerySWDB,     "query-swdb", 256,
+      N_("query the software version database") },
     { aReload,        "reload", 256, N_("reload all or a given component")},
     { aLaunch,        "launch", 256, N_("launch a given component")},
     { aKill,          "kill", 256,   N_("kill a given component")},
@@ -203,6 +207,235 @@ list_dirs (estream_t fp, char **names)
 }
 
 
+
+/* Check whether NAME is valid argument for query_swdb().  Valid names
+ * start with a letter and contain only alphanumeric characters or an
+ * underscore.  */
+static int
+valid_swdb_name_p (const char *name)
+{
+  if (!name || !*name || !alphap (name))
+    return 0;
+
+  for (name++; *name; name++)
+    if (!alnump (name) && *name != '_')
+      return 0;
+
+  return 1;
+}
+
+
+/* Query the SWDB file.  If necessary and possible this functions asks
+ * the dirmngr to load an updated version of that file.  The caller
+ * needs to provide the NAME to query (e.g. "gnupg", "libgcrypt") and
+ * optional the currently installed version in CURRENT_VERSION.  The
+ * output written to OUT is a colon delimited line with these fields:
+ *
+ * name   :: The name of the package
+ * status :: This value tells the status of the software package
+ *           '-' :: No information available
+ *                  (error or CURRENT_VERSION not given)
+ *           '?' :: Unknown NAME
+ *           'u' :: Update available
+ *           'c' :: The version is Current
+ *           'n' :: The current version is already Newer than the
+ *                  available one.
+ * urgency :: If the value is greater than zero an urgent update is required.
+ * error   :: 0 on success or an gpg_err_code_t
+ *            Common codes seen:
+ *            GPG_ERR_TOO_OLD :: The SWDB file is to old to be used.
+ *            GPG_ERR_ENOENT  :: The SWDB file is not available.
+ *            GPG_ERR_BAD_SIGNATURE :: Currupted SWDB file.
+ * filedate:: Date of the swdb file (yyyymmddThhmmss)
+ * verified:: Date we checked the validity of the file (yyyyymmddThhmmss)
+ * version :: The version string from the swdb.
+ * reldate :: Release date of that version (yyyymmddThhmmss)
+ * size    :: Size of the package in bytes.
+ * hash    :: SHA-2 hash of the package.
+ *
+ */
+static void
+query_swdb (estream_t out, const char *name, const char *current_version)
+{
+  gpg_error_t err;
+  const char *search_name;
+  char *fname = NULL;
+  estream_t fp = NULL;
+  char *line = NULL;
+  char *self_version = NULL;
+  size_t length_of_line = 0;
+  size_t  maxlen;
+  ssize_t len;
+  char *fields[2];
+  char *p;
+  gnupg_isotime_t filedate = {0};
+  gnupg_isotime_t verified = {0};
+  char *value_ver = NULL;
+  gnupg_isotime_t value_date = {0};
+  char *value_size = NULL;
+  char *value_sha2 = NULL;
+  unsigned long value_size_ul;
+  int status, i;
+
+
+  if (!valid_swdb_name_p (name))
+    {
+      log_error ("error in package name '%s': %s\n",
+                 name, gpg_strerror (GPG_ERR_INV_NAME));
+      goto leave;
+    }
+  if (!strcmp (name, "gnupg"))
+    search_name = "gnupg21";
+  else if (!strcmp (name, "gnupg1"))
+    search_name = "gnupg1";
+  else
+    search_name = name;
+
+  if (!current_version && !strcmp (name, "gnupg"))
+    {
+      /* Use our own version but string a possible beta string.  */
+      self_version = xstrdup (PACKAGE_VERSION);
+      p = strchr (self_version, '-');
+      if (p)
+        *p = 0;
+      current_version = self_version;
+    }
+
+  if (current_version && compare_version_strings (current_version, NULL))
+    {
+      log_error ("error in version string '%s': %s\n",
+                 current_version, gpg_strerror (GPG_ERR_INV_ARG));
+      goto leave;
+    }
+
+  fname = make_filename (gnupg_homedir (), "swdb.lst", NULL);
+  fp = es_fopen (fname, "r");
+  if (!fp)
+    {
+      err = gpg_error_from_syserror ();
+      es_fprintf (out, "%s:-::%u:::::::\n", name, gpg_err_code (err));
+      if (gpg_err_code (err) != GPG_ERR_ENOENT)
+        log_error (_("error opening '%s': %s\n"), fname, gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Note that the parser uses the first occurance of a matching
+   * values and ignores possible duplicated values.  */
+
+  maxlen = 2048; /* Set limit.  */
+  while ((len = es_read_line (fp, &line, &length_of_line, &maxlen)) > 0)
+    {
+      if (!maxlen)
+        {
+          err = gpg_error (GPG_ERR_LINE_TOO_LONG);
+          log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err));
+          goto leave;
+        }
+      /* Strip newline and carriage return, if present.  */
+      while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r'))
+	line[--len] = '\0';
+
+      if (split_fields (line, fields, DIM (fields)) < DIM(fields))
+        continue; /* Skip empty lines and names w/o a value.  */
+      if (*fields[0] == '#')
+        continue; /* Skip comments.  */
+
+      /* Record the meta data.  */
+      if (!*filedate && !strcmp (fields[0], ".filedate"))
+        {
+          string2isotime (filedate, fields[1]);
+          continue;
+        }
+      if (!*verified && !strcmp (fields[0], ".verified"))
+        {
+          string2isotime (verified, fields[1]);
+          continue;
+        }
+
+      /* Tokenize the name.  */
+      p = strrchr (fields[0], '_');
+      if (!p)
+        continue; /* Name w/o an underscore.  */
+      *p++ = 0;
+
+      /* Wait for the requested name.  */
+      if (!strcmp (fields[0], search_name))
+        {
+          if (!strcmp (p, "ver") && !value_ver)
+            value_ver = xstrdup (fields[1]);
+          else if (!strcmp (p, "date") && !*value_date)
+            string2isotime (value_date, fields[1]);
+          else if (!strcmp (p, "size") && !value_size)
+            value_size = xstrdup (fields[1]);
+          else if (!strcmp (p, "sha2") && !value_sha2)
+            value_sha2 = xstrdup (fields[1]);
+        }
+    }
+  if (len < 0 || es_ferror (fp))
+    {
+      err = gpg_error_from_syserror ();
+      log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err));
+      goto leave;
+    }
+
+  if (!*filedate || !*verified)
+    {
+      err = gpg_error (GPG_ERR_INV_TIME);
+      es_fprintf (out, "%s:-::%u:::::::\n", name, gpg_err_code (err));
+      goto leave;
+    }
+
+  if (!value_ver)
+    {
+      es_fprintf (out, "%s:?:::::::::\n", name);
+      goto leave;
+    }
+
+  if (value_size)
+    {
+      gpg_err_set_errno (0);
+      value_size_ul = strtoul (value_size, &p, 10);
+      if (errno)
+        value_size_ul = 0;
+      else if (*p == 'k')
+        value_size_ul *= 1024;
+    }
+
+  err = 0;
+  status = '-';
+  if (compare_version_strings (value_ver, NULL))
+    err = gpg_error (GPG_ERR_INV_VALUE);
+  else if (!current_version)
+    ;
+  else if (!(i = compare_version_strings (value_ver, current_version)))
+    status = 'c';
+  else if (i > 0)
+    status = 'u';
+  else
+    status = 'n';
+
+  es_fprintf (out, "%s:%c::%d:%s:%s:%s:%s:%lu:%s:\n",
+              name,
+              status,
+              err,
+              filedate,
+              verified,
+              value_ver,
+              value_date,
+              value_size_ul,
+              value_sha2? value_sha2 : "");
+
+ leave:
+  xfree (value_ver);
+  xfree (value_size);
+  xfree (value_sha2);
+  xfree (line);
+  es_fclose (fp);
+  xfree (fname);
+  xfree (self_version);
+}
+
+
 /* gpgconf main. */
 int
 main (int argc, char **argv)
@@ -250,6 +483,7 @@ main (int argc, char **argv)
         case aApplyDefaults:
         case aListConfig:
         case aCheckConfig:
+        case aQuerySWDB:
         case aReload:
         case aLaunch:
         case aKill:
@@ -417,6 +651,18 @@ main (int argc, char **argv)
       list_dirs (outfp, argc? argv : NULL);
       break;
 
+    case aQuerySWDB:
+      /* Query the software version database.  */
+      if (!fname || argc > 2)
+	{
+	  es_fprintf (es_stderr, "usage: %s --query-swdb NAME [VERSION]\n",
+                      GPGCONF_NAME);
+	  exit (2);
+	}
+      get_outfp (&outfp);
+      query_swdb (outfp, fname, argc > 1? argv[1] : NULL);
+      break;
+
     case aCreateSocketDir:
       {
         char *socketdir;

commit 488b183811fc25c1ae49b4730491accf1adf518e
Author: Werner Koch <wk at gnupg.org>
Date:   Wed Nov 2 16:24:58 2016 +0100

    common: Improve compare_string_versions.
    
    * common/stringhelp.c: Include limits.h.
    (compare_version_strings): Change semantics to behave like strcmp.
    Include the patch lebel in the comparison.  Allow checking a single
    version string.
    * common/t-stringhelp.c (test_compare_version_strings): Adjust test
    vectors and a few new vectors.
    * g10/call-agent.c (warn_version_mismatch): Adjust to new sematics.
    * g10/call-dirmngr.c (warn_version_mismatch): Ditto.
    * sm/call-agent.c (warn_version_mismatch): Ditto.
    * sm/call-dirmngr.c (warn_version_mismatch): Ditto.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/common/stringhelp.c b/common/stringhelp.c
index b5d9f4c..f494bc5 100644
--- a/common/stringhelp.c
+++ b/common/stringhelp.c
@@ -49,6 +49,7 @@
 # include <windows.h>
 #endif
 #include <assert.h>
+#include <limits.h>
 
 #include "util.h"
 #include "common-defs.h"
@@ -1356,9 +1357,9 @@ parse_version_number (const char *s, int *number)
 
 /* This function breaks up the complete string-representation of the
    version number S, which is of the following struture: <major
-   number>.<minor number>.<micro number><patch level>.  The major,
-   minor and micro number components will be stored in *MAJOR, *MINOR
-   and *MICRO.
+   number>.<minor number>[.<micro number>]<patch level>.  The major,
+   minor, and micro number components will be stored in *MAJOR, *MINOR
+   and *MICRO.  If MICRO is not given 0 is used instead.
 
    On success, the last component, the patch level, will be returned;
    in failure, NULL will be returned.  */
@@ -1385,32 +1386,50 @@ parse_version_string (const char *s, int *major, int *minor, int *micro)
 }
 
 
-/* Check that the version string MY_VERSION is greater or equal than
-   REQ_VERSION.  Returns true if the condition is satisfied or false
-   if not.  This works with 3 part and two part version strings; for a
-   two part version string the micor part is assumed to be 0.  */
+/* Compare the version string MY_VERSION to the version string
+ * REQ_VERSION.  Returns -1, 0, or 1 if MY_VERSION is found,
+ * respectively, to be less than, to match, or be greater than
+ * REQ_VERSION.  This function works for three and two part version
+ * strings; for a two part version string the micro part is assumed to
+ * be 0.  Patch levels are compared as strings.  If a version number
+ * is invalid INT_MIN is returned.  If REQ_VERSION is given as NULL
+ * the function returns 0 if MY_VERSION is parsable version string. */
 int
 compare_version_strings (const char *my_version, const char *req_version)
 {
   int my_major, my_minor, my_micro;
   int rq_major, rq_minor, rq_micro;
-
-  if (!my_version || !req_version)
-    return 0;
-
-  if (!parse_version_string (my_version, &my_major, &my_minor, &my_micro))
-    return 0;
-  if (!parse_version_string(req_version, &rq_major, &rq_minor, &rq_micro))
-    return 0;
-
-  if (my_major > rq_major
-      || (my_major == rq_major && my_minor > rq_minor)
-      || (my_major == rq_major && my_minor == rq_minor
-	  && my_micro >= rq_micro))
+  const char *my_patch, *rq_patch;
+  int result;
+
+  if (!my_version)
+    return INT_MIN;
+
+  my_patch = parse_version_string (my_version, &my_major, &my_minor, &my_micro);
+  if (!my_patch)
+    return INT_MIN;
+  if (!req_version)
+    return 0; /* MY_VERSION can be parsed.  */
+  rq_patch = parse_version_string (req_version, &rq_major, &rq_minor,&rq_micro);
+  if (!rq_patch)
+    return INT_MIN;
+
+  if (my_major == rq_major)
     {
-      return 1;
+      if (my_minor == rq_minor)
+        {
+          if (my_micro == rq_micro)
+            result = strcmp (my_patch, rq_patch);
+          else
+            result = my_micro - rq_micro;
+        }
+      else
+        result = my_minor - rq_minor;
     }
-  return 0;
+  else
+    result = my_major - rq_major;
+
+  return !result? 0 : result < 0 ? -1 : 1;
 }
 
 
diff --git a/common/t-stringhelp.c b/common/t-stringhelp.c
index ccadf02..93b014a 100644
--- a/common/t-stringhelp.c
+++ b/common/t-stringhelp.c
@@ -40,6 +40,7 @@
 #endif
 #include <unistd.h>
 #include <sys/types.h>
+#include <limits.h>
 
 #include "t-support.h"
 #include "stringhelp.h"
@@ -903,45 +904,63 @@ static void
 test_compare_version_strings (void)
 {
   struct { const char *a; const char *b; int okay; } tests[] = {
-    { "1.0.0",   "1.0.0", 1 },
+    { "1.0.0",   "1.0.0", 0 },
     { "1.0.0-",  "1.0.0", 1 },
     { "1.0.0-1", "1.0.0", 1 },
     { "1.0.0.1", "1.0.0", 1 },
-    { "1.0.0",   "1.0.1", 0 },
-    { "1.0.0-",  "1.0.1", 0 },
-    { "1.0.0-1", "1.0.1", 0 },
-    { "1.0.0.1", "1.0.1", 0 },
-    { "1.0.0",   "1.1.0", 0 },
-    { "1.0.0-",  "1.1.0", 0 },
-    { "1.0.0-1", "1.1.0", 0 },
-    { "1.0.0.1", "1.1.0", 0 },
-
-    { "1.0.0",   "1.0.0-", 1 },
-    { "1.0.0",   "1.0.0-1", 1 },
-    { "1.0.0",   "1.0.0.1", 1 },
+    { "1.0.0",   "1.0.1", -1 },
+    { "1.0.0-",  "1.0.1", -1 },
+    { "1.0.0-1", "1.0.1", -1 },
+    { "1.0.0.1", "1.0.1", -1 },
+    { "1.0.0",   "1.1.0", -1 },
+    { "1.0.0-",  "1.1.0", -1 },
+    { "1.0.0-1", "1.1.0", -1 },
+    { "1.0.0.1", "1.1.0", -1 },
+
+    { "1.0.0",   "1.0.0-", -1 },
+    { "1.0.0",   "1.0.0-1", -1 },
+    { "1.0.0",   "1.0.0.1", -1 },
     { "1.1.0",   "1.0.0", 1 },
     { "1.1.1",   "1.1.0", 1 },
-    { "1.1.2",   "1.1.2", 1 },
+    { "1.1.2",   "1.1.2", 0 },
     { "1.1.2",   "1.0.2", 1 },
     { "1.1.2",   "0.0.2", 1 },
-    { "1.1.2",   "1.1.3", 0 },
+    { "1.1.2",   "1.1.3", -1 },
 
     { "0.99.1",  "0.9.9", 1 },
-    { "0.9.1",   "0.91.0", 0 },
+    { "0.9.1",   "0.91.0", -1 },
 
     { "1.5.3",   "1.5",  1 },
-    { "1.5.0",   "1.5",  1 },
-    { "1.4.99",  "1.5",  0 },
+    { "1.5.0",   "1.5",  0 },
+    { "1.4.99",  "1.5",  -1 },
     { "1.5",     "1.4.99",  1 },
-    { "1.5",     "1.5.0",  1 },
-    { "1.5",     "1.5.1",  0 },
+    { "1.5",     "1.5.0",  0 },
+    { "1.5",     "1.5.1",  -1 },
 
     { "1.5.3-x17",   "1.5-23",  1 },
 
     { "1.5.3a",   "1.5.3",  1 },
-    { "1.5.3a",   "1.5.3b",  1 },
-
-    { NULL, NULL, 0 }
+    { "1.5.3a",   "1.5.3b",  -1 },
+
+    { "3.1.4-ab", "3.1.4-ab", 0 },
+    { "3.1.4-ab", "3.1.4-ac", -1 },
+    { "3.1.4-ac", "3.1.4-ab", 1 },
+    { "3.1.4-ab", "3.1.4-abb", -1 },
+    { "3.1.4-abb", "3.1.4-ab", 1 },
+
+    { "",       "",   INT_MIN },
+    { NULL,     "",   INT_MIN },
+    { "1.2.3",  "",   INT_MIN },
+    { "1.2.3",  "2",  INT_MIN },
+
+    /* Test cases for validity of A.  */
+    { "",      NULL, INT_MIN },
+    { "1",     NULL, INT_MIN },
+    { "1.",    NULL, 0       },
+    { "1.0",   NULL, 0       },
+    { "1.0.",  NULL, 0       },
+    { "a1.2",  NULL, INT_MIN },
+    { NULL,    NULL, INT_MIN }
   };
   int idx;
   int res;
diff --git a/g10/call-agent.c b/g10/call-agent.c
index b17a80f..eeea7bf 100644
--- a/g10/call-agent.c
+++ b/g10/call-agent.c
@@ -195,7 +195,7 @@ warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
   if (err)
     log_error (_("error getting version from '%s': %s\n"),
                servername, gpg_strerror (err));
-  else if (!compare_version_strings (serverversion, myversion))
+  else if (compare_version_strings (serverversion, myversion) < 0)
     {
       char *warn;
 
diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c
index f739833..66db357 100644
--- a/g10/call-dirmngr.c
+++ b/g10/call-dirmngr.c
@@ -145,7 +145,7 @@ warn_version_mismatch (assuan_context_t ctx, const char *servername)
   if (err)
     log_error (_("error getting version from '%s': %s\n"),
                servername, gpg_strerror (err));
-  else if (!compare_version_strings (serverversion, myversion))
+  else if (compare_version_strings (serverversion, myversion) < 0)
     {
       char *warn;
 
diff --git a/sm/call-agent.c b/sm/call-agent.c
index c0a2081..c9a210f 100644
--- a/sm/call-agent.c
+++ b/sm/call-agent.c
@@ -97,7 +97,7 @@ warn_version_mismatch (ctrl_t ctrl, assuan_context_t ctx,
   if (err)
     log_error (_("error getting version from '%s': %s\n"),
                servername, gpg_strerror (err));
-  else if (!compare_version_strings (serverversion, myversion))
+  else if (compare_version_strings (serverversion, myversion) < 0)
     {
       char *warn;
 
diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c
index 03c9a68..6d7053c 100644
--- a/sm/call-dirmngr.c
+++ b/sm/call-dirmngr.c
@@ -163,7 +163,7 @@ warn_version_mismatch (ctrl_t ctrl, assuan_context_t ctx,
   if (err)
     log_error (_("error getting version from '%s': %s\n"),
                servername, gpg_strerror (err));
-  else if (!compare_version_strings (serverversion, myversion))
+  else if (compare_version_strings (serverversion, myversion) < 0)
     {
       char *warn;
 

-----------------------------------------------------------------------

Summary of changes:
 common/stringhelp.c   |  63 ++++++++-----
 common/t-stringhelp.c |  65 ++++++++-----
 doc/tools.texi        |  88 ++++++++++++++++++
 g10/call-agent.c      |   2 +-
 g10/call-dirmngr.c    |   2 +-
 sm/call-agent.c       |   2 +-
 sm/call-dirmngr.c     |   2 +-
 tools/gpgconf.c       | 246 ++++++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 421 insertions(+), 49 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list