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