(Does not compile yet)
authorWerner Koch <wk@gnupg.org>
Tue, 3 Nov 1998 19:38:58 +0000 (19:38 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 3 Nov 1998 19:38:58 +0000 (19:38 +0000)
27 files changed:
Makefile.am
NEWS
PROJECTS
THANKS
TODO
configure.in
doc/gpg.1pod
g10/ChangeLog
g10/export.c
g10/g10.c
g10/import.c
g10/keyedit.c
g10/keygen.c
g10/parse-packet.c
g10/sig-check.c
g10/signal.c
g10/tdbio.c
g10/trustdb.c
g10/trustdb.h
include/util.h
mpi/ChangeLog
mpi/config.links
po/ChangeLog
po/fr.po
util/ChangeLog
util/argparse.c
util/strgutil.c

index 567fccd..68b203a 100644 (file)
@@ -53,7 +53,7 @@ tobold-get:
                      tobold:gnupg/ .
 
 tobold-put:
-       rsync -Cavuzb --excude scratch --exclude .deps \
+       rsync -Cavuzb --exclude scratch --exclude .deps \
                      . tobold:gnupg/
 
 
diff --git a/NEWS b/NEWS
index 17d0330..e1948f6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,8 @@
     * A Russian language file in the distribution (alternatives are in
       the contrib directory of the FTP servers)
 
+    * commandline option processing now works as expected for GNU programs
+      with the execption that you can't mix options and normal arguments.
 
 
 Noteworthy changes in version 0.4.2
index 10afb99..47ed1eb 100644 (file)
--- a/PROJECTS
+++ b/PROJECTS
@@ -8,3 +8,7 @@
     of other keys (processing of the sdir hintlist).  The signatures
     may then be verified by a maintainence pass.
 
+  * Not GnupG replated:  What about option completion in bash?
+    Can "--dump-options" be used for this or should we place the
+    options in a special ELF segment?
+
diff --git a/THANKS b/THANKS
index 88e7c23..be08dde 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -12,9 +12,11 @@ Charles Levert               charles@comm.polymtl.ca
 Christian von Roques   roques@pond.sub.org
 Christopher Oliver     oliver@fritz.traverse.net
 Daniel Eisenbud        eisenbud@cs.swarthmore.edu
+David Ellement         ellement@sdd.hp.com
 Detlef Lannert         lannert@lannert.rz.uni-duesseldorf.de
 Ed Boraas              ecxjo@esperanto.org
 Ernst Molitor          ernst.molitor@uni-bonn.de
+Fabio Coatti           cova@felix.unife.it
 Frank Heckenbach       heckenb@mi.uni-erlangen.de
 Gaël Quéri             gqueri@mail.dotcom.fr
 Greg Louis             glouis@dynamicro.on.ca
@@ -49,9 +51,11 @@ Paul D. Smith                psmith@baynetworks.com
 Peter Gutmann          pgut001@cs.auckland.ac.nz
 QingLong               qinglong@bolizm.ihep.su
 Ralph Gillen           gillen@theochem.uni-duesseldorf.de
+Roddy Strachan         roddy@satlink.com.au
 Roland Rosenfeld       roland@spinnaker.rhein.de
 Serge Munhoven         munhoven@mema.ucl.ac.be
 SL Baur                steve@xemacs.org
+Stefan Karrmann        S.Karrmann@gmx.net
 Steffen Ullrich        ccrlphr@xensei.com
 Steffen Zahn           zahn@berlin.snafu.de
 Thomas Roessler        roessler@guug.de
diff --git a/TODO b/TODO
index e891645..bd5e43f 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,4 +1,27 @@
 
+    * rmove assert in random.c:160 4096 bit keys need more random.
+
+    * list all matching user ids
+
+    * use zlib 1.1.13 to avoid a bug with 13 bit windows
+
+    * FreeBSD:
+#define USE_DYNAMIC_LINKING
+#define HAVE_DL_DLOPEN
+
+and the ld option -export-dynamic.
+
+    *
+Well, there was one thing extra I needed to do.  While configure found the
+gdbm library, it didn't add the path the the include file list.  I had to
+re-run configure with CPPFLAGS set:
+
+    env CPPFLAGS='-I/usr/local/include' configure ...
+
+
+    * clearsig: keep lineendings as they are. Remember that trailings
+      blanks are not hashed.
+
     * Fix ;) revocation and expire stuff.
 
     * check preferences (cipher and compress)
     * prefer a type 16 subkey for encryption because pgp cannot handle
       type 20?
 
-    * calculation of marginals never yields a completely trusted key.
-
     * The critical bit of signature subpackets is not yet supported; i.e.
       it is ignored.
 
-    * Exportable Certification Flag is ignored
-
     * We need a maintainence pass over the trustdb which flags
       signatures as expired if the key used to make the signature has
       expired. Maybe it is a good idea to store the exiration time
     * add an option to re-create a public key from a secret key; we
       can do this in trustdb.c:verify_own_keys.
 
+    * signature verification is done duplicated on import: in import.c and
+      tehn in trustdb.c too.  Maybe we can use a flag to skip the actual
+      verification process (this should work if we use the same keyblock,
+      but I'm not sure how to accomplish that).  Another way is to allow
+      the import of bogus data and let trustdb mark these keys as invalid;
+      I see an advantage in this that it may help to prevent a DoS on a
+      keyserver by sending him a lot of bogus signatures which he has
+      to check - Needs further investigation.
+
     * change the fake_data stuff to mpi_set_opaque
 
     * Is it okay to use gettext for the help system?
index a497b3d..29a4395 100644 (file)
@@ -44,9 +44,9 @@ else
 fi
 if test "$use_m_guard" = yes ; then
     AC_DEFINE(M_GUARD)
-    CFLAGS="-g -Wall"
+    CFLAGS="$CFLAGS -g -Wall"
 else
-    CFLAGS="-O2 -Wall"
+    CFLAGS="$CFLAGS -O2 -Wall"
 fi
 
 
index 2b67240..56d802b 100644 (file)
@@ -75,7 +75,7 @@ B<-k> [I<username>] [I<keyring>]
     B<-kvc>   List fingerprints
     B<-kvvc>  List fingerprints and signatures
 
-B<--list-keys> [I<names>]
+B<--list-keys>  [I<names>]
     List all keys from the public keyrings, or just the
     ones given on the command line.
 
@@ -83,7 +83,7 @@ B<--list-secret-keys> [I<names>]
     List all keys from the secret keyrings, or just the
     ones given on the command line.
 
-B<--list-sigs> [I<names>]
+B<--list-sigs>  [I<names>]
     Same as B<--list-keys>, but the signatures are listed
     too.
 
@@ -129,7 +129,7 @@ B<--edit-key> I<name>
     B<delkey>
        Remove a subkey.
     B<expire>
-       Change the key expiration time. If a key is
+       Change the key expiration time.  If a key is
        select, the time of this key will be changed.
        With no selection the key expiration of the
        primary key is changed.
@@ -191,7 +191,7 @@ B<--export-secret-keys> [I<names>
     This is normally not very useful.
 
 B<--import>, B<--fast-import>
-    Import/merge keys. The fast version does not build
+    Import/merge keys.  The fast version does not build
     the trustdb; this can be deon at anytime with the
     command B<--update-trustdb>.
 
@@ -208,7 +208,7 @@ B<--import-ownertrust> [I<filename>]
 
 Long options can be put in an options file (default F<~/.gnupg/options>);
 do not write the 2 dashes, but simply the name of the option and any
-arguments if required. Lines with a hash as the first non-white-space
+arguments if required.  Lines with a hash as the first non-white-space
 character are ignored. Commands may be put in this file too, but that
 does not make sense.
 
@@ -249,8 +249,12 @@ B<-z> I<n>
     compression level of zlib (which is 6).
 
 B<-t>, B<--textmode>
-    Use canonical text mode.  Used to make clear-text
-    signatures.
+    Use canonical text mode.  If B<-t> (but not
+    B<--textmode>) is used together with armoring
+    and signing, this enables clearsigned messages.
+    This kludge is needed for PGP compatibility;
+    normally you would use B<--sign> or b<--clearsign>
+    to selected the type os signatures.
 
 B<-n>, B<--dry-run>
     Don't make any changes (not yet implemented).
@@ -443,11 +447,11 @@ a signature was bad and other errorcode for fatal errors.
 
 =head1 EXAMPLES
 
-  -se -r Bob [file]         sign and encrypt for user Bob
-  -sat [file]               make a clear text signature
-  -sb  [file]               make a detached signature
-  -k   [userid]             show keys
-  -kc  [userid]             show fingerprint
+  -se -r Bob [file]          sign and encrypt for user Bob
+  -sat [file]                make a clear text signature
+  -sb  [file]                make a detached signature
+  -k   [userid]              show keys
+  -kc  [userid]              show fingerprint
 
 =head1 ENVIRONMENT
 
@@ -462,13 +466,13 @@ F<~/.gnupg/pubring.gpg>     The public keyring
 
 F<~/.gnupg/trustdb.gpg>     The trust database
 
-F<~/.gnupg/options>        May contain options
+F<~/.gnupg/options>         May contain options
 
 F</usr[/local]/lib/gnupg/>  Default location for extensions
 
 =head1 SEE ALSO
 
-gpg(1) gpgm(1)
+gpg(1)  gpgm(1)
 
 
 =head1 WARNINGS
index 35afefa..9109e65 100644 (file)
@@ -1,3 +1,30 @@
+Tue Nov  3 16:19:21 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * keygen.c (ask_user_id): Now converted to UTF-8
+
+       * g10.c (main): Kludge for pgp clearsigs and textmode.
+
+Fri Oct 30 16:40:39 1998  me,,,  (wk@tobold)
+
+       * signal.c (block_all_signals): New.
+       (unblock_all_signals): New
+       * tdbio.c (tdbio_end_transaction): Now blocks all signals.
+
+       * trustdb.c (new_lid_table): Changed the represenation of the
+       former local_lid_info stuff.
+
+       * trustdb.c (update_trust_record): Reorganized the whole thing.
+       * sig-check.c (check_key_signature): Now handles class 0x28
+
+
+Wed Oct 28 18:56:33 1998  me,,,  (wk@tobold)
+
+       * export.c (do_export): Takes care of the exportable sig flag.
+
+Tue Oct 27 14:53:04 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * trustdb.c (update_trust_record): New "fast" parameter.
+
 Sun Oct 25 19:32:05 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
        * openfile.c (copy_options_File): New.
index 46413ff..637f675 100644 (file)
@@ -128,6 +128,15 @@ do_export( STRLIST users, int secret )
             * secret keyring */
            if( !secret && node->pkt->pkttype == PKT_COMMENT )
                continue;
+           /* do not export packets which are marked as not exportable */
+           if( node->pkt->pkttype == PKT_SIGNATURE ) {
+               const char *p;
+               p = parse_sig_subpkt2( node->pkt->pkt.signature,
+                                      SIGSUBPKT_EXPORTABLE, NULL );
+               if( p && !*p )
+                   continue; /* not exportable */
+           }
+
            if( (rc = build_packet( out, node->pkt )) ) {
                log_error("build_packet(%d) failed: %s\n",
                            node->pkt->pkttype, g10_errstr(rc) );
index 3df9121..9d4f20d 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -60,7 +60,7 @@ enum cmd_and_opt_values { aNull = 0,
     oQuiet       = 'q',
     oRemote      = 'r',
     aSign        = 's',
-    oTextmode    = 't',
+    oTextmodeShort= 't',
     oUser        = 'u',
     oVerbose     = 'v',
     oCompress    = 'z',
@@ -100,6 +100,7 @@ enum cmd_and_opt_values { aNull = 0,
     aEnArmor,
     aGenRandom,
 
+    oTextmode,
     oFingerprint,
     oAnswerYes,
     oAnswerNo,
@@ -205,6 +206,7 @@ static ARGPARSE_OPTS opts[] = {
     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
     { oRemote, "remote-user", 2, N_("use this user-id for encryption")},
     { oCompress, NULL,       1, N_("|N|set compress level N (0 disables)") },
+    { oTextmodeShort, NULL,   0, "@"},
     { oTextmode, "textmode",  0, N_("use canonical text mode")},
   #endif
     { oOutput, "output",    2, N_("use as output file")},
@@ -734,6 +736,7 @@ main( int argc, char **argv )
            sl->next = remusr;
            remusr = sl;
            break;
+         case oTextmodeShort: opt.textmode = 2; break;
          case oTextmode: opt.textmode=1;  break;
          case oUser: /* store the local users */
            sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
@@ -839,7 +842,7 @@ main( int argc, char **argv )
 
 
     /* kludge to let -sat generate a clear text signature */
-    if( opt.textmode && !detached_sig && opt.armor && cmd == aSign )
+    if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
        cmd = aClearsign;
 
     if( opt.verbose > 1 )
index 075ecd3..0cd1353 100644 (file)
@@ -465,7 +465,7 @@ import_one( const char *fname, KBNODE keyblock, int fast )
                                        (ulong)keyid[1], g10_errstr(rc) );
        }
        else if( mod_key )
-           rc = update_trust_record( keyblock_orig, NULL );
+           rc = update_trust_record( keyblock_orig, 1, NULL );
        else
            rc = clear_trust_checked_flag( new_key? pk : pk_orig );
     }
index 6292134..a2b0a76 100644 (file)
@@ -647,7 +647,7 @@ keyedit_menu( const char *username, STRLIST locusr )
            }
            else
                tty_printf(_("Key not changed so no update needed.\n"));
-           rc = update_trust_record( keyblock, NULL );
+           rc = update_trust_record( keyblock, 0, NULL );
            if( rc )
                log_error(_("update of trust db failed: %s\n"),
                            g10_errstr(rc) );
@@ -705,7 +705,7 @@ keyedit_menu( const char *username, STRLIST locusr )
                sec_modified = modified = 1;
                /* must update the trustdb already here, so that preferences
                 * get listed correctly */
-               rc = update_trust_record( keyblock, NULL );
+               rc = update_trust_record( keyblock, 0, NULL );
                if( rc ) {
                    log_error(_("update of trust db failed: %s\n"),
                                g10_errstr(rc) );
index 6b04971..a17d479 100644 (file)
@@ -689,6 +689,11 @@ ask_user_id( int mode )
            break;
        m_free(uid); uid = NULL;
     }
+    if( uid ) {
+       char *p = native_to_utf8( uid );
+       m_free( uid );
+       uid = p;
+    }
     return uid;
 }
 
index 542676c..1f19b05 100644 (file)
@@ -633,7 +633,8 @@ dump_sig_subpkt( int hashed, int type, int critical,
            printf("sig expires %s", strtimestamp( buffer_to_u32(buffer) ) );
        break;
       case SIGSUBPKT_EXPORTABLE:
-       p = "exportable";
+       if( length )
+           printf("%sexportable", *buffer? "":"not ");
        break;
       case SIGSUBPKT_TRUST:
        p = "trust signature";
@@ -759,6 +760,10 @@ parse_sig_subpkt( const byte *buffer, sigsubpkttype_t reqtype, size_t *ret_n )
        if( n < 4 )
            break;
        return buffer;
+      case SIGSUBPKT_EXPORTABLE:
+       if( !n )
+           break;
+       return buffer;
       case SIGSUBPKT_ISSUER:/* issuer key ID */
        if( n < 8 )
            break;
index fd476f7..da732c4 100644 (file)
@@ -278,12 +278,27 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
        rc = do_check( pk, sig, md );
        md_close(md);
     }
+    else if( sig->sig_class == 0x28 ) { /* subkey revocation */
+       KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
+
+       if( snode ) {
+           md = md_open( algo, 0 );
+           hash_public_key( md, pk );
+           hash_public_key( md, snode->pkt->pkt.public_key );
+           rc = do_check( pk, sig, md );
+           md_close(md);
+       }
+       else {
+           log_error("no subkey for subkey revocation packet\n");
+           rc = G10ERR_SIG_CLASS;
+       }
+    }
     else if( sig->sig_class == 0x18 ) {
        KBNODE snode = find_prev_kbnode( root, node, PKT_PUBLIC_SUBKEY );
 
        if( snode ) {
-           if( is_selfsig ) {
-               u32 keyid[2];
+           if( is_selfsig ) {  /* does this make sense????? */
+               u32 keyid[2];   /* it should always be a selfsig */
 
                keyid_from_pk( pk, keyid );
                if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
index d89b548..8a0f3fe 100644 (file)
@@ -121,3 +121,42 @@ pause_on_sigusr( int which )
   #endif
 }
 
+
+static void
+do_block( int block )
+{
+  #ifndef __MINGW32__
+    static int is_blocked;
+    static sigset_t oldmask;
+
+    if( block ) {
+       sigset_t newmask;
+
+       if( is_blocked )
+           log_bug("signals are already blocked\n");
+       sigfillset( &newmask );
+       sigprocmask( SIG_BLOCK, &newmask, &oldmask );
+       is_blocked = 1;
+    }
+    else {
+       if( !is_blocked )
+           log_bug("signals are not blocked\n");
+       sigprocmask( SIG_SETMASK, &oldmask, NULL );
+       is_blocked = 0;
+    }
+  #endif /*__MINGW32__*/
+}
+
+
+void
+block_all_signals()
+{
+    do_block(1);
+}
+
+void
+unblock_all_signals()
+{
+    do_block(0);
+}
+
index 1954929..f4c97e8 100644 (file)
@@ -320,10 +320,15 @@ tdbio_begin_transaction()
 int
 tdbio_end_transaction()
 {
+    int rc;
+
     if( !in_transaction )
        log_bug("tdbio: no active transaction\n");
+    block_all_signals();
     in_transaction = 0;
-    return tdbio_sync();
+    rc = tdbio_sync();
+    unblock_all_signals();
+    return rc;
 }
 
 int
index 7a6ec3b..43903a9 100644 (file)
   #error Must change structure of trustdb
 #endif
 
-typedef struct local_id_info *LOCAL_ID_INFO;
-struct local_id_info {
-    LOCAL_ID_INFO next;
+struct local_id_item {
+    struct local_id_item *next;
     ulong lid;
     unsigned flag;
 };
 
+struct local_id_table {
+    struct local_id_table *next; /* only used to keep a list of unused tables */
+    struct local_id_item *items[16];
+};
+
+
+typedef struct local_id_table *LOCAL_ID_TABLE;
+
 
 typedef struct trust_info TRUST_INFO;
 struct trust_info {
     ulong    lid;
-    unsigned trust;
+    byte     otrust; /* ownertrust (assigned trust) */
+    byte     trust; /* calculated trust (validity) */
 };
 
-
 typedef struct trust_seg_list *TRUST_SEG_LIST;
 struct trust_seg_list {
     TRUST_SEG_LIST next;
-    int   nseg;     /* number of segments */
-    int   dup;
-    TRUST_INFO seg[1];  /* segment list */
+    int  pathlen;
+    TRUST_INFO path[1];
 };
 
 
@@ -82,10 +88,10 @@ typedef struct recno_list_struct *RECNO_LIST;
 
 static int walk_sigrecs( SIGREC_CONTEXT *c );
 
-static LOCAL_ID_INFO *new_lid_table(void);
-static void release_lid_table( LOCAL_ID_INFO *tbl );
-static int ins_lid_table_item( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag );
-static int qry_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned *flag );
+static LOCAL_ID_TABLE new_lid_table(void);
+static void release_lid_table( LOCAL_ID_TABLE tbl );
+static int ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag );
+static int qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag );
 
 static void print_user_id( const char *text, u32 *keyid );
 static int list_sigs( ulong pubkey_id );
@@ -95,8 +101,11 @@ static int get_dir_record( PKT_public_key *pk, TRUSTREC *rec );
 
 /* a table used to keep track of ultimately trusted keys
  * which are the ones from our secrings */
-static LOCAL_ID_INFO *ultikey_table;
+static LOCAL_ID_TABLE ultikey_table;
 
+/* list of unused lid items and tables */
+static LOCAL_ID_TABLE unused_lid_tables;
+static struct local_id_item *unused_lid_items;
 
 
 #define HEXTOBIN(a) ( (a) >= '0' && (a) <= '9' ? ((a)-'0') : \
@@ -215,53 +224,67 @@ rel_recno_list( RECNO_LIST *head )
     *head = NULL;
 }
 
-static LOCAL_ID_INFO *
+static LOCAL_ID_TABLE
 new_lid_table(void)
 {
-    return m_alloc_clear( 16 * sizeof(LOCAL_ID_INFO));
+    LOCAL_ID_TABLE a;
+
+    a = unused_lid_tables;
+    if( a ) {
+       unused_lid_tables = a->next;
+       a->next = NULL;
+    }
+    else
+       a = m_alloc_clear( sizeof *a );
+    return a;
 }
 
 static void
-release_lid_table( LOCAL_ID_INFO *tbl )
+release_lid_table( LOCAL_ID_TABLE tbl )
 {
-    LOCAL_ID_INFO a, a2;
+    struct local_id_item *a, *a2;
     int i;
 
     for(i=0; i < 16; i++ ) {
-       for(a=tbl[i]; a; a = a2 ) {
+       for(a=tbl->items[i]; a; a = a2 ) {
            a2 = a->next;
-           m_free(a);
+           a->next = unused_lid_items;
+           unused_lid_items = a;
        }
     }
-    m_free(tbl);
+    tbl->next = unused_lid_tables;
+    unused_lid_tables = tbl;
 }
 
 /****************
  * Add a new item to the table or return 1 if we already have this item
- * fixme: maybe it's a good idea to take items from an unused item list.
  */
 static int
-ins_lid_table_item( LOCAL_ID_INFO *tbl, ulong lid, unsigned flag )
+ins_lid_table_item( LOCAL_ID_TABLE tbl, ulong lid, unsigned flag )
 {
-    LOCAL_ID_INFO a;
+    struct local_id_item *a;
 
-    for( a = tbl[lid & 0x0f]; a; a = a->next )
+    for( a = tbl->items[lid & 0x0f]; a; a = a->next )
        if( a->lid == lid )
            return 1;
-    a = m_alloc( sizeof *a );
+    a = unused_lid_items;
+    if( a )
+       unused_lid_items = a->next;
+    else
+       a = m_alloc( sizeof *a );
     a->lid = lid;
     a->flag = flag;
-    a->next = tbl[lid & 0x0f];
-    tbl[lid & 0x0f] = a;
+    a->next = tbl->items[lid & 0x0f];
+    tbl->items[lid & 0x0f] = a;
     return 0;
 }
 
 static int
-qry_lid_table_flag( LOCAL_ID_INFO *tbl, ulong lid, unsigned *flag )
+qry_lid_table_flag( LOCAL_ID_TABLE tbl, ulong lid, unsigned *flag )
 {
-    LOCAL_ID_INFO a;
+    struct local_id_item *a;
 
-    for( a = tbl[lid & 0x0f]; a; a = a->next )
+    for( a = tbl->items[lid & 0x0f]; a; a = a->next )
        if( a->lid == lid ) {
            if( flag )
                *flag = a->flag;
@@ -493,7 +516,7 @@ print_user_id( const char *text, u32 *keyid )
     m_free(p);
 }
 
-
+#if 0
 static int
 print_keyid( FILE *fp, ulong lid )
 {
@@ -521,7 +544,7 @@ print_trust( FILE *fp, unsigned trust )
     putc(c, fp);
     return 1;
 }
-
+#endif
 
 static int
 print_sigflags( FILE *fp, unsigned flags )
@@ -542,7 +565,7 @@ print_sigflags( FILE *fp, unsigned flags )
 /* (a non-recursive algorithm would be easier) */
 static int
 do_list_sigs( ulong root, ulong pk_lid, int depth,
-             LOCAL_ID_INFO *lids, unsigned *lineno )
+             LOCAL_ID_TABLE lids, unsigned *lineno )
 {
     SIGREC_CONTEXT sx;
     int rc;
@@ -551,8 +574,8 @@ do_list_sigs( ulong root, ulong pk_lid, int depth,
     memset( &sx, 0, sizeof sx );
     sx.lid = pk_lid;
     for(;;) {
-       rc = walk_sigrecs( &sx );
-       if( rc )
+       rc = walk_sigrecs( &sx ); /* should we replace it and use */
+       if( rc )                  /* use a loop like in collect_paths ??*/
            break;
        rc = keyid_from_lid( sx.sig_lid, keyid );
        if( rc ) {
@@ -609,7 +632,7 @@ list_sigs( ulong pubkey_id )
 {
     int rc;
     u32 keyid[2];
-    LOCAL_ID_INFO *lids;
+    LOCAL_ID_TABLE lids;
     unsigned lineno = 1;
 
     rc = keyid_from_lid( pubkey_id, keyid );
@@ -692,40 +715,54 @@ list_records( ulong lid )
 
 
 
+
 /****************
- * Given the directory record of a key, check whether we can
- * find a path to an ultimately trusted key.  We do this by
- * checking all key signatures up to a some depth.
+ * stack is an array of (max_path+1) elements. If trust_seg_head is not
+ * NULL it is a pointer to a variable which will receive a linked list
+ * of trust paths - The caller has to free the memory.
  */
 static int
-verify_key( int depth, int max_depth, TRUSTREC *drec )
+collect_paths( int depth, int max_depth, int all, TRUSTREC *drec,
+              TRUST_INFO *stack, TRUST_SEG_LIST *trust_seg_head )
 {
     ulong rn, uidrn;
     int marginal=0;
     int fully=0;
-    size_t dbglen;
-
-    /* Note: If used stack size is an issue, we could reuse the
-     * trustrec vars and reread them as needed */
+    LOCAL_ID_TABLE sigs_seen = NULL;
 
-    dbglen = printf("verify_key: depth=%d %*s", depth, depth*3,"" );
-    dbglen += print_keyid( stdout, drec->recnum );
-    dbglen += printf(" ot=");
-    dbglen += print_trust(stdout, drec->r.dir.ownertrust );
-    dbglen += printf(" -> ");
-
-    if( depth >= max_depth ) {
-       /* max cert_depth reached */
-       puts("undefined (too deep)");
+    if( depth >= max_depth )  /* max cert_depth reached */
        return TRUST_UNDEFINED;
+    {  int i;
+
+       for(i=0; i < depth; i++ )
+           if( stack[i].lid == drec->r.dir.lid )
+               return TRUST_UNDEFINED; /* closed (we already visited this lid) */
     }
+
+    stack[depth].lid = drec->r.dir.lid;
+    stack[depth].otrust = drec->r.dir.ownertrust;
+    stack[depth].trust = 0;
     if( !qry_lid_table_flag( ultikey_table, drec->r.dir.lid, NULL ) ) {
        /* we are at the end of a path */
-       puts("ultimate");
+       TRUST_SEG_LIST tsl;
+       int i;
+
+       stack[depth].trust = TRUST_ULTIMATE;
+       if( trust_seg_head ) {
+           /* we can now put copy our current stack to the trust_seg_list */
+           tsl = m_alloc( sizeof *tsl + (depth+1)*sizeof( TRUST_INFO ) );
+           for(i=0; i <= depth; i++ )
+               tsl->path[i] = stack[i];
+           tsl->pathlen = i;
+           tsl->next = *trust_seg_head;
+           *trust_seg_head = tsl;
+       }
        return TRUST_ULTIMATE;
     }
 
     /* loop over all user-ids */
+    if( !all )
+       sigs_seen = new_lid_table();
     for( rn = drec->r.dir.uidlist; rn; rn = uidrn ) {
        TRUSTREC rec;  /* used for uids and sigs */
        ulong sigrn;
@@ -755,40 +792,39 @@ verify_key( int depth, int max_depth, TRUSTREC *drec )
                    continue; /* skip expired signatures */
                if( (rec.r.sig.sig[i].flag & SIGF_REVOKED) )
                    continue; /* skip revoked signatures */
-               /* fixme: skip duplicates */
 
-               read_record( rec.r.sig.sig[i].lid, &tmp, RECTYPE_DIR );
-               ot = tmp.r.dir.ownertrust & TRUST_MASK;
-             #if 0 /* Does not work, because the owner trust of our
-                    * own keys is not always set
-                    * -- fix this in verify_own_keys() ? */
-               if( ot < TRUST_MARGINAL ) {
-                   printf(". ");
-                   continue;  /* ownertrust is too low; don't need to check */
+               /* visit every signer only once (a signer may have
+                * signed multizple user IDs */
+               if( sigs_seen && ins_lid_table_item( sigs_seen,
+                                                    rec.r.sig.sig[i].lid, 0) )
+                   continue; /* we alread have this one */
+
+               read_record( rec.r.sig.sig[i].lid, &tmp, 0 );
+               if( tmp.rectype != RECTYPE_DIR ) {
+                   log_info("oops: lid %lu: sig %lu has rectype %d"
+                            " - skipped\n",
+                           drec->r.dir.lid, tmp.recnum, tmp.rectype );
+                   continue;
                }
-             #endif
+               ot = tmp.r.dir.ownertrust & TRUST_MASK;
                if( ot >= TRUST_FULLY )
                    ot = TRUST_FULLY;  /* just in case */
+               nt = collect_paths( depth+1, max_depth, all, &tmp, stack,
+                                                       trust_seg_head );
+               nt &= TRUST_MASK;
 
-               puts("");
-               nt = verify_key( depth+1, max_depth, &tmp ) & TRUST_MASK;
                if( nt < TRUST_MARGINAL ) {
-                   printf("%*s* ", dbglen, "");
-                   dbglen += 2;
                    continue;
                }
 
                if( nt == TRUST_ULTIMATE ) {
                    /* we have signed this key and only in this special case
-                    * we assume a completes-needed or marginals-needed of 1 */
-                   printf("%*s", dbglen, "");
-                   if( ot == TRUST_MARGINAL )
-                       puts("marginal (1st level)");
-                   else if( ot == TRUST_FULLY )
-                       puts("fully    (1st level)");
-                   else
-                       puts("?????    (1st level)");
-                   return ot;
+                    * we assume that this one is fully trusted */
+                   if( !all ) {
+                       if( sigs_seen )
+                           release_lid_table( sigs_seen );
+                       return (stack[depth].trust = TRUST_FULLY);
+                   }
                }
 
                if( nt >= TRUST_FULLY )
@@ -798,127 +834,45 @@ verify_key( int depth, int max_depth, TRUSTREC *drec )
 
                if( fully >= opt.completes_needed
                    || marginal >= opt.marginals_needed ) {
-                   printf("%*s", dbglen, "");
-                   puts("fully");
-                   return TRUST_FULLY;
+                   if( !all ) {
+                       if( sigs_seen )
+                           release_lid_table( sigs_seen );
+                       return (stack[depth].trust = TRUST_FULLY);
+                   }
                }
            }
        }
     }
-    printf("%*s", dbglen, "");
+    if( sigs_seen )
+       release_lid_table( sigs_seen );
+    if( all && ( fully >= opt.completes_needed
+                || marginal >= opt.marginals_needed ) ) {
+       return (stack[depth].trust = TRUST_FULLY );
+    }
     if( marginal ) {
-       puts("marginal");
-       return TRUST_MARGINAL;
+       return (stack[depth].trust = TRUST_MARGINAL);
     }
-    puts("undefined");
-    return TRUST_UNDEFINED;
+    return (stack[depth].trust=TRUST_UNDEFINED);
 }
 
 
+/****************
+ * Given the directory record of a key, check whether we can
+ * find a path to an ultimately trusted key.  We do this by
+ * checking all key signatures up to a some depth.
+ */
 static int
-list_paths( int depth, int max_depth, TRUSTREC *drec )
+verify_key( int max_depth, TRUSTREC *drec )
 {
-    ulong rn, uidrn;
-    int marginal=0;
-    int fully=0;
-    size_t dbglen;
+    TRUST_INFO *tmppath = m_alloc_clear( (max_depth+1)* sizeof *tmppath );
+    int tr;
 
-    if( depth >= max_depth ) {
-       /* max cert_depth reached */
-       puts("undefined (too deep)");
-       return TRUST_UNDEFINED;
-    }
-    if( !qry_lid_table_flag( ultikey_table, drec->r.dir.lid, NULL ) ) {
-       /* we are at the end of a path */
-       puts("ultimate");
-       return TRUST_ULTIMATE;
-    }
-
-    /* loop over all user-ids */
-    for( rn = drec->r.dir.uidlist; rn; rn = uidrn ) {
-       TRUSTREC rec;  /* used for uids and sigs */
-       ulong sigrn;
-
-       read_record( rn, &rec, RECTYPE_UID );
-       uidrn = rec.r.uid.next;
-       /* fixme: continue if the uidrec is not marked valid */
-
-       /* loop over all signature records */
-       for( rn = rec.r.uid.siglist; rn; rn = sigrn ) {
-           int i;
-
-           read_record( rn, &rec, RECTYPE_SIG );
-           sigrn = rec.r.sig.next;
-
-           for(i=0; i < SIGS_PER_RECORD; i++ ) {
-               TRUSTREC tmp;
-               int ot, nt;
-
-               if( !rec.r.sig.sig[i].lid )
-                   continue; /* skip deleted sigs */
-               if( !(rec.r.sig.sig[i].flag & SIGF_CHECKED) )
-                   continue; /* skip unchecked signatures */
-               if( !(rec.r.sig.sig[i].flag & SIGF_VALID) )
-                   continue; /* skip invalid signatures */
-               if( (rec.r.sig.sig[i].flag & SIGF_EXPIRED) )
-                   continue; /* skip expired signatures */
-               if( (rec.r.sig.sig[i].flag & SIGF_REVOKED) )
-                   continue; /* skip revoked signatures */
-               /* fixme: skip duplicates */
-
-               read_record( rec.r.sig.sig[i].lid, &tmp, RECTYPE_DIR );
-               ot = tmp.r.dir.ownertrust & TRUST_MASK;
-               if( ot < TRUST_MARGINAL ) {
-                   printf(". ");
-                   continue;  /* ownertrust is too low; don't need to check */
-               }
-
-               if( ot >= TRUST_FULLY )
-                   ot = TRUST_FULLY;  /* just in case */
-
-               puts("");
-               nt = verify_key( depth+1, max_depth, &tmp ) & TRUST_MASK;
-               if( nt < TRUST_MARGINAL ) {
-                   printf("%*s* ", dbglen, "");
-                   dbglen += 2;
-                   continue;
-               }
-
-               if( nt == TRUST_ULTIMATE ) {
-                   /* we have signed this key and only in this special case
-                    * we assume a completes-needed or marginals-needed of 1 */
-                   printf("%*s", dbglen, "");
-                   if( ot == TRUST_MARGINAL )
-                       puts("marginal (1st level)");
-                   else if( ot == TRUST_FULLY )
-                       puts("fully    (1st level)");
-                   else
-                       puts("?????    (1st level)");
-                   return ot;
-               }
+    tr = collect_paths( 0, max_depth, 0, drec, tmppath, NULL );
+    m_free( tmppath );
+    return tr;
+}
 
-               if( nt >= TRUST_FULLY )
-                   fully++;
-               if( nt >= TRUST_MARGINAL )
-                   marginal++;
 
-               if( fully >= opt.completes_needed
-                   || marginal >= opt.marginals_needed ) {
-                   printf("%*s", dbglen, "");
-                   puts("fully");
-                   return TRUST_FULLY;
-               }
-           }
-       }
-    }
-    printf("%*s", dbglen, "");
-    if( marginal ) {
-       puts("marginal");
-       return TRUST_MARGINAL;
-    }
-    puts("undefined");
-    return TRUST_UNDEFINED;
-}
 
 
 /****************
@@ -937,7 +891,7 @@ do_check( TRUSTREC *dr, unsigned *trustlevel )
        return G10ERR_TRUSTDB;
     }
 
-    *trustlevel = verify_key( 1, 5, dr );
+    *trustlevel = verify_key( 5, dr );
 
     if( dr->r.dir.dirflags & DIRF_REVOKED )
        *trustlevel |= TRUST_FLAG_REVOKED;
@@ -1092,6 +1046,7 @@ import_ownertrust( const char *fname )
        n = strlen(line);
        if( line[n-1] != '\n' ) {
            log_error_f(fname, "line to long\n" );
+           /* ... or last line does not have a LF */
            break; /* can't continue */
        }
        for(p = line; *p && *p != ':' ; p++ )
@@ -1161,20 +1116,44 @@ import_ownertrust( const char *fname )
 }
 
 
+
+
+static void
+print_path( int pathlen, TRUST_INFO *path )
+{
+    int rc, i;
+    u32 keyid[2];
+
+    fputs("path:", stdout);
+    for( i = 0; i < pathlen; i++ )  {
+       if( i && !(i%4) )
+           fputs("     ", stdout );
+       rc = keyid_from_lid( path[i].lid, keyid );
+       if( rc )
+           printf(" ????????.%lu:", path[i].lid );
+       else
+           printf(" %08lX.%lu:", (ulong)keyid[1], path[i].lid );
+       print_sigflags( stdout, path[i].otrust );
+    }
+    putchar('\n');
+}
+
+
+
 void
 list_trust_path( int max_depth, const char *username )
 {
     int rc;
     int wipe=0;
     TRUSTREC rec;
+    TRUST_INFO *tmppath;
+    TRUST_SEG_LIST trust_seg_list, tsl, tsl2;
     PKT_public_key *pk = m_alloc_clear( sizeof *pk );
 
     if( max_depth < 0 ) {
        wipe = 1;
        max_depth = -max_depth;
     }
-    if( max_depth < 1 )
-       max_depth = 1;
 
     if( (rc = get_pubkey_byname( pk, username )) )
        log_error("user '%s' not found: %s\n", username, g10_errstr(rc) );
@@ -1190,14 +1169,30 @@ list_trust_path( int max_depth, const char *username )
            assert( pk->local_id );
        }
     }
+    free_public_key( pk );
 
+    /* collect the paths */
+    tmppath = m_alloc_clear( (max_depth+1)* sizeof *tmppath );
+    trust_seg_list = NULL;
+    collect_paths( 0, max_depth, 1, &rec, tmppath, &trust_seg_list );
+    m_free( tmppath );
+    /* and now print them */
+    for(tsl = trust_seg_list; tsl; tsl = tsl->next ) {
+       print_path( tsl->pathlen, tsl->path );
+    }
 
-    free_public_key( pk );
+    /* release the list */
+    for(tsl = trust_seg_list; tsl; tsl = tsl2 ) {
+       tsl2 = tsl->next;
+       m_free( tsl );
+    }
+    trust_seg_list = NULL;
 }
 
 
 /****************
  * Check the complete trustdb or only the entries for the given username.
+ * We check the complete database and recalculate all flags.
  */
 void
 check_trustdb( const char *username )
@@ -1218,7 +1213,7 @@ check_trustdb( const char *username )
        else {
            int modified;
 
-           rc = update_trust_record( keyblock, &modified );
+           rc = update_trust_record( keyblock, 0, &modified );
            if( rc == -1 ) { /* not yet in trustdb: insert */
                rc = insert_trust_record(
                            find_kbnode( keyblock, PKT_PUBLIC_KEY
@@ -1265,7 +1260,7 @@ check_trustdb( const char *username )
                    continue;
                }
 
-               rc = update_trust_record( keyblock, &modified );
+               rc = update_trust_record( keyblock, 0, &modified );
                if( rc ) {
                    log_error("lid %lu: update failed: %s\n",
                                                 recnum, g10_errstr(rc) );
@@ -1295,6 +1290,10 @@ check_trustdb( const char *username )
 }
 
 
+/****************
+ * Put new entries  from the pubrings into the trustdb.
+ * This function honors the sig flags to speed up the check.
+ */
 void
 update_trustdb( )
 {
@@ -1309,7 +1308,7 @@ update_trustdb( )
        while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
            int modified;
 
-           rc = update_trust_record( keyblock, &modified );
+           rc = update_trust_record( keyblock, 1, &modified );
            if( rc == -1 ) { /* not yet in trustdb: insert */
                PKT_public_key *pk =
                            find_kbnode( keyblock, PKT_PUBLIC_KEY
@@ -1904,13 +1903,34 @@ create_shadow_dir( PKT_signature *sig, ulong lid  )
 }
 
 
+/****************
+ * This function checks the given public key and inserts or updates
+ * the keyrecord from the trustdb.  Revocation certificates
+ * are handled here and the keybinding of subkeys is checked.
+ * Hmmm: Should we check here, that the key has at least one valid
+ * user ID or do we allow keys w/o user ID?
+ *
+ * keyblock points to the first node in the keyblock,
+ * keynode is the node with the public key to check
+ * (either primary or secondary), keyid is the keyid of
+ * the primary key, drec is the directory record and recno_list
+ * is a list used to keep track of visited records.
+ * Existing keyflags are recalculated if recheck is true.
+ */
 static void
-upd_key_record( PKT_public_key *pk, TRUSTREC *drec, RECNO_LIST *recno_list )
+upd_key_record( KBNODE keyblock, KBNODE keynode, u32 *keyid,
+               TRUSTREC *drec, RECNO_LIST *recno_list, int recheck )
 {
     TRUSTREC krec;
+    KBNODE  node;
+    PKT_public_key *pk = keynode->pkt->pkt.public_key,;
+    ulon lid = drec->recnum;
     byte fpr[MAX_FINGERPRINT_LEN];
     size_t fprlen;
     ulong recno, newrecno;
+    int keybind_seen = 0;
+    int revoke_seen = 0;
+    int rc;
 
     fingerprint_from_pk( pk, fpr, &fprlen );
     /* do we already have this key? */
@@ -1924,9 +1944,10 @@ upd_key_record( PKT_public_key *pk, TRUSTREC *drec, RECNO_LIST *recno_list )
        ins_recno_list( recno_list, recno, RECTYPE_KEY );
     }
     else { /* no: insert this new key */
+       recheck = 1;
        memset( &krec, 0, sizeof(krec) );
        krec.rectype = RECTYPE_KEY;
-       krec.r.key.lid = drec->recnum;
+       krec.r.key.lid = lid;
        krec.r.key.pubkey_algo = pk->pubkey_algo;
        krec.r.key.fingerprint_len = fprlen;
        memcpy(krec.r.key.fingerprint, fpr, fprlen );
@@ -1939,23 +1960,127 @@ upd_key_record( PKT_public_key *pk, TRUSTREC *drec, RECNO_LIST *recno_list )
            drec->r.dir.keylist = newrecno;
            drec->dirty = 1;
        }
-       else { /* we already have a key, append it to the list */
+       else { /* we already have a key, append the new one */
+           TRUSTREC save = krec;
            for( ; recno; recno = krec.r.key.next )
                read_record( recno, &krec, RECTYPE_KEY );
            krec.r.key.next = newrecno;
            write_record( &krec );
+           krec = save;
        }
     }
+
+    if( !recheck && (krec.r.key.keyflags & KEYF_CHECKED) )
+       return;
+
+    /* check keybindings and revocations */
+    krec.r.key.keyflags = 0;
+    if( keynode->pkt->pkttype == PKT_PUBLIC_KEY ) {
+       /* we assume that a primary key is always valid
+        * and check later whether we have a revocation */
+       krec.r.key.keyflags |= KEYF_CHECKED | KEYF_VALID;
+    }
+
+    for( node=keynode->next; node; node = node->next ) {
+       if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+           break; /* ready */
+       else if( node->pkt->pkttype == PKT_PUBLIC_SIGNATURE ) {
+           PKT_signature *sig = node->pkt->pkt.signature;
+
+           if( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] )
+               continue; /* not a self signature */
+           if( sig->sig_class == 0x18 && !keybind_seen ) { /* a keybinding */
+               if( keynode->pkt->pkttype == PKT_PUBLIC_KEY )
+                   continue; /* oops, not for a main key */
+               /* we check until we find a valid keybinding */
+               rc = check_key_signature( keyblock, node, NULL );
+               if( !rc ) {
+                   if( opt.verbose )
+                       log_info(_(
+                           "key %08lX.%lu: Good subkey binding\n"),
+                            (ulong)keyid_from_pk(pk,NULL), lid );
+                   krec.r.key.keyflags |= KEYF_CHECKED | KEYF_VALID;
+               }
+               else {
+                   log_info(_(
+                     "key %08lX.%lu: Invalid subkey binding: %s\n"),
+                       (ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
+                   krec.r.key.keyflags |= KEYF_CHECKED;
+                   krec.r.key.keyflags &= ~KEYF_VALID;
+               }
+               keybind_seen = 1;
+           }
+           else if( sig->sig_class == 0x20 && !revoke_seen ) {
+               if( keynode->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+                   continue; /* a subkey is not expected here */
+               /* This is a key revocation certificate: check it */
+               rc = check_key_signature( keyblock, node, NULL );
+               if( !rc ) {
+                   if( opt.verbose )
+                       log_info(_(
+                           "key %08lX.%lu: Valid key revocation\n"),
+                            (ulong)keyid_from_pk(pk,NULL), lid );
+                   krec.r.key.keyflags |= KEYF_REVOKED;
+               }
+               else {
+                   log_info(_(
+                     "key %08lX.%lu: Invalid key revocation: %s\n"),
+                     (ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
+               }
+               revoke_seen = 1;
+           }
+           else if( sig->sig_class == 0x28 && !revoke_seen ) {
+               if( keynode->pkt->pkttype == PKT_PUBLIC_KEY )
+                   continue; /* a mainkey is not expected here */
+               /* This is a subkey revocation certificate: check it */
+               /* fixme: we should also check the revocation
+                * is newer tha the key (OpenPGP) */
+               rc = check_key_signature( keyblock, node, NULL );
+               if( !rc ) {
+                   if( opt.verbose )
+                       log_info(_(
+                           "key %08lX.%lu: Valid subkey revocation\n"),
+                            (ulong)keyid_from_pk(pk,NULL), lid );
+                   krec.r.key.keyflags |= KEYF_REVOKED;
+               }
+               else {
+                   log_info(_(
+                     "key %08lX.%lu: Invalid subkey binding: %s\n"),
+                     (ulong)keyid_from_pk(pk,NULL), lid, g10_errstr(rc) );
+               }
+               revoke_seen = 1;
+           }
+       } /* end signature */
+    }
+
+    write_record( &krec );
 }
 
 
+/****************
+ * This function checks the given user ID and inserts or updates
+ * the uid record of the trustdb.  Revocation certificates
+ * are handled here.
+ *
+ * keyblock points to the first node in the keyblock,
+ * uidnode is the node with the user id to check
+ * keyid is the keyid of
+ * the primary key, drec is the directory record and recno_list
+ * is a list used to keep track of visited records.
+ * Existing uidflags are recalculated if recheck is true.
+ */
 static void
-upd_uid_record( PKT_user_id *uid, TRUSTREC *drec, RECNO_LIST *recno_list,
-                             u32 *keyid, ulong *uidrecno, byte *uidhash )
+upd_uid_record( KBNODE keyblock, KBNODE uidnode, u32 *keyid,
+               TRUSTREC *drec, RECNO_LIST *recno_list, int recheck )
 {
+    ulong lid = drec->recnum;
+    PKT_user_id *uid = uidnode->pkt->pkt.user_id;
     TRUSTREC urec;
+    byte uidhash[20];
     ulong recno, newrecno;
 
+    /* see whether we already have an uid record */
+  WORK WORK
     rmd160_hash_buffer( uidhash, uid->name, uid->len );
     for( recno=drec->r.dir.uidlist; recno; recno = urec.r.uid.next ) {
        read_record( recno, &urec, RECTYPE_UID );
@@ -2014,7 +2139,7 @@ upd_pref_record( PKT_signature *sig, ulong lid, const u32 *keyid,
     /* First delete all pref records
      * This is much simpler than checking whether we have to
      * do update the record at all - the record cache may care about it
-     * FIXME: We never get correct statistics if we di it like this */
+     * FIXME: We never get correct statistics if we do it like this */
     for( recno=urec->r.uid.prefrec; recno; recno = prec.r.pref.next ) {
        read_record( recno, &prec, RECTYPE_PREF );
        delete_record( recno );
@@ -2097,13 +2222,14 @@ upd_self_key_sigs( PKT_signature *sig, TRUSTREC *urec,
 }
 
 
+
 /****************
  * update non-self key signatures (class 0x10..0x13)
  */
 static void
 upd_nonself_key_sigs( PKT_signature *sig, TRUSTREC *urec,
                      ulong lid, const u32 *keyid,  const byte *uidhash,
-                     KBNODE keyblock, KBNODE signode)
+                     KBNODE keyblock, KBNODE signode, int fast)
 {
     /* We simply insert the signature into the sig records but
      * avoid duplicate ones.  We do not check them here because
@@ -2178,9 +2304,9 @@ upd_nonself_key_sigs( PKT_signature *sig, TRUSTREC *urec,
                }
                found_sig = 1;
            }
-           if( rec.r.sig.sig[i].flag & SIGF_CHECKED )
+           if( fast && (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
                continue; /* we already checked this signature */
-           if( rec.r.sig.sig[i].flag & SIGF_NOPUBKEY )
+           if( fast && (rec.r.sig.sig[i].flag & SIGF_NOPUBKEY) )
                continue; /* we do not have the public key */
 
            read_record( rec.r.sig.sig[i].lid, &tmp, 0 );
@@ -2197,10 +2323,11 @@ upd_nonself_key_sigs( PKT_signature *sig, TRUSTREC *urec,
                    rec.r.sig.sig[i].flag = SIGF_CHECKED | SIGF_VALID;
                }
                else if( rc == G10ERR_NO_PUBKEY ) {
-                   log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
-                              "weird: no public key\n"),
-                         (ulong)keyid[1], lid, uidhash[18],
-                          uidhash[19], (ulong)sig->keyid[1] );
+                   if( (rec.r.sig.sig[i].flag & SIGF_CHECKED) )
+                       log_info(_("key %08lX.%lu, uid %02X%02X, sig %08lX: "
+                                  "public key lost\n"),
+                                 (ulong)keyid[1], lid, uidhash[18],
+                                uidhash[19], (ulong)sig->keyid[1] );
                    rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
                }
                else {
@@ -2219,8 +2346,9 @@ upd_nonself_key_sigs( PKT_signature *sig, TRUSTREC *urec,
                    && tmp.r.sdir.keyid[1] == sig->keyid[1]
                    && (!tmp.r.sdir.pubkey_algo
                         || tmp.r.sdir.pubkey_algo == sig->pubkey_algo )) {
-                   log_info(_("key %08lX.%lu, uid %02X%02X: "
-                              "has shadow dir %lu but not yet marked.\n"),
+                   if( !(rec.r.sig.sig[i].flag & SIGF_NOPUBKEY) )
+                       log_info(_("key %08lX.%lu, uid %02X%02X: "
+                                  "has shadow dir %lu but not yet marked.\n"),
                                (ulong)keyid[1], lid,
                                uidhash[18], uidhash[19], tmp.recnum );
                    rec.r.sig.sig[i].flag = SIGF_NOPUBKEY;
@@ -2314,7 +2442,7 @@ upd_nonself_key_sigs( PKT_signature *sig, TRUSTREC *urec,
 static void
 upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
                u32 *keyid, ulong *uidrecno, byte *uidhash,
-               KBNODE keyblock, KBNODE signode)
+               KBNODE keyblock, KBNODE signode, int fast)
 {
     TRUSTREC urec;
     ulong lid = drec->recnum;
@@ -2342,9 +2470,6 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
                                                keyblock, signode );
        }
        else if( sig->sig_class == 0x18 ) { /* key binding */
-           /* get the corresponding key */
-
-           /* FIXME */
        }
        else if( sig->sig_class == 0x20 ) { /* key revocation */
            /* FIXME */
@@ -2358,7 +2483,7 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
     }
     else if( (sig->sig_class&~3) == 0x10 ) {
        upd_nonself_key_sigs( sig, &urec, lid, keyid, uidhash,
-                                               keyblock, signode );
+                                               keyblock, signode, fast );
     }
     else if( sig->sig_class == 0x18 ) { /* key binding */
        log_info(_("key %08lX: bogus key binding by %08lX\n"),
@@ -2387,11 +2512,11 @@ upd_sig_record( PKT_signature *sig, TRUSTREC *drec,
  * Update all the info from the public keyblock.
  * The key must already exist in the keydb.
  * This function is responsible for checking the signatures in cases
- * where the public key is already available.  If we no not have the public
+ * where the public key is already available.  If we do not have the public
  * key, the check is done by some special code in insert_trust_record().
  */
 int
-update_trust_record( KBNODE keyblock, int *modified )
+update_trust_record( KBNODE keyblock, int recheck, int *modified )
 {
     PKT_public_key *primary_pk;
     KBNODE node;
@@ -2421,44 +2546,31 @@ update_trust_record( KBNODE keyblock, int *modified )
 
     keyid_from_pk( primary_pk, keyid );
 
+    /* fixme: check that the keyblock has a valid structure */
+
     rc = tdbio_begin_transaction();
     if( rc )
        return rc;
 
-    /* now update keys and user ids */
+    /* update the keys */
     for( node=keyblock; node; node = node->next ) {
-       switch( node->pkt->pkttype ) {
-         case PKT_PUBLIC_KEY:
-         case PKT_PUBLIC_SUBKEY:
-           uidrecno = 0;
-           upd_key_record( node->pkt->pkt.public_key, &drec, &recno_list );
-           break;
-
-         case PKT_USER_ID:
-           if( drec.dirty ) { /* upd_pref_record may read the drec */
-               write_record( &drec );
-               drec.dirty = 0;
-           }
-           upd_uid_record( node->pkt->pkt.user_id, &drec, &recno_list,
-                                            keyid, &uidrecno, uidhash );
-           break;
-
-         case PKT_SIGNATURE:
-           if( drec.dirty ) { /* upd_sig_recory may read the drec */
-               write_record( &drec );
-               drec.dirty = 0;
-           }
-           upd_sig_record( node->pkt->pkt.signature, &drec, keyid,
-                                  &uidrecno, uidhash, keyblock, node );
-           break;
-
-         default:
-           break;
-       }
-    } /* end loop over all nodes */
+       if( node->pkt->pkttype == PKT_PUBLIC_KEY
+           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+           upd_key_record( keyblock, node, keyid,
+                           &drec, &recno_list, recheck );
+    }
+    /* update the user IDs */
+    for( node=keyblock; node; node = node->next ) {
+       if( node->pkt->pkttype == PKT_USER_ID )
+           upd_uid_record( keyblock, node, keyid,
+                           &drec, &recno_list, recheck );
+    }
 
 
+  WORk - WORK
     /* delete keyrecords from the trustdb which are not anymore used */
+    /* should we really do this, or is it better to keep them and */
+    /* mark as unused? */
     lastrecno = 0;
     for( recno=drec.r.dir.keylist; recno; recno = krec.r.key.next ) {
        read_record( recno, &krec, RECTYPE_KEY );
@@ -2623,7 +2735,7 @@ insert_trust_record( PKT_public_key *pk )
     }
 
     /* and put all the other stuff into the keydb */
-    rc = update_trust_record( keyblock, NULL );
+    rc = update_trust_record( keyblock, 0, NULL );
     if( !rc )
        process_hintlist( hintlist, dirrec.r.dir.lid );
 
index 01d3dab..4dc8b2c 100644 (file)
@@ -60,7 +60,7 @@ ulong lid_from_keyblock( KBNODE keyblock );
 int query_trust_record( PKT_public_key *pk );
 int clear_trust_checked_flag( PKT_public_key *pk );
 int insert_trust_record( PKT_public_key *pk );
-int update_trust_record( KBNODE keyblock, int *modified );
+int update_trust_record( KBNODE keyblock, int fast, int *modified );
 int update_ownertrust( ulong lid, unsigned new_trust );
 
 /*-- pkclist.c --*/
index 5dd656e..56098ae 100644 (file)
@@ -152,6 +152,8 @@ const char *memistr( const char *buf, size_t buflen, const char *sub );
 char *mem2str( char *, const void *, size_t);
 char *trim_spaces( char *string );
 int string_count_chr( const char *string, int c );
+char *native_to_utf8( const char *string );
+char *utf8_to_native( const char *string );
 
 #define stricmp(a,b) strcasecmp((a),(b))
 
index 73f296d..893c4c2 100644 (file)
@@ -1,6 +1,10 @@
+Tue Oct 27 12:37:46 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * config.links (freebsd): Fixes for FreeBSD 3.0
+
 Wed Oct 14 09:59:30 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
-       * config-links (freebsd): ELF patches from Jun Kuriyama.
+       * config.links (freebsd): ELF patches from Jun Kuriyama.
 
 Thu Oct  8 13:28:17 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
index 5c3f960..308733c 100644 (file)
@@ -10,12 +10,12 @@ test -d ./mpi || mkdir ./mpi
 echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h
 
 case "${target}" in
-    i[34]86*-*-freebsd*-elf)
+    i[34]86*-*-freebsd*-elf | i[34]86*-*-freebsd3*)
        echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h     >>./mpi/asm-syntax.h
        path="i386"
        ;;
-    i[56]86*-*-freebsd*-elf)
+    i[56]86*-*-freebsd*-elf | i[56]86*-*-freebsd3*)
        echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h     >>./mpi/asm-syntax.h
        path="i586 i386"
index 5c4611e..b9ec290 100644 (file)
@@ -1,3 +1,7 @@
+Fri Oct 30 20:03:17 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * fr.po: Imported new version
+
 Mon Oct 12 09:08:09 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
        * it.po: Imported new version.
index f6c2bc0..9bb50be 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -1,12 +1,12 @@
-# gnupg french translation
+# GnuPG french translation
 # Copyright (C) 1998 Free Software Foundation, Inc.
 # Gaël Quéri <gqueri@mail.dotcom.fr>, 1998.
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: gnupg-0.4.1\n"
-"POT-Creation-Date: 1998-10-18 16:36+0200\n"
-"PO-Revision-Date: 1998-10-11 00:21+0200\n"
+"Project-Id-Version: gnupg-0.4.1a\n"
+"POT-Creation-Date: 1998-10-29 17:30+0100\n"
+"PO-Revision-Date: 1998-10-29 19:01+0100\n"
 "Last-Translator: Gaël Quéri <gqueri@mail.dotcom.fr>\n"
 "Language-Team: French <fr@li.org>\n"
 "MIME-Version: 1.0\n"
@@ -199,8 +199,8 @@ msgstr "Mauvaise cl
 
 #: util/logger.c:177
 #, c-format
-msgid "Ohhhh jeeee ... this is a bug (%s:%d:%s)\n"
-msgstr "Ouais ... c'est un bug (%s:%d:%s)\n"
+msgid "... this is a bug (%s:%d:%s)\n"
+msgstr "... c'est un bug (%s:%d:%s)\n"
 
 #: util/logger.c:183
 #, c-format
@@ -237,7 +237,7 @@ msgstr ""
 "Il n'y a pas assez d'octets aléatoires disponibles. Faites autre chose\n"
 "pour que l'OS puisse amasser plus d'entropie! (il faut %d octets de plus)\n"
 
-#: g10/g10.c:149
+#: g10/g10.c:151
 msgid ""
 "@Commands:\n"
 " "
@@ -245,124 +245,124 @@ msgstr ""
 "@Commandes:\n"
 " "
 
-#: g10/g10.c:152
+#: g10/g10.c:154
 msgid "|[file]|make a signature"
 msgstr "|[fichier]|faire une signature"
 
-#: g10/g10.c:153
+#: g10/g10.c:155
 msgid "|[file]|make a clear text signature"
 msgstr "|[fichier]|faire une signature en texte clair"
 
-#: g10/g10.c:154
+#: g10/g10.c:156
 msgid "make a detached signature"
 msgstr "faire une signature détachée"
 
-#: g10/g10.c:155
+#: g10/g10.c:157
 msgid "encrypt data"
 msgstr "crypter les données"
 
-#: g10/g10.c:156
+#: g10/g10.c:158
 msgid "encryption only with symmetric cipher"
 msgstr "chiffrement symétrique seumement"
 
-#: g10/g10.c:157
+#: g10/g10.c:159
 msgid "store only"
 msgstr "pas d'action"
 
-#: g10/g10.c:158
+#: g10/g10.c:160
 msgid "decrypt data (default)"
 msgstr "décrypter les données (défaut)"
 
-#: g10/g10.c:159
+#: g10/g10.c:161
 msgid "verify a signature"
 msgstr "vérifier une signature"
 
-#: g10/g10.c:161
+#: g10/g10.c:163
 msgid "list keys"
 msgstr "lister les clés"
 
-#: g10/g10.c:162
+#: g10/g10.c:164
 msgid "list keys and signatures"
 msgstr "lister les clés et les signatures"
 
-#: g10/g10.c:163
+#: g10/g10.c:165
 msgid "check key signatures"
 msgstr "vérifier les signatures des clés"
 
-#: g10/g10.c:164
+#: g10/g10.c:166
 msgid "list keys and fingerprints"
 msgstr "lister les clés et les empreintes"
 
-#: g10/g10.c:165
+#: g10/g10.c:167
 msgid "list secret keys"
 msgstr "lister les clés secrètes"
 
-#: g10/g10.c:167
+#: g10/g10.c:169
 msgid "generate a new key pair"
 msgstr "générer une nouvelle paire de clés"
 
-#: g10/g10.c:169
+#: g10/g10.c:171
 msgid "remove key from the public keyring"
 msgstr "enlever la clé du porte-clés public"
 
-#: g10/g10.c:171
+#: g10/g10.c:173
 msgid "sign or edit a key"
 msgstr "signer ou éditer une clé"
 
-#: g10/g10.c:172
+#: g10/g10.c:174
 msgid "generate a revocation certificate"
 msgstr "générer un certificat de révocation"
 
-#: g10/g10.c:174
+#: g10/g10.c:176
 msgid "export keys"
 msgstr "exporter les clés"
 
-#: g10/g10.c:176
+#: g10/g10.c:178
 msgid "import/merge keys"
 msgstr "importer/fusionner les clés"
 
-#: g10/g10.c:177
+#: g10/g10.c:180
 msgid "list only the sequence of packets"
 msgstr "ne lister qu'une suite de paquets"
 
-#: g10/g10.c:180
+#: g10/g10.c:183
 msgid "export the ownertrust values"
 msgstr "exporter les valeurs de confiance"
 
-#: g10/g10.c:182
+#: g10/g10.c:185
 msgid "import ownertrust values"
 msgstr "importer les valeurs de confiance"
 
-#: g10/g10.c:184
-#, fuzzy
+#
+#: g10/g10.c:187
 msgid "|[NAMES]|update the trust database"
-msgstr "|[NOMS]|vérifier la base de confiance"
+msgstr "|[NOMS]|mettre la base de confiance à jour"
 
-#: g10/g10.c:186
+#: g10/g10.c:189
 msgid "|[NAMES]|check the trust database"
 msgstr "|[NOMS]|vérifier la base de confiance"
 
-#: g10/g10.c:187
+#: g10/g10.c:190
 msgid "fix a corrupted trust database"
 msgstr "réparer une base de confiance corrompue"
 
-#: g10/g10.c:188
+#: g10/g10.c:191
 msgid "De-Armor a file or stdin"
 msgstr "Enlever l'armure d'un fichier ou de stdin"
 
-#: g10/g10.c:189
+#: g10/g10.c:192
 msgid "En-Armor a file or stdin"
 msgstr "Mettre une armure à un fichier ou à stdin"
 
-#: g10/g10.c:190
+#: g10/g10.c:193
 msgid "|algo [files]|print message digests"
 msgstr "|alg. [fich.]|indiquer les fonctions de hachage"
 
-#: g10/g10.c:191
+#: g10/g10.c:194
 msgid "print all message digests"
 msgstr "écrire toutes les fonctions de hachage"
 
-#: g10/g10.c:198
+#: g10/g10.c:201
 msgid ""
 "@\n"
 "Options:\n"
@@ -372,129 +372,133 @@ msgstr ""
 "Options:\n"
 " "
 
-#: g10/g10.c:200
+#: g10/g10.c:203
 msgid "create ascii armored output"
 msgstr "créer une sortie ascii armurée"
 
-#: g10/g10.c:202
+#: g10/g10.c:205
 msgid "use this user-id to sign or decrypt"
 msgstr "utiliser ce nom pour signer ou décrypter"
 
-#: g10/g10.c:203
+#: g10/g10.c:206
 msgid "use this user-id for encryption"
 msgstr "utiliser ce nom d'utilisateur pour crypter"
 
-#: g10/g10.c:204
+#: g10/g10.c:207
 msgid "|N|set compress level N (0 disables)"
 msgstr "|N|niveau de compression N (0 désactive)"
 
-#: g10/g10.c:205
+#: g10/g10.c:208
 msgid "use canonical text mode"
 msgstr "utiliser le mode de texte canonique"
 
-#: g10/g10.c:207
+#: g10/g10.c:210
 msgid "use as output file"
 msgstr "utiliser comme fichier de sortie"
 
-#: g10/g10.c:208
+#: g10/g10.c:211
 msgid "verbose"
 msgstr "bavard"
 
-#: g10/g10.c:209
-#, fuzzy
+#: g10/g10.c:212
+msgid "be somewhat more quiet"
+msgstr "devenir beaucoup plus silencieux"
+
+#
+#: g10/g10.c:213
 msgid "force v3 signatures"
-msgstr "vérifier les signatures des clés"
+msgstr "forcer les signatures en v3"
 
 #. { oDryRun, "dry-run",   0, N_("do not make any changes") },
-#: g10/g10.c:211
+#: g10/g10.c:215
 msgid "batch mode: never ask"
-msgstr "mode automatique: ne jamais demander"
+msgstr "mode automatique: ne jamais rien demander"
 
-#: g10/g10.c:212
+#: g10/g10.c:216
 msgid "assume yes on most questions"
 msgstr "supposer oui à la plupart des questions"
 
-#: g10/g10.c:213
+#: g10/g10.c:217
 msgid "assume no on most questions"
 msgstr "supposer non à la plupart des questions"
 
-#: g10/g10.c:214
+#: g10/g10.c:218
 msgid "add this keyring to the list of keyrings"
 msgstr "ajouter ce porte-clés à la liste des porte-clés"
 
-#: g10/g10.c:215
+#: g10/g10.c:219
 msgid "add this secret keyring to the list"
 msgstr "ajouter ce porte-clés secret à la liste"
 
-#: g10/g10.c:216
+#: g10/g10.c:220
 msgid "|NAME|use NAME as default secret key"
 msgstr "|NOM|utiliser NOM comme clé secrète par défaut"
 
-#: g10/g10.c:217
+#: g10/g10.c:221
 msgid "read options from file"
 msgstr "lire les options du fichier"
 
-#: g10/g10.c:219
+#: g10/g10.c:223
 msgid "set debugging flags"
 msgstr "choisir les attributs de déboguage"
 
-#: g10/g10.c:220
+#: g10/g10.c:224
 msgid "enable full debugging"
 msgstr "permettre un déboguage complet"
 
-#: g10/g10.c:221
+#: g10/g10.c:225
 msgid "|FD|write status info to this FD"
 msgstr "|FD|écrire les informations d'état sur ce descripteur"
 
-#: g10/g10.c:222
+#: g10/g10.c:226
 msgid "do not write comment packets"
 msgstr "ne pas écrire de paquets de commentaire"
 
-#: g10/g10.c:223
+#: g10/g10.c:227
 msgid "(default is 1)"
 msgstr "(1 par défaut)"
 
-#: g10/g10.c:224
+#: g10/g10.c:228
 msgid "(default is 3)"
 msgstr "(3 par défaut)"
 
-#: g10/g10.c:225
+#: g10/g10.c:229
 msgid "|FILE|load extension module FILE"
 msgstr "|FICH|charger le module d'extension FICH"
 
-#: g10/g10.c:226
+#: g10/g10.c:230
 msgid "emulate the mode described in RFC1991"
 msgstr "émuler le mode décrit dans la RFC1991"
 
-#: g10/g10.c:227
+#: g10/g10.c:231
 msgid "|N|use passphrase mode N"
 msgstr "|N|utiliser le mode de mots de passe N"
 
-#: g10/g10.c:229
+#: g10/g10.c:233
 msgid "|NAME|use message digest algorithm NAME for passphrases"
 msgstr "|NOM|utiliser le hachage NOM pour les mots de passe"
 
-#: g10/g10.c:231
+#: g10/g10.c:235
 msgid "|NAME|use cipher algorithm NAME for passphrases"
 msgstr "|NOM|utiliser le cryptage NOM pour les mots de passe"
 
-#: g10/g10.c:233
+#: g10/g10.c:237
 msgid "|NAME|use cipher algorithm NAME"
 msgstr "|NOM|utiliser l'algorithme de cryptage NOM"
 
-#: g10/g10.c:234
+#: g10/g10.c:238
 msgid "|NAME|use message digest algorithm NAME"
 msgstr "|NOM|utiliser la fonction de hachage NOM"
 
-#: g10/g10.c:235
+#: g10/g10.c:239
 msgid "|N|use compress algorithm N"
 msgstr "|N|utiliser l'algorithme de compression N"
 
-#: g10/g10.c:236
+#: g10/g10.c:240
 msgid "throw keyid field of encrypted packets"
 msgstr "enlever l'identification des paquets cryptés"
 
-#: g10/g10.c:244
+#: g10/g10.c:248
 msgid ""
 "@\n"
 "Examples:\n"
@@ -514,28 +518,28 @@ msgstr ""
 " --list-keys [utilisateur]    montrer les clés\n"
 " --fingerprint [utilisateur]  montrer les empreintes\n"
 
-#: g10/g10.c:319
+#: g10/g10.c:323
 msgid "Please report bugs to <gnupg-bugs@gnu.org>.\n"
 msgstr "Rapporter toutes anomalies à <gnupg-bugs@gnu.org>.\n"
 
-#: g10/g10.c:324
+#: g10/g10.c:328
 msgid "Usage: gpgm [options] [files] (-h for help)"
 msgstr "Utilisation: gpgm [options] [fichiers] (-h pour l'aide)"
 
-#: g10/g10.c:326
+#: g10/g10.c:330
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Utilisation: gpg [options] [fichiers] (-h pour l'aide)"
 
-#: g10/g10.c:331
-#, fuzzy
+#
+#: g10/g10.c:335
 msgid ""
 "Syntax: gpgm [options] [files]\n"
 "GnuPG maintenance utility\n"
 msgstr ""
 "Syntaxe: gpgm [options] [fichiers]\n"
-"utilitaire de maitenance de GNUPG\n"
+"utilitaire de maitenance de GnuPG\n"
 
-#: g10/g10.c:334
+#: g10/g10.c:338
 msgid ""
 "Syntax: gpg [options] [files]\n"
 "sign, check, encrypt or decrypt\n"
@@ -545,7 +549,7 @@ msgstr ""
 "signer, vérifier, crypter ou décrypter\n"
 "l'opération par défaut dépend des données entrées\n"
 
-#: g10/g10.c:340
+#: g10/g10.c:344
 msgid ""
 "\n"
 "Supported algorithms:\n"
@@ -553,141 +557,141 @@ msgstr ""
 "\n"
 "Algorithmes supportés:\n"
 
-#: g10/g10.c:415
+#: g10/g10.c:419
 msgid "usage: gpgm [options] "
 msgstr "utilisation: gpgm [options] "
 
-#: g10/g10.c:417
+#: g10/g10.c:421
 msgid "usage: gpg [options] "
 msgstr "utilisation: gpg [options] "
 
-#: g10/g10.c:458
+#: g10/g10.c:462
 msgid "conflicting commands\n"
 msgstr "commandes en conflit\n"
 
-#: g10/g10.c:596
+#: g10/g10.c:600
 #, c-format
 msgid "note: no default option file '%s'\n"
 msgstr "note: pas de fichier d'options par défaut '%s'\n"
 
-#: g10/g10.c:600
+#: g10/g10.c:604
 #, c-format
 msgid "option file '%s': %s\n"
 msgstr "fichier d'options '%s' : %s\n"
 
-#: g10/g10.c:607
+#: g10/g10.c:611
 #, c-format
 msgid "reading options from '%s'\n"
 msgstr "lire les options de '%s'\n"
 
-#: g10/g10.c:778 g10/g10.c:790
+#: g10/g10.c:784 g10/g10.c:796
 msgid "selected cipher algorithm is invalid\n"
 msgstr "l'algorithme de cryptage sélectionné est invalide\n"
 
-#: g10/g10.c:784 g10/g10.c:796
+#: g10/g10.c:790 g10/g10.c:802
 msgid "selected digest algorithm is invalid\n"
 msgstr "la fonction de hachage sélectionnée est invalide\n"
 
-#: g10/g10.c:799
+#: g10/g10.c:805
 #, c-format
 msgid "compress algorithm must be in range %d..%d\n"
 msgstr "l'algorithme de compression doit faire partie de l'échelle %d..%d\n"
 
-#: g10/g10.c:801
+#: g10/g10.c:807
 msgid "completes-needed must be greater than 0\n"
 msgstr "le nombre de signatures complètes minimal doit être supérieur à 0\n"
 
-#: g10/g10.c:803
+#: g10/g10.c:809
 msgid "marginals-needed must be greater than 1\n"
 msgstr "le nombre de singatures marginales minimal doit être supérieur à 1\n"
 
-#: g10/g10.c:806
+#: g10/g10.c:812
 msgid "note: simple S2K mode (0) is strongly discouraged\n"
 msgstr "note: le mode S2K simple (0) est fortement déconseillé\n"
 
-#: g10/g10.c:810
+#: g10/g10.c:816
 msgid "invalid S2K mode; must be 0, 1 or 3\n"
 msgstr "mode S2K invalide; doit être 0, 1 ou 3\n"
 
-#: g10/g10.c:886
+#: g10/g10.c:892
 #, c-format
 msgid "failed to initialize the TrustDB: %s\n"
 msgstr "n'a pas pu initialiser la base de confiance: %s\n"
 
-#: g10/g10.c:892
+#: g10/g10.c:898
 msgid "--store [filename]"
 msgstr "--store [nom du fichier]"
 
-#: g10/g10.c:900
+#: g10/g10.c:906
 msgid "--symmetric [filename]"
 msgstr "--symmetric [nom du fichier]"
 
-#: g10/g10.c:908
+#: g10/g10.c:914
 msgid "--encrypt [filename]"
 msgstr "--encrypt [nom du fichier]"
 
-#: g10/g10.c:921
+#: g10/g10.c:927
 msgid "--sign [filename]"
 msgstr "--sign [nom du fichier]"
 
-#: g10/g10.c:934
+#: g10/g10.c:940
 msgid "--sign --encrypt [filename]"
 msgstr "--sign --encrypt [nom du fichier]"
 
-#: g10/g10.c:948
+#: g10/g10.c:954
 msgid "--clearsign [filename]"
 msgstr "--clearsign [nom du fichier]"
 
-#: g10/g10.c:960
+#: g10/g10.c:966
 msgid "--decrypt [filename]"
 msgstr "--decrypt [nom du fichier]"
 
-#: g10/g10.c:969
+#: g10/g10.c:975
 msgid "--edit-key username"
 msgstr "--edit-key utilisateur"
 
-#: g10/g10.c:977
+#: g10/g10.c:983
 msgid "--delete-secret-key username"
 msgstr "--delete-secret-key utilisateur"
 
-#: g10/g10.c:980
+#: g10/g10.c:986
 msgid "--delete-key username"
 msgstr "--delete-key utilisateur"
 
-#: g10/encode.c:215 g10/g10.c:1003 g10/keylist.c:80
+#: g10/encode.c:216 g10/g10.c:1009
 #, c-format
 msgid "can't open %s: %s\n"
 msgstr "ne peut ouvrir %s: %s\n"
 
-#: g10/g10.c:1014
+#: g10/g10.c:1020
 msgid "-k[v][v][v][c] [userid] [keyring]"
 msgstr "-k[v][v][v][c] [utilisateur] [porte-clés]"
 
-#: g10/g10.c:1069
+#: g10/g10.c:1076
 #, c-format
 msgid "dearmoring failed: %s\n"
 msgstr "suppression d'armure non réussie: %s\n"
 
-#: g10/g10.c:1077
+#: g10/g10.c:1084
 #, c-format
 msgid "enarmoring failed: %s\n"
 msgstr "mise d'armure non réussie:%s \n"
 
-#: g10/g10.c:1138
+#: g10/g10.c:1145
 #, c-format
 msgid "invalid hash algorithm '%s'\n"
 msgstr "algorithme de hachage invalide '%s'\n"
 
-#: g10/g10.c:1220
+#: g10/g10.c:1227
 msgid "[filename]"
 msgstr "[nom du fichier]"
 
-#: g10/decrypt.c:59 g10/g10.c:1222 g10/verify.c:66
+#: g10/decrypt.c:59 g10/g10.c:1229 g10/verify.c:66
 #, c-format
 msgid "can't open '%s'\n"
 msgstr "ne peut ouvrir '%s'\n"
 
-#: g10/g10.c:1269
+#: g10/g10.c:1276
 msgid ""
 "RSA keys are deprecated; please consider creating a new key and use this key "
 "in the future\n"
@@ -1100,7 +1104,7 @@ msgstr ""
 msgid "Is this correct (y/n)? "
 msgstr "Est-ce correct (o/n)? "
 
-#: g10/keygen.c:561
+#: g10/keygen.c:569
 msgid ""
 "\n"
 "You need a User-ID to identify your key; the software constructs the user "
@@ -1116,51 +1120,51 @@ msgstr ""
 "   \"Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de\"\n"
 "\n"
 
-#: g10/keygen.c:572
+#: g10/keygen.c:580
 msgid "keygen.name"
 msgstr ""
 
-#: g10/keygen.c:572
+#: g10/keygen.c:580
 msgid "Real name: "
 msgstr "Nom: "
 
-#: g10/keygen.c:576
+#: g10/keygen.c:584
 msgid "Invalid character in name\n"
 msgstr "Caractère invalide dans le nom\n"
 
-#: g10/keygen.c:578
+#: g10/keygen.c:586
 msgid "Name may not start with a digit\n"
 msgstr "Le nom ne doit pas commencer avec un chiffre\n"
 
-#: g10/keygen.c:580
+#: g10/keygen.c:588
 msgid "Name must be at least 5 characters long\n"
 msgstr "Le nom doit faire au moins 5 caractères de long\n"
 
-#: g10/keygen.c:588
+#: g10/keygen.c:596
 msgid "keygen.email"
 msgstr ""
 
-#: g10/keygen.c:588
+#: g10/keygen.c:596
 msgid "Email address: "
 msgstr "Adresse e-mail: "
 
-#: g10/keygen.c:600
+#: g10/keygen.c:608
 msgid "Not a valid email address\n"
 msgstr "Ce n'est pas une adresse e-mail valide\n"
 
-#: g10/keygen.c:608
+#: g10/keygen.c:616
 msgid "keygen.comment"
 msgstr ""
 
-#: g10/keygen.c:608
+#: g10/keygen.c:616
 msgid "Comment: "
 msgstr "Commentaire: "
 
-#: g10/keygen.c:614
+#: g10/keygen.c:622
 msgid "Invalid character in comment\n"
 msgstr "Caractère invalide dans le commentaire\n"
 
-#: g10/keygen.c:634
+#: g10/keygen.c:642
 #, c-format
 msgid ""
 "You selected this USER-ID:\n"
@@ -1171,11 +1175,11 @@ msgstr ""
 "    \"%s\"\n"
 "\n"
 
-#: g10/keygen.c:637
+#: g10/keygen.c:645
 msgid "NnCcEeOoQq"
 msgstr "NnCcEeOoQq"
 
-#: g10/keygen.c:646
+#: g10/keygen.c:654
 msgid "keygen.userid.cmd"
 msgstr ""
 "N pour changer le nom.\n"
@@ -1184,11 +1188,11 @@ msgstr ""
 "O pour continuer à générer la clé.\n"
 "Q pour arrêter de générer de clé."
 
-#: g10/keygen.c:647
+#: g10/keygen.c:655
 msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
 msgstr "Changer le (N)om, le (C)ommentaire, l'(E)-mail ou (O)K/(Q)uitter? "
 
-#: g10/keygen.c:694
+#: g10/keygen.c:702
 msgid ""
 "You need a Passphrase to protect your secret key.\n"
 "\n"
@@ -1196,11 +1200,11 @@ msgstr ""
 "Vous avez besoin d'un mot de passe pour protéger votre clé secrète.\n"
 "\n"
 
-#: g10/keyedit.c:389 g10/keygen.c:702
+#: g10/keyedit.c:389 g10/keygen.c:710
 msgid "passphrase not correctly repeated; try again.\n"
 msgstr "le mot de passe n'a pas été correctement répété; recommencez.\n"
 
-#: g10/keygen.c:708
+#: g10/keygen.c:716
 msgid ""
 "You don't want a passphrase - this is probably a *bad* idea!\n"
 "I will do it anyway.  You can change your passphrase at any time,\n"
@@ -1212,7 +1216,7 @@ msgstr ""
 "le désirez, en utilisant ce programme avec l'option \"--edit-key\".\n"
 "\n"
 
-#: g10/keygen.c:729
+#: g10/keygen.c:737
 msgid ""
 "We need to generate a lot of random bytes. It is a good idea to perform\n"
 "some other action (work in another window, move the mouse, utilize the\n"
@@ -1225,33 +1229,33 @@ msgstr ""
 "premiers; cela permet au générateur de nombres aléatoires de gagner assez\n"
 "d'entropie plus facilement.\n"
 
-#: g10/keygen.c:799
+#: g10/keygen.c:807
 msgid "Key generation can only be used in interactive mode\n"
 msgstr "La génération de clé ne peut être faite qu'en mode interactif\n"
 
-#: g10/keygen.c:807
+#: g10/keygen.c:815
 msgid "DSA keypair will have 1024 bits.\n"
 msgstr "La paire de clés DSA fera 1024 bits.\n"
 
-#: g10/keygen.c:813
+#: g10/keygen.c:821
 msgid "Key generation cancelled.\n"
 msgstr "La génération a été annulée.\n"
 
-#: g10/keygen.c:823
+#: g10/keygen.c:831
 #, c-format
 msgid "writing public certificate to '%s'\n"
 msgstr "écriture d'un certificat public à '%s'\n"
 
-#: g10/keygen.c:824
+#: g10/keygen.c:832
 #, c-format
 msgid "writing secret certificate to '%s'\n"
 msgstr "écriture d'un certificat secret à '%s'\n"
 
-#: g10/keygen.c:901
+#: g10/keygen.c:909
 msgid "public and secret key created and signed.\n"
 msgstr "les clés publique et secrète ont été créées et signées.\n"
 
-#: g10/keygen.c:903
+#: g10/keygen.c:911
 msgid ""
 "Note that this key cannot be used for encryption.  You may want to use\n"
 "the command \"--add-key\" to generate a secondary key for this purpose.\n"
@@ -1260,20 +1264,20 @@ msgstr ""
 "utiliser\n"
 "la commande \"--add-key\" pour générer une clé secondaire à cette fin.\n"
 
-#: g10/keygen.c:917 g10/keygen.c:1002
+#: g10/keygen.c:925 g10/keygen.c:1010
 #, c-format
 msgid "Key generation failed: %s\n"
 msgstr "La génération de clé a échoué: %s\n"
 
-#: g10/keygen.c:979
+#: g10/keygen.c:987
 msgid "keygen.sub.okay"
 msgstr "Répondez \"oui\" (ou simplement \"o\") pour générer la sous-clé"
 
-#: g10/keygen.c:980
+#: g10/keygen.c:988
 msgid "Really create? "
 msgstr "Créer vraiment? "
 
-#: g10/encode.c:88
+#: g10/encode.c:88 g10/openfile.c:81 g10/openfile.c:158
 #, c-format
 msgid "%s: can't open: %s\n"
 msgstr "%s: ne peut ouvrir: %s\n"
@@ -1283,230 +1287,288 @@ msgstr "%s: ne peut ouvrir: %s\n"
 msgid "error creating passphrase: %s\n"
 msgstr "erreur pendant la création du mot de passe: %s\n"
 
-#: g10/encode.c:154 g10/encode.c:267
+#: g10/encode.c:155 g10/encode.c:269
 #, c-format
 msgid "%s: warning: empty file\n"
 msgstr "%s: attention: fichier vide\n"
 
-#: g10/encode.c:221
+#: g10/encode.c:222
 #, c-format
 msgid "reading from '%s'\n"
 msgstr "lecture de '%s'\n"
 
-#: g10/encode.c:395
+#: g10/encode.c:397
 #, c-format
 msgid "%s encrypted for: %s\n"
 msgstr "%s crypté pour: %s\n"
 
-#: g10/getkey.c:854
+#: g10/getkey.c:850
 #, c-format
 msgid "using secondary key %08lX instead of primary key %08lX\n"
 msgstr ""
 "utilisation de la clé secondaire %08lX à la place de la clé\n"
 "principale %08lX\n"
 
-#: g10/import.c:106 g10/trustdb.c:1100
+#: g10/import.c:125 g10/trustdb.c:1082
 #, c-format
 msgid "can't open file: %s\n"
 msgstr "ne peut ouvrir le fichier: %s\n"
 
-#: g10/import.c:122
+#: g10/import.c:141
 #, c-format
 msgid "skipping block of type %d\n"
 msgstr "ne prend pas en compte le bloc du type %d\n"
 
-#: g10/import.c:132 g10/trustdb.c:1175
+#: g10/import.c:148 g10/trustdb.c:1284 g10/trustdb.c:1349
+#, c-format
+msgid "%lu keys so far processed\n"
+msgstr "%lu clés traitées jusqu'ici\n"
+
+#: g10/import.c:153 g10/trustdb.c:1157
 #, c-format
 msgid "read error: %s\n"
 msgstr "erreur de lecture: %s\n"
 
-#: g10/import.c:273 g10/import.c:446
+#: g10/import.c:155
+#, c-format
+msgid "Total number processed: %lu\n"
+msgstr "       Quantité totale traitée: %lu\n"
+
+#: g10/import.c:157
+#, c-format
+msgid "          w/o user IDs: %lu\n"
+msgstr "        sans nom d'utilisateur: %lu\n"
+
+#: g10/import.c:159
+#, c-format
+msgid "              imported: %lu"
+msgstr "                       importé: %lu"
+
+#: g10/import.c:165
+#, c-format
+msgid "             unchanged: %lu\n"
+msgstr "                      inchangé: %lu\n"
+
+#: g10/import.c:167
+#, c-format
+msgid "          new user IDs: %lu\n"
+msgstr "   nouveaux noms d'utilisateur: %lu\n"
+
+#: g10/import.c:169
+#, c-format
+msgid "           new subkeys: %lu\n"
+msgstr "           nouvelles sous-clés: %lu\n"
+
+#: g10/import.c:171
+#, c-format
+msgid "        new signatures: %lu\n"
+msgstr "          nouvelles signatures: %lu\n"
+
+#: g10/import.c:173
+#, c-format
+msgid "   new key revocations: %lu\n"
+msgstr " nouvelles révocations de clés: %lu\n"
+
+#: g10/import.c:175
+#, c-format
+msgid "      secret keys read: %lu\n"
+msgstr "            clés secrètes lues: %lu\n"
+
+#: g10/import.c:177
+#, c-format
+msgid "  secret keys imported: %lu\n"
+msgstr "       clés secrètes importées: %lu\n"
+
+#: g10/import.c:179
+#, c-format
+msgid " secret keys unchanged: %lu\n"
+msgstr "      clés secrètes inchangées: %lu\n"
+
+#: g10/import.c:321 g10/import.c:513
 #, c-format
 msgid "key %08lX: no user id\n"
 msgstr "clé %08lX: pas de nom d'utilisateur\n"
 
-#: g10/import.c:283
+#: g10/import.c:332
 #, c-format
 msgid "key %08lX: no valid user ids\n"
 msgstr "clé %08lX: pas de nom d'utilisateur valide\n"
 
-#: g10/import.c:285
+#: g10/import.c:334
 msgid "this may be caused by a missing self-signature\n"
 msgstr "cela peut provenir d'une auto-signature manquante\n"
 
-#: g10/import.c:294 g10/import.c:512
+#: g10/import.c:345 g10/import.c:581
 #, c-format
 msgid "key %08lX: public key not found: %s\n"
 msgstr "clé %08lX: clé publique pas trouvée: %s\n"
 
-#: g10/import.c:300
+#: g10/import.c:351
 msgid "no default public keyring\n"
 msgstr "pas de porte-clés public par défaut\n"
 
-#: g10/import.c:304
+#: g10/import.c:355 g10/openfile.c:105
 #, c-format
 msgid "writing to '%s'\n"
 msgstr "écriture de '%s'\n"
 
-#: g10/import.c:308 g10/import.c:363 g10/import.c:566
+#: g10/import.c:359 g10/import.c:419 g10/import.c:635
 #, c-format
 msgid "can't lock public keyring: %s\n"
 msgstr "ne peut verrouiller le porte-clés public: %s\n"
 
-#: g10/import.c:311
+#: g10/import.c:362
 #, c-format
 msgid "can't write to keyring: %s\n"
 msgstr "ne peut écrire sur le porte-clés: %s\n"
 
-#. we are ready
-#: g10/import.c:314
+#: g10/import.c:366
 #, c-format
 msgid "key %08lX: public key imported\n"
 msgstr "clé %08lX: clé publique importée\n"
 
-#: g10/import.c:323
+#: g10/import.c:379
 #, c-format
 msgid "key %08lX: doesn't match our copy\n"
 msgstr "clé %08lX: ne vérifie pas notre copie\n"
 
-#: g10/import.c:336 g10/import.c:521
+#: g10/import.c:392 g10/import.c:590
 #, c-format
 msgid "key %08lX: can't locate original keyblock: %s\n"
 msgstr "clé %08lX: ne peut trouver le bloc de clés original: %s\n"
 
-#: g10/import.c:343 g10/import.c:528
+#: g10/import.c:399 g10/import.c:597
 #, c-format
 msgid "key %08lX: can't read original keyblock: %s\n"
 msgstr "clé %08lX: ne peut lire le bloc de clés original: %s\n"
 
-#: g10/import.c:360 g10/import.c:461 g10/import.c:563
+#: g10/import.c:416 g10/import.c:528 g10/import.c:632
 msgid "writing keyblock\n"
 msgstr "écriture du bloc de clés\n"
 
-#: g10/import.c:366 g10/import.c:569
+#: g10/import.c:422 g10/import.c:638
 #, c-format
 msgid "can't write keyblock: %s\n"
 msgstr "ne peut écrire le bloc de clés: %s\n"
 
-#: g10/import.c:370
+#: g10/import.c:427
 #, c-format
 msgid "key %08lX: 1 new user-id\n"
 msgstr "clé %08lX: un nouvel utilisateur\n"
 
-#: g10/import.c:373
+#: g10/import.c:430
 #, c-format
 msgid "key %08lX: %d new user-ids\n"
 msgstr "clé %08lX: %d nouveaux utilisateurs\n"
 
-#: g10/import.c:376
+#: g10/import.c:433
 #, c-format
 msgid "key %08lX: 1 new signature\n"
 msgstr "clé %08lX: une nouvelle signature\n"
 
-#: g10/import.c:379
+#: g10/import.c:436
 #, c-format
 msgid "key %08lX: %d new signatures\n"
 msgstr "clé %08lX: %d nouvelles signatures\n"
 
-#: g10/import.c:382
+#: g10/import.c:439
 #, c-format
 msgid "key %08lX: 1 new subkey\n"
 msgstr "clé %08lX: une nouvelle sous-clé\n"
 
-#: g10/import.c:385
+#: g10/import.c:442
 #, c-format
 msgid "key %08lX: %d new subkeys\n"
 msgstr "clé %08lX: %d nouvelles sous-clés\n"
 
-#: g10/import.c:389
+#: g10/import.c:452
 #, c-format
 msgid "key %08lX: not changed\n"
 msgstr "clé %08lX: n'a pas changé\n"
 
-#: g10/import.c:464
+#: g10/import.c:531
 #, c-format
 msgid "can't lock secret keyring: %s\n"
 msgstr "ne peut verrouiller le porte-clés secret: %s\n"
 
-#: g10/import.c:467
+#: g10/import.c:534
 #, c-format
 msgid "can't write keyring: %s\n"
 msgstr "ne peut écrire le porte-clés: %s\n"
 
 #. we are ready
-#: g10/import.c:470
+#: g10/import.c:537
 #, c-format
 msgid "key %08lX: secret key imported\n"
 msgstr "clé %08lX: clé secrète importée\n"
 
 #. we can't merge secret keys
-#: g10/import.c:473
+#: g10/import.c:541
 #, c-format
 msgid "key %08lX: already in secret keyring\n"
 msgstr "clé %08lX: déjà dans le porte-clés secret\n"
 
-#: g10/import.c:477
+#: g10/import.c:546
 #, c-format
 msgid "key %08lX: secret key not found: %s\n"
 msgstr "clé %08lX: clé secrète pas trouvée: %s\n"
 
-#: g10/import.c:506
+#: g10/import.c:575
 #, c-format
 msgid "key %08lX: no public key - can't apply revocation certificate\n"
 msgstr ""
 "clé %08lX: pas de clé publique - ne peut appliquer le certificat de\n"
 "révocation\n"
 
-#: g10/import.c:539
+#: g10/import.c:608
 #, c-format
 msgid "key %08lX: invalid revocation certificate: %s - rejected\n"
 msgstr "clé %08lX: certificat de révocation invalide: %s - rejeté\n"
 
-#. we are ready
-#: g10/import.c:572
+#: g10/import.c:642
 #, c-format
 msgid "key %08lX: revocation certificate imported\n"
 msgstr "clé %08lX: certificat de révocation importé\n"
 
-#: g10/import.c:602
+#: g10/import.c:673
 #, c-format
 msgid "key %08lX: no user-id for signature\n"
 msgstr "clé %08lX: pas d'utilisateur pour la signature\n"
 
-#: g10/import.c:609
+#: g10/import.c:680
 #, c-format
 msgid "key %08lX: unsupported public key algorithm\n"
 msgstr "clé %08lX: algorithme de clé publique non supporté\n"
 
-#: g10/import.c:610
+#: g10/import.c:681
 #, c-format
 msgid "key %08lX: invalid self-signature\n"
 msgstr "clé %08lX: auto-signature invalide\n"
 
-#: g10/import.c:639
+#: g10/import.c:710
 #, c-format
 msgid "key %08lX: skipped userid '"
 msgstr "clé %08lX: utilisateur non pris en compte '"
 
-#: g10/import.c:662
+#: g10/import.c:733
 #, c-format
 msgid "key %08lX: revocation certificate at wrong place - skipped\n"
 msgstr ""
 "clé %08lX: certificat de révocation au mauvais endroit - non prise en "
 "compte\n"
 
-#: g10/import.c:670
+#: g10/import.c:741
 #, c-format
 msgid "key %08lX: invalid revocation certificate: %s - skipped\n"
 msgstr ""
 "clé %08lX: certificat de révocation invalide: %s - non prise en compte\n"
 
-#: g10/import.c:732
+#: g10/import.c:803
 #, c-format
 msgid "key %08lX: revocation certificate added\n"
 msgstr "clé %08lX: certificat de révocation ajouté\n"
 
-#: g10/import.c:795 g10/import.c:831
+#: g10/import.c:866 g10/import.c:902
 #, c-format
 msgid "key %08lX: our copy has no self-signature\n"
 msgstr "clé %08lX: notre copie n'a pas d'auto-signature\n"
@@ -1748,14 +1810,12 @@ msgid "delete a secondary key"
 msgstr "enlever une clé secondaire"
 
 #: g10/keyedit.c:508
-#, fuzzy
 msgid "expire"
-msgstr "préf"
+msgstr "expire"
 
 #: g10/keyedit.c:508
-#, fuzzy
 msgid "change the expire date"
-msgstr "changer le mot de passe"
+msgstr "changer la date d'expiration"
 
 #: g10/keyedit.c:509
 msgid "toggle"
@@ -1803,164 +1863,163 @@ msgstr "ne peut faire cela en mode automatique\n"
 msgid "Secret key is available.\n"
 msgstr "La clé secrète est disponible.\n"
 
-#: g10/keyedit.c:575
+#: g10/keyedit.c:576
 msgid "keyedit.cmd"
 msgstr "Entrez \"aide\" s'il vous plaît."
 
-#: g10/keyedit.c:575
+#: g10/keyedit.c:576
 msgid "Command> "
 msgstr "Commande> "
 
-#: g10/keyedit.c:600
+#: g10/keyedit.c:602
 msgid "Need the secret key to to this.\n"
 msgstr "Il faut la clé secrète pour faire cela.\n"
 
-#: g10/keyedit.c:619
+#: g10/keyedit.c:621
 msgid "keyedit.save.okay"
 msgstr ""
 
-#: g10/keyedit.c:620
+#: g10/keyedit.c:622
 msgid "Save changes? "
 msgstr "Enregistrer les changements? "
 
-#: g10/keyedit.c:622
+#: g10/keyedit.c:624
 msgid "keyedit.cancel.okay"
 msgstr ""
 
-#: g10/keyedit.c:623
+#: g10/keyedit.c:625
 msgid "Quit without saving? "
 msgstr "Quitter sans enregistrer? "
 
-#: g10/keyedit.c:633
+#: g10/keyedit.c:635
 #, c-format
 msgid "update failed: %s\n"
 msgstr "la mise à jour a échoué: %s\n"
 
-#: g10/keyedit.c:640
+#: g10/keyedit.c:642
 #, c-format
 msgid "update secret failed: %s\n"
 msgstr "la mise à jour de la clé secrète a échoué: %s\n"
 
-#: g10/keyedit.c:647
+#: g10/keyedit.c:649
 msgid "Key not changed so no update needed.\n"
 msgstr "La clé n'a pas changé donc la mise à jour est inutile.\n"
 
-#: g10/keyedit.c:650 g10/keyedit.c:708
+#: g10/keyedit.c:652 g10/keyedit.c:710
 #, c-format
 msgid "update of trust db failed: %s\n"
 msgstr "la mise à jour de la base de confiance a échoué: %s\n"
 
-#: g10/keyedit.c:681
+#: g10/keyedit.c:683
 msgid "keyedit.sign_all.okay"
 msgstr ""
 
-#: g10/keyedit.c:682
+#: g10/keyedit.c:684
 msgid "Really sign all user ids? "
 msgstr "Signer vraiment tous les utilisateurs? "
 
-#: g10/keyedit.c:683
+#: g10/keyedit.c:685
 msgid "Hint: Select the user ids to sign\n"
 msgstr "Aide: Sélectionner les utilisateurs à signer\n"
 
-#: g10/keyedit.c:719
+#: g10/keyedit.c:721
 msgid "You must select at least one user id.\n"
 msgstr "Vous devez sélectionner au moins un utilisateur.\n"
 
-#: g10/keyedit.c:721
+#: g10/keyedit.c:723
 msgid "You can't delete the last user id!\n"
 msgstr "Vous ne pouvez pas supprimer le dernier utilisateur!\n"
 
-#: g10/keyedit.c:723
+#: g10/keyedit.c:725
 msgid "keyedit.remove.uid.okay"
 msgstr ""
 
-#: g10/keyedit.c:724
+#: g10/keyedit.c:726
 msgid "Really remove all selected user ids? "
 msgstr "Enlever réellement tous les utilisateurs sélectionnés? "
 
-#: g10/keyedit.c:725
+#: g10/keyedit.c:727
 msgid "Really remove this user id? "
 msgstr "Enlever réellement cet utilisateur? "
 
-#: g10/keyedit.c:748
+#: g10/keyedit.c:750
 msgid "You must select at least one key.\n"
 msgstr "Vous devez sélectionner au moins une clé.\n"
 
-#: g10/keyedit.c:750
+#: g10/keyedit.c:752
 msgid "keyedit.remove.subkey.okay"
 msgstr ""
 
-#: g10/keyedit.c:752
+#: g10/keyedit.c:754
 msgid "Do you really want to delete the selected keys? "
 msgstr "Voulez-vous supprimer les clés sélectionnées? "
 
-#: g10/keyedit.c:753
+#: g10/keyedit.c:755
 msgid "Do you really want to delete this key? "
 msgstr "Voulez-vous vraiment supprimer cette clé? "
 
-#: g10/keyedit.c:800
+#: g10/keyedit.c:802
 msgid "Invalid command  (try \"help\")\n"
 msgstr "Commande invalide  (essayez \"help\")\n"
 
-#: g10/keyedit.c:1178
+#: g10/keyedit.c:1180
 msgid "Please remove selections from the secret keys.\n"
-msgstr ""
+msgstr "Enlevez les sélections des clés secrètes.\n"
 
-#: g10/keyedit.c:1184
-#, fuzzy
+#: g10/keyedit.c:1186
 msgid "Please select at most one secondary key.\n"
-msgstr "Vous devez sélectionner au moins une clé.\n"
+msgstr "Vous devez sélectionner au plus une clé secondaire.\n"
 
-#: g10/keyedit.c:1188
+#: g10/keyedit.c:1190
 msgid "Changing exiration time for a secondary key.\n"
-msgstr ""
+msgstr "Changer la date d'expiration d'une clé secondaire.\n"
 
-#: g10/keyedit.c:1190
+#: g10/keyedit.c:1192
 msgid "Changing exiration time for the primary key.\n"
-msgstr ""
+msgstr "Changer la date d'expiration de la clé primaire.\n"
 
-#: g10/keyedit.c:1234
+#: g10/keyedit.c:1236
 msgid "No corresponding signature in secret ring\n"
-msgstr ""
+msgstr "Pas de signature correspondante dans le porte-clés secret\n"
 
-#: g10/keyedit.c:1294
+#: g10/keyedit.c:1296
 #, c-format
 msgid "No user id with index %d\n"
 msgstr "Pas d'utilisateur avec l'index %d\n"
 
-#: g10/keyedit.c:1339
+#: g10/keyedit.c:1341
 #, c-format
 msgid "No secondary key with index %d\n"
 msgstr "Pas de clé secondaire avec l'index %d\n"
 
-#: g10/mainproc.c:200
+#: g10/mainproc.c:201
 #, c-format
 msgid "public key decryption failed: %s\n"
 msgstr "le décryptage de la clé publique a échoué: %s\n"
 
-#: g10/mainproc.c:230
+#: g10/mainproc.c:231
 #, c-format
 msgid "decryption failed: %s\n"
 msgstr "le décryptage a échoué: %s\n"
 
-#: g10/mainproc.c:247
+#: g10/mainproc.c:248
 msgid "note: sender requested \"for-your-eyes-only\"\n"
 msgstr "note: l'expéditeur a demandé \"pour vos yeux seulement\"\n"
 
-#: g10/mainproc.c:848
+#: g10/mainproc.c:842
 #, c-format
 msgid "Signature made %.*s using %s key ID %08lX\n"
 msgstr "Signature faite %.*s avec %s clé ID %08lX\n"
 
-#: g10/mainproc.c:856
+#: g10/mainproc.c:850
 msgid "BAD signature from \""
 msgstr "MAUVAISE signature de \""
 
-#: g10/mainproc.c:857
+#: g10/mainproc.c:851
 msgid "Good signature from \""
 msgstr "Bonne signature de \""
 
-#: g10/mainproc.c:868
+#: g10/mainproc.c:862
 #, c-format
 msgid "Can't check signature: %s\n"
 msgstr "Ne peut vérifier la signature: %s\n"
@@ -2049,193 +2108,237 @@ msgstr ""
 msgid "warning: signature key expired %s\n"
 msgstr "attention: la clé de signature a expiré le %s\n"
 
-#: g10/trustdb.c:122
+#: g10/trustdb.c:115
 msgid "The trust DB is corrupted; please run \"gpgm --fix-trust-db\".\n"
 msgstr ""
 "La base de confiance est corrompue; exécutez \"gpgm --fix-trust-db\".\n"
 
-#: g10/trustdb.c:389
+#: g10/trustdb.c:379
 #, c-format
 msgid "chained sigrec %lu has a wrong owner\n"
 msgstr "l'enregistrement de signature %lu a un mauvais propriétaire\n"
 
-#: g10/trustdb.c:436
-#, fuzzy, c-format
+#: g10/trustdb.c:426
+#, c-format
 msgid "key %08lX: secret key without public key - skipped\n"
-msgstr "clé %08lX: clé secrète sans clé publique\n"
+msgstr "clé %08lX: clé secrète sans clé publique - non prise en compte\n"
 
-#: g10/trustdb.c:442
+#: g10/trustdb.c:432
 #, c-format
 msgid "key %08lX: secret and public key don't match\n"
 msgstr "clé %08lX: les clés secrète et publique ne correspondent pas\n"
 
-#: g10/trustdb.c:452
+#: g10/trustdb.c:442
 #, c-format
 msgid "key %08lX: can't put it into the trustdb\n"
 msgstr "clé %08lX: ne peut mettre cela dans la base de confiance\n"
 
-#: g10/trustdb.c:458
+#: g10/trustdb.c:448
 #, c-format
 msgid "key %08lX: query record failed\n"
 msgstr "clé %08lX: l'enregistrement de requête a échoué\n"
 
-#: g10/trustdb.c:467
-#, fuzzy, c-format
+#: g10/trustdb.c:457
+#, c-format
 msgid "key %08lX: already in secret key table\n"
-msgstr "clé %08lX: déjà dans le porte-clés secret\n"
+msgstr "clé %08lX: déjà dans la table des clés secrètes\n"
 
-#: g10/trustdb.c:470
-#, fuzzy, c-format
+#: g10/trustdb.c:460
+#, c-format
 msgid "key %08lX: accepted as secret key.\n"
-msgstr "clé %08lX: déjà dans le porte-clés secret\n"
+msgstr "clé %08lX: acceptée comme clé secrète.\n"
 
-#: g10/trustdb.c:477
+#: g10/trustdb.c:467
 #, c-format
 msgid "enum_secret_keys failed: %s\n"
 msgstr "enum_secret_keys a échoué: %s\n"
 
-#: g10/trustdb.c:1428
+#: g10/trustdb.c:1287 g10/trustdb.c:1351
+#, c-format
+msgid "%lu keys processed\n"
+msgstr "%lu clés traitées\n"
+
+#: g10/trustdb.c:1289
+#, c-format
+msgid "\t%lu keys skipped\n"
+msgstr "\t%lu clés non prises en compte\n"
+
+#: g10/trustdb.c:1291 g10/trustdb.c:1353
+#, c-format
+msgid "\t%lu keys with errors\n"
+msgstr "\t%lu clés avec erreurs\n"
+
+#: g10/trustdb.c:1293 g10/trustdb.c:1355
+#, c-format
+msgid "\t%lu keys updated\n"
+msgstr "\t%lu clés mises à jour\n"
+
+#: g10/trustdb.c:1357
+#, c-format
+msgid "\t%lu keys inserted\n"
+msgstr "\t%lu clés insérées\n"
+
+#: g10/trustdb.c:1412
 #, c-format
 msgid "key %08lX: insert trust record failed: %s\n"
 msgstr "clé %08lX: l'insertion d'enregistrement de confiance a échoué: %s\n"
 
-#: g10/trustdb.c:1432
+#: g10/trustdb.c:1416
 #, c-format
 msgid "key %08lX.%lu: inserted into trustdb\n"
 msgstr "clé %08lX.%lu: insérée dans la base de confiance\n"
 
-#: g10/trustdb.c:1440
+#: g10/trustdb.c:1424
 #, c-format
 msgid "key %08lX.%lu: created in future (time warp or clock problem)\n"
 msgstr "clé %08lX.%lu: créée dans le futur (problème d'horloge)\n"
 
-#: g10/trustdb.c:1447
+#: g10/trustdb.c:1431
 #, c-format
 msgid "key %08lX.%lu: expired at %s\n"
 msgstr "clé %08lX.%lu: a expiré le %s\n"
 
-#: g10/trustdb.c:1455
+#: g10/trustdb.c:1439
 #, c-format
 msgid "key %08lX.%lu: trust check failed: %s\n"
 msgstr "clé %08lX.%lu: la vérification de confiance a échoué: %s\n"
 
-#: g10/trustdb.c:1718
+#: g10/trustdb.c:1656
 #, c-format
 msgid "note: sig rec %lu[%d] in hintlist of %lu but marked as checked\n"
 msgstr ""
+"note: enregistrement de signature %lu[%d] dans la liste d'aide de %lu mais\n"
+"mais marqué comme vérifié\n"
 
-#: g10/trustdb.c:1722
+#: g10/trustdb.c:1660
 #, c-format
 msgid "note: sig rec %lu[%d] in hintlist of %lu but not marked\n"
 msgstr ""
+"note: enregistrement de signature %lu[%d] dans la liste d'aide de %lu mais\n"
+"non marqué\n"
 
 #. we need the dir record
-#: g10/trustdb.c:1729
+#: g10/trustdb.c:1667
 #, c-format
 msgid "sig rec %lu[%d] in hintlist of %u does not point to a dir record\n"
 msgstr ""
+"l'enregistrement de signature %lu[%d] dans la liste d'aide de %u ne pointe\n"
+"pas vers un enregistrement de répertoire\n"
 
-#: g10/trustdb.c:1735
+#: g10/trustdb.c:1673
 #, c-format
 msgid "lid %lu: no primary key\n"
-msgstr ""
+msgstr "lid %lu: pas de clé primaire\n"
 
-#: g10/trustdb.c:1764
-#, fuzzy, c-format
+#: g10/trustdb.c:1705
+#, c-format
 msgid "lid %lu: user id not found in keyblock\n"
-msgstr "%s: utilisateur non trouvé\n"
+msgstr "lid %lu: utilisateur non trouvé dans le bloc de clés\n"
 
-#: g10/trustdb.c:1771
+#: g10/trustdb.c:1709
+#, c-format
+msgid "lid %lu: user id without signature\n"
+msgstr "lid %lu: utilisateur sans signature\n"
+
+#: g10/trustdb.c:1716
 #, c-format
 msgid "lid %lu: self-signature in hintlist\n"
-msgstr ""
+msgstr "lid %lu: auto-signature dans la liste d'aide\n"
 
-#: g10/trustdb.c:1776
-#, fuzzy, c-format
-msgid "key %08lX.%lu, uid %02X%02X, sig %08lX: good signature (3)\n"
-msgstr "clé %08lXi.%lu, uid %02X%02X: %ssignature invalide: %s\n"
+#: g10/trustdb.c:1721
+#, c-format
+msgid "key %08lX.%lu, uid %02X%02X, sig %08lX: Good signature (3)\n"
+msgstr "clé %08lX.%lu, uid %02X%02X, sig %08lX: Bonne signature (3)\n"
 
-#: g10/trustdb.c:1783
-#, fuzzy, c-format
+#: g10/trustdb.c:1728
+#, c-format
 msgid "key %08lX.%lu, uid %02X%02X, sig %08lX: very strange: no public key\n"
 msgstr ""
-"clé %08lX.%lu, uid %02X%02X: pas de clé publique pour la signature %08lX\n"
+"clé %08lX.%lu, uid %02X%02X, sig %08lX: très étrange: pas de clé publique\n"
 
-#: g10/trustdb.c:1790 g10/trustdb.c:2225 g10/trustdb.c:2297
-#, fuzzy, c-format
-msgid "key %08lX.%lu, uid %02X%02X, sig %08lX: invalid signature: %s\n"
-msgstr "clé %08lXi.%lu, uid %02X%02X: %ssignature invalide: %s\n"
+#: g10/trustdb.c:1735 g10/trustdb.c:2207 g10/trustdb.c:2280
+#, c-format
+msgid "key %08lX.%lu, uid %02X%02X, sig %08lX: %s\n"
+msgstr "clé %08lX.%lu, uid %02X%02X, sig %08lX: %s\n"
 
-#: g10/trustdb.c:1835
+#: g10/trustdb.c:1779
 #, c-format
 msgid "hintlist %lu[%d] of %lu does not point to a dir record\n"
 msgstr ""
+"la liste d'aide de %lu[%d] de %lu ne pointe pas vers un enregistrement\n"
+"de répertoire\n"
 
-#: g10/trustdb.c:1841
+#: g10/trustdb.c:1785
 #, c-format
 msgid "lid %lu does not have a key\n"
-msgstr ""
+msgstr "la lid %lu n'a pas de clé\n"
 
-#: g10/trustdb.c:1851
-#, fuzzy, c-format
+#: g10/trustdb.c:1795
+#, c-format
 msgid "lid %lu: can't get keyblock: %s\n"
-msgstr "ne peut écrire le bloc de clés: %s\n"
+msgstr "lid %lu: ne peut obtenir le bloc de clés: %s\n"
 
-#: g10/trustdb.c:2096
-#, fuzzy, c-format
-msgid "key %08lX.%lu, uid %02X%02X: good self-signature\n"
-msgstr "clé %08lXi.%lu, uid %02X%02X: %ssignature invalide: %s\n"
+#: g10/trustdb.c:2085
+#, c-format
+msgid "key %08lX.%lu, uid %02X%02X: Good self-signature\n"
+msgstr "clé %08lX.%lu, uid %02X%02X: Bonne auto-signature\n"
+
+#: g10/trustdb.c:2091
+#, c-format
+msgid "key %08lX, uid %02X%02X: Invalid self-signature: %s\n"
+msgstr "clé %08lX.%lu, uid %02X%02X: Auto-signature invalide: %s\n"
 
-#: g10/trustdb.c:2188
-#, fuzzy, c-format
+#: g10/trustdb.c:2171
+#, c-format
 msgid ""
 "key %08lX.%lu, uid %02X%02X, sig %08lX: duplicated signature - deleted\n"
-msgstr "clé %08lXi.%lu, uid %02X%02X: %ssignature invalide: %s\n"
+msgstr ""
+"clé %08lX.%lu, uid %02X%02X, sig %08lX: signature dupliquée - effacée\n"
 
-#: g10/trustdb.c:2211
-#, fuzzy, c-format
-msgid "key %08lX.%lu, uid %02X%02X, sig %08lX: good signature (1)\n"
-msgstr "clé %08lXi.%lu, uid %02X%02X: %ssignature invalide: %s\n"
+#: g10/trustdb.c:2193
+#, c-format
+msgid "key %08lX.%lu, uid %02X%02X, sig %08lX: Good signature (1)\n"
+msgstr "clé %08lX.%lu, uid %02X%02X, sig %08lX: Bonne signature (1)\n"
 
-#: g10/trustdb.c:2218
-#, fuzzy, c-format
+#: g10/trustdb.c:2200
+#, c-format
 msgid "key %08lX.%lu, uid %02X%02X, sig %08lX: weird: no public key\n"
-msgstr ""
-"clé %08lX.%lu, uid %02X%02X: pas de clé publique pour la signature %08lX\n"
+msgstr "clé %08lX.%lu, uid %02X%02X, sig %08lX: bizarre: pas de clé publique\n"
 
-#: g10/trustdb.c:2240
-#, fuzzy, c-format
+#: g10/trustdb.c:2222
+#, c-format
 msgid "key %08lX.%lu, uid %02X%02X: has shadow dir %lu but not yet marked.\n"
-msgstr "clé %08lXi.%lu, uid %02X%02X: %ssignature invalide: %s\n"
+msgstr ""
+"clé %08lX.%lu, uid %02X%02X: possède une ombre %lu mais pas encore\n"
+"marquée.\n"
 
-#: g10/trustdb.c:2279
-#, fuzzy, c-format
-msgid "key %08lX.%lu, uid %02X%02X, sig %08lX: good signature (2)\n"
-msgstr "clé %08lXi.%lu, uid %02X%02X: %ssignature invalide: %s\n"
+#: g10/trustdb.c:2263
+#, c-format
+msgid "key %08lX.%lu, uid %02X%02X, sig %08lX: Good signature (2)\n"
+msgstr "clé %08lX.%lu, uid %02X%02X, sig %08lX: Bonne signature (2)\n"
 
-#: g10/trustdb.c:2290
-#, fuzzy, c-format
+#: g10/trustdb.c:2272
+#, c-format
 msgid "key %08lX.%lu, uid %02X%02X, sig %08lX: no public key\n"
-msgstr ""
-"clé %08lX.%lu, uid %02X%02X: pas de clé publique pour la signature %08lX\n"
+msgstr "clé %08lX.%lu, uid %02X%02X, sig %08lX: pas de clé publique\n"
 
 #. key binding
-#: g10/trustdb.c:2386
-#, fuzzy, c-format
+#: g10/trustdb.c:2364
+#, c-format
 msgid "key %08lX: bogus key binding by %08lX\n"
-msgstr "clé %08lX: pas de nom d'utilisateur\n"
+msgstr "clé %08lX: mauvaise association avec %08lX\n"
 
 #. key revocation
-#: g10/trustdb.c:2390
-#, fuzzy, c-format
+#: g10/trustdb.c:2368
+#, c-format
 msgid "key %08lX: bogus key revocation by %08lX\n"
-msgstr "clé %08lX: clé publique pas trouvée: %s\n"
+msgstr "clé %08lX: mauvaise révocation de clé par %08lX\n"
 
 #. subkey revocation
-#: g10/trustdb.c:2394
-#, fuzzy, c-format
+#: g10/trustdb.c:2372
+#, c-format
 msgid "key %08lX: bogus subkey revocation by %08lX\n"
-msgstr "clé %08lX: clé publique pas trouvée: %s\n"
+msgstr "clé %08lX: mauvaise révocation de sous-clé par %08lX\n"
 
 #: g10/status.c:246
 msgid "No help available"
@@ -2275,6 +2378,25 @@ msgstr ""
 msgid "Overwrite (y/N)? "
 msgstr "Réécrire (o/N)? "
 
+#: g10/openfile.c:85
+msgid "writing to stdout\n"
+msgstr "écriture vers la sortie standard\n"
+
+#: g10/openfile.c:101 g10/openfile.c:165
+#, c-format
+msgid "%s: can't create: %s\n"
+msgstr "%s: ne peut créer: %s\n"
+
+#: g10/openfile.c:134
+#, c-format
+msgid "assuming signed data in '%s'\n"
+msgstr "les données signées sont supposées être dans '%s'\n"
+
+#: g10/openfile.c:181
+#, c-format
+msgid "%s: new options file created\n"
+msgstr "%s: nouveau fichier d'options créé\n"
+
 #: g10/encr-data.c:74
 msgid ""
 "Warning: Message was encrypted with a weak key in the symmetric cipher.\n"
@@ -2284,7 +2406,7 @@ msgstr ""
 
 #: g10/seskey.c:52
 msgid "weak key created - retrying\n"
-msgstr "mauvais clé générée - nouvel essai\n"
+msgstr "mauvaise clé générée - nouvel essai\n"
 
 #: g10/seskey.c:57
 #, c-format
@@ -2292,6 +2414,3 @@ msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n"
 msgstr ""
 "ne peut éviter une mauvaise clé pour le chiffrement symétrique: \n"
 "%d essais ont eu lieu!\n"
-
-#~ msgid "key %08lX: already in ultikey_table\n"
-#~ msgstr "clé %08lX: déja dans ultikey_table\n"
index c58f9f7..af18ddc 100644 (file)
@@ -1,3 +1,17 @@
+Tue Nov  3 16:17:56 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * strgutil.c (native_to_utf8): New.
+       (utf8_to_native): New, but only as a stub.
+
+       * argparse.c (optfile_parse): Trimmed spaces from args.
+
+
+Wed Oct 28 08:01:49 1998  me,,,  (wk@tobold)
+
+       * argparse.c (find_long_option): New.
+       (arg_parse): option=value is now allowed. Add a new internal
+       option "--dump-options".
+
 Thu Oct 22 16:25:49 1998  Michael Roth (mroth@nessie.de)
 
        * fileutil.c (make_basename): New.
index 766d461..a75ef34 100644 (file)
@@ -1,13 +1,13 @@
 /* [argparse.c wk 17.06.97] Argument Parser for option handling
  *     Copyright (C) 1998 Free Software Foundation, Inc.
- *  This file is part of WkLib.
+ *  This file is part of GnuPG.
  *
- *  WkLib is free software; you can redistribute it and/or modify
+ *  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.
  *
- *  WkLib is distributed in the hope that it will be useful,
+ *  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.
@@ -73,8 +73,8 @@
  *     Bit 4 : Do not skip the first arg.
  *     Bit 5 : allow usage of long option with only one dash
  *     Bit 6 : ignore --version
- *     all other bits must be set to zero, this value is modified by the function
- *     so assume this is write only.
+ *     all other bits must be set to zero, this value is modified by the
+ *     function, so assume this is write only.
  *  Local flags (for each option):
  *     Bit 2-0 : 0 = does not take an argument
  *              1 = takes int argument
@@ -83,8 +83,8 @@
  *              4 = takes ulong argument
  *     Bit 3 : argument is optional (r_type will the be set to 0)
  *     Bit 4 : allow 0x etc. prefixed values.
- *     Bit 7 : this is an command and not an option
- *  If can stop the option processing by setting opts to NULL, the function will
+ *     Bit 7 : this is a command and not an option
+ *  You stop the option processing by setting opts to NULL, the function will
  *  then return 0.
  * @Return Value
  *   Returns the args.r_opt or 0 if ready
@@ -167,8 +167,14 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno )
        else {
            if( arg->r_opt == -3 )
                s = "Missing argument for option \"%.50s\"\n";
+           else if( arg->r_opt == -6 )
+               s = "Option \"%.50s\" does not expect an argument\n";
            else if( arg->r_opt == -7 )
                s = "Invalid command \"%.50s\"\n";
+           else if( arg->r_opt == -8 )
+               s = "Option \"%.50s\" is ambiguous\n";
+           else if( arg->r_opt == -9 )
+               s = "Command \"%.50s\" is ambiguous\n";
            else
                s = "Invalid option \"%.50s\"\n";
            log_error(s, arg->internal.last? arg->internal.last:"[??]" );
@@ -186,10 +192,15 @@ initialize( ARGPARSE_ARGS *arg, const char *filename, unsigned *lineno )
  * Lines starting with '#' are comment lines.
  * Syntax is simply a keyword and the argument.
  * Valid keywords are all keywords from the long_opt list without
- * the leading dashes. The special keywords help, warranty and version
+ * the leading dashes. The special keywords "help", "warranty" and "version"
  * are not valid here.
  * Caller must free returned strings.
  * If called with FP set to NULL command line args are parse instead.
+ *
+ * Q: Should we allow the syntax
+ *     keyword = value
+ *    and accept for boolean options a value of 1/0, yes/no or true/false?
+ * Note: Abbreviation of options is here not allowed.
  */
 int
 optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
@@ -229,7 +240,7 @@ optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
                    arg->r_opt = (opts[index].flags & 256)? -7:-2;
                else if( (opts[index].flags & 8) ) /* no argument */
                    arg->r_opt = -3;           /* error */
-               else                           /* no or optiona argument */
+               else                           /* no or optional argument */
                    arg->r_type = 0;           /* okay */
                break;
            }
@@ -253,6 +264,7 @@ optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
                    else
                        buffer[i] = 0;
 
+                   trim_spaces( buffer );
                    if( !set_opt_arg(arg, opts[index].flags, buffer) )
                        m_free(buffer);
                }
@@ -331,6 +343,37 @@ optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
 
 
 
+static int
+find_long_option( ARGPARSE_OPTS *opts, const char *keyword )
+{
+    int i;
+    size_t n;
+
+    /* Would be better if we can do a binary search, but it is not
+       possible to reorder our option table because we would mess
+       up our help strings - What we can do is: Build a nice option
+       lookup table wehn this function is first invoked */
+    if( !*keyword )
+       return -1;
+    for(i=0; opts[i].short_opt; i++ )
+       if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) )
+           return i;
+    /* not found, see whether it is an abbreviation */
+    n = strlen( keyword );
+    for(i=0; opts[i].short_opt; i++ ) {
+       if( opts[i].long_opt && !strncmp( opts[i].long_opt, keyword, n ) ) {
+           int j;
+           for(j=i+1; opts[j].short_opt; j++ ) {
+               if( opts[j].long_opt
+                   && !strncmp( opts[j].long_opt, keyword, n ) )
+                   return -2;  /* abbreviation is ambiguous */
+           }
+           return i;
+       }
+    }
+    return -1;
+}
+
 int
 arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
 {
@@ -369,6 +412,8 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
        goto leave;
     }
     else if( *s == '-' && s[1] == '-' ) { /* long option */
+       char *argpos;
+
        arg->internal.inarg = 0;
        if( !s[2] && !(arg->flags & (1<<3)) ) { /* stop option processing */
            arg->internal.stopped = 1;
@@ -376,37 +421,57 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
            goto next_one;
        }
 
-       for(i=0; opts[i].short_opt; i++ )
-           if( opts[i].long_opt && !strcmp( opts[i].long_opt, s+2) )
-               break;
+       argpos = strchr( s+2, '=' );
+       if( argpos )
+           *argpos = 0;
+       i = find_long_option( opts, s+2 );
+       if( argpos )
+           *argpos = '=';
 
-       if( !opts[i].short_opt && !strcmp( "help", s+2) )
+       if( i < 0 && !strcmp( "help", s+2) )
            show_help(opts, arg->flags);
-       else if( !opts[i].short_opt && !strcmp( "version", s+2) ) {
+       else if( i < 0 && !strcmp( "version", s+2) ) {
            if( !(arg->flags & (1<<6)) ) {
                show_version();
                exit(0);
            }
        }
-       else if( !opts[i].short_opt && !strcmp( "warranty", s+2) ) {
+       else if( i < 0 && !strcmp( "warranty", s+2) ) {
            puts( strusage(16) );
            exit(0);
        }
+       else if( i < 0 && !strcmp( "dump-options", s+2) ) {
+           for(i=0; opts[i].short_opt; i++ )
+               if( opts[i].long_opt )
+                   printf( "--%s\n", opts[i].long_opt );
+           exit(0);
+       }
 
-       arg->r_opt = opts[i].short_opt;
-       if( !opts[i].short_opt ) {
+       if( i == -2 ) /* ambiguous option */
+           arg->r_opt = (opts[i].flags & 256)? -9:-8;
+       else if( i == -1 ) {
            arg->r_opt = (opts[i].flags & 256)? -7:-2;
            arg->r.ret_str = s+2;
        }
+       else
+           arg->r_opt = opts[i].short_opt;
+       if( i < 0 )
+           ;
        else if( (opts[i].flags & 7) ) {
-           s2 = argv[1];
+           if( argpos ) {
+               s2 = argpos+1;
+               if( !*s2 )
+                   s2 = NULL;
+           }
+           else
+               s2 = argv[1];
            if( !s2 && (opts[i].flags & 8) ) { /* no argument but it is okay*/
                arg->r_type = 0;               /* because it is optional */
            }
            else if( !s2 ) {
                arg->r_opt = -3; /* missing argument */
            }
-           else if( *s2 == '-' && (opts[i].flags & 8) ) {
+           else if( !argpos && *s2 == '-' && (opts[i].flags & 8) ) {
                /* the argument is optional and the next seems to be
                 * an option. We do not check this possible option
                 * but assume no argument */
@@ -414,11 +479,16 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts)
            }
            else {
                set_opt_arg(arg, opts[i].flags, s2);
-               argc--; argv++; index++; /* skip one */
+               if( !argpos ) {
+                   argc--; argv++; index++; /* skip one */
+               }
            }
        }
        else { /* does not take an argument */
-           arg->r_type = 0;
+           if( argpos )
+               arg->r_type = -6; /* argument not expected */
+           else
+               arg->r_type = 0;
        }
        argc--; argv++; index++; /* set to next one */
     }
index 809b0c3..217b640 100644 (file)
@@ -179,6 +179,52 @@ string_count_chr( const char *string, int c )
     return count;
 }
 
+
+/****************
+ * Convert string, which is in native encoding to UTF8 and return the
+ * new allocated UTF8 string.
+ * This code assumes that native is iso-8859-1.
+ */
+char *
+native_to_utf8( const char *string )
+{
+    const byte *s;
+    char *buffer;
+    byte *p;
+    size_t length=0;
+
+    for(s=string; *s; s++ ) {
+       length++;
+       if( *s & 0x80 )
+           length++;
+    }
+    buffer = m_alloc( length + 1 );
+    for(p=buffer, s=string; *s; s++ ) {
+       if( *s & 0x80 ) {
+           *p++ = 0xc0 | ((*s >> 6) & 3);
+           *p++ = 0x80 | ( *s & 0x3f );
+       }
+       else
+           *p++ = *s;
+    }
+    *p = 0;
+    return buffer;
+}
+
+
+/****************
+ * Convert string, which is in UTF8 to native encoding.  Replace
+ * illegal encodings by some "\xnn".
+ * This code assumes that native is iso-8859-1.
+ */
+char *
+utf8_to_native( const char *string )
+{
+    /* FIXME: Not yet done */
+    return m_strdup(string);
+}
+
+
 /*********************************************
  ********** missing string functions *********
  *********************************************/