Merge branch 'STABLE-BRANCH-2-2' into master
[gnupg.git] / g10 / tdbio.c
index 4c93c96..7572b9a 100644 (file)
@@ -15,7 +15,7 @@
  * 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/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include <assert.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 
 #include "gpg.h"
-#include "status.h"
-#include "iobuf.h"
-#include "util.h"
+#include "../common/status.h"
+#include "../common/iobuf.h"
+#include "../common/util.h"
 #include "options.h"
 #include "main.h"
-#include "i18n.h"
+#include "../common/i18n.h"
 #include "trustdb.h"
 #include "tdbio.h"
 
@@ -87,7 +86,7 @@ static int cache_entries;
 static int cache_is_dirty;
 
 
-/* An object to pass infomation to cmp_krec_fpr. */
+/* An object to pass information to cmp_krec_fpr. */
 struct cmp_krec_fpr_struct
 {
   int pubkey_algo;
@@ -95,7 +94,7 @@ struct cmp_krec_fpr_struct
   int fprlen;
 };
 
-/* An object used to pass infomation to cmp_[s]dir. */
+/* An object used to pass information to cmp_[s]dir. */
 struct cmp_xdir_struct
 {
   int pubkey_algo;
@@ -120,6 +119,7 @@ static int in_transaction;
 
 \f
 static void open_db (void);
+static void create_hashtable (ctrl_t ctrl, TRUSTREC *vr, int type);
 
 
 \f
@@ -225,7 +225,7 @@ write_cache_item (CACHE_CTRL r)
  *
  * Returns: 0 on success or an error code.
  */
-int
+static int
 put_record_into_cache (ulong recno, const char *data)
 {
   CACHE_CTRL r, unused;
@@ -317,7 +317,7 @@ put_record_into_cache (ulong recno, const char *data)
        }
 
       /* Now put into the cache.  */
-      assert (unused);
+      log_assert (unused);
       r = unused;
       r->flags.used = 1;
       r->recno = recno;
@@ -383,7 +383,7 @@ put_record_into_cache (ulong recno, const char *data)
       release_write_lock ();
 
       /* Now put into the cache.  */
-      assert (unused);
+      log_assert (unused);
       r = unused;
       r->flags.used = 1;
       r->recno = recno;
@@ -446,7 +446,7 @@ tdbio_sync()
 /*
  * Simple transactions system:
  * Everything between begin_transaction and end/cancel_transaction
- * is not immediatly written but at the time of end_transaction.
+ * is not immediately written but at the time of end_transaction.
  *
  * NOTE: The transaction code is disabled in the 1.2 branch, as it is
  * not yet used.
@@ -535,7 +535,7 @@ cleanup (void)
  * Returns: 0 on success or an error code.
  */
 int
-tdbio_update_version_record (void)
+tdbio_update_version_record (ctrl_t ctrl)
 {
   TRUSTREC rec;
   int rc;
@@ -551,7 +551,7 @@ tdbio_update_version_record (void)
       rec.r.ver.cert_depth  = opt.max_cert_depth;
       rec.r.ver.trust_model = opt.trust_model;
       rec.r.ver.min_cert_level = opt.min_cert_level;
-      rc=tdbio_write_record(&rec);
+      rc = tdbio_write_record (ctrl, &rec);
     }
 
   return rc;
@@ -564,7 +564,7 @@ tdbio_update_version_record (void)
  * Returns: 0 on success or an error code.
  */
 static int
-create_version_record (void)
+create_version_record (ctrl_t ctrl)
 {
   TRUSTREC rec;
   int rc;
@@ -582,9 +582,14 @@ create_version_record (void)
   rec.r.ver.min_cert_level = opt.min_cert_level;
   rec.rectype = RECTYPE_VER;
   rec.recnum = 0;
-  rc = tdbio_write_record (&rec);
+  rc = tdbio_write_record (ctrl, &rec);
+
   if (!rc)
     tdbio_sync ();
+
+  if (!rc)
+    create_hashtable (ctrl, &rec, 0);
+
   return rc;
 }
 
@@ -601,11 +606,13 @@ create_version_record (void)
  *
  */
 int
-tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile)
+tdbio_set_dbname (ctrl_t ctrl, const char *new_dbname,
+                  int create, int *r_nofile)
 {
-  char *fname;
+  char *fname, *p;
   struct stat statbuf;
   static int initialized = 0;
+  int save_slash;
 
   if (!initialized)
     {
@@ -617,14 +624,15 @@ tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile)
 
   if (!new_dbname)
     {
-      fname = make_filename (opt.homedir, "trustdb" EXTSEP_S GPGEXT_GPG, NULL);
+      fname = make_filename (gnupg_homedir (),
+                             "trustdb" EXTSEP_S GPGEXT_GPG, NULL);
     }
   else if (*new_dbname != DIRSEP_C )
     {
       if (strchr (new_dbname, DIRSEP_C))
         fname = make_filename (new_dbname, NULL);
       else
-        fname = make_filename (opt.homedir, new_dbname, NULL);
+        fname = make_filename (gnupg_homedir (), new_dbname, NULL);
     }
   else
     {
@@ -643,11 +651,48 @@ tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile)
       /* OK, we have the valid trustdb.gpg already.  */
       return 0;
     }
+  else if (!create)
+    {
+      *r_nofile = 1;
+      return 0;
+    }
+
+  /* Here comes: No valid trustdb.gpg AND CREATE==1 */
+
+  /*
+   * Make sure the directory exists.  This should be done before
+   * acquiring the lock, which assumes the existence of the directory.
+   */
+  p = strrchr (fname, DIRSEP_C);
+#if HAVE_W32_SYSTEM
+  {
+    /* Windows may either have a slash or a backslash.  Take
+       care of it.  */
+    char *pp = strrchr (fname, '/');
+    if (!p || pp > p)
+      p = pp;
+  }
+#endif /*HAVE_W32_SYSTEM*/
+  log_assert (p);
+  save_slash = *p;
+  *p = 0;
+  if (access (fname, F_OK))
+    {
+      try_make_homedir (fname);
+      if (access (fname, F_OK))
+        log_fatal (_("%s: directory does not exist!\n"), fname);
+    }
+  *p = save_slash;
 
   take_write_lock ();
 
-  if (access (fname, R_OK))
+  if (access (fname, R_OK) || stat (fname, &statbuf) || statbuf.st_size == 0)
     {
+      FILE *fp;
+      TRUSTREC rec;
+      int rc;
+      mode_t oldmask;
+
 #ifdef HAVE_W32CE_SYSTEM
       /* We know how the cegcc implementation of access works ;-). */
       if (GetLastError () == ERROR_FILE_NOT_FOUND)
@@ -655,69 +700,37 @@ tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile)
       else
         gpg_err_set_errno (EIO);
 #endif /*HAVE_W32CE_SYSTEM*/
-      if (errno != ENOENT)
+      if (errno && errno != ENOENT)
         log_fatal ( _("can't access '%s': %s\n"), fname, strerror (errno));
 
-      if (!create)
-        *r_nofile = 1;
-      else
+      oldmask = umask (077);
+      if (is_secured_filename (fname))
         {
-          FILE *fp;
-          TRUSTREC rec;
-          int rc;
-          char *p = strrchr (fname, DIRSEP_C);
-          mode_t oldmask;
-          int save_slash;
-
-#if HAVE_W32_SYSTEM
-          {
-            /* Windows may either have a slash or a backslash.  Take
-               care of it.  */
-            char *pp = strrchr (fname, '/');
-            if (!p || pp > p)
-              p = pp;
-          }
-#endif /*HAVE_W32_SYSTEM*/
-          assert (p);
-          save_slash = *p;
-          *p = 0;
-          if (access (fname, F_OK))
-            {
-              try_make_homedir (fname);
-              if (access (fname, F_OK))
-                log_fatal (_("%s: directory does not exist!\n"), fname);
-           }
-          *p = save_slash;
-
-          oldmask = umask (077);
-          if (is_secured_filename (fname))
-            {
-              fp = NULL;
-              gpg_err_set_errno (EPERM);
-            }
-          else
-            fp = fopen (fname, "wb");
-          umask(oldmask);
-          if (!fp)
-            log_fatal (_("can't create '%s': %s\n"), fname, strerror (errno));
-          fclose (fp);
+          fp = NULL;
+          gpg_err_set_errno (EPERM);
+        }
+      else
+        fp = fopen (fname, "wb");
+      umask(oldmask);
+      if (!fp)
+        log_fatal (_("can't create '%s': %s\n"), fname, strerror (errno));
+      fclose (fp);
 
-          db_fd = open (db_name, O_RDWR | MY_O_BINARY);
-          if (db_fd == -1)
-            log_fatal (_("can't open '%s': %s\n"), db_name, strerror (errno));
+      db_fd = open (db_name, O_RDWR | MY_O_BINARY);
+      if (db_fd == -1)
+        log_fatal (_("can't open '%s': %s\n"), db_name, strerror (errno));
 
-          rc = create_version_record ();
-          if (rc)
-            log_fatal (_("%s: failed to create version record: %s"),
-                       fname, gpg_strerror (rc));
+      rc = create_version_record (ctrl);
+      if (rc)
+        log_fatal (_("%s: failed to create version record: %s"),
+                   fname, gpg_strerror (rc));
 
-          /* Read again to check that we are okay. */
-          if (tdbio_read_record (0, &rec, RECTYPE_VER))
-            log_fatal (_("%s: invalid trustdb created\n"), db_name);
+      /* Read again to check that we are okay. */
+      if (tdbio_read_record (0, &rec, RECTYPE_VER))
+        log_fatal (_("%s: invalid trustdb created\n"), db_name);
 
-          if (!opt.quiet)
-            log_info (_("%s: trustdb created\n"), db_name);
-       }
+      if (!opt.quiet)
+        log_info (_("%s: trustdb created\n"), db_name);
     }
 
   release_write_lock ();
@@ -745,7 +758,7 @@ open_db ()
 {
   TRUSTREC rec;
 
-  assert( db_fd == -1 );
+  log_assert( db_fd == -1 );
 
 #ifdef HAVE_W32CE_SYSTEM
   {
@@ -794,7 +807,7 @@ open_db ()
  * the function terminates the process.
  */
 static void
-create_hashtable( TRUSTREC *vr, int type )
+create_hashtable (ctrl_t ctrl, TRUSTREC *vr, int type)
 {
   TRUSTREC rec;
   off_t offset;
@@ -805,7 +818,7 @@ create_hashtable( TRUSTREC *vr, int type )
   if (offset == -1)
     log_fatal ("trustdb: lseek to end failed: %s\n", strerror(errno));
   recnum = offset / TRUST_RECORD_LEN;
-  assert (recnum); /* This is will never be the first record. */
+  log_assert (recnum); /* This is will never be the first record. */
 
   if (!type)
     vr->r.ver.trusthashtbl = recnum;
@@ -817,13 +830,13 @@ create_hashtable( TRUSTREC *vr, int type )
       memset (&rec, 0, sizeof rec);
       rec.rectype = RECTYPE_HTBL;
       rec.recnum = recnum;
-      rc = tdbio_write_record (&rec);
+      rc = tdbio_write_record (ctrl, &rec);
       if (rc)
         log_fatal (_("%s: failed to create hashtable: %s\n"),
                    db_name, gpg_strerror (rc));
     }
   /* Update the version record and flush. */
-  rc = tdbio_write_record (vr);
+  rc = tdbio_write_record (ctrl, vr);
   if (!rc)
     rc = tdbio_sync ();
   if (rc)
@@ -907,7 +920,7 @@ tdbio_read_nextcheck ()
  * Return: True if the stamp actually changed.
  */
 int
-tdbio_write_nextcheck (ulong stamp)
+tdbio_write_nextcheck (ctrl_t ctrl, ulong stamp)
 {
   TRUSTREC vr;
   int rc;
@@ -921,7 +934,7 @@ tdbio_write_nextcheck (ulong stamp)
     return 0;
 
   vr.r.ver.nextcheck = stamp;
-  rc = tdbio_write_record( &vr );
+  rc = tdbio_write_record (ctrl, &vr);
   if (rc)
     log_fatal (_("%s: error writing version record: %s\n"),
                db_name, gpg_strerror (rc));
@@ -951,8 +964,6 @@ get_trusthashrec(void)
       if (rc)
         log_fatal (_("%s: error reading version record: %s\n"),
                    db_name, gpg_strerror (rc) );
-      if (!vr.r.ver.trusthashtbl)
-        create_hashtable (&vr, 0);
 
       trusthashtbl = vr.r.ver.trusthashtbl;
     }
@@ -970,7 +981,7 @@ get_trusthashrec(void)
  * Return: 0 on success or an error code.
  */
 static int
-upd_hashtable (ulong table, byte *key, int keylen, ulong newrecnum)
+upd_hashtable (ctrl_t ctrl, ulong table, byte *key, int keylen, ulong newrecnum)
 {
   TRUSTREC lastrec, rec;
   ulong hashrec, item;
@@ -993,7 +1004,7 @@ upd_hashtable (ulong table, byte *key, int keylen, ulong newrecnum)
   if (!item)  /* Insert a new item into the hash table.  */
     {
       rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = newrecnum;
-      rc = tdbio_write_record (&rec);
+      rc = tdbio_write_record (ctrl, &rec);
       if (rc)
         {
           log_error ("upd_hashtable: write htbl failed: %s\n",
@@ -1058,7 +1069,7 @@ upd_hashtable (ulong table, byte *key, int keylen, ulong newrecnum)
                     {
                       /* Empty slot found.  */
                       rec.r.hlst.rnum[i] = newrecnum;
-                      rc = tdbio_write_record (&rec);
+                      rc = tdbio_write_record (ctrl, &rec);
                       if (rc)
                         log_error ("upd_hashtable: write hlst failed: %s\n",
                                    gpg_strerror (rc));
@@ -1080,8 +1091,8 @@ upd_hashtable (ulong table, byte *key, int keylen, ulong newrecnum)
               else
                 {
                   /* Append a new record to the list.  */
-                  rec.r.hlst.next = item = tdbio_new_recnum ();
-                  rc = tdbio_write_record (&rec);
+                  rec.r.hlst.next = item = tdbio_new_recnum (ctrl);
+                  rc = tdbio_write_record (ctrl, &rec);
                   if (rc)
                     {
                       log_error ("upd_hashtable: write hlst failed: %s\n",
@@ -1092,7 +1103,7 @@ upd_hashtable (ulong table, byte *key, int keylen, ulong newrecnum)
                   rec.rectype = RECTYPE_HLST;
                   rec.recnum = item;
                   rec.r.hlst.rnum[0] = newrecnum;
-                  rc = tdbio_write_record (&rec);
+                  rc = tdbio_write_record (ctrl, &rec);
                   if (rc)
                     log_error ("upd_hashtable: write ext hlst failed: %s\n",
                                gpg_strerror (rc));
@@ -1110,10 +1121,10 @@ upd_hashtable (ulong table, byte *key, int keylen, ulong newrecnum)
           item = rec.recnum; /* Save number of key record.  */
           memset (&rec, 0, sizeof rec);
           rec.rectype = RECTYPE_HLST;
-          rec.recnum = tdbio_new_recnum ();
+          rec.recnum = tdbio_new_recnum (ctrl);
           rec.r.hlst.rnum[0] = item;       /* Old key record */
           rec.r.hlst.rnum[1] = newrecnum; /* and new key record */
-          rc = tdbio_write_record (&rec);
+          rc = tdbio_write_record (ctrl, &rec);
           if (rc)
             {
               log_error( "upd_hashtable: write new hlst failed: %s\n",
@@ -1122,7 +1133,7 @@ upd_hashtable (ulong table, byte *key, int keylen, ulong newrecnum)
             }
           /* Update the hashtable record.  */
           lastrec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = rec.recnum;
-          rc = tdbio_write_record (&lastrec);
+          rc = tdbio_write_record (ctrl, &lastrec);
           if (rc)
             log_error ("upd_hashtable: update htbl failed: %s\n",
                        gpg_strerror (rc));
@@ -1133,7 +1144,7 @@ upd_hashtable (ulong table, byte *key, int keylen, ulong newrecnum)
           log_error ("hashtbl %lu: %lu/%d points to an invalid record %lu\n",
                      table, hashrec, (msb % ITEMS_PER_HTBL_RECORD), item);
           if (opt.verbose > 1)
-            list_trustdb (es_stderr, NULL);
+            list_trustdb (ctrl, es_stderr, NULL);
           return GPG_ERR_TRUSTDB;
        }
     }
@@ -1149,7 +1160,8 @@ upd_hashtable (ulong table, byte *key, int keylen, ulong newrecnum)
  * Return: 0 on success or an error code.
  */
 static int
-drop_from_hashtable (ulong table, byte *key, int keylen, ulong recnum)
+drop_from_hashtable (ctrl_t ctrl, ulong table,
+                     byte *key, int keylen, ulong recnum)
 {
   TRUSTREC rec;
   ulong hashrec, item;
@@ -1175,7 +1187,7 @@ drop_from_hashtable (ulong table, byte *key, int keylen, ulong recnum)
   if (item == recnum) /* Table points direct to the record.  */
     {
       rec.r.htbl.item[msb % ITEMS_PER_HTBL_RECORD] = 0;
-      rc = tdbio_write_record( &rec );
+      rc = tdbio_write_record (ctrl, &rec);
       if (rc)
         log_error ("drop_from_hashtable: write htbl failed: %s\n",
                    gpg_strerror (rc));
@@ -1211,7 +1223,7 @@ drop_from_hashtable (ulong table, byte *key, int keylen, ulong recnum)
               if (rec.r.hlst.rnum[i] == recnum)
                 {
                   rec.r.hlst.rnum[i] = 0; /* Mark as free.  */
-                  rc = tdbio_write_record (&rec);
+                  rc = tdbio_write_record (ctrl, &rec);
                   if (rc)
                     log_error("drop_from_hashtable: write htbl failed: %s\n",
                               gpg_strerror (rc));
@@ -1245,10 +1257,9 @@ drop_from_hashtable (ulong table, byte *key, int keylen, ulong recnum)
  * the result in REC.  The return value of CMP() should be True if the
  * record is the desired one.
  *
- * Return: -1 if not found, 0 if found or another error code.
- * FIXME: Use GPG_ERR_NOT_FOUND instead of -1.
+ * Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code.
  */
-static int
+static gpg_error_t
 lookup_hashtable (ulong table, const byte *key, size_t keylen,
                  int (*cmpfnc)(const void*, const TRUSTREC *),
                   const void *cmpdata, TRUSTREC *rec )
@@ -1271,7 +1282,7 @@ lookup_hashtable (ulong table, const byte *key, size_t keylen,
 
   item = rec->r.htbl.item[msb % ITEMS_PER_HTBL_RECORD];
   if (!item)
-    return -1; /* Not found. */
+    return gpg_error (GPG_ERR_NOT_FOUND);
 
   rc = tdbio_read_record (item, rec, 0);
   if (rc)
@@ -1327,14 +1338,14 @@ lookup_hashtable (ulong table, const byte *key, size_t keylen,
                }
            }
           else
-            return -1; /* not found */
+            return gpg_error (GPG_ERR_NOT_FOUND);
        }
     }
 
   if ((*cmpfnc)(cmpdata, rec))
     return 0; /* really found */
 
-  return -1; /* no: not found */
+  return gpg_error (GPG_ERR_NOT_FOUND); /* no: not found */
 }
 
 
@@ -1345,9 +1356,9 @@ lookup_hashtable (ulong table, const byte *key, size_t keylen,
  * Return: 0 on success or an error code.
  */
 static int
-update_trusthashtbl( TRUSTREC *tr )
+update_trusthashtbl (ctrl_t ctrl, TRUSTREC *tr)
 {
-  return upd_hashtable (get_trusthashrec(),
+  return upd_hashtable (ctrl, get_trusthashrec (),
                         tr->r.trust.fingerprint, 20, tr->recnum);
 }
 
@@ -1498,13 +1509,16 @@ tdbio_read_record (ulong recnum, TRUSTREC *rec, int expected)
           rec->r.ver.trust_model = *p++;
           rec->r.ver.min_cert_level = *p++;
           p += 2;
-          rec->r.ver.created  = buf32_to_ulong(p); p += 4;
-          rec->r.ver.nextcheck = buf32_to_ulong(p); p += 4;
+          rec->r.ver.created  = buf32_to_ulong(p);
+          p += 4;
+          rec->r.ver.nextcheck = buf32_to_ulong(p);
           p += 4;
           p += 4;
-          rec->r.ver.firstfree =buf32_to_ulong(p); p += 4;
           p += 4;
-          rec->r.ver.trusthashtbl =buf32_to_ulong(p); p += 4;
+          rec->r.ver.firstfree = buf32_to_ulong(p);
+          p += 4;
+          p += 4;
+          rec->r.ver.trusthashtbl = buf32_to_ulong(p);
           if (recnum)
             {
               log_error( _("%s: version record with recnum %lu\n"), db_name,
@@ -1521,37 +1535,43 @@ tdbio_read_record (ulong recnum, TRUSTREC *rec, int expected)
       break;
 
     case RECTYPE_FREE:
-      rec->r.free.next  = buf32_to_ulong(p); p += 4;
+      rec->r.free.next  = buf32_to_ulong(p);
       break;
 
     case RECTYPE_HTBL:
       for (i=0; i < ITEMS_PER_HTBL_RECORD; i++)
         {
-          rec->r.htbl.item[i] = buf32_to_ulong(p); p += 4;
+          rec->r.htbl.item[i] = buf32_to_ulong(p);
+          p += 4;
        }
       break;
 
     case RECTYPE_HLST:
-      rec->r.hlst.next = buf32_to_ulong(p); p += 4;
+      rec->r.hlst.next = buf32_to_ulong(p);
+      p += 4;
       for (i=0; i < ITEMS_PER_HLST_RECORD; i++)
         {
-          rec->r.hlst.rnum[i] = buf32_to_ulong(p); p += 4;
+          rec->r.hlst.rnum[i] = buf32_to_ulong(p);
+          p += 4;
        }
       break;
 
     case RECTYPE_TRUST:
-      memcpy (rec->r.trust.fingerprint, p, 20); p+=20;
+      memcpy (rec->r.trust.fingerprint, p, 20);
+      p+=20;
       rec->r.trust.ownertrust = *p++;
       rec->r.trust.depth = *p++;
       rec->r.trust.min_ownertrust = *p++;
       p++;
-      rec->r.trust.validlist = buf32_to_ulong(p); p += 4;
+      rec->r.trust.validlist = buf32_to_ulong(p);
       break;
 
     case RECTYPE_VALID:
-      memcpy (rec->r.valid.namehash, p, 20); p+=20;
+      memcpy (rec->r.valid.namehash, p, 20);
+      p+=20;
       rec->r.valid.validity = *p++;
-      rec->r.valid.next = buf32_to_ulong(p); p += 4;
+      rec->r.valid.next = buf32_to_ulong(p);
+      p += 4;
       rec->r.valid.full_count = *p++;
       rec->r.valid.marginal_count = *p++;
       break;
@@ -1573,7 +1593,7 @@ tdbio_read_record (ulong recnum, TRUSTREC *rec, int expected)
  * Return: 0 on success or an error code.
  */
 int
-tdbio_write_record( TRUSTREC *rec )
+tdbio_write_record (ctrl_t ctrl, TRUSTREC *rec)
 {
   byte buf[TRUST_RECORD_LEN];
   byte *p;
@@ -1657,7 +1677,7 @@ tdbio_write_record( TRUSTREC *rec )
   if (rc)
     ;
   else if (rec->rectype == RECTYPE_TRUST)
-    rc = update_trusthashtbl (rec);
+    rc = update_trusthashtbl (ctrl, rec);
 
   return rc;
 }
@@ -1669,7 +1689,7 @@ tdbio_write_record( TRUSTREC *rec )
  * Return: 0 on success or an error code.
  */
 int
-tdbio_delete_record (ulong recnum)
+tdbio_delete_record (ctrl_t ctrl, ulong recnum)
 {
   TRUSTREC vr, rec;
   int rc;
@@ -1680,14 +1700,14 @@ tdbio_delete_record (ulong recnum)
     ;
   else if (rec.rectype == RECTYPE_TRUST)
     {
-      rc = drop_from_hashtable (get_trusthashrec(),
+      rc = drop_from_hashtable (ctrl, get_trusthashrec(),
                                 rec.r.trust.fingerprint, 20, rec.recnum);
     }
 
   if (rc)
     return rc;
 
-  /* Now we can chnage it to a free record.  */
+  /* Now we can change it to a free record.  */
   rc = tdbio_read_record (0, &vr, RECTYPE_VER);
   if (rc)
     log_fatal (_("%s: error reading version record: %s\n"),
@@ -1697,9 +1717,9 @@ tdbio_delete_record (ulong recnum)
   rec.rectype = RECTYPE_FREE;
   rec.r.free.next = vr.r.ver.firstfree;
   vr.r.ver.firstfree = recnum;
-  rc = tdbio_write_record (&rec);
+  rc = tdbio_write_record (ctrl, &rec);
   if (!rc)
-    rc = tdbio_write_record (&vr);
+    rc = tdbio_write_record (ctrl, &vr);
 
   return rc;
 }
@@ -1709,7 +1729,7 @@ tdbio_delete_record (ulong recnum)
  * Create a new record and return its record number.
  */
 ulong
-tdbio_new_recnum ()
+tdbio_new_recnum (ctrl_t ctrl)
 {
   off_t offset;
   ulong recnum;
@@ -1733,7 +1753,7 @@ tdbio_new_recnum ()
        }
       /* Update dir record.  */
       vr.r.ver.firstfree = rec.r.free.next;
-      rc = tdbio_write_record (&vr);
+      rc = tdbio_write_record (ctrl, &vr);
       if (rc)
         {
           log_error (_("%s: error writing dir record: %s\n"),
@@ -1745,7 +1765,7 @@ tdbio_new_recnum ()
       rec.rectype = 0; /* Mark as unused record (actually already done
                           my the memset).  */
       rec.recnum = recnum;
-      rc = tdbio_write_record (&rec);
+      rc = tdbio_write_record (ctrl, &rec);
       if (rc)
         log_fatal (_("%s: failed to zero a record: %s\n"),
                    db_name, gpg_strerror (rc));
@@ -1756,7 +1776,7 @@ tdbio_new_recnum ()
       if (offset == (off_t)(-1))
         log_fatal ("trustdb: lseek to end failed: %s\n", strerror (errno));
       recnum = offset / TRUST_RECORD_LEN;
-      assert (recnum); /* this is will never be the first record */
+      log_assert (recnum); /* this is will never be the first record */
       /* We must write a record, so that the next call to this
        * function returns another recnum.  */
       memset (&rec, 0, sizeof rec);
@@ -1805,10 +1825,9 @@ cmp_trec_fpr ( const void *fpr, const TRUSTREC *rec )
  * Given a 20 byte FINGERPRINT search its trust record and return
  * that at REC.
  *
- * Return: -1 if not found, 0 if found or another error code.
- * FIXME: Use GPG_ERR_NOT_FOUND instead of -1.
+ * Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code.
  */
-int
+gpg_error_t
 tdbio_search_trust_byfpr (const byte *fingerprint, TRUSTREC *rec)
 {
   int rc;
@@ -1824,10 +1843,9 @@ tdbio_search_trust_byfpr (const byte *fingerprint, TRUSTREC *rec)
  * Given a primary public key object PK search its trust record and
  * return that at REC.
  *
- * Return: -1 if not found, 0 if found or another error code.
- * FIXME: Use GPG_ERR_NOT_FOUND instead of -1.
+ * Return: 0 if found, GPG_ERR_NOT_FOUND, or another error code.
  */
-int
+gpg_error_t
 tdbio_search_trust_bypk (PKT_public_key *pk, TRUSTREC *rec)
 {
   byte fingerprint[MAX_FINGERPRINT_LEN];