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