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