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