[git] GnuPG - branch, master, updated. gnupg-2.1.9-88-g641df61

by Neal H. Walfield cvs at cvs.gnupg.org
Thu Oct 29 10:12:54 CET 2015


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  641df615da4937b0073c420a0503c5810c237972 (commit)
       via  d68bdc553a206e54234d5d53ad35c4ba34133118 (commit)
       via  ef052591ba51ee16bafc3c5b79d837ed8f01b520 (commit)
       via  89eee5f6b7ca3da7ebdcc3e5d069701d0834b39e (commit)
       via  99c84b49b787dab8da26cf61eed24dd4a2b77fd9 (commit)
       via  421827424fe87855307fe3e803b42ffa02738600 (commit)
       via  351f4213e192aa11500c0c590d11183edbe326c5 (commit)
      from  d25e29ad9374da1c11ccfc38f392dbab2d707042 (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 641df615da4937b0073c420a0503c5810c237972
Author: Neal H. Walfield <neal at g10code.com>
Date:   Thu Oct 29 10:09:58 2015 +0100

    gpg: Display the correct error message.
    
    * g10/trustdb.c (validate_keys): If tdbio_update_version_record fails,
    RC does not contain the error code.  Save the error code in rc2 and
    use that.
    
    --
    Signed-off-by: Neal H. Walfield <neal at g10code.com>

diff --git a/g10/trustdb.c b/g10/trustdb.c
index 54a779e..64de985 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -2106,6 +2106,8 @@ validate_keys (int interactive)
   release_key_hash_table (stored);
   if (!rc && !quit) /* mark trustDB as checked */
     {
+      int rc2;
+
       if (next_expire == 0xffffffff || next_expire < start_time )
         tdbio_write_nextcheck (0);
       else
@@ -2115,11 +2117,12 @@ validate_keys (int interactive)
                     strtimestamp (next_expire));
         }
 
-      if(tdbio_update_version_record()!=0)
+      rc2 = tdbio_update_version_record ();
+      if (rc2)
 	{
-	  log_error(_("unable to update trustdb version record: "
-		      "write failed: %s\n"), gpg_strerror (rc));
-	  tdbio_invalid();
+	  log_error (_("unable to update trustdb version record: "
+                       "write failed: %s\n"), gpg_strerror (rc2));
+	  tdbio_invalid ();
 	}
 
       do_sync ();

commit d68bdc553a206e54234d5d53ad35c4ba34133118
Author: Neal H. Walfield <neal at g10code.com>
Date:   Thu Oct 29 10:01:43 2015 +0100

    gpg: Eliminate a memory leak.
    
    * g10/trustdb.c (validate_key_list): Don't leak the keyblocks on
    failure.
    
    --
    Signed-off-by: Neal H. Walfield <neal at g10code.com>

diff --git a/g10/trustdb.c b/g10/trustdb.c
index 32061e4..54a779e 100644
--- a/g10/trustdb.c
+++ b/g10/trustdb.c
@@ -1729,9 +1729,8 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
     }
   if (rc)
     {
-      log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc));
-      xfree (keys);
-      return NULL;
+      log_error ("keydb_search(first) failed: %s\n", gpg_strerror (rc));
+      goto die;
     }
 
   desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */
@@ -1746,8 +1745,7 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
       if (rc)
         {
           log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
-          xfree (keys);
-          return NULL;
+	  goto die;
         }
 
       if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY)
@@ -1804,12 +1802,16 @@ validate_key_list (KEYDB_HANDLE hd, KeyHashTable full_trust,
   if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
     {
       log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
-      xfree (keys);
-      return NULL;
+      goto die;
     }
 
   keys[nkeys].keyblock = NULL;
   return keys;
+
+ die:
+  keys[nkeys].keyblock = NULL;
+  release_key_array (keys);
+  return NULL;
 }
 
 /* Caller must sync */

commit ef052591ba51ee16bafc3c5b79d837ed8f01b520
Author: Neal H. Walfield <neal at g10code.com>
Date:   Thu Oct 29 09:58:02 2015 +0100

    gpg: Remove unused prototype.
    
    g10/keyring.h (keyring_locate_writable): Remove unused prototype.
    
    --
    Signed-off-by: Neal H. Walfield <neal at g10code.com>

diff --git a/g10/keyring.h b/g10/keyring.h
index 1469b70..d97bd4c 100644
--- a/g10/keyring.h
+++ b/g10/keyring.h
@@ -36,7 +36,6 @@ int keyring_lock (KEYRING_HANDLE hd, int yes);
 int keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb);
 int keyring_update_keyblock (KEYRING_HANDLE hd, KBNODE kb);
 int keyring_insert_keyblock (KEYRING_HANDLE hd, KBNODE kb);
-int keyring_locate_writable (KEYRING_HANDLE hd);
 int keyring_delete_keyblock (KEYRING_HANDLE hd);
 int keyring_search_reset (KEYRING_HANDLE hd);
 int keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,

commit 89eee5f6b7ca3da7ebdcc3e5d069701d0834b39e
Author: Neal H. Walfield <neal at g10code.com>
Date:   Thu Oct 29 09:57:00 2015 +0100

    gpg: Eliminate a memory leak.
    
    * g10/gpg.c (main): Don't leak OPT.DEF_RECIPIENT.
    
    --
    Signed-off-by: Neal H. Walfield <neal at g10code.com>

diff --git a/g10/gpg.c b/g10/gpg.c
index c18edd0..0f1c74a 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -2580,7 +2580,10 @@ main (int argc, char **argv)
 	  case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
 	  case oDefRecipient:
             if( *pargs.r.ret_str )
-              opt.def_recipient = make_username(pargs.r.ret_str);
+	      {
+		xfree (opt.def_recipient);
+		opt.def_recipient = make_username(pargs.r.ret_str);
+	      }
             break;
 	  case oDefRecipientSelf:
             xfree(opt.def_recipient); opt.def_recipient = NULL;

commit 99c84b49b787dab8da26cf61eed24dd4a2b77fd9
Author: Neal H. Walfield <neal at g10code.com>
Date:   Thu Oct 29 09:52:56 2015 +0100

    gpg: Fix keyring support.
    
    * g10/keydb.c (keydb_rebuild_caches): Only mark the cached as prepared
    if it is actually prepared, which it only is if the resource is a
    keybox.
    
    --
    Signed-off-by: Neal H. Walfield <neal at g10code.com>

diff --git a/g10/keydb.c b/g10/keydb.c
index da18bc0..bcafe90 100644
--- a/g10/keydb.c
+++ b/g10/keydb.c
@@ -1701,7 +1701,8 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
   if (!hd->no_caching
       && !rc
       && ndesc == 1 && (desc[0].mode == KEYDB_SEARCH_MODE_FPR20
-                        || desc[0].mode == KEYDB_SEARCH_MODE_FPR))
+                        || desc[0].mode == KEYDB_SEARCH_MODE_FPR)
+      && hd->active[hd->current].type == KEYDB_RESOURCE_TYPE_KEYBOX)
     {
       hd->keyblock_cache.state = KEYBLOCK_CACHE_PREPARED;
       memcpy (hd->keyblock_cache.fpr, desc[0].u.fpr, 20);

commit 421827424fe87855307fe3e803b42ffa02738600
Author: Neal H. Walfield <neal at g10code.com>
Date:   Thu Oct 29 09:36:36 2015 +0100

    gpg: Change sqlite3_stepx to pass the sqlite3_stmt * to the callback.
    
    * g10/sqlite.h (enum sqlite_arg_type): Add SQLITE_ARG_BLOB.
    (sqlite3_stepx_callback): New declaration.
    (sqlite3_stepx): Change the callback's type to sqlite3_stepx_callback,
    which passes an additional parameter, the sqlite3_stmt *.  Update
    users.
    
    --
    Signed-off-by: Neal H. Walfield <neal at g10code.com>

diff --git a/g10/sqlite.c b/g10/sqlite.c
index da3ca96..ee7514c 100644
--- a/g10/sqlite.c
+++ b/g10/sqlite.c
@@ -59,7 +59,7 @@ sqlite3_exec_printf (sqlite3 *db,
 int
 sqlite3_stepx (sqlite3 *db,
                sqlite3_stmt **stmtp,
-               int (*callback) (void*,int,char**,char**),
+               sqlite3_stepx_callback callback,
                void *cookie,
                char **errmsg,
                const char *sql, ...)
@@ -150,6 +150,13 @@ sqlite3_stepx (sqlite3 *db,
                 err = sqlite3_bind_text (stmt, i, text, -1, SQLITE_STATIC);
                 break;
               }
+            case SQLITE_ARG_BLOB:
+              {
+                char *blob = va_arg (va, void *);
+                long long length = va_arg (va, long long);
+                err = sqlite3_bind_blob (stmt, i, blob, length, SQLITE_STATIC);
+                break;
+              }
             default:
               /* Internal error.  Likely corruption.  */
               log_fatal ("Bad value for parameter type %d.\n", t);
@@ -201,7 +208,7 @@ sqlite3_stepx (sqlite3 *db,
             }
         }
 
-      if (callback (cookie, cols, (char **) azVals, (char **) azColName))
+      if (callback (cookie, cols, (char **) azVals, (char **) azColName, stmt))
         /* A non-zero result means to abort.  */
         {
           err = SQLITE_ABORT;
diff --git a/g10/sqlite.h b/g10/sqlite.h
index 7ebe8d9..753e37a 100644
--- a/g10/sqlite.h
+++ b/g10/sqlite.h
@@ -27,7 +27,10 @@ enum sqlite_arg_type
     SQLITE_ARG_END = 0xdead001,
     SQLITE_ARG_INT,
     SQLITE_ARG_LONG_LONG,
-    SQLITE_ARG_STRING
+    SQLITE_ARG_STRING,
+    /* This takes two arguments: the blob as a void * and the length
+       of the blob as a long long.  */
+    SQLITE_ARG_BLOB
   };
 
 
@@ -36,9 +39,22 @@ int sqlite3_exec_printf (sqlite3 *db,
                          char **errmsg,
                          const char *sql, ...);
 
+typedef int (*sqlite3_stepx_callback) (void *cookie,
+                                       /* number of columns.  */
+                                       int cols,
+                                       /* columns as text.  */
+                                       char **values,
+                                       /* column names.  */
+                                       char **names,
+                                       /* The prepared statement so
+                                          that it is possible to use
+                                          something like
+                                          sqlite3_column_blob().  */
+                                       sqlite3_stmt *statement);
+
 int sqlite3_stepx (sqlite3 *db,
                    sqlite3_stmt **stmtp,
-                   int (*callback) (void*,int,char**,char**),
+                   sqlite3_stepx_callback callback,
                    void *cookie,
                    char **errmsg,
                    const char *sql, ...);
diff --git a/g10/tofu.c b/g10/tofu.c
index 905010c..6dda873 100644
--- a/g10/tofu.c
+++ b/g10/tofu.c
@@ -418,6 +418,14 @@ get_single_unsigned_long_cb (void *cookie, int argc, char **argv,
   return 0;
 }
 
+static int
+get_single_unsigned_long_cb2 (void *cookie, int argc, char **argv,
+			     char **azColName, sqlite3_stmt *stmt)
+{
+  (void) stmt;
+  return get_single_unsigned_long_cb (cookie, argc, argv, azColName);
+}
+
 /* We expect a single integer column whose name is "version".  COOKIE
    must point to an int.  This function always aborts.  On error or a
    if the version is bad, sets *VERSION to -1.  */
@@ -1050,6 +1058,13 @@ get_single_long_cb (void *cookie, int argc, char **argv, char **azColName)
   return 0;
 }
 
+static int
+get_single_long_cb2 (void *cookie, int argc, char **argv, char **azColName,
+                     sqlite3_stmt *stmt)
+{
+  (void) stmt;
+  return get_single_long_cb (cookie, argc, argv, azColName);
+}
 
 /* Record (or update) a trust policy about a (possibly new)
    binding.
@@ -1109,7 +1124,7 @@ record_binding (struct dbs *dbs, const char *fingerprint, const char *email,
     {
       rc = sqlite3_stepx
 	(db_email->db, &db_email->s.record_binding_get_old_policy,
-         get_single_long_cb, &policy_old, &err,
+         get_single_long_cb2, &policy_old, &err,
 	 "select policy from bindings where fingerprint = ? and email = ?",
 	 SQLITE_ARG_STRING, fingerprint, SQLITE_ARG_STRING, email,
          SQLITE_ARG_END);
@@ -1261,6 +1276,15 @@ strings_collect_cb (void *cookie, int argc, char **argv, char **azColName)
   return 0;
 }
 
+static int
+strings_collect_cb2 (void *cookie, int argc, char **argv, char **azColName,
+                     sqlite3_stmt *stmt)
+{
+  (void) stmt;
+  return strings_collect_cb (cookie, argc, argv, azColName);
+
+}
+
 /* Auxiliary data structure to collect statistics about
    signatures.  */
 struct signature_stats
@@ -1316,7 +1340,7 @@ signature_stats_prepend (struct signature_stats **statsp,
      <fingerprint, policy, time ago, count>.  */
 static int
 signature_stats_collect_cb (void *cookie, int argc, char **argv,
-			    char **azColName)
+			    char **azColName, sqlite3_stmt *stmt)
 {
   struct signature_stats **statsp = cookie;
   char *tail;
@@ -1326,6 +1350,7 @@ signature_stats_collect_cb (void *cookie, int argc, char **argv,
   unsigned long count;
 
   (void) azColName;
+  (void) stmt;
 
   i ++;
 
@@ -1447,7 +1472,7 @@ get_policy (struct dbs *dbs, const char *fingerprint, const char *email,
      still TOFU_POLICY_NONE after executing the query, then the
      result set was empty.)  */
   rc = sqlite3_stepx (db->db, &db->s.get_policy_select_policy_and_conflict,
-                      strings_collect_cb, &strlist, &err,
+                      strings_collect_cb2, &strlist, &err,
                       "select policy, conflict from bindings\n"
                       " where fingerprint = ? and email = ?",
                       SQLITE_ARG_STRING, fingerprint,
@@ -1692,7 +1717,7 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
      a new binding.  */
   rc = sqlite3_stepx
     (db->db, &db->s.get_trust_bindings_with_this_email,
-     strings_collect_cb, &bindings_with_this_email, &err,
+     strings_collect_cb2, &bindings_with_this_email, &err,
      "select distinct fingerprint from bindings where email = ?;",
      SQLITE_ARG_STRING, email, SQLITE_ARG_END);
   if (rc)
@@ -1835,7 +1860,7 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email,
 	{
 	  rc = sqlite3_stepx
 	    (db_key->db, &db_key->s.get_trust_gather_other_user_ids,
-             strings_collect_cb, &other_user_ids, &err,
+             strings_collect_cb2, &other_user_ids, &err,
              opt.tofu_db_format == TOFU_DB_SPLIT
 	     ? "select user_id, email from bindings where fingerprint = ?;"
 	     : "select user_id, policy from bindings where fingerprint = ?;",
@@ -2519,7 +2544,7 @@ tofu_register (const byte *fingerprint_bin, const char *user_id,
      it again.  */
   rc = sqlite3_stepx
     (db->db, &db->s.register_already_seen,
-     get_single_unsigned_long_cb, &c, &err,
+     get_single_unsigned_long_cb2, &c, &err,
      "select count (*)\n"
      " from signatures left join bindings\n"
      "  on signatures.binding = bindings.oid\n"

commit 351f4213e192aa11500c0c590d11183edbe326c5
Author: Neal H. Walfield <neal at g10code.com>
Date:   Wed Oct 28 13:12:27 2015 +0100

    gpg: Move sqlite helper functions into their own file.
    
    * g10/tofu.c (sqlite3_exec_printf): Move from here...
    * g10/sqlite.c (sqlite3_exec_printf): ... to this new file.  Don't
    mark as static.
    * g10/tofu.c (sqlite3_stepx): Move from here...
    * g10/sqlite.c (sqlite3_stepx): ... to this new file.  Don't
    mark as static.
    * g10/tofu.c (enum sqlite_arg_type): Move from here...
    * g10/sqlite.h (enum sqlite_arg_type): ... to this new file.
    
    --
    Signed-off-by: Neal H. Walfield <neal at g10code.com>

diff --git a/g10/Makefile.am b/g10/Makefile.am
index 75ccac8..2fe5c9a 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -57,7 +57,7 @@ trust_source = trustdb.c trustdb.h tdbdump.c tdbio.c tdbio.h
 endif
 
 if USE_TOFU
-tofu_source = tofu.h tofu.c
+tofu_source = tofu.h tofu.c sqlite.c sqlite.h
 else
 tofu_source =
 endif
diff --git a/g10/sqlite.c b/g10/sqlite.c
new file mode 100644
index 0000000..da3ca96
--- /dev/null
+++ b/g10/sqlite.c
@@ -0,0 +1,245 @@
+/* sqlite.c - SQLite helper functions.
+ * Copyright (C) 2015 g10 Code GmbH
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "gpg.h"
+#include "util.h"
+#include "logging.h"
+
+#include "sqlite.h"
+
+/* This is a convenience function that combines sqlite3_mprintf and
+   sqlite3_exec.  */
+int
+sqlite3_exec_printf (sqlite3 *db,
+		     int (*callback)(void*,int,char**,char**), void *cookie,
+		     char **errmsg,
+		     const char *sql, ...)
+{
+  va_list ap;
+  int rc;
+  char *sql2;
+
+  va_start (ap, sql);
+  sql2 = sqlite3_vmprintf (sql, ap);
+  va_end (ap);
+
+#if 0
+  log_debug ("tofo db: executing: '%s'\n", sql2);
+#endif
+
+  rc = sqlite3_exec (db, sql2, callback, cookie, errmsg);
+
+  sqlite3_free (sql2);
+
+  return rc;
+}
+
+int
+sqlite3_stepx (sqlite3 *db,
+               sqlite3_stmt **stmtp,
+               int (*callback) (void*,int,char**,char**),
+               void *cookie,
+               char **errmsg,
+               const char *sql, ...)
+{
+  int rc;
+  int err = 0;
+  sqlite3_stmt *stmt = NULL;
+
+  va_list va;
+  int args;
+  enum sqlite_arg_type t;
+  int i;
+
+  int cols;
+  /* Names of the columns.  We initialize this lazily to avoid the
+     overhead in case the query doesn't return any results.  */
+  const char **azColName = 0;
+  int callback_initialized = 0;
+
+  const char **azVals = 0;
+
+  callback_initialized = 0;
+
+  if (stmtp && *stmtp)
+    {
+      stmt = *stmtp;
+
+      /* Make sure this statement is associated with the supplied db.  */
+      assert (db == sqlite3_db_handle (stmt));
+
+#if DEBUG_TOFU_CACHE
+      prepares_saved ++;
+#endif
+    }
+  else
+    {
+      const char *tail = NULL;
+
+      rc = sqlite3_prepare_v2 (db, sql, -1, &stmt, &tail);
+      if (rc)
+        log_fatal ("failed to prepare SQL: %s", sql);
+
+      /* We can only process a single statement.  */
+      if (tail)
+        {
+          while (*tail == ' ' || *tail == ';')
+            tail ++;
+
+          if (*tail)
+            log_fatal
+              ("sqlite3_stepx can only process a single SQL statement."
+               "  Second statement starts with: '%s'\n",
+               tail);
+        }
+
+      if (stmtp)
+        *stmtp = stmt;
+    }
+
+#if DEBUG_TOFU_CACHE
+  queries ++;
+#endif
+
+  args = sqlite3_bind_parameter_count (stmt);
+  va_start (va, sql);
+  if (args)
+    {
+      for (i = 1; i <= args; i ++)
+        {
+          t = va_arg (va, enum sqlite_arg_type);
+          switch (t)
+            {
+            case SQLITE_ARG_INT:
+              {
+                int value = va_arg (va, int);
+                err = sqlite3_bind_int (stmt, i, value);
+                break;
+              }
+            case SQLITE_ARG_LONG_LONG:
+              {
+                long long value = va_arg (va, long long);
+                err = sqlite3_bind_int64 (stmt, i, value);
+                break;
+              }
+            case SQLITE_ARG_STRING:
+              {
+                char *text = va_arg (va, char *);
+                err = sqlite3_bind_text (stmt, i, text, -1, SQLITE_STATIC);
+                break;
+              }
+            default:
+              /* Internal error.  Likely corruption.  */
+              log_fatal ("Bad value for parameter type %d.\n", t);
+            }
+
+          if (err)
+            {
+              log_fatal ("Error binding parameter %d\n", i);
+              goto out;
+            }
+        }
+
+    }
+  t = va_arg (va, enum sqlite_arg_type);
+  assert (t == SQLITE_ARG_END);
+  va_end (va);
+
+  for (;;)
+    {
+      rc = sqlite3_step (stmt);
+
+      if (rc != SQLITE_ROW)
+        /* No more data (SQLITE_DONE) or an error occured.  */
+        break;
+
+      if (! callback)
+        continue;
+
+      if (! callback_initialized)
+        {
+          cols = sqlite3_column_count (stmt);
+          azColName = xmalloc (2 * cols * sizeof (const char *) + 1);
+
+          for (i = 0; i < cols; i ++)
+            azColName[i] = sqlite3_column_name (stmt, i);
+
+          callback_initialized = 1;
+        }
+
+      azVals = &azColName[cols];
+      for (i = 0; i < cols; i ++)
+        {
+          azVals[i] = sqlite3_column_text (stmt, i);
+          if (! azVals[i] && sqlite3_column_type (stmt, i) != SQLITE_NULL)
+            /* Out of memory.  */
+            {
+              err = SQLITE_NOMEM;
+              break;
+            }
+        }
+
+      if (callback (cookie, cols, (char **) azVals, (char **) azColName))
+        /* A non-zero result means to abort.  */
+        {
+          err = SQLITE_ABORT;
+          break;
+        }
+    }
+
+ out:
+  xfree (azColName);
+
+  if (stmtp)
+    rc = sqlite3_reset (stmt);
+  else
+    rc = sqlite3_finalize (stmt);
+  if (rc == SQLITE_OK && err)
+    /* Local error.  */
+    {
+      rc = err;
+      if (errmsg)
+        {
+          const char *e = sqlite3_errstr (err);
+          size_t l = strlen (e) + 1;
+          *errmsg = sqlite3_malloc (l);
+          if (! *errmsg)
+            log_fatal ("Out of memory.\n");
+          memcpy (*errmsg, e, l);
+        }
+    }
+  else if (rc != SQLITE_OK && errmsg)
+    /* Error reported by sqlite.  */
+    {
+      const char * e = sqlite3_errmsg (db);
+      size_t l = strlen (e) + 1;
+      *errmsg = sqlite3_malloc (l);
+      if (! *errmsg)
+        log_fatal ("Out of memory.\n");
+      memcpy (*errmsg, e, l);
+    }
+
+  return rc;
+}
diff --git a/g10/sqlite.h b/g10/sqlite.h
new file mode 100644
index 0000000..7ebe8d9
--- /dev/null
+++ b/g10/sqlite.h
@@ -0,0 +1,46 @@
+/* sqlite.h - SQLite helper functions.
+ * Copyright (C) 2015 g10 Code GmbH
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_SQLITE_H
+#define GNUPG_SQLITE_H
+
+#include <sqlite3.h>
+
+enum sqlite_arg_type
+  {
+    SQLITE_ARG_END = 0xdead001,
+    SQLITE_ARG_INT,
+    SQLITE_ARG_LONG_LONG,
+    SQLITE_ARG_STRING
+  };
+
+
+int sqlite3_exec_printf (sqlite3 *db,
+                         int (*callback)(void*,int,char**,char**), void *cookie,
+                         char **errmsg,
+                         const char *sql, ...);
+
+int sqlite3_stepx (sqlite3 *db,
+                   sqlite3_stmt **stmtp,
+                   int (*callback) (void*,int,char**,char**),
+                   void *cookie,
+                   char **errmsg,
+                   const char *sql, ...);
+
+#endif
diff --git a/g10/tofu.c b/g10/tofu.c
index 43a6224..905010c 100644
--- a/g10/tofu.c
+++ b/g10/tofu.c
@@ -40,6 +40,7 @@
 #include "i18n.h"
 #include "trustdb.h"
 #include "mkdir_p.h"
+#include "sqlite.h"
 
 #include "tofu.h"
 
@@ -213,229 +214,6 @@ tofu_policy_to_trust_level (enum tofu_policy policy)
       return 0;
     }
 }
-
-/* This is a convenience function that combines sqlite3_mprintf and
-   sqlite3_exec.  */
-static int
-sqlite3_exec_printf (sqlite3 *db,
-		     int (*callback)(void*,int,char**,char**), void *cookie,
-		     char **errmsg,
-		     const char *sql, ...)
-{
-  va_list ap;
-  int rc;
-  char *sql2;
-
-  va_start (ap, sql);
-  sql2 = sqlite3_vmprintf (sql, ap);
-  va_end (ap);
-
-#if 0
-  log_debug ("tofo db: executing: '%s'\n", sql2);
-#endif
-
-  rc = sqlite3_exec (db, sql2, callback, cookie, errmsg);
-
-  sqlite3_free (sql2);
-
-  return rc;
-}
-
-enum sqlite_arg_type
-  {
-    SQLITE_ARG_END = 0xdead001,
-    SQLITE_ARG_INT,
-    SQLITE_ARG_LONG_LONG,
-    SQLITE_ARG_STRING
-  };
-
-static int
-sqlite3_stepx (sqlite3 *db,
-               sqlite3_stmt **stmtp,
-               int (*callback) (void*,int,char**,char**),
-               void *cookie,
-               char **errmsg,
-               const char *sql, ...)
-{
-  int rc;
-  int err = 0;
-  sqlite3_stmt *stmt = NULL;
-
-  va_list va;
-  int args;
-  enum sqlite_arg_type t;
-  int i;
-
-  int cols;
-  /* Names of the columns.  We initialize this lazily to avoid the
-     overhead in case the query doesn't return any results.  */
-  const char **azColName = 0;
-  int callback_initialized = 0;
-
-  const char **azVals = 0;
-
-  callback_initialized = 0;
-
-  if (stmtp && *stmtp)
-    {
-      stmt = *stmtp;
-
-      /* Make sure this statement is associated with the supplied db.  */
-      assert (db == sqlite3_db_handle (stmt));
-
-#if DEBUG_TOFU_CACHE
-      prepares_saved ++;
-#endif
-    }
-  else
-    {
-      const char *tail = NULL;
-
-      rc = sqlite3_prepare_v2 (db, sql, -1, &stmt, &tail);
-      if (rc)
-        log_fatal ("failed to prepare SQL: %s", sql);
-
-      /* We can only process a single statement.  */
-      if (tail)
-        {
-          while (*tail == ' ' || *tail == ';')
-            tail ++;
-
-          if (*tail)
-            log_fatal
-              ("sqlite3_stepx can only process a single SQL statement."
-               "  Second statement starts with: '%s'\n",
-               tail);
-        }
-
-      if (stmtp)
-        *stmtp = stmt;
-    }
-
-#if DEBUG_TOFU_CACHE
-  queries ++;
-#endif
-
-  args = sqlite3_bind_parameter_count (stmt);
-  va_start (va, sql);
-  if (args)
-    {
-      for (i = 1; i <= args; i ++)
-        {
-          t = va_arg (va, enum sqlite_arg_type);
-          switch (t)
-            {
-            case SQLITE_ARG_INT:
-              {
-                int value = va_arg (va, int);
-                err = sqlite3_bind_int (stmt, i, value);
-                break;
-              }
-            case SQLITE_ARG_LONG_LONG:
-              {
-                long long value = va_arg (va, long long);
-                err = sqlite3_bind_int64 (stmt, i, value);
-                break;
-              }
-            case SQLITE_ARG_STRING:
-              {
-                char *text = va_arg (va, char *);
-                err = sqlite3_bind_text (stmt, i, text, -1, SQLITE_STATIC);
-                break;
-              }
-            default:
-              /* Internal error.  Likely corruption.  */
-              log_fatal ("Bad value for parameter type %d.\n", t);
-            }
-
-          if (err)
-            {
-              log_fatal ("Error binding parameter %d\n", i);
-              goto out;
-            }
-        }
-
-    }
-  t = va_arg (va, enum sqlite_arg_type);
-  assert (t == SQLITE_ARG_END);
-  va_end (va);
-
-  for (;;)
-    {
-      rc = sqlite3_step (stmt);
-
-      if (rc != SQLITE_ROW)
-        /* No more data (SQLITE_DONE) or an error occured.  */
-        break;
-
-      if (! callback)
-        continue;
-
-      if (! callback_initialized)
-        {
-          cols = sqlite3_column_count (stmt);
-          azColName = xmalloc (2 * cols * sizeof (const char *) + 1);
-
-          for (i = 0; i < cols; i ++)
-            azColName[i] = sqlite3_column_name (stmt, i);
-
-          callback_initialized = 1;
-        }
-
-      azVals = &azColName[cols];
-      for (i = 0; i < cols; i ++)
-        {
-          azVals[i] = sqlite3_column_text (stmt, i);
-          if (! azVals[i] && sqlite3_column_type (stmt, i) != SQLITE_NULL)
-            /* Out of memory.  */
-            {
-              err = SQLITE_NOMEM;
-              break;
-            }
-        }
-
-      if (callback (cookie, cols, (char **) azVals, (char **) azColName))
-        /* A non-zero result means to abort.  */
-        {
-          err = SQLITE_ABORT;
-          break;
-        }
-    }
-
- out:
-  xfree (azColName);
-
-  if (stmtp)
-    rc = sqlite3_reset (stmt);
-  else
-    rc = sqlite3_finalize (stmt);
-  if (rc == SQLITE_OK && err)
-    /* Local error.  */
-    {
-      rc = err;
-      if (errmsg)
-        {
-          const char *e = sqlite3_errstr (err);
-          size_t l = strlen (e) + 1;
-          *errmsg = sqlite3_malloc (l);
-          if (! *errmsg)
-            log_fatal ("Out of memory.\n");
-          memcpy (*errmsg, e, l);
-        }
-    }
-  else if (rc != SQLITE_OK && errmsg)
-    /* Error reported by sqlite.  */
-    {
-      const char * e = sqlite3_errmsg (db);
-      size_t l = strlen (e) + 1;
-      *errmsg = sqlite3_malloc (l);
-      if (! *errmsg)
-        log_fatal ("Out of memory.\n");
-      memcpy (*errmsg, e, l);
-    }
-
-  return rc;
-}
 

 static int batch_update;
 static time_t batch_update_started;

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

Summary of changes:
 g10/Makefile.am |   2 +-
 g10/gpg.c       |   5 +-
 g10/keydb.c     |   3 +-
 g10/keyring.h   |   1 -
 g10/sqlite.c    | 252 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 g10/sqlite.h    |  62 ++++++++++++++
 g10/tofu.c      | 261 +++++++-------------------------------------------------
 g10/trustdb.c   |  27 +++---
 8 files changed, 369 insertions(+), 244 deletions(-)
 create mode 100644 g10/sqlite.c
 create mode 100644 g10/sqlite.h


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




More information about the Gnupg-commits mailing list