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