See ChangeLog: Wed Dec 23 13:34:22 CET 1998 Werner Koch
[gnupg.git] / g10 / g10.c
index 9d4f20d..8191ea0 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -1,14 +1,14 @@
 /* g10.c - The GnuPG utility (main for gpg)
  *     Copyright (C) 1998 Free Software Foundation, Inc.
  *
- * This file is part of GNUPG.
+ * This file is part of GnuPG.
  *
- * GNUPG 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.
  *
- * GNUPG 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.
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 #include <unistd.h>
 
-/* #define MAINTAINER_OPTIONS */
+#define MAINTAINER_OPTIONS
 
 #include "packet.h"
 #include "iobuf.h"
@@ -83,6 +84,7 @@ enum cmd_and_opt_values { aNull = 0,
     aListSigs,
     aListSecretKeys,
     aExport,
+    aExportAll,
     aExportSecret,
     aCheckKeys,
     aGenRevoke,
@@ -107,6 +109,7 @@ enum cmd_and_opt_values { aNull = 0,
     oKeyring,
     oSecretKeyring,
     oDefaultKey,
+    oTrustedKey,
     oOptions,
     oDebug,
     oDebugAll,
@@ -114,6 +117,7 @@ enum cmd_and_opt_values { aNull = 0,
     oNoComment,
     oCompletesNeeded,
     oMarginalsNeeded,
+    oMaxCertDepth,
     oLoadExtension,
     oRFC1991,
     oCipherAlgo,
@@ -144,6 +148,10 @@ enum cmd_and_opt_values { aNull = 0,
     oS2KMode,
     oS2KDigest,
     oS2KCipher,
+    oCharset,
+    oNotDashEscaped,
+    oEscapeFrom,
+    oLockOnce,
 aTest };
 
 
@@ -174,7 +182,8 @@ static ARGPARSE_OPTS opts[] = {
     { aEditKey, "edit-key"  ,256, N_("sign or edit a key")},
     { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
   #endif
-    { aExport, "export"          , 256, N_("export keys") },
+    { aExport, "export"           , 256, N_("export keys") },
+    { aExportAll, "export-all"    , 256, "@" },
     { aExportSecret, "export-secret-keys" , 256, "@" },
     { aImport, "import",      256     , N_("import/merge keys")},
     { aFastImport, "fast-import",  256 , "@"},
@@ -220,6 +229,7 @@ static ARGPARSE_OPTS opts[] = {
     { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
     { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
     { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
+    { oCharset, "charset"   , 2, N_("|NAME|set terminal charset to NAME") },
     { oOptions, "options"   , 2, N_("read options from file")},
 
     { oDebug, "debug"     ,4|16, N_("set debugging flags")},
@@ -228,6 +238,8 @@ static ARGPARSE_OPTS opts[] = {
     { oNoComment, "no-comment", 0,   N_("do not write comment packets")},
     { oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")},
     { oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")},
+    { oMaxCertDepth,   "max-cert-depth", 1, "@" },
+    { oTrustedKey, "trusted-key", 2, N_("|KEYID|ulimately trust this key")},
     { oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
     { oRFC1991, "rfc1991",   0, N_("emulate the mode described in RFC1991")},
     { oS2KMode, "s2k-mode",  1, N_("|N|use passphrase mode N")},
@@ -257,14 +269,12 @@ static ARGPARSE_OPTS opts[] = {
 
   /* hidden options */
   #ifdef IS_G10MAINT
-    { aTest, "test"      , 0, "@" },
     { aExportOwnerTrust, "list-ownertrust",0 , "@"},  /* alias */
     { aListTrustDB, "list-trustdb",0 , "@"},
     { aListTrustPath, "list-trust-path",0, "@"},
   #endif
   #ifdef IS_G10
     { oKOption, NULL,   0, "@"},
-    { aEditKey, "edit-sig"  ,0, "@"}, /* alias for edit-key */
     { oPasswdFD, "passphrase-fd",1, "@" },
     { aSignKey, "sign-key"  ,256, "@" }, /* alias for edit-key */
   #endif
@@ -291,10 +301,16 @@ static ARGPARSE_OPTS opts[] = {
     { oRunAsShmCP, "run-as-shm-coprocess", 4, "@" },
     { oSetFilename, "set-filename", 2, "@" },
     { oComment, "comment", 2, "@" },
+    { oNotDashEscaped, "not-dash-escaped", 0, "@" },
+    { oEscapeFrom, "escape-from-lines", 0, "@" },
+    { oLockOnce, "lock-once", 0, "@" },
 {0} };
 
 
 
+int g10_errors_seen = 0;
+
+
 static int maybe_setuid = 1;
 
 static char *build_list( const char *text,
@@ -488,7 +504,6 @@ main( int argc, char **argv )
     unsigned configlineno;
     int parse_debug = 0;
     int default_config =1;
-    int errors=0;
     int default_keyring = 1;
     int greeting = 1;
     enum cmd_and_opt_values cmd = 0;
@@ -529,6 +544,7 @@ main( int argc, char **argv )
     opt.s2k_cipher_algo = CIPHER_ALGO_BLOWFISH;
     opt.completes_needed = 1;
     opt.marginals_needed = 3;
+    opt.max_cert_depth = 5;
     opt.homedir = getenv("GNUPGHOME");
     if( !opt.homedir || !*opt.homedir ) {
       #ifdef __MINGW32__
@@ -599,7 +615,7 @@ main( int argc, char **argv )
        if( !configfp ) {
            if( default_config ) {
                if( parse_debug )
-                   log_info(_("note: no default option file '%s'\n"),
+                   log_info(_("NOTE: no default option file '%s'\n"),
                                                            configname );
            }
            else {
@@ -622,6 +638,7 @@ main( int argc, char **argv )
          case aImport: set_cmd( &cmd, aImport); break;
          case aFastImport: set_cmd( &cmd, aFastImport); break;
          case aExport: set_cmd( &cmd, aExport); break;
+         case aExportAll: set_cmd( &cmd, aExportAll); break;
          case aListKeys: set_cmd( &cmd, aListKeys); break;
          case aListSigs: set_cmd( &cmd, aListSigs); break;
          case aExportSecret: set_cmd( &cmd, aExportSecret); break;
@@ -644,7 +661,6 @@ main( int argc, char **argv )
        #else
          #ifdef MAINTAINER_OPTIONS
            case aPrimegen: set_cmd( &cmd, aPrimegen); break;
-           case aTest: set_cmd( &cmd, aTest); break;
            case aGenRandom: set_cmd( &cmd, aGenRandom); break;
          #endif
          case aPrintMD: set_cmd( &cmd, aPrintMD); break;
@@ -695,8 +711,10 @@ main( int argc, char **argv )
          case oNoComment: opt.no_comment=1; break;
          case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
          case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
+         case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
          case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
          case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
+         case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
          case oNoOptions: break; /* no-options */
          case oHomedir: opt.homedir = pargs.r.ret_str; break;
          case oNoBatch: opt.batch = 0; break;
@@ -711,7 +729,11 @@ main( int argc, char **argv )
            register_cipher_extension(orig_argc? *orig_argv:NULL,
                                      pargs.r.ret_str);
            break;
-         case oRFC1991: opt.rfc1991 = 1; opt.no_comment = 1; break;
+         case oRFC1991:
+           opt.rfc1991 = 1;
+           opt.no_comment = 1;
+           opt.escape_from = 1;
+           break;
          case oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break;
          case oCompressSigs: opt.compress_sigs = 1; break;
          case oRunAsShmCP:
@@ -755,8 +777,16 @@ main( int argc, char **argv )
          case oNoSecmemWarn:
            break;  /* dummies */
        #endif
+         case oCharset:
+           if( set_native_charset( pargs.r.ret_str ) )
+               log_error(_("%s is not a valid character set\n"),
+                                                   pargs.r.ret_str);
+           break;
+         case oNotDashEscaped: opt.not_dash_escaped = 1; break;
+         case oEscapeFrom: opt.escape_from = 1; break;
+         case oLockOnce: opt.lock_once = 1; break;
 
-         default : errors++; pargs.err = configfp? 1:2; break;
+         default : pargs.err = configfp? 1:2; break;
        }
     }
     if( configfp ) {
@@ -810,15 +840,24 @@ main( int argc, char **argv )
        log_error(_("completes-needed must be greater than 0\n"));
     if( opt.marginals_needed < 2 )
        log_error(_("marginals-needed must be greater than 1\n"));
+    if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
+       log_error(_("max-cert-depth must be in range 1 to 255\n"));
     switch( opt.s2k_mode ) {
       case 0:
-       log_info(_("note: simple S2K mode (0) is strongly discouraged\n"));
+       log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
        break;
       case 1: case 3: break;
       default:
        log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
     }
 
+    {  const char *p = strusage(13);
+       for( ; *p && (isdigit(*p) || *p=='.'); p++ )
+           ;
+       if( *p )
+           log_info("NOTE: This is a development version!\n");
+    }
+
     if( log_get_errorcount(0) )
        g10_exit(2);
 
@@ -974,9 +1013,17 @@ main( int argc, char **argv )
 
       case aSignKey: /* sign the key given as argument */
       case aEditKey: /* Edit a key signature */
-       if( argc != 1 )
-           wrong_args(_("--edit-key username"));
-       keyedit_menu(fname, locusr );
+       if( !argc )
+           wrong_args(_("--edit-key username [commands]"));
+       if( argc > 1 ) {
+           sl = NULL;
+           for( argc--, argv++ ; argc; argc--, argv++ )
+               append_to_strlist( &sl, *argv );
+           keyedit_menu( fname, locusr, sl );
+           free_strlist(sl);
+       }
+       else
+           keyedit_menu(fname, locusr, NULL );
        break;
 
       #endif /* IS_G10 */
@@ -1047,10 +1094,11 @@ main( int argc, char **argv )
        break;
 
       case aExport:
+      case aExportAll:
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist( &sl, *argv );
-       export_pubkeys( sl );
+       export_pubkeys( sl, (cmd == aExport) );
        free_strlist(sl);
        break;
 
@@ -1123,15 +1171,20 @@ main( int argc, char **argv )
        if( argc < 1 || argc > 2 )
            wrong_args("--gen-random level [hex]");
        {
+           int c;
            int level = atoi(*argv);
            for(;;) {
-               byte *p = get_random_bits( 8, level, 0);
-               if( argc == 1 ) {
+               byte *p;
+               if( argc == 2 ) {
+                   p = get_random_bits( 8, level, 0);
                    printf("%02x", *p );
                    fflush(stdout);
                }
-               else
-                   putchar(c&0xff);
+               else {
+                   p = get_random_bits( 800, level, 0);
+                   for(c=0; c < 100; c++ )
+                       putchar( p[c] );
+               }
                m_free(p);
            }
        }
@@ -1167,10 +1220,6 @@ main( int argc, char **argv )
        }
        break;
 
-     #ifdef MAINTAINER_OPTIONS
-      case aTest: do_test( argc? atoi(*argv): 1 ); break;
-      #endif /* MAINTAINER OPTIONS */
-
       case aListTrustDB:
        if( !argc )
            list_trustdb(NULL);
@@ -1202,9 +1251,10 @@ main( int argc, char **argv )
        break;
 
       case aListTrustPath:
-       if( argc != 2 )
-           wrong_args("--list-trust-path [-- -]<maxdepth> <username>");
-       list_trust_path( atoi(*argv), argv[1] );
+       if( !argc )
+           wrong_args("--list-trust-path <usernames>");
+       for( ; argc; argc--, argv++ )
+           list_trust_path( *argv );
        break;
 
       case aExportOwnerTrust:
@@ -1228,9 +1278,15 @@ main( int argc, char **argv )
        /* fixme: g10maint should do regular maintenace tasks here */
        if( argc > 1 )
            wrong_args(_("[filename]"));
+       /* Issue some output for the unix newbie */
+       if( !fname && !opt.outfile && isatty( fileno(stdin) )
+               && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
+           log_info(_("Go ahead and type your message ...\n"));
+
        if( !(a = iobuf_open(fname)) )
            log_error(_("can't open '%s'\n"), print_fname_stdin(fname));
        else {
+
            if( !opt.no_armor ) {
                if( use_armor_filter( a ) ) {
                    memset( &afx, 0, sizeof afx);
@@ -1263,23 +1319,13 @@ g10_exit( int rc )
     if( opt.debug )
        secmem_dump_stats();
     secmem_term();
-    rc = rc? rc : log_get_errorcount(0)? 2:0;
+    rc = rc? rc : log_get_errorcount(0)? 2 :
+                       g10_errors_seen? 1 : 0;
     /*write_status( STATUS_LEAVE );*/
     exit(rc );
 }
 
 
-void
-do_not_use_RSA()
-{
-    static int did_rsa_note = 0;
-
-    if( !did_rsa_note ) {
-       did_rsa_note = 1;
-       log_info(_("RSA keys are deprecated; please consider "
-                  "creating a new key and use this key in the future\n"));
-    }
-}
 
 
 #ifdef IS_G10MAINT
@@ -1385,12 +1431,5 @@ print_mds( const char *fname, int algo )
 
 
 
-#ifdef MAINTAINER_OPTIONS
-static void
-do_test(int times)
-{
-    m_check(NULL);
-}
-#endif /* MAINTAINER OPTIONS */
 #endif /* IS_G10MAINT */