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