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