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