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