2a17214d9e3929f50304eb3a5819ae4daa80d4ad
[gnupg.git] / g10 / g10.c
1 /* g10.c - The GnuPG utility (main for gpg)
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
3  *               2004 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <unistd.h>
29 #include <assert.h>
30 #ifdef HAVE_DOSISH_SYSTEM
31 #include <fcntl.h> /* for setmode() */
32 #endif
33 #ifdef HAVE_STAT
34 #include <sys/stat.h> /* for stat() */
35 #endif
36 #include <fcntl.h>
37
38 #define INCLUDED_BY_MAIN_MODULE 1
39 #include "packet.h"
40 #include "iobuf.h"
41 #include "memory.h"
42 #include "util.h"
43 #include "main.h"
44 #include "options.h"
45 #include "keydb.h"
46 #include "trustdb.h"
47 #include "mpi.h"
48 #include "cipher.h"
49 #include "filter.h"
50 #include "ttyio.h"
51 #include "i18n.h"
52 #include "status.h"
53 #include "g10defs.h"
54 #include "keyserver-internal.h"
55 #include "exec.h"
56 #include "cardglue.h"
57 #ifdef ENABLE_CARD_SUPPORT
58 #include "ccid-driver.h"
59 #endif
60
61 #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
62 #define MY_O_BINARY  O_BINARY
63 #ifndef S_IRGRP
64 # define S_IRGRP 0
65 # define S_IWGRP 0
66 #endif
67 #else
68 #define MY_O_BINARY  0
69 #endif
70
71
72 enum cmd_and_opt_values
73   {
74     aNull = 0,
75     oArmor        = 'a',
76     aDetachedSign = 'b',
77     aSym          = 'c',
78     aDecrypt      = 'd',
79     aEncr         = 'e',
80     oInteractive  = 'i',
81     oKOption      = 'k',
82     oDryRun       = 'n',
83     oOutput       = 'o',
84     oQuiet        = 'q',
85     oRecipient    = 'r',
86     oHiddenRecipient = 'R',
87     aSign         = 's',
88     oTextmodeShort= 't',
89     oUser         = 'u',
90     oVerbose      = 'v',
91     oCompress     = 'z',
92     oSetNotation  = 'N',
93     aListSecretKeys = 'K',
94     oBatch        = 500,
95     oMaxOutput,
96     oSigNotation,
97     oCertNotation,
98     oShowNotation,
99     oNoShowNotation,
100     aEncrFiles,
101     aEncrSym,
102     aDecryptFiles,
103     aClearsign,
104     aStore,
105     aKeygen,
106     aSignEncr,
107     aSignEncrSym,
108     aSignSym,
109     aSignKey,
110     aLSignKey,
111     aNRSignKey,
112     aNRLSignKey,
113     aListConfig,
114     aGPGConfList,
115     aListPackets,
116     aEditKey,
117     aDeleteKeys,
118     aDeleteSecretKeys,
119     aDeleteSecretAndPublicKeys,
120     aKMode,
121     aKModeC,
122     aImport,
123     aFastImport,
124     aVerify,
125     aVerifyFiles,
126     aListKeys,
127     aListSigs,
128     aSendKeys,
129     aRecvKeys,
130     aSearchKeys,
131     aExport,
132     aExportSecret,
133     aExportSecretSub,
134     aCheckKeys,
135     aGenRevoke,
136     aDesigRevoke,
137     aPrimegen,
138     aPrintMD,
139     aPrintMDs,
140     aCheckTrustDB,
141     aUpdateTrustDB,
142     aFixTrustDB,
143     aListTrustDB,
144     aListTrustPath,
145     aExportOwnerTrust,
146     aListOwnerTrust,
147     aImportOwnerTrust,
148     aDeArmor,
149     aEnArmor,
150     aGenRandom,
151     aPipeMode,
152     aRebuildKeydbCaches,
153     aRefreshKeys,
154     aCardStatus,
155     aCardEdit,
156     aChangePIN,
157
158     oTextmode,
159     oNoTextmode,
160     oExpert,
161     oNoExpert,
162     oAskSigExpire,
163     oNoAskSigExpire,
164     oAskCertExpire,
165     oNoAskCertExpire,
166     oAskCertLevel,
167     oNoAskCertLevel,
168     oFingerprint,
169     oWithFingerprint,
170     oAnswerYes,
171     oAnswerNo,
172     oDefCertLevel,
173     oMinCertLevel,
174     oKeyring,
175     oPrimaryKeyring,
176     oSecretKeyring,
177     oShowKeyring,
178     oDefaultKey,
179     oDefRecipient,
180     oDefRecipientSelf,
181     oNoDefRecipient,
182     oOptions,
183     oDebug,
184     oDebugAll,
185     oDebugCCIDDriver,
186     oStatusFD,
187     oStatusFile,
188     oAttributeFD,
189     oAttributeFile,
190     oSKComments,
191     oNoSKComments,
192     oEmitVersion,
193     oNoEmitVersion,
194     oCompletesNeeded,
195     oMarginalsNeeded,
196     oMaxCertDepth,
197     oLoadExtension,
198     oGnuPG,
199     oRFC1991,
200     oRFC2440,
201     oOpenPGP,
202     oPGP2,
203     oPGP6,
204     oPGP7,
205     oPGP8,
206     oCipherAlgo,
207     oDigestAlgo,
208     oCertDigestAlgo,
209     oCompressAlgo,
210     oCompressLevel,
211     oBZ2CompressLevel,
212     oBZ2DecompressLowmem,
213     oPasswdFD,
214     oPasswdFile,
215     oCommandFD,
216     oCommandFile,
217     oQuickRandom,
218     oNoVerbose,
219     oTrustDBName,
220     oNoSecmemWarn,
221     oNoPermissionWarn,
222     oNoMDCWarn,
223     oNoArmor,
224     oNoDefKeyring,
225     oNoGreeting,
226     oNoTTY,
227     oNoOptions,
228     oNoBatch,
229     oHomedir,
230     oWithColons,
231     oWithKeyData,
232     oSkipVerify,
233     oCompressKeys,
234     oCompressSigs,
235     oAlwaysTrust,
236     oTrustModel,
237     oForceOwnertrust,
238     oRunAsShmCP,
239     oSetFilename,
240     oForYourEyesOnly,
241     oNoForYourEyesOnly,
242     oSetPolicyURL,
243     oSigPolicyURL,
244     oCertPolicyURL,
245     oShowPolicyURL,
246     oNoShowPolicyURL,
247     oSigKeyserverURL,
248     oUseEmbeddedFilename,
249     oNoUseEmbeddedFilename,
250     oComment,
251     oDefaultComment,
252     oNoComments,
253     oThrowKeyids,
254     oNoThrowKeyids,
255     oShowPhotos,
256     oNoShowPhotos,
257     oPhotoViewer,
258     oForceV3Sigs,
259     oNoForceV3Sigs,
260     oForceV4Certs,
261     oNoForceV4Certs,
262     oForceMDC,
263     oNoForceMDC,
264     oDisableMDC,
265     oNoDisableMDC,
266     oS2KMode,
267     oS2KDigest,
268     oS2KCipher,
269     oSimpleSKChecksum,                          
270     oDisplayCharset,
271     oNotDashEscaped,
272     oEscapeFrom,
273     oNoEscapeFrom,
274     oLockOnce,
275     oLockMultiple,
276     oLockNever,
277     oKeyServer,
278     oKeyServerOptions,
279     oImportOptions,
280     oExportOptions,
281     oListOptions,
282     oVerifyOptions,
283     oTempDir,
284     oExecPath,
285     oEncryptTo,
286     oHiddenEncryptTo,
287     oNoEncryptTo,
288     oLoggerFD,
289     oLoggerFile,
290     oUtf8Strings,
291     oNoUtf8Strings,
292     oDisableCipherAlgo,
293     oDisablePubkeyAlgo,
294     oAllowNonSelfsignedUID,
295     oNoAllowNonSelfsignedUID,
296     oAllowFreeformUID,
297     oNoAllowFreeformUID,
298     oAllowSecretKeyImport,                      
299     oEnableSpecialFilenames,
300     oNoLiteral,
301     oSetFilesize,
302     oHonorHttpProxy,
303     oFastListMode,
304     oListOnly,
305     oIgnoreTimeConflict,
306     oIgnoreValidFrom,
307     oIgnoreCrcError,
308     oIgnoreMDCError,
309     oShowSessionKey,
310     oOverrideSessionKey,
311     oNoRandomSeedFile,
312     oAutoKeyRetrieve,
313     oNoAutoKeyRetrieve,
314     oUseAgent,
315     oNoUseAgent,
316     oGpgAgentInfo,
317     oMergeOnly,
318     oTryAllSecrets,
319     oTrustedKey,
320     oNoExpensiveTrustChecks,
321     oFixedListMode,
322     oNoSigCache,
323     oNoSigCreateCheck,
324     oAutoCheckTrustDB,
325     oNoAutoCheckTrustDB,
326     oPreservePermissions,
327     oDefaultPreferenceList,
328     oPersonalCipherPreferences,
329     oPersonalDigestPreferences,
330     oPersonalCompressPreferences,
331     oDisplay,
332     oTTYname,
333     oTTYtype,
334     oLCctype,
335     oLCmessages,
336     oGroup,
337     oUnGroup,
338     oNoGroups,
339     oStrict,
340     oNoStrict,
341     oMangleDosFilenames,
342     oNoMangleDosFilenames,
343     oEnableProgressFilter,
344     oMultifile,
345     oKeyidFormat,
346
347     oReaderPort,
348     octapiDriver,
349     opcscDriver,
350     oDisableCCID,
351
352     aTest
353   };
354
355
356 static ARGPARSE_OPTS opts[] = {
357
358     { 300, NULL, 0, N_("@Commands:\n ") },
359
360     { aSign, "sign",      256, N_("|[file]|make a signature")},
361     { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature")},
362     { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
363     { aEncr, "encrypt",   256, N_("encrypt data")},
364     { aEncrFiles, "encrypt-files", 256, "@"},
365     { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
366     { aStore, "store",     256, "@"},
367     { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
368     { aDecryptFiles, "decrypt-files", 256, "@"},
369     { aVerify, "verify"   , 256, N_("verify a signature")},
370     { aVerifyFiles, "verify-files" , 256, "@" },
371     { aListKeys, "list-keys", 256, N_("list keys")},
372     { aListKeys, "list-public-keys", 256, "@" },
373     { aListSigs, "list-sigs", 256, N_("list keys and signatures")},
374     { aCheckKeys, "check-sigs",256, N_("list and check key signatures")},
375     { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
376     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
377     { aKeygen,     "gen-key",  256, N_("generate a new key pair")},
378     { aDeleteKeys,"delete-keys",256,N_("remove keys from the public keyring")},
379     { aDeleteSecretKeys, "delete-secret-keys",256,
380                                     N_("remove keys from the secret keyring")},
381     { aSignKey,  "sign-key"   ,256, N_("sign a key")},
382     { aLSignKey, "lsign-key"  ,256, N_("sign a key locally")},
383     { aNRSignKey, "nrsign-key"  ,256, "@"},
384     { aNRLSignKey, "nrlsign-key"  ,256, "@"},
385     { aEditKey,  "edit-key"   ,256, N_("sign or edit a key")},
386     { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
387     { aDesigRevoke, "desig-revoke",256, "@" },
388     { aExport, "export"           , 256, N_("export keys") },
389     { aSendKeys, "send-keys"     , 256, N_("export keys to a key server") },
390     { aRecvKeys, "recv-keys"     , 256, N_("import keys from a key server") },
391     { aSearchKeys, "search-keys" , 256,
392                                     N_("search for keys on a key server") },
393     { aRefreshKeys, "refresh-keys", 256,
394                                     N_("update all keys from a keyserver")},
395     { aExportSecret, "export-secret-keys" , 256, "@" },
396     { aExportSecretSub, "export-secret-subkeys" , 256, "@" },
397     { aImport, "import",      256     , N_("import/merge keys")},
398     { aFastImport, "fast-import",  256 , "@"},
399 #ifdef ENABLE_CARD_SUPPORT
400     { aCardStatus,  "card-status", 256, N_("print the card status")},
401     { aCardEdit,   "card-edit",  256, N_("change data on a card")},
402     { aChangePIN,  "change-pin", 256, N_("change a card's PIN")},
403 #endif
404     { aListConfig, "list-config", 256, "@"},
405     { aGPGConfList, "gpgconf-list", 256, "@" },
406     { aListPackets, "list-packets",256, "@"},
407     { aExportOwnerTrust, "export-ownertrust", 256, "@"},
408     { aImportOwnerTrust, "import-ownertrust", 256, "@"},
409     { aUpdateTrustDB,
410               "update-trustdb",0 , N_("update the trust database")},
411     { aCheckTrustDB, "check-trustdb", 0, "@"},
412     { aFixTrustDB, "fix-trustdb", 0, "@"},
413     { aDeArmor, "dearmor", 256, "@"},
414     { aDeArmor, "dearmour", 256, "@"},
415     { aEnArmor, "enarmor", 256, "@"},
416     { aEnArmor, "enarmour", 256, "@"},
417     { aPrintMD,  "print-md" , 256, N_("|algo [files]|print message digests")},
418     { aPrimegen, "gen-prime" , 256, "@" },
419     { aGenRandom, "gen-random" , 256, "@" },
420
421     { 301, NULL, 0, N_("@\nOptions:\n ") },
422
423     { oArmor, "armor",     0, N_("create ascii armored output")},
424     { oArmor, "armour",     0, "@" },
425     { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
426     { oHiddenRecipient, "hidden-recipient", 2, "@" },
427     { oRecipient, "remote-user", 2, "@"},  /* old option name */
428     { oDefRecipient, "default-recipient", 2, "@"},
429     { oDefRecipientSelf, "default-recipient-self", 0, "@"},
430     { oNoDefRecipient, "no-default-recipient", 0, "@" },
431     { oTempDir, "temp-directory", 2, "@" },
432     { oExecPath, "exec-path", 2, "@" },
433     { oEncryptTo, "encrypt-to", 2, "@" },
434     { oHiddenEncryptTo, "hidden-encrypt-to", 2, "@" },
435     { oNoEncryptTo, "no-encrypt-to", 0, "@" },
436     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
437     { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") },
438     { oCompressLevel, "compress-level", 1, "@" },
439     { oBZ2CompressLevel, "bzip2-compress-level", 1, "@" },
440     { oBZ2DecompressLowmem, "bzip2-decompress-lowmem", 0, "@" },
441     { oTextmodeShort, NULL,   0, "@"},
442     { oTextmode, "textmode",  0, N_("use canonical text mode")},
443     { oNoTextmode, "no-textmode",  0, "@"},
444     { oExpert, "expert",   0, "@"},
445     { oNoExpert, "no-expert",   0, "@"},
446     { oAskSigExpire, "ask-sig-expire",   0, "@"},
447     { oNoAskSigExpire, "no-ask-sig-expire",   0, "@"},
448     { oAskCertExpire, "ask-cert-expire",   0, "@"},
449     { oNoAskCertExpire, "no-ask-cert-expire",   0, "@"},
450     { oAskCertLevel, "ask-cert-level",   0, "@"},
451     { oNoAskCertLevel, "no-ask-cert-level",   0, "@"},
452     { oOutput, "output",    2, N_("use as output file")},
453     { oMaxOutput, "max-output", 16|4, "@" },
454     { oVerbose, "verbose",   0, N_("verbose") },
455     { oQuiet,   "quiet",   0, "@"},
456     { oNoTTY, "no-tty", 0, "@"},
457     { oForceV3Sigs, "force-v3-sigs", 0, "@"},
458     { oNoForceV3Sigs, "no-force-v3-sigs", 0, "@"},
459     { oForceV4Certs, "force-v4-certs", 0, "@"},
460     { oNoForceV4Certs, "no-force-v4-certs", 0, "@"},
461     { oForceMDC, "force-mdc", 0, "@"},
462     { oNoForceMDC, "no-force-mdc", 0, "@" },
463     { oDisableMDC, "disable-mdc", 0, "@"},
464     { oNoDisableMDC, "no-disable-mdc", 0, "@" },
465     { oDryRun, "dry-run",   0, N_("do not make any changes") },
466     { oInteractive, "interactive", 0, N_("prompt before overwriting") },
467     { oUseAgent, "use-agent",0, "@"},
468     { oNoUseAgent, "no-use-agent",0, "@"},
469     { oGpgAgentInfo, "gpg-agent-info",2, "@"},
470     { oBatch, "batch", 0, "@"},
471     { oAnswerYes, "yes", 0, "@"},
472     { oAnswerNo, "no", 0, "@"},
473     { oKeyring, "keyring", 2, "@"},
474     { oPrimaryKeyring, "primary-keyring",2, "@" },
475     { oSecretKeyring, "secret-keyring", 2, "@"},
476     { oShowKeyring, "show-keyring", 0, "@"},
477     { oDefaultKey, "default-key", 2, "@"},
478     { oKeyServer, "keyserver", 2, "@"},
479     { oKeyServerOptions, "keyserver-options",2,"@"},
480     { oImportOptions, "import-options",2,"@"},
481     { oExportOptions, "export-options",2,"@"},
482     { oListOptions, "list-options",2,"@"},
483     { oVerifyOptions, "verify-options",2,"@"},
484     { oDisplayCharset, "display-charset", 2, "@"},
485     { oDisplayCharset, "charset", 2, "@"},
486     { oOptions, "options", 2, "@"},
487     { oDebug, "debug"     ,4|16, "@"},
488     { oDebugAll, "debug-all" ,0, "@"},
489     { oStatusFD, "status-fd" ,1, "@"},
490     { oStatusFile, "status-file" ,2, "@"},
491     { oAttributeFD, "attribute-fd" ,1, "@" },
492     { oAttributeFile, "attribute-file" ,2, "@" },
493     { oNoSKComments, "no-sk-comments", 0,   "@"},
494     { oSKComments, "sk-comments", 0,   "@"},
495     { oCompletesNeeded, "completes-needed", 1, "@"},
496     { oMarginalsNeeded, "marginals-needed", 1, "@"},
497     { oMaxCertDepth,    "max-cert-depth", 1, "@" },
498     { oTrustedKey, "trusted-key", 2, "@"},
499     { oLoadExtension, "load-extension", 2, "@"},
500     { oGnuPG, "gnupg",   0, "@"},
501     { oGnuPG, "no-pgp2", 0, "@"},
502     { oGnuPG, "no-pgp6", 0, "@"},
503     { oGnuPG, "no-pgp7", 0, "@"},
504     { oGnuPG, "no-pgp8", 0, "@"},
505     { oRFC1991, "rfc1991",   0, "@"},
506     { oRFC2440, "rfc2440", 0, "@" },
507     { oOpenPGP, "openpgp", 0, N_("use strict OpenPGP behavior")},
508     { oPGP2, "pgp2", 0, N_("generate PGP 2.x compatible messages")},
509     { oPGP6, "pgp6", 0, "@"},
510     { oPGP7, "pgp7", 0, "@"},
511     { oPGP8, "pgp8", 0, "@"},
512     { oS2KMode, "s2k-mode", 1, "@"},
513     { oS2KDigest, "s2k-digest-algo", 2, "@"},
514     { oS2KCipher, "s2k-cipher-algo", 2, "@"},
515     { oSimpleSKChecksum, "simple-sk-checksum", 0, "@"},
516     { oCipherAlgo, "cipher-algo", 2, "@"},
517     { oDigestAlgo, "digest-algo", 2, "@"},
518     { oCertDigestAlgo, "cert-digest-algo", 2 , "@" },
519     { oCompressAlgo,"compress-algo", 2, "@"},
520     { oThrowKeyids, "throw-keyid", 0, "@"},
521     { oThrowKeyids, "throw-keyids", 0, "@"},
522     { oNoThrowKeyids, "no-throw-keyid", 0, "@" },
523     { oNoThrowKeyids, "no-throw-keyids", 0, "@" },
524     { oShowPhotos,   "show-photos", 0, "@" },
525     { oNoShowPhotos, "no-show-photos", 0, "@" },
526     { oPhotoViewer,  "photo-viewer", 2, "@" },
527     { oSetNotation,  "set-notation", 2, "@" },
528     { oSetNotation,  "notation-data", 2, "@" }, /* Alias */
529     { oSigNotation,  "sig-notation", 2, "@" },
530     { oCertNotation, "cert-notation", 2, "@" },
531
532     { 302, NULL, 0, N_(
533   "@\n(See the man page for a complete listing of all commands and options)\n"
534                       )},
535
536     { 303, NULL, 0, N_("@\nExamples:\n\n"
537     " -se -r Bob [file]          sign and encrypt for user Bob\n"
538     " --clearsign [file]         make a clear text signature\n"
539     " --detach-sign [file]       make a detached signature\n"
540     " --list-keys [names]        show keys\n"
541     " --fingerprint [names]      show fingerprints\n"  ) },
542
543   /* hidden options */
544     { aListOwnerTrust, "list-ownertrust", 256, "@"}, /* deprecated */
545     { oCompressAlgo, "compression-algo", 1, "@"}, /* alias */
546     { aPrintMDs, "print-mds" , 256, "@"}, /* old */
547     { aListTrustDB, "list-trustdb",0 , "@"},
548     /* Not yet used */
549     /* { aListTrustPath, "list-trust-path",0, "@"}, */
550     { aPipeMode,  "pipemode", 0, "@" },
551     { oKOption, NULL,    0, "@"},
552     { oPasswdFD, "passphrase-fd",1, "@" },
553     { oPasswdFile, "passphrase-file",2, "@" },
554     { oCommandFD, "command-fd",1, "@" },
555     { oCommandFile, "command-file",2, "@" },
556     { oQuickRandom, "quick-random", 0, "@"},
557     { oNoVerbose, "no-verbose", 0, "@"},
558     { oTrustDBName, "trustdb-name", 2, "@" },
559     { oNoSecmemWarn, "no-secmem-warning", 0, "@" },
560     { oNoPermissionWarn, "no-permission-warning", 0, "@" },
561     { oNoMDCWarn, "no-mdc-warning", 0, "@" },
562     { oNoArmor, "no-armor",   0, "@"},
563     { oNoArmor, "no-armour",   0, "@"},
564     { oNoDefKeyring, "no-default-keyring", 0, "@" },
565     { oNoGreeting, "no-greeting", 0, "@" },
566     { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
567     { oHomedir, "homedir", 2, "@" },   /* defaults to "~/.gnupg" */
568     { oNoBatch, "no-batch", 0, "@" },
569     { oWithColons, "with-colons", 0, "@"},
570     { oWithKeyData,"with-key-data", 0, "@"},
571     { aListKeys, "list-key", 0, "@" }, /* alias */
572     { aListSigs, "list-sig", 0, "@" }, /* alias */
573     { aCheckKeys, "check-sig",0, "@" }, /* alias */
574     { oSkipVerify, "skip-verify",0, "@" },
575     { oCompressKeys, "compress-keys",0, "@"},
576     { oCompressSigs, "compress-sigs",0, "@"},
577     { oDefCertLevel, "default-cert-check-level", 1, "@"}, /* Old option */
578     { oDefCertLevel, "default-cert-level", 1, "@"},
579     { oMinCertLevel, "min-cert-level", 1, "@"},
580     { oAlwaysTrust, "always-trust", 0, "@"},
581     { oTrustModel, "trust-model", 2, "@"},
582     { oForceOwnertrust, "force-ownertrust", 2, "@"},
583     { oRunAsShmCP, "run-as-shm-coprocess", 4, "@" },
584     { oSetFilename, "set-filename", 2, "@" },
585     { oForYourEyesOnly, "for-your-eyes-only", 0, "@" },
586     { oNoForYourEyesOnly, "no-for-your-eyes-only", 0, "@" },
587     { oSetPolicyURL, "set-policy-url", 2, "@" },
588     { oSigPolicyURL, "sig-policy-url", 2, "@" },
589     { oCertPolicyURL, "cert-policy-url", 2, "@" },
590     { oShowPolicyURL, "show-policy-url", 0, "@" },
591     { oNoShowPolicyURL, "no-show-policy-url", 0, "@" },
592     { oSigKeyserverURL, "sig-keyserver-url", 2, "@" },
593     { oShowNotation, "show-notation", 0, "@" },
594     { oNoShowNotation, "no-show-notation", 0, "@" },
595     { oComment, "comment", 2, "@" },
596     { oDefaultComment, "default-comment", 0, "@" },
597     { oNoComments, "no-comments", 0, "@" },
598     { oEmitVersion, "emit-version", 0, "@"},
599     { oNoEmitVersion, "no-emit-version", 0, "@"},
600     { oNoEmitVersion, "no-version", 0, "@"}, /* alias */
601     { oNotDashEscaped, "not-dash-escaped", 0, "@" },
602     { oEscapeFrom, "escape-from-lines", 0, "@" },
603     { oNoEscapeFrom, "no-escape-from-lines", 0, "@" },
604     { oLockOnce, "lock-once", 0, "@" },
605     { oLockMultiple, "lock-multiple", 0, "@" },
606     { oLockNever, "lock-never", 0, "@" },
607     { oLoggerFD, "logger-fd",1, "@" },
608     { oLoggerFile, "logger-file",2, "@" },
609     { oUseEmbeddedFilename, "use-embedded-filename", 0, "@" },
610     { oNoUseEmbeddedFilename, "no-use-embedded-filename", 0, "@" },
611     { oUtf8Strings, "utf8-strings", 0, "@" },
612     { oNoUtf8Strings, "no-utf8-strings", 0, "@" },
613     { oWithFingerprint, "with-fingerprint", 0, "@" },
614     { oDisableCipherAlgo,  "disable-cipher-algo", 2, "@" },
615     { oDisablePubkeyAlgo,  "disable-pubkey-algo", 2, "@" },
616     { oAllowNonSelfsignedUID, "allow-non-selfsigned-uid", 0, "@" },
617     { oNoAllowNonSelfsignedUID, "no-allow-non-selfsigned-uid", 0, "@" },
618     { oAllowFreeformUID, "allow-freeform-uid", 0, "@" },
619     { oNoAllowFreeformUID, "no-allow-freeform-uid", 0, "@" },
620     { oNoLiteral, "no-literal", 0, "@" },
621     { oSetFilesize, "set-filesize", 20, "@" },
622     { oHonorHttpProxy,"honor-http-proxy", 0, "@" },
623     { oFastListMode,"fast-list-mode", 0, "@" },
624     { oFixedListMode,"fixed-list-mode", 0, "@" },
625     { oListOnly, "list-only", 0, "@"},
626     { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
627     { oIgnoreValidFrom,    "ignore-valid-from",    0, "@" },
628     { oIgnoreCrcError, "ignore-crc-error", 0,"@" },
629     { oIgnoreMDCError, "ignore-mdc-error", 0,"@" },
630     { oShowSessionKey, "show-session-key", 0, "@" },
631     { oOverrideSessionKey, "override-session-key", 2, "@" },
632     { oNoRandomSeedFile,  "no-random-seed-file", 0, "@" },
633     { oAutoKeyRetrieve, "auto-key-retrieve", 0, "@" },
634     { oNoAutoKeyRetrieve, "no-auto-key-retrieve", 0, "@" },
635     { oNoSigCache,         "no-sig-cache", 0, "@" },
636     { oNoSigCreateCheck,   "no-sig-create-check", 0, "@" },
637     { oAutoCheckTrustDB, "auto-check-trustdb", 0, "@"},
638     { oNoAutoCheckTrustDB, "no-auto-check-trustdb", 0, "@"},
639     { oMergeOnly,         "merge-only", 0, "@" },
640     { oAllowSecretKeyImport, "allow-secret-key-import", 0, "@" },
641     { oTryAllSecrets,  "try-all-secrets", 0, "@" },
642     { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" },
643     { oNoExpensiveTrustChecks, "no-expensive-trust-checks", 0, "@" },
644     { aDeleteSecretAndPublicKeys, "delete-secret-and-public-keys",256, "@" },
645     { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"},
646     { oPreservePermissions, "preserve-permissions", 0, "@"},
647     { oDefaultPreferenceList,  "default-preference-list", 2, "@"},
648     { oPersonalCipherPreferences,  "personal-cipher-preferences", 2, "@"},
649     { oPersonalDigestPreferences,  "personal-digest-preferences", 2, "@"},
650     { oPersonalCompressPreferences,  "personal-compress-preferences", 2, "@"},
651     /* Aliases.  I constantly mistype these, and assume other people
652        do as well. */
653     { oPersonalCipherPreferences, "personal-cipher-prefs", 2, "@"},
654     { oPersonalDigestPreferences, "personal-digest-prefs", 2, "@"},
655     { oPersonalCompressPreferences, "personal-compress-prefs", 2, "@"},
656     { oDisplay,    "display",     2, "@" },
657     { oTTYname,    "ttyname",     2, "@" },
658     { oTTYtype,    "ttytype",     2, "@" },
659     { oLCctype,    "lc-ctype",    2, "@" },
660     { oLCmessages, "lc-messages", 2, "@" },
661     { oGroup,      "group",       2, "@" },
662     { oUnGroup,    "ungroup",     2, "@" },
663     { oNoGroups,   "no-groups",    0, "@" },
664     { oStrict,     "strict",      0, "@" },
665     { oNoStrict,   "no-strict",   0, "@" },
666     { oMangleDosFilenames, "mangle-dos-filenames", 0, "@" },
667     { oNoMangleDosFilenames, "no-mangle-dos-filenames", 0, "@" },
668     { oEnableProgressFilter, "enable-progress-filter", 0, "@" },
669     { oMultifile, "multifile", 0, "@" },
670     { oKeyidFormat, "keyid-format", 2, "@" },
671
672     { oReaderPort, "reader-port",    2, "@"},
673     { octapiDriver, "ctapi-driver",  2, "@"},
674     { opcscDriver, "pcsc-driver",    2, "@"},
675     { oDisableCCID, "disable-ccid", 0, "@"},
676 #if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB)
677     { oDebugCCIDDriver, "debug-ccid-driver", 0, "@"},
678 #endif
679
680     {0,NULL,0,NULL}
681 };
682
683
684 #ifdef ENABLE_SELINUX_HACKS
685 #define ALWAYS_ADD_KEYRINGS 1
686 #else
687 #define ALWAYS_ADD_KEYRINGS 0
688 #endif
689
690
691 int g10_errors_seen = 0;
692
693 static int utf8_strings = 0;
694 static int maybe_setuid = 1;
695
696 static char *build_list( const char *text, char letter,
697                          const char *(*mapf)(int), int (*chkf)(int) );
698 static void set_cmd( enum cmd_and_opt_values *ret_cmd,
699                         enum cmd_and_opt_values new_cmd );
700 static void print_mds( const char *fname, int algo );
701 static void add_notation_data( const char *string, int which );
702 static void add_policy_url( const char *string, int which );
703 static void add_keyserver_url( const char *string, int which );
704
705 const char *
706 strusage( int level )
707 {
708   static char *digests, *pubkeys, *ciphers, *zips;
709     const char *p;
710     switch( level ) {
711       case 11: p = "gpg (GnuPG)";
712         break;
713       case 13: p = VERSION; break;
714       case 17: p = PRINTABLE_OS_NAME; break;
715       case 19: p =
716             _("Please report bugs to <gnupg-bugs@gnu.org>.\n");
717         break;
718
719 #ifdef IS_DEVELOPMENT_VERSION
720       case 20:
721         p="NOTE: THIS IS A DEVELOPMENT VERSION!";
722         break;
723       case 21:
724         p="It is only intended for test purposes and should NOT be";
725         break;
726       case 22:
727         p="used in a production environment or with production keys!";
728         break;
729 #endif
730
731       case 1:
732       case 40:  p =
733             _("Usage: gpg [options] [files] (-h for help)");
734         break;
735       case 41:  p =
736             _("Syntax: gpg [options] [files]\n"
737               "sign, check, encrypt or decrypt\n"
738               "default operation depends on the input data\n");
739         break;
740
741       case 31: p = "\nHome: "; break;
742 #ifndef __riscos__
743       case 32: p = opt.homedir; break;
744 #else /* __riscos__ */
745       case 32: p = make_filename(opt.homedir, NULL); break;
746 #endif /* __riscos__ */
747       case 33: p = _("\nSupported algorithms:\n"); break;
748       case 34:
749         if( !pubkeys )
750             pubkeys = build_list(_("Pubkey: "), 0, pubkey_algo_to_string,
751                                                         check_pubkey_algo );
752         p = pubkeys;
753         break;
754       case 35:
755         if( !ciphers )
756             ciphers = build_list(_("Cipher: "), 'S', cipher_algo_to_string,
757                                                         check_cipher_algo );
758         p = ciphers;
759         break;
760       case 36:
761         if( !digests )
762             digests = build_list(_("Hash: "), 'H', digest_algo_to_string,
763                                                         check_digest_algo );
764         p = digests;
765         break;
766       case 37:
767         if( !zips )
768             zips = build_list(_("Compression: "),'Z',compress_algo_to_string,
769                                                         check_compress_algo);
770         p = zips;
771         break;
772
773       default:  p = default_strusage(level);
774     }
775     return p;
776 }
777
778
779 static char *
780 build_list( const char *text, char letter,
781             const char * (*mapf)(int), int (*chkf)(int) )
782 {
783     int i;
784     const char *s;
785     size_t n=strlen(text)+2;
786     char *list, *p, *line=NULL;
787
788     if( maybe_setuid )
789         secmem_init( 0 );    /* drop setuid */
790
791     for(i=0; i <= 110; i++ )
792         if( !chkf(i) && (s=mapf(i)) )
793             n += strlen(s) + 7 + 2;
794     list = m_alloc( 21 + n ); *list = 0;
795     for(p=NULL, i=0; i <= 110; i++ ) {
796         if( !chkf(i) && (s=mapf(i)) ) {
797             if( !p ) {
798                 p = stpcpy( list, text );
799                 line=p;
800             }
801             else
802                 p = stpcpy( p, ", ");
803
804             if(strlen(line)>60) {
805               int spaces=strlen(text);
806
807               list=m_realloc(list,n+spaces+1);
808               /* realloc could move the block, so find the end again */
809               p=list;
810               while(*p)
811                 p++;
812
813               p=stpcpy(p, "\n");
814               line=p;
815               for(;spaces;spaces--)
816                 p=stpcpy(p, " ");
817             }
818
819             p = stpcpy(p, s );
820             if(opt.verbose && letter)
821               {
822                 char num[8];
823                 sprintf(num," (%c%d)",letter,i);
824                 p = stpcpy(p,num);
825               }
826         }
827     }
828     if( p )
829         p = stpcpy(p, "\n" );
830     return list;
831 }
832
833
834 static void
835 i18n_init(void)
836 {
837 #ifdef USE_SIMPLE_GETTEXT
838     set_gettext_file( PACKAGE );
839 #else
840 #ifdef ENABLE_NLS
841     setlocale( LC_ALL, "" );
842     bindtextdomain( PACKAGE, G10_LOCALEDIR );
843     textdomain( PACKAGE );
844 #endif
845 #endif
846 }
847
848 static void
849 wrong_args( const char *text)
850 {
851     fputs(_("usage: gpg [options] "),stderr);
852     fputs(text,stderr);
853     putc('\n',stderr);
854     g10_exit(2);
855 }
856
857
858 static char *
859 make_username( const char *string )
860 {
861     char *p;
862     if( utf8_strings )
863         p = m_strdup(string);
864     else
865         p = native_to_utf8( string );
866     return p;
867 }
868
869
870 static void
871 set_debug(void)
872 {
873     if( opt.debug & DBG_MEMORY_VALUE )
874         memory_debug_mode = 1;
875     if( opt.debug & DBG_MEMSTAT_VALUE )
876         memory_stat_debug_mode = 1;
877     if( opt.debug & DBG_MPI_VALUE )
878         mpi_debug_mode = 1;
879     if( opt.debug & DBG_CIPHER_VALUE )
880         g10c_debug_mode = 1;
881     if( opt.debug & DBG_IOBUF_VALUE )
882         iobuf_debug_mode = 1;
883
884 }
885
886
887 /* We need the home directory also in some other directories, so make
888    sure that both variables are always in sync. */
889 static void
890 set_homedir (char *dir)
891 {
892   if (!dir)
893     dir = "";
894   g10_opt_homedir = opt.homedir = dir;
895 }
896
897
898 /* We set the screen dimensions for UI purposes.  Do not allow screens
899    smaller than 80x24 for the sake of simplicity. */
900 static void
901 set_screen_dimensions(void)
902 {
903 #ifndef _WIN32
904   char *str;
905
906   str=getenv("COLUMNS");
907   if(str)
908     opt.screen_columns=atoi(str);
909
910   str=getenv("LINES");
911   if(str)
912     opt.screen_lines=atoi(str);
913 #endif
914
915   if(opt.screen_columns<80 || opt.screen_columns>255)
916     opt.screen_columns=80;
917
918   if(opt.screen_lines<24 || opt.screen_lines>255)
919     opt.screen_lines=24;
920 }
921
922
923 /* Helper to open a file FNAME either for reading or writing to be
924    used with --status-file etc functions.  Not generally useful but it
925    avoids the riscos specific functions and well some Windows people
926    might like it too.  Prints an error message and returns -1 on
927    error. On success the file descriptor is returned.  */
928 static int
929 open_info_file (const char *fname, int for_write)
930 {
931 #ifdef __riscos__
932   return riscos_fdopenfile (fname, for_write);
933 #elif defined (ENABLE_SELINUX_HACKS)
934   /* We can't allow these even when testing for a secured filename
935      because files to be secured might not yet been secured.  This is
936      similar to the option file but in that case it is unlikely that
937      sensitive information may be retrieved by means of error
938      messages.  */
939   return -1;
940 #else 
941   int fd;
942
943 /*   if (is_secured_filename (fname)) */
944 /*     { */
945 /*       fd = -1; */
946 /*       errno = EPERM; */
947 /*     } */
948 /*   else */
949 /*     { */
950       do
951         {
952           if (for_write)
953             fd = open (fname, O_CREAT | O_TRUNC | O_WRONLY,
954                         S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
955           else
956             fd = open (fname, O_RDONLY | MY_O_BINARY);
957         }
958       while (fd == -1 && errno == EINTR);
959 /*     } */
960   if ( fd == -1)
961     log_error ( for_write? _("can't create `%s': %s\n")
962                          : _("can't open `%s': %s\n"), fname, strerror(errno));
963   
964   return fd;
965 #endif
966 }
967
968 static void
969 set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
970 {
971     enum cmd_and_opt_values cmd = *ret_cmd;
972
973     if( !cmd || cmd == new_cmd )
974         cmd = new_cmd;
975     else if( cmd == aSign && new_cmd == aEncr )
976         cmd = aSignEncr;
977     else if( cmd == aEncr && new_cmd == aSign )
978         cmd = aSignEncr;
979     else if( cmd == aSign && new_cmd == aSym )
980         cmd = aSignSym;
981     else if( cmd == aSym && new_cmd == aSign )
982         cmd = aSignSym;
983     else if( cmd == aSym && new_cmd == aEncr )
984         cmd = aEncrSym;
985     else if( cmd == aEncr && new_cmd == aSym )
986         cmd = aEncrSym;
987     else if( cmd == aKMode && new_cmd == aSym )
988         cmd = aKModeC;
989     else if (cmd == aSignEncr && new_cmd == aSym)
990         cmd = aSignEncrSym;
991     else if (cmd == aSignSym && new_cmd == aEncr)
992         cmd = aSignEncrSym;
993     else if (cmd == aEncrSym && new_cmd == aSign)
994         cmd = aSignEncrSym;
995     else if(    ( cmd == aSign     && new_cmd == aClearsign )
996              || ( cmd == aClearsign && new_cmd == aSign )  )
997         cmd = aClearsign;
998     else {
999         log_error(_("conflicting commands\n"));
1000         g10_exit(2);
1001     }
1002
1003     *ret_cmd = cmd;
1004 }
1005
1006
1007 static void
1008 add_group(char *string)
1009 {
1010   char *name,*value;
1011   struct groupitem *item;
1012
1013   /* Break off the group name */
1014   name=strsep(&string,"=");
1015   if(string==NULL)
1016     {
1017       log_error(_("no = sign found in group definition `%s'\n"),name);
1018       return;
1019     }
1020
1021   trim_trailing_ws(name,strlen(name));
1022
1023   /* Does this group already exist? */
1024   for(item=opt.grouplist;item;item=item->next)
1025     if(strcasecmp(item->name,name)==0)
1026       break;
1027
1028   if(!item)
1029     {
1030       item=m_alloc(sizeof(struct groupitem));
1031       item->name=name;
1032       item->next=opt.grouplist;
1033       item->values=NULL;
1034       opt.grouplist=item;
1035     }
1036
1037   /* Break apart the values */
1038   while ((value= strsep(&string," \t")))
1039     {
1040       if (*value)
1041         add_to_strlist2(&item->values,value,utf8_strings);
1042     }
1043 }
1044
1045
1046 static void
1047 rm_group(char *name)
1048 {
1049   struct groupitem *item,*last=NULL;
1050
1051   trim_trailing_ws(name,strlen(name));
1052
1053   for(item=opt.grouplist;item;last=item,item=item->next)
1054     {
1055       if(strcasecmp(item->name,name)==0)
1056         {
1057           if(last)
1058             last->next=item->next;
1059           else
1060             opt.grouplist=item->next;
1061
1062           free_strlist(item->values);
1063           m_free(item);
1064           break;
1065         }
1066     }
1067 }
1068
1069
1070 /* We need to check three things.
1071
1072    0) The homedir.  It must be x00, a directory, and owned by the
1073    user.
1074
1075    1) The options/gpg.conf file.  Okay unless it or its containing
1076    directory is group or other writable or not owned by us.  Disable
1077    exec in this case.
1078
1079    2) Extensions.  Same as #1.
1080
1081    Returns true if the item is unsafe. */
1082 static int
1083 check_permissions(const char *path,int item)
1084 {
1085 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
1086   static int homedir_cache=-1;
1087   char *tmppath,*dir;
1088   struct stat statbuf,dirbuf;
1089   int homedir=0,ret=0,checkonly=0;
1090   int perm=0,own=0,enc_dir_perm=0,enc_dir_own=0;
1091
1092   if(opt.no_perm_warn)
1093     return 0;
1094
1095   assert(item==0 || item==1 || item==2);
1096
1097   /* extensions may attach a path */
1098   if(item==2 && path[0]!=DIRSEP_C)
1099     {
1100       if(strchr(path,DIRSEP_C))
1101         tmppath=make_filename(path,NULL);
1102       else
1103         tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
1104     }
1105   else
1106     tmppath=m_strdup(path);
1107
1108   /* If the item is located in the homedir, but isn't the homedir,
1109      don't continue if we already checked the homedir itself.  This is
1110      to avoid user confusion with an extra options file warning which
1111      could be rectified if the homedir itself had proper
1112      permissions. */
1113   if(item!=0 && homedir_cache>-1
1114      && ascii_strncasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0)
1115     {
1116       ret=homedir_cache;
1117       goto end;
1118     }
1119
1120   /* It's okay if the file or directory doesn't exist */
1121   if(stat(tmppath,&statbuf)!=0)
1122     {
1123       ret=0;
1124       goto end;
1125     }
1126
1127   /* Now check the enclosing directory.  Theoretically, we could walk
1128      this test up to the root directory /, but for the sake of sanity,
1129      I'm stopping at one level down. */
1130   dir=make_dirname(tmppath);
1131
1132   if(stat(dir,&dirbuf)!=0 || !S_ISDIR(dirbuf.st_mode))
1133     {
1134       /* Weird error */
1135       ret=1;
1136       goto end;
1137     }
1138
1139   m_free(dir);
1140
1141   /* Assume failure */
1142   ret=1;
1143
1144   if(item==0)
1145     {
1146       /* The homedir must be x00, a directory, and owned by the user. */
1147
1148       if(S_ISDIR(statbuf.st_mode))
1149         {
1150           if(statbuf.st_uid==getuid())
1151             {
1152               if((statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
1153                 ret=0;
1154               else
1155                 perm=1;
1156             }
1157           else
1158             own=1;
1159
1160           homedir_cache=ret;
1161         }
1162     }
1163   else if(item==1 || item==2)
1164     {
1165       /* The options or extension file.  Okay unless it or its
1166          containing directory is group or other writable or not owned
1167          by us or root. */
1168
1169       if(S_ISREG(statbuf.st_mode))
1170         {
1171           if(statbuf.st_uid==getuid() || statbuf.st_uid==0)
1172             {
1173               if((statbuf.st_mode & (S_IWGRP|S_IWOTH))==0)
1174                 {
1175                   /* it's not writable, so make sure the enclosing
1176                      directory is also not writable */
1177                   if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0)
1178                     {
1179                       if((dirbuf.st_mode & (S_IWGRP|S_IWOTH))==0)
1180                         ret=0;
1181                       else
1182                         enc_dir_perm=1;
1183                     }
1184                   else
1185                     enc_dir_own=1;
1186                 }
1187               else
1188                 {
1189                   /* it's writable, so the enclosing directory had
1190                      better not let people get to it. */
1191                   if(dirbuf.st_uid==getuid() || dirbuf.st_uid==0)
1192                     {
1193                       if((dirbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
1194                         ret=0;
1195                       else
1196                         perm=enc_dir_perm=1; /* unclear which one to fix! */
1197                     }
1198                   else
1199                     enc_dir_own=1;
1200                 }
1201             }
1202           else
1203             own=1;
1204         }
1205     }
1206   else
1207     BUG();
1208
1209   if(!checkonly)
1210     {
1211       if(own)
1212         {
1213           if(item==0)
1214             log_info(_("WARNING: unsafe ownership on"
1215                        " homedir `%s'\n"),tmppath);
1216           else if(item==1)
1217             log_info(_("WARNING: unsafe ownership on"
1218                        " configuration file `%s'\n"),tmppath);
1219           else
1220             log_info(_("WARNING: unsafe ownership on"
1221                        " extension `%s'\n"),tmppath);
1222         }
1223       if(perm)
1224         {
1225           if(item==0)
1226             log_info(_("WARNING: unsafe permissions on"
1227                        " homedir `%s'\n"),tmppath);
1228           else if(item==1)
1229             log_info(_("WARNING: unsafe permissions on"
1230                        " configuration file `%s'\n"),tmppath);
1231           else
1232             log_info(_("WARNING: unsafe permissions on"
1233                        " extension `%s'\n"),tmppath);
1234         }
1235       if(enc_dir_own)
1236         {
1237           if(item==0)
1238             log_info(_("WARNING: unsafe enclosing directory ownership on"
1239                        " homedir `%s'\n"),tmppath);
1240           else if(item==1)
1241             log_info(_("WARNING: unsafe enclosing directory ownership on"
1242                        " configuration file `%s'\n"),tmppath);
1243           else
1244             log_info(_("WARNING: unsafe enclosing directory ownership on"
1245                        " extension `%s'\n"),tmppath);
1246         }
1247       if(enc_dir_perm)
1248         {
1249           if(item==0)
1250             log_info(_("WARNING: unsafe enclosing directory permissions on"
1251                        " homedir `%s'\n"),tmppath);
1252           else if(item==1)
1253             log_info(_("WARNING: unsafe enclosing directory permissions on"
1254                        " configuration file `%s'\n"),tmppath);
1255           else
1256             log_info(_("WARNING: unsafe enclosing directory permissions on"
1257                        " extension `%s'\n"),tmppath);
1258         }
1259     }
1260
1261  end:
1262   m_free(tmppath);
1263
1264   if(homedir)
1265     homedir_cache=ret;
1266
1267   return ret;
1268
1269 #endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
1270
1271   return 0;
1272 }
1273
1274
1275 static void
1276 print_algo_numbers(int (*checker)(int))
1277 {
1278   int i,first=1;
1279
1280   for(i=0;i<=110;i++)
1281     {
1282       if(!checker(i))
1283         {
1284           if(first)
1285             first=0;
1286           else
1287             printf(";");
1288           printf("%d",i);
1289         }
1290     }
1291 }
1292
1293
1294 /* In the future, we can do all sorts of interesting configuration
1295    output here.  For now, just give "group" as the Enigmail folks need
1296    it, and pubkey, cipher, hash, and compress as they may be useful
1297    for frontends. */
1298 static void
1299 list_config(char *items)
1300 {
1301   int show_all=(items==NULL);
1302   char *name=NULL;
1303
1304   if(!opt.with_colons)
1305     return;
1306
1307   while(show_all || (name=strsep(&items," ")))
1308     {
1309       int any=0;
1310
1311       if(show_all || ascii_strcasecmp(name,"group")==0)
1312         {
1313           struct groupitem *iter;
1314
1315           for(iter=opt.grouplist;iter;iter=iter->next)
1316             {
1317               STRLIST sl;
1318
1319               printf("cfg:group:");
1320               print_string(stdout,iter->name,strlen(iter->name),':');
1321               printf(":");
1322
1323               for(sl=iter->values;sl;sl=sl->next)
1324                 {
1325                   print_string2(stdout,sl->d,strlen(sl->d),':',';');
1326                   if(sl->next)
1327                     printf(";");
1328                 }
1329
1330               printf("\n");
1331             }
1332
1333           any=1;
1334         }
1335
1336       if(show_all || ascii_strcasecmp(name,"version")==0)
1337         {
1338           printf("cfg:version:");
1339           print_string(stdout,VERSION,strlen(VERSION),':');
1340           printf("\n");
1341           any=1;
1342         }
1343
1344       if(show_all || ascii_strcasecmp(name,"pubkey")==0)
1345         {
1346           printf("cfg:pubkey:");
1347           print_algo_numbers(check_pubkey_algo);
1348           printf("\n");
1349           any=1;
1350         }
1351
1352       if(show_all || ascii_strcasecmp(name,"cipher")==0)
1353         {
1354           printf("cfg:cipher:");
1355           print_algo_numbers(check_cipher_algo);
1356           printf("\n");
1357           any=1;
1358         }
1359
1360       if(show_all
1361          || ascii_strcasecmp(name,"digest")==0
1362          || ascii_strcasecmp(name,"hash")==0)
1363         {
1364           printf("cfg:digest:");
1365           print_algo_numbers(check_digest_algo);
1366           printf("\n");
1367           any=1;
1368         }
1369
1370       if(show_all || ascii_strcasecmp(name,"compress")==0)
1371         {
1372           printf("cfg:compress:");
1373           print_algo_numbers(check_compress_algo);
1374           printf("\n");
1375           any=1;
1376         }
1377
1378       if(show_all || ascii_strcasecmp(name,"ccid-reader-id")==0)
1379         {
1380 #if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB)
1381           char *p, *p2, *list = ccid_get_reader_list ();
1382
1383           for (p=list; p && (p2 = strchr (p, '\n')); p = p2+1)
1384             {
1385               *p2 = 0;
1386               printf("cfg:ccid-reader-id:%s\n", p);
1387             }
1388           free (list);
1389 #endif
1390           any=1;
1391         }
1392
1393       if(show_all)
1394         break;
1395
1396       if(!any)
1397         log_error(_("unknown configuration item `%s'\n"),name);
1398     }
1399 }
1400
1401
1402 /* List options and default values in the GPG Conf format.  This is a
1403    new tool distributed with gnupg 1.9.x but we also want some limited
1404    support in older gpg versions.  The output is the name of the
1405    configuration file and a list of options available for editing by
1406    gpgconf.  */
1407 static void
1408 gpgconf_list (const char *configfile)
1409 {
1410   /* The following definitions are taken from gnupg/tools/gpgconf-comp.c.  */
1411 #define GC_OPT_FLAG_NONE        0UL
1412 #define GC_OPT_FLAG_DEFAULT     (1UL << 4)
1413
1414   printf ("gpgconf-gpg.conf:%lu:\"%s\n",
1415           GC_OPT_FLAG_DEFAULT,configfile?configfile:"/dev/null");
1416   printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
1417   printf ("quiet:%lu:\n",   GC_OPT_FLAG_NONE);
1418   printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE);
1419   printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE);
1420 }
1421
1422
1423 static int
1424 parse_subpacket_list(char *list)
1425 {
1426   char *tok;
1427   byte subpackets[128],i;
1428   int count=0;
1429
1430   if(!list)
1431     {
1432       /* No arguments means all subpackets */
1433       memset(subpackets+1,1,sizeof(subpackets)-1);
1434       count=127;
1435     }
1436   else
1437     {
1438       memset(subpackets,0,sizeof(subpackets));
1439
1440       /* Merge with earlier copy */
1441       if(opt.show_subpackets)
1442         {
1443           byte *in;
1444
1445           for(in=opt.show_subpackets;*in;in++)
1446             {
1447               if(*in>127 || *in<1)
1448                 BUG();
1449
1450               if(!subpackets[*in])
1451                 count++;
1452               subpackets[*in]=1;
1453             }
1454         }
1455
1456       while((tok=strsep(&list," ,")))
1457         {
1458           if(!*tok)
1459             continue;
1460
1461           i=atoi(tok);
1462           if(i>127 || i<1)
1463             return 0;
1464
1465           if(!subpackets[i])
1466             count++;
1467           subpackets[i]=1;
1468         }
1469     }
1470
1471   m_free(opt.show_subpackets);
1472   opt.show_subpackets=m_alloc(count+1);
1473   opt.show_subpackets[count--]=0;
1474
1475   for(i=1;i<128 && count>=0;i++)
1476     if(subpackets[i])
1477       opt.show_subpackets[count--]=i;
1478
1479   return 1;
1480 }
1481
1482
1483 static int
1484 parse_list_options(char *str)
1485 {
1486   char *subpackets=""; /* something that isn't NULL */
1487   struct parse_options lopts[]=
1488     {
1489       {"show-photos",LIST_SHOW_PHOTOS,NULL},
1490       {"show-policy-urls",LIST_SHOW_POLICY_URLS,NULL},
1491       {"show-notations",LIST_SHOW_NOTATIONS,NULL},
1492       {"show-std-notations",LIST_SHOW_STD_NOTATIONS,NULL},
1493       {"show-standard-notations",LIST_SHOW_STD_NOTATIONS,NULL},
1494       {"show-user-notations",LIST_SHOW_USER_NOTATIONS,NULL},
1495       {"show-keyserver-urls",LIST_SHOW_KEYSERVER_URLS,NULL},
1496       {"show-uid-validity",LIST_SHOW_UID_VALIDITY,NULL},
1497       {"show-unusable-uids",LIST_SHOW_UNUSABLE_UIDS,NULL},
1498       {"show-unusable-subkeys",LIST_SHOW_UNUSABLE_SUBKEYS,NULL},
1499       {"show-keyring",LIST_SHOW_KEYRING,NULL},
1500       {"show-sig-expire",LIST_SHOW_SIG_EXPIRE,NULL},
1501       {"show-sig-subpackets",LIST_SHOW_SIG_SUBPACKETS,NULL},
1502       {NULL,0,NULL}
1503     };
1504
1505   /* C99 allows for non-constant initializers, but we'd like to
1506      compile everywhere, so fill in the show-sig-subpackets argument
1507      here.  Note that if the parse_options array changes, we'll have
1508      to change the subscript here. */
1509   lopts[12].value=&subpackets;
1510
1511   if(parse_options(str,&opt.list_options,lopts,1))
1512     {
1513       if(opt.list_options&LIST_SHOW_SIG_SUBPACKETS)
1514         {
1515           /* Unset so users can pass multiple lists in. */
1516           opt.list_options&=~LIST_SHOW_SIG_SUBPACKETS;
1517           if(!parse_subpacket_list(subpackets))
1518             return 0;
1519         }
1520       else if(subpackets==NULL && opt.show_subpackets)
1521         {
1522           /* User did 'no-show-subpackets' */
1523           m_free(opt.show_subpackets);
1524           opt.show_subpackets=NULL;
1525         }
1526
1527       return 1;
1528     }
1529   else
1530     return 0;
1531 }
1532
1533
1534 /* Collapses argc/argv into a single string that must be freed */
1535 static char *
1536 collapse_args(int argc,char *argv[])
1537 {
1538   char *str=NULL;
1539   int i,first=1,len=0;
1540
1541   for(i=0;i<argc;i++)
1542     {
1543       len+=strlen(argv[i])+2;
1544       str=m_realloc(str,len);
1545       if(first)
1546         {
1547           str[0]='\0';
1548           first=0;
1549         }
1550       else
1551         strcat(str," ");
1552
1553       strcat(str,argv[i]);
1554     }
1555
1556   return str;
1557 }
1558
1559 static void
1560 parse_trust_model(const char *model)
1561 {
1562   if(ascii_strcasecmp(model,"pgp")==0)
1563     opt.trust_model=TM_PGP;
1564   else if(ascii_strcasecmp(model,"classic")==0)
1565     opt.trust_model=TM_CLASSIC;
1566   else if(ascii_strcasecmp(model,"always")==0)
1567     opt.trust_model=TM_ALWAYS;
1568   else if(ascii_strcasecmp(model,"direct")==0)
1569     opt.trust_model=TM_DIRECT;
1570   else if(ascii_strcasecmp(model,"auto")==0)
1571     opt.trust_model=TM_AUTO;
1572   else
1573     log_error("unknown trust model `%s'\n",model);
1574 }
1575
1576 int
1577 main( int argc, char **argv )
1578 {
1579     ARGPARSE_ARGS pargs;
1580     IOBUF a;
1581     int rc=0;
1582     int orig_argc;
1583     char **orig_argv;
1584     const char *fname;
1585     char *username;
1586     int may_coredump;
1587     STRLIST sl, remusr= NULL, locusr=NULL;
1588     STRLIST nrings=NULL, sec_nrings=NULL;
1589     armor_filter_context_t afx;
1590     int detached_sig = 0;
1591     FILE *configfp = NULL;
1592     char *configname = NULL;
1593     char *save_configname = NULL;
1594     unsigned configlineno;
1595     int parse_debug = 0;
1596     int default_config = 1;
1597     int default_keyring = 1;
1598     int greeting = 0;
1599     int nogreeting = 0;
1600     int use_random_seed = 1;
1601     enum cmd_and_opt_values cmd = 0;
1602     const char *trustdb_name = NULL;
1603     char *def_cipher_string = NULL;
1604     char *def_digest_string = NULL;
1605     char *compress_algo_string = NULL;
1606     char *cert_digest_string = NULL;
1607     char *s2k_cipher_string = NULL;
1608     char *s2k_digest_string = NULL;
1609     char *pers_cipher_list = NULL;
1610     char *pers_digest_list = NULL;
1611     char *pers_compress_list = NULL;
1612     int eyes_only=0;
1613     int multifile=0;
1614     int pwfd = -1;
1615     int with_fpr = 0; /* make an option out of --fingerprint */
1616     int any_explicit_recipient = 0;
1617 #ifdef USE_SHM_COPROCESSING
1618     ulong requested_shm_size=0;
1619 #endif
1620
1621 #ifdef __riscos__
1622     opt.lock_once = 1;
1623 #endif /* __riscos__ */
1624
1625     trap_unaligned();
1626     secmem_set_flags( secmem_get_flags() | 2 ); /* suspend warnings */
1627     /* Please note that we may running SUID(ROOT), so be very CAREFUL
1628      * when adding any stuff between here and the call to
1629      * secmem_init()  somewhere after the option parsing
1630      */
1631     log_set_name("gpg");
1632     secure_random_alloc(); /* put random number into secure memory */
1633     may_coredump = disable_core_dumps();
1634     init_signals();
1635     create_dotlock(NULL); /* register locking cleanup */
1636     i18n_init();
1637     opt.command_fd = -1; /* no command fd */
1638     opt.compress_level = -1; /* defaults to standard compress level */
1639     opt.bz2_compress_level = -1; /* defaults to standard compress level */
1640     /* note: if you change these lines, look at oOpenPGP */
1641     opt.def_cipher_algo = 0;
1642     opt.def_digest_algo = 0;
1643     opt.cert_digest_algo = 0;
1644     opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */
1645     opt.s2k_mode = 3; /* iterated+salted */
1646 #ifdef USE_CAST5
1647     opt.s2k_cipher_algo = CIPHER_ALGO_CAST5;
1648 #else
1649     opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
1650 #endif
1651     opt.completes_needed = 1;
1652     opt.marginals_needed = 3;
1653     opt.max_cert_depth = 5;
1654     opt.pgp2_workarounds = 1;
1655     opt.force_v3_sigs = 1;
1656     opt.escape_from = 1;
1657     opt.import_options=IMPORT_SK2PK;
1658     opt.export_options=EXPORT_ATTRIBUTES;
1659     opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG;
1660     opt.keyserver_options.export_options=EXPORT_ATTRIBUTES;
1661     opt.keyserver_options.options=
1662       KEYSERVER_INCLUDE_SUBKEYS|KEYSERVER_INCLUDE_REVOKED|KEYSERVER_TRY_DNS_SRV|KEYSERVER_HONOR_KEYSERVER_URL;
1663     opt.verify_options=
1664       VERIFY_SHOW_POLICY_URLS|VERIFY_SHOW_STD_NOTATIONS|VERIFY_SHOW_KEYSERVER_URLS;
1665     opt.trust_model=TM_AUTO;
1666     opt.mangle_dos_filenames=0;
1667     opt.min_cert_level=2;
1668     set_screen_dimensions();
1669     opt.keyid_format=KF_SHORT;
1670 #if defined (_WIN32)
1671     set_homedir ( read_w32_registry_string( NULL,
1672                                     "Software\\GNU\\GnuPG", "HomeDir" ));
1673 #else
1674     set_homedir ( getenv("GNUPGHOME") );
1675 #endif
1676     if( !*opt.homedir )
1677         set_homedir ( GNUPG_HOMEDIR );
1678
1679 #ifdef ENABLE_CARD_SUPPORT
1680 # ifdef _WIN32
1681     opt.pcsc_driver = "winscard.dll"; 
1682 #else
1683     opt.pcsc_driver = "libpcsclite.so"; 
1684 #endif
1685 #endif /*ENABLE_CARD_SUPPORT*/
1686
1687     /* check whether we have a config file on the commandline */
1688     orig_argc = argc;
1689     orig_argv = argv;
1690     pargs.argc = &argc;
1691     pargs.argv = &argv;
1692     pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
1693     while( arg_parse( &pargs, opts) ) {
1694         if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
1695             parse_debug++;
1696         else if( pargs.r_opt == oOptions ) {
1697             /* yes there is one, so we do not try the default one, but
1698              * read the option file when it is encountered at the commandline
1699              */
1700             default_config = 0;
1701         }
1702         else if( pargs.r_opt == oNoOptions )
1703             default_config = 0; /* --no-options */
1704         else if( pargs.r_opt == oHomedir )
1705             set_homedir ( pargs.r.ret_str );
1706         else if( pargs.r_opt == oNoPermissionWarn )
1707             opt.no_perm_warn=1;
1708         else if (pargs.r_opt == oStrict )
1709           {
1710             opt.strict=1;
1711             log_set_strict(1);
1712           }
1713         else if (pargs.r_opt == oNoStrict )
1714           {
1715             opt.strict=0;
1716             log_set_strict(0);
1717           }
1718 #ifdef USE_SHM_COPROCESSING
1719         else if( pargs.r_opt == oRunAsShmCP ) {
1720             /* does not make sense in a options file, we do it here,
1721              * so that we are the able to drop setuid as soon as possible */
1722             opt.shm_coprocess = 1;
1723             requested_shm_size = pargs.r.ret_ulong;
1724         }
1725         else if ( pargs.r_opt == oStatusFD ) {
1726             /* this is needed to ensure that the status-fd filedescriptor is
1727              * initialized when init_shm_coprocessing() is called */
1728             set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) );
1729         }
1730 #endif
1731     }
1732
1733 #ifdef HAVE_DOSISH_SYSTEM
1734     if ( strchr (opt.homedir,'\\') ) {
1735         char *d, *buf = m_alloc (strlen (opt.homedir)+1);
1736         const char *s = opt.homedir;
1737         for (d=buf,s=opt.homedir; *s; s++)
1738             *d++ = *s == '\\'? '/': *s;
1739         *d = 0;
1740         set_homedir (buf);
1741     }
1742 #endif
1743 #ifdef USE_SHM_COPROCESSING
1744     if( opt.shm_coprocess ) {
1745         init_shm_coprocessing(requested_shm_size, 1 );
1746     }
1747 #endif
1748     /* initialize the secure memory. */
1749     secmem_init( 32768 );
1750     maybe_setuid = 0;
1751     /* Okay, we are now working under our real uid */
1752
1753 #if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
1754     /* There should be no way to get to this spot while still carrying
1755        setuid privs.  Just in case, bomb out if we are. */
1756     if(getuid()!=geteuid())
1757       BUG();
1758 #endif
1759
1760     set_native_charset (NULL); /* Try to auto set the character set */
1761
1762     /* Try for a version specific config file first */
1763     if( default_config )
1764       {
1765         char *name=m_strdup("gpg" EXTSEP_S "conf-" SAFE_VERSION);
1766         char *ver=&name[strlen("gpg" EXTSEP_S "conf-")];
1767
1768         do
1769           {
1770             if(configname)
1771               {
1772                 char *tok;
1773
1774                 m_free(configname);
1775                 configname=NULL;
1776
1777                 if((tok=strrchr(ver,SAFE_VERSION_DASH)))
1778                   *tok='\0';
1779                 else if((tok=strrchr(ver,SAFE_VERSION_DOT)))
1780                   *tok='\0';
1781                 else
1782                   break;
1783               }
1784
1785             configname = make_filename(opt.homedir,name,NULL);
1786           }
1787         while(access(configname,R_OK));
1788
1789         m_free(name);
1790
1791         if(!configname)
1792           configname=make_filename(opt.homedir, "gpg" EXTSEP_S "conf", NULL );
1793         if (!access (configname, R_OK))
1794           { /* Print a warning when both config files are present. */
1795             char *p = make_filename(opt.homedir, "options", NULL );
1796             if (!access (p, R_OK))
1797               log_info (_("NOTE: old default options file `%s' ignored\n"), p);
1798             m_free (p);
1799           }
1800         else
1801           { /* Keep on using the old default one. */
1802             m_free (configname);
1803             configname = make_filename(opt.homedir, "options", NULL );
1804           }
1805       }
1806     argc = orig_argc;
1807     argv = orig_argv;
1808     pargs.argc = &argc;
1809     pargs.argv = &argv;
1810     pargs.flags=  1;  /* do not remove the args */
1811
1812     /* By this point we have a homedir, and cannot change it. */
1813     check_permissions(opt.homedir,0);
1814
1815   next_pass:
1816     if( configname ) {
1817       if(check_permissions(configname,1))
1818         {
1819           /* If any options file is unsafe, then disable any external
1820              programs for keyserver calls or photo IDs.  Since the
1821              external program to call is set in the options file, a
1822              unsafe options file can lead to an arbitrary program
1823              being run. */
1824
1825           opt.exec_disable=1;
1826         }
1827
1828         configlineno = 0;
1829         configfp = fopen( configname, "r" );
1830         if (configfp && is_secured_file (fileno (configfp)))
1831           {
1832             fclose (configfp);
1833             configfp = NULL;
1834             errno = EPERM;
1835           }
1836         if( !configfp ) {
1837             if( default_config ) {
1838                 if( parse_debug )
1839                     log_info(_("NOTE: no default option file `%s'\n"),
1840                                                             configname );
1841             }
1842             else {
1843                 log_error(_("option file `%s': %s\n"),
1844                                     configname, strerror(errno) );
1845                 g10_exit(2);
1846             }
1847             m_free(configname); configname = NULL;
1848         }
1849         if( parse_debug && configname )
1850             log_info(_("reading options from `%s'\n"), configname );
1851         default_config = 0;
1852     }
1853
1854     while( optfile_parse( configfp, configname, &configlineno,
1855                                                 &pargs, opts) )
1856       {
1857         switch( pargs.r_opt )
1858           {
1859           case aCheckKeys: 
1860           case aListConfig:
1861           case aGPGConfList:
1862           case aListPackets:
1863           case aImport: 
1864           case aFastImport: 
1865           case aSendKeys: 
1866           case aRecvKeys: 
1867           case aSearchKeys:
1868           case aRefreshKeys:
1869           case aExport: 
1870             set_cmd (&cmd, pargs.r_opt);
1871             break;
1872           case aListKeys: set_cmd( &cmd, aListKeys); break;
1873           case aListSigs: set_cmd( &cmd, aListSigs); break;
1874           case aExportSecret: set_cmd( &cmd, aExportSecret); break;
1875           case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break;
1876           case aDeleteSecretKeys:
1877             set_cmd( &cmd, aDeleteSecretKeys);
1878             greeting=1;
1879             break;
1880           case aDeleteSecretAndPublicKeys:
1881             set_cmd( &cmd, aDeleteSecretAndPublicKeys);
1882             greeting=1; 
1883             break;
1884           case aDeleteKeys: set_cmd( &cmd, aDeleteKeys); greeting=1; break;
1885
1886           case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
1887           case aSym: set_cmd( &cmd, aSym); break;
1888
1889           case aDecryptFiles: multifile=1; /* fall through */
1890           case aDecrypt: set_cmd( &cmd, aDecrypt); break;
1891
1892           case aEncrFiles: multifile=1; /* fall through */
1893           case aEncr: set_cmd( &cmd, aEncr); break;
1894
1895           case aVerifyFiles: multifile=1; /* fall through */
1896           case aVerify: set_cmd( &cmd, aVerify); break;
1897
1898           case aSign: set_cmd( &cmd, aSign );  break;
1899           case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break;
1900           case aSignKey: set_cmd( &cmd, aSignKey); break;
1901           case aLSignKey: set_cmd( &cmd, aLSignKey); break;
1902           case aNRSignKey: set_cmd( &cmd, aNRSignKey); break;
1903           case aNRLSignKey: set_cmd( &cmd, aNRLSignKey); break;
1904           case aStore: set_cmd( &cmd, aStore); break;
1905           case aEditKey: set_cmd( &cmd, aEditKey); greeting=1; break;
1906           case aClearsign: set_cmd( &cmd, aClearsign); break;
1907           case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
1908           case aDesigRevoke: set_cmd( &cmd, aDesigRevoke); break;
1909           case aPrimegen: set_cmd( &cmd, aPrimegen); break;
1910           case aGenRandom: set_cmd( &cmd, aGenRandom); break;
1911           case aPrintMD: set_cmd( &cmd, aPrintMD); break;
1912           case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
1913           case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
1914           case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
1915           case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
1916           case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break;
1917           case aListTrustPath: set_cmd( &cmd, aListTrustPath); break;
1918           case aDeArmor: set_cmd( &cmd, aDeArmor); break;
1919           case aEnArmor: set_cmd( &cmd, aEnArmor); break;
1920           case aListOwnerTrust:
1921             deprecated_warning(configname,configlineno,
1922                                "--list-ownertrust","--export-ownertrust","");
1923           case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break;
1924           case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break;
1925           case aPipeMode: set_cmd( &cmd, aPipeMode); break;
1926           case aRebuildKeydbCaches: set_cmd( &cmd, aRebuildKeydbCaches); break;
1927
1928 #ifdef ENABLE_CARD_SUPPORT
1929           case aCardStatus: set_cmd (&cmd, aCardStatus); break;
1930           case aCardEdit: set_cmd (&cmd, aCardEdit); break;
1931           case aChangePIN: set_cmd (&cmd, aChangePIN); break;
1932           case oReaderPort:
1933             card_set_reader_port (pargs.r.ret_str);
1934             break;
1935           case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break;
1936           case opcscDriver: opt.pcsc_driver = pargs.r.ret_str; break;
1937           case oDisableCCID: opt.disable_ccid = 1; break;
1938 #endif /* ENABLE_CARD_SUPPORT*/
1939
1940           case oArmor: opt.armor = 1; opt.no_armor=0; break;
1941           case oOutput: opt.outfile = pargs.r.ret_str; break;
1942           case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break;
1943           case oQuiet: opt.quiet = 1; break;
1944           case oNoTTY: tty_no_terminal(1); break;
1945           case oDryRun: opt.dry_run = 1; break;
1946           case oInteractive: opt.interactive = 1; break;
1947           case oVerbose:
1948             g10_opt_verbose++;
1949             opt.verbose++;
1950             opt.list_options|=LIST_SHOW_UNUSABLE_UIDS;
1951             opt.list_options|=LIST_SHOW_UNUSABLE_SUBKEYS;
1952             break;
1953           case oKOption: set_cmd( &cmd, aKMode ); break;
1954
1955           case oBatch: opt.batch = 1; nogreeting = 1; break;
1956           case oUseAgent:
1957 #ifndef __riscos__
1958             opt.use_agent = 1;
1959 #else /* __riscos__ */
1960             opt.use_agent = 0;
1961             riscos_not_implemented("use-agent");
1962 #endif /* __riscos__ */
1963             break;
1964           case oNoUseAgent: opt.use_agent = 0; break;
1965           case oGpgAgentInfo: opt.gpg_agent_info = pargs.r.ret_str; break;
1966           case oAnswerYes: opt.answer_yes = 1; break;
1967           case oAnswerNo: opt.answer_no = 1; break;
1968           case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
1969           case oPrimaryKeyring:
1970             sl=append_to_strlist( &nrings, pargs.r.ret_str);
1971             sl->flags=2;
1972             break;
1973           case oShowKeyring:
1974             deprecated_warning(configname,configlineno,"--show-keyring",
1975                                "--list-options ","show-keyring");
1976             opt.list_options|=LIST_SHOW_KEYRING;
1977             break;
1978           case oDebug: opt.debug |= pargs.r.ret_ulong; break;
1979           case oDebugAll: opt.debug = ~0; break;
1980           case oDebugCCIDDriver: 
1981 #if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB)
1982             ccid_set_debug_level (1);
1983 #endif
1984             break;
1985           case oStatusFD:
1986             set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) );
1987             break;
1988           case oStatusFile:
1989             set_status_fd ( open_info_file (pargs.r.ret_str, 1) );
1990             break;
1991           case oAttributeFD:
1992             set_attrib_fd(iobuf_translate_file_handle (pargs.r.ret_int, 1));
1993             break;
1994           case oAttributeFile:
1995             set_attrib_fd ( open_info_file (pargs.r.ret_str, 1) );
1996             break;
1997           case oLoggerFD:
1998             log_set_logfile( NULL,
1999                              iobuf_translate_file_handle (pargs.r.ret_int, 1));
2000             break;
2001           case oLoggerFile:
2002             log_set_logfile( NULL, open_info_file (pargs.r.ret_str, 1) );
2003             break;
2004
2005           case oWithFingerprint:
2006             opt.with_fingerprint = 1;
2007             with_fpr=1; /*fall thru*/
2008           case oFingerprint: opt.fingerprint++; break;
2009           case oSecretKeyring:
2010             append_to_strlist( &sec_nrings, pargs.r.ret_str);
2011             break;
2012           case oOptions:
2013             /* config files may not be nested (silently ignore them) */
2014             if( !configfp ) {
2015                 m_free(configname);
2016                 configname = m_strdup(pargs.r.ret_str);
2017                 goto next_pass;
2018             }
2019             break;
2020           case oNoArmor: opt.no_armor=1; opt.armor=0; break;
2021           case oNoDefKeyring: default_keyring = 0; break;
2022           case oDefCertLevel: opt.def_cert_level=pargs.r.ret_int; break;
2023           case oMinCertLevel: opt.min_cert_level=pargs.r.ret_int; break;
2024           case oNoGreeting: nogreeting = 1; break;
2025           case oNoVerbose: g10_opt_verbose = 0;
2026                            opt.verbose = 0; opt.list_sigs=0; break;
2027           case oQuickRandom: quick_random_gen(1); break;
2028           case oSKComments: opt.sk_comments=1; break;
2029           case oNoSKComments: opt.sk_comments=0; break;
2030           case oEmitVersion: opt.no_version=0; break;
2031           case oNoEmitVersion: opt.no_version=1; break;
2032           case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
2033           case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
2034           case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
2035           case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
2036           case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
2037           case oDefRecipient:
2038                     if( *pargs.r.ret_str )
2039                         opt.def_recipient = make_username(pargs.r.ret_str);
2040                     break;
2041           case oDefRecipientSelf:
2042                     m_free(opt.def_recipient); opt.def_recipient = NULL;
2043                     opt.def_recipient_self = 1;
2044                     break;
2045           case oNoDefRecipient:
2046                     m_free(opt.def_recipient); opt.def_recipient = NULL;
2047                     opt.def_recipient_self = 0;
2048                     break;
2049           case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
2050           case oHomedir: break;
2051           case oNoBatch: opt.batch = 0; break;
2052           case oWithKeyData: opt.with_key_data=1; /* fall thru */
2053           case oWithColons: opt.with_colons=':'; break;
2054
2055           case oSkipVerify: opt.skip_verify=1; break;
2056           case oCompressKeys: opt.compress_keys = 1; break;
2057           case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
2058             /* There are many programs (like mutt) that call gpg with
2059                --always-trust so keep this option around for a long
2060                time. */
2061           case oAlwaysTrust: opt.trust_model=TM_ALWAYS; break;
2062           case oTrustModel:
2063             parse_trust_model(pargs.r.ret_str);
2064             break;
2065           case oForceOwnertrust:
2066             log_info(_("NOTE: %s is not for normal use!\n"),
2067                      "--force-ownertrust");
2068             opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str);
2069             if(opt.force_ownertrust==-1)
2070               {
2071                 log_error("invalid ownertrust `%s'\n",pargs.r.ret_str);
2072                 opt.force_ownertrust=0;
2073               }
2074             break;
2075           case oLoadExtension:
2076 #ifndef __riscos__
2077 #if defined(USE_DYNAMIC_LINKING) || defined(_WIN32)
2078             if(check_permissions(pargs.r.ret_str,2))
2079               log_info(_("cipher extension `%s' not loaded due to"
2080                          " unsafe permissions\n"),pargs.r.ret_str);
2081             else
2082               register_cipher_extension(orig_argc? *orig_argv:NULL,
2083                                         pargs.r.ret_str);
2084 #endif
2085 #else /* __riscos__ */
2086             riscos_not_implemented("load-extension");
2087 #endif /* __riscos__ */
2088             break;
2089           case oRFC1991:
2090             opt.compliance = CO_RFC1991;
2091             opt.force_v4_certs = 0;
2092             opt.escape_from = 1;
2093             break;
2094           case oRFC2440:
2095           case oOpenPGP:
2096             /* TODO: When 2440bis becomes a RFC, these may need
2097                changing. */
2098             opt.compliance = CO_RFC2440;
2099             opt.allow_non_selfsigned_uid = 1;
2100             opt.allow_freeform_uid = 1;
2101             opt.pgp2_workarounds = 0;
2102             opt.escape_from = 0;
2103             opt.force_v3_sigs = 0;
2104             opt.compress_keys = 0;          /* not mandated  but we do it */
2105             opt.compress_sigs = 0;          /* ditto. */
2106             opt.not_dash_escaped = 0;
2107             opt.def_cipher_algo = 0;
2108             opt.def_digest_algo = 0;
2109             opt.cert_digest_algo = 0;
2110             opt.compress_algo = -1;
2111             opt.s2k_mode = 3; /* iterated+salted */
2112             opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
2113             opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
2114             break;
2115           case oPGP2:  opt.compliance = CO_PGP2;  break;
2116           case oPGP6:  opt.compliance = CO_PGP6;  break;
2117           case oPGP7:  opt.compliance = CO_PGP7;  break;
2118           case oPGP8:  opt.compliance = CO_PGP8;  break;
2119           case oGnuPG: opt.compliance = CO_GNUPG; break;
2120           case oCompressSigs: opt.compress_sigs = 1; break;
2121           case oRunAsShmCP:
2122 #ifndef __riscos__
2123 # ifndef USE_SHM_COPROCESSING
2124             /* not possible in the option file,
2125              * but we print the warning here anyway */
2126             log_error("shared memory coprocessing is not available\n");
2127 # endif
2128 #else /* __riscos__ */
2129             riscos_not_implemented("run-as-shm-coprocess");
2130 #endif /* __riscos__ */
2131             break;
2132           case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
2133           case oForYourEyesOnly: eyes_only = 1; break;
2134           case oNoForYourEyesOnly: eyes_only = 0; break;
2135           case oSetPolicyURL:
2136             add_policy_url(pargs.r.ret_str,0);
2137             add_policy_url(pargs.r.ret_str,1);
2138             break;
2139           case oSigPolicyURL: add_policy_url(pargs.r.ret_str,0); break;
2140           case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break;
2141           case oShowPolicyURL:
2142             deprecated_warning(configname,configlineno,"--show-policy-url",
2143                                "--list-options ","show-policy-urls");
2144             deprecated_warning(configname,configlineno,"--show-policy-url",
2145                                "--verify-options ","show-policy-urls");
2146             opt.list_options|=LIST_SHOW_POLICY_URLS;
2147             opt.verify_options|=VERIFY_SHOW_POLICY_URLS;
2148             break;
2149           case oNoShowPolicyURL:
2150             deprecated_warning(configname,configlineno,"--no-show-policy-url",
2151                                "--list-options ","no-show-policy-urls");
2152             deprecated_warning(configname,configlineno,"--no-show-policy-url",
2153                                "--verify-options ","no-show-policy-urls");
2154             opt.list_options&=~LIST_SHOW_POLICY_URLS;
2155             opt.verify_options&=~VERIFY_SHOW_POLICY_URLS;
2156             break;
2157           case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break;
2158           case oUseEmbeddedFilename: opt.use_embedded_filename = 1; break;
2159           case oNoUseEmbeddedFilename: opt.use_embedded_filename = 0; break;
2160           case oComment:
2161             if(pargs.r.ret_str[0])
2162               append_to_strlist(&opt.comments,pargs.r.ret_str);
2163             break;
2164           case oDefaultComment:
2165             deprecated_warning(configname,configlineno,
2166                                "--default-comment","--no-comments","");
2167             /* fall through */
2168           case oNoComments:
2169             free_strlist(opt.comments);
2170             opt.comments=NULL;
2171             break;
2172           case oThrowKeyids: opt.throw_keyid = 1; break;
2173           case oNoThrowKeyids: opt.throw_keyid = 0; break;
2174           case oShowPhotos:
2175             deprecated_warning(configname,configlineno,"--show-photos",
2176                                "--list-options ","show-photos");
2177             deprecated_warning(configname,configlineno,"--show-photos",
2178                                "--verify-options ","show-photos");
2179             opt.list_options|=LIST_SHOW_PHOTOS;
2180             opt.verify_options|=VERIFY_SHOW_PHOTOS;
2181             break;
2182           case oNoShowPhotos:
2183             deprecated_warning(configname,configlineno,"--no-show-photos",
2184                                "--list-options ","no-show-photos");
2185             deprecated_warning(configname,configlineno,"--no-show-photos",
2186                                "--verify-options ","no-show-photos");
2187             opt.list_options&=~LIST_SHOW_PHOTOS;
2188             opt.verify_options&=~VERIFY_SHOW_PHOTOS;
2189             break;
2190           case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
2191           case oForceV3Sigs: opt.force_v3_sigs = 1; break;
2192           case oNoForceV3Sigs: opt.force_v3_sigs = 0; break;
2193           case oForceV4Certs: opt.force_v4_certs = 1; break;
2194           case oNoForceV4Certs: opt.force_v4_certs = 0; break;
2195           case oForceMDC: opt.force_mdc = 1; break;
2196           case oNoForceMDC: opt.force_mdc = 0; break;
2197           case oDisableMDC: opt.disable_mdc = 1; break;
2198           case oNoDisableMDC: opt.disable_mdc = 0; break;
2199           case oS2KMode:   opt.s2k_mode = pargs.r.ret_int; break;
2200           case oS2KDigest: s2k_digest_string = m_strdup(pargs.r.ret_str); break;
2201           case oS2KCipher: s2k_cipher_string = m_strdup(pargs.r.ret_str); break;
2202           case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break;
2203           case oNoEncryptTo: opt.no_encrypt_to = 1; break;
2204           case oEncryptTo: /* store the recipient in the second list */
2205             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2206             sl->flags = 1;
2207             break;
2208           case oHiddenEncryptTo: /* store the recipient in the second list */
2209             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2210             sl->flags = 1|2;
2211             break;
2212           case oRecipient: /* store the recipient */
2213             add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2214             any_explicit_recipient = 1;
2215             break;
2216           case oHiddenRecipient: /* store the recipient with a flag */
2217             sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
2218             sl->flags = 2;
2219             any_explicit_recipient = 1;
2220             break;
2221           case oTextmodeShort: opt.textmode = 2; break;
2222           case oTextmode: opt.textmode=1;  break;
2223           case oNoTextmode: opt.textmode=0;  break;
2224           case oExpert: opt.expert = 1; break;
2225           case oNoExpert: opt.expert = 0; break;
2226           case oAskSigExpire: opt.ask_sig_expire = 1; break;
2227           case oNoAskSigExpire: opt.ask_sig_expire = 0; break;
2228           case oAskCertExpire: opt.ask_cert_expire = 1; break;
2229           case oNoAskCertExpire: opt.ask_cert_expire = 0; break;
2230           case oAskCertLevel: opt.ask_cert_level = 1; break;
2231           case oNoAskCertLevel: opt.ask_cert_level = 0; break;
2232           case oUser: /* store the local users */
2233             add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
2234             break;
2235           case oCompress:
2236             /* this is the -z command line option */
2237             opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int;
2238             break;
2239           case oCompressLevel: opt.compress_level = pargs.r.ret_int; break;
2240           case oBZ2CompressLevel: opt.bz2_compress_level = pargs.r.ret_int; break;
2241           case oBZ2DecompressLowmem: opt.bz2_decompress_lowmem=1; break;
2242           case oPasswdFD:
2243             pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
2244             opt.use_agent = 0;
2245             break;
2246           case oPasswdFile:
2247             pwfd = open_info_file (pargs.r.ret_str, 0);
2248             break;
2249           case oCommandFD:
2250             opt.command_fd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
2251             break;
2252           case oCommandFile:
2253             opt.command_fd = open_info_file (pargs.r.ret_str, 0);
2254             break;
2255           case oCipherAlgo: 
2256             def_cipher_string = m_strdup(pargs.r.ret_str);
2257             break;
2258           case oDigestAlgo:
2259             def_digest_string = m_strdup(pargs.r.ret_str);
2260             break;
2261           case oCompressAlgo:
2262             /* If it is all digits, stick a Z in front of it for
2263                later.  This is for backwards compatibility with
2264                versions that took the compress algorithm number. */
2265             {
2266               char *pt=pargs.r.ret_str;
2267               while(*pt)
2268                 {
2269                   if(!isdigit(*pt))
2270                     break;
2271
2272                   pt++;
2273                 }
2274
2275               if(*pt=='\0')
2276                 {
2277                   compress_algo_string=m_alloc(strlen(pargs.r.ret_str)+2);
2278                   strcpy(compress_algo_string,"Z");
2279                   strcat(compress_algo_string,pargs.r.ret_str);
2280                 }
2281               else
2282                 compress_algo_string = m_strdup(pargs.r.ret_str);
2283             }
2284             break;
2285           case oCertDigestAlgo: cert_digest_string = m_strdup(pargs.r.ret_str); break;
2286           case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
2287           case oNoPermissionWarn: opt.no_perm_warn=1; break;
2288           case oNoMDCWarn: opt.no_mdc_warn=1; break;
2289           case oDisplayCharset:
2290             if( set_native_charset( pargs.r.ret_str ) )
2291                 log_error(_("`%s' is not a valid character set\n"),
2292                           pargs.r.ret_str);
2293             break;
2294           case oNotDashEscaped: opt.not_dash_escaped = 1; break;
2295           case oEscapeFrom: opt.escape_from = 1; break;
2296           case oNoEscapeFrom: opt.escape_from = 0; break;
2297           case oLockOnce: opt.lock_once = 1; break;
2298           case oLockNever: disable_dotlock(); break;
2299           case oLockMultiple:
2300 #ifndef __riscos__
2301             opt.lock_once = 0;
2302 #else /* __riscos__ */
2303             riscos_not_implemented("lock-multiple");
2304 #endif /* __riscos__ */
2305             break;
2306           case oKeyServer:
2307             opt.keyserver=parse_keyserver_uri(pargs.r.ret_str,0,
2308                                               configname,configlineno);
2309             if(!opt.keyserver)
2310               log_error(_("could not parse keyserver URL\n"));
2311             break;
2312           case oKeyServerOptions:
2313             if(!parse_keyserver_options(pargs.r.ret_str))
2314               {
2315                 if(configname)
2316                   log_error(_("%s:%d: invalid keyserver options\n"),
2317                             configname,configlineno);
2318                 else
2319                   log_error(_("invalid keyserver options\n"));
2320               }
2321             break;
2322           case oImportOptions:
2323             if(!parse_import_options(pargs.r.ret_str,&opt.import_options,1))
2324               {
2325                 if(configname)
2326                   log_error(_("%s:%d: invalid import options\n"),
2327                             configname,configlineno);
2328                 else
2329                   log_error(_("invalid import options\n"));
2330               }
2331             break;
2332           case oExportOptions:
2333             if(!parse_export_options(pargs.r.ret_str,&opt.export_options,1))
2334               {
2335                 if(configname)
2336                   log_error(_("%s:%d: invalid export options\n"),
2337                             configname,configlineno);
2338                 else
2339                   log_error(_("invalid export options\n"));
2340               }
2341             break;
2342           case oListOptions:
2343             if(!parse_list_options(pargs.r.ret_str))
2344               {
2345                 if(configname)
2346                   log_error(_("%s:%d: invalid list options\n"),
2347                             configname,configlineno);
2348                 else
2349                   log_error(_("invalid list options\n"));
2350               }
2351             break;
2352           case oVerifyOptions:
2353             {
2354               struct parse_options vopts[]=
2355                 {
2356                   {"show-photos",VERIFY_SHOW_PHOTOS,NULL},
2357                   {"show-policy-urls",VERIFY_SHOW_POLICY_URLS,NULL},
2358                   {"show-notations",VERIFY_SHOW_NOTATIONS,NULL},
2359                   {"show-std-notations",VERIFY_SHOW_STD_NOTATIONS,NULL},
2360                   {"show-standard-notations",VERIFY_SHOW_STD_NOTATIONS,NULL},
2361                   {"show-user-notations",VERIFY_SHOW_USER_NOTATIONS,NULL},
2362                   {"show-keyserver-urls",VERIFY_SHOW_KEYSERVER_URLS,NULL},
2363                   {"show-uid-validity",VERIFY_SHOW_UID_VALIDITY,NULL},
2364                   {"show-unusable-uids",VERIFY_SHOW_UNUSABLE_UIDS,NULL},
2365                   {NULL,0,NULL}
2366                 };
2367
2368               if(!parse_options(pargs.r.ret_str,&opt.verify_options,vopts,1))
2369                 {
2370                   if(configname)
2371                     log_error(_("%s:%d: invalid verify options\n"),
2372                               configname,configlineno);
2373                   else
2374                     log_error(_("invalid verify options\n"));
2375                 }
2376             }
2377             break;
2378           case oTempDir: opt.temp_dir=pargs.r.ret_str; break;
2379           case oExecPath:
2380             if(set_exec_path(pargs.r.ret_str,0))
2381               log_error(_("unable to set exec-path to %s\n"),pargs.r.ret_str);
2382             else
2383               opt.exec_path_set=1;
2384             break;
2385           case oSetNotation:
2386             add_notation_data( pargs.r.ret_str, 0 );
2387             add_notation_data( pargs.r.ret_str, 1 );
2388             break;
2389           case oSigNotation: add_notation_data( pargs.r.ret_str, 0 ); break;
2390           case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break;
2391           case oShowNotation:
2392             deprecated_warning(configname,configlineno,"--show-notation",
2393                                "--list-options ","show-notations");
2394             deprecated_warning(configname,configlineno,"--show-notation",
2395                                "--verify-options ","show-notations");
2396             opt.list_options|=LIST_SHOW_NOTATIONS;
2397             opt.verify_options|=VERIFY_SHOW_NOTATIONS;
2398             break;
2399           case oNoShowNotation:
2400             deprecated_warning(configname,configlineno,"--no-show-notation",
2401                                "--list-options ","no-show-notations");
2402             deprecated_warning(configname,configlineno,"--no-show-notation",
2403                                "--verify-options ","no-show-notations");
2404             opt.list_options&=~LIST_SHOW_NOTATIONS;
2405             opt.verify_options&=~VERIFY_SHOW_NOTATIONS;
2406             break;
2407           case oUtf8Strings: utf8_strings = 1; break;
2408           case oNoUtf8Strings: utf8_strings = 0; break;
2409           case oDisableCipherAlgo:
2410                 disable_cipher_algo( string_to_cipher_algo(pargs.r.ret_str) );
2411                 break;
2412           case oDisablePubkeyAlgo:
2413                 disable_pubkey_algo( string_to_pubkey_algo(pargs.r.ret_str) );
2414                 break;
2415           case oNoSigCache: opt.no_sig_cache = 1; break;
2416           case oNoSigCreateCheck: opt.no_sig_create_check = 1; break;
2417           case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break;
2418           case oNoAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid=0; break;
2419           case oAllowFreeformUID: opt.allow_freeform_uid = 1; break;
2420           case oNoAllowFreeformUID: opt.allow_freeform_uid = 0; break;
2421           case oNoLiteral: opt.no_literal = 1; break;
2422           case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
2423           case oHonorHttpProxy:
2424                 add_to_strlist(&opt.keyserver_options.other,"http-proxy");
2425                 deprecated_warning(configname,configlineno,
2426                                    "--honor-http-proxy",
2427                                    "--keyserver-options ","http-proxy");
2428                 break;
2429           case oFastListMode: opt.fast_list_mode = 1; break;
2430           case oFixedListMode: opt.fixed_list_mode = 1; break;
2431           case oListOnly: opt.list_only=1; break;
2432           case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
2433           case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
2434           case oIgnoreCrcError: opt.ignore_crc_error = 1; break;
2435           case oIgnoreMDCError: opt.ignore_mdc_error = 1; break;
2436           case oNoRandomSeedFile: use_random_seed = 0; break;
2437           case oAutoKeyRetrieve:
2438           case oNoAutoKeyRetrieve:
2439                 if(pargs.r_opt==oAutoKeyRetrieve)
2440                   opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
2441                 else
2442                   opt.keyserver_options.options&=~KEYSERVER_AUTO_KEY_RETRIEVE;
2443
2444                 deprecated_warning(configname,configlineno,
2445                            pargs.r_opt==oAutoKeyRetrieve?"--auto-key-retrieve":
2446                                "--no-auto-key-retrieve","--keyserver-options ",
2447                            pargs.r_opt==oAutoKeyRetrieve?"auto-key-retrieve":
2448                                "no-auto-key-retrieve");
2449                 break;
2450           case oShowSessionKey: opt.show_session_key = 1; break;
2451           case oOverrideSessionKey:
2452                 opt.override_session_key = pargs.r.ret_str;
2453                 break;
2454           case oMergeOnly:
2455                 deprecated_warning(configname,configlineno,"--merge-only",
2456                                    "--import-options ","merge-only");
2457                 opt.import_options|=IMPORT_MERGE_ONLY;
2458             break;
2459           case oAllowSecretKeyImport: /* obsolete */ break;
2460           case oTryAllSecrets: opt.try_all_secrets = 1; break;
2461           case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
2462           case oEnableSpecialFilenames:
2463             iobuf_enable_special_filenames (1);
2464             break;
2465           case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break;
2466           case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break;
2467           case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break;
2468           case oPreservePermissions: opt.preserve_permissions=1; break;
2469           case oDefaultPreferenceList:
2470             opt.def_preference_list = pargs.r.ret_str;
2471             break;
2472           case oPersonalCipherPreferences:
2473             pers_cipher_list=pargs.r.ret_str;
2474             break;
2475           case oPersonalDigestPreferences:
2476             pers_digest_list=pargs.r.ret_str;
2477             break;
2478           case oPersonalCompressPreferences:
2479             pers_compress_list=pargs.r.ret_str;
2480             break;
2481           case oDisplay: opt.display = pargs.r.ret_str; break;
2482           case oTTYname: opt.ttyname = pargs.r.ret_str; break;
2483           case oTTYtype: opt.ttytype = pargs.r.ret_str; break;
2484           case oLCctype: opt.lc_ctype = pargs.r.ret_str; break;
2485           case oLCmessages: opt.lc_messages = pargs.r.ret_str; break;
2486           case oGroup: add_group(pargs.r.ret_str); break;
2487           case oUnGroup: rm_group(pargs.r.ret_str); break;
2488           case oNoGroups:
2489             while(opt.grouplist)
2490               {
2491                 struct groupitem *iter=opt.grouplist;
2492                 free_strlist(iter->values);
2493                 opt.grouplist=opt.grouplist->next;
2494                 m_free(iter);
2495               }
2496             break;
2497           case oStrict: opt.strict=1; log_set_strict(1); break;
2498           case oNoStrict: opt.strict=0; log_set_strict(0); break;
2499           case oMangleDosFilenames: opt.mangle_dos_filenames = 1; break;
2500           case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break;
2501           case oEnableProgressFilter: opt.enable_progress_filter = 1; break;
2502           case oMultifile: multifile=1; break;
2503           case oKeyidFormat:
2504             if(ascii_strcasecmp(pargs.r.ret_str,"short")==0)
2505               opt.keyid_format=KF_SHORT;
2506             else if(ascii_strcasecmp(pargs.r.ret_str,"long")==0)
2507               opt.keyid_format=KF_LONG;
2508             else if(ascii_strcasecmp(pargs.r.ret_str,"0xshort")==0)
2509               opt.keyid_format=KF_0xSHORT;
2510             else if(ascii_strcasecmp(pargs.r.ret_str,"0xlong")==0)
2511               opt.keyid_format=KF_0xLONG;
2512             else
2513               log_error("unknown keyid-format `%s'\n",pargs.r.ret_str);
2514             break;
2515
2516           default : pargs.err = configfp? 1:2; break;
2517           }
2518       }
2519
2520
2521     if( configfp ) {
2522         fclose( configfp );
2523         configfp = NULL;
2524         /* Remember the first config file name. */
2525         if (!save_configname)
2526           save_configname = configname;
2527         else
2528           m_free(configname);
2529         configname = NULL;
2530         goto next_pass;
2531     }
2532     m_free( configname ); configname = NULL;
2533     if( log_get_errorcount(0) )
2534         g10_exit(2);
2535
2536     /* The command --gpgconf-list is pretty simple and may be called
2537        directly after the option parsing. */
2538     if (cmd == aGPGConfList)
2539       {
2540         gpgconf_list (save_configname);
2541         g10_exit (0);
2542       }
2543     m_free (save_configname);
2544
2545     if( nogreeting )
2546         greeting = 0;
2547
2548     if( greeting ) {
2549         fprintf(stderr, "%s %s; %s\n",
2550                         strusage(11), strusage(13), strusage(14) );
2551         fprintf(stderr, "%s\n", strusage(15) );
2552     }
2553 #ifdef IS_DEVELOPMENT_VERSION
2554     if( !opt.batch )
2555       {
2556         const char *s;
2557
2558         if((s=strusage(20)))
2559           log_info("%s\n",s);
2560         if((s=strusage(21)))
2561           log_info("%s\n",s);
2562         if((s=strusage(22)))
2563           log_info("%s\n",s);
2564       }
2565 #endif
2566
2567     if (opt.verbose > 2)
2568         log_info ("using character set `%s'\n", get_native_charset ());
2569
2570     if( may_coredump && !opt.quiet )
2571         log_info(_("WARNING: program may create a core file!\n"));
2572
2573     if (eyes_only) {
2574       if (opt.set_filename)
2575           log_info(_("WARNING: %s overrides %s\n"),
2576                    "--for-your-eyes-only","--set-filename");
2577
2578       opt.set_filename="_CONSOLE";
2579     }
2580
2581     if (opt.no_literal) {
2582         log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal");
2583         if (opt.textmode)
2584             log_error(_("%s not allowed with %s!\n"),
2585                        "--textmode", "--no-literal" );
2586         if (opt.set_filename)
2587             log_error(_("%s makes no sense with %s!\n"),
2588                         eyes_only?"--for-your-eyes-only":"--set-filename",
2589                         "--no-literal" );
2590     }
2591
2592     if (opt.set_filesize)
2593         log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize");
2594     if( opt.batch )
2595         tty_batchmode( 1 );
2596
2597     secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
2598
2599     set_debug();
2600
2601     /* Do these after the switch(), so they can override settings. */
2602     if(PGP2)
2603       {
2604         int unusable=0;
2605
2606         if(cmd==aSign && !detached_sig)
2607           {
2608             log_info(_("you can only make detached or clear signatures "
2609                        "while in --pgp2 mode\n"));
2610             unusable=1;
2611           }
2612         else if(cmd==aSignEncr || cmd==aSignSym)
2613           {
2614             log_info(_("you can't sign and encrypt at the "
2615                        "same time while in --pgp2 mode\n"));
2616             unusable=1;
2617           }
2618         else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym))
2619           {
2620             log_info(_("you must use files (and not a pipe) when "
2621                        "working with --pgp2 enabled.\n"));
2622             unusable=1;
2623           }
2624         else if(cmd==aEncr || cmd==aSym)
2625           {
2626             /* Everything else should work without IDEA (except using
2627                a secret key encrypted with IDEA and setting an IDEA
2628                preference, but those have their own error
2629                messages). */
2630
2631             if(check_cipher_algo(CIPHER_ALGO_IDEA))
2632               {
2633                 log_info(_("encrypting a message in --pgp2 mode requires "
2634                            "the IDEA cipher\n"));
2635                 idea_cipher_warn(1);
2636                 unusable=1;
2637               }
2638             else if(cmd==aSym)
2639               {
2640                 /* This only sets IDEA for symmetric encryption
2641                    since it is set via select_algo_from_prefs for
2642                    pk encryption. */
2643                 m_free(def_cipher_string);
2644                 def_cipher_string = m_strdup("idea");
2645               }
2646
2647             /* PGP2 can't handle the output from the textmode
2648                filter, so we disable it for anything that could
2649                create a literal packet (only encryption and
2650                symmetric encryption, since we disable signing
2651                above). */
2652             if(!unusable)
2653               opt.textmode=0;
2654           }
2655
2656         if(unusable)
2657           compliance_failure();
2658         else
2659           {
2660             opt.force_v4_certs = 0;
2661             opt.sk_comments = 0;
2662             opt.escape_from = 1;
2663             opt.force_v3_sigs = 1;
2664             opt.pgp2_workarounds = 1;
2665             opt.ask_sig_expire = 0;
2666             opt.ask_cert_expire = 0;
2667             m_free(def_digest_string);
2668             def_digest_string = m_strdup("md5");
2669             m_free(s2k_digest_string);
2670             s2k_digest_string = m_strdup("md5");
2671             opt.compress_algo = COMPRESS_ALGO_ZIP;
2672           }
2673       }
2674     else if(PGP6)
2675       {
2676         opt.sk_comments=0;
2677         opt.escape_from=1;
2678         opt.force_v3_sigs=1;
2679         opt.ask_sig_expire=0;
2680       }
2681     else if(PGP7)
2682       {
2683         opt.sk_comments=0;
2684         opt.escape_from=1;
2685         opt.force_v3_sigs=1;
2686         opt.ask_sig_expire=0;
2687       }
2688     else if(PGP8)
2689       {
2690         opt.escape_from=1;
2691       }
2692
2693     /* must do this after dropping setuid, because string_to...
2694      * may try to load an module */
2695     if( def_cipher_string ) {
2696         opt.def_cipher_algo = string_to_cipher_algo(def_cipher_string);
2697         if(opt.def_cipher_algo==0 &&
2698            (ascii_strcasecmp(def_cipher_string,"idea")==0
2699             || ascii_strcasecmp(def_cipher_string,"s1")==0))
2700           idea_cipher_warn(1);
2701         m_free(def_cipher_string); def_cipher_string = NULL;
2702         if( check_cipher_algo(opt.def_cipher_algo) )
2703             log_error(_("selected cipher algorithm is invalid\n"));
2704     }
2705     if( def_digest_string ) {
2706         opt.def_digest_algo = string_to_digest_algo(def_digest_string);
2707         m_free(def_digest_string); def_digest_string = NULL;
2708         if( check_digest_algo(opt.def_digest_algo) )
2709             log_error(_("selected digest algorithm is invalid\n"));
2710     }
2711     if( compress_algo_string ) {
2712         opt.compress_algo = string_to_compress_algo(compress_algo_string);
2713         m_free(compress_algo_string); compress_algo_string = NULL;
2714         if( check_compress_algo(opt.compress_algo) )
2715             log_error(_("selected compression algorithm is invalid\n"));
2716     }
2717     if( cert_digest_string ) {
2718         opt.cert_digest_algo = string_to_digest_algo(cert_digest_string);
2719         m_free(cert_digest_string); cert_digest_string = NULL;
2720         if( check_digest_algo(opt.cert_digest_algo) )
2721             log_error(_("selected certification digest algorithm is invalid\n"));
2722     }
2723     if( s2k_cipher_string ) {
2724         opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string);
2725         m_free(s2k_cipher_string); s2k_cipher_string = NULL;
2726         if( check_cipher_algo(opt.s2k_cipher_algo) )
2727             log_error(_("selected cipher algorithm is invalid\n"));
2728     }
2729     if( s2k_digest_string ) {
2730         opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string);
2731         m_free(s2k_digest_string); s2k_digest_string = NULL;
2732         if( check_digest_algo(opt.s2k_digest_algo) )
2733             log_error(_("selected digest algorithm is invalid\n"));
2734     }
2735     if( opt.completes_needed < 1 )
2736       log_error(_("completes-needed must be greater than 0\n"));
2737     if( opt.marginals_needed < 2 )
2738       log_error(_("marginals-needed must be greater than 1\n"));
2739     if( opt.max_cert_depth < 1 || opt.max_cert_depth > 255 )
2740       log_error(_("max-cert-depth must be in the range from 1 to 255\n"));
2741     if(opt.def_cert_level<0 || opt.def_cert_level>3)
2742       log_error(_("invalid default-cert-level; must be 0, 1, 2, or 3\n"));
2743     if( opt.min_cert_level < 1 || opt.min_cert_level > 3 )
2744       log_error(_("invalid min-cert-level; must be 1, 2, or 3\n"));
2745     switch( opt.s2k_mode ) {
2746       case 0:
2747         log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
2748         break;
2749       case 1: case 3: break;
2750       default:
2751         log_error(_("invalid S2K mode; must be 0, 1 or 3\n"));
2752     }
2753
2754     /* This isn't actually needed, but does serve to error out if the
2755        string is invalid. */
2756     if(opt.def_preference_list &&
2757         keygen_set_std_prefs(opt.def_preference_list,0))
2758       log_error(_("invalid default preferences\n"));
2759
2760     /* We provide defaults for the personal digest list.  This is
2761        SHA-1. */
2762     if(!pers_digest_list)
2763       pers_digest_list="h2";
2764
2765     if(pers_cipher_list &&
2766        keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM))
2767       log_error(_("invalid personal cipher preferences\n"));
2768
2769     if(pers_digest_list &&
2770        keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH))
2771       log_error(_("invalid personal digest preferences\n"));
2772
2773     if(pers_compress_list &&
2774        keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
2775       log_error(_("invalid personal compress preferences\n"));
2776
2777     /* We don't support all possible commands with multifile yet */
2778     if(multifile)
2779       {
2780         char *cmdname;
2781
2782         switch(cmd)
2783           {
2784           case aSign:
2785             cmdname="--sign";
2786             break;
2787           case aClearsign:
2788             cmdname="--clearsign";
2789             break;
2790           case aDetachedSign:
2791             cmdname="--detach-sign";
2792             break;
2793           case aSym:
2794             cmdname="--symmetric";
2795             break;
2796           case aEncrSym:
2797             cmdname="--symmetric --encrypt";
2798             break;
2799           case aStore:
2800             cmdname="--store";
2801             break;
2802           default:
2803             cmdname=NULL;
2804             break;
2805           }
2806
2807         if(cmdname)
2808           log_error(_("%s does not yet work with %s\n"),cmdname,"--multifile");
2809       }
2810
2811     if( log_get_errorcount(0) )
2812         g10_exit(2);
2813
2814     if(opt.compress_level==0)
2815       opt.compress_algo=COMPRESS_ALGO_NONE;
2816
2817     /* Check our chosen algorithms against the list of legal
2818        algorithms. */
2819
2820     if(!GNUPG)
2821       {
2822         const char *badalg=NULL;
2823         preftype_t badtype=PREFTYPE_NONE;
2824
2825         if(opt.def_cipher_algo
2826            && !algo_available(PREFTYPE_SYM,opt.def_cipher_algo,NULL))
2827           {
2828             badalg=cipher_algo_to_string(opt.def_cipher_algo);
2829             badtype=PREFTYPE_SYM;
2830           }
2831         else if(opt.def_digest_algo
2832                 && !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL))
2833           {
2834             badalg=digest_algo_to_string(opt.def_digest_algo);
2835             badtype=PREFTYPE_HASH;
2836           }
2837         else if(opt.cert_digest_algo
2838                 && !algo_available(PREFTYPE_HASH,opt.cert_digest_algo,NULL))
2839           {
2840             badalg=digest_algo_to_string(opt.cert_digest_algo);
2841             badtype=PREFTYPE_HASH;
2842           }
2843         else if(opt.compress_algo!=-1
2844                 && !algo_available(PREFTYPE_ZIP,opt.compress_algo,NULL))
2845           {
2846             badalg=compress_algo_to_string(opt.compress_algo);
2847             badtype=PREFTYPE_ZIP;
2848           }
2849
2850         if(badalg)
2851           {
2852             switch(badtype)
2853               {
2854               case PREFTYPE_SYM:
2855                 log_info(_("you may not use cipher algorithm `%s'"
2856                            " while in %s mode\n"),
2857                          badalg,compliance_option_string());
2858                 break;
2859               case PREFTYPE_HASH:
2860                 log_info(_("you may not use digest algorithm `%s'"
2861                            " while in %s mode\n"),
2862                          badalg,compliance_option_string());
2863                 break;
2864               case PREFTYPE_ZIP:
2865                 log_info(_("you may not use compression algorithm `%s'"
2866                            " while in %s mode\n"),
2867                          badalg,compliance_option_string());
2868                 break;
2869               default:
2870                 BUG();
2871               }
2872
2873             compliance_failure();
2874           }
2875       }
2876
2877     /* set the random seed file */
2878     if( use_random_seed ) {
2879         char *p = make_filename(opt.homedir, "random_seed", NULL );
2880         set_random_seed_file(p);
2881         if (!access (p, F_OK))
2882           register_secured_file (p);
2883         m_free(p);
2884     }
2885
2886     if( !cmd && opt.fingerprint && !with_fpr ) {
2887         set_cmd( &cmd, aListKeys);
2888     }
2889
2890     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
2891         if( cmd == aKModeC ) {
2892             opt.fingerprint = 1;
2893             cmd = aKMode;
2894         }
2895         opt.list_sigs = 0;
2896         if( opt.verbose > 2 )
2897             opt.check_sigs++;
2898         if( opt.verbose > 1 )
2899             opt.list_sigs++;
2900
2901         opt.verbose = opt.verbose > 1;
2902         g10_opt_verbose = opt.verbose;
2903     }
2904
2905     /* kludge to let -sat generate a clear text signature */
2906     if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
2907         cmd = aClearsign;
2908
2909     if( opt.verbose > 1 )
2910         set_packet_list_mode(1);
2911
2912     /* Add the keyrings, but not for some special commands and not in
2913        case of "-kvv userid keyring".  Also avoid adding the secret
2914        keyring for a couple of commands to avoid unneeded access in
2915        case the secrings are stored on a floppy.
2916        
2917        We always need to add the keyrings if we are running under
2918        SELinux, thi is so that the rings are added to the list of
2919        secured files. */
2920     if( ALWAYS_ADD_KEYRINGS 
2921         || (cmd != aDeArmor && cmd != aEnArmor
2922             && !(cmd == aKMode && argc == 2 )) ) 
2923       {
2924         if (ALWAYS_ADD_KEYRINGS
2925             || (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
2926                 && cmd != aVerify && cmd != aSym))
2927           {
2928             if (!sec_nrings || default_keyring) /* add default secret rings */
2929               keydb_add_resource ("secring" EXTSEP_S "gpg", 0, 1);
2930             for (sl = sec_nrings; sl; sl = sl->next)
2931               keydb_add_resource ( sl->d, 0, 1 );
2932           }
2933         if( !nrings || default_keyring )  /* add default ring */
2934             keydb_add_resource ("pubring" EXTSEP_S "gpg", 0, 0);
2935         for(sl = nrings; sl; sl = sl->next )
2936             keydb_add_resource ( sl->d, sl->flags, 0 );
2937       }
2938     FREE_STRLIST(nrings);
2939     FREE_STRLIST(sec_nrings);
2940
2941
2942     if( pwfd != -1 )  /* read the passphrase now. */
2943         read_passphrase_from_fd( pwfd );
2944
2945     fname = argc? *argv : NULL;
2946
2947     switch( cmd ) {
2948       case aPrimegen:
2949       case aPrintMD:
2950       case aPrintMDs:
2951       case aGenRandom:
2952       case aDeArmor:
2953       case aEnArmor:
2954       case aFixTrustDB:
2955         break;
2956       case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break;
2957       case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break;
2958       default: rc = setup_trustdb(1, trustdb_name ); break;
2959     }
2960     if( rc )
2961         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
2962
2963
2964     switch (cmd)
2965       {
2966       case aStore: 
2967       case aSym:  
2968       case aSign: 
2969       case aSignSym: 
2970       case aClearsign: 
2971         if (!opt.quiet && any_explicit_recipient)
2972           log_info (_("WARNING: recipients (-r) given "
2973                       "without using public key encryption\n"));
2974         break;
2975       default:
2976         break;
2977       }
2978
2979     switch( cmd )
2980       {
2981       case aStore: /* only store the file */
2982         if( argc > 1 )
2983             wrong_args(_("--store [filename]"));
2984         if( (rc = encode_store(fname)) )
2985             log_error ("storing `%s' failed: %s\n",
2986                        print_fname_stdin(fname),g10_errstr(rc) );
2987         break;
2988       case aSym: /* encrypt the given file only with the symmetric cipher */
2989         if( argc > 1 )
2990             wrong_args(_("--symmetric [filename]"));
2991         if( (rc = encode_symmetric(fname)) )
2992             log_error (_("symmetric encryption of `%s' failed: %s\n"),
2993                         print_fname_stdin(fname),g10_errstr(rc) );
2994         break;
2995
2996       case aEncr: /* encrypt the given file */
2997         if(multifile)
2998           encode_crypt_files(argc, argv, remusr);
2999         else
3000           {
3001             if( argc > 1 )
3002               wrong_args(_("--encrypt [filename]"));
3003             if( (rc = encode_crypt(fname,remusr,0)) )
3004               log_error("%s: encryption failed: %s\n",
3005                         print_fname_stdin(fname), g10_errstr(rc) );
3006           }
3007         break;
3008
3009       case aEncrSym:
3010         /* This works with PGP 8 in the sense that it acts just like a
3011            symmetric message.  It doesn't work at all with 2 or 6.  It
3012            might work with 7, but alas, I don't have a copy to test
3013            with right now. */
3014         if( argc > 1 )
3015           wrong_args(_("--symmetric --encrypt [filename]"));
3016         else if(opt.s2k_mode==0)
3017           log_error(_("you cannot use --symmetric --encrypt"
3018                       " with --s2k-mode 0\n"));
3019         else if(PGP2 || PGP6 || PGP7 || RFC1991)
3020           log_error(_("you cannot use --symmetric --encrypt"
3021                       " while in %s mode\n"),compliance_option_string());
3022         else
3023           {
3024             if( (rc = encode_crypt(fname,remusr,1)) )
3025               log_error("%s: encryption failed: %s\n",
3026                         print_fname_stdin(fname), g10_errstr(rc) );
3027           }
3028         break;
3029
3030       case aSign: /* sign the given file */
3031         sl = NULL;
3032         if( detached_sig ) { /* sign all files */
3033             for( ; argc; argc--, argv++ )
3034                 add_to_strlist( &sl, *argv );
3035         }
3036         else {
3037             if( argc > 1 )
3038                 wrong_args(_("--sign [filename]"));
3039             if( argc ) {
3040                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
3041                 strcpy(sl->d, fname);
3042             }
3043         }
3044         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
3045             log_error("signing failed: %s\n", g10_errstr(rc) );
3046         free_strlist(sl);
3047         break;
3048
3049       case aSignEncr: /* sign and encrypt the given file */
3050         if( argc > 1 )
3051             wrong_args(_("--sign --encrypt [filename]"));
3052         if( argc ) {
3053             sl = m_alloc_clear( sizeof *sl + strlen(fname));
3054             strcpy(sl->d, fname);
3055         }
3056         else
3057             sl = NULL;
3058         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
3059             log_error("%s: sign+encrypt failed: %s\n",
3060                       print_fname_stdin(fname), g10_errstr(rc) );
3061         free_strlist(sl);
3062         break;
3063
3064       case aSignEncrSym: /* sign and encrypt the given file */
3065         if( argc > 1 )
3066             wrong_args(_("--symmetric --sign --encrypt [filename]"));
3067         else if(opt.s2k_mode==0)
3068           log_error(_("you cannot use --symmetric --sign --encrypt"
3069                       " with --s2k-mode 0\n"));
3070         else if(PGP2 || PGP6 || PGP7 || RFC1991)
3071           log_error(_("you cannot use --symmetric --sign --encrypt"
3072                       " while in %s mode\n"),compliance_option_string());
3073         else
3074           {
3075             if( argc )
3076               {
3077                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
3078                 strcpy(sl->d, fname);
3079               }
3080             else
3081               sl = NULL;
3082             if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) )
3083               log_error("%s: symmetric+sign+encrypt failed: %s\n",
3084                         print_fname_stdin(fname), g10_errstr(rc) );
3085             free_strlist(sl);
3086           }
3087         break;
3088
3089       case aSignSym: /* sign and conventionally encrypt the given file */
3090         if (argc > 1)
3091             wrong_args(_("--sign --symmetric [filename]"));
3092         rc = sign_symencrypt_file (fname, locusr);
3093         if (rc)
3094             log_error("%s: sign+symmetric failed: %s\n",
3095                       print_fname_stdin(fname), g10_errstr(rc) );
3096         break;
3097
3098       case aClearsign: /* make a clearsig */
3099         if( argc > 1 )
3100             wrong_args(_("--clearsign [filename]"));
3101         if( (rc = clearsign_file(fname, locusr, NULL)) )
3102             log_error("%s: clearsign failed: %s\n",
3103                       print_fname_stdin(fname), g10_errstr(rc) );
3104         break;
3105
3106       case aVerify:
3107         if(multifile)
3108           {
3109             if( (rc = verify_files( argc, argv ) ))
3110               log_error("verify files failed: %s\n", g10_errstr(rc) );
3111           }
3112         else
3113           {
3114             if( (rc = verify_signatures( argc, argv ) ))
3115               log_error("verify signatures failed: %s\n", g10_errstr(rc) );
3116           }
3117         break;
3118
3119       case aDecrypt:
3120         if(multifile)
3121           decrypt_messages(argc, argv);
3122         else
3123           {
3124             if( argc > 1 )
3125               wrong_args(_("--decrypt [filename]"));
3126             if( (rc = decrypt_message( fname ) ))
3127               log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
3128           }
3129         break;
3130             
3131       case aSignKey:
3132         if( argc != 1 )
3133           wrong_args(_("--sign-key user-id"));
3134         /* fall through */
3135       case aLSignKey:
3136         if( argc != 1 )
3137           wrong_args(_("--lsign-key user-id"));
3138         /* fall through */
3139       case aNRSignKey:
3140         if( argc != 1 )
3141           wrong_args(_("--nrsign-key user-id"));
3142         /* fall through */
3143       case aNRLSignKey:
3144         if( argc != 1 )
3145           wrong_args(_("--nrlsign-key user-id"));
3146
3147         sl=NULL;
3148
3149         if(cmd==aSignKey)
3150           append_to_strlist(&sl,"sign");
3151         else if(cmd==aLSignKey)
3152           append_to_strlist(&sl,"lsign");
3153         else if(cmd==aNRSignKey)
3154           append_to_strlist(&sl,"nrsign");
3155         else if(cmd==aNRLSignKey)
3156           append_to_strlist(&sl,"nrlsign");
3157         else
3158           BUG();
3159
3160         append_to_strlist( &sl, "save" );
3161         username = make_username( fname );
3162         keyedit_menu(fname, locusr, sl, 0, 0 );
3163         m_free(username);
3164         free_strlist(sl);
3165         break;
3166
3167       case aEditKey: /* Edit a key signature */
3168         if( !argc )
3169             wrong_args(_("--edit-key user-id [commands]"));
3170         username = make_username( fname );
3171         if( argc > 1 ) {
3172             sl = NULL;
3173             for( argc--, argv++ ; argc; argc--, argv++ )
3174                 append_to_strlist( &sl, *argv );
3175             keyedit_menu( username, locusr, sl, 0, 1 );
3176             free_strlist(sl);
3177         }
3178         else
3179             keyedit_menu(username, locusr, NULL, 0, 1 );
3180         m_free(username);
3181         break;
3182
3183       case aDeleteKeys:
3184       case aDeleteSecretKeys:
3185       case aDeleteSecretAndPublicKeys:
3186         sl = NULL;
3187         /* I'm adding these in reverse order as add_to_strlist2
3188            reverses them again, and it's easier to understand in the
3189            proper order :) */
3190         for( ; argc; argc-- )
3191           add_to_strlist2( &sl, argv[argc-1], utf8_strings );
3192         delete_keys(sl,cmd==aDeleteSecretKeys,cmd==aDeleteSecretAndPublicKeys);
3193         free_strlist(sl);
3194         break;
3195
3196       case aCheckKeys:
3197         opt.check_sigs = 1;
3198       case aListSigs:
3199         opt.list_sigs = 1;
3200       case aListKeys:
3201         sl = NULL;
3202         for( ; argc; argc--, argv++ )
3203             add_to_strlist2( &sl, *argv, utf8_strings );
3204         public_key_list( sl );
3205         free_strlist(sl);
3206         break;
3207       case aListSecretKeys:
3208         sl = NULL;
3209         for( ; argc; argc--, argv++ )
3210             add_to_strlist2( &sl, *argv, utf8_strings );
3211         secret_key_list( sl );
3212         free_strlist(sl);
3213         break;
3214
3215       case aKMode: /* list keyring -- NOTE: This will be removed soon */
3216         if( argc < 2 ) { /* -kv [userid] */
3217             sl = NULL;
3218             if (argc && **argv)
3219                 add_to_strlist2( &sl, *argv, utf8_strings );
3220             public_key_list( sl );
3221             free_strlist(sl);
3222         }
3223         else if( argc == 2 ) { /* -kv userid keyring */
3224             if( access( argv[1], R_OK ) ) {
3225                 log_error(_("can't open `%s': %s\n"),
3226                                print_fname_stdin(argv[1]), strerror(errno));
3227             }
3228             else {
3229                 /* add keyring (default keyrings are not registered in this
3230                  * special case */
3231                 keydb_add_resource( argv[1], 0, 0 );
3232                 sl = NULL;
3233                 if (**argv)
3234                     add_to_strlist2( &sl, *argv, utf8_strings );
3235                 public_key_list( sl );
3236                 free_strlist(sl);
3237             }
3238         }
3239         else
3240             wrong_args(_("-k[v][v][v][c] [user-id] [keyring]") );
3241         break;
3242
3243       case aKeygen: /* generate a key */
3244         if( opt.batch ) {
3245             if( argc > 1 )
3246                 wrong_args("--gen-key [parameterfile]");
3247             generate_keypair( argc? *argv : NULL, NULL, NULL );
3248         }
3249         else {
3250             if( argc )
3251                 wrong_args("--gen-key");
3252             generate_keypair(NULL, NULL, NULL);
3253         }
3254         break;
3255
3256       case aFastImport:
3257         opt.import_options |= IMPORT_FAST;
3258       case aImport:
3259         import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
3260         break;
3261
3262       case aExport:
3263       case aSendKeys:
3264       case aRecvKeys:
3265         sl = NULL;
3266         for( ; argc; argc--, argv++ )
3267             add_to_strlist2( &sl, *argv, utf8_strings );
3268         if( cmd == aSendKeys )
3269             rc=keyserver_export( sl );
3270         else if( cmd == aRecvKeys )
3271             rc=keyserver_import( sl );
3272         else
3273             rc=export_pubkeys( sl, opt.export_options );
3274         if(rc)
3275           {
3276             if(cmd==aSendKeys)
3277               log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
3278             else if(cmd==aRecvKeys)
3279               log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
3280             else
3281               log_error(_("key export failed: %s\n"),g10_errstr(rc));
3282           }
3283         free_strlist(sl);
3284         break;
3285
3286      case aSearchKeys:
3287         sl = NULL;
3288         for( ; argc; argc--, argv++ )
3289           append_to_strlist2( &sl, *argv, utf8_strings );
3290         rc=keyserver_search( sl );
3291         if(rc)
3292           log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
3293         free_strlist(sl);
3294         break;
3295
3296       case aRefreshKeys:
3297         sl = NULL;
3298         for( ; argc; argc--, argv++ )
3299             add_to_strlist2( &sl, *argv, utf8_strings );
3300         rc=keyserver_refresh(sl);
3301         if(rc)
3302           log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
3303         free_strlist(sl);
3304         break;
3305
3306       case aExportSecret:
3307         sl = NULL;
3308         for( ; argc; argc--, argv++ )
3309             add_to_strlist2( &sl, *argv, utf8_strings );
3310         export_seckeys( sl );
3311         free_strlist(sl);
3312         break;
3313
3314       case aExportSecretSub:
3315         sl = NULL;
3316         for( ; argc; argc--, argv++ )
3317             add_to_strlist2( &sl, *argv, utf8_strings );
3318         export_secsubkeys( sl );
3319         free_strlist(sl);
3320         break;
3321
3322       case aGenRevoke:
3323         if( argc != 1 )
3324             wrong_args("--gen-revoke user-id");
3325         username =  make_username(*argv);
3326         gen_revoke( username );
3327         m_free( username );
3328         break;
3329
3330       case aDesigRevoke:
3331         if( argc != 1 )
3332             wrong_args("--desig-revoke user-id");
3333         username =  make_username(*argv);
3334         gen_desig_revoke( username );
3335         m_free( username );
3336         break;
3337
3338       case aDeArmor:
3339         if( argc > 1 )
3340             wrong_args("--dearmor [file]");
3341         rc = dearmor_file( argc? *argv: NULL );
3342         if( rc )
3343             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
3344         break;
3345
3346       case aEnArmor:
3347         if( argc > 1 )
3348             wrong_args("--enarmor [file]");
3349         rc = enarmor_file( argc? *argv: NULL );
3350         if( rc )
3351             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
3352         break;
3353
3354
3355       case aPrimegen:
3356         {   int mode = argc < 2 ? 0 : atoi(*argv);
3357
3358             if( mode == 1 && argc == 2 ) {
3359                 mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1);
3360             }
3361             else if( mode == 2 && argc == 3 ) {
3362                 mpi_print( stdout, generate_elg_prime(
3363                                              0, atoi(argv[1]),
3364                                              atoi(argv[2]), NULL,NULL ), 1);
3365             }
3366             else if( mode == 3 && argc == 3 ) {
3367                 MPI *factors;
3368                 mpi_print( stdout, generate_elg_prime(
3369                                              1, atoi(argv[1]),
3370                                              atoi(argv[2]), NULL,&factors ), 1);
3371                 putchar('\n');
3372                 mpi_print( stdout, factors[0], 1 ); /* print q */
3373             }
3374             else if( mode == 4 && argc == 3 ) {
3375                 MPI g = mpi_alloc(1);
3376                 mpi_print( stdout, generate_elg_prime(
3377                                                  0, atoi(argv[1]),
3378                                                  atoi(argv[2]), g, NULL ), 1);
3379                 putchar('\n');
3380                 mpi_print( stdout, g, 1 );
3381                 mpi_free(g);
3382             }
3383             else
3384                 wrong_args("--gen-prime mode bits [qbits] ");
3385             putchar('\n');
3386         }
3387         break;
3388
3389       case aGenRandom:
3390         {
3391             int level = argc ? atoi(*argv):0;
3392             int count = argc > 1 ? atoi(argv[1]): 0;
3393             int endless = !count;
3394
3395             if( argc < 1 || argc > 2 || level < 0 || level > 2 || count < 0 )
3396                 wrong_args("--gen-random 0|1|2 [count]");
3397
3398             while( endless || count ) {
3399                 byte *p;
3400                 /* Wee need a multiple of 3, so that in case of
3401                    armored output we get a correct string.  No
3402                    linefolding is done, as it is best to levae this to
3403                    other tools */
3404                 size_t n = !endless && count < 99? count : 99;
3405
3406                 p = get_random_bits( n*8, level, 0);
3407 #ifdef HAVE_DOSISH_SYSTEM
3408                 setmode ( fileno(stdout), O_BINARY );
3409 #endif
3410                 if (opt.armor) {
3411                     char *tmp = make_radix64_string (p, n);
3412                     fputs (tmp, stdout);
3413                     m_free (tmp);
3414                     if (n%3 == 1)
3415                       putchar ('=');
3416                     if (n%3)
3417                       putchar ('=');
3418                 } else {
3419                     fwrite( p, n, 1, stdout );
3420                 }
3421                 m_free(p);
3422                 if( !endless )
3423                     count -= n;
3424             }
3425             if (opt.armor)
3426                 putchar ('\n');
3427         }
3428         break;
3429
3430       case aPrintMD:
3431         if( argc < 1)
3432             wrong_args("--print-md algo [files]");
3433         {
3434             int all_algos = (**argv=='*' && !(*argv)[1]);
3435             int algo = all_algos? 0 : string_to_digest_algo(*argv);
3436
3437             if( !algo && !all_algos )
3438                 log_error(_("invalid hash algorithm `%s'\n"), *argv );
3439             else {
3440                 argc--; argv++;
3441                 if( !argc )
3442                     print_mds(NULL, algo);
3443                 else {
3444                     for(; argc; argc--, argv++ )
3445                         print_mds(*argv, algo);
3446                 }
3447             }
3448         }
3449         break;
3450
3451       case aPrintMDs: /* old option */
3452         if( !argc )
3453             print_mds(NULL,0);
3454         else {
3455             for(; argc; argc--, argv++ )
3456                 print_mds(*argv,0);
3457         }
3458         break;
3459
3460       case aListTrustDB:
3461         if( !argc )
3462             list_trustdb(NULL);
3463         else {
3464             for( ; argc; argc--, argv++ )
3465                 list_trustdb( *argv );
3466         }
3467         break;
3468
3469       case aUpdateTrustDB:
3470         if( argc )
3471             wrong_args("--update-trustdb");
3472         update_trustdb();
3473         break;
3474
3475       case aCheckTrustDB:
3476         /* Old versions allowed for arguments - ignore them */
3477         check_trustdb();
3478         break;
3479
3480       case aFixTrustDB:
3481         log_error("this command is not yet implemented.\n");
3482         log_error("A workaround is to use \"--export-ownertrust\", remove\n");
3483         log_error("the trustdb file and do an \"--import-ownertrust\".\n" );
3484         break;
3485
3486       case aListTrustPath:
3487         if( !argc )
3488             wrong_args("--list-trust-path <user-ids>");
3489         for( ; argc; argc--, argv++ ) {
3490             username = make_username( *argv );
3491             list_trust_path( username );
3492             m_free(username);
3493         }
3494         break;
3495
3496       case aExportOwnerTrust:
3497         if( argc )
3498             wrong_args("--export-ownertrust");
3499         export_ownertrust();
3500         break;
3501
3502       case aImportOwnerTrust:
3503         if( argc > 1 )
3504             wrong_args("--import-ownertrust [file]");
3505         import_ownertrust( argc? *argv:NULL );
3506         break;
3507       
3508       case aPipeMode:
3509         if ( argc )
3510             wrong_args ("--pipemode");
3511         run_in_pipemode ();
3512         break;
3513
3514       case aRebuildKeydbCaches:
3515         if (argc)
3516             wrong_args ("--rebuild-keydb-caches");
3517         keydb_rebuild_caches (1);
3518         break;
3519
3520 #ifdef ENABLE_CARD_SUPPORT
3521       case aCardStatus:
3522         if (argc)
3523             wrong_args ("--card-status");
3524         card_status (stdout, NULL, 0);
3525         break;
3526
3527       case aCardEdit:
3528         if (argc) {
3529             sl = NULL;
3530             for (argc--, argv++ ; argc; argc--, argv++)
3531                 append_to_strlist (&sl, *argv);
3532             card_edit (sl);
3533             free_strlist (sl);
3534         }
3535         else
3536             card_edit (NULL);
3537         break;
3538
3539       case aChangePIN:
3540         if (!argc)
3541             change_pin (0,1);
3542         else if (argc == 1)
3543             change_pin (atoi (*argv),1);
3544         else
3545         wrong_args ("--change-pin [no]");
3546         break;
3547 #endif /* ENABLE_CARD_SUPPORT*/
3548
3549       case aListConfig:
3550         {
3551           char *str=collapse_args(argc,argv);
3552           list_config(str);
3553           m_free(str);
3554         }
3555         break;
3556
3557       case aListPackets:
3558         opt.list_packets=2;
3559       default:
3560         if( argc > 1 )
3561             wrong_args(_("[filename]"));
3562         /* Issue some output for the unix newbie */
3563         if( !fname && !opt.outfile && isatty( fileno(stdin) )
3564                 && isatty( fileno(stdout) ) && isatty( fileno(stderr) ) )
3565             log_info(_("Go ahead and type your message ...\n"));
3566
3567         a = iobuf_open(fname);
3568         if (a && is_secured_file (iobuf_get_fd (a)))
3569           {
3570             iobuf_close (a);
3571             a = NULL;
3572             errno = EPERM;
3573           }
3574         if( !a )
3575             log_error(_("can't open `%s'\n"), print_fname_stdin(fname));
3576         else {
3577
3578             if( !opt.no_armor ) {
3579                 if( use_armor_filter( a ) ) {
3580                     memset( &afx, 0, sizeof afx);
3581                     iobuf_push_filter( a, armor_filter, &afx );
3582                 }
3583             }
3584             if( cmd == aListPackets ) {
3585                 set_packet_list_mode(1);
3586                 opt.list_packets=1;
3587             }
3588             rc = proc_packets(NULL, a );
3589             if( rc )
3590                 log_error("processing message failed: %s\n", g10_errstr(rc) );
3591             iobuf_close(a);
3592         }
3593         break;
3594       }
3595
3596     /* cleanup */
3597     FREE_STRLIST(remusr);
3598     FREE_STRLIST(locusr);
3599     g10_exit(0);
3600     return 8; /*NEVER REACHED*/
3601 }
3602
3603
3604 void
3605 g10_exit( int rc )
3606 {
3607 #ifdef ENABLE_CARD_SUPPORT
3608     card_close ();
3609 #endif
3610     update_random_seed_file();
3611     if( opt.debug & DBG_MEMSTAT_VALUE ) {
3612         m_print_stats("on exit");
3613         random_dump_stats();
3614     }
3615     if( opt.debug )
3616         secmem_dump_stats();
3617     secmem_term();
3618     rc = rc? rc : log_get_errorcount(0)? 2 :
3619                         g10_errors_seen? 1 : 0;
3620     exit(rc );
3621 }
3622
3623
3624 /* Pretty-print hex hashes.  This assumes at least an 80-character
3625    display, but there are a few other similar assumptions in the
3626    display code. */
3627 static void
3628 print_hex( MD_HANDLE md, int algo, const char *fname )
3629 {
3630   int i,n,count,indent=0;
3631   const byte *p;
3632
3633   if(fname)
3634     indent=printf("%s: ",fname);
3635
3636   if(indent>40)
3637     {
3638       printf("\n");
3639       indent=0;
3640     }
3641
3642   if(algo==DIGEST_ALGO_RMD160)
3643     indent+=printf("RMD160 = ");
3644   else if(algo>0)
3645     indent+=printf("%6s = ",digest_algo_to_string(algo));
3646   else
3647     algo=abs(algo);
3648
3649   count=indent;
3650
3651   p = md_read( md, algo );
3652   n = md_digest_length(algo);
3653
3654   count+=printf("%02X",*p++);
3655
3656   for(i=1;i<n;i++,p++)
3657     {
3658       if(n==16)
3659         {
3660           if(count+2>79)
3661             {
3662               printf("\n%*s",indent," ");
3663               count=indent;
3664             }
3665           else
3666             count+=printf(" ");
3667
3668           if(!(i%8))
3669             count+=printf(" ");
3670         }
3671       else if (n==20)
3672         {
3673           if(!(i%2))
3674             {
3675               if(count+4>79)
3676                 {
3677                   printf("\n%*s",indent," ");
3678                   count=indent;
3679                 }
3680               else
3681                 count+=printf(" ");
3682             }
3683
3684           if(!(i%10))
3685             count+=printf(" ");
3686         }
3687       else
3688         {
3689           if(!(i%4))
3690             {
3691               if(count+8>79)
3692                 {
3693                   printf("\n%*s",indent," ");
3694                   count=indent;
3695                 }
3696               else
3697                 count+=printf(" ");
3698             }
3699         }
3700
3701       count+=printf("%02X",*p);
3702     }
3703
3704   printf("\n");
3705 }
3706
3707 static void
3708 print_hashline( MD_HANDLE md, int algo, const char *fname )
3709 {
3710     int i, n;
3711     const byte *p;
3712     
3713     if ( fname ) {
3714         for (p = fname; *p; p++ ) {
3715             if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' )
3716                 printf("%%%02X", *p );
3717             else 
3718                 putchar( *p );
3719         }
3720     }
3721     putchar(':');
3722     printf("%d:", algo );
3723     p = md_read( md, algo );
3724     n = md_digest_length(algo);
3725     for(i=0; i < n ; i++, p++ ) 
3726         printf("%02X", *p );
3727     putchar(':');
3728     putchar('\n');
3729 }
3730
3731 static void
3732 print_mds( const char *fname, int algo )
3733 {
3734     FILE *fp;
3735     char buf[1024];
3736     size_t n;
3737     MD_HANDLE md;
3738
3739     if( !fname ) {
3740         fp = stdin;
3741 #ifdef HAVE_DOSISH_SYSTEM
3742         setmode ( fileno(fp) , O_BINARY );
3743 #endif
3744     }
3745     else {
3746         fp = fopen( fname, "rb" );
3747         if (fp && is_secured_file (fileno (fp)))
3748           {
3749             fclose (fp);
3750             fp = NULL;
3751             errno = EPERM;
3752           }
3753     }
3754     if( !fp ) {
3755         log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
3756         return;
3757     }
3758
3759     md = md_open( 0, 0 );
3760     if( algo )
3761         md_enable( md, algo );
3762     else {
3763         md_enable( md, DIGEST_ALGO_MD5 );
3764         md_enable( md, DIGEST_ALGO_SHA1 );
3765         md_enable( md, DIGEST_ALGO_RMD160 );
3766 #ifdef USE_SHA256
3767         md_enable( md, DIGEST_ALGO_SHA256 );
3768 #endif
3769 #ifdef USE_SHA512
3770         md_enable( md, DIGEST_ALGO_SHA384 );
3771         md_enable( md, DIGEST_ALGO_SHA512 );
3772 #endif
3773     }
3774
3775     while( (n=fread( buf, 1, DIM(buf), fp )) )
3776         md_write( md, buf, n );
3777     if( ferror(fp) )
3778         log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
3779     else {
3780         md_final(md);
3781         if ( opt.with_colons ) {
3782             if ( algo ) 
3783                 print_hashline( md, algo, fname );
3784             else {
3785                 print_hashline( md, DIGEST_ALGO_MD5, fname );
3786                 print_hashline( md, DIGEST_ALGO_SHA1, fname );
3787                 print_hashline( md, DIGEST_ALGO_RMD160, fname );
3788 #ifdef USE_SHA256
3789                 print_hashline( md, DIGEST_ALGO_SHA256, fname );
3790 #endif
3791 #ifdef USE_SHA512
3792                 print_hashline( md, DIGEST_ALGO_SHA384, fname );
3793                 print_hashline( md, DIGEST_ALGO_SHA512, fname );
3794 #endif
3795             }
3796         }
3797         else {
3798             if( algo )
3799                print_hex(md,-algo,fname);
3800             else {
3801                 print_hex( md, DIGEST_ALGO_MD5, fname );
3802                 print_hex( md, DIGEST_ALGO_SHA1, fname );
3803                 print_hex( md, DIGEST_ALGO_RMD160, fname );
3804 #ifdef USE_SHA256
3805                 print_hex( md, DIGEST_ALGO_SHA256, fname );
3806 #endif
3807 #ifdef USE_SHA512
3808                 print_hex( md, DIGEST_ALGO_SHA384, fname );
3809                 print_hex( md, DIGEST_ALGO_SHA512, fname );
3810 #endif
3811             }
3812         }
3813     }
3814     md_close(md);
3815
3816     if( fp != stdin )
3817         fclose(fp);
3818 }
3819
3820
3821 /****************
3822  * Check the supplied name,value string and add it to the notation
3823  * data to be used for signatures.  which==0 for sig notations, and 1
3824  * for cert notations.
3825 */
3826 static void
3827 add_notation_data( const char *string, int which )
3828 {
3829     const char *s;
3830     STRLIST sl,*notation_data;
3831     int critical=0;
3832     int highbit=0;
3833     int saw_at=0;
3834
3835     if(which)
3836       notation_data=&opt.cert_notation_data;
3837     else
3838       notation_data=&opt.sig_notation_data;
3839
3840     if( *string == '!' ) {
3841         critical = 1;
3842         string++;
3843     }
3844
3845     /* If and when the IETF assigns some official name tags, we'll
3846        have to add them here. */
3847
3848     for( s=string ; *s != '='; s++ )
3849       {
3850         if( *s=='@')
3851           saw_at=1;
3852
3853         if( !*s || (*s & 0x80) || (!isgraph(*s) && !isspace(*s)) )
3854           {
3855             log_error(_("a notation name must have only printable characters "
3856                         "or spaces, and end with an '='\n") );
3857             return;
3858           }
3859       }
3860
3861     if(!saw_at && !opt.expert)
3862       {
3863         log_error(_("a user notation name must contain the '@' character\n"));
3864         return;
3865       }
3866
3867     /* we only support printable text - therefore we enforce the use
3868      * of only printable characters (an empty value is valid) */
3869     for( s++; *s ; s++ ) {
3870         if ((*s & 0x80))
3871           highbit = 1;
3872         else if (iscntrl(*s)) {
3873             log_error(_("a notation value must not use"
3874                         " any control characters\n") );
3875             return;
3876         }
3877     }
3878
3879     if( highbit )   /* must use UTF8 encoding */
3880         sl = add_to_strlist2( notation_data, string, utf8_strings );
3881     else
3882         sl = add_to_strlist( notation_data, string );
3883
3884     if( critical )
3885         sl->flags |= 1;
3886 }
3887
3888 static void
3889 add_policy_url( const char *string, int which )
3890 {
3891   unsigned int i,critical=0;
3892   STRLIST sl;
3893
3894   if(*string=='!')
3895     {
3896       string++;
3897       critical=1;
3898     }
3899
3900   for(i=0;i<strlen(string);i++)
3901     if(string[i]&0x80 || iscntrl(string[i]))
3902       break;
3903
3904   if(i==0 || i<strlen(string))
3905     {
3906       if(which)
3907         log_error(_("the given certification policy URL is invalid\n"));
3908       else
3909         log_error(_("the given signature policy URL is invalid\n"));
3910     }
3911
3912   if(which)
3913     sl=add_to_strlist( &opt.cert_policy_url, string );
3914   else
3915     sl=add_to_strlist( &opt.sig_policy_url, string );
3916
3917   if(critical)
3918     sl->flags |= 1;    
3919 }
3920
3921 static void
3922 add_keyserver_url( const char *string, int which )
3923 {
3924   unsigned int i,critical=0;
3925   STRLIST sl;
3926
3927   if(*string=='!')
3928     {
3929       string++;
3930       critical=1;
3931     }
3932
3933   for(i=0;i<strlen(string);i++)
3934     if(string[i]&0x80 || iscntrl(string[i]))
3935       break;
3936
3937   if(i==0 || i<strlen(string))
3938     {
3939       if(which)
3940         BUG();
3941       else
3942         log_error(_("the given preferred keyserver URL is invalid\n"));
3943     }
3944
3945   if(which)
3946     BUG();
3947   else
3948     sl=add_to_strlist( &opt.sig_keyserver_url, string );
3949
3950   if(critical)
3951     sl->flags |= 1;    
3952 }