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