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