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