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