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