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