See ChangeLog: Thu Jul 1 12:47:31 CEST 1999 Werner Koch
authorWerner Koch <wk@gnupg.org>
Thu, 1 Jul 1999 10:53:35 +0000 (10:53 +0000)
committerWerner Koch <wk@gnupg.org>
Thu, 1 Jul 1999 10:53:35 +0000 (10:53 +0000)
31 files changed:
NEWS
TODO
cipher/ChangeLog
cipher/dsa.c
cipher/elgamal.c
cipher/primegen.c
doc/DETAILS
doc/gpg.sgml
g10/ChangeLog
g10/encode.c
g10/g10.c
g10/helptext.c
g10/import.c
g10/keydb.h
g10/keyedit.c
g10/keygen.c
g10/main.h
g10/mainproc.c
g10/openfile.c
g10/passphrase.c
g10/pkclist.c
g10/plaintext.c
g10/seckey-cert.c
g10/sig-check.c
g10/tdbdump.c
g10/trustdb.c
g10/trustdb.h
include/util.h
util/ChangeLog
util/miscutil.c
util/strgutil.c

diff --git a/NEWS b/NEWS
index 8e05065..185104f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,9 @@
 
-    *
+    * New options --[no-]utf8-strings.
 
+    * New edit-menu commands "enable" and "disable" for entire keys.
+
+    * You will be asked for a filename if gpg cannot deduce one.
 
 Noteworthy changes in version 0.9.8
 -----------------------------------
diff --git a/TODO b/TODO
index 4920344..34b009b 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,6 +1,4 @@
 
-  * add keylength and type to status output.
-
   * add some status output put for signing and encryption.
     replace the putc in primegen with some kind of status-fd outputs.
 
@@ -21,7 +19,7 @@
   * find a way to allow the import of non-self-signed keys.  This is needed
     for the IN ENCR/SIGN hack.
 
-  * convert the given user ID to UTF-8 and add an option to suppress this.
+  * Not all user names are correctly converted to UTF8.
 
 
 Nice to have
@@ -52,4 +50,3 @@ Nice to have
     verification status of the message to the output (i.e. write something to
     the --output file and not only to stderr.
 
-
index 30d2ddd..77a3e4b 100644 (file)
@@ -1,3 +1,9 @@
+Thu Jul  1 12:47:31 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+
+       * primegen.c, elgamal.c, dsa.c (progess): New and replaced all
+       fputc with a call to this function.
+
 Sat Jun 26 12:15:59 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
 
 
index 1485463..cbd90ac 100644 (file)
@@ -52,6 +52,13 @@ static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors );
 static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey);
 static int  verify(MPI r, MPI s, MPI input, DSA_public_key *pkey);
 
+static void
+progress( int c )
+{
+    fputc( c, stderr );
+}
+
+
 /****************
  * Generate a random secret exponent k less than q
  */
@@ -65,7 +72,7 @@ gen_k( MPI q )
        log_debug("choosing a random k ");
     for(;;) {
        if( DBG_CIPHER )
-           fputc('.', stderr);
+           progress('.');
        {   char *p = get_random_bits( nbits, 1, 1 );
            mpi_set_buffer( k, p, (nbits+7)/8, 0 );
            m_free(p);
@@ -84,7 +91,7 @@ gen_k( MPI q )
        break;  /* okay */
     }
     if( DBG_CIPHER )
-       fputc('\n', stderr);
+       progress('\n');
 
     return k;
 }
@@ -170,7 +177,7 @@ generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
     rndbuf = NULL;
     do {
        if( DBG_CIPHER )
-           fputc('.', stderr);
+           progress('.');
        if( !rndbuf )
            rndbuf = get_random_bits( qbits, 2, 1 );
        else { /* change only some of the higher bits (= 2 bytes)*/
@@ -190,7 +197,7 @@ generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
     mpi_powm( y, g, x, p );
 
     if( DBG_CIPHER ) {
-       fputc('\n', stderr);
+       progress('\n');
        log_mpidump("dsa  p= ", p );
        log_mpidump("dsa  q= ", q );
        log_mpidump("dsa  g= ", g );
index 9d9058f..0e6b992 100644 (file)
@@ -57,6 +57,13 @@ static int  verify(MPI a, MPI b, MPI input, ELG_public_key *pkey);
 
 
 static void
+progress( int c )
+{
+    fputc( c, stderr );
+}
+
+
+static void
 test_keys( ELG_secret_key *sk, unsigned nbits )
 {
     ELG_public_key pk;
@@ -108,7 +115,7 @@ gen_k( MPI p )
     mpi_sub_ui( p_1, p, 1);
     for(;;) {
        if( DBG_CIPHER )
-           fputc('.', stderr);
+           progress('.');
        {   char *pp = get_random_bits( nbits, 1, 1 );
            mpi_set_buffer( k, pp, (nbits+7)/8, 0 );
            m_free(pp);
@@ -128,7 +135,7 @@ gen_k( MPI p )
            break;  /* okay, k is relatively prime to (p-1) */
     }
     if( DBG_CIPHER )
-       fputc('\n', stderr);
+       progress('\n');
     mpi_free(p_1);
     mpi_free(temp);
 
@@ -179,7 +186,7 @@ generate(  ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
     rndbuf = NULL;
     do {
        if( DBG_CIPHER )
-           fputc('.', stderr);
+           progress('.');
        if( rndbuf ) { /* change only some of the higher bits */
            if( nbits < 16 ) {/* should never happen ... */
                m_free(rndbuf);
@@ -202,7 +209,7 @@ generate(  ELG_secret_key *sk, unsigned nbits, MPI **ret_factors )
     mpi_powm( y, g, x, p );
 
     if( DBG_CIPHER ) {
-       fputc('\n', stderr);
+       progress('\n');
        log_mpidump("elg  p= ", p );
        log_mpidump("elg  g= ", g );
        log_mpidump("elg  y= ", y );
index 9019e28..9bf1085 100644 (file)
@@ -39,6 +39,13 @@ static int is_prime( MPI n, int steps, int *count );
 static void m_out_of_n( char *array, int m, int n );
 
 
+static void
+progress( int c )
+{
+    fputc( c, stderr );
+}
+
+
 /****************
  * Generate a prime number (stored in secure memory)
  */
@@ -48,7 +55,7 @@ generate_secret_prime( unsigned  nbits )
     MPI prime;
 
     prime = gen_prime( nbits, 1, 2 );
-    fputc('\n', stderr);
+    progress('\n');
     return prime;
 }
 
@@ -58,7 +65,7 @@ generate_public_prime( unsigned  nbits )
     MPI prime;
 
     prime = gen_prime( nbits, 0, 2 );
-    fputc('\n', stderr);
+    progress('\n');
     return prime;
 }
 
@@ -152,7 +159,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
                }
            if( i == n ) {
                m_free(perms); perms = NULL;
-               fputc('!', stderr);
+               progress('!');
                goto next_try;  /* allocate new primes */
            }
        }
@@ -169,7 +176,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
            if( ++count1 > 20 ) {
                count1 = 0;
                qbits++;
-               fputc('>', stderr);
+               progress('>');
                q = gen_prime( qbits, 0, 1 );
                goto next_try;
            }
@@ -180,7 +187,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
            if( ++count2 > 20 ) {
                count2 = 0;
                qbits--;
-               fputc('<', stderr);
+               progress('<');
                q = gen_prime( qbits, 0, 1 );
                goto next_try;
            }
@@ -190,7 +197,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
     } while( !(nprime == pbits && check_prime( prime, val_2 )) );
 
     if( DBG_CIPHER ) {
-       putc('\n', stderr);
+       progress('\n');
        log_mpidump( "prime    : ", prime );
        log_mpidump( "factor  q: ", q );
        if( mode == 1 )
@@ -202,7 +209,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
            fprintf(stderr, ", q0=%u", mpi_get_nbits(q_factor) );
        for(i=0; i < n; i++ )
            fprintf(stderr, ", p%d=%u", i, mpi_get_nbits(factors[i]) );
-       putc('\n', stderr);
+       progress('\n');
     }
 
     if( ret_factors ) { /* caller wants the factors */
@@ -237,7 +244,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
                mpi_print( stderr, g, 1 );
            }
            else
-               fputc('^', stderr);
+               progress('^');
            for(i=0; i < n+2; i++ ) {
                /*fputc('~', stderr);*/
                mpi_fdiv_q(tmp, pmin1, factors[i] );
@@ -247,7 +254,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
                    break;
            }
            if( DBG_CIPHER )
-               fputc('\n', stderr);
+               progress('\n');
        } while( i < n+2 );
        mpi_free(factors[n+1]);
        mpi_free(tmp);
@@ -255,7 +262,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
        mpi_free(pmin1);
     }
     if( !DBG_CIPHER )
-       putc('\n', stderr);
+       progress('\n');
 
     m_free( factors ); /* (factors are shallow copies) */
     for(i=0; i < m; i++ )
@@ -335,7 +342,7 @@ gen_prime( unsigned  nbits, int secret, int randomlevel )
                /* perform stronger tests */
                if( is_prime(ptest, 5, &count2 ) ) {
                    if( !mpi_test_bit( ptest, nbits-1 ) ) {
-                       fputc('\n', stderr);
+                       progress('\n');
                        log_debug("overflow in prime generation\n");
                        break; /* step loop, continue with a new prime */
                    }
@@ -350,11 +357,11 @@ gen_prime( unsigned  nbits, int secret, int randomlevel )
                }
            }
            if( ++dotcount == 10 ) {
-               fputc('.', stderr);
+               progress('.');
                dotcount = 0;
            }
        }
-       fputc(':', stderr); /* restart with a new random value */
+       progress(':'); /* restart with a new random value */
     }
 }
 
@@ -383,7 +390,7 @@ check_prime( MPI prime, MPI val_2 )
        mpi_free( pminus1 );
        if( mpi_cmp_ui( result, 1 ) ) { /* if composite */
            mpi_free( result );
-           fputc('.', stderr);
+           progress('.');
            return 0;
        }
        mpi_free( result );
@@ -392,7 +399,7 @@ check_prime( MPI prime, MPI val_2 )
     /* perform stronger tests */
     if( is_prime(prime, 5, &count ) )
        return 1; /* is probably a prime */
-    fputc('.', stderr);
+    progress('.');
     return 0;
 }
 
@@ -452,7 +459,7 @@ is_prime( MPI n, int steps, int *count )
            if( mpi_cmp( y, nminus1 ) )
                goto leave; /* not a prime */
        }
-       fputc('+', stderr);
+       progress('+');
     }
     rc = 1; /* may be a prime */
 
index 84b4283..6ff7cb6 100644 (file)
@@ -85,8 +85,11 @@ more arguments in future versions.
        unique ids - others may yield duplicated ones when they
        have been created in the same second.
 
-    ENC_TO  <long keyid>
+    ENC_TO  <long keyid>  <keytype>  <keylength>
        The message is encrypted to this keyid.
+       keytype is the numerical value of the public key algorithm,
+       kenlength is the length of the key or 0 if it is not known
+       (which is currently always the case).
 
     NODATA  <what>
        No data has been found. Codes for what are:
@@ -122,8 +125,11 @@ more arguments in future versions.
     SHM_GET_BOOL
     SHM_GET_HIDDEN
 
-    NEED_PASSPHRASE <long keyid>
+    NEED_PASSPHRASE <long keyid>  <keytype>  <keylength>
        Issued whenever a passphrase is needed.
+       keytype is the numerical value of the public key algorithm
+       or 0 if this is not applicable, keylength is the length
+       of the key or 0 if it is not known (this is currently always the case).
 
     NEED_PASSPHRASE_SYM <cipher_algo> <s2k_mode> <s2k_hash>
        Issued whenever a passphrase for symmetric encryption is needed.
index 82e069b..21d74fc 100644 (file)
@@ -269,6 +269,12 @@ certificate should be generated.</para></listitem></varlistentry>
 Change the owner trust value. This updates the
 trust-db immediately and no save is required.</para></listitem></varlistentry>
     <varlistentry>
+    <term>disable</term>
+    <term>enable</term>
+    <listitem><para>
+Disable or enable an entire key. A disabled key can normally not be used
+for encryption.</para></listitem></varlistentry>
+    <varlistentry>
     <term>adduid</term>
     <listitem><para>
 Create an alternate user id.</para></listitem></varlistentry>
@@ -537,7 +543,8 @@ in the options file and may be used together with
 an own user-id as an "encrypt-to-self".  These keys
 are only used when there are other recipients given
 either by use of --recipient or by the asked user id.
-No trust checking is performed for these user ids.
+No trust checking is performed for these user ids and
+even disabled keys can be used.
 </para></listitem></varlistentry>
 
 
@@ -699,6 +706,18 @@ Valid values for &ParmName; are:</para>
 
 
 <varlistentry>
+<term>--utf8-strings</term>
+<term>--no-utf8-strings</term>
+<listitem><para>
+Assume that the arguments are already given as UTF8 strings.  The default
+(--no-utf8-strings)
+is to assume that arguments are encoded in the character set as specified
+by --charset. These options effects all following arguments.  Both options may
+used multiple times.
+</para></listitem></varlistentry>
+
+
+<varlistentry>
 <term>--options &ParmFile;</term>
 <listitem><para>
 Read options from &ParmFile; and do not try to read
index 9db45bb..ca68a14 100644 (file)
@@ -1,3 +1,28 @@
+Thu Jul  1 12:47:31 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+
+       * keyedit.c (show_key_with_all_names): Print a notice for disabled keys.
+       (enable_disable_keys): Add functionality
+       * pkclist.c (edit_ownertrust): preserve disabled state.
+       (build_pk_list): Skip disabled keys.
+       * trustdb.c (upd_one_ownertrust): Ditto.
+       (build_cert_tree): Mask the ownertrust.
+       (trust_letter): Mask the value.
+       (do_check): Take disabled flag into account.
+
+       * passphrase.c (passphrase_to_dek): Add a pubkey_alfo arg and changed
+       all callers.
+
+       * g10.c (utf8_strings): 2 new options.
+
+       * trustdb.c (insert_trust_record_by_pk): New, replaces the next one.
+       (insert_trust_record): Now takes a keyblock as arg.  Changed all
+       callers to use the appropritae function.
+
+       * openfile.c (ask_outfile_name): New.
+       * plaintext.c (handle_plaintext): Ask for filename if there is
+       no valid syntax. Don't use fname varbatim but filter it.
+
 Tue Jun 29 21:44:25 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
 
 
index 7daec6c..147607b 100644 (file)
@@ -102,7 +102,7 @@ encode_simple( const char *filename, int mode )
        s2k->mode = opt.rfc1991? 0:opt.s2k_mode;
        s2k->hash_algo = opt.def_digest_algo ? opt.def_digest_algo
                                             : opt.s2k_digest_algo;
-       cfx.dek = passphrase_to_dek( NULL,
+       cfx.dek = passphrase_to_dek( NULL, 0,
                       opt.def_cipher_algo ? opt.def_cipher_algo
                                           : opt.s2k_cipher_algo , s2k, 2 );
        if( !cfx.dek || !cfx.dek->keylen ) {
index 94aa280..66a91bf 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -166,6 +166,8 @@ enum cmd_and_opt_values { aNull = 0,
     oEncryptTo,
     oNoEncryptTo,
     oLoggerFD,
+    oUtf8Strings,
+    oNoUtf8Strings,
 aTest };
 
 
@@ -315,13 +317,15 @@ static ARGPARSE_OPTS opts[] = {
     { oLockMultiple, "lock-multiple", 0, "@" },
     { oLoggerFD, "logger-fd",1, "@" },
     { oUseEmbeddedFilename, "use-embedded-filename", 0, "@" },
+    { oUtf8Strings, "utf8-strings", 0, "@" },
+    { oNoUtf8Strings, "no-utf8-strings", 0, "@" },
 {0} };
 
 
 
 int g10_errors_seen = 0;
 
-
+static int utf8_strings = 0;
 static int maybe_setuid = 1;
 
 static char *build_list( const char *text,
@@ -761,16 +765,16 @@ main( int argc, char **argv )
 
          case oNoEncryptTo: opt.no_encrypt_to = 1; break;
          case oEncryptTo: /* store the recipient in the second list */
-           sl = add_to_strlist( &remusr, pargs.r.ret_str );
+           sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
            sl->flags = 1;
            break;
          case oRecipient: /* store the recipient */
-           add_to_strlist( &remusr, pargs.r.ret_str );
+           add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
            break;
          case oTextmodeShort: opt.textmode = 2; break;
          case oTextmode: opt.textmode=1;  break;
          case oUser: /* store the local users */
-           add_to_strlist( &locusr, pargs.r.ret_str );
+           add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
            break;
          case oCompress: opt.compress = pargs.r.ret_int; break;
          case oPasswdFD: pwfd = pargs.r.ret_int; break;
@@ -788,6 +792,8 @@ main( int argc, char **argv )
          case oLockMultiple: opt.lock_once = 0; break;
          case oKeyServer: opt.keyserver_name = pargs.r.ret_str; break;
          case oNotation: add_notation_data( pargs.r.ret_str ); break;
+         case oUtf8Strings: utf8_strings = 1; break;
+         case oNoUtf8Strings: utf8_strings = 0; break;
 
          default : pargs.err = configfp? 1:2; break;
        }
@@ -1025,7 +1031,7 @@ main( int argc, char **argv )
        if( argc > 1 ) {
            sl = NULL;
            for( argc--, argv++ ; argc; argc--, argv++ )
-               append_to_strlist( &sl, *argv );
+               append_to_strlist2( &sl, *argv, utf8_strings );
            keyedit_menu( fname, locusr, sl );
            free_strlist(sl);
        }
@@ -1040,6 +1046,7 @@ main( int argc, char **argv )
        if( argc != 1 )
            wrong_args(_("--delete-key username"));
        /* note: fname is the user id! */
+       /* fixme: do utf8 conversion */
        if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) )
            log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
        break;
@@ -1482,11 +1489,8 @@ add_notation_data( const char *string )
            highbit = 1;
     }
 
-    if( highbit ) {  /* must use UTF8 encoding */
-       char *p = native_to_utf8( string );
-       sl = add_to_strlist( &opt.notation_data, p );
-       m_free( p );
-    }
+    if( highbit )   /* must use UTF8 encoding */
+       sl = add_to_strlist2( &opt.notation_data, string, utf8_strings );
     else
        sl = add_to_strlist( &opt.notation_data, string );
 
index 521df53..5fb8007 100644 (file)
@@ -208,10 +208,17 @@ static struct helptexts { const char *key; const char *help; } helptexts[] = {
  "Give the name fo the file to which the signature applies"
 },
 
+/* openfile.c (overwrite_filep) */
 { N_("openfile.overwrite.okay"),
  "Answer \"yes\" if it is okay to overwrite the file"
 },
 
+/* openfile.c (ask_outfile_name) */
+{ N_("openfile.askoutname"),
+ "Please enter a new filename. If you just hit RETURN the default\n"
+ "file (which is shown in brackets) will be used."
+},
+
 /* end of list */
 { NULL, NULL } };
 
index 060990e..a81c7ed 100644 (file)
@@ -376,10 +376,10 @@ import_one( const char *fname, KBNODE keyblock, int fast )
            log_info( _("writing to `%s'\n"),
                                keyblock_resource_name(&kbpos) );
        if( (rc=lock_keyblock( &kbpos )) )
-           log_error(_("can't lock keyring `%s': %s\n"),
+          log_error(_("can't lock keyring `%s': %s\n"),
                       keyblock_resource_name(&kbpos), g10_errstr(rc) );
        else if( (rc=insert_keyblock( &kbpos, keyblock )) )
-           log_error( _("error writing keyring `%s': %s\n"),
+          log_error( _("error writing keyring `%s': %s\n"),
                       keyblock_resource_name(&kbpos), g10_errstr(rc) );
        unlock_keyblock( &kbpos );
        /* we are ready */
@@ -402,9 +402,6 @@ import_one( const char *fname, KBNODE keyblock, int fast )
            goto leave;
        }
 
-       /* See whether we have only non-self-signature on one user id; if not
-        * ask the user what to do. <--- fixme */
-
        /* now read the original keyblock */
        rc = find_keyblock_bypk( &kbpos, pk_orig );
        if( rc ) {
@@ -432,7 +429,7 @@ import_one( const char *fname, KBNODE keyblock, int fast )
            mod_key = 1;
            /* keyblock_orig has been updated; write */
            if( (rc=lock_keyblock( &kbpos )) )
-               log_error( _("can't lock keyring `%s': %s\n"),
+              log_error( _("can't lock keyring `%s': %s\n"),
                          keyblock_resource_name(&kbpos), g10_errstr(rc) );
            else if( (rc=update_keyblock( &kbpos, keyblock_orig )) )
                log_error( _("error writing keyring `%s': %s\n"),
@@ -475,7 +472,7 @@ import_one( const char *fname, KBNODE keyblock, int fast )
        if( rc && rc != -1 )
            log_error("trustdb error: %s\n", g10_errstr(rc) );
        else if( rc == -1 ) { /* not found trustdb */
-           rc = insert_trust_record( new_key? pk : pk_orig );
+           rc = insert_trust_record( new_key? keyblock : keyblock_orig );
            if( rc )
                log_error("key %08lX: trustdb insert failed: %s\n",
                                        (ulong)keyid[1], g10_errstr(rc) );
index 2369675..20a8a63 100644 (file)
@@ -125,7 +125,8 @@ int  build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list,
 /*-- passphrase.h --*/
 int  have_static_passphrase(void);
 void read_passphrase_from_fd( int fd );
-DEK *passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode);
+DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo,
+                       int cipher_algo, STRING2KEY *s2k, int mode);
 void set_next_passphrase( const char *s );
 char *get_last_passphrase(void);
 
index df14f13..e936340 100644 (file)
@@ -451,7 +451,7 @@ change_passphrase( KBNODE keyblock )
        for(;;) {
            s2k->mode = opt.s2k_mode;
            s2k->hash_algo = opt.s2k_digest_algo;
-           dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 );
+           dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2 );
            if( !dek ) {
                tty_printf(_("passphrase not correctly repeated; try again.\n"));
            }
@@ -1033,6 +1033,12 @@ show_key_with_all_names( KBNODE keyblock, int only_marked,
                          expirestr_from_pk(pk) );
            if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
                tty_printf(" trust: %c/%c", otrust, trust );
+               if( node->pkt->pkttype == PKT_PUBLIC_KEY
+                   && (get_ownertrust( pk->local_id )&TRUST_FLAG_DISABLED)) {
+                   tty_printf("\n*** ");
+                   tty_printf(_("This key has been disabled"));
+               }
+
                if( with_fpr  ) {
                    tty_printf("\n");
                    show_fingerprint( pk );
@@ -1872,12 +1878,20 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
 static int
 enable_disable_key( KBNODE keyblock, int disable )
 {
-    int entire;
-    int changed = 0;
-
-
-    entire = !count_selected_keys( keyblock );
-
-    return changed;
+    ulong lid = find_kbnode( keyblock, PKT_PUBLIC_KEY )
+                           ->pkt->pkt.public_key->local_id;
+    unsigned int trust, newtrust;
+
+    /* Note: Because the keys have beed displayed, we have
+     * ensured that local_id has been set */
+    trust = newtrust = get_ownertrust( lid );
+    newtrust &= ~TRUST_FLAG_DISABLED;
+    if( disable )
+       newtrust |= TRUST_FLAG_DISABLED;
+    if( trust == newtrust )
+       return 0; /* already in that state */
+    if( !update_ownertrust( lid, newtrust ) )
+       return 1;
+    return 0;
 }
 
index 1621d94..74840e8 100644 (file)
@@ -743,7 +743,7 @@ ask_passphrase( STRING2KEY **ret_s2k )
     for(;;) {
        s2k->mode = opt.s2k_mode;
        s2k->hash_algo = opt.s2k_digest_algo;
-       dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 );
+       dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2 );
        if( !dek ) {
            tty_printf(_("passphrase not correctly repeated; try again.\n"));
        }
@@ -1045,7 +1045,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
        s2k->mode = opt.s2k_mode;
        s2k->hash_algo = opt.s2k_digest_algo;
        set_next_passphrase( passphrase );
-       dek = passphrase_to_dek( NULL, opt.s2k_cipher_algo, s2k, 2 );
+       dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2 );
     }
 
     rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,
index 5889ccf..f2c059b 100644 (file)
@@ -97,6 +97,7 @@ int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
 /*-- openfile.c --*/
 int overwrite_filep( const char *fname );
 char *make_outfile_name( const char *iname );
+char *ask_outfile_name( const char *name, size_t namelen );
 int   open_outfile( const char *iname, int mode, IOBUF *a );
 IOBUF open_sigfile( const char *iname );
 void copy_options_file( const char *destdir );
index cb2388f..51d4361 100644 (file)
@@ -163,7 +163,7 @@ proc_symkey_enc( CTX c, PACKET *pkt )
        log_error( "symkey_enc packet with session keys are not supported!\n");
     else {
        c->last_was_session_key = 2;
-       c->dek = passphrase_to_dek( NULL, enc->cipher_algo, &enc->s2k, 0 );
+       c->dek = passphrase_to_dek( NULL, 0, enc->cipher_algo, &enc->s2k, 0 );
     }
     free_packet(pkt);
 }
@@ -185,7 +185,8 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
 
     if( is_status_enabled() ) {
        char buf[50];
-       sprintf(buf, "%08lX%08lX", (ulong)enc->keyid[0], (ulong)enc->keyid[1]);
+       sprintf(buf, "%08lX%08lX %d 0",
+               (ulong)enc->keyid[0], (ulong)enc->keyid[1], enc->pubkey_algo );
        write_status_text( STATUS_ENC_TO, buf );
     }
 
@@ -230,7 +231,7 @@ proc_encrypted( CTX c, PACKET *pkt )
     /*log_debug("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
     if( !c->dek && !c->last_was_session_key ) {
        /* assume this is old conventional encrypted data */
-       c->dek = passphrase_to_dek( NULL,
+       c->dek = passphrase_to_dek( NULL, 0,
                    opt.def_cipher_algo ? opt.def_cipher_algo
                                        : DEFAULT_CIPHER_ALGO, NULL, 0 );
     }
index af0ab3c..ebf9548 100644 (file)
@@ -99,6 +99,44 @@ make_outfile_name( const char *iname )
 }
 
 
+/****************
+ * Ask for a outputfilename and use the given one as default.
+ * Return NULL if no file has been given or it is not possible to
+ * ask the user.
+ */
+char *
+ask_outfile_name( const char *name, size_t namelen )
+{
+    size_t n;
+    const char *s;
+    char *prompt;
+    char *fname;
+    char *defname;
+
+    if( opt.batch )
+       return NULL;
+
+    s = _("Enter new filename");
+
+    n = strlen(s) + namelen + 10;
+    defname = name && namelen? make_printable_string( name, namelen, 0): NULL;
+    prompt = m_alloc(n);
+    if( defname )
+       sprintf(prompt, "%s [%s]: ", s, defname );
+    else
+       sprintf(prompt, "%s: ", s );
+    fname = cpr_get("openfile.askoutname", prompt );
+    cpr_kill_prompt();
+    m_free(prompt);
+    if( !*fname ) {
+       m_free( fname ); fname = NULL;
+       fname = defname; defname = NULL;
+    }
+    m_free(defname);
+    return fname;
+}
+
+
 
 /****************
  * Make an output filename for the inputfile INAME.
index 9581246..80c6fa3 100644 (file)
@@ -114,9 +114,11 @@ read_passphrase_from_fd( int fd )
  *         (only for mode 2)
  *         a dek->keylen of 0 means: no passphrase entered.
  *         (only for mode 2)
+ * pubkey_algo is only informational.
  */
 DEK *
-passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
+passphrase_to_dek( u32 *keyid, int pubkey_algo,
+                  int cipher_algo, STRING2KEY *s2k, int mode )
 {
     char *pw = NULL;
     DEK *dek;
@@ -139,8 +141,8 @@ passphrase_to_dek( u32 *keyid, int cipher_algo, STRING2KEY *s2k, int mode )
            sprintf( buf, "%08lX%08lX", (ulong)keyid[0], (ulong)keyid[1] );
            if( keyid[2] && keyid[3] && keyid[0] != keyid[2]
                                     && keyid[1] != keyid[3] )
-               sprintf( buf+strlen(buf), " %08lX%08lX",
-                                         (ulong)keyid[2], (ulong)keyid[3] );
+               sprintf( buf+strlen(buf), " %08lX%08lX %d 0",
+                          (ulong)keyid[2], (ulong)keyid[3], pubkey_algo );
            write_status_text( STATUS_NEED_PASSPHRASE, buf );
        }
        else {
index 39ed0e5..d8c25eb 100644 (file)
@@ -206,7 +206,7 @@ do_edit_ownertrust( ulong lid, int mode, unsigned *new_trust )
 int
 edit_ownertrust( ulong lid, int mode )
 {
-    unsigned trust;
+    unsigned int trust;
 
     for(;;) {
        switch( do_edit_ownertrust( lid, mode, &trust ) ) {
@@ -216,6 +216,8 @@ edit_ownertrust( ulong lid, int mode )
            show_paths( lid, 1  );
            break;
          case 1:
+           trust &= ~TRUST_FLAG_DISABLED;
+           trust |= get_ownertrust( lid ) & TRUST_FLAG_DISABLED;
            if( !update_ownertrust( lid, trust ) )
                return 1;
            return 0;
@@ -301,7 +303,7 @@ do_we_trust( PKT_public_key *pk, int trustlevel )
 
     switch( (trustlevel & TRUST_MASK) ) {
       case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
-       rc = insert_trust_record( pk );
+       rc = insert_trust_record_by_pk( pk );
        if( rc ) {
            log_error("failed to insert it into the trustdb: %s\n",
                                                      g10_errstr(rc) );
@@ -462,7 +464,7 @@ check_signatures_trust( PKT_signature *sig )
 
     switch( (trustlevel & TRUST_MASK) ) {
       case TRUST_UNKNOWN: /* No pubkey in trustDB: Insert and check again */
-       rc = insert_trust_record( pk );
+       rc = insert_trust_record_by_pk( pk );
        if( rc ) {
            log_error("failed to insert it into the trustdb: %s\n",
                                                      g10_errstr(rc) );
@@ -633,6 +635,9 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
                    log_error("error checking pk of `%s': %s\n",
                                                      answer, g10_errstr(rc) );
                }
+               else if( (trustlevel & TRUST_FLAG_DISABLED) ) {
+                   tty_printf(_("Public key is disabled.\n") );
+               }
                else if( do_we_trust_pre( pk, trustlevel ) ) {
                    PK_LIST r;
 
@@ -673,6 +678,11 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
                    log_error(_("%s: error checking key: %s\n"),
                                                      remusr->d, g10_errstr(rc) );
                }
+               else if( (trustlevel & TRUST_FLAG_DISABLED) ) {
+                   free_public_key(pk); pk = NULL;
+                   log_info(_("%s: skipped: public key is disabled\n"),
+                                                                   remusr->d);
+               }
                else if( do_we_trust_pre( pk, trustlevel ) ) {
                    /* note: do_we_trust may have changed the trustlevel */
 
index 1edca16..878bdc4 100644 (file)
@@ -65,15 +65,15 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx,
     }
     else if( !opt.use_embedded_filename ) {
        fname = make_outfile_name( iobuf_get_real_fname(pt->buf) );
+       if( !fname )
+           fname = ask_outfile_name( pt->name, pt->namelen );
        if( !fname ) {
            rc = G10ERR_CREATE_FILE;
            goto leave;
        }
     }
     else {
-       fname = m_alloc( pt->namelen +1 );
-       memcpy( fname, pt->name, pt->namelen );
-       fname[pt->namelen] = 0;
+       fname = make_printable_string( pt->name, pt->namelen, 0 );
     }
 
     if( nooutput )
index 03cf3f2..95af40b 100644 (file)
@@ -64,7 +64,7 @@ do_check( PKT_secret_key *sk )
                keyid_from_sk( sk2, keyid+2 );
            free_secret_key( sk2 );
        }
-       dek = passphrase_to_dek( keyid, sk->protect.algo,
+       dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
                                 &sk->protect.s2k, 0 );
        cipher_hd = cipher_open( sk->protect.algo,
                                 CIPHER_MODE_AUTO_CFB, 1);
index 4873437..e57ae80 100644 (file)
@@ -412,6 +412,11 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig )
     pk = root->pkt->pkt.public_key;
     sig = node->pkt->pkt.signature;
     algo = sig->digest_algo;
+
+    if( sig->flags.checked )
+       log_debug("check_key_signature: already checked: %s\n",
+                     sig->flags.valid? "good":"bad" );
+
     if( (rc=check_digest_algo(algo)) )
        return rc;
 
index 2d3502c..799309e 100644 (file)
@@ -503,7 +503,7 @@ import_ownertrust( const char *fname )
                if( rc != -1 )
                    log_error_f(fname, _("Oops: key is now in trustdb???\n"));
                else {
-                   rc = insert_trust_record( pk );
+                   rc = insert_trust_record_by_pk( pk );
                    if( !rc )
                        goto repeat; /* update the ownertrust */
                    log_error_f(fname, _("insert trust record failed: %s\n"),
index 1e804d7..fa1e43a 100644 (file)
@@ -513,7 +513,7 @@ verify_own_keys(void)
        /* make sure that the pubkey is in the trustdb */
        rc = query_trust_record( pk );
        if( rc == -1 ) { /* put it into the trustdb */
-           rc = insert_trust_record( pk );
+           rc = insert_trust_record_by_pk( pk );
            if( rc ) {
                log_error(_("key %08lX: can't put it into the trustdb\n"),
                                                            (ulong)keyid[1] );
@@ -633,10 +633,14 @@ print_user_id( FILE *fp, const char *text, u32 *keyid )
 
 
 
+/****************
+ * This function returns a letter for a trustvalue  Trust flags
+ * are ignore.
+ */
 int
 trust_letter( unsigned value )
 {
-    switch( value ) {
+    switch( (value & TRUST_MASK) ) {
       case TRUST_UNKNOWN:   return '-';
       case TRUST_EXPIRED:   return 'e';
       case TRUST_UNDEFINED: return 'q';
@@ -994,6 +998,10 @@ check_keybinding( KBNODE keyblock, KBNODE keynode, u32 *mainkid,
     int is_main = (keynode->pkt->pkttype == PKT_PUBLIC_KEY);
     int rc;
 
+    if( DBG_TRUST )
+       log_debug("check_keybinding: %08lX.%lu\n",
+                           (ulong)mainkid[1], lid );
+
     if( is_main ) {
        /* a primary key is always valid (user IDs are handled elsewhere)*/
        keyflags = KEYF_CHECKED | KEYF_VALID;
@@ -1134,6 +1142,10 @@ check_uidsigs( KBNODE keyblock, KBNODE keynode, u32 *mainkid, ulong lid )
     PKT_signature *selfsig = NULL; /* the latest valid self signature */
     int rc;
 
+    if( DBG_TRUST )
+       log_debug("check_uidsigs: %08lX.%lu\n",
+                           (ulong)mainkid[1], lid );
+
     /* first we check only the selfsignatures */
     for( node=keynode->next; node; node = node->next ) {
        if( node->pkt->pkttype == PKT_USER_ID
@@ -1217,6 +1229,10 @@ check_sig_record( KBNODE keyblock, KBNODE signode,
     TRUSTREC tmp;
     int revocation=0, rc;
 
+    if( DBG_TRUST )
+       log_debug("check_sig_record: %08lX.%lu %lu[%d]\n",
+                           (ulong)keyid[1], lid, siglid, sigidx );
+
     if( (sig->sig_class&~3) == 0x10 ) /* regular certification */
        ;
     else if( sig->sig_class == 0x30 ) /* cert revocation */
@@ -1447,6 +1463,8 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
        primary_pk->local_id = drec.recnum;
 
     keyid_from_pk( primary_pk, keyid );
+    if( DBG_TRUST )
+       log_debug("update_trust_record: %08lX.%lu\n", (ulong)keyid[1], drec.recnum );
 
     rc = tdbio_begin_transaction();
     if( rc )
@@ -1512,14 +1530,11 @@ update_trust_record( KBNODE keyblock, int recheck, int *modified )
  * This function assumes that the record does not yet exist.
  */
 int
-insert_trust_record( PKT_public_key *orig_pk )
+insert_trust_record( KBNODE keyblock )
 {
     TRUSTREC dirrec;
     TRUSTREC shadow;
-    KBNODE keyblock = NULL;
     KBNODE node;
-    byte fingerprint[MAX_FINGERPRINT_LEN];
-    size_t fingerlen;
     int rc = 0;
     PKT_public_key *pk;
 
@@ -1529,39 +1544,11 @@ insert_trust_record( PKT_public_key *orig_pk )
 
     init_trustdb();
 
-    fingerprint_from_pk( orig_pk, fingerprint, &fingerlen );
-
-    /* fixme: assert that we do not have this record.
-     * we can do this by searching for the primary keyid
-     *
-     * fixme: If there is no such key we should look whether one
-     * of the subkeys has been used to sign another key and in this case
-     * we got the key anyway - this is because a secondary key can't be used
-     * without a primary key (it is needed to bind the secondary one
-     * to the primary one which has the user ids etc.)
-     */
-
-    if( orig_pk->local_id )
-       log_debug("insert_trust_record with pk->local_id=%lu (1)\n",
-                                                  orig_pk->local_id );
-
-    /* get the keyblock which has the key */
-    rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
-    if( rc ) { /* that should never happen */
-       log_error( _("insert_trust_record: keyblock not found: %s\n"),
-                                                         g10_errstr(rc) );
-       goto leave;
-    }
-
-    /* make sure that we use the primary key */
     pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )->pkt->pkt.public_key;
-
     if( pk->local_id ) {
-       orig_pk->local_id = pk->local_id;
        log_debug("insert_trust_record with pk->local_id=%lu (2)\n",
                                                        pk->local_id );
        rc = update_trust_record( keyblock, 1, NULL );
-       release_kbnode( keyblock );
        return rc;
     }
 
@@ -1581,9 +1568,8 @@ insert_trust_record( PKT_public_key *orig_pk )
     dirrec.r.dir.lid = dirrec.recnum;
     write_record( &dirrec );
 
-    /* put the LID into the in-memory copy of the keyblock */
+    /* put the LID into the keyblock */
     pk->local_id = dirrec.r.dir.lid;
-    orig_pk->local_id = dirrec.r.dir.lid;
     for( node=keyblock; node; node = node->next ) {
        if( node->pkt->pkttype == PKT_PUBLIC_KEY
            || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
@@ -1602,12 +1588,40 @@ insert_trust_record( PKT_public_key *orig_pk )
     /* and put all the other stuff into the keydb */
     rc = update_trust_record( keyblock, 1, NULL );
 
-  leave:
-    release_kbnode( keyblock );
     do_sync();
     return rc;
 }
 
+/****************
+ * Insert a trust record indentified by a PK into the TrustDB
+ */
+int
+insert_trust_record_by_pk( PKT_public_key *pk )
+{
+    KBNODE keyblock = NULL;
+    byte fingerprint[MAX_FINGERPRINT_LEN];
+    size_t fingerlen;
+    int rc;
+
+    /* get the keyblock */
+    fingerprint_from_pk( pk, fingerprint, &fingerlen );
+    rc = get_keyblock_byfprint( &keyblock, fingerprint, fingerlen );
+    if( rc ) { /* that should never happen */
+       log_debug( "insert_trust_record_by_pk: keyblock not found: %s\n",
+                                                         g10_errstr(rc) );
+    }
+    else {
+       rc = insert_trust_record( keyblock );
+       if( !rc ) /* copy the LID into the PK */
+           pk->local_id = find_kbnode( keyblock, PKT_PUBLIC_KEY )
+                                           ->pkt->pkt.public_key->local_id;
+    }
+
+    release_kbnode( keyblock );
+    return rc;
+}
+
+
 
 /****************
  * Walk over the keyrings and create trustdb records for all keys
@@ -1633,8 +1647,9 @@ update_trustdb()
 
            rc = update_trust_record( keyblock, 1, &modified );
            if( rc == -1 ) { /* not yet in trustdb: insert */
-               PKT_public_key *pk = keyblock->pkt->pkt.public_key;
-               rc = insert_trust_record( pk );
+               PKT_public_key *pk;
+               rc = insert_trust_record( keyblock );
+               pk = keyblock->pkt->pkt.public_key;
                if( rc && !pk->local_id ) {
                    log_error(_("lid ?: insert failed: %s\n"),
                                                     g10_errstr(rc) );
@@ -1782,7 +1797,7 @@ build_cert_tree( ulong lid, int depth, int max_depth, TN helproot )
        m_free(keynode);
        return NULL;
     }
-    keynode->n.k.ownertrust = dirrec.r.dir.ownertrust;
+    keynode->n.k.ownertrust = dirrec.r.dir.ownertrust & TRUST_MASK;
 
     /* loop over all user ids */
     for( uidrno = dirrec.r.dir.uidlist; uidrno; uidrno = uidrec.r.uid.next ) {
@@ -1872,12 +1887,17 @@ upd_one_ownertrust( ulong lid, unsigned new_trust, unsigned *retflgs )
        log_debug("upd_one_ownertrust of %lu from %u to %u\n",
                           lid, (unsigned)rec.r.dir.ownertrust, new_trust );
     if( retflgs ) {
-       if( new_trust > rec.r.dir.ownertrust )
+       if( (new_trust & TRUST_MASK) > (rec.r.dir.ownertrust & TRUST_MASK) )
            *retflgs |= 16; /* modified up */
        else
            *retflgs |= 32; /* modified down */
     }
-    rec.r.dir.ownertrust = new_trust;
+
+    /* we preserve the disabled state here */
+    if( (rec.r.dir.ownertrust & TRUST_FLAG_DISABLED) )
+       rec.r.dir.ownertrust = new_trust | TRUST_FLAG_DISABLED;
+    else
+       rec.r.dir.ownertrust = new_trust & ~TRUST_FLAG_DISABLED;
     write_record( &rec );
 }
 
@@ -2072,8 +2092,9 @@ do_check( TRUSTREC *dr, unsigned *validity,
     if( retflgs )
        *retflgs &= ~(16|32);  /* reset the 2 special flags */
 
-
-    if( namehash ) {
+    if( (dr->r.dir.ownertrust & TRUST_FLAG_DISABLED) )
+       *validity = 0; /* no need to check further */
+    else if( namehash ) {
        /* Fixme: use the cache */
        *validity = verify_key( opt.max_cert_depth, dr, namehash,
                                                        add_fnc, retflgs );
@@ -2091,6 +2112,9 @@ do_check( TRUSTREC *dr, unsigned *validity,
     if( !(*validity & TRUST_MASK) )
        *validity = TRUST_UNDEFINED;
 
+    if( (dr->r.dir.ownertrust & TRUST_FLAG_DISABLED) )
+       *validity |= TRUST_FLAG_DISABLED;
+
     if( dr->r.dir.dirflags & DIRF_REVOKED )
        *validity |= TRUST_FLAG_REVOKED;
 
@@ -2223,7 +2247,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
            return rc;
        }
        else if( rc == -1 ) { /* not found - insert */
-           rc = insert_trust_record( pk );
+           rc = insert_trust_record_by_pk( pk );
            if( rc ) {
                log_error(_("key %08lX: insert trust record failed: %s\n"),
                                          (ulong)keyid[1], g10_errstr(rc));
@@ -2247,7 +2271,7 @@ check_trust( PKT_public_key *pk, unsigned *r_trustlevel,
        log_info(_("key %08lX.%lu: expired at %s\n"),
                        (ulong)keyid[1], pk->local_id,
                             asctimestamp( pk->expiredate) );
-        trustlevel = TRUST_EXPIRED;
+       trustlevel = TRUST_EXPIRED;
     }
     else {
        rc = do_check( &rec, &trustlevel, namehash, add_fnc, retflgs );
@@ -2364,7 +2388,7 @@ list_trust_path( const char *username )
                                            username, g10_errstr(rc));
     else if( rc == -1 ) {
        log_info(_("user '%s' not in trustdb - inserting\n"), username);
-       rc = insert_trust_record( pk );
+       rc = insert_trust_record_by_pk( pk );
        if( rc )
            log_error(_("failed to put '%s' into trustdb: %s\n"),
                                                    username, g10_errstr(rc));
index 9f3e4c3..6396fde 100644 (file)
@@ -64,8 +64,9 @@ int keyid_from_lid( ulong lid, u32 *keyid );
 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 fast, int *modified );
+int insert_trust_record( KBNODE keyblock );
+int insert_trust_record_by_pk( PKT_public_key *pk );
 int update_ownertrust( ulong lid, unsigned new_trust );
 int trust_letter( unsigned value );
 
index d266af4..b36e11b 100644 (file)
@@ -153,6 +153,7 @@ const char *strtimevalue( u32 stamp );
 const char *strtimestamp( u32 stamp ); /* GMT */
 const char *asctimestamp( u32 stamp ); /* localized */
 void print_string( FILE *fp, const byte *p, size_t n, int delim );
+char *make_printable_string( const byte *p, size_t n, int delim );
 int answer_is_yes( const char *s );
 int answer_is_yes_no_quit( const char *s );
 
@@ -160,7 +161,9 @@ int answer_is_yes_no_quit( const char *s );
 void free_strlist( STRLIST sl );
 #define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0)
 STRLIST add_to_strlist( STRLIST *list, const char *string );
+STRLIST add_to_strlist2( STRLIST *list, const char *string, int is_utf8 );
 STRLIST append_to_strlist( STRLIST *list, const char *string );
+STRLIST append_to_strlist2( STRLIST *list, const char *string, int is_utf8 );
 STRLIST strlist_prev( STRLIST head, STRLIST node );
 STRLIST strlist_last( STRLIST node );
 const char *memistr( const char *buf, size_t buflen, const char *sub );
index 35e69fb..e74bf85 100644 (file)
@@ -1,3 +1,10 @@
+Thu Jul  1 12:47:31 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+
+       * miscutil.c (make_printable_string): New.
+
+       * strgutil.c (add_to_strlist2,append_to_strlist2): New.
+
 Tue Jun 29 21:44:25 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
 
 
index d982e64..4244ccc 100644 (file)
@@ -149,6 +149,60 @@ print_string( FILE *fp, const byte *p, size_t n, int delim )
            putc(*p, fp);
 }
 
+/****************
+ * This function returns a string which is suitable for printing
+ * Caller must release it with m_free()
+ */
+char *
+make_printable_string( const byte *p, size_t n, int delim )
+{
+    size_t save_n, buflen;
+    const byte *save_p;
+    char *buffer, *d;
+
+    /* first count length */
+    for(save_n = n, save_p = p, buflen=1 ; n; n--, p++ ) {
+       if( iscntrl( *p ) || *p == delim ) {
+           if( *p=='\n' || *p=='\r' || *p=='\f'
+               || *p=='\v' || *p=='\b' || !*p )
+               buflen += 2;
+           else
+               buflen += 3;
+       }
+       else
+           buflen++;
+    }
+    p = save_p;
+    n = save_n;
+    /* and now make the string */
+    d = buffer = m_alloc( buflen );
+    for( ; n; n--, p++ ) {
+       if( iscntrl( *p ) || *p == delim ) {
+           *d++ = '\\';
+           if( *p == '\n' )
+               *d++ = 'n';
+           else if( *p == '\r' )
+               *d++ = 'r';
+           else if( *p == '\f' )
+               *d++ = 'f';
+           else if( *p == '\v' )
+               *d++ = 'v';
+           else if( *p == '\b' )
+               *d++ = 'b';
+           else if( !*p )
+               *d++ = '0';
+           else {
+               sprintf(d, "x%02x", *p );
+               d += 2;
+           }
+       }
+       else
+           *d++ = *p;
+    }
+    *d = 0;
+    return buffer;
+}
+
 
 int
 answer_is_yes( const char *s )
index 94f8a5d..b27f9b7 100644 (file)
@@ -94,6 +94,25 @@ add_to_strlist( STRLIST *list, const char *string )
     return sl;
 }
 
+/****************
+ * ame as add_to_strlist() but if is_utf8 is *not* set a conversion
+ * to UTF8 is done
+ */
+STRLIST
+add_to_strlist2( STRLIST *list, const char *string, int is_utf8 )
+{
+    STRLIST sl;
+
+    if( is_utf8 )
+       sl = add_to_strlist( list, string );
+    else {
+       char *p = native_to_utf8( string );
+       sl = add_to_strlist( list, p );
+       m_free( p );
+    }
+    return sl;
+}
+
 STRLIST
 append_to_strlist( STRLIST *list, const char *string )
 {
@@ -113,6 +132,20 @@ append_to_strlist( STRLIST *list, const char *string )
     return sl;
 }
 
+STRLIST
+append_to_strlist2( STRLIST *list, const char *string, int is_utf8 )
+{
+    STRLIST sl;
+
+    if( is_utf8 )
+       sl = append_to_strlist( list, string );
+    else {
+       char *p = native_to_utf8( string );
+       sl = append_to_strlist( list, p );
+       m_free( p );
+    }
+    return sl;
+}
 
 
 STRLIST