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