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