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