Epxerimenta support for GDBM keyings.
authorWerner Koch <wk@gnupg.org>
Wed, 21 Oct 1998 17:34:36 +0000 (17:34 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 21 Oct 1998 17:34:36 +0000 (17:34 +0000)
36 files changed:
ChangeLog
NEWS
PROJECTS
THANKS
TODO
VERSION
acinclude.m4
cipher/ChangeLog
cipher/Makefile.am
cipher/pubkey.c
configure.in
doc/DETAILS
g10/ChangeLog
g10/Makefile.am
g10/delkey.c
g10/getkey.c
g10/kbnode.c
g10/keydb.h
g10/keygen.c
g10/keylist.c
g10/mainproc.c
g10/ringedit.c
g10/sign.c
g10/tdbio.c
g10/tdbio.h
g10/trustdb.c
include/ChangeLog
include/distfiles
include/host2net.h [new file with mode: 0644]
include/iobuf.h
scripts/autogen.sh
tools/Makefile.am
util/ChangeLog
util/Makefile.am
util/iobuf.c
util/logger.c

index 6a1ac49..1a25ff3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Wed Oct 21 17:24:24 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in: Removed gettext kludge
+       * acinclude.m4: Add patched AM_WITH_NKS macro
+
+Tue Oct 20 19:03:36 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in: Kludge to make AM_GNU_GETTEXT work,
+       changed some macors to more modern versions. Also
+       changeg the all makefiles to remove duplicate ../intl.
+       * acinclude.m4: Removed the gettext stuff, as this
+       already comes with automake now.
+
 Wed Oct 14 12:11:34 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
        * configure.in (NAME_OF_DEV_RANDOM): New.
diff --git a/NEWS b/NEWS
index 549a869..1e359d0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,18 @@
+
+    * Fixed the gettext configure bug.
+
+    * Kludge for RSA keys: keyid and length of a RSA key are
+      correctly reported, but you get an error if you try to use
+      this key (If you do not have the non-US version).
+
+    * Experimental support for keyrings stored in a GDBM database.
+      This is *much* faster than a standard keyring.  You will notice
+      that the import gets slower with time; the reason is that all
+      new keys are used to verify signatures of previous inserted
+      keys.  Use "--keyring gnupg-gdbm:<name-of-gdbm-file>".  This is
+      not (yet) supported for secret keys.
+
+
 Noteworthy changes in version 0.4.2
 -----------------------------------
 
index 835bf22..10afb99 100644 (file)
--- a/PROJECTS
+++ b/PROJECTS
@@ -1,6 +1,10 @@
 
-  - abstraction of the MPI
+  * abstraction of the MPI
 
-  - Add a way to override the current cipher/md implementations
+  * Add a way to override the current cipher/md implementations
     by others (using extensions)
 
+  * add a fast-import command which does not do the signature checks
+    of other keys (processing of the sdir hintlist).  The signatures
+    may then be verified by a maintainence pass.
+
diff --git a/THANKS b/THANKS
index baaf5f1..88e7c23 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -17,6 +17,8 @@ Ed Boraas             ecxjo@esperanto.org
 Ernst Molitor          ernst.molitor@uni-bonn.de
 Frank Heckenbach       heckenb@mi.uni-erlangen.de
 Gaël Quéri             gqueri@mail.dotcom.fr
+Greg Louis             glouis@dynamicro.on.ca
+Gregory Steuck         steuck@iname.com
 Hendrik Buschkamp      buschkamp@rheumanet.org
 Holger Schurig         holger@d.om.org
 Hugh Daniel            hugh@toad.com
diff --git a/TODO b/TODO
index 6cc2398..a17096a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,6 +1,4 @@
 
-    * There is a new memory leak in update-trustdb :-(
-
     * Fix ;) revocation and expire stuff.
 
     * OpenBSD: dynamic loading with dlopen works on OpenBSD, but:
diff --git a/VERSION b/VERSION
index 2b7c5ae..61f859e 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.4.2
+0.4.2a
index f540edc..fbbe2d0 100644 (file)
@@ -209,83 +209,12 @@ define(WK_CHECK_MLOCK,
   ])
 
 
-######################################################################
-# progtest.m4 from gettext 0.35
-######################################################################
-# Search path for a program which passes the given test.
-# Ulrich Drepper <drepper@cygnus.com>, 1996.
-#
-# This file can be copied and used freely without restrictions.  It can
-# be used in projects which are not available under the GNU Public License
-# but which still want to provide support for the GNU gettext functionality.
-# Please note that the actual code is *not* freely available.
 
-# serial 1
-
-dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
-dnl   TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
-AC_DEFUN(AM_PATH_PROG_WITH_TEST,
-[# Extract the first word of "$2", so it can be a program name with args.
-set dummy $2; ac_word=[$]2
-AC_MSG_CHECKING([for $ac_word])
-AC_CACHE_VAL(ac_cv_path_$1,
-[case "[$]$1" in
-  /*)
-  ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
-  ;;
-  *)
-  IFS="${IFS=   }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-  for ac_dir in ifelse([$5], , $PATH, [$5]); do
-    test -z "$ac_dir" && ac_dir=.
-    if test -f $ac_dir/$ac_word; then
-      if [$3]; then
-       ac_cv_path_$1="$ac_dir/$ac_word"
-       break
-      fi
-    fi
-  done
-  IFS="$ac_save_ifs"
-dnl If no 4th arg is given, leave the cache variable unset,
-dnl so AC_PATH_PROGS will keep looking.
-ifelse([$4], , , [  test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
-])dnl
-  ;;
-esac])dnl
-$1="$ac_cv_path_$1"
-if test -n "[$]$1"; then
-  AC_MSG_RESULT([$]$1)
-else
-  AC_MSG_RESULT(no)
-fi
-AC_SUBST($1)dnl
-])
 
-######################################################################
-# lcmessage.m4 from gettext 0.35
-######################################################################
-# Check whether LC_MESSAGES is available in <locale.h>.
-# Ulrich Drepper <drepper@cygnus.com>, 1995.
-#
-# This file can be copied and used freely without restrictions.  It can
-# be used in projects which are not available under the GNU Public License
-# but which still want to provide support for the GNU gettext functionality.
-# Please note that the actual code is *not* freely available.
 
-# serial 1
 
-AC_DEFUN(AM_LC_MESSAGES,
-  [if test $ac_cv_header_locale_h = yes; then
-    AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
-      [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
-       am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
-    if test $am_cv_val_LC_MESSAGES = yes; then
-      AC_DEFINE(HAVE_LC_MESSAGES)
-    fi
-  fi])
 
-######################################################################
-# gettext.m4 from gettext 0.35
-######################################################################
+
 # Macro to add for using GNU gettext.
 # Ulrich Drepper <drepper@cygnus.com>, 1995.
 #
@@ -294,7 +223,7 @@ AC_DEFUN(AM_LC_MESSAGES,
 # but which still want to provide support for the GNU gettext functionality.
 # Please note that the actual code is *not* freely available.
 
-# serial 5
+# serial 5 + patch (wk 21.10.98)
 
 AC_DEFUN(AM_WITH_NLS,
   [AC_MSG_CHECKING([whether NLS is requested])
@@ -334,14 +263,15 @@ AC_DEFUN(AM_WITH_NLS,
 
           if test "$gt_cv_func_gettext_libc" != "yes"; then
             AC_CHECK_LIB(intl, bindtextdomain,
-              [AC_CACHE_CHECK([for gettext in libintl],
-                gt_cv_func_gettext_libintl,
-                [AC_CHECK_LIB(intl, gettext,
-                 gt_cv_func_gettext_libintl=yes,
-                 gt_cv_func_gettext_libintl=no)],
+              [AC_CHECK_LIB(intl, gettext,
+                gt_cv_func_gettext_libintl=yes,
                 gt_cv_func_gettext_libintl=no)])
           fi
 
+          if test "$gt_cv_func_gettext_libintl" = "yes" ; then
+            LIBS="-lintl $LIBS"
+          fi
+
           if test "$gt_cv_func_gettext_libc" = "yes" \
              || test "$gt_cv_func_gettext_libintl" = "yes"; then
              AC_DEFINE(HAVE_GETTEXT)
@@ -481,6 +411,7 @@ AC_DEFUN(AM_WITH_NLS,
     AC_SUBST(POSUB)
   ])
 
+
 AC_DEFUN(AM_GNU_GETTEXT,
   [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
    AC_REQUIRE([AC_PROG_CC])dnl
index 99cd301..58997ec 100644 (file)
@@ -1,3 +1,7 @@
+Mon Oct 19 18:34:30 1998  me,,,  (wk@tobold)
+
+       * pubkey.c: Hack to allow us to give some info about RSA keys back.
+
 Thu Oct 15 11:47:57 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
        * dynload.c: Support for DLD
index e151de5..1b96cb0 100644 (file)
@@ -2,7 +2,7 @@
 
 gnupg_extensions = tiger twofish
 
-INCLUDES =  -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
+INCLUDES =  -I$(top_srcdir)/include -I$(top_srcdir)/intl
 
 noinst_LIBRARIES = libcipher.a
 if ENABLE_GNUPG_EXTENSIONS
index 62a48a6..5147117 100644 (file)
@@ -309,6 +309,8 @@ pubkey_get_npkey( int algo )
            if( pubkey_table[i].algo == algo )
                return pubkey_table[i].npkey;
     } while( load_pubkey_modules() );
+    if( is_RSA(algo) )   /* special hack, so that we are able to */
+       return 2;         /* see the RSA keyids */
     return 0;
 }
 
@@ -324,6 +326,8 @@ pubkey_get_nskey( int algo )
            if( pubkey_table[i].algo == algo )
                return pubkey_table[i].nskey;
     } while( load_pubkey_modules() );
+    if( is_RSA(algo) )   /* special hack, so that we are able to */
+       return 6;         /* see the RSA keyids */
     return 0;
 }
 
@@ -339,6 +343,8 @@ pubkey_get_nsig( int algo )
            if( pubkey_table[i].algo == algo )
                return pubkey_table[i].nsig;
     } while( load_pubkey_modules() );
+    if( is_RSA(algo) )   /* special hack, so that we are able to */
+       return 1;         /* see the RSA keyids */
     return 0;
 }
 
@@ -354,6 +360,8 @@ pubkey_get_nenc( int algo )
            if( pubkey_table[i].algo == algo )
                return pubkey_table[i].nenc;
     } while( load_pubkey_modules() );
+    if( is_RSA(algo) )   /* special hack, so that we are able to */
+       return 1;         /* see the RSA keyids */
     return 0;
 }
 
@@ -370,6 +378,8 @@ pubkey_nbits( int algo, MPI *pkey )
            if( pubkey_table[i].algo == algo )
                return (*pubkey_table[i].get_nbits)( algo, pkey );
     } while( load_pubkey_modules() );
+    if( is_RSA(algo) ) /* we always wanna see the length of a key :-) */
+       return mpi_get_nbits( pkey[0] );
     return 0;
 }
 
index 28cebf7..93ef19d 100644 (file)
@@ -3,6 +3,9 @@ dnl Configure template for GNUPG
 dnl
 dnl (Process this file with autoconf to produce a configure script.)
 
+dnl Must reset CDPATH so that bash's cd does not print to stdout
+CDPATH=
+
 AC_INIT(g10/g10.c)
 AC_CONFIG_AUX_DIR(scripts)
 AM_CONFIG_HEADER(config.h)
@@ -53,15 +56,12 @@ AC_ARG_WITH(included-zlib,
 [g10_force_zlib=yes], [g10_force_zlib=no] )
 AC_MSG_RESULT($g10_force_zlib)
 
-
-AC_CANONICAL_SYSTEM
-WK_CHECK_CACHE
-
 dnl Checks for programs.
 
-AC_PROG_MAKE_SET
+AC_CANONICAL_SYSTEM
 AC_ARG_PROGRAM
-
+AC_PROG_MAKE_SET
+AM_SANITY_CHECK
 missing_dir=`cd $ac_aux_dir && pwd`
 AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
 AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
@@ -87,6 +87,12 @@ case "${target}" in
        ac_cv_have_dev_random=no
        AC_DEFINE(USE_RAND_W32)
        ;;
+    *-*-hpux*)
+       if test -z "$GCC" ; then
+           CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
+       fi
+       AC_DEFINE(USE_RAND_UNIX)
+       ;;
     *)
        AC_DEFINE(USE_RAND_UNIX)
        ;;
@@ -124,6 +130,8 @@ AC_DEFINE_UNQUOTED(NAME_OF_DEV_URANDOM, "$NAME_OF_DEV_URANDOM")
 
 dnl Checks for libraries.
 
+AM_GNU_GETTEXT
+
 AC_CHECK_LIB(gdbm,gdbm_firstkey)
 
 if test "$try_dynload" = yes ; then
@@ -261,12 +269,8 @@ fi
 fi
 AC_SUBST(ZLIBS)
 
-
-WK_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl )
-
 WK_DO_LINK_FILES
 
-AM_GNU_GETTEXT
 
 AC_OUTPUT([
 Makefile
@@ -280,7 +284,5 @@ doc/Makefile
 tools/Makefile
 zlib/Makefile
 checks/Makefile
-],[echo timestamp >stamp-h; \
-   sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
 ])
 
index c40e86a..0ac48bd 100644 (file)
@@ -349,6 +349,28 @@ There is one enhancement used with the old style packet headers:
 +  that this is the last packet.
 
 
+Usage of gdbm files for keyrings
+================================
+    The key to store the keyblokc is it's fingerpint, other records
+    are used for secondary keys.  fingerprints are always 20 bytes
+    where 16 bit fingerprints are appded with zero.
+    The first byte of the key gives some information on the type of the
+    key.
+      1 = key is a 20 bit fingerprint (16 bytes fpr are padded with zeroes)
+         data is the keyblock
+      2 = key is the complete 8 byte keyid
+         data is a list of 20 byte fingerprints
+      3 = key is the short 4 byte keyid
+         data is a list of 20 byte fingerprints
+      4 = key is the email address
+         data is a list of 20 byte fingerprints
+
+    Data is prepended with a type byte:
+      1 = keyblock
+      2 = list of 20 byte padded fingerprints
+      3 = list of list fingerprints (but how to we key them?)
+
+
 
 
 Other Notes
index 72e0244..f16a600 100644 (file)
@@ -1,3 +1,27 @@
+Wed Oct 21 18:19:36 1998  Michael Roth <mroth@nessie.de>
+
+       * ringedit.c (add_keyblock_resource): Directory is now created.
+       * tdbio.c (tdbio_set_dbname): New info message.
+
+Wed Oct 21 11:52:04 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * trustdb.c (update_trustdb): released keyblock in loop.
+
+       * keylist.c (list_block): New.
+       (list_all): Changed to use list_block.
+
+       * trustdb.c: Completed support for GDBM
+
+       * sign.c (only_old_style): Changed the way force_v3 is handled
+       (sign_file): Ditto.
+       (clearsign_file): Ditto.
+
+       * keygen.c (has_invalid_email_chars): Splitted into mailbox and
+       host part.
+
+       * keylist.c (list_one): Add a merge_keys_and_selfsig.
+       * mainproc.c (proc_tree): Ditto.
+
 Sun Oct 18 11:49:03 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
        * sign.c (only_old_style): Add option force_v3_sigs
index da04fec..7583852 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
-INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
+INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
 EXTRA_DIST = OPTIONS  pubring.asc
 OMIT_DEPENDENCIES = zlib.h zconf.h
 LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@
@@ -76,7 +76,7 @@ gpgm_SOURCES = dearmor.c     \
 #             $(common_source)
 
 
-LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@
+LDADD =  $(needed_libs) @ZLIBS@ @INTLLIBS@
 
 gpgm_LDADD = g10maint.o $(LDADD)
 
index 2105284..b84a8bf 100644 (file)
@@ -1,4 +1,4 @@
-/* delkey.c - delte keys
+/* delkey.c - delete keys
  *     Copyright (C) 1998 Free Software Foundation, Inc.
  *
  * This file is part of GNUPG.
index 3aa1203..1756a35 100644 (file)
@@ -683,6 +683,182 @@ merge_keys_and_selfsig( KBNODE keyblock )
 }
 
 
+static KBNODE
+find_by_name( KBNODE keyblock, PKT_public_key *pk, const char *name,
+             int mode, byte *namehash, int *use_namehash )
+{
+    KBNODE k, kk;
+
+    for(k=keyblock; k; k = k->next ) {
+       if( k->pkt->pkttype == PKT_USER_ID
+           && !compare_name( k->pkt->pkt.user_id->name,
+                             k->pkt->pkt.user_id->len, name, mode)) {
+           /* we found a matching name, look for the key */
+           for(kk=keyblock; kk; kk = kk->next ) {
+               if( (    kk->pkt->pkttype == PKT_PUBLIC_KEY
+                     || kk->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+                   && ( !pk->pubkey_algo
+                        || pk->pubkey_algo
+                           == kk->pkt->pkt.public_key->pubkey_algo)
+                   && ( !pk->pubkey_usage
+                        || !check_pubkey_algo2(
+                              kk->pkt->pkt.public_key->pubkey_algo,
+                                                  pk->pubkey_usage ))
+                 )
+                   break;
+           }
+           if( kk ) {
+               u32 aki[2];
+               keyid_from_pk( kk->pkt->pkt.public_key, aki );
+               cache_user_id( k->pkt->pkt.user_id, aki );
+               rmd160_hash_buffer( namehash,
+                                   k->pkt->pkt.user_id->name,
+                                   k->pkt->pkt.user_id->len );
+               *use_namehash = 1;
+               return kk;
+           }
+           else if( is_RSA(pk->pubkey_algo) )
+               log_error("RSA key cannot be used in this version\n");
+           else
+               log_error("No key for userid\n");
+       }
+    }
+    return NULL;
+}
+
+
+static KBNODE
+find_by_keyid( KBNODE keyblock, PKT_public_key *pk, u32 *keyid, int mode )
+{
+    KBNODE k;
+
+    if( DBG_CACHE )
+       log_debug("lookup keyid=%08lx%08lx req_algo=%d mode=%d\n",
+                  (ulong)keyid[0], (ulong)keyid[1], pk->pubkey_algo, mode );
+
+    for(k=keyblock; k; k = k->next ) {
+       if(    k->pkt->pkttype == PKT_PUBLIC_KEY
+           || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
+           u32 aki[2];
+           keyid_from_pk( k->pkt->pkt.public_key, aki );
+           if( DBG_CACHE )
+               log_debug("         aki=%08lx%08lx algo=%d\n",
+                               (ulong)aki[0], (ulong)aki[1],
+                                k->pkt->pkt.public_key->pubkey_algo    );
+
+           if( aki[1] == keyid[1]
+               && ( mode == 10 || aki[0] == keyid[0] )
+               && ( !pk->pubkey_algo
+                    || pk->pubkey_algo
+                       == k->pkt->pkt.public_key->pubkey_algo) ){
+               KBNODE kk;
+               /* cache the userid */
+               for(kk=keyblock; kk; kk = kk->next )
+                   if( kk->pkt->pkttype == PKT_USER_ID )
+                       break;
+               if( kk )
+                   cache_user_id( kk->pkt->pkt.user_id, aki );
+               else
+                   log_error("No userid for key\n");
+               return k; /* found */
+           }
+       }
+    }
+    return NULL;
+}
+
+
+static KBNODE
+find_first( KBNODE keyblock, PKT_public_key *pk )
+{
+    KBNODE k;
+
+    for(k=keyblock; k; k = k->next ) {
+       if(    k->pkt->pkttype == PKT_PUBLIC_KEY
+           || k->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+       {
+           if( !pk->pubkey_algo
+               || pk->pubkey_algo == k->pkt->pkt.public_key->pubkey_algo )
+               return k;
+       }
+    }
+    return NULL;
+}
+
+
+static KBNODE
+find_by_fpr( KBNODE keyblock, PKT_public_key *pk, const char *name, int mode )
+{
+    KBNODE k;
+
+    for(k=keyblock; k; k = k->next ) {
+       if(    k->pkt->pkttype == PKT_PUBLIC_KEY
+           || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
+           byte afp[MAX_FINGERPRINT_LEN];
+           size_t an;
+
+           fingerprint_from_pk(k->pkt->pkt.public_key, afp, &an );
+
+           if( DBG_CACHE ) {
+               u32 aki[2];
+               keyid_from_pk( k->pkt->pkt.public_key, aki );
+               log_debug("         aki=%08lx%08lx algo=%d mode=%d an=%u\n",
+                               (ulong)aki[0], (ulong)aki[1],
+                       k->pkt->pkt.public_key->pubkey_algo, mode, an );
+           }
+
+           if( an == mode
+               && !memcmp( afp, name, an)
+               && ( !pk->pubkey_algo
+                    || pk->pubkey_algo == k->pkt->pkt.public_key->pubkey_algo) )
+               return k;
+       }
+    }
+    return NULL;
+}
+
+
+static void
+finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash,
+                                              int use_namehash, int primary )
+{
+    assert(    k->pkt->pkttype == PKT_PUBLIC_KEY
+           || k->pkt->pkttype == PKT_PUBLIC_SUBKEY );
+    assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY );
+    if( primary && !pk->pubkey_usage ) {
+       copy_public_key_new_namehash( pk, keyblock->pkt->pkt.public_key,
+                                     use_namehash? namehash:NULL);
+       merge_one_pk_and_selfsig( keyblock, keyblock );
+    }
+    else {
+       if( primary && pk->pubkey_usage
+           && check_pubkey_algo2( k->pkt->pkt.public_key->pubkey_algo,
+                      pk->pubkey_usage ) == G10ERR_WR_PUBKEY_ALGO ) {
+           /* if the usage is not correct, try to use a subkey */
+           KBNODE save_k = k;
+
+           for( ; k; k = k->next ) {
+               if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY
+                   && !check_pubkey_algo2(
+                           k->pkt->pkt.public_key->pubkey_algo,
+                                            pk->pubkey_usage ) )
+                   break;
+           }
+           if( !k )
+               k = save_k;
+           else
+               log_info(_("using secondary key %08lX "
+                          "instead of primary key %08lX\n"),
+                     (ulong)keyid_from_pk( k->pkt->pkt.public_key, NULL),
+                     (ulong)keyid_from_pk( save_k->pkt->pkt.public_key, NULL)
+                       );
+       }
+
+       copy_public_key_new_namehash( pk, k->pkt->pkt.public_key,
+                                     use_namehash? namehash:NULL);
+       merge_one_pk_and_selfsig( keyblock, k );
+    }
+}
 
 
 
@@ -709,175 +885,87 @@ lookup( PKT_public_key *pk, int mode,  u32 *keyid,
 {
     int rc;
     KBNODE keyblock = NULL;
+    KBNODE k;
     KBPOS kbpos;
     int oldmode = set_packet_list_mode(0);
     byte namehash[20];
     int use_namehash=0;
 
-    rc = enum_keyblocks( 0, &kbpos, &keyblock );
-    if( rc ) {
-       if( rc == -1 )
-           rc = G10ERR_NO_PUBKEY;
-       else if( rc )
-           log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) );
-       goto leave;
-    }
-
-    while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
-       KBNODE k, kk;
-       if( mode < 10 ) { /* name lookup */
-           for(k=keyblock; k; k = k->next ) {
-               if( k->pkt->pkttype == PKT_USER_ID
-                   && !compare_name( k->pkt->pkt.user_id->name,
-                                     k->pkt->pkt.user_id->len, name, mode)) {
-                   /* we found a matching name, look for the key */
-                   for(kk=keyblock; kk; kk = kk->next ) {
-                       if( (    kk->pkt->pkttype == PKT_PUBLIC_KEY
-                             || kk->pkt->pkttype == PKT_PUBLIC_SUBKEY )
-                           && ( !pk->pubkey_algo
-                                || pk->pubkey_algo
-                                   == kk->pkt->pkt.public_key->pubkey_algo)
-                           && ( !pk->pubkey_usage
-                                || !check_pubkey_algo2(
-                                      kk->pkt->pkt.public_key->pubkey_algo,
-                                                          pk->pubkey_usage ))
-                         )
-                           break;
-                   }
-                   if( kk ) {
-                       u32 aki[2];
-                       keyid_from_pk( kk->pkt->pkt.public_key, aki );
-                       cache_user_id( k->pkt->pkt.user_id, aki );
-                       rmd160_hash_buffer( namehash,
-                                           k->pkt->pkt.user_id->name,
-                                           k->pkt->pkt.user_id->len );
-                       use_namehash = 1;
-                       k = kk;
-                       break;
-                   }
-                   else
-                       log_error("No key for userid\n");
-               }
-           }
-       }
-       else { /* keyid or fingerprint lookup */
-           if( DBG_CACHE && (mode== 10 || mode==11) ) {
-               log_debug("lookup keyid=%08lx%08lx req_algo=%d mode=%d\n",
-                               (ulong)keyid[0], (ulong)keyid[1],
-                                pk->pubkey_algo, mode );
-           }
-           for(k=keyblock; k; k = k->next ) {
-               if(    k->pkt->pkttype == PKT_PUBLIC_KEY
-                   || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
-                   if( mode == 10 || mode == 11 ) {
-                       u32 aki[2];
-                       keyid_from_pk( k->pkt->pkt.public_key, aki );
-                       if( DBG_CACHE ) {
-                           log_debug("         aki=%08lx%08lx algo=%d\n",
-                                           (ulong)aki[0], (ulong)aki[1],
-                                   k->pkt->pkt.public_key->pubkey_algo    );
-                       }
-                       if( aki[1] == keyid[1]
-                           && ( mode == 10 || aki[0] == keyid[0] )
-                           && ( !pk->pubkey_algo
-                                || pk->pubkey_algo
-                                   == k->pkt->pkt.public_key->pubkey_algo) ){
-                           /* cache the userid */
-                           for(kk=keyblock; kk; kk = kk->next )
-                               if( kk->pkt->pkttype == PKT_USER_ID )
-                                   break;
-                           if( kk )
-                               cache_user_id( kk->pkt->pkt.user_id, aki );
-                           else
-                               log_error("No userid for key\n");
-                           break; /* found */
-                       }
-                   }
-                   else if( mode == 15 ) { /* get the first key */
-                       if( !pk->pubkey_algo
-                           || pk->pubkey_algo
-                                 == k->pkt->pkt.public_key->pubkey_algo )
-                           break;
-                   }
-                   else if( mode == 16 || mode == 20 ) {
-                       byte afp[MAX_FINGERPRINT_LEN];
-                       size_t an;
+    /* try the quick functions */
+    k = NULL;
+    switch( mode ) {
+      case 10:
+      case 11:
+       rc = locate_keyblock_by_keyid( &kbpos, keyid, mode==10, 0 );
+       if( !rc )
+           rc = read_keyblock( &kbpos, &keyblock );
+       if( !rc )
+           k = find_by_keyid( keyblock, pk, keyid, mode );
+       break;
 
-                       fingerprint_from_pk(k->pkt->pkt.public_key, afp, &an );
+      case 16:
+      case 20:
+       rc = locate_keyblock_by_fpr( &kbpos, name, mode, 0 );
+       if( !rc )
+           rc = read_keyblock( &kbpos, &keyblock );
+       if( !rc )
+           k = find_by_fpr( keyblock, pk, name, mode );
+       break;
 
-                       if( DBG_CACHE ) {
-                           u32 aki[2];
-                           keyid_from_pk( k->pkt->pkt.public_key, aki );
-                           log_debug("         aki=%08lx%08lx algo=%d mode=%d an=%u\n",
-                                           (ulong)aki[0], (ulong)aki[1],
-                                   k->pkt->pkt.public_key->pubkey_algo,
-                                                       mode, an );
-                       }
-                       if( an == mode && !memcmp( afp, name, an)
-                           && ( !pk->pubkey_algo
-                                || pk->pubkey_algo
-                                   == k->pkt->pkt.public_key->pubkey_algo) ) {
-                           break;
-                       }
-                   }
-                   else
-                       BUG();
-               } /* end compare public keys */
-           }
+      default: rc = G10ERR_UNSUPPORTED;
+    }
+    if( !rc ) {
+       if( !k ) {
+           log_error("lookup: key has been located but was not found\n");
+           rc = G10ERR_INV_KEYRING;
        }
-       if( k ) { /* found */
-           assert(    k->pkt->pkttype == PKT_PUBLIC_KEY
-                   || k->pkt->pkttype == PKT_PUBLIC_SUBKEY );
-           assert( keyblock->pkt->pkttype == PKT_PUBLIC_KEY );
-           if( primary && !pk->pubkey_usage ) {
-               copy_public_key_new_namehash( pk, keyblock->pkt->pkt.public_key,
-                                             use_namehash? namehash:NULL);
-               merge_one_pk_and_selfsig( keyblock, keyblock );
-           }
-           else {
-               if( primary && pk->pubkey_usage
-                   && check_pubkey_algo2( k->pkt->pkt.public_key->pubkey_algo,
-                              pk->pubkey_usage ) == G10ERR_WR_PUBKEY_ALGO ) {
-                   /* if the usage is not correct, try to use a subkey */
-                   KBNODE save_k = k;
-
-                   for( ; k; k = k->next ) {
-                       if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY
-                           && !check_pubkey_algo2(
-                                   k->pkt->pkt.public_key->pubkey_algo,
-                                                    pk->pubkey_usage ) )
-                           break;
-                   }
-                   if( !k )
-                       k = save_k;
-                   else
-                       log_info(_("using secondary key %08lX "
-                                  "instead of primary key %08lX\n"),
-                     (ulong)keyid_from_pk( k->pkt->pkt.public_key, NULL),
-                     (ulong)keyid_from_pk( save_k->pkt->pkt.public_key, NULL)
-                               );
-               }
+       else
+           finish_lookup( keyblock, pk, k, namehash, 0, primary );
+    }
 
-               copy_public_key_new_namehash( pk, k->pkt->pkt.public_key,
-                                             use_namehash? namehash:NULL);
-               merge_one_pk_and_selfsig( keyblock, k );
-           }
-           if( ret_keyblock ) {
-               *ret_keyblock = keyblock;
+    /* if this was not possible, loop over all keyblocks
+     * fixme: If one of the resources in the quick functions above
+     *       works, but the key was not found, we will not find it
+     *       in the other resources */
+    if( rc == G10ERR_UNSUPPORTED ) {
+       rc = enum_keyblocks( 0, &kbpos, &keyblock );
+       if( !rc ) {
+           while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
+               if( mode < 10 )
+                   k = find_by_name( keyblock, pk, name, mode,
+                                               namehash, &use_namehash);
+               else if( mode == 10 || mode == 11 )
+                   k = find_by_keyid( keyblock, pk, keyid, mode );
+               else if( mode == 15 )
+                   k = find_first( keyblock, pk );
+               else if( mode == 16 || mode == 20 )
+                   k = find_by_fpr( keyblock, pk, name, mode );
+               else
+                   BUG();
+               if( k ) {
+                   finish_lookup( keyblock, pk, k, namehash,
+                                                   use_namehash, primary );
+                   break; /* found */
+               }
+               release_kbnode( keyblock );
                keyblock = NULL;
            }
-           break; /* enumeration */
        }
-       release_kbnode( keyblock );
-       keyblock = NULL;
+       enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
+       if( rc && rc != -1 )
+           log_error("enum_keyblocks failed: %s\n", g10_errstr(rc));
     }
-    if( rc == -1 )
+
+    if( !rc ) {
+       if( ret_keyblock ) {
+           *ret_keyblock = keyblock;
+           keyblock = NULL;
+       }
+    }
+    else if( rc == -1 )
        rc = G10ERR_NO_PUBKEY;
-    else if( rc )
-       log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
 
-  leave:
-    enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
+
     release_kbnode( keyblock );
     set_packet_list_mode(oldmode);
     if( opt.debug & DBG_MEMSTAT_VALUE ) {
index 18b16d0..1048f31 100644 (file)
@@ -46,6 +46,7 @@ new_kbnode( PACKET *pkt )
     n->pkt = pkt;
     n->flag = 0;
     n->private_flag=0;
+    n->recno = 0;
     return n;
 }
 
index 229e525..f93d05a 100644 (file)
@@ -46,6 +46,7 @@ struct kbnode_struct {
     PACKET *pkt;
     int flag;
     int private_flag;
+    ulong recno;  /* used while updating the trustdb */
 };
 
 
@@ -69,6 +70,7 @@ struct keyblock_pos_struct {
     int secret;      /* working on a secret keyring */
   #ifdef HAVE_LIBGDBM
     GDBM_FILE dbf;
+    byte keybuf[21];
   #endif
     PACKET *pkt;     /* ditto */
 };
@@ -172,6 +174,10 @@ const char *enum_keyblock_resources( int *sequence, int secret );
 int add_keyblock_resource( const char *resname, int force, int secret );
 const char *keyblock_resource_name( KBPOS *kbpos );
 int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos );
+int locate_keyblock_by_fpr( KBPOS *kbpos, const byte *fpr,
+                                           int fprlen, int secret );
+int locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid,
+                                           int shortkid, int secret );
 int find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos );
 int find_keyblock_byname( KBPOS *kbpos, const char *username );
 int find_keyblock_bypk( KBPOS *kbpos, PKT_public_key *pk );
index 1aac84f..6b04971 100644 (file)
@@ -541,10 +541,18 @@ ask_expiredate()
 static int
 has_invalid_email_chars( const char *s )
 {
+    int at_seen=0;
+
     for( ; *s; s++ ) {
        if( *s & 0x80 )
            return 1;
-       if( !strchr("01234567890abcdefghijklmnopqrstuvwxyz_-.@", *s ) )
+       if( *s == '@' )
+           at_seen=1;
+       else if( !at_seen
+                && !strchr("01234567890abcdefghijklmnopqrstuvwxyz_-.+", *s ))
+           return 1;
+       else if( at_seen
+                && !strchr("01234567890abcdefghijklmnopqrstuvwxyz_-.", *s ) )
            return 1;
     }
     return 0;
index 69e9b52..a1150cd 100644 (file)
@@ -37,6 +37,7 @@
 
 static void list_all(int);
 static void list_one(const char *name, int secret);
+static void list_keyblock( KBNODE keyblock, int secret );
 static void fingerprint( PKT_public_key *pk, PKT_secret_key *sk );
 
 
@@ -70,63 +71,87 @@ secret_key_list( int nnames, char **names )
 static void
 list_all( int secret )
 {
-    int i, seq=0;
-    const char *s;
-    IOBUF a;
-
-    /* FIXME: this assumes a keyring resource is a plain keyring file */
-    while( (s = enum_keyblock_resources( &seq, secret )) ) {
-       if( !(a = iobuf_open(s)) ) {
-           log_error(_("can't open %s: %s\n"), s, strerror(errno));
-           continue;
-       }
-       if( seq > 1 )
-           putchar('\n');
-       printf("%s\n", s );
-       for(i=strlen(s); i; i-- )
-           putchar('-');
-       putchar('\n');
+    KBPOS kbpos;
+    KBNODE keyblock = NULL;
+    int rc=0;
+    int lastresno;
+
+    rc = enum_keyblocks( secret? 5:0, &kbpos, &keyblock );
+    if( rc ) {
+       if( rc != -1 )
+           log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) );
+       goto leave;
+    }
 
-       proc_packets( a );
-       iobuf_close(a);
+    lastresno = -1;
+    while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
+       if( lastresno != kbpos.resno ) {
+           const char *s = keyblock_resource_name( &kbpos );
+           int i;
+
+           lastresno = kbpos.resno;
+           printf("%s\n", s );
+           for(i=strlen(s); i; i-- )
+               putchar('-');
+           putchar('\n');
+       }
+       merge_keys_and_selfsig( keyblock );
+       list_keyblock( keyblock, secret );
+       release_kbnode( keyblock ); keyblock = NULL;
     }
+
+    if( rc && rc != -1 )
+       log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
+
+  leave:
+    enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
+    release_kbnode( keyblock );
 }
 
+
+
 static void
 list_one( const char *name, int secret )
 {
     int rc = 0;
     KBNODE keyblock = NULL;
-    KBNODE kbctx;
-    KBNODE node;
     KBPOS kbpos;
-    PKT_public_key *pk;
-    PKT_secret_key *sk;
-    u32 keyid[2];
-    int any=0;
-    int trustletter = 0;
 
-    /* search the userid */
     rc = secret? find_secret_keyblock_byname( &kbpos, name )
               : find_keyblock_byname( &kbpos, name );
     if( rc ) {
        log_error("%s: user not found\n", name );
-       goto leave;
+       return;
     }
 
-    /* read the keyblock */
     rc = read_keyblock( &kbpos, &keyblock );
     if( rc ) {
        log_error("%s: keyblock read problem: %s\n", name, g10_errstr(rc) );
-       goto leave;
+       return;
     }
+    merge_keys_and_selfsig( keyblock );
+    list_keyblock( keyblock, secret );
+    release_kbnode( keyblock );
+}
 
 
+static void
+list_keyblock( KBNODE keyblock, int secret )
+{
+    int rc = 0;
+    KBNODE kbctx;
+    KBNODE node;
+    PKT_public_key *pk;
+    PKT_secret_key *sk;
+    u32 keyid[2];
+    int any=0;
+    int trustletter = 0;
+
     /* get the keyid from the keyblock */
     node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
     if( !node ) {
        log_error("Oops; key lost!\n");
-       goto leave;
+       return;
     }
 
     if( secret ) {
@@ -336,11 +361,9 @@ list_one( const char *name, int secret )
            putchar(':');
        putchar('\n');
     }
+}
 
 
-  leave:
-    release_kbnode( keyblock );
-}
 
 static void
 fingerprint( PKT_public_key *pk, PKT_secret_key *sk )
index dd1546c..7980c22 100644 (file)
@@ -886,10 +886,14 @@ proc_tree( CTX c, KBNODE node )
     c->local_id = 0;
     c->trustletter = ' ';
     if( node->pkt->pkttype == PKT_PUBLIC_KEY
-       || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+       || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
+       merge_keys_and_selfsig( node );
        list_node( c, node );
-    else if( node->pkt->pkttype == PKT_SECRET_KEY )
+    }
+    else if( node->pkt->pkttype == PKT_SECRET_KEY ) {
+       merge_keys_and_selfsig( node );
        list_node( c, node );
+    }
     else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
        /* check all signatures */
        if( !c->have_data ) {
index 119cd67..e414d05 100644 (file)
@@ -35,8 +35,6 @@
  *
  *  - Delete a key block
  *
- * FIXME:  Keep track of all nodes, so that a change is propagated
- *        to all nodes. (or use shallow copies and ref-counting?)
  */
 
 
 #include "mpi.h"
 #include "iobuf.h"
 #include "keydb.h"
+#include "host2net.h"
 #include "options.h"
 #include "i18n.h"
 
-#undef HAVE_LIBGDBM  /* <--- not ready */
 
 struct resource_table_struct {
     int used;
@@ -88,6 +86,14 @@ static int keyring_read( KBPOS *kbpos, KBNODE *ret_root );
 static int keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs );
 static int keyring_copy( KBPOS *kbpos, int mode, KBNODE root );
 
+#ifdef HAVE_LIBGDBM
+static int do_gdbm_store( KBPOS *kbpos, KBNODE root, int update );
+static int do_gdbm_locate( GDBM_FILE dbf, KBPOS *kbpos,
+                                         const byte *fpr, int fprlen );
+static int do_gdbm_locate_by_keyid( GDBM_FILE dbf, KBPOS *kbpos, u32 *keyid );
+static int do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root );
+static int do_gdbm_enum( KBPOS *kbpos, KBNODE *ret_root );
+#endif
 
 
 static RESTBL *
@@ -100,6 +106,14 @@ check_pos( KBPOS *kbpos )
     return resource_table + kbpos->resno;
 }
 
+#ifdef HAVE_LIBGDBM
+static void
+fatal_gdbm_error( const char *string )
+{
+    log_fatal("gdbm failed: %s\n", string);
+}
+
+#endif /* HAVE_LIBGDBM */
 
 /****************************************************************
  ****************** public functions ****************************
@@ -188,9 +202,33 @@ add_keyblock_resource( const char *url, int force, int secret )
        goto leave;
     }
 
+    /* see whether we can determine the filetype */
+    if( rt == rt_UNKNOWN ) {
+       FILE *fp = fopen( filename, "rb" );
+
+       if( fp ) {
+           u32 magic;
+
+           if( fread( &magic, 4, 1, fp) == 1 ) {
+               if( magic == 0x13579ace )
+                   rt = rt_GDBM;
+               else if( magic == 0xce9a5713 )
+                   log_error("%s: endianess does not match\n", url );
+               else
+                   rt = rt_RING;
+           }
+           fclose( fp );
+       }
+       else /* no file yet: create ring */
+           rt = rt_RING;
+    }
 
     switch( rt ) {
       case rt_UNKNOWN:
+       log_error("%s: unknown resource type\n", url );
+       rc = G10ERR_GENERAL;
+       goto leave;
+
       case rt_RING:
        iobuf = iobuf_fopen( filename, "rb" );
        if( !iobuf && !force ) {
@@ -199,20 +237,46 @@ add_keyblock_resource( const char *url, int force, int secret )
        }
 
        if( !iobuf ) {
+           char *last_slash_in_filename;
+
+           last_slash_in_filename = strrchr(filename, '/');
+           *last_slash_in_filename = 0;
+
+           if( access(filename, F_OK) ) {
+               if( strlen(filename) >= 7
+                   && !strcmp(filename+strlen(filename)-7, "/.gnupg") ) {
+                 #if __MINGW32__
+                   if( mkdir(filename) )
+                 #else
+                   if( mkdir(filename, S_IRUSR|S_IWUSR|S_IXUSR) )
+                 #endif
+                   {
+                       log_error( _("%s: can't create directory: %s\n"),
+                                 filename, strerror(errno));
+                       rc = G10ERR_OPEN_FILE;
+                       goto leave;
+                   }
+                   else
+                       log_info( _("%s: directory created\n"), filename );
+               }
+               else
+               {
+                   rc = G10ERR_OPEN_FILE;
+                   goto leave;
+               }
+           }
+
+           *last_slash_in_filename = '/';
+
            iobuf = iobuf_create( filename );
            if( !iobuf ) {
-               log_error("%s: can't create: %s\n", filename, strerror(errno));
+               log_error("%s: can't create keyring: %s\n", filename, strerror(errno));
                rc = G10ERR_OPEN_FILE;
                goto leave;
            }
            else
                log_info("%s: keyring created\n", filename );
        }
-       /* fixme: see whether it is really a ring or if type is unknown,
-        * try to figure out of what type it is
-        */
-       rt = rt_RING; /* <--- FIXME */
-
       #ifdef __MINGW32__
        /* must close it again */
        iobuf_close( iobuf );
@@ -222,6 +286,17 @@ add_keyblock_resource( const char *url, int force, int secret )
 
     #ifdef HAVE_LIBGDBM
       case rt_GDBM:
+       resource_table[i].dbf = gdbm_open( filename, 0,
+                                          force? GDBM_WRCREAT : GDBM_WRITER,
+                                          S_IRUSR | S_IWUSR |
+                                          S_IRGRP | S_IWGRP | S_IROTH,
+                                          fatal_gdbm_error );
+       if( !resource_table[i].dbf ) {
+           log_error("%s: can't open gdbm file: %s\n",
+                           filename, gdbm_strerror(gdbm_errno));
+           rc = G10ERR_OPEN_FILE;
+           goto leave;
+       }
        break;
     #endif
 
@@ -310,14 +385,21 @@ search( PACKET *pkt, KBPOS *kbpos, int secret )
                                                 resource_table[i].fname );
                break;
             #ifdef HAVE_LIBGDBM
-             case rt_GDBM
-               rc = do_gdbm_search( pkt, kbpos, resource_table[i].dbf,
-                                                resource_table[i].fname );
+             case rt_GDBM: {
+                   PKT_public_key *req_pk = pkt->pkt.public_key;
+                   byte fpr[20];
+                   size_t fprlen;
+
+                   fingerprint_from_pk( req_pk, fpr, &fprlen );
+                   rc = do_gdbm_locate( resource_table[i].dbf,
+                                        kbpos, fpr, fprlen );
+               }
                break;
             #endif
              default: BUG();
            }
 
+           kbpos->rt = resource_table[i].rt;
            if( !rc ) {
                kbpos->resno = i;
                kbpos->fp = NULL;
@@ -404,6 +486,92 @@ find_secret_keyblock_byname( KBPOS *kbpos, const char *username )
 }
 
 
+/****************
+ * Locate a keyblock in a database which is capable of direct access
+ * Put all information into KBPOS, which can be later be to access this
+ * key block.
+ * This function looks into all registered keyblock sources.
+ *
+ * Returns: 0 if found,
+ *         -1 if not found
+ *         G10ERR_UNSUPPORTED if no resource is able to handle this
+ *         or another errorcode.
+ */
+int
+locate_keyblock_by_fpr( KBPOS *kbpos, const byte *fpr, int fprlen, int secret )
+{
+    RESTBL *rentry;
+    int i, rc, any=0, last_rc=-1;
+
+
+    for(i=0, rentry = resource_table; i < MAX_RESOURCES; i++, rentry++ ) {
+       if( rentry->used && !rentry->secret == !secret ) {
+           kbpos->rt = rentry->rt;
+           switch( rentry->rt ) {
+             case rt_GDBM:
+               any = 1;
+               rc = do_gdbm_locate( rentry->dbf, kbpos, fpr, fprlen );
+               break;
+             default:
+               break;
+           }
+
+           if( !rc ) {
+               kbpos->resno = i;
+               kbpos->fp = NULL;
+               return 0;
+           }
+           else if( rc != -1 ) {
+               log_error("error searching resource %d: %s\n",
+                                                 i, g10_errstr(rc));
+               last_rc = rc;
+           }
+       }
+    }
+
+    return (last_rc == -1 && !any)? G10ERR_UNSUPPORTED : last_rc;
+}
+
+
+int
+locate_keyblock_by_keyid( KBPOS *kbpos, u32 *keyid, int shortkid, int secret )
+{
+    RESTBL *rentry;
+    int i, rc, any=0, last_rc=-1;
+
+    if( shortkid )
+       return G10ERR_UNSUPPORTED;
+
+    for(i=0, rentry = resource_table; i < MAX_RESOURCES; i++, rentry++ ) {
+       if( rentry->used && !rentry->secret == !secret ) {
+           kbpos->rt = rentry->rt;
+           switch( rentry->rt ) {
+             case rt_GDBM:
+               any = 1;
+               rc = do_gdbm_locate_by_keyid( rentry->dbf, kbpos, keyid );
+               break;
+             default:
+               break;
+           }
+
+           if( !rc ) {
+               kbpos->resno = i;
+               kbpos->fp = NULL;
+               return 0;
+           }
+           else if( rc != -1 ) {
+               log_error("error searching resource %d: %s\n",
+                                                 i, g10_errstr(rc));
+               last_rc = rc;
+           }
+       }
+    }
+
+    return (last_rc == -1 && !any)? G10ERR_UNSUPPORTED : last_rc;
+}
+
+
+
 
 /****************
  * Lock the keyblock; wait until it's available
@@ -502,7 +670,8 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
            break;
         #ifdef HAVE_LIBGDBM
          case rt_GDBM:
-           /* FIXME!!!! */
+           /* FIXME: make sure that there is only one enum at a time */
+           kbpos->offset = 0;
            break;
         #endif
          default: BUG();
@@ -521,7 +690,7 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
                break;
             #ifdef HAVE_LIBGDBM
              case rt_GDBM:
-               /* FIXME!!!! */
+               rc = do_gdbm_enum( kbpos, ret_root );
                break;
             #endif
              default: BUG();
@@ -548,11 +717,8 @@ enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
                kbpos->fp = NULL;
            }
            break;
-        #ifdef HAVE_LIBGDBM
          case rt_GDBM:
-           /* FIXME!!!! */
            break;
-        #endif
          default: BUG();
        }
        /* release pending packet */
@@ -583,7 +749,7 @@ insert_keyblock( KBPOS *kbpos, KBNODE root )
        break;
      #ifdef HAVE_LIBGDBM
       case rt_GDBM:
-       /* FIXME!!!! */
+       rc = do_gdbm_store( kbpos, root, 0 );
        break;
      #endif
       default: BUG();
@@ -639,7 +805,7 @@ update_keyblock( KBPOS *kbpos, KBNODE root )
        break;
      #ifdef HAVE_LIBGDBM
       case rt_GDBM:
-       /* FIXME!!!! */
+       rc = do_gdbm_store( kbpos, root, 1 );
        break;
      #endif
       default: BUG();
@@ -1129,58 +1295,179 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
  ********** Functions which operates on GDM files ***************
  ****************************************************************/
 
+#if MAX_FINGERPRINT_LEN > 20
+  #error A GDBM keyring assumes that fingerprints are less than 21
+#endif
+
 /****************
- * search one keybox, return 0 if found, -1 if not found or an errorcode.
+ * Insert the keyblock into the GDBM database
  */
+
 static int
-do_gdbm_search( PACKET *req, KBPOS *kbpos, GDBM_FILE dbf, const char *fname )
+do_gdbm_store( KBPOS *kbpos, KBNODE root, int update )
 {
-    int rc;
-    PACKET pkt;
-    int save_mode;
-    ulong offset;
-    int pkttype = req->pkttype;
-    PKT_public_key *req_pk = req->pkt.public_key;
-    PKT_secret_key *req_sk = req->pkt.secret_key;
-
-    init_packet(&pkt);
-    save_mode = set_packet_list_mode(0);
-
+    RESTBL *rentry;
+    PKT_public_key *pk;
+    KBNODE kbctx, node;
+    IOBUF fp = NULL;
+    byte fpr[20];
+    byte contbuf[21];
+    byte keybuf[21];
+    size_t fprlen;
+    datum key, content;
+    int i, rc;
 
-    while( !(rc=search_packet(iobuf, &pkt, pkttype, &offset)) ) {
-       if( pkt.pkttype == PKT_SECRET_KEY ) {
-           PKT_secret_key *sk = pkt.pkt.secret_key;
+    if( !(rentry = check_pos( kbpos )) )
+       return G10ERR_GENERAL;
 
-           if(   req_sk->timestamp == sk->timestamp
-              && req_sk->pubkey_algo == sk->pubkey_algo
-              && !cmp_seckey( req_sk, sk) )
-               break; /* found */
+    /* construct the fingerprint which is used as the primary key */
+    node = find_kbnode( root, PKT_PUBLIC_KEY );
+    if( !node )
+       log_bug("a gdbm database can't store secret keys\n");
+    pk = node->pkt->pkt.public_key;
+
+    fingerprint_from_pk( pk, fpr, &fprlen );
+    for(i=fprlen; i < DIM(fpr); i++ )
+       fpr[i] = 0;
+
+    /* build the keyblock */
+    kbctx=NULL;
+    fp = iobuf_temp();
+    iobuf_put( fp, 1 ); /* data is a keyblock */
+    while( (node = walk_kbnode( root, &kbctx, 0 )) ) {
+       if( (rc = build_packet( fp, node->pkt )) ) {
+           log_error("build_packet(%d) failed: %s\n",
+                       node->pkt->pkttype, g10_errstr(rc) );
+           rc = G10ERR_WRITE_FILE;
+           goto leave;
        }
-       else if( pkt.pkttype == PKT_PUBLIC_KEY ) {
-           PKT_public_key *pk = pkt.pkt.public_key;
-
-           if(   req_pk->timestamp == pk->timestamp
-              && req_pk->pubkey_algo == pk->pubkey_algo
-              && !cmp_pubkey( req_pk, pk ) )
-               break; /* found */
+    }
+    /* store data and key */
+    *keybuf = 1;   /* key is a padded fingerprint */
+    memcpy(keybuf+1, fpr, 20 );
+    key.dptr  = keybuf;
+    key.dsize = 21;
+    content.dptr  = iobuf_get_temp_buffer( fp );
+    content.dsize = iobuf_get_temp_length( fp );
+    rc = gdbm_store( rentry->dbf, key, content,
+                                 update? GDBM_REPLACE : GDBM_INSERT );
+    if( rc ) {
+       log_error("%s: gdbm_store failed: %s\n", rentry->fname,
+                           rc == 1 ? "already stored"
+                                   : gdbm_strerror(gdbm_errno) );
+       rc = G10ERR_WRITE_FILE;
+       goto leave;
+    }
+    /* now store all keyids */
+    *contbuf = 2;  /* data is a list of fingerprints */
+    memcpy(contbuf+1, fpr, 20 );
+    content.dptr = contbuf;
+    content.dsize= 21;
+    kbctx=NULL;
+    while( (node = walk_kbnode( root, &kbctx, 0 )) ) {
+       if(    node->pkt->pkttype == PKT_PUBLIC_KEY
+           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
+           u32 aki[2];
+
+           keyid_from_pk( node->pkt->pkt.public_key, aki );
+           *keybuf = 2; /* key is a 8 byte keyid */
+           u32tobuf( keybuf+1  , aki[0] );
+           u32tobuf( keybuf+5, aki[1] );
+           key.dptr = keybuf;
+           key.dsize= 9;
+           /* fixme: must be more clever when a insert failed:
+            *        build a list of fingerprints in this case */
+           rc = gdbm_store( rentry->dbf, key, content,
+                                         update? GDBM_REPLACE : GDBM_INSERT );
+           if( rc ) {
+               log_info("%s: gdbm_store keyid failed: %s\n", rentry->fname,
+                                   rc == 1 ? "already stored"
+                                           : gdbm_strerror(gdbm_errno) );
+               rc = 0;
+           }
        }
-       else
-           BUG();
-       free_packet(&pkt);
     }
-    if( !rc )
-       kbpos->offset = offset;
 
   leave:
-    free_packet(&pkt);
-    set_packet_list_mode(save_mode);
-  #if __MINGW32__
-    iobuf_close(iobuf);
-  #endif
+    iobuf_close(fp); /* don't need a cancel because it is a temp iobuf */
+    return rc;
+}
+
+
+
+/****************
+ * search one keybox, return 0 if found, -1 if not found or an errorcode.
+ */
+static int
+do_gdbm_locate( GDBM_FILE dbf, KBPOS *kbpos, const byte *fpr, int fprlen )
+{
+    byte *keybuf = kbpos->keybuf;
+    datum key;
+    int i;
+
+    *keybuf = 1;
+    for(i=0; i < fprlen; i++ )
+       keybuf[i+1] = fpr[i];
+    for(; i < 20; i++ )
+       keybuf[i+1] = 0;
+
+    /* fetch the data */
+    key.dptr  = keybuf;
+    key.dsize = 21;
+    if( !gdbm_exists( dbf, key ) )
+       return -1; /* not found */
+    return 0;
+}
+
+/****************
+ * locate by keyid.
+ * FIXME: we must have a way to enumerate thru the list opf fingerprints
+ */
+static int
+do_gdbm_locate_by_keyid( GDBM_FILE dbf, KBPOS *kbpos, u32 *keyid )
+{
+    byte keybuf[9];
+    datum key, content;
+    int rc;
+
+    /* construct the fingerprint which is used as the primary key */
+    *keybuf = 2;
+    u32tobuf( keybuf+1, keyid[0] );
+    u32tobuf( keybuf+5, keyid[1] );
+
+    /* fetch the data */
+    key.dptr  = keybuf;
+    key.dsize = 9;
+    content = gdbm_fetch( dbf, key );
+    if( !content.dptr )
+       return -1;
+
+    if( content.dsize < 2 ) {
+       log_error("gdbm_fetch did not return enough data\n" );
+       free( content.dptr ); /* can't use m_free() here */
+       return G10ERR_INV_KEYRING;
+    }
+    if( *content.dptr != 2 ) {
+       log_error("gdbm_fetch returned unexpected type %d\n",
+                   *(byte*)content.dptr );
+       free( content.dptr ); /* can't use m_free() here */
+       return G10ERR_INV_KEYRING;
+    }
+    if( content.dsize < 21 ) {
+       log_error("gdbm_fetch did not return a complete fingerprint\n" );
+       free( content.dptr ); /* can't use m_free() here */
+       return G10ERR_INV_KEYRING;
+    }
+    if( content.dsize > 21 )
+       log_info("gdbm_fetch: warning: more than one fingerprint\n" );
+
+    rc = do_gdbm_locate( dbf, kbpos, content.dptr+1, 20 );
+    free( content.dptr ); /* can't use m_free() here */
     return rc;
 }
 
 
+
 static int
 do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
 {
@@ -1189,23 +1476,33 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
     RESTBL *rentry;
     KBNODE root = NULL;
     IOBUF a;
-    int in_cert = 0;
+    datum key, content;
 
     if( !(rentry=check_pos(kbpos)) )
        return G10ERR_GENERAL;
 
-    a = iobuf_fopen( rentry->fname, "rb" );
-    if( !a ) {
-       log_error("can't open '%s'\n", rentry->fname );
-       return G10ERR_OPEN_FILE;
+    key.dptr  = kbpos->keybuf;
+    key.dsize = 21;
+    content = gdbm_fetch( rentry->dbf, key );
+    if( !content.dptr ) {
+       log_error("gdbm_fetch failed: %s\n", gdbm_strerror(gdbm_errno) );
+       return G10ERR_INV_KEYRING;
     }
-
-    if( iobuf_seek( a, kbpos->offset ) ) {
-       log_error("can't seek to %lu\n", kbpos->offset);
-       iobuf_close(a);
-       return G10ERR_KEYRING_OPEN;
+    if( content.dsize < 2 ) {
+       log_error("gdbm_fetch did not return enough data\n" );
+       free( content.dptr ); /* can't use m_free() here */
+       return G10ERR_INV_KEYRING;
+    }
+    if( *content.dptr != 1 ) {
+       log_error("gdbm_fetch returned unexpected type %d\n",
+                   *(byte*)content.dptr );
+       free( content.dptr ); /* can't use m_free() here */
+       return G10ERR_INV_KEYRING;
     }
 
+    a = iobuf_temp_with_content( content.dptr+1, content.dsize-1 );
+    free( content.dptr ); /* can't use m_free() here */
+
     pkt = m_alloc( sizeof *pkt );
     init_packet(pkt);
     kbpos->count=0;
@@ -1214,7 +1511,7 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
            if( rc != G10ERR_UNKNOWN_PACKET ) {
                log_error("read_keyblock: read error: %s\n", g10_errstr(rc) );
                rc = G10ERR_INV_KEYRING;
-               goto ready;
+               break;
            }
            kbpos->count++;
            free_packet( pkt );
@@ -1222,27 +1519,16 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
            continue;
        }
        /* make a linked list of all packets */
-       switch( pkt->pkttype ) {
-         case PKT_PUBLIC_KEY:
-         case PKT_SECRET_KEY:
-           if( in_cert )
-               goto ready;
-           in_cert = 1;
-         default:
-           kbpos->count++;
-           if( !root )
-               root = new_kbnode( pkt );
-           else
-               add_kbnode( root, new_kbnode( pkt ) );
-           pkt = m_alloc( sizeof *pkt );
-           init_packet(pkt);
-           break;
-       }
+       kbpos->count++;
+       if( !root )
+           root = new_kbnode( pkt );
+       else
+           add_kbnode( root, new_kbnode( pkt ) );
+       pkt = m_alloc( sizeof *pkt );
+       init_packet(pkt);
     }
-  ready:
     if( rc == -1 && root )
        rc = 0;
-
     if( rc )
        release_kbnode( root );
     else
@@ -1254,84 +1540,43 @@ do_gdbm_read( KBPOS *kbpos, KBNODE *ret_root )
 }
 
 
+/****************
+ * Enum over keyblok data
+ */
 static int
-do_gdbm_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs )
+do_gdbm_enum( KBPOS *kbpos, KBNODE *ret_root )
 {
-    PACKET *pkt;
-    int rc;
     RESTBL *rentry;
-    KBNODE root = NULL;
+    datum key, helpkey;
 
     if( !(rentry=check_pos(kbpos)) )
        return G10ERR_GENERAL;
 
-    if( kbpos->pkt ) {
-       root = new_kbnode( kbpos->pkt );
-       kbpos->pkt = NULL;
+    if( !kbpos->offset ) {
+       kbpos->offset = 1;
+       key = gdbm_firstkey( rentry->dbf );
     }
-
-    pkt = m_alloc( sizeof *pkt );
-    init_packet(pkt);
-    while( (rc=parse_packet(kbpos->fp, pkt)) != -1 ) {
-       if( rc ) {  /* ignore errors */
-           if( rc != G10ERR_UNKNOWN_PACKET ) {
-               log_error("read_keyblock: read error: %s\n", g10_errstr(rc) );
-               rc = G10ERR_INV_KEYRING;
-               goto ready;
-           }
-           free_packet( pkt );
-           init_packet( pkt );
-           continue;
-       }
-       /* make a linked list of all packets */
-       switch( pkt->pkttype ) {
-         case PKT_PUBLIC_KEY:
-         case PKT_SECRET_KEY:
-           if( root ) { /* store this packet */
-               kbpos->pkt = pkt;
-               pkt = NULL;
-               goto ready;
-           }
-           root = new_kbnode( pkt );
-           pkt = m_alloc( sizeof *pkt );
-           init_packet(pkt);
-           break;
-
-         default:
-           /* skip pakets at the beginning of a keyring, until we find
-            * a start packet; issue a warning if it is not a comment */
-           if( !root && pkt->pkttype != PKT_COMMENT
-                     && pkt->pkttype != PKT_OLD_COMMENT ) {
-               log_info("keyring_enum: skipped packet of type %d\n",
-                           pkt->pkttype );
-               break;
-           }
-           if( !root || (skipsigs && ( pkt->pkttype == PKT_SIGNATURE
-                                     ||pkt->pkttype == PKT_COMMENT
-                                     ||pkt->pkttype == PKT_OLD_COMMENT )) ) {
-               init_packet(pkt);
-               break;
-           }
-           add_kbnode( root, new_kbnode( pkt ) );
-           pkt = m_alloc( sizeof *pkt );
-           init_packet(pkt);
-           break;
-       }
+    else {
+       helpkey.dptr = kbpos->keybuf;
+       helpkey.dsize= 21;
+       key = gdbm_nextkey( rentry->dbf, helpkey );
     }
-  ready:
-    if( rc == -1 && root )
-       rc = 0;
-
-    if( rc )
-       release_kbnode( root );
-    else
-       *ret_root = root;
-    free_packet( pkt );
-    m_free( pkt );
+    while( key.dptr && (!key.dsize || *key.dptr != 1) ) {
+       helpkey = key;
+       key = gdbm_nextkey( rentry->dbf, helpkey );
+       free( helpkey.dptr ); /* free and not m_free() ! */
+    }
+    if( !key.dptr )
+       return -1; /* eof */
 
-    return rc;
+    if( key.dsize < 21 ) {
+       free( key.dptr ); /* free and not m_free() ! */
+       log_error("do_gdm_enum: key is too short\n" );
+       return G10ERR_INV_KEYRING;
+    }
+    memcpy( kbpos->keybuf, key.dptr, 21 );
+    free( key.dptr ); /* free and not m_free() ! */
+    return do_gdbm_read( kbpos, ret_root );
 }
 
 #endif /*HAVE_LIBGDBM*/
-
-
index 7404cac..1f4e1ce 100644 (file)
@@ -108,9 +108,6 @@ only_old_style( SK_LIST sk_list )
     SK_LIST sk_rover = NULL;
     int old_style = 0;
 
-    if( opt.force_v3_sigs )
-       return 1;
-
     /* if there are only old style capable key we use the old sytle */
     for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
        PKT_secret_key *sk = sk_rover->sk;
@@ -159,7 +156,6 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
     int compr_algo = -1; /* unknown */
 
 
-
     memset( &afx, 0, sizeof afx);
     memset( &zfx, 0, sizeof zfx);
     memset( &mfx, 0, sizeof mfx);
@@ -181,6 +177,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
        goto leave;
     if( !old_style )
        old_style = only_old_style( sk_list );
+
     if( encrypt ) {
        if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )) )
            goto leave;
@@ -372,7 +369,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
        /* build the signature packet */
        /* fixme: this code is partly duplicated in make_keysig_packet */
        sig = m_alloc_clear( sizeof *sig );
-       sig->version = old_style? 3 : sk->version;
+       sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
        keyid_from_sk( sk, sig->keyid );
        sig->digest_algo = hash_for(sk->pubkey_algo);
        sig->pubkey_algo = sk->pubkey_algo;
@@ -608,7 +605,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
        /* build the signature packet */
        /* fixme: this code is duplicated above */
        sig = m_alloc_clear( sizeof *sig );
-       sig->version = old_style? 3 : sk->version;
+       sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
        keyid_from_sk( sk, sig->keyid );
        sig->digest_algo = hash_for(sk->pubkey_algo);
        sig->pubkey_algo = sk->pubkey_algo;
index 5c1b7f4..76e606e 100644 (file)
@@ -269,7 +269,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
 
     if( access( fname, R_OK ) ) {
        if( errno != ENOENT ) {
-           log_error_f( fname, _("can't access: %s\n"), strerror(errno) );
+           log_error( _("%s: can't access: %s\n"), fname, strerror(errno) );
            m_free(fname);
            return G10ERR_TRUSTDB;
        }
@@ -289,17 +289,19 @@ tdbio_set_dbname( const char *new_dbname, int create )
                  #else
                    if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
                  #endif
-                       log_fatal_f( fname, _("can't create directory: %s\n"),
-                                                           strerror(errno) );
+                       log_fatal( _("%s: can't create directory: %s\n"),
+                                                   fname,  strerror(errno) );
+                   else
+                       log_info( _("%s: directory created\n"), fname );
                }
                else
-                   log_fatal_f(fname, _("directory does not exist!\n") );
+                   log_fatal( _("%s: directory does not exist!\n"), fname );
            }
            *p = '/';
 
            fp =fopen( fname, "wb" );
            if( !fp )
-               log_fatal_f( fname, _("can't create: %s\n"), strerror(errno) );
+               log_fatal( _("%s: can't create: %s\n"), fname, strerror(errno) );
            fclose(fp);
            m_free(db_name);
            db_name = fname;
@@ -309,7 +311,7 @@ tdbio_set_dbname( const char *new_dbname, int create )
            db_fd = open( db_name, O_RDWR );
          #endif
            if( db_fd == -1 )
-               log_fatal_f( db_name, _("can't open: %s\n"), strerror(errno) );
+               log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
 
            memset( &rec, 0, sizeof rec );
            rec.r.ver.version = 2;
@@ -320,11 +322,14 @@ tdbio_set_dbname( const char *new_dbname, int create )
            if( !rc )
                tdbio_sync();
            if( rc )
-               log_fatal_f( fname, _("failed to create version record: %s"),
-                                                              g10_errstr(rc));
+               log_fatal( _("%s: failed to create version record: %s"),
+                                                  fname, g10_errstr(rc));
            /* and read again to check that we are okay */
            if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
-               log_fatal_f( db_name, "invalid trust-db created\n" );
+               log_fatal( _("%s: invalid trust-db created\n"), db_name );
+
+           log_info(_("%s: trust-db created\n"), db_name);
+
            return 0;
        }
     }
@@ -354,9 +359,9 @@ open_db()
     db_fd = open( db_name, O_RDWR );
   #endif
     if( db_fd == -1 )
-       log_fatal_f( db_name, _("can't open: %s\n"), strerror(errno) );
+       log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
     if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
-       log_fatal_f( db_name, _("invalid trust-db\n") );
+       log_fatal( _("%s: invalid trust-db\n"), db_name );
     /* fixme: check ->locked and other stuff */
 }
 
@@ -390,16 +395,16 @@ create_hashtable( TRUSTREC *vr, int type )
         rec.recnum = recnum;
         rc = tdbio_write_record( &rec );
         if( rc )
-            log_fatal_f(db_name,_("failed to create hashtable: %s\n"),
-                                                g10_errstr(rc));
+            log_fatal( _("%s: failed to create hashtable: %s\n"),
+                                       db_name, g10_errstr(rc));
     }
     /* update the version record */
     rc = tdbio_write_record( vr );
     if( !rc )
        rc = tdbio_sync();
     if( rc )
-       log_fatal_f( db_name, _("error updating version record: %s\n"),
-                                                            g10_errstr(rc));
+       log_fatal( _("%s: error updating version record: %s\n"),
+                                                 db_name, g10_errstr(rc));
 }
 
 
@@ -418,8 +423,8 @@ get_keyhashrec()
 
        rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
        if( rc )
-           log_fatal_f( db_name, _("error reading version record: %s\n"),
-                                                           g10_errstr(rc) );
+           log_fatal( _("%s: error reading version record: %s\n"),
+                                           db_name, g10_errstr(rc) );
        if( !vr.r.ver.keyhashtbl )
            create_hashtable( &vr, 0 );
 
@@ -443,8 +448,8 @@ get_sdirhashrec()
 
        rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
        if( rc )
-           log_fatal_f( db_name, _("error reading version record: %s\n"),
-                                                           g10_errstr(rc) );
+           log_fatal( _("%s: error reading version record: %s\n"),
+                                                   db_name, g10_errstr(rc) );
        if( !vr.r.ver.sdirhashtbl )
            create_hashtable( &vr, 1 );
 
@@ -744,14 +749,14 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp  )
                    rec->r.dir.uidlist,
                    rec->r.dir.cacherec,
                    rec->r.dir.ownertrust );
-       if( rec->r.dir.dirflags & DIRF_ERROR )
-           fputs(", error", fp );
-       if( rec->r.dir.dirflags & DIRF_CHECKED )
-           fputs(", checked", fp );
-       if( rec->r.dir.dirflags & DIRF_REVOKED )
-           fputs(", revoked", fp );
-       if( rec->r.dir.dirflags & DIRF_MISKEY )
-           fputs(", miskey", fp );
+       if( rec->r.dir.dirflags & DIRF_CHECKED ) {
+           if( rec->r.dir.dirflags & DIRF_VALID )
+               fputs(", valid", fp );
+           if( rec->r.dir.dirflags & DIRF_EXPIRED )
+               fputs(", expired", fp );
+           if( rec->r.dir.dirflags & DIRF_REVOKED )
+               fputs(", revoked", fp );
+       }
        putc('\n', fp);
        break;
       case RECTYPE_KEY:
@@ -761,8 +766,14 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp  )
                   rec->r.key.pubkey_algo );
        for(i=0; i < rec->r.key.fingerprint_len; i++ )
            fprintf(fp, "%02X", rec->r.key.fingerprint[i] );
-       if( rec->r.key.keyflags & KEYF_REVOKED )
-           fputs(", revoked", fp );
+       if( rec->r.key.keyflags & KEYF_CHECKED ) {
+           if( rec->r.key.keyflags & KEYF_VALID )
+               fputs(", valid", fp );
+           if( rec->r.key.keyflags & KEYF_EXPIRED )
+               fputs(", expired", fp );
+           if( rec->r.key.keyflags & KEYF_REVOKED )
+               fputs(", revoked", fp );
+       }
        putc('\n', fp);
        break;
       case RECTYPE_UID:
@@ -772,12 +783,12 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp  )
                    rec->r.uid.prefrec,
                    rec->r.uid.siglist,
                    rec->r.uid.namehash[18], rec->r.uid.namehash[19]);
-       if( rec->r.uid.uidflags & UIDF_CHECKED )
-           fputs(", checked", fp );
-       if( rec->r.uid.uidflags & UIDF_VALID )
-           fputs(", valid", fp );
-       if( rec->r.uid.uidflags & UIDF_REVOKED )
-           fputs(", revoked", fp );
+       if( rec->r.uid.uidflags & UIDF_CHECKED ) {
+           if( rec->r.uid.uidflags & UIDF_VALID )
+               fputs(", valid", fp );
+           if( rec->r.uid.uidflags & UIDF_REVOKED )
+               fputs(", revoked", fp );
+       }
        putc('\n', fp);
        break;
       case RECTYPE_PREF:
@@ -795,9 +806,19 @@ tdbio_dump_record( TRUSTREC *rec, FILE *fp  )
        fprintf(fp, "sig %lu, next=%lu,",
                         rec->r.sig.lid, rec->r.sig.next );
        for(i=0; i < SIGS_PER_RECORD; i++ ) {
-           if( rec->r.sig.sig[i].lid )
-               fprintf(fp, " %lu:%02x", rec->r.sig.sig[i].lid,
-                                         rec->r.sig.sig[i].flag );
+           if( rec->r.sig.sig[i].lid ) {
+               fprintf(fp, " %lu:", rec->r.sig.sig[i].lid );
+               if( rec->r.sig.sig[i].flag & SIGF_CHECKED ) {
+                   fprintf(fp,"%c%c%c",
+                      (rec->r.sig.sig[i].flag & SIGF_VALID)   ? 'V':'-',
+                      (rec->r.sig.sig[i].flag & SIGF_EXPIRED) ? 'E':'-',
+                      (rec->r.sig.sig[i].flag & SIGF_REVOKED) ? 'R':'-');
+               }
+               else if( rec->r.sig.sig[i].flag & SIGF_NOPUBKEY)
+                   fputs("?--", fp);
+               else
+                   fputs("---", fp);
+           }
        }
        putc('\n', fp);
        break;
@@ -876,7 +897,7 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
        break;
       case RECTYPE_VER: /* version record */
        if( memcmp(buf+1, "gpg", 3 ) ) {
-           log_error_f( db_name, _("not a trustdb file\n") );
+           log_error( _("%s: not a trustdb file\n"), db_name );
            rc = G10ERR_TRUSTDB;
        }
        p += 2; /* skip "pgp" */
@@ -890,12 +911,12 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
        rec->r.ver.firstfree =buftoulong(p); p += 4;
        rec->r.ver.sdirhashtbl =buftoulong(p); p += 4;
        if( recnum ) {
-           log_error_f( db_name, "version record with recnum %lu\n",
+           log_error( _("%s: version record with recnum %lu\n"), db_name,
                                                             (ulong)recnum );
            rc = G10ERR_TRUSTDB;
        }
        else if( rec->r.ver.version != 2 ) {
-           log_error_f( db_name, "invalid file version %d\n",
+           log_error( _("%s: invalid file version %d\n"), db_name,
                                                        rec->r.ver.version );
            rc = G10ERR_TRUSTDB;
        }
@@ -911,8 +932,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
        rec->r.dir.ownertrust = *p++;
        rec->r.dir.dirflags   = *p++;
        if( rec->r.dir.lid != recnum ) {
-           log_error_f( db_name, "dir LID != recnum (%lu,%lu)\n",
-                                        rec->r.dir.lid, (ulong)recnum );
+           log_error( "%s: dir LID != recnum (%lu,%lu)\n",
+                             db_name, rec->r.dir.lid, (ulong)recnum );
            rc = G10ERR_TRUSTDB;
        }
        break;
@@ -957,8 +978,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
        p += 3;
        rec->r.sdir.hintlist = buftoulong(p);
        if( rec->r.sdir.lid != recnum ) {
-           log_error_f( db_name, "sdir LID != recnum (%lu,%lu)\n",
-                                        rec->r.sdir.lid, (ulong)recnum );
+           log_error( "%s: sdir LID != recnum (%lu,%lu)\n",
+                              db_name, rec->r.sdir.lid, (ulong)recnum );
            rc = G10ERR_TRUSTDB;
        }
        break;
@@ -979,8 +1000,8 @@ tdbio_read_record( ulong recnum, TRUSTREC *rec, int expected )
        }
        break;
       default:
-       log_error_f( db_name, "invalid record type %d at recnum %lu\n",
-                                             rec->rectype, (ulong)recnum );
+       log_error( "%s: invalid record type %d at recnum %lu\n",
+                                  db_name, rec->rectype, (ulong)recnum );
        rc = G10ERR_TRUSTDB;
        break;
     }
@@ -1122,8 +1143,8 @@ tdbio_delete_record( ulong recnum )
 
     rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
     if( rc )
-       log_fatal_f( db_name, _("error reading version record: %s\n"),
-                                                       g10_errstr(rc) );
+       log_fatal( _("%s: error reading version record: %s\n"),
+                                      db_name, g10_errstr(rc) );
 
     rec.recnum = recnum;
     rec.rectype = RECTYPE_FREE;
@@ -1149,22 +1170,22 @@ tdbio_new_recnum()
     /* look for unused records */
     rc = tdbio_read_record( 0, &vr, RECTYPE_VER );
     if( rc )
-       log_fatal_f( db_name, _("error reading version record: %s\n"),
-                                                       g10_errstr(rc) );
+       log_fatal( _("%s: error reading version record: %s\n"),
+                                            db_name, g10_errstr(rc) );
     if( vr.r.ver.firstfree ) {
        recnum = vr.r.ver.firstfree;
        rc = tdbio_read_record( recnum, &rec, RECTYPE_FREE );
        if( rc ) {
-           log_error_f( db_name, _("error reading free record: %s\n"),
-                                                           g10_errstr(rc) );
+           log_error( _("%s: error reading free record: %s\n"),
+                                                 db_name,  g10_errstr(rc) );
            return rc;
        }
        /* update dir record */
        vr.r.ver.firstfree = rec.r.free.next;
        rc = tdbio_write_record( &vr );
        if( rc ) {
-           log_error_f( db_name, _("error writing dir record: %s\n"),
-                                                           g10_errstr(rc) );
+           log_error( _("%s: error writing dir record: %s\n"),
+                                                    db_name, g10_errstr(rc) );
            return rc;
        }
        /*zero out the new record */
@@ -1173,8 +1194,8 @@ tdbio_new_recnum()
        rec.recnum = recnum;
        rc = tdbio_write_record( &rec );
        if( rc )
-           log_fatal_f(db_name,_("failed to zero a record: %s\n"),
-                                               g10_errstr(rc));
+           log_fatal(_("%s: failed to zero a record: %s\n"),
+                                      db_name, g10_errstr(rc));
     }
     else { /* not found, append a new record */
        offset = lseek( db_fd, 0, SEEK_END );
@@ -1203,8 +1224,8 @@ tdbio_new_recnum()
        }
 
        if( rc )
-           log_fatal_f(db_name,_("failed to append a record: %s\n"),
-                                               g10_errstr(rc));
+           log_fatal(_("%s: failed to append a record: %s\n"),
+                                   db_name,    g10_errstr(rc));
     }
     return recnum ;
 }
@@ -1230,10 +1251,9 @@ tdbio_search_dir_bypk( PKT_public_key *pk, TRUSTREC *rec )
 
     if( !rc ) {
        if( pk->local_id && pk->local_id != rec->recnum )
-           log_error_f(db_name,
-                      "found record, but LID from memory does "
+           log_error("%s: found record, but LID from memory does "
                       "not match recnum (%lu,%lu)\n",
-                                     pk->local_id, rec->recnum );
+                           db_name,  pk->local_id, rec->recnum );
        pk->local_id = rec->recnum;
     }
     return rc;
@@ -1272,8 +1292,8 @@ tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen,
        /* Now read the dir record */
        rc = tdbio_read_record( recnum, rec, RECTYPE_DIR);
        if( rc )
-           log_error_f(db_name, "can't read dirrec %lu: %s\n",
-                                                   recnum, g10_errstr(rc) );
+           log_error("%s: can't read dirrec %lu: %s\n",
+                                    db_name, recnum, g10_errstr(rc) );
     }
     return rc;
 }
index 2c52b22..68011d4 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef G10_TDBIO_H
 #define G10_TDBIO_H
 
+#include "host2net.h"
 
 #define TRUST_RECORD_LEN 40
 #define SIGS_PER_RECORD        ((TRUST_RECORD_LEN-10)/5)
 #define RECTYPE_FREE 254
 
 
-#define DIRF_CHECKED  1 /* everything has been checked, the other bits are
-                          valid */
-#define DIRF_MISKEY   2 /* not all signatures are checked */
-                       /* this flag is used as a quick hint, that we */
-                       /* do not need to look at the sig records */
-#define DIRF_ERROR    4 /* severe errors: the key is not valid for some reasons
-                          but we mark it to avoid duplicate checks */
+#define DIRF_CHECKED  1 /* has been checkd - other bits are valid */
+#define DIRF_VALID    2 /* This key is valid:  There is at least */
+                       /* one uid with a selfsignature or an revocation */
+#define DIRF_EXPIRED  4 /* the complete key has expired */
 #define DIRF_REVOKED  8 /* the complete key has been revoked */
 
+#define KEYF_CHECKED  1 /* This key has been checked */
+#define KEYF_VALID    2 /* This is a valid (sub)key */
 #define KEYF_EXPIRED  4 /* this key is expired */
 #define KEYF_REVOKED  8 /* this key has been revoked */
 
@@ -64,6 +64,7 @@
 
 #define SIGF_CHECKED  1 /* signature has been checked - bits 0..6 are valid */
 #define SIGF_VALID    2 /* the signature is valid */
+#define SIGF_EXPIRED  4 /* the key of this signature has expired */
 #define SIGF_REVOKED  8 /* this signature has been revoked */
 #define SIGF_NOPUBKEY 128 /* there is no pubkey for this sig */
 
@@ -176,22 +177,4 @@ int tdbio_search_dir_byfpr( const byte *fingerprint, size_t fingerlen,
 int tdbio_search_sdir( u32 *keyid, int pubkey_algo, TRUSTREC *rec );
 
 
-#define buftoulong( p )  ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
-                      (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
-#define buftoushort( p )  ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
-#define ulongtobuf( p, a ) do {                          \
-                           ((byte*)p)[0] = a >> 24;    \
-                           ((byte*)p)[1] = a >> 16;    \
-                           ((byte*)p)[2] = a >>  8;    \
-                           ((byte*)p)[3] = a      ;    \
-                       } while(0)
-#define ushorttobuf( p, a ) do {                          \
-                           ((byte*)p)[0] = a >>  8;    \
-                           ((byte*)p)[1] = a      ;    \
-                       } while(0)
-#define buftou32( p)   buftoulong( (p) )
-#define u32tobuf( p, a) ulongtobuf( (p), (a) )
-
-
-
 #endif /*G10_TDBIO_H*/
index e4a4478..5f391d0 100644 (file)
@@ -1370,6 +1370,8 @@ update_trustdb( )
            else
                log_info("lid %lu: updated\n",
                                lid_from_keyblock(keyblock) );
+
+           release_kbnode( keyblock ); keyblock = NULL;
        }
     }
     if( rc && rc != -1 )
@@ -1910,7 +1912,6 @@ upd_key_record( PKT_public_key *pk, TRUSTREC *drec, RECNO_LIST *recno_list )
     }
     if( recno ) { /* yes */
        ins_recno_list( recno_list, recno, RECTYPE_KEY );
-       /* here we would compare/update the keyflags */
     }
     else { /* no: insert this new key */
        memset( &krec, 0, sizeof(krec) );
@@ -2110,6 +2111,8 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
            }
        }
        else if( sig->sig_class == 0x18 ) { /* key binding */
+           /* get the corresponding key */
+
            /* FIXME */
        }
        else if( sig->sig_class == 0x20 ) { /* key revocation */
@@ -2427,6 +2430,7 @@ update_trust_record( KBNODE keyblock )
     ulong uidrecno = 0;
     byte uidhash[20];
     RECNO_LIST recno_list = NULL; /* list of verified records */
+    /* fixme: replace recno_list by a lookup on node->recno */
 
     node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
     primary_pk = node->pkt->pkt.public_key;
@@ -2459,6 +2463,7 @@ update_trust_record( KBNODE keyblock )
 
          case PKT_SIGNATURE:
            if( drec.dirty ) { /* upd_sig_recrod may read the drec */
+
                write_record( &drec );
                drec.dirty = 0;
            }
index 9274ee9..6cb61d8 100644 (file)
@@ -1,3 +1,7 @@
+Tue Oct 20 11:40:00 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * iobuf.h (iobuf_get_temp_buffer): New.
+
 Tue Oct 13 12:40:48 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
        * iobuf.h (iobuf_get): Now uses .nofast
index 6257e96..191dd88 100644 (file)
@@ -7,6 +7,7 @@ ttyio.h
 types.h
 util.h
 i18n.h
+host2net.h
 
 g10lib.h
 
diff --git a/include/host2net.h b/include/host2net.h
new file mode 100644 (file)
index 0000000..4c14d64
--- /dev/null
@@ -0,0 +1,43 @@
+/* host2net.h - Some macros
+ *     Copyright (C) 1998 Free Software Foundation, Inc.
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef G10_HOST2NET_H
+#define G10_HOST2NET_H
+
+#include "types.h"
+
+#define buftoulong( p )  ((*(byte*)(p) << 24) | (*((byte*)(p)+1)<< 16) | \
+                      (*((byte*)(p)+2) << 8) | (*((byte*)(p)+3)))
+#define buftoushort( p )  ((*((byte*)(p)) << 8) | (*((byte*)(p)+1)))
+#define ulongtobuf( p, a ) do {                          \
+                           ((byte*)p)[0] = a >> 24;    \
+                           ((byte*)p)[1] = a >> 16;    \
+                           ((byte*)p)[2] = a >>  8;    \
+                           ((byte*)p)[3] = a      ;    \
+                       } while(0)
+#define ushorttobuf( p, a ) do {                          \
+                           ((byte*)p)[0] = a >>  8;    \
+                           ((byte*)p)[1] = a      ;    \
+                       } while(0)
+#define buftou32( p)   buftoulong( (p) )
+#define u32tobuf( p, a) ulongtobuf( (p), (a) )
+
+
+#endif /*G10_HOST2NET_H*/
index f09d701..8c836cc 100644 (file)
@@ -71,6 +71,7 @@ int iobuf_debug_mode;
 
 IOBUF iobuf_alloc(int usage, size_t bufsize);
 IOBUF iobuf_temp(void);
+IOBUF iobuf_temp_with_content( const char *buffer, size_t length );
 IOBUF iobuf_open( const char *fname );
 IOBUF iobuf_fopen( const char *fname, const char *mode );
 IOBUF iobuf_create( const char *fname );
@@ -129,6 +130,7 @@ int  iobuf_in_block_mode( IOBUF a );
 #define iobuf_where(a) "[don't know]"
 #define iobuf_id(a)    ((a)->no)
 
+#define iobuf_get_temp_buffer(a) ( (a)->d.buf )
 #define iobuf_get_temp_length(a) ( (a)->d.len )
 #define iobuf_is_temp(a)        ( (a)->usage == 3 )
 
index 17905a1..cba5adc 100755 (executable)
@@ -9,19 +9,25 @@ if (autoconf --version) < /dev/null > /dev/null 2>&1 ; then
 else
     echo
     echo "**Error**: You must have "\`autoconf\'" installed to compile $PGM."
-    echo '           (version 2.10 or newer is required'
+    echo '           (version 2.10 or newer is required)'
     DIE="yes"
 fi
 
 if (automake --version) < /dev/null > /dev/null 2>&1 ; then
   if (aclocal --version) < /dev/null > /dev/null 2>&1; then
-    :
+    if (aclocal --version | awk 'NR==1 { if( $4 >= 1.3 ) exit 1; exit 0; }');
+    then
+      echo "**Error**: "\`aclocal\'" is too old."
+      echo '           (version 1.3 or newer is required)'
+      DIE="yes"
+    fi
   else
     echo
     echo "**Error**: Missing "\`aclocal\'".  The version of "\`automake\'
     echo "           installed doesn't appear recent enough."
     DIE="yes"
   fi
+
 else
     echo
     echo "**Error**: You must have "\`automake\'" installed to compile $PGM."
@@ -40,3 +46,5 @@ automake --gnu;
 autoheader
 autoconf
 
+echo "Ready to run ./configure"
+
index e3c8975..418df21 100644 (file)
@@ -1,8 +1,8 @@
 ## Process this file with automake to produce Makefile.in
 
-INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
+INCLUDES = -I$(top_srcdir)/include
 needed_libs = ../cipher/libcipher.a  ../util/libutil.a \
-             ../mpi/libmpi.a ../util/libutil.a
+             ../mpi/libmpi.a ../util/libutil.a @INTLLIBS@
 
 noinst_PROGRAMS = mpicalc bftest clean-sat mk-tdata shmtest
 
@@ -15,10 +15,10 @@ mk_tdata_SOURCES = mk-tdata.c
 shmtest_SOURCES = shmtest.c
 
 
-mpicalc_LDADD = @INTLLIBS@  $(needed_libs)
-bftest_LDADD = @INTLLIBS@  $(needed_libs)
+mpicalc_LDADD =  $(needed_libs)
+bftest_LDADD = $(needed_libs)
 
-shmtest_LDADD = @INTLLIBS@ $(needed_libs)
+shmtest_LDADD =  $(needed_libs)
 
 mpicalc bftest shmtest: $(needed_libs)
 
index 6904c93..3c1dba6 100644 (file)
@@ -1,3 +1,8 @@
+Wed Oct 21 12:20:29 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * util.c (iobuf_flush): autoincreasing of a temp. iobuf
+       (iobuf_temp_with_content): New.
+
 Tue Oct 13 12:40:13 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
        * util.c (.nofast): set this variable
index eee154e..3f2f9a3 100644 (file)
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
-INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
+INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
 
 noinst_LIBRARIES = libutil.a
 
index e4c4124..e1b62cf 100644 (file)
@@ -483,6 +483,18 @@ iobuf_temp()
     return a;
 }
 
+IOBUF
+iobuf_temp_with_content( const char *buffer, size_t length )
+{
+    IOBUF a;
+
+    a = iobuf_alloc(3, length );
+    memcpy( a->d.buf, buffer, length );
+    a->d.len = length;
+
+    return a;
+}
+
 
 /****************
  * Create a head iobuf for reading from a file
@@ -877,8 +889,19 @@ iobuf_flush(IOBUF a)
        return 0;
 
     /*log_debug("iobuf-%d.%d: flush\n", a->no, a->subno );*/
-    if( a->usage == 3 )
-       log_bug("temp buffer too short\n");
+    if( a->usage == 3 ) { /* must increase the size of the temp buffer */
+       char *newbuf;
+       size_t newsize = a->d.size + 8192;
+
+       log_debug("increasing temp iobuf from %lu to %lu\n",
+                   (ulong)a->d.size, (ulong)newsize );
+       newbuf = m_alloc( newsize );
+       memcpy( newbuf, a->d.buf, a->d.len );
+       m_free(a->d.buf);
+       a->d.buf = newbuf;
+       a->d.size = newsize;
+       return 0;
+    }
     else if( a->usage != 2 )
        log_bug("flush on non-output iobuf\n");
     else if( !a->filter )
index 60f59da..8183abe 100644 (file)
@@ -161,7 +161,7 @@ g10_log_bug( const char *fmt, ... )
     va_list arg_ptr ;
 
     putc('\n', stderr );
-    print_prefix("Ooops: ");
+    print_prefix("Ohhhh jeeee: ");
     va_start( arg_ptr, fmt ) ;
     vfprintf(stderr,fmt,arg_ptr) ;
     va_end(arg_ptr);
@@ -174,7 +174,7 @@ g10_log_bug( const char *fmt, ... )
 void
 g10_log_bug0( const char *file, int line, const char *func )
 {
-    log_bug(_("Ohhhh jeeee ... this is a bug (%s:%d:%s)\n"), file, line, func );
+    log_bug(_("... this is a bug (%s:%d:%s)\n"), file, line, func );
 }
 #else
 void