See ChangeLog ;-). Key validation should now be faster
[gnupg.git] / g10 / g10.c
1 /* g10.c - The GnuPG utility (main for gpg)
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *
4  * This file is part of GNUPG.
5  *
6  * GNUPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GNUPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27
28 /* #define MAINTAINER_OPTIONS */
29
30 #include "packet.h"
31 #include "iobuf.h"
32 #include "memory.h"
33 #include "util.h"
34 #include "main.h"
35 #include "options.h"
36 #include "keydb.h"
37 #include "mpi.h"
38 #include "cipher.h"
39 #include "filter.h"
40 #include "trustdb.h"
41 #include "ttyio.h"
42 #include "i18n.h"
43 #include "status.h"
44 #include "g10defs.h"
45
46 #ifndef IS_G10MAINT
47   #define IS_G10 1
48 #endif
49
50
51 enum cmd_and_opt_values { aNull = 0,
52     oArmor        = 'a',
53     aDetachedSign = 'b',
54     aSym          = 'c',
55     aDecrypt      = 'd',
56     aEncr         = 'e',
57     oKOption      = 'k',
58     oDryRun       = 'n',
59     oOutput       = 'o',
60     oQuiet        = 'q',
61     oRemote       = 'r',
62     aSign         = 's',
63     oTextmodeShort= 't',
64     oUser         = 'u',
65     oVerbose      = 'v',
66     oCompress     = 'z',
67     oBatch        = 500,
68     aClearsign,
69     aStore,
70     aKeygen,
71     aSignEncr,
72     aSignKey,
73     aListPackets,
74     aEditKey,
75     aDeleteKey,
76     aDeleteSecretKey,
77     aKMode,
78     aKModeC,
79     aImport,
80     aFastImport,
81     aVerify,
82     aListKeys,
83     aListSigs,
84     aListSecretKeys,
85     aExport,
86     aExportSecret,
87     aCheckKeys,
88     aGenRevoke,
89     aPrimegen,
90     aPrintMD,
91     aPrintMDs,
92     aCheckTrustDB,
93     aUpdateTrustDB,
94     aFixTrustDB,
95     aListTrustDB,
96     aListTrustPath,
97     aExportOwnerTrust,
98     aImportOwnerTrust,
99     aDeArmor,
100     aEnArmor,
101     aGenRandom,
102
103     oTextmode,
104     oFingerprint,
105     oAnswerYes,
106     oAnswerNo,
107     oKeyring,
108     oSecretKeyring,
109     oDefaultKey,
110     oOptions,
111     oDebug,
112     oDebugAll,
113     oStatusFD,
114     oNoComment,
115     oCompletesNeeded,
116     oMarginalsNeeded,
117     oMaxCertDepth,
118     oLoadExtension,
119     oRFC1991,
120     oCipherAlgo,
121     oDigestAlgo,
122     oCompressAlgo,
123     oPasswdFD,
124     oQuickRandom,
125     oNoVerbose,
126     oTrustDBName,
127     oNoSecmemWarn,
128     oNoArmor,
129     oNoDefKeyring,
130     oNoGreeting,
131     oNoOptions,
132     oNoBatch,
133     oHomedir,
134     oWithColons,
135     oSkipVerify,
136     oCompressKeys,
137     oCompressSigs,
138     oAlwaysTrust,
139     oEmuChecksumBug,
140     oRunAsShmCP,
141     oSetFilename,
142     oComment,
143     oThrowKeyid,
144     oForceV3Sigs,
145     oS2KMode,
146     oS2KDigest,
147     oS2KCipher,
148     oCharset,
149 aTest };
150
151
152 static ARGPARSE_OPTS opts[] = {
153
154     { 300, NULL, 0, N_("@Commands:\n ") },
155
156   #ifdef IS_G10
157     { aSign, "sign",      256, N_("|[file]|make a signature")},
158     { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature") },
159     { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
160     { aEncr, "encrypt",   256, N_("encrypt data")},
161     { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
162     { aStore, "store",     256, N_("store only")},
163     { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
164     { aVerify, "verify"   , 256, N_("verify a signature")},
165   #endif
166     { aListKeys, "list-keys", 256, N_("list keys")},
167     { aListSigs, "list-sigs", 256, N_("list keys and signatures")},
168     { aCheckKeys, "check-sigs",256, N_("check key signatures")},
169     { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
170     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
171   #ifdef IS_G10
172     { aKeygen, "gen-key",   256, N_("generate a new key pair")},
173   #endif
174     { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")},
175   #ifdef IS_G10
176     { aEditKey, "edit-key"  ,256, N_("sign or edit a key")},
177     { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
178   #endif
179     { aExport, "export"          , 256, N_("export keys") },
180     { aExportSecret, "export-secret-keys" , 256, "@" },
181     { aImport, "import",      256     , N_("import/merge keys")},
182     { aFastImport, "fast-import",  256 , "@"},
183     { aListPackets, "list-packets",256,N_("list only the sequence of packets")},
184   #ifdef IS_G10MAINT
185     { aExportOwnerTrust,
186               "export-ownertrust", 256, N_("export the ownertrust values")},
187     { aImportOwnerTrust,
188               "import-ownertrust", 256 , N_("import ownertrust values")},
189     { aUpdateTrustDB,
190               "update-trustdb",0 , N_("|[NAMES]|update the trust database")},
191     { aCheckTrustDB,
192               "check-trustdb",0 , N_("|[NAMES]|check the trust database")},
193     { aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")},
194     { aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") },
195     { aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") },
196     { aPrintMD,  "print-md" , 256, N_("|algo [files]|print message digests")},
197     { aPrintMDs, "print-mds" , 256, N_("print all message digests")},
198     #ifdef MAINTAINER_OPTIONS
199     { aPrimegen, "gen-prime" , 256, "@" },
200     { aGenRandom, "gen-random" , 256, "@" },
201     #endif
202   #endif
203
204     { 301, NULL, 0, N_("@\nOptions:\n ") },
205
206     { oArmor, "armor",     0, N_("create ascii armored output")},
207   #ifdef IS_G10
208     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
209     { oRemote, "remote-user", 2, N_("use this user-id for encryption")},
210     { oCompress, NULL,        1, N_("|N|set compress level N (0 disables)") },
211     { oTextmodeShort, NULL,   0, "@"},
212     { oTextmode, "textmode",  0, N_("use canonical text mode")},
213   #endif
214     { oOutput, "output",    2, N_("use as output file")},
215     { oVerbose, "verbose",   0, N_("verbose") },
216     { oQuiet,   "quiet",   0, N_("be somewhat more quiet") },
217     { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
218  /* { oDryRun, "dry-run",   0, N_("do not make any changes") }, */
219     { oBatch, "batch",     0, N_("batch mode: never ask")},
220     { oAnswerYes, "yes",       0, N_("assume yes on most questions")},
221     { oAnswerNo,  "no",        0, N_("assume no on most questions")},
222     { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
223     { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
224     { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
225     { oCharset, "charset"   , 2, N_("|NAME| set terminal charset to NAME") },
226     { oOptions, "options"   , 2, N_("read options from file")},
227
228     { oDebug, "debug"     ,4|16, N_("set debugging flags")},
229     { oDebugAll, "debug-all" ,0, N_("enable full debugging")},
230     { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
231     { oNoComment, "no-comment", 0,   N_("do not write comment packets")},
232     { oCompletesNeeded, "completes-needed", 1, N_("(default is 1)")},
233     { oMarginalsNeeded, "marginals-needed", 1, N_("(default is 3)")},
234     { oMaxCertDepth,    "max-cert-depth", 1, "@" },
235     { oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
236     { oRFC1991, "rfc1991",   0, N_("emulate the mode described in RFC1991")},
237     { oS2KMode, "s2k-mode",  1, N_("|N|use passphrase mode N")},
238     { oS2KDigest, "s2k-digest-algo",2,
239                 N_("|NAME|use message digest algorithm NAME for passphrases")},
240     { oS2KCipher, "s2k-cipher-algo",2,
241                 N_("|NAME|use cipher algorithm NAME for passphrases")},
242   #ifdef IS_G10
243     { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
244     { oDigestAlgo, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")},
245     { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
246     { oThrowKeyid, "throw-keyid", 0, N_("throw keyid field of encrypted packets")},
247   #else /* some dummies */
248     { oCipherAlgo, "cipher-algo", 2 , "@"},
249     { oDigestAlgo, "digest-algo", 2 , "@"},
250     { oCompressAlgo, "compress-algo", 1 , "@"},
251   #endif
252
253   #ifdef IS_G10
254     { 302, NULL, 0, N_("@\nExamples:\n\n"
255     " -se -r Bob [file]          sign and encrypt for user Bob\n"
256     " --clearsign [file]         make a clear text signature\n"
257     " --detach-sign [file]       make a detached signature\n"
258     " --list-keys [names]        show keys\n"
259     " --fingerprint [names]      show fingerprints\n"  ) },
260   #endif
261
262   /* hidden options */
263   #ifdef IS_G10MAINT
264     { aTest, "test"      , 0, "@" },
265     { aExportOwnerTrust, "list-ownertrust",0 , "@"},  /* alias */
266     { aListTrustDB, "list-trustdb",0 , "@"},
267     { aListTrustPath, "list-trust-path",0, "@"},
268   #endif
269   #ifdef IS_G10
270     { oKOption, NULL,    0, "@"},
271     { aEditKey, "edit-sig"  ,0, "@"}, /* alias for edit-key */
272     { oPasswdFD, "passphrase-fd",1, "@" },
273     { aSignKey, "sign-key"  ,256, "@" }, /* alias for edit-key */
274   #endif
275     { aDeleteSecretKey, "delete-secret-key",0, "@" },
276     { oQuickRandom, "quick-random", 0, "@"},
277     { oNoVerbose, "no-verbose", 0, "@"},
278     { oTrustDBName, "trustdb-name", 2, "@" },
279     { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */
280     { oNoArmor, "no-armor",   0, "@"},
281     { oNoDefKeyring, "no-default-keyring", 0, "@" },
282     { oNoGreeting, "no-greeting", 0, "@" },
283     { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
284     { oHomedir, "homedir", 2, "@" },   /* defaults to "~/.gnupg" */
285     { oNoBatch, "no-batch", 0, "@" },
286     { oWithColons, "with-colons", 0, "@"},
287     { aListKeys, "list-key", 0, "@" }, /* alias */
288     { aListSigs, "list-sig", 0, "@" }, /* alias */
289     { aCheckKeys, "check-sig",0, "@" }, /* alias */
290     { oSkipVerify, "skip-verify",0, "@" },
291     { oCompressKeys, "compress-keys",0, "@"},
292     { oCompressSigs, "compress-sigs",0, "@"},
293     { oAlwaysTrust, "always-trust", 0, "@"},
294     { oEmuChecksumBug, "emulate-checksum-bug", 0, "@"},
295     { oRunAsShmCP, "run-as-shm-coprocess", 4, "@" },
296     { oSetFilename, "set-filename", 2, "@" },
297     { oComment, "comment", 2, "@" },
298 {0} };
299
300
301
302 int g10_errors_seen = 0;
303
304
305 static int maybe_setuid = 1;
306
307 static char *build_list( const char *text,
308                          const char *(*mapf)(int), int (*chkf)(int) );
309 static void set_cmd( enum cmd_and_opt_values *ret_cmd,
310                         enum cmd_and_opt_values new_cmd );
311 #ifdef IS_G10MAINT
312 static void print_hex( byte *p, size_t n );
313 static void print_mds( const char *fname, int algo );
314 #endif
315
316 const char *
317 strusage( int level )
318 {
319   static char *digests, *pubkeys, *ciphers;
320     const char *p;
321     switch( level ) {
322       case 11: p =
323           #ifdef IS_G10MAINT
324             "gpgm (GnuPG)";
325           #else
326             "gpg (GnuPG)";
327           #endif
328         break;
329       case 13: p = VERSION; break;
330       case 17: p = PRINTABLE_OS_NAME; break;
331       case 19: p =
332             _("Please report bugs to <gnupg-bugs@gnu.org>.\n");
333         break;
334       case 1:
335       case 40:  p =
336           #ifdef IS_G10MAINT
337             _("Usage: gpgm [options] [files] (-h for help)");
338           #else
339             _("Usage: gpg [options] [files] (-h for help)");
340           #endif
341         break;
342       case 41:  p =
343           #ifdef IS_G10MAINT
344             _("Syntax: gpgm [options] [files]\n"
345               "GnuPG maintenance utility\n");
346           #else
347             _("Syntax: gpg [options] [files]\n"
348               "sign, check, encrypt or decrypt\n"
349               "default operation depends on the input data\n");
350           #endif
351         break;
352
353       case 31: p = _("\nSupported algorithms:\n"); break;
354       case 32:
355         if( !ciphers )
356             ciphers = build_list("Cipher: ", cipher_algo_to_string,
357                                                         check_cipher_algo );
358         p = ciphers;
359         break;
360       case 33:
361         if( !pubkeys )
362             pubkeys = build_list("Pubkey: ", pubkey_algo_to_string,
363                                                         check_pubkey_algo );
364         p = pubkeys;
365         break;
366       case 34:
367         if( !digests )
368             digests = build_list("Hash: ", digest_algo_to_string,
369                                                         check_digest_algo );
370         p = digests;
371         break;
372
373       default:  p = default_strusage(level);
374     }
375     return p;
376 }
377
378
379 static char *
380 build_list( const char *text, const char * (*mapf)(int), int (*chkf)(int) )
381 {
382     int i;
383     const char *s;
384     size_t n=strlen(text)+2;
385     char *list, *p;
386
387     if( maybe_setuid )
388         secmem_init( 0 );    /* drop setuid */
389
390     for(i=1; i < 110; i++ )
391         if( !chkf(i) && (s=mapf(i)) )
392             n += strlen(s) + 2;
393     list = m_alloc( 21 + n ); *list = 0;
394     for(p=NULL, i=1; i < 110; i++ ) {
395         if( !chkf(i) && (s=mapf(i)) ) {
396             if( !p )
397                 p = stpcpy( list, text );
398             else
399                 p = stpcpy( p, ", ");
400             p = stpcpy(p, s );
401         }
402     }
403     if( p )
404         p = stpcpy(p, "\n" );
405     return list;
406 }
407
408
409 static void
410 i18n_init(void)
411 {
412   #ifdef ENABLE_NLS
413     #ifdef HAVE_LC_MESSAGES
414        setlocale( LC_TIME, "" );
415        setlocale( LC_MESSAGES, "" );
416     #else
417        setlocale( LC_ALL, "" );
418     #endif
419     bindtextdomain( PACKAGE, G10_LOCALEDIR );
420     textdomain( PACKAGE );
421   #endif
422 }
423
424 static void
425 wrong_args( const char *text)
426 {
427   #ifdef IS_G10MAINT
428     fputs(_("usage: gpgm [options] "),stderr);
429   #else
430     fputs(_("usage: gpg [options] "),stderr);
431   #endif
432     fputs(text,stderr);
433     putc('\n',stderr);
434     g10_exit(2);
435 }
436
437 static void
438 set_debug(void)
439 {
440     if( opt.debug & DBG_MEMORY_VALUE )
441         memory_debug_mode = 1;
442     if( opt.debug & DBG_MEMSTAT_VALUE )
443         memory_stat_debug_mode = 1;
444     if( opt.debug & DBG_MPI_VALUE )
445         mpi_debug_mode = 1;
446     if( opt.debug & DBG_CIPHER_VALUE )
447         g10c_debug_mode = 1;
448     if( opt.debug & DBG_IOBUF_VALUE )
449         iobuf_debug_mode = 1;
450
451 }
452
453
454 static void
455 set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
456 {
457     enum cmd_and_opt_values cmd = *ret_cmd;
458
459     if( !cmd || cmd == new_cmd )
460         cmd = new_cmd;
461     else if( cmd == aSign && new_cmd == aEncr )
462         cmd = aSignEncr;
463     else if( cmd == aEncr && new_cmd == aSign )
464         cmd = aSignEncr;
465     else if( cmd == aKMode && new_cmd == aSym )
466         cmd = aKModeC;
467     else if(    ( cmd == aSign     && new_cmd == aClearsign )
468              || ( cmd == aClearsign && new_cmd == aSign )  )
469         cmd = aClearsign;
470     else {
471         log_error(_("conflicting commands\n"));
472         g10_exit(2);
473     }
474
475     *ret_cmd = cmd;
476 }
477
478
479
480 int
481 main( int argc, char **argv )
482 {
483     ARGPARSE_ARGS pargs;
484     IOBUF a;
485     int rc=0;
486     int orig_argc;
487     char **orig_argv;
488     const char *fname;
489     STRLIST sl, remusr= NULL, locusr=NULL;
490     STRLIST nrings=NULL, sec_nrings=NULL;
491     armor_filter_context_t afx;
492     int detached_sig = 0;
493     FILE *configfp = NULL;
494     char *configname = NULL;
495     unsigned configlineno;
496     int parse_debug = 0;
497     int default_config =1;
498     int default_keyring = 1;
499     int greeting = 1;
500     enum cmd_and_opt_values cmd = 0;
501     const char *trustdb_name = NULL;
502     char *def_cipher_string = NULL;
503     char *def_digest_string = NULL;
504     char *s2k_cipher_string = NULL;
505     char *s2k_digest_string = NULL;
506     int pwfd = -1;
507   #ifdef USE_SHM_COPROCESSING
508     ulong requested_shm_size=0;
509   #endif
510
511     trap_unaligned();
512     secmem_set_flags( secmem_get_flags() | 2 ); /* suspend warnings */
513   #ifdef IS_G10MAINT
514     secmem_init( 0 );      /* disable use of secmem */
515     maybe_setuid = 0;
516     log_set_name("gpgm");
517   #else
518     /* Please note that we may running SUID(ROOT), so be very CAREFUL
519      * when adding any stuff between here and the call to
520      * secmem_init()  somewhere after the option parsing
521      */
522     log_set_name("gpg");
523     secure_random_alloc(); /* put random number into secure memory */
524     disable_core_dumps();
525   #endif
526     init_signals();
527     i18n_init();
528     opt.compress = -1; /* defaults to standard compress level */
529     /* fixme: set the next two to zero and decide where used */
530     opt.def_cipher_algo = 0;
531     opt.def_digest_algo = 0;
532     opt.def_compress_algo = 2;
533     opt.s2k_mode = 1; /* salted */
534     opt.s2k_digest_algo = DIGEST_ALGO_RMD160;
535     opt.s2k_cipher_algo = CIPHER_ALGO_BLOWFISH;
536     opt.completes_needed = 1;
537     opt.marginals_needed = 3;
538     opt.max_cert_depth = 5;
539     opt.homedir = getenv("GNUPGHOME");
540     if( !opt.homedir || !*opt.homedir ) {
541       #ifdef __MINGW32__
542         opt.homedir = "c:/gnupg";
543       #else
544         opt.homedir = "~/.gnupg";
545       #endif
546     }
547
548     /* check whether we have a config file on the commandline */
549     orig_argc = argc;
550     orig_argv = argv;
551     pargs.argc = &argc;
552     pargs.argv = &argv;
553     pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
554     while( arg_parse( &pargs, opts) ) {
555         if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
556             parse_debug++;
557         else if( pargs.r_opt == oOptions ) {
558             /* yes there is one, so we do not try the default one, but
559              * read the option file when it is encountered at the commandline
560              */
561             default_config = 0;
562         }
563         else if( pargs.r_opt == oNoOptions )
564             default_config = 0; /* --no-options */
565         else if( pargs.r_opt == oHomedir )
566             opt.homedir = pargs.r.ret_str;
567       #ifdef USE_SHM_COPROCESSING
568         else if( pargs.r_opt == oRunAsShmCP ) {
569             /* does not make sense in a options file, we do it here,
570              * so that we are the able to drop setuid as soon as possible */
571             opt.shm_coprocess = 1;
572             requested_shm_size = pargs.r.ret_ulong;
573         }
574       #endif
575     }
576
577
578   #ifdef USE_SHM_COPROCESSING
579     if( opt.shm_coprocess ) {
580       #ifdef IS_G10
581         init_shm_coprocessing(requested_shm_size, 1 );
582       #else
583         init_shm_coprocessing(requested_shm_size, 0 );
584       #endif
585     }
586   #endif
587   #ifdef IS_G10
588     /* initialize the secure memory. */
589     secmem_init( 16384 );
590     maybe_setuid = 0;
591     /* Okay, we are now working under our real uid */
592   #endif
593
594     if( default_config )
595         configname = make_filename(opt.homedir, "options", NULL );
596
597     argc = orig_argc;
598     argv = orig_argv;
599     pargs.argc = &argc;
600     pargs.argv = &argv;
601     pargs.flags=  1;  /* do not remove the args */
602   next_pass:
603     if( configname ) {
604         configlineno = 0;
605         configfp = fopen( configname, "r" );
606         if( !configfp ) {
607             if( default_config ) {
608                 if( parse_debug )
609                     log_info(_("NOTE: no default option file '%s'\n"),
610                                                             configname );
611             }
612             else {
613                 log_error(_("option file '%s': %s\n"),
614                                     configname, strerror(errno) );
615                 g10_exit(2);
616             }
617             m_free(configname); configname = NULL;
618         }
619         if( parse_debug && configname )
620             log_info(_("reading options from '%s'\n"), configname );
621         default_config = 0;
622     }
623
624     while( optfile_parse( configfp, configname, &configlineno,
625                                                 &pargs, opts) ) {
626         switch( pargs.r_opt ) {
627           case aCheckKeys: set_cmd( &cmd, aCheckKeys); break;
628           case aListPackets: set_cmd( &cmd, aListPackets); break;
629           case aImport: set_cmd( &cmd, aImport); break;
630           case aFastImport: set_cmd( &cmd, aFastImport); break;
631           case aExport: set_cmd( &cmd, aExport); break;
632           case aListKeys: set_cmd( &cmd, aListKeys); break;
633           case aListSigs: set_cmd( &cmd, aListSigs); break;
634           case aExportSecret: set_cmd( &cmd, aExportSecret); break;
635           case aDeleteSecretKey: set_cmd( &cmd, aDeleteSecretKey); break;
636           case aDeleteKey: set_cmd( &cmd, aDeleteKey); break;
637
638         #ifdef IS_G10
639           case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
640           case aSym: set_cmd( &cmd, aSym); break;
641           case aDecrypt: set_cmd( &cmd, aDecrypt); break;
642           case aEncr: set_cmd( &cmd, aEncr); break;
643           case aSign: set_cmd( &cmd, aSign );  break;
644           case aKeygen: set_cmd( &cmd, aKeygen); break;
645           case aSignKey: set_cmd( &cmd, aSignKey); break;
646           case aStore: set_cmd( &cmd, aStore); break;
647           case aEditKey: set_cmd( &cmd, aEditKey); break;
648           case aClearsign: set_cmd( &cmd, aClearsign); break;
649           case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
650           case aVerify: set_cmd( &cmd, aVerify); break;
651         #else
652           #ifdef MAINTAINER_OPTIONS
653             case aPrimegen: set_cmd( &cmd, aPrimegen); break;
654             case aTest: set_cmd( &cmd, aTest); break;
655             case aGenRandom: set_cmd( &cmd, aGenRandom); break;
656           #endif
657           case aPrintMD: set_cmd( &cmd, aPrintMD); break;
658           case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
659           case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
660           case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
661           case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
662           case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break;
663           case aListTrustPath: set_cmd( &cmd, aListTrustPath); break;
664           case aDeArmor: set_cmd( &cmd, aDeArmor); break;
665           case aEnArmor: set_cmd( &cmd, aEnArmor); break;
666           case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break;
667           case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break;
668         #endif /* IS_G10MAINT */
669
670
671
672           case oArmor: opt.armor = 1; opt.no_armor=0; break;
673           case oOutput: opt.outfile = pargs.r.ret_str; break;
674           case oQuiet: opt.quiet = 1; break;
675           case oVerbose: g10_opt_verbose++;
676                     opt.verbose++; opt.list_sigs=1; break;
677           case oKOption: set_cmd( &cmd, aKMode ); break;
678
679           case oBatch: opt.batch = 1; greeting = 0; break;
680           case oAnswerYes: opt.answer_yes = 1; break;
681           case oAnswerNo: opt.answer_no = 1; break;
682           case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
683           case oDebug: opt.debug |= pargs.r.ret_ulong; break;
684           case oDebugAll: opt.debug = ~0; break;
685           case oStatusFD: set_status_fd( pargs.r.ret_int ); break;
686           case oFingerprint: opt.fingerprint++; break;
687           case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break;
688           case oOptions:
689             /* config files may not be nested (silently ignore them) */
690             if( !configfp ) {
691                 m_free(configname);
692                 configname = m_strdup(pargs.r.ret_str);
693                 goto next_pass;
694             }
695             break;
696           case oNoArmor: opt.no_armor=1; opt.armor=0; break;
697           case oNoDefKeyring: default_keyring = 0; break;
698           case oNoGreeting: greeting = 0; break;
699           case oNoVerbose: g10_opt_verbose = 0;
700                            opt.verbose = 0; opt.list_sigs=0; break;
701           case oQuickRandom: quick_random_gen(1); break;
702           case oNoComment: opt.no_comment=1; break;
703           case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
704           case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
705           case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
706           case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
707           case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
708           case oNoOptions: break; /* no-options */
709           case oHomedir: opt.homedir = pargs.r.ret_str; break;
710           case oNoBatch: opt.batch = 0; break;
711           case oWithColons: opt.with_colons=':'; break;
712
713           case oSkipVerify: opt.skip_verify=1; break;
714           case oCompressAlgo: opt.def_compress_algo = pargs.r.ret_int; break;
715           case oCompressKeys: opt.compress_keys = 1; break;
716           case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
717           case oAlwaysTrust: opt.always_trust = 1; break;
718           case oLoadExtension:
719             register_cipher_extension(orig_argc? *orig_argv:NULL,
720                                       pargs.r.ret_str);
721             break;
722           case oRFC1991: opt.rfc1991 = 1; opt.no_comment = 1; break;
723           case oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break;
724           case oCompressSigs: opt.compress_sigs = 1; break;
725           case oRunAsShmCP:
726           #ifndef USE_SHM_COPROCESSING
727             /* not possible in the option file,
728              * but we print the warning here anyway */
729             log_error("shared memory coprocessing is not available\n");
730           #endif
731             break;
732           case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
733           case oComment: opt.comment_string = pargs.r.ret_str; break;
734           case oThrowKeyid: opt.throw_keyid = 1; break;
735           case oForceV3Sigs: opt.force_v3_sigs = 1; break;
736           case oS2KMode:   opt.s2k_mode = pargs.r.ret_int; break;
737           case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break;
738           case oS2KCipher: s2k_cipher_string = m_strdup(pargs.r.ret_str); break;
739
740         #ifdef IS_G10
741           case oRemote: /* store the remote users */
742             sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
743             strcpy(sl->d, pargs.r.ret_str);
744             sl->next = remusr;
745             remusr = sl;
746             break;
747           case oTextmodeShort: opt.textmode = 2; break;
748           case oTextmode: opt.textmode=1;  break;
749           case oUser: /* store the local users */
750             sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
751             strcpy(sl->d, pargs.r.ret_str);
752             sl->next = locusr;
753             locusr = sl;
754             break;
755           case oCompress: opt.compress = pargs.r.ret_int; break;
756           case oPasswdFD: pwfd = pargs.r.ret_int; break;
757           case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break;
758           case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break;
759           case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
760         #else
761           case oCipherAlgo:
762           case oDigestAlgo:
763           case oNoSecmemWarn:
764             break;  /* dummies */
765         #endif
766           case oCharset:
767             if( set_native_charset( pargs.r.ret_str ) )
768                 log_error(_("%s is not a valid character set\n"),
769                                                     pargs.r.ret_str);
770             break;
771
772           default : pargs.err = configfp? 1:2; break;
773         }
774     }
775     if( configfp ) {
776         fclose( configfp );
777         configfp = NULL;
778         m_free(configname); configname = NULL;
779         goto next_pass;
780     }
781     m_free( configname ); configname = NULL;
782     if( log_get_errorcount(0) )
783         g10_exit(2);
784
785     if( greeting ) {
786         tty_printf("%s %s; %s\n", strusage(11), strusage(13), strusage(14) );
787         tty_printf("%s\n", strusage(15) );
788     }
789
790     secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
791
792     set_debug();
793
794     /* must do this after dropping setuid, because string_to...
795      * may try to load an module */
796     if( def_cipher_string ) {
797         opt.def_cipher_algo = string_to_cipher_algo(def_cipher_string);
798         m_free(def_cipher_string); def_cipher_string = NULL;
799         if( check_cipher_algo(opt.def_cipher_algo) )
800             log_error(_("selected cipher algorithm is invalid\n"));
801     }
802     if( def_digest_string ) {
803         opt.def_digest_algo = string_to_digest_algo(def_digest_string);
804         m_free(def_digest_string); def_digest_string = NULL;
805         if( check_digest_algo(opt.def_digest_algo) )
806             log_error(_("selected digest algorithm is invalid\n"));
807     }
808     if( s2k_cipher_string ) {
809         opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string);
810         m_free(s2k_cipher_string); s2k_cipher_string = NULL;
811         if( check_cipher_algo(opt.s2k_cipher_algo) )
812             log_error(_("selected cipher algorithm is invalid\n"));
813     }
814     if( s2k_digest_string ) {
815         opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string);
816         m_free(s2k_digest_string); s2k_digest_string = NULL;
817         if( check_digest_algo(opt.s2k_digest_algo) )
818             log_error(_("selected digest algorithm is invalid\n"));
819     }
820     if( opt.def_compress_algo < 1 || opt.def_compress_algo > 2 )
821         log_error(_("compress algorithm must be in range %d..%d\n"), 1, 2);
822     if( opt.completes_needed < 1 )
823         log_error(_("completes-needed must be greater than 0\n"));
824     if( opt.marginals_needed < 2 )
825         log_error(_("marginals-needed must be greater than 1\n"));
826     if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
827         log_error(_("max-cert-depth must be in range 1 to 255\n"));
828     switch( opt.s2k_mode ) {
829       case 0:
830         log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
831         break;
832       case 1: case 3: break;
833       default:
834         log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
835     }
836
837     if( log_get_errorcount(0) )
838         g10_exit(2);
839
840     if( !cmd && opt.fingerprint )
841         set_cmd( &cmd, aListKeys);
842
843     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
844         if( cmd == aKModeC ) {
845             opt.fingerprint = 1;
846             cmd = aKMode;
847         }
848         opt.list_sigs = 0;
849         if( opt.verbose > 2 )
850             opt.check_sigs++;
851         if( opt.verbose > 1 )
852             opt.list_sigs++;
853
854         opt.verbose = opt.verbose > 1;
855         g10_opt_verbose = opt.verbose;
856     }
857
858
859     /* kludge to let -sat generate a clear text signature */
860     if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
861         cmd = aClearsign;
862
863     if( opt.verbose > 1 )
864         set_packet_list_mode(1);
865
866     /* add the keyrings, but not for some special commands and
867      * not in case of "-kvv userid keyring" */
868     if( cmd != aDeArmor && cmd != aEnArmor
869         && !(cmd == aKMode && argc == 2 ) ) {
870
871         if( !sec_nrings || default_keyring )  /* add default secret rings */
872             add_keyblock_resource("secring.gpg", 0, 1);
873         for(sl = sec_nrings; sl; sl = sl->next )
874             add_keyblock_resource( sl->d, 0, 1 );
875         if( !nrings || default_keyring )  /* add default ring */
876             add_keyblock_resource("pubring.gpg", 0, 0);
877         for(sl = nrings; sl; sl = sl->next )
878             add_keyblock_resource( sl->d, 0, 0 );
879     }
880     FREE_STRLIST(nrings);
881     FREE_STRLIST(sec_nrings);
882
883
884     if( pwfd != -1 )  /* read the passphrase now. */
885         read_passphrase_from_fd( pwfd );
886
887     fname = argc? *argv : NULL;
888
889     switch( cmd ) {
890       case aPrimegen:
891       case aPrintMD:
892       case aPrintMDs:
893       case aGenRandom:
894       case aDeArmor:
895       case aEnArmor:
896       case aFixTrustDB:
897         break;
898       case aKMode:
899       case aListKeys:
900       case aListSecretKeys:
901       case aCheckKeys:
902         if( opt.with_colons ) /* need this to list the trust */
903             rc = init_trustdb(1, trustdb_name );
904         break;
905       case aExportOwnerTrust: rc = init_trustdb( 0, trustdb_name ); break;
906       case aListTrustDB: rc = init_trustdb( argc? 1:0, trustdb_name ); break;
907       default: rc = init_trustdb(1, trustdb_name ); break;
908     }
909     if( rc )
910         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
911
912
913     switch( cmd ) {
914       case aStore: /* only store the file */
915         if( argc > 1 )
916             wrong_args(_("--store [filename]"));
917         if( (rc = encode_store(fname)) )
918             log_error_f( print_fname_stdin(fname),
919                         "store failed: %s\n", g10_errstr(rc) );
920         break;
921     #ifdef IS_G10
922       case aSym: /* encrypt the given file only with the symmetric cipher */
923         if( argc > 1 )
924             wrong_args(_("--symmetric [filename]"));
925         if( (rc = encode_symmetric(fname)) )
926             log_error_f(print_fname_stdin(fname),
927                         "symmetric encryption failed: %s\n",g10_errstr(rc) );
928         break;
929
930       case aEncr: /* encrypt the given file */
931         if( argc > 1 )
932             wrong_args(_("--encrypt [filename]"));
933         if( (rc = encode_crypt(fname,remusr)) )
934             log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
935         break;
936
937       case aSign: /* sign the given file */
938         sl = NULL;
939         if( detached_sig ) { /* sign all files */
940             for( ; argc; argc--, argv++ )
941                 add_to_strlist( &sl, *argv );
942         }
943         else {
944             if( argc > 1 )
945                 wrong_args(_("--sign [filename]"));
946             if( argc ) {
947                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
948                 strcpy(sl->d, fname);
949             }
950         }
951         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
952             log_error("signing failed: %s\n", g10_errstr(rc) );
953         free_strlist(sl);
954         break;
955
956       case aSignEncr: /* sign and encrypt the given file */
957         if( argc > 1 )
958             wrong_args(_("--sign --encrypt [filename]"));
959         if( argc ) {
960             sl = m_alloc_clear( sizeof *sl + strlen(fname));
961             strcpy(sl->d, fname);
962         }
963         else
964             sl = NULL;
965         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
966             log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
967         free_strlist(sl);
968         break;
969
970       case aClearsign: /* make a clearsig */
971         if( argc > 1 )
972             wrong_args(_("--clearsign [filename]"));
973         if( (rc = clearsign_file(fname, locusr, NULL)) )
974             log_error("%s: clearsign failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
975         break;
976
977       case aVerify:
978         if( (rc = verify_signatures( argc, argv ) ))
979             log_error("verify signatures failed: %s\n", g10_errstr(rc) );
980         break;
981
982       case aDecrypt:
983         if( argc > 1 )
984             wrong_args(_("--decrypt [filename]"));
985         if( (rc = decrypt_message( fname ) ))
986             log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
987         break;
988
989
990       case aSignKey: /* sign the key given as argument */
991       case aEditKey: /* Edit a key signature */
992         if( argc != 1 )
993             wrong_args(_("--edit-key username"));
994         keyedit_menu(fname, locusr );
995         break;
996
997       #endif /* IS_G10 */
998
999       case aDeleteSecretKey:
1000         if( argc != 1 )
1001             wrong_args(_("--delete-secret-key username"));
1002       case aDeleteKey:
1003         if( argc != 1 )
1004             wrong_args(_("--delete-key username"));
1005         /* note: fname is the user id! */
1006         if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) )
1007             log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
1008         break;
1009
1010
1011       case aCheckKeys:
1012         opt.check_sigs = 1;
1013       case aListSigs:
1014         opt.list_sigs = 1;
1015       case aListKeys:
1016         public_key_list( argc, argv );
1017         break;
1018       case aListSecretKeys:
1019         secret_key_list( argc, argv );
1020         break;
1021
1022       case aKMode: /* list keyring */
1023         if( argc < 2 )  /* -kv [userid] */
1024             public_key_list( (argc && **argv)? 1:0, argv );
1025         else if( argc == 2 ) { /* -kv userid keyring */
1026             if( access( argv[1], R_OK ) ) {
1027                 log_error(_("can't open %s: %s\n"),
1028                                print_fname_stdin(argv[1]), strerror(errno));
1029             }
1030             else {
1031                 /* add keyring (default keyrings are not registered in this
1032                  * special case */
1033                 add_keyblock_resource( argv[1], 0, 0 );
1034                 public_key_list( **argv?1:0, argv );
1035             }
1036         }
1037         else
1038             wrong_args(_("-k[v][v][v][c] [userid] [keyring]") );
1039         break;
1040
1041     #ifdef IS_G10
1042       case aKeygen: /* generate a key (interactive) */
1043         if( argc )
1044             wrong_args("--gen-key");
1045         generate_keypair();
1046         break;
1047     #endif
1048
1049       case aFastImport:
1050       case aImport:
1051         if( !argc  ) {
1052             rc = import_keys( NULL, (cmd == aFastImport) );
1053             if( rc )
1054                 log_error("import failed: %s\n", g10_errstr(rc) );
1055         }
1056         for( ; argc; argc--, argv++ ) {
1057             rc = import_keys( *argv, (cmd == aFastImport) );
1058             if( rc )
1059                 log_error("import from '%s' failed: %s\n",
1060                                                 *argv, g10_errstr(rc) );
1061         }
1062         break;
1063
1064       case aExport:
1065         sl = NULL;
1066         for( ; argc; argc--, argv++ )
1067             add_to_strlist( &sl, *argv );
1068         export_pubkeys( sl );
1069         free_strlist(sl);
1070         break;
1071
1072       case aExportSecret:
1073         sl = NULL;
1074         for( ; argc; argc--, argv++ )
1075             add_to_strlist( &sl, *argv );
1076         export_seckeys( sl );
1077         free_strlist(sl);
1078         break;
1079
1080     #ifdef IS_G10
1081       case aGenRevoke:
1082         if( argc != 1 )
1083             wrong_args("--gen-revoke user-id");
1084         gen_revoke( *argv );
1085         break;
1086     #endif
1087
1088     #ifdef IS_G10MAINT
1089       case aDeArmor:
1090         if( argc > 1 )
1091             wrong_args("--dearmor [file]");
1092         rc = dearmor_file( argc? *argv: NULL );
1093         if( rc )
1094             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
1095         break;
1096
1097       case aEnArmor:
1098         if( argc > 1 )
1099             wrong_args("--enarmor [file]");
1100         rc = enarmor_file( argc? *argv: NULL );
1101         if( rc )
1102             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
1103         break;
1104
1105
1106      #ifdef MAINTAINER_OPTIONS
1107       case aPrimegen:
1108         if( argc == 1 ) {
1109             mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1);
1110             putchar('\n');
1111         }
1112         else if( argc == 2 ) {
1113             mpi_print( stdout, generate_elg_prime( 0, atoi(argv[0]),
1114                                                    atoi(argv[1]), NULL,NULL ), 1);
1115             putchar('\n');
1116         }
1117         else if( argc == 3 ) {
1118             MPI g = mpi_alloc(1);
1119             mpi_print( stdout, generate_elg_prime( 0, atoi(argv[0]),
1120                                                    atoi(argv[1]), g, NULL ), 1);
1121             printf("\nGenerator: ");
1122             mpi_print( stdout, g, 1 );
1123             putchar('\n');
1124             mpi_free(g);
1125         }
1126         else if( argc == 4 ) {
1127             mpi_print( stdout, generate_elg_prime( 1, atoi(argv[0]),
1128                                                    atoi(argv[1]), NULL,NULL ), 1);
1129             putchar('\n');
1130         }
1131         else
1132             usage(1);
1133         break;
1134       #endif /* MAINTAINER OPTIONS */
1135
1136       #ifdef MAINTAINER_OPTIONS
1137       case aGenRandom:
1138         if( argc < 1 || argc > 2 )
1139             wrong_args("--gen-random level [hex]");
1140         {
1141             int level = atoi(*argv);
1142             for(;;) {
1143                 byte *p = get_random_bits( 8, level, 0);
1144                 if( argc == 1 ) {
1145                     printf("%02x", *p );
1146                     fflush(stdout);
1147                 }
1148                 else
1149                     putchar(c&0xff);
1150                 m_free(p);
1151             }
1152         }
1153         break;
1154       #endif /* MAINTAINER OPTIONS */
1155
1156       case aPrintMD:
1157         if( argc < 1)
1158             wrong_args("--print-md algo [file]");
1159         else {
1160             int algo = string_to_digest_algo(*argv);
1161
1162             if( !algo )
1163                 log_error(_("invalid hash algorithm '%s'\n"), *argv );
1164             else {
1165                 argc--; argv++;
1166                 if( !argc )
1167                     print_mds(NULL, algo);
1168                 else {
1169                     for(; argc; argc--, argv++ )
1170                         print_mds(*argv, algo);
1171                 }
1172             }
1173         }
1174         break;
1175
1176       case aPrintMDs:
1177         if( !argc )
1178             print_mds(NULL,0);
1179         else {
1180             for(; argc; argc--, argv++ )
1181                 print_mds(*argv,0);
1182         }
1183         break;
1184
1185      #ifdef MAINTAINER_OPTIONS
1186       case aTest: do_test( argc? atoi(*argv): 1 ); break;
1187       #endif /* MAINTAINER OPTIONS */
1188
1189       case aListTrustDB:
1190         if( !argc )
1191             list_trustdb(NULL);
1192         else {
1193             for( ; argc; argc--, argv++ )
1194                 list_trustdb( *argv );
1195         }
1196         break;
1197
1198       case aUpdateTrustDB:
1199         if( argc )
1200             wrong_args("--update-trustdb");
1201         update_trustdb();
1202         break;
1203
1204       case aCheckTrustDB:
1205         if( !argc )
1206             check_trustdb(NULL);
1207         else {
1208             for( ; argc; argc--, argv++ )
1209                 check_trustdb( *argv );
1210         }
1211         break;
1212
1213       case aFixTrustDB:
1214         log_error("this command ist not yet implemented.\"\n");
1215         log_error("A workaround is to use \"--export-ownertrust\", remove\n");
1216         log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
1217         break;
1218
1219       case aListTrustPath:
1220         if( argc != 2 )
1221             wrong_args("--list-trust-path [-- -]<maxdepth> <username>");
1222         list_trust_path( atoi(*argv), argv[1] );
1223         break;
1224
1225       case aExportOwnerTrust:
1226         if( argc )
1227             wrong_args("--export-ownertrust");
1228         export_ownertrust();
1229         break;
1230
1231       case aImportOwnerTrust:
1232         if( argc > 1 )
1233             wrong_args("--import-ownertrust [file]");
1234         import_ownertrust( argc? *argv:NULL );
1235         break;
1236
1237      #endif /* IS_G10MAINT */
1238
1239
1240       case aListPackets:
1241         opt.list_packets=1;
1242       default:
1243         /* fixme: g10maint should do regular maintenace tasks here */
1244         if( argc > 1 )
1245             wrong_args(_("[filename]"));
1246         /* Issue some output for the unix newbie */
1247         if( !fname && !opt.outfile && isatty( fileno(stdin) )
1248                 && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
1249             log_info(_("Go ahead and type your message ...\n"));
1250
1251         if( !(a = iobuf_open(fname)) )
1252             log_error(_("can't open '%s'\n"), print_fname_stdin(fname));
1253         else {
1254
1255             if( !opt.no_armor ) {
1256                 if( use_armor_filter( a ) ) {
1257                     memset( &afx, 0, sizeof afx);
1258                     iobuf_push_filter( a, armor_filter, &afx );
1259                 }
1260             }
1261             if( cmd == aListPackets ) {
1262                 set_packet_list_mode(1);
1263                 opt.list_packets=1;
1264             }
1265             proc_packets( a );
1266             iobuf_close(a);
1267         }
1268         break;
1269     }
1270
1271     /* cleanup */
1272     FREE_STRLIST(remusr);
1273     FREE_STRLIST(locusr);
1274     g10_exit(0);
1275     return 8; /*NEVER REACHED*/
1276 }
1277
1278
1279 void
1280 g10_exit( int rc )
1281 {
1282     if( opt.debug & DBG_MEMSTAT_VALUE )
1283         m_print_stats("on exit");
1284     if( opt.debug )
1285         secmem_dump_stats();
1286     secmem_term();
1287     rc = rc? rc : log_get_errorcount(0)? 2 :
1288                         g10_errors_seen? 1 : 0;
1289     /*write_status( STATUS_LEAVE );*/
1290     exit(rc );
1291 }
1292
1293
1294 void
1295 do_not_use_RSA()
1296 {
1297     static int did_rsa_note = 0;
1298
1299     if( !did_rsa_note ) {
1300         did_rsa_note = 1;
1301         log_info(_("RSA keys are deprecated; please consider "
1302                    "creating a new key and use this key in the future\n"));
1303     }
1304 }
1305
1306
1307 #ifdef IS_G10MAINT
1308 static void
1309 print_hex( byte *p, size_t n )
1310 {
1311     int i;
1312
1313     if( n == 20 ) {
1314         for(i=0; i < n ; i++, i++, p += 2 ) {
1315             if( i )
1316                 putchar(' ');
1317             if( i == 10 )
1318                 putchar(' ');
1319             printf("%02X%02X", *p, p[1] );
1320         }
1321     }
1322     else if( n == 24 ) {
1323         for(i=0; i < n ; i += 4, p += 4 ) {
1324             if( i )
1325                 putchar(' ');
1326             if( i == 12 )
1327                 putchar(' ');
1328             printf("%02X%02X%02X%02X", *p, p[1], p[2], p[3] );
1329         }
1330     }
1331     else {
1332         for(i=0; i < n ; i++, p++ ) {
1333             if( i )
1334                 putchar(' ');
1335             if( i && !(i%8) )
1336                 putchar(' ');
1337             printf("%02X", *p );
1338         }
1339     }
1340 }
1341
1342 static void
1343 print_mds( const char *fname, int algo )
1344 {
1345     FILE *fp;
1346     char buf[1024];
1347     size_t n;
1348     MD_HANDLE md;
1349     char *pname;
1350
1351     if( !fname ) {
1352         fp = stdin;
1353         pname = m_strdup("[stdin]: ");
1354     }
1355     else {
1356         pname = m_alloc(strlen(fname)+3);
1357         strcpy(stpcpy(pname,fname),": ");
1358         fp = fopen( fname, "rb" );
1359     }
1360     if( !fp ) {
1361         log_error("%s%s\n", pname, strerror(errno) );
1362         m_free(pname);
1363         return;
1364     }
1365
1366     md = md_open( 0, 0 );
1367     if( algo )
1368         md_enable( md, algo );
1369     else {
1370         md_enable( md, DIGEST_ALGO_MD5 );
1371         md_enable( md, DIGEST_ALGO_SHA1 );
1372         md_enable( md, DIGEST_ALGO_RMD160 );
1373         if( !check_digest_algo(DIGEST_ALGO_TIGER) )
1374             md_enable( md, DIGEST_ALGO_TIGER );
1375     }
1376
1377     while( (n=fread( buf, 1, DIM(buf), fp )) )
1378         md_write( md, buf, n );
1379     if( ferror(fp) )
1380         log_error("%s%s\n", pname, strerror(errno) );
1381     else {
1382         md_final(md);
1383         if( algo ) {
1384             if( fname )
1385                 fputs( pname, stdout );
1386             print_hex(md_read(md, algo), md_digest_length(algo) );
1387         }
1388         else {
1389             printf(  "%s   MD5 = ", fname?pname:"" );
1390                             print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
1391             printf("\n%s  SHA1 = ", fname?pname:""  );
1392                             print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
1393             printf("\n%sRMD160 = ", fname?pname:""  );
1394                             print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
1395             if( !check_digest_algo(DIGEST_ALGO_TIGER) ) {
1396                 printf("\n%s TIGER = ", fname?pname:""  );
1397                             print_hex(md_read(md, DIGEST_ALGO_TIGER), 24 );
1398             }
1399         }
1400         putchar('\n');
1401     }
1402     md_close(md);
1403
1404     if( fp != stdin )
1405         fclose(fp);
1406 }
1407
1408
1409
1410 #ifdef MAINTAINER_OPTIONS
1411 static void
1412 do_test(int times)
1413 {
1414     m_check(NULL);
1415 }
1416 #endif /* MAINTAINER OPTIONS */
1417 #endif /* IS_G10MAINT */
1418