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