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