g10: Avoid translating simple error messages.
[gnupg.git] / g10 / gpg.c
index 6daa144..cab5d53 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1,6 +1,7 @@
 /* gpg.c - The GnuPG utility (main for gpg)
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
- *               2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 1998-2011 Free Software Foundation, Inc.
+ * Copyright (C) 1997-2016 Werner Koch
+ * Copyright (C) 2015-2016 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
@@ -15,7 +16,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
-#include <assert.h>
 #ifdef HAVE_STAT
 #include <sys/stat.h> /* for stat() */
 #endif
 #include <fcntl.h>
 #ifdef HAVE_W32_SYSTEM
-#include <windows.h>
+# ifdef HAVE_WINSOCK2_H
+#  include <winsock2.h>
+# endif
+# include <windows.h>
 #endif
 
 #define INCLUDED_BY_MAIN_MODULE 1
 #include "../common/iobuf.h"
 #include "util.h"
 #include "packet.h"
+#include "membuf.h"
 #include "main.h"
 #include "options.h"
 #include "keydb.h"
 #include "trustdb.h"
-#include "cipher.h"
 #include "filter.h"
 #include "ttyio.h"
 #include "i18n.h"
 #include "gc-opt-flags.h"
 #include "asshelp.h"
 #include "call-dirmngr.h"
+#include "tofu.h"
+#include "../common/init.h"
+#include "../common/mbox-util.h"
+#include "../common/shareddefs.h"
 
 #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
 #define MY_O_BINARY  O_BINARY
@@ -75,6 +82,8 @@ enum cmd_and_opt_values
     aSym         = 'c',
     aDecrypt     = 'd',
     aEncr        = 'e',
+    oRecipientFile       = 'f',
+    oHiddenRecipientFile = 'F',
     oInteractive  = 'i',
     aListKeys    = 'k',
     oDryRun      = 'n',
@@ -91,6 +100,7 @@ enum cmd_and_opt_values
     aListSecretKeys = 'K',
     oBatch       = 500,
     oMaxOutput,
+    oInputSizeHint,
     oSigNotation,
     oCertNotation,
     oShowNotation,
@@ -100,13 +110,22 @@ enum cmd_and_opt_values
     aDecryptFiles,
     aClearsign,
     aStore,
+    aQuickKeygen,
+    aFullKeygen,
     aKeygen,
     aSignEncr,
     aSignEncrSym,
     aSignSym,
     aSignKey,
     aLSignKey,
+    aQuickSignKey,
+    aQuickLSignKey,
+    aQuickAddUid,
+    aQuickAddKey,
+    aQuickRevUid,
+    aQuickSetExpire,
     aListConfig,
+    aListGcryptConfig,
     aGPGConfList,
     aGPGConfTest,
     aListPackets,
@@ -128,6 +147,7 @@ enum cmd_and_opt_values
     aExport,
     aExportSecret,
     aExportSecretSub,
+    aExportSshKey,
     aCheckKeys,
     aGenRevoke,
     aDesigRevoke,
@@ -150,7 +170,9 @@ enum cmd_and_opt_values
     aChangePIN,
     aPasswd,
     aServer,
+    aTOFUPolicy,
 
+    oMimemode,
     oTextmode,
     oNoTextmode,
     oExpert,
@@ -167,7 +189,16 @@ enum cmd_and_opt_values
     oNoAskCertLevel,
     oFingerprint,
     oWithFingerprint,
+    oWithSubkeyFingerprint,
+    oWithICAOSpelling,
     oWithKeygrip,
+    oWithSecret,
+    oWithWKDHash,
+    oWithColons,
+    oWithKeyData,
+    oWithTofuInfo,
+    oWithSigList,
+    oWithSigCheck,
     oAnswerYes,
     oAnswerNo,
     oKeyring,
@@ -183,7 +214,7 @@ enum cmd_and_opt_values
     oDebug,
     oDebugLevel,
     oDebugAll,
-    oDebugCCIDDriver,
+    oDebugIOLBF,
     oStatusFD,
     oStatusFile,
     oAttributeFD,
@@ -194,15 +225,16 @@ enum cmd_and_opt_values
     oMarginalsNeeded,
     oMaxCertDepth,
     oLoadExtension,
+    oCompliance,
     oGnuPG,
-    oRFC1991,
     oRFC2440,
     oRFC4880,
+    oRFC4880bis,
     oOpenPGP,
-    oPGP2,
     oPGP6,
     oPGP7,
     oPGP8,
+    oDE_VS,
     oRFC2440Text,
     oNoRFC2440Text,
     oCipherAlgo,
@@ -216,6 +248,7 @@ enum cmd_and_opt_values
     oPassphraseFD,
     oPassphraseFile,
     oPassphraseRepeat,
+    oPinentryMode,
     oCommandFD,
     oCommandFile,
     oQuickRandom,
@@ -228,20 +261,15 @@ enum cmd_and_opt_values
     oNoMDCWarn,
     oNoArmor,
     oNoDefKeyring,
+    oNoKeyring,
     oNoGreeting,
     oNoTTY,
     oNoOptions,
     oNoBatch,
     oHomedir,
-    oWithColons,
-    oWithKeyData,
-    oWithSigList,
-    oWithSigCheck,
     oSkipVerify,
     oSkipHiddenRecipients,
     oNoSkipHiddenRecipients,
-    oCompressKeys,
-    oCompressSigs,
     oAlwaysTrust,
     oTrustModel,
     oForceOwnertrust,
@@ -264,10 +292,6 @@ enum cmd_and_opt_values
     oShowPhotos,
     oNoShowPhotos,
     oPhotoViewer,
-    oForceV3Sigs,
-    oNoForceV3Sigs,
-    oForceV4Certs,
-    oNoForceV4Certs,
     oForceMDC,
     oNoForceMDC,
     oDisableMDC,
@@ -286,7 +310,9 @@ enum cmd_and_opt_values
     oKeyServer,
     oKeyServerOptions,
     oImportOptions,
+    oImportFilter,
     oExportOptions,
+    oExportFilter,
     oListOptions,
     oVerifyOptions,
     oTempDir,
@@ -294,6 +320,7 @@ enum cmd_and_opt_values
     oEncryptTo,
     oHiddenEncryptTo,
     oNoEncryptTo,
+    oEncryptToDefaultKey,
     oLoggerFD,
     oLoggerFile,
     oUtf8Strings,
@@ -304,7 +331,7 @@ enum cmd_and_opt_values
     oNoAllowNonSelfsignedUID,
     oAllowFreeformUID,
     oNoAllowFreeformUID,
-    oAllowSecretKeyImport,                      
+    oAllowSecretKeyImport,
     oEnableSpecialFilenames,
     oNoLiteral,
     oSetFilesize,
@@ -317,6 +344,7 @@ enum cmd_and_opt_values
     oIgnoreMDCError,
     oShowSessionKey,
     oOverrideSessionKey,
+    oOverrideSessionKeyFD,
     oNoRandomSeedFile,
     oAutoKeyRetrieve,
     oNoAutoKeyRetrieve,
@@ -328,8 +356,8 @@ enum cmd_and_opt_values
     oTrustedKey,
     oNoExpensiveTrustChecks,
     oFixedListMode,
+    oLegacyListMode,
     oNoSigCache,
-    oNoSigCreateCheck,
     oAutoCheckTrustDB,
     oNoAutoCheckTrustDB,
     oPreservePermissions,
@@ -339,6 +367,7 @@ enum cmd_and_opt_values
     oPersonalDigestPreferences,
     oPersonalCompressPreferences,
     oAgentProgram,
+    oDirmngrProgram,
     oDisplay,
     oTTYname,
     oTTYtype,
@@ -357,16 +386,34 @@ enum cmd_and_opt_values
     oKeyidFormat,
     oExitOnStatusWriteError,
     oLimitCardInsertTries,
+    oReaderPort,
+    octapiDriver,
+    opcscDriver,
+    oDisableCCID,
     oRequireCrossCert,
     oNoRequireCrossCert,
     oAutoKeyLocate,
     oNoAutoKeyLocate,
     oAllowMultisigVerification,
+    oEnableLargeRSA,
+    oDisableLargeRSA,
     oEnableDSA2,
     oDisableDSA2,
     oAllowMultipleMessages,
     oNoAllowMultipleMessages,
+    oAllowWeakDigestAlgos,
     oFakedSystemTime,
+    oNoAutostart,
+    oPrintPKARecords,
+    oPrintDANERecords,
+    oTOFUDefaultPolicy,
+    oTOFUDBFormat,
+    oDefaultNewKeyAlgo,
+    oWeakDigest,
+    oUnwrap,
+    oOnlySignTextIDs,
+    oDisableSignerUID,
+    oSender,
 
     oNoop
   };
@@ -377,7 +424,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_group (300, N_("@Commands:\n ")),
 
   ARGPARSE_c (aSign, "sign", N_("make a signature")),
-  ARGPARSE_c (aClearsign, "clearsign", N_("make a clear text signature")),
+  ARGPARSE_c (aClearsign, "clear-sign", N_("make a clear text signature")),
+  ARGPARSE_c (aClearsign, "clearsign", "@"),
   ARGPARSE_c (aDetachedSign, "detach-sign", N_("make a detached signature")),
   ARGPARSE_c (aEncr, "encrypt",   N_("encrypt data")),
   ARGPARSE_c (aEncrFiles, "encrypt-files", "@"),
@@ -389,50 +437,87 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aVerifyFiles, "verify-files" , "@" ),
   ARGPARSE_c (aListKeys, "list-keys", N_("list keys")),
   ARGPARSE_c (aListKeys, "list-public-keys", "@" ),
-  ARGPARSE_c (aListSigs, "list-sigs", N_("list keys and signatures")),
-  ARGPARSE_c (aCheckKeys, "check-sigs",N_("list and check key signatures")),
+  ARGPARSE_c (aListSigs, "list-signatures", N_("list keys and signatures")),
+  ARGPARSE_c (aListSigs, "list-sigs", "@"),
+  ARGPARSE_c (aCheckKeys, "check-signatures",
+             N_("list and check key signatures")),
+  ARGPARSE_c (aCheckKeys, "check-sigs", "@"),
   ARGPARSE_c (oFingerprint, "fingerprint", N_("list keys and fingerprints")),
   ARGPARSE_c (aListSecretKeys, "list-secret-keys", N_("list secret keys")),
-  ARGPARSE_c (aKeygen,    "gen-key",  N_("generate a new key pair")),
-  ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
-  ARGPARSE_c (aDeleteKeys,"delete-keys", 
+  ARGPARSE_c (aKeygen,     "generate-key",
+              N_("generate a new key pair")),
+  ARGPARSE_c (aKeygen,     "gen-key", "@"),
+  ARGPARSE_c (aQuickKeygen, "quick-generate-key" ,
+              N_("quickly generate a new key pair")),
+  ARGPARSE_c (aQuickKeygen, "quick-gen-key", "@"),
+  ARGPARSE_c (aQuickAddUid,  "quick-add-uid",
+              N_("quickly add a new user-id")),
+  ARGPARSE_c (aQuickAddUid,  "quick-adduid", "@"),
+  ARGPARSE_c (aQuickAddKey,  "quick-add-key", "@"),
+  ARGPARSE_c (aQuickAddKey,  "quick-addkey", "@"),
+  ARGPARSE_c (aQuickRevUid,  "quick-revoke-uid",
+              N_("quickly revoke a user-id")),
+  ARGPARSE_c (aQuickRevUid,  "quick-revuid", "@"),
+  ARGPARSE_c (aQuickSetExpire,  "quick-set-expire",
+              N_("quickly set a new expiration date")),
+  ARGPARSE_c (aFullKeygen,  "full-generate-key" ,
+              N_("full featured key pair generation")),
+  ARGPARSE_c (aFullKeygen,  "full-gen-key", "@"),
+  ARGPARSE_c (aGenRevoke, "generate-revocation",
+             N_("generate a revocation certificate")),
+  ARGPARSE_c (aGenRevoke, "gen-revoke", "@"),
+  ARGPARSE_c (aDeleteKeys,"delete-keys",
               N_("remove keys from the public keyring")),
   ARGPARSE_c (aDeleteSecretKeys, "delete-secret-keys",
               N_("remove keys from the secret keyring")),
+  ARGPARSE_c (aQuickSignKey,  "quick-sign-key" ,
+              N_("quickly sign a key")),
+  ARGPARSE_c (aQuickLSignKey, "quick-lsign-key",
+              N_("quickly sign a key locally")),
   ARGPARSE_c (aSignKey,  "sign-key"   ,N_("sign a key")),
   ARGPARSE_c (aLSignKey, "lsign-key"  ,N_("sign a key locally")),
   ARGPARSE_c (aEditKey,  "edit-key"   ,N_("sign or edit a key")),
   ARGPARSE_c (aEditKey,  "key-edit"   ,"@"),
-  ARGPARSE_c (aPasswd,   "passwd",     N_("change a passphrase")),
+  ARGPARSE_c (aPasswd,   "change-passphrase", N_("change a passphrase")),
+  ARGPARSE_c (aPasswd,   "passwd", "@"),
+  ARGPARSE_c (aDesigRevoke, "generate-designated-revocation", "@"),
   ARGPARSE_c (aDesigRevoke, "desig-revoke","@" ),
   ARGPARSE_c (aExport, "export"           , N_("export keys") ),
-  ARGPARSE_c (aSendKeys, "send-keys"     , N_("export keys to a key server") ),
-  ARGPARSE_c (aRecvKeys, "recv-keys"     , N_("import keys from a key server") ),
-  ARGPARSE_c (aSearchKeys, "search-keys" , 
-              N_("search for keys on a key server") ),
-  ARGPARSE_c (aRefreshKeys, "refresh-keys", 
+  ARGPARSE_c (aSendKeys, "send-keys"     , N_("export keys to a keyserver") ),
+  ARGPARSE_c (aRecvKeys, "receive-keys" , N_("import keys from a keyserver") ),
+  ARGPARSE_c (aRecvKeys, "recv-keys"     , "@"),
+  ARGPARSE_c (aSearchKeys, "search-keys" ,
+              N_("search for keys on a keyserver") ),
+  ARGPARSE_c (aRefreshKeys, "refresh-keys",
               N_("update all keys from a keyserver")),
   ARGPARSE_c (aLocateKeys, "locate-keys", "@"),
   ARGPARSE_c (aFetchKeys, "fetch-keys" , "@" ),
   ARGPARSE_c (aExportSecret, "export-secret-keys" , "@" ),
   ARGPARSE_c (aExportSecretSub, "export-secret-subkeys" , "@" ),
+  ARGPARSE_c (aExportSshKey, "export-ssh-key", "@" ),
   ARGPARSE_c (aImport, "import", N_("import/merge keys")),
   ARGPARSE_c (aFastImport, "fast-import", "@"),
 #ifdef ENABLE_CARD_SUPPORT
   ARGPARSE_c (aCardStatus,  "card-status", N_("print the card status")),
-  ARGPARSE_c (aCardEdit,   "card-edit",  N_("change data on a card")),
+  ARGPARSE_c (aCardEdit,   "edit-card",  N_("change data on a card")),
+  ARGPARSE_c (aCardEdit,   "card-edit", "@"),
   ARGPARSE_c (aChangePIN,  "change-pin", N_("change a card's PIN")),
 #endif
   ARGPARSE_c (aListConfig, "list-config", "@"),
+  ARGPARSE_c (aListGcryptConfig, "list-gcrypt-config", "@"),
   ARGPARSE_c (aGPGConfList, "gpgconf-list", "@" ),
   ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@" ),
   ARGPARSE_c (aListPackets, "list-packets","@"),
+
+#ifndef NO_TRUST_MODELS
   ARGPARSE_c (aExportOwnerTrust, "export-ownertrust", "@"),
   ARGPARSE_c (aImportOwnerTrust, "import-ownertrust", "@"),
   ARGPARSE_c (aUpdateTrustDB,"update-trustdb",
               N_("update the trust database")),
   ARGPARSE_c (aCheckTrustDB, "check-trustdb", "@"),
   ARGPARSE_c (aFixTrustDB, "fix-trustdb", "@"),
+#endif
+
   ARGPARSE_c (aDeArmor, "dearmor", "@"),
   ARGPARSE_c (aDeArmor, "dearmour", "@"),
   ARGPARSE_c (aEnArmor, "enarmor", "@"),
@@ -441,6 +526,8 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aPrimegen, "gen-prime", "@" ),
   ARGPARSE_c (aGenRandom,"gen-random", "@" ),
   ARGPARSE_c (aServer,   "server",  N_("run in server mode")),
+  ARGPARSE_c (aTOFUPolicy, "tofu-policy",
+             N_("|VALUE|set the TOFU policy for a key")),
 
   ARGPARSE_group (301, N_("@\nOptions:\n ")),
 
@@ -449,6 +536,8 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oRecipient, "recipient", N_("|USER-ID|encrypt for USER-ID")),
   ARGPARSE_s_s (oHiddenRecipient, "hidden-recipient", "@"),
+  ARGPARSE_s_s (oRecipientFile, "recipient-file", "@"),
+  ARGPARSE_s_s (oHiddenRecipientFile, "hidden-recipient-file", "@"),
   ARGPARSE_s_s (oRecipient, "remote-user", "@"),  /* (old option name) */
   ARGPARSE_s_s (oDefRecipient, "default-recipient", "@"),
   ARGPARSE_s_n (oDefRecipientSelf,  "default-recipient-self", "@"),
@@ -459,8 +548,10 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oEncryptTo,      "encrypt-to", "@"),
   ARGPARSE_s_n (oNoEncryptTo, "no-encrypt-to", "@"),
   ARGPARSE_s_s (oHiddenEncryptTo, "hidden-encrypt-to", "@"),
+  ARGPARSE_s_n (oEncryptToDefaultKey, "encrypt-to-default-key", "@"),
   ARGPARSE_s_s (oLocalUser, "local-user",
                 N_("|USER-ID|use USER-ID to sign or decrypt")),
+  ARGPARSE_s_s (oSender, "sender", "@"),
 
   ARGPARSE_s_s (oTrySecretKey, "try-secret-key", "@"),
 
@@ -470,8 +561,9 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_i (oBZ2CompressLevel, "bzip2-compress-level", "@"),
   ARGPARSE_s_n (oBZ2DecompressLowmem, "bzip2-decompress-lowmem", "@"),
 
+  ARGPARSE_s_n (oMimemode, "mimemode", "@"),
   ARGPARSE_s_n (oTextmodeShort, NULL, "@"),
-  ARGPARSE_s_n (oTextmode,      "textmode", N_("use canonical text mode")),
+  ARGPARSE_s_n (oTextmode,   "textmode", N_("use canonical text mode")),
   ARGPARSE_s_n (oNoTextmode, "no-textmode", "@"),
 
   ARGPARSE_s_n (oExpert,      "expert", "@"),
@@ -490,27 +582,22 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")),
   ARGPARSE_p_u (oMaxOutput, "max-output", "@"),
+  ARGPARSE_s_s (oInputSizeHint, "input-size-hint", "@"),
 
   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
   ARGPARSE_s_n (oQuiet,          "quiet",   "@"),
   ARGPARSE_s_n (oNoTTY,   "no-tty",  "@"),
 
-  ARGPARSE_s_n (oForceV3Sigs,      "force-v3-sigs", "@"),
-  ARGPARSE_s_n (oNoForceV3Sigs, "no-force-v3-sigs", "@"),
-  ARGPARSE_s_n (oForceV4Certs,     "force-v4-certs", "@"),
-  ARGPARSE_s_n (oNoForceV4Certs, "no-force-v4-certs", "@"),
   ARGPARSE_s_n (oForceMDC, "force-mdc", "@"),
   ARGPARSE_s_n (oNoForceMDC, "no-force-mdc", "@"),
   ARGPARSE_s_n (oDisableMDC, "disable-mdc", "@"),
   ARGPARSE_s_n (oNoDisableMDC, "no-disable-mdc", "@"),
 
+  ARGPARSE_s_n (oDisableSignerUID, "disable-signer-uid", "@"),
+
   ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
   ARGPARSE_s_n (oInteractive, "interactive", N_("prompt before overwriting")),
 
-  ARGPARSE_s_n (oUseAgent,      "use-agent", "@"),
-  ARGPARSE_s_n (oNoUseAgent, "no-use-agent", "@"),
-  ARGPARSE_s_s (oGpgAgentInfo, "gpg-agent-info", "@"),
-
   ARGPARSE_s_n (oBatch, "batch", "@"),
   ARGPARSE_s_n (oAnswerYes, "yes", "@"),
   ARGPARSE_s_n (oAnswerNo, "no", "@"),
@@ -523,7 +610,9 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oKeyServer, "keyserver", "@"),
   ARGPARSE_s_s (oKeyServerOptions, "keyserver-options", "@"),
   ARGPARSE_s_s (oImportOptions, "import-options", "@"),
+  ARGPARSE_s_s (oImportFilter,  "import-filter", "@"),
   ARGPARSE_s_s (oExportOptions, "export-options", "@"),
+  ARGPARSE_s_s (oExportFilter,  "export-filter", "@"),
   ARGPARSE_s_s (oListOptions,   "list-options", "@"),
   ARGPARSE_s_s (oVerifyOptions, "verify-options", "@"),
 
@@ -531,17 +620,15 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oDisplayCharset, "charset", "@"),
   ARGPARSE_s_s (oOptions, "options", "@"),
 
-  ARGPARSE_p_u (oDebug, "debug", "@"),
+  ARGPARSE_s_s (oDebug, "debug", "@"),
   ARGPARSE_s_s (oDebugLevel, "debug-level", "@"),
   ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
+  ARGPARSE_s_n (oDebugIOLBF, "debug-iolbf", "@"),
   ARGPARSE_s_i (oStatusFD, "status-fd", "@"),
   ARGPARSE_s_s (oStatusFile, "status-file", "@"),
   ARGPARSE_s_i (oAttributeFD, "attribute-fd", "@"),
   ARGPARSE_s_s (oAttributeFile, "attribute-file", "@"),
 
-  ARGPARSE_s_n (oNoop, "sk-comments", "@"),
-  ARGPARSE_s_n (oNoop, "no-sk-comments", "@"),
-
   ARGPARSE_s_i (oCompletesNeeded, "completes-needed", "@"),
   ARGPARSE_s_i (oMarginalsNeeded, "marginals-needed", "@"),
   ARGPARSE_s_i (oMaxCertDepth, "max-cert-depth", "@" ),
@@ -549,16 +636,16 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oLoadExtension, "load-extension", "@"),  /* Dummy.  */
 
+  ARGPARSE_s_s (oCompliance, "compliance",   "@"),
   ARGPARSE_s_n (oGnuPG, "gnupg",   "@"),
   ARGPARSE_s_n (oGnuPG, "no-pgp2", "@"),
   ARGPARSE_s_n (oGnuPG, "no-pgp6", "@"),
   ARGPARSE_s_n (oGnuPG, "no-pgp7", "@"),
   ARGPARSE_s_n (oGnuPG, "no-pgp8", "@"),
-  ARGPARSE_s_n (oRFC1991, "rfc1991", "@"),
   ARGPARSE_s_n (oRFC2440, "rfc2440", "@"),
   ARGPARSE_s_n (oRFC4880, "rfc4880", "@"),
+  ARGPARSE_s_n (oRFC4880bis, "rfc4880bis", "@"),
   ARGPARSE_s_n (oOpenPGP, "openpgp", N_("use strict OpenPGP behavior")),
-  ARGPARSE_s_n (oPGP2, "pgp2", "@"),
   ARGPARSE_s_n (oPGP6, "pgp6", "@"),
   ARGPARSE_s_n (oPGP7, "pgp7", "@"),
   ARGPARSE_s_n (oPGP8, "pgp8", "@"),
@@ -574,15 +661,12 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"),
   ARGPARSE_s_s (oCompressAlgo,"compress-algo", "@"),
   ARGPARSE_s_s (oCompressAlgo, "compression-algo", "@"), /* Alias */
-  ARGPARSE_s_n (oThrowKeyids, "throw-keyid", "@"),
   ARGPARSE_s_n (oThrowKeyids, "throw-keyids", "@"),
-  ARGPARSE_s_n (oNoThrowKeyids, "no-throw-keyid", "@"),
   ARGPARSE_s_n (oNoThrowKeyids, "no-throw-keyids", "@"),
   ARGPARSE_s_n (oShowPhotos,   "show-photos", "@"),
   ARGPARSE_s_n (oNoShowPhotos, "no-show-photos", "@"),
   ARGPARSE_s_s (oPhotoViewer,  "photo-viewer", "@"),
   ARGPARSE_s_s (oSetNotation,  "set-notation", "@"),
-  ARGPARSE_s_s (oSetNotation,  "notation-data", "@"), /* Alias */
   ARGPARSE_s_s (oSigNotation,  "sig-notation", "@"),
   ARGPARSE_s_s (oCertNotation, "cert-notation", "@"),
 
@@ -592,15 +676,18 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_group (303, N_("@\nExamples:\n\n"
     " -se -r Bob [file]          sign and encrypt for user Bob\n"
-    " --clearsign [file]         make a clear text signature\n"
+    " --clear-sign [file]        make a clear text signature\n"
     " --detach-sign [file]       make a detached signature\n"
     " --list-keys [names]        show keys\n"
     " --fingerprint [names]      show fingerprints\n")),
 
   /* More hidden commands and options. */
   ARGPARSE_c (aPrintMDs, "print-mds", "@"), /* old */
+#ifndef NO_TRUST_MODELS
   ARGPARSE_c (aListTrustDB, "list-trustdb", "@"),
-  /* Not yet used: 
+#endif
+
+  /* Not yet used:
      ARGPARSE_c (aListTrustPath, "list-trust-path", "@"), */
   ARGPARSE_c (aDeleteSecretAndPublicKeys,
               "delete-secret-and-public-keys", "@"),
@@ -610,11 +697,19 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_i (oPassphraseFD,    "passphrase-fd", "@"),
   ARGPARSE_s_s (oPassphraseFile,  "passphrase-file", "@"),
   ARGPARSE_s_i (oPassphraseRepeat,"passphrase-repeat", "@"),
+  ARGPARSE_s_s (oPinentryMode,    "pinentry-mode", "@"),
   ARGPARSE_s_i (oCommandFD, "command-fd", "@"),
   ARGPARSE_s_s (oCommandFile, "command-file", "@"),
   ARGPARSE_s_n (oQuickRandom, "debug-quick-random", "@"),
   ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
+
+#ifndef NO_TRUST_MODELS
   ARGPARSE_s_s (oTrustDBName, "trustdb-name", "@"),
+  ARGPARSE_s_n (oAutoCheckTrustDB, "auto-check-trustdb", "@"),
+  ARGPARSE_s_n (oNoAutoCheckTrustDB, "no-auto-check-trustdb", "@"),
+  ARGPARSE_s_s (oForceOwnertrust, "force-ownertrust", "@"),
+#endif
+
   ARGPARSE_s_n (oNoSecmemWarn, "no-secmem-warning", "@"),
   ARGPARSE_s_n (oRequireSecmem, "require-secmem", "@"),
   ARGPARSE_s_n (oNoRequireSecmem, "no-require-secmem", "@"),
@@ -623,11 +718,13 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oNoArmor, "no-armor", "@"),
   ARGPARSE_s_n (oNoArmor, "no-armour", "@"),
   ARGPARSE_s_n (oNoDefKeyring, "no-default-keyring", "@"),
+  ARGPARSE_s_n (oNoKeyring, "no-keyring", "@"),
   ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
-  ARGPARSE_s_n (oNoOptions, "no-options", "@"), 
-  ARGPARSE_s_s (oHomedir, "homedir", "@"), 
+  ARGPARSE_s_n (oNoOptions, "no-options", "@"),
+  ARGPARSE_s_s (oHomedir, "homedir", "@"),
   ARGPARSE_s_n (oNoBatch, "no-batch", "@"),
   ARGPARSE_s_n (oWithColons, "with-colons", "@"),
+  ARGPARSE_s_n (oWithTofuInfo,"with-tofu-info", "@"),
   ARGPARSE_s_n (oWithKeyData,"with-key-data", "@"),
   ARGPARSE_s_n (oWithSigList,"with-sig-list", "@"),
   ARGPARSE_s_n (oWithSigCheck,"with-sig-check", "@"),
@@ -637,12 +734,12 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oSkipVerify, "skip-verify", "@"),
   ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"),
   ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"),
-  ARGPARSE_s_n (oCompressKeys, "compress-keys", "@"),
-  ARGPARSE_s_n (oCompressSigs, "compress-sigs", "@"),
   ARGPARSE_s_i (oDefCertLevel, "default-cert-check-level", "@"), /* old */
+#ifndef NO_TRUST_MODELS
   ARGPARSE_s_n (oAlwaysTrust, "always-trust", "@"),
+#endif
   ARGPARSE_s_s (oTrustModel, "trust-model", "@"),
-  ARGPARSE_s_s (oForceOwnertrust, "force-ownertrust", "@"),
+  ARGPARSE_s_s (oTOFUDefaultPolicy, "tofu-default-policy", "@"),
   ARGPARSE_s_s (oSetFilename, "set-filename", "@"),
   ARGPARSE_s_n (oForYourEyesOnly, "for-your-eyes-only", "@"),
   ARGPARSE_s_n (oNoForYourEyesOnly, "no-for-your-eyes-only", "@"),
@@ -674,7 +771,12 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oUtf8Strings,      "utf8-strings", "@"),
   ARGPARSE_s_n (oNoUtf8Strings, "no-utf8-strings", "@"),
   ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"),
+  ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprint", "@"),
+  ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprints", "@"),
+  ARGPARSE_s_n (oWithICAOSpelling, "with-icao-spelling", "@"),
   ARGPARSE_s_n (oWithKeygrip,     "with-keygrip", "@"),
+  ARGPARSE_s_n (oWithSecret,      "with-secret", "@"),
+  ARGPARSE_s_n (oWithWKDHash,     "with-wkd-hash", "@"),
   ARGPARSE_s_s (oDisableCipherAlgo,  "disable-cipher-algo", "@"),
   ARGPARSE_s_s (oDisablePubkeyAlgo,  "disable-pubkey-algo", "@"),
   ARGPARSE_s_n (oAllowNonSelfsignedUID,      "allow-non-selfsigned-uid", "@"),
@@ -683,23 +785,23 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oNoAllowFreeformUID, "no-allow-freeform-uid", "@"),
   ARGPARSE_s_n (oNoLiteral, "no-literal", "@"),
   ARGPARSE_p_u (oSetFilesize, "set-filesize", "@"),
-  ARGPARSE_s_n (oHonorHttpProxy, "honor-http-proxy", "@"),
   ARGPARSE_s_n (oFastListMode, "fast-list-mode", "@"),
   ARGPARSE_s_n (oFixedListMode, "fixed-list-mode", "@"),
+  ARGPARSE_s_n (oLegacyListMode, "legacy-list-mode", "@"),
   ARGPARSE_s_n (oListOnly, "list-only", "@"),
+  ARGPARSE_s_n (oPrintPKARecords, "print-pka-records", "@"),
+  ARGPARSE_s_n (oPrintDANERecords, "print-dane-records", "@"),
   ARGPARSE_s_n (oIgnoreTimeConflict, "ignore-time-conflict", "@"),
   ARGPARSE_s_n (oIgnoreValidFrom,    "ignore-valid-from", "@"),
   ARGPARSE_s_n (oIgnoreCrcError, "ignore-crc-error", "@"),
   ARGPARSE_s_n (oIgnoreMDCError, "ignore-mdc-error", "@"),
   ARGPARSE_s_n (oShowSessionKey, "show-session-key", "@"),
   ARGPARSE_s_s (oOverrideSessionKey, "override-session-key", "@"),
+  ARGPARSE_s_i (oOverrideSessionKeyFD, "override-session-key-fd", "@"),
   ARGPARSE_s_n (oNoRandomSeedFile,  "no-random-seed-file", "@"),
   ARGPARSE_s_n (oAutoKeyRetrieve, "auto-key-retrieve", "@"),
   ARGPARSE_s_n (oNoAutoKeyRetrieve, "no-auto-key-retrieve", "@"),
   ARGPARSE_s_n (oNoSigCache,         "no-sig-cache", "@"),
-  ARGPARSE_s_n (oNoSigCreateCheck,   "no-sig-create-check", "@"),
-  ARGPARSE_s_n (oAutoCheckTrustDB, "auto-check-trustdb", "@"),
-  ARGPARSE_s_n (oNoAutoCheckTrustDB, "no-auto-check-trustdb", "@"),
   ARGPARSE_s_n (oMergeOnly,      "merge-only", "@" ),
   ARGPARSE_s_n (oAllowSecretKeyImport, "allow-secret-key-import", "@"),
   ARGPARSE_s_n (oTryAllSecrets,  "try-all-secrets", "@"),
@@ -713,13 +815,18 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oPersonalCompressPreferences,
                                          "personal-compress-preferences", "@"),
   ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
+  ARGPARSE_s_s (oWeakDigest, "weak-digest","@"),
+  ARGPARSE_s_n (oUnwrap, "unwrap", "@"),
+  ARGPARSE_s_n (oOnlySignTextIDs, "only-sign-text-ids", "@"),
 
   /* Aliases.  I constantly mistype these, and assume other people do
      as well. */
   ARGPARSE_s_s (oPersonalCipherPreferences, "personal-cipher-prefs", "@"),
   ARGPARSE_s_s (oPersonalDigestPreferences, "personal-digest-prefs", "@"),
   ARGPARSE_s_s (oPersonalCompressPreferences, "personal-compress-prefs", "@"),
+
   ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
+  ARGPARSE_s_s (oDirmngrProgram, "dirmngr-program", "@"),
   ARGPARSE_s_s (oDisplay,    "display",    "@"),
   ARGPARSE_s_s (oTTYname,    "ttyname",    "@"),
   ARGPARSE_s_s (oTTYtype,    "ttytype",    "@"),
@@ -738,13 +845,18 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oKeyidFormat, "keyid-format", "@"),
   ARGPARSE_s_n (oExitOnStatusWriteError, "exit-on-status-write-error", "@"),
   ARGPARSE_s_i (oLimitCardInsertTries, "limit-card-insert-tries", "@"),
-  
-  ARGPARSE_s_n (oAllowMultisigVerification, 
+
+  ARGPARSE_s_n (oAllowMultisigVerification,
                 "allow-multisig-verification", "@"),
+  ARGPARSE_s_n (oEnableLargeRSA, "enable-large-rsa", "@"),
+  ARGPARSE_s_n (oDisableLargeRSA, "disable-large-rsa", "@"),
   ARGPARSE_s_n (oEnableDSA2, "enable-dsa2", "@"),
   ARGPARSE_s_n (oDisableDSA2, "disable-dsa2", "@"),
   ARGPARSE_s_n (oAllowMultipleMessages,      "allow-multiple-messages", "@"),
   ARGPARSE_s_n (oNoAllowMultipleMessages, "no-allow-multiple-messages", "@"),
+  ARGPARSE_s_n (oAllowWeakDigestAlgos, "allow-weak-digest-algos", "@"),
+
+  ARGPARSE_s_s (oDefaultNewKeyAlgo, "default-new-key-algo", "@"),
 
   /* These two are aliases to help users of the PGP command line
      product use gpg with minimal pain.  Many commands are common
@@ -761,11 +873,55 @@ static ARGPARSE_OPTS opts[] = {
   /* New options.  Fixme: Should go more to the top.  */
   ARGPARSE_s_s (oAutoKeyLocate, "auto-key-locate", "@"),
   ARGPARSE_s_n (oNoAutoKeyLocate, "no-auto-key-locate", "@"),
+  ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"),
+
+  /* Dummy options with warnings.  */
+  ARGPARSE_s_n (oUseAgent,      "use-agent", "@"),
+  ARGPARSE_s_n (oNoUseAgent, "no-use-agent", "@"),
+  ARGPARSE_s_s (oGpgAgentInfo, "gpg-agent-info", "@"),
+  ARGPARSE_s_s (oReaderPort, "reader-port", "@"),
+  ARGPARSE_s_s (octapiDriver, "ctapi-driver", "@"),
+  ARGPARSE_s_s (opcscDriver, "pcsc-driver", "@"),
+  ARGPARSE_s_n (oDisableCCID, "disable-ccid", "@"),
+  ARGPARSE_s_n (oHonorHttpProxy, "honor-http-proxy", "@"),
+  ARGPARSE_s_s (oTOFUDBFormat, "tofu-db-format", "@"),
+
+  /* Dummy options.  */
+  ARGPARSE_s_n (oNoop, "sk-comments", "@"),
+  ARGPARSE_s_n (oNoop, "no-sk-comments", "@"),
+  ARGPARSE_s_n (oNoop, "compress-keys", "@"),
+  ARGPARSE_s_n (oNoop, "compress-sigs", "@"),
+  ARGPARSE_s_n (oNoop, "force-v3-sigs", "@"),
+  ARGPARSE_s_n (oNoop, "no-force-v3-sigs", "@"),
+  ARGPARSE_s_n (oNoop, "force-v4-certs", "@"),
+  ARGPARSE_s_n (oNoop, "no-force-v4-certs", "@"),
 
   ARGPARSE_end ()
 };
 
 
+/* The list of supported debug flags.  */
+static struct debug_flags_s debug_flags [] =
+  {
+    { DBG_PACKET_VALUE , "packet"  },
+    { DBG_MPI_VALUE    , "mpi"     },
+    { DBG_CRYPTO_VALUE , "crypto"  },
+    { DBG_FILTER_VALUE , "filter"  },
+    { DBG_IOBUF_VALUE  , "iobuf"   },
+    { DBG_MEMORY_VALUE , "memory"  },
+    { DBG_CACHE_VALUE  , "cache"   },
+    { DBG_MEMSTAT_VALUE, "memstat" },
+    { DBG_TRUST_VALUE  , "trust"   },
+    { DBG_HASHING_VALUE, "hashing" },
+    { DBG_CARD_IO_VALUE, "cardio"  },
+    { DBG_IPC_VALUE    , "ipc"     },
+    { DBG_CLOCK_VALUE  , "clock"   },
+    { DBG_LOOKUP_VALUE , "lookup"  },
+    { DBG_EXTPROG_VALUE, "extprog" },
+    { 0, NULL }
+  };
+
+
 #ifdef ENABLE_SELINUX_HACKS
 #define ALWAYS_ADD_KEYRINGS 1
 #else
@@ -787,6 +943,7 @@ static void add_notation_data( const char *string, int which );
 static void add_policy_url( const char *string, int which );
 static void add_keyserver_url( const char *string, int which );
 static void emergency_cleanup (void);
+static void read_sessionkey_from_fd (int fd);
 
 
 static char *
@@ -794,7 +951,7 @@ make_libversion (const char *libname, const char *(*getfnc)(const char*))
 {
   const char *s;
   char *result;
-  
+
   if (maybe_setuid)
     {
       gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
@@ -807,6 +964,54 @@ make_libversion (const char *libname, const char *(*getfnc)(const char*))
 }
 
 
+static int
+build_list_pk_test_algo (int algo)
+{
+  /* Show only one "RSA" string.  If RSA_E or RSA_S is available RSA
+     is also available.  */
+  if (algo == PUBKEY_ALGO_RSA_E
+      || algo == PUBKEY_ALGO_RSA_S)
+    return GPG_ERR_DIGEST_ALGO;
+
+  return openpgp_pk_test_algo (algo);
+}
+
+static const char *
+build_list_pk_algo_name (int algo)
+{
+  return openpgp_pk_algo_name (algo);
+}
+
+static int
+build_list_cipher_test_algo (int algo)
+{
+  return openpgp_cipher_test_algo (algo);
+}
+
+static const char *
+build_list_cipher_algo_name (int algo)
+{
+  return openpgp_cipher_algo_name (algo);
+}
+
+static int
+build_list_md_test_algo (int algo)
+{
+  /* By default we do not accept MD5 based signatures.  To avoid
+     confusion we do not announce support for it either.  */
+  if (algo == DIGEST_ALGO_MD5)
+    return GPG_ERR_DIGEST_ALGO;
+
+  return openpgp_md_test_algo (algo);
+}
+
+static const char *
+build_list_md_algo_name (int algo)
+{
+  return openpgp_md_algo_name (algo);
+}
+
+
 static const char *
 my_strusage( int level )
 {
@@ -814,7 +1019,7 @@ my_strusage( int level )
   const char *p;
 
     switch( level ) {
-      case 11: p = "gpg (GnuPG)";
+      case 11: p = "@GPG@ (@GNUPG@)";
        break;
       case 13: p = VERSION; break;
       case 17: p = PRINTABLE_OS_NAME; break;
@@ -840,40 +1045,40 @@ my_strusage( int level )
 
       case 1:
       case 40: p =
-           _("Usage: gpg [options] [files] (-h for help)");
+           _("Usage: @GPG@ [options] [files] (-h for help)");
        break;
       case 41: p =
-           _("Syntax: gpg [options] [files]\n"
-             "sign, check, encrypt or decrypt\n"
-             "default operation depends on the input data\n");
+           _("Syntax: @GPG@ [options] [files]\n"
+             "Sign, check, encrypt or decrypt\n"
+             "Default operation depends on the input data\n");
        break;
 
       case 31: p = "\nHome: "; break;
 #ifndef __riscos__
-      case 32: p = opt.homedir; break;
+      case 32: p = gnupg_homedir (); break;
 #else /* __riscos__ */
-      case 32: p = make_filename(opt.homedir, NULL); break;
+      case 32: p = make_filename(gnupg_homedir (), NULL); break;
 #endif /* __riscos__ */
       case 33: p = _("\nSupported algorithms:\n"); break;
       case 34:
        if (!pubkeys)
-            pubkeys = build_list (_("Pubkey: "), 0,
-                                  openpgp_pk_algo_name,
-                                  openpgp_pk_test_algo );
+            pubkeys = build_list (_("Pubkey: "), 1,
+                                  build_list_pk_algo_name,
+                                  build_list_pk_test_algo );
        p = pubkeys;
        break;
       case 35:
        if( !ciphers )
-           ciphers = build_list(_("Cipher: "), 'S', 
-                                 openpgp_cipher_algo_name,
-                                 openpgp_cipher_test_algo );
+           ciphers = build_list(_("Cipher: "), 'S',
+                                 build_list_cipher_algo_name,
+                                 build_list_cipher_test_algo );
        p = ciphers;
        break;
       case 36:
        if( !digests )
-           digests = build_list(_("Hash: "), 'H', 
-                                 gcry_md_algo_name,
-                                 openpgp_md_test_algo );
+           digests = build_list(_("Hash: "), 'H',
+                                 build_list_md_algo_name,
+                                 build_list_md_test_algo );
        p = digests;
        break;
       case 37:
@@ -891,67 +1096,64 @@ my_strusage( int level )
 
 
 static char *
-build_listconst char *text, char letter,
-           const char * (*mapf)(int), int (*chkf)(int) )
+build_list (const char *text, char letter,
+           const char * (*mapf)(int), int (*chkf)(int))
 {
-    int i;
-    const char *s;
-    size_t n=strlen(text)+2;
-    char *list, *p, *line=NULL;
-
-    if (maybe_setuid)
-      gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
-
-    for(i=0; i <= 110; i++ )
-       if( !chkf(i) && (s=mapf(i)) )
-           n += strlen(s) + 7 + 2;
-    list = xmalloc( 21 + n ); *list = 0;
-    for(p=NULL, i=0; i <= 110; i++ ) {
-       if( !chkf(i) && (s=mapf(i)) ) {
-           if( !p ) {
-               p = stpcpy( list, text );
-               line=p;
-           }
-           else
-               p = stpcpy( p, ", ");
+  membuf_t mb;
+  int indent;
+  int i, j, len;
+  const char *s;
+  char *string;
 
-           if(strlen(line)>60) {
-             int spaces=strlen(text);
+  if (maybe_setuid)
+    gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
 
-             list=xrealloc(list,n+spaces+1);
-             /* realloc could move the block, so find the end again */
-             p=list;
-             while(*p)
-               p++;
+  indent = utf8_charcount (text, -1);
+  len = 0;
+  init_membuf (&mb, 512);
 
-             p=stpcpy(p, "\n");
-             line=p;
-             for(;spaces;spaces--)
-               p=stpcpy(p, " ");
+  for (i=0; i <= 110; i++ )
+    {
+      if (!chkf (i) && (s = mapf (i)))
+        {
+          if (mb.len - len > 60)
+            {
+              put_membuf_str (&mb, ",\n");
+              len = mb.len;
+              for (j=0; j < indent; j++)
+                put_membuf_str (&mb, " ");
            }
+          else if (mb.len)
+            put_membuf_str (&mb, ", ");
+          else
+            put_membuf_str (&mb, text);
 
-           p = stpcpy(p, s );
-           if(opt.verbose && letter)
-             {
-               char num[8];
-               sprintf(num," (%c%d)",letter,i);
-               p = stpcpy(p,num);
-             }
+          put_membuf_str (&mb, s);
+          if (opt.verbose && letter)
+            {
+              char num[20];
+              if (letter == 1)
+                snprintf (num, sizeof num, " (%d)", i);
+              else
+                snprintf (num, sizeof num, " (%c%d)", letter, i);
+              put_membuf_str (&mb, num);
+            }
        }
     }
-    if( p )
-       p = stpcpy(p, "\n" );
-    return list;
+  if (mb.len)
+    put_membuf_str (&mb, "\n");
+  put_membuf (&mb, "", 1);
+
+  string = get_membuf (&mb, NULL);
+  return xrealloc (string, strlen (string)+1);
 }
 
 
 static void
 wrong_args( const char *text)
 {
-    fputs(_("usage: gpg [options] "),stderr);
-    fputs(text,stderr);
-    putc('\n',stderr);
-    g10_exit(2);
+  es_fprintf (es_stderr, _("usage: %s [options] %s\n"), GPG_NAME, text);
+  g10_exit(2);
 }
 
 
@@ -971,13 +1173,14 @@ static void
 set_opt_session_env (const char *name, const char *value)
 {
   gpg_error_t err;
-  
+
   err = session_env_setenv (opt.session_env, name, value);
   if (err)
     log_fatal ("error setting session environment: %s\n",
                gpg_strerror (err));
 }
 
+
 /* Setup the debugging.  With a LEVEL of NULL only the active debug
    flags are propagated to the subsystems.  With LEVEL set, a specific
    set of debug flags is set; thus overriding all flags already
@@ -998,62 +1201,37 @@ set_debug (const char *level)
     opt.debug = DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE;
   else if (!strcmp (level, "expert")  || (numok && numlvl <= 8))
     opt.debug = (DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE
-                 |DBG_CACHE_VALUE|DBG_FILTER_VALUE|DBG_PACKET_VALUE);
+                 |DBG_CACHE_VALUE|DBG_LOOKUP|DBG_FILTER_VALUE|DBG_PACKET_VALUE);
   else if (!strcmp (level, "guru") || numok)
     {
       opt.debug = ~0;
       /* Unless the "guru" string has been used we don't want to allow
          hashing debugging.  The rationale is that people tend to
          select the highest debug value and would then clutter their
-         disk with debug files which may reveal confidential data.  */ 
+         disk with debug files which may reveal confidential data.  */
       if (numok)
         opt.debug &= ~(DBG_HASHING_VALUE);
     }
   else
     {
-      log_error (_("invalid debug-level `%s' given\n"), level);
+      log_error (_("invalid debug-level '%s' given\n"), level);
       g10_exit (2);
     }
 
-  if (opt.debug & DBG_MEMORY_VALUE )
+  if ((opt.debug & DBG_MEMORY_VALUE))
     memory_debug_mode = 1;
-  if (opt.debug & DBG_MEMSTAT_VALUE )
+  if ((opt.debug & DBG_MEMSTAT_VALUE))
     memory_stat_debug_mode = 1;
-  if (opt.debug & DBG_MPI_VALUE)
+  if (DBG_MPI)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
-  if (opt.debug & DBG_CIPHER_VALUE )
+  if (DBG_CRYPTO)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
-  if (opt.debug & DBG_IOBUF_VALUE )
+  if ((opt.debug & DBG_IOBUF_VALUE))
     iobuf_debug_mode = 1;
   gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
 
   if (opt.debug)
-    log_info ("enabled debug flags:%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
-              (opt.debug & DBG_PACKET_VALUE )? " packet":"",    
-              (opt.debug & DBG_MPI_VALUE    )? " mpi":"",    
-              (opt.debug & DBG_CIPHER_VALUE )? " cipher":"",    
-              (opt.debug & DBG_FILTER_VALUE )? " filter":"", 
-              (opt.debug & DBG_IOBUF_VALUE  )? " iobuf":"", 
-              (opt.debug & DBG_MEMORY_VALUE )? " memory":"", 
-              (opt.debug & DBG_CACHE_VALUE  )? " cache":"", 
-              (opt.debug & DBG_MEMSTAT_VALUE)? " memstat":"", 
-              (opt.debug & DBG_TRUST_VALUE  )? " trust":"", 
-              (opt.debug & DBG_HASHING_VALUE)? " hashing":"", 
-              (opt.debug & DBG_EXTPROG_VALUE)? " extprog":"", 
-              (opt.debug & DBG_CARD_IO_VALUE)? " cardio":"",
-              (opt.debug & DBG_ASSUAN_VALUE )? " assuan":"");
-}
-
-
-
-/* We need the home directory also in some other directories, so make
-   sure that both variables are always in sync. */
-static void
-set_homedir (const char *dir)
-{
-  if (!dir)
-    dir = "";
-  opt.homedir = dir;
+    parse_debug_flag (NULL, &opt.debug, debug_flags);
 }
 
 
@@ -1102,7 +1280,7 @@ open_info_file (const char *fname, int for_write, int binary)
   (void)for_write;
   (void)binary;
   return -1;
-#else 
+#else
   int fd;
 
   if (binary)
@@ -1126,9 +1304,9 @@ open_info_file (const char *fname, int for_write, int binary)
       while (fd == -1 && errno == EINTR);
 /*     } */
   if ( fd == -1)
-    log_error ( for_write? _("can't create `%s': %s\n")
-                         : _("can't open `%s': %s\n"), fname, strerror(errno));
-  
+    log_error ( for_write? _("can't create '%s': %s\n")
+                         : _("can't open '%s': %s\n"), fname, strerror(errno));
+
   return fd;
 #endif
 }
@@ -1180,7 +1358,7 @@ add_group(char *string)
   name=strsep(&string,"=");
   if(string==NULL)
     {
-      log_error(_("no = sign found in group definition `%s'\n"),name);
+      log_error(_("no = sign found in group definition '%s'\n"),name);
       return;
     }
 
@@ -1258,7 +1436,7 @@ check_permissions (const char *path, int item)
   if(opt.no_perm_warn)
     return 0;
 
-  assert(item==0 || item==1 || item==2);
+  log_assert(item==0 || item==1 || item==2);
 
   /* extensions may attach a path */
   if(item==2 && path[0]!=DIRSEP_C)
@@ -1277,7 +1455,8 @@ check_permissions (const char *path, int item)
      could be rectified if the homedir itself had proper
      permissions. */
   if(item!=0 && homedir_cache>-1
-     && ascii_strncasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0)
+     && !ascii_strncasecmp (gnupg_homedir (), tmppath,
+                            strlen (gnupg_homedir ())))
     {
       ret=homedir_cache;
       goto end;
@@ -1378,49 +1557,49 @@ check_permissions (const char *path, int item)
        {
          if(item==0)
            log_info(_("WARNING: unsafe ownership on"
-                      " homedir `%s'\n"),tmppath);
+                      " homedir '%s'\n"),tmppath);
          else if(item==1)
            log_info(_("WARNING: unsafe ownership on"
-                      " configuration file `%s'\n"),tmppath);
+                      " configuration file '%s'\n"),tmppath);
          else
            log_info(_("WARNING: unsafe ownership on"
-                      " extension `%s'\n"),tmppath);
+                      " extension '%s'\n"),tmppath);
        }
       if(perm)
        {
          if(item==0)
            log_info(_("WARNING: unsafe permissions on"
-                      " homedir `%s'\n"),tmppath);
+                      " homedir '%s'\n"),tmppath);
          else if(item==1)
            log_info(_("WARNING: unsafe permissions on"
-                      " configuration file `%s'\n"),tmppath);
+                      " configuration file '%s'\n"),tmppath);
          else
            log_info(_("WARNING: unsafe permissions on"
-                      " extension `%s'\n"),tmppath);
+                      " extension '%s'\n"),tmppath);
        }
       if(enc_dir_own)
        {
          if(item==0)
            log_info(_("WARNING: unsafe enclosing directory ownership on"
-                      " homedir `%s'\n"),tmppath);
+                      " homedir '%s'\n"),tmppath);
          else if(item==1)
            log_info(_("WARNING: unsafe enclosing directory ownership on"
-                      " configuration file `%s'\n"),tmppath);
+                      " configuration file '%s'\n"),tmppath);
          else
            log_info(_("WARNING: unsafe enclosing directory ownership on"
-                      " extension `%s'\n"),tmppath);
+                      " extension '%s'\n"),tmppath);
        }
       if(enc_dir_perm)
        {
          if(item==0)
            log_info(_("WARNING: unsafe enclosing directory permissions on"
-                      " homedir `%s'\n"),tmppath);
+                      " homedir '%s'\n"),tmppath);
          else if(item==1)
            log_info(_("WARNING: unsafe enclosing directory permissions on"
-                      " configuration file `%s'\n"),tmppath);
+                      " configuration file '%s'\n"),tmppath);
          else
            log_info(_("WARNING: unsafe enclosing directory permissions on"
-                      " extension `%s'\n"),tmppath);
+                      " extension '%s'\n"),tmppath);
        }
     }
 
@@ -1485,8 +1664,11 @@ print_algo_names(int (*checker)(int),const char *(*mapper)(int))
 static void
 list_config(char *items)
 {
-  int show_all=(items==NULL);
-  char *name=NULL;
+  int show_all = !items;
+  char *name = NULL;
+  const char *s;
+  struct groupitem *giter;
+  int first, iter;
 
   if(!opt.with_colons)
     return;
@@ -1497,20 +1679,19 @@ list_config(char *items)
 
       if(show_all || ascii_strcasecmp(name,"group")==0)
        {
-         struct groupitem *iter;
-
-         for(iter=opt.grouplist;iter;iter=iter->next)
+         for (giter = opt.grouplist; giter; giter = giter->next)
            {
              strlist_t sl;
 
              es_fprintf (es_stdout, "cfg:group:");
-             es_write_sanitized (es_stdout, iter->name, strlen(iter->name),
+             es_write_sanitized (es_stdout, giter->name, strlen(giter->name),
                                   ":", NULL);
              es_putc (':', es_stdout);
 
-             for(sl=iter->values;sl;sl=sl->next)
+             for(sl=giter->values; sl; sl=sl->next)
                {
-                 print_sanitized_string2 (stdout, sl->d, ':',';');
+                 es_write_sanitized (es_stdout, sl->d, strlen (sl->d),
+                                      ":;", NULL);
                  if(sl->next)
                     es_printf(";");
                }
@@ -1532,7 +1713,16 @@ list_config(char *items)
       if(show_all || ascii_strcasecmp(name,"pubkey")==0)
        {
          es_printf ("cfg:pubkey:");
-         print_algo_numbers (openpgp_pk_test_algo);
+         print_algo_numbers (build_list_pk_test_algo);
+         es_printf ("\n");
+         any=1;
+       }
+
+      if(show_all || ascii_strcasecmp(name,"pubkeyname")==0)
+       {
+         es_printf ("cfg:pubkeyname:");
+         print_algo_names (build_list_pk_test_algo,
+                            build_list_pk_algo_name);
          es_printf ("\n");
          any=1;
        }
@@ -1540,7 +1730,7 @@ list_config(char *items)
       if(show_all || ascii_strcasecmp(name,"cipher")==0)
        {
          es_printf ("cfg:cipher:");
-         print_algo_numbers(openpgp_cipher_test_algo);
+         print_algo_numbers (build_list_cipher_test_algo);
          es_printf ("\n");
          any=1;
        }
@@ -1548,7 +1738,8 @@ list_config(char *items)
       if (show_all || !ascii_strcasecmp (name,"ciphername"))
        {
          es_printf ("cfg:ciphername:");
-         print_algo_names (openpgp_cipher_test_algo,openpgp_cipher_algo_name);
+         print_algo_names (build_list_cipher_test_algo,
+                            build_list_cipher_algo_name);
          es_printf ("\n");
          any = 1;
        }
@@ -1558,7 +1749,7 @@ list_config(char *items)
         || ascii_strcasecmp(name,"hash")==0)
        {
          es_printf ("cfg:digest:");
-         print_algo_numbers(openpgp_md_test_algo);
+         print_algo_numbers (build_list_md_test_algo);
          es_printf ("\n");
          any=1;
        }
@@ -1568,11 +1759,12 @@ list_config(char *items)
           || !ascii_strcasecmp(name,"hashname"))
        {
          es_printf ("cfg:digestname:");
-         print_algo_names (openpgp_md_test_algo, gcry_md_algo_name);
+         print_algo_names (build_list_md_test_algo,
+                            build_list_md_algo_name);
          es_printf ("\n");
          any=1;
        }
-      
+
       if(show_all || ascii_strcasecmp(name,"compress")==0)
        {
          es_printf ("cfg:compress:");
@@ -1581,20 +1773,40 @@ list_config(char *items)
          any=1;
        }
 
-      if(show_all || ascii_strcasecmp(name,"ccid-reader-id")==0)
+      if(show_all || ascii_strcasecmp (name, "compressname") == 0)
+       {
+         es_printf ("cfg:compressname:");
+         print_algo_names (check_compress_algo,
+                           compress_algo_to_string);
+         es_printf ("\n");
+         any=1;
+       }
+
+      if (show_all || !ascii_strcasecmp(name,"ccid-reader-id"))
        {
-#if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB) \
-    && GNUPG_MAJOR_VERSION == 1
+          /* We ignore this for GnuPG 1.4 backward compatibility.  */
+         any=1;
+       }
 
-          char *p, *p2, *list = ccid_get_reader_list ();
+      if (show_all || !ascii_strcasecmp (name,"curve"))
+       {
+         es_printf ("cfg:curve:");
+          for (iter=0, first=1; (s = openpgp_enum_curves (&iter)); first=0)
+            es_printf ("%s%s", first?"":";", s);
+         es_printf ("\n");
+         any=1;
+       }
 
-          for (p=list; p && (p2 = strchr (p, '\n')); p = p2+1)
+      /* Curve OIDs are rarely useful and thus only printed if requested.  */
+      if (name && !ascii_strcasecmp (name,"curveoid"))
+       {
+         es_printf ("cfg:curveoid:");
+          for (iter=0, first=1; (s = openpgp_enum_curves (&iter)); first = 0)
             {
-              *p2 = 0;
-              es_printf ("cfg:ccid-reader-id:%s\n", p);
+              s = openpgp_curve_to_oid (s, NULL);
+              es_printf ("%s%s", first?"":";", s? s:"[?]");
             }
-          free (list);
-#endif
+         es_printf ("\n");
          any=1;
        }
 
@@ -1602,7 +1814,7 @@ list_config(char *items)
        break;
 
       if(!any)
-       log_error(_("unknown configuration item `%s'\n"),name);
+       log_error(_("unknown configuration item '%s'\n"),name);
     }
 }
 
@@ -1617,7 +1829,8 @@ gpgconf_list (const char *configfile)
 {
   char *configfile_esc = percent_escape (configfile, NULL);
 
-  es_printf ("gpgconf-gpg.conf:%lu:\"%s\n",
+  es_printf ("%s-%s.conf:%lu:\"%s\n",
+             GPGCONF_NAME, GPG_NAME,
              GC_OPT_FLAG_DEFAULT,
              configfile_esc ? configfile_esc : "/dev/null");
   es_printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
@@ -1635,7 +1848,7 @@ gpgconf_list (const char *configfile)
   /* The next one is an info only item and should match the macros at
      the top of keygen.c  */
   es_printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT,
-             "RSA-2048");
+             get_default_pubkey_algo ());
 
   xfree (configfile_esc);
 }
@@ -1709,6 +1922,8 @@ parse_list_options(char *str)
     {
       {"show-photos",LIST_SHOW_PHOTOS,NULL,
        N_("display photo IDs during key listings")},
+      {"show-usage",LIST_SHOW_USAGE,NULL,
+       N_("show key usage information during key listings")},
       {"show-policy-urls",LIST_SHOW_POLICY_URLS,NULL,
        N_("show policy URLs during signature listings")},
       {"show-notations",LIST_SHOW_NOTATIONS,NULL,
@@ -1740,7 +1955,7 @@ parse_list_options(char *str)
      compile everywhere, so fill in the show-sig-subpackets argument
      here.  Note that if the parse_options array changes, we'll have
      to change the subscript here. */
-  lopts[12].value=&subpackets;
+  lopts[13].value=&subpackets;
 
   if(parse_options(str,&opt.list_options,lopts,1))
     {
@@ -1790,6 +2005,8 @@ collapse_args(int argc,char *argv[])
   return str;
 }
 
+
+#ifndef NO_TRUST_MODELS
 static void
 parse_trust_model(const char *model)
 {
@@ -1801,14 +2018,160 @@ parse_trust_model(const char *model)
     opt.trust_model=TM_ALWAYS;
   else if(ascii_strcasecmp(model,"direct")==0)
     opt.trust_model=TM_DIRECT;
+#ifdef USE_TOFU
+  else if(ascii_strcasecmp(model,"tofu")==0)
+    opt.trust_model=TM_TOFU;
+  else if(ascii_strcasecmp(model,"tofu+pgp")==0)
+    opt.trust_model=TM_TOFU_PGP;
+#endif /*USE_TOFU*/
   else if(ascii_strcasecmp(model,"auto")==0)
     opt.trust_model=TM_AUTO;
   else
-    log_error("unknown trust model `%s'\n",model);
+    log_error("unknown trust model '%s'\n",model);
+}
+#endif /*NO_TRUST_MODELS*/
+
+
+static int
+parse_tofu_policy (const char *policystr)
+{
+#ifdef USE_TOFU
+  struct { const char *keyword; int policy; } list[] = {
+    { "auto",    TOFU_POLICY_AUTO },
+    { "good",    TOFU_POLICY_GOOD },
+    { "unknown", TOFU_POLICY_UNKNOWN },
+    { "bad",     TOFU_POLICY_BAD },
+    { "ask",     TOFU_POLICY_ASK }
+  };
+  int i;
+
+  if (!ascii_strcasecmp (policystr, "help"))
+    {
+      log_info (_("valid values for option '%s':\n"), "--tofu-policy");
+      for (i=0; i < DIM (list); i++)
+        log_info ("  %s\n", list[i].keyword);
+      g10_exit (1);
+    }
+
+  for (i=0; i < DIM (list); i++)
+    if (!ascii_strcasecmp (policystr, list[i].keyword))
+      return list[i].policy;
+#endif /*USE_TOFU*/
+
+  log_error (_("unknown TOFU policy '%s'\n"), policystr);
+  if (!opt.quiet)
+    log_info (_("(use \"help\" to list choices)\n"));
+  g10_exit (1);
+}
+
+
+/* Parse the value of --compliance.  */
+static int
+parse_compliance_option (const char *string)
+{
+  struct { const char *keyword; enum cmd_and_opt_values option; } list[] = {
+    { "gnupg",      oGnuPG },
+    { "openpgp",    oOpenPGP },
+    { "rfc4880bis", oRFC4880bis },
+    { "rfc4880",    oRFC4880 },
+    { "rfc2440",    oRFC2440 },
+    { "pgp6",       oPGP6 },
+    { "pgp7",       oPGP7 },
+    { "pgp8",       oPGP8 },
+    { "de-vs",      oDE_VS }
+  };
+  int i;
+
+  if (!ascii_strcasecmp (string, "help"))
+    {
+      log_info (_("valid values for option '%s':\n"), "--compliance");
+      for (i=0; i < DIM (list); i++)
+        log_info ("  %s\n", list[i].keyword);
+      g10_exit (1);
+    }
+
+  for (i=0; i < DIM (list); i++)
+    if (!ascii_strcasecmp (string, list[i].keyword))
+      return list[i].option;
+
+  log_error (_("invalid value for option '%s'\n"), "--compliance");
+  if (!opt.quiet)
+    log_info (_("(use \"help\" to list choices)\n"));
+  g10_exit (1);
+}
+
+
+
+/* Helper to set compliance related options.  This is a separte
+ * function so that it can also be used by the --compliance option
+ * parser.  */
+static void
+set_compliance_option (enum cmd_and_opt_values option)
+{
+  switch (option)
+    {
+    case oRFC4880bis:
+      opt.flags.rfc4880bis = 1;
+      /* fall through.  */
+    case oOpenPGP:
+    case oRFC4880:
+      /* This is effectively the same as RFC2440, but with
+         "--enable-dsa2 --no-rfc2440-text --escape-from-lines
+         --require-cross-certification". */
+      opt.compliance = CO_RFC4880;
+      opt.flags.dsa2 = 1;
+      opt.flags.require_cross_cert = 1;
+      opt.rfc2440_text = 0;
+      opt.allow_non_selfsigned_uid = 1;
+      opt.allow_freeform_uid = 1;
+      opt.escape_from = 1;
+      opt.not_dash_escaped = 0;
+      opt.def_cipher_algo = 0;
+      opt.def_digest_algo = 0;
+      opt.cert_digest_algo = 0;
+      opt.compress_algo = -1;
+      opt.s2k_mode = 3; /* iterated+salted */
+      opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
+      opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
+      break;
+    case oRFC2440:
+      opt.compliance = CO_RFC2440;
+      opt.flags.dsa2 = 0;
+      opt.rfc2440_text = 1;
+      opt.allow_non_selfsigned_uid = 1;
+      opt.allow_freeform_uid = 1;
+      opt.escape_from = 0;
+      opt.not_dash_escaped = 0;
+      opt.def_cipher_algo = 0;
+      opt.def_digest_algo = 0;
+      opt.cert_digest_algo = 0;
+      opt.compress_algo = -1;
+      opt.s2k_mode = 3; /* iterated+salted */
+      opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
+      opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
+      break;
+    case oPGP6:  opt.compliance = CO_PGP6;  break;
+    case oPGP7:  opt.compliance = CO_PGP7;  break;
+    case oPGP8:  opt.compliance = CO_PGP8;  break;
+    case oGnuPG: opt.compliance = CO_GNUPG; break;
+
+    case oDE_VS:
+      set_compliance_option (oOpenPGP);
+      opt.compliance = CO_DE_VS;
+      /* Fixme: Change other options.  */
+      break;
+
+    default:
+      BUG ();
+    }
 }
 
 
-/* This fucntion called to initialized a new control object.  It is
+
+
+
+
+/* This function called to initialized a new control object.  It is
    assumed that this object has been zeroed out before calling this
    function. */
 static void
@@ -1823,6 +2186,9 @@ gpg_init_default_ctrl (ctrl_t ctrl)
 static void
 gpg_deinit_default_ctrl (ctrl_t ctrl)
 {
+#ifdef USE_TOFU
+  tofu_closedbs (ctrl);
+#endif
   gpg_dirmngr_deinit_session_data (ctrl);
 }
 
@@ -1831,15 +2197,15 @@ char *
 get_default_configname (void)
 {
   char *configname = NULL;
-  char *name = xstrdup ("gpg" EXTSEP_S "conf-" SAFE_VERSION);
-  char *ver = &name[strlen ("gpg" EXTSEP_S "conf-")];
+  char *name = xstrdup (GPG_NAME EXTSEP_S "conf-" SAFE_VERSION);
+  char *ver = &name[strlen (GPG_NAME EXTSEP_S "conf-")];
 
   do
     {
       if (configname)
        {
          char *tok;
-         
+
          xfree (configname);
          configname = NULL;
 
@@ -1850,27 +2216,28 @@ get_default_configname (void)
          else
            break;
        }
-      
-      configname = make_filename (opt.homedir, name, NULL);
+
+      configname = make_filename (gnupg_homedir (), name, NULL);
     }
   while (access (configname, R_OK));
 
   xfree(name);
-  
+
   if (! configname)
-    configname = make_filename (opt.homedir, "gpg" EXTSEP_S "conf", NULL);
+    configname = make_filename (gnupg_homedir (),
+                                GPG_NAME EXTSEP_S "conf", NULL);
   if (! access (configname, R_OK))
     {
       /* Print a warning when both config files are present.  */
-      char *p = make_filename (opt.homedir, "options", NULL);
+      char *p = make_filename (gnupg_homedir (), "options", NULL);
       if (! access (p, R_OK))
-       log_info (_("NOTE: old default options file `%s' ignored\n"), p);
+       log_info (_("Note: old default options file '%s' ignored\n"), p);
       xfree (p);
     }
   else
     {
       /* Use the old default only if it exists.  */
-      char *p = make_filename (opt.homedir, "options", NULL);
+      char *p = make_filename (gnupg_homedir (), "options", NULL);
       if (!access (p, R_OK))
        {
          xfree (configname);
@@ -1883,7 +2250,6 @@ get_default_configname (void)
   return configname;
 }
 
-
 int
 main (int argc, char **argv)
 {
@@ -1895,7 +2261,9 @@ main (int argc, char **argv)
     const char *fname;
     char *username;
     int may_coredump;
-    strlist_t sl, remusr= NULL, locusr=NULL;
+    strlist_t sl;
+    strlist_t remusr = NULL;
+    strlist_t locusr = NULL;
     strlist_t nrings = NULL;
     armor_filter_context_t *afx = NULL;
     int detached_sig = 0;
@@ -1913,7 +2281,9 @@ main (int argc, char **argv)
     int use_random_seed = 1;
     enum cmd_and_opt_values cmd = 0;
     const char *debug_level = NULL;
+#ifndef NO_TRUST_MODELS
     const char *trustdb_name = NULL;
+#endif /*!NO_TRUST_MODELS*/
     char *def_cipher_string = NULL;
     char *def_digest_string = NULL;
     char *compress_algo_string = NULL;
@@ -1926,39 +2296,37 @@ main (int argc, char **argv)
     int eyes_only=0;
     int multifile=0;
     int pwfd = -1;
+    int ovrseskeyfd = -1;
     int fpr_maybe_cmd = 0; /* --fingerprint maybe a command.  */
     int any_explicit_recipient = 0;
-    int require_secmem=0,got_secmem=0;
+    int require_secmem = 0;
+    int got_secmem = 0;
     struct assuan_malloc_hooks malloc_hooks;
     ctrl_t ctrl;
 
+    static int print_dane_records;
+    static int print_pka_records;
+
+
 #ifdef __riscos__
     opt.lock_once = 1;
 #endif /* __riscos__ */
 
-
     /* Please note that we may running SUID(ROOT), so be very CAREFUL
        when adding any stuff between here and the call to
        secmem_init() somewhere after the option parsing. */
-    gnupg_reopen_std ("gpg");
+    early_system_init ();
+    gnupg_reopen_std (GPG_NAME);
     trap_unaligned ();
     gnupg_rl_initialize ();
     set_strusage (my_strusage);
     gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
-    log_set_prefix ("gpg", 1);
+    log_set_prefix (GPG_NAME, GPGRT_LOG_WITH_PREFIX);
 
     /* Make sure that our subsystems are ready.  */
     i18n_init();
     init_common_subsystems (&argc, &argv);
 
-    /* Check that the libraries are suitable.  Do it right here because the
-       option parsing may need services of the library.  */
-    if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
-      {
-        log_fatal ( _("libgcrypt is too old (need %s, have %s)\n"),
-                    NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
-      }
-
     /* Use our own logging handler for Libcgrypt.  */
     setup_libgcrypt_logging ();
 
@@ -1969,8 +2337,9 @@ main (int argc, char **argv)
 
     gnupg_init_signals (0, emergency_cleanup);
 
-    create_dotlock(NULL); /* Register locking cleanup. */
+    dotlock_create (NULL, 0); /* Register lock file cleanup. */
 
+    opt.autostart = 1;
     opt.session_env = session_env_new ();
     if (!opt.session_env)
       log_fatal ("error allocating session environment block: %s\n",
@@ -1986,41 +2355,52 @@ main (int argc, char **argv)
     opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */
     opt.s2k_mode = 3; /* iterated+salted */
     opt.s2k_count = 0; /* Auto-calibrate when needed.  */
-    opt.s2k_cipher_algo = CIPHER_ALGO_CAST5;
+    opt.s2k_cipher_algo = DEFAULT_CIPHER_ALGO;
     opt.completes_needed = 1;
     opt.marginals_needed = 3;
     opt.max_cert_depth = 5;
-    opt.pgp2_workarounds = 1;
     opt.escape_from = 1;
     opt.flags.require_cross_cert = 1;
     opt.import_options = 0;
     opt.export_options = EXPORT_ATTRIBUTES;
     opt.keyserver_options.import_options = IMPORT_REPAIR_PKS_SUBKEY_BUG;
     opt.keyserver_options.export_options = EXPORT_ATTRIBUTES;
-    opt.keyserver_options.options = (KEYSERVER_HONOR_KEYSERVER_URL
-                                     | KEYSERVER_HONOR_PKA_RECORD );
-    opt.verify_options = (VERIFY_SHOW_POLICY_URLS
+    opt.keyserver_options.options = KEYSERVER_HONOR_PKA_RECORD;
+    opt.verify_options = (LIST_SHOW_UID_VALIDITY
+                          | VERIFY_SHOW_POLICY_URLS
                           | VERIFY_SHOW_STD_NOTATIONS
                           | VERIFY_SHOW_KEYSERVER_URLS);
+    opt.list_options   = (LIST_SHOW_UID_VALIDITY
+                          | LIST_SHOW_USAGE);
+#ifdef NO_TRUST_MODELS
+    opt.trust_model = TM_ALWAYS;
+#else
     opt.trust_model = TM_AUTO;
+#endif
+    opt.tofu_default_policy = TOFU_POLICY_AUTO;
     opt.mangle_dos_filenames = 0;
     opt.min_cert_level = 2;
     set_screen_dimensions ();
-    opt.keyid_format = KF_SHORT;
+    opt.keyid_format = KF_NONE;
     opt.def_sig_expire = "0";
     opt.def_cert_expire = "0";
-    set_homedir (default_homedir ());
+    gnupg_set_homedir (NULL);
     opt.passphrase_repeat = 1;
+    opt.emit_version = 0;
+    opt.weak_digests = NULL;
+    additional_weak_digest("MD5");
 
     /* Check whether we have a config file on the command line.  */
     orig_argc = argc;
     orig_argv = argv;
     pargs.argc = &argc;
     pargs.argv = &argv;
-    pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
+    pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
     while( arg_parse( &pargs, opts) ) {
        if( pargs.r_opt == oDebug || pargs.r_opt == oDebugAll )
            parse_debug++;
+       else if (pargs.r_opt == oDebugIOLBF)
+            es_setvbuf (es_stdout, NULL, _IOLBF, 0);
        else if( pargs.r_opt == oOptions ) {
            /* yes there is one, so we do not try the default one, but
             * read the option file when it is encountered at the commandline
@@ -2033,7 +2413,7 @@ main (int argc, char **argv)
             opt.no_homedir_creation = 1;
           }
         else if( pargs.r_opt == oHomedir )
-           set_homedir ( pargs.r.ret_str );
+           gnupg_set_homedir (pargs.r.ret_str);
        else if( pargs.r_opt == oNoPermissionWarn )
            opt.no_perm_warn=1;
        else if (pargs.r_opt == oStrict )
@@ -2047,10 +2427,10 @@ main (int argc, char **argv)
     }
 
 #ifdef HAVE_DOSISH_SYSTEM
-    if ( strchr (opt.homedir,'\\') ) {
-        char *d, *buf = xmalloc (strlen (opt.homedir)+1);
-        const char *s = opt.homedir;
-        for (d=buf,s=opt.homedir; *s; s++)
+    if ( strchr (gnupg_homedir (), '\\') ) {
+      char *d, *buf = xmalloc (strlen (gnupg_homedir ())+1);
+      const char *s;
+      for (d=buf, s = gnupg_homedir (); *s; s++)
           {
             *d++ = *s == '\\'? '/': *s;
 #ifdef HAVE_W32_SYSTEM
@@ -2059,13 +2439,13 @@ main (int argc, char **argv)
 #endif
           }
         *d = 0;
-        set_homedir (buf);
+        gnupg_set_homedir (buf);
     }
 #endif
 
     /* Initialize the secure memory. */
-    if (!gcry_control (GCRYCTL_INIT_SECMEM, 32768, 0))
-      got_secmem = 1; 
+    if (!gcry_control (GCRYCTL_INIT_SECMEM, SECMEM_BUFFER_SIZE, 0))
+      got_secmem = 1;
 #if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
     /* There should be no way to get to this spot while still carrying
        setuid privs.  Just in case, bomb out if we are. */
@@ -2082,8 +2462,8 @@ main (int argc, char **argv)
     malloc_hooks.free = gcry_free;
     assuan_set_malloc_hooks (&malloc_hooks);
     assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
-    setup_libassuan_logging (&opt.debug);
+    setup_libassuan_logging (&opt.debug, NULL);
+
     /* Try for a version specific config file first */
     default_configname = get_default_configname ();
     if (default_config)
@@ -2093,10 +2473,10 @@ main (int argc, char **argv)
     argv = orig_argv;
     pargs.argc = &argc;
     pargs.argv = &argv;
-    pargs.flags=  1;  /* do not remove the args */
+    pargs.flags= ARGPARSE_FLAG_KEEP;
 
     /* By this point we have a homedir, and cannot change it. */
-    check_permissions(opt.homedir,0);
+    check_permissions (gnupg_homedir (), 0);
 
   next_pass:
     if( configname ) {
@@ -2122,18 +2502,18 @@ main (int argc, char **argv)
        if( !configfp ) {
            if( default_config ) {
                if( parse_debug )
-                   log_info(_("NOTE: no default option file `%s'\n"),
+                   log_info(_("Note: no default option file '%s'\n"),
                                                            configname );
            }
            else {
-               log_error(_("option file `%s': %s\n"),
+               log_error(_("option file '%s': %s\n"),
                                    configname, strerror(errno) );
                g10_exit(2);
            }
            xfree(configname); configname = NULL;
        }
        if( parse_debug && configname )
-           log_info(_("reading options from `%s'\n"), configname );
+           log_info(_("reading options from '%s'\n"), configname );
        default_config = 0;
     }
 
@@ -2142,55 +2522,70 @@ main (int argc, char **argv)
       {
        switch( pargs.r_opt )
          {
-         case aCheckKeys: 
          case aListConfig:
+         case aListGcryptConfig:
           case aGPGConfList:
           case aGPGConfTest:
+            set_cmd (&cmd, pargs.r_opt);
+            /* Do not register a keyring for these commands.  */
+            default_keyring = -1;
+            break;
+
+         case aCheckKeys:
          case aListPackets:
-         case aImport: 
-         case aFastImport: 
-         case aSendKeys: 
-         case aRecvKeys: 
+         case aImport:
+         case aFastImport:
+         case aSendKeys:
+         case aRecvKeys:
          case aSearchKeys:
          case aRefreshKeys:
          case aFetchKeys:
-         case aExport: 
+         case aExport:
 #ifdef ENABLE_CARD_SUPPORT
           case aCardStatus:
-          case aCardEdit: 
+          case aCardEdit:
           case aChangePIN:
 #endif /* ENABLE_CARD_SUPPORT*/
-         case aListKeys: 
+         case aListKeys:
          case aLocateKeys:
-         case aListSigs: 
-         case aExportSecret: 
-         case aExportSecretSub: 
+         case aListSigs:
+         case aExportSecret:
+         case aExportSecretSub:
+         case aExportSshKey:
          case aSym:
-         case aClearsign: 
-         case aGenRevoke: 
-         case aDesigRevoke: 
-         case aPrimegen: 
+         case aClearsign:
+         case aGenRevoke:
+         case aDesigRevoke:
+         case aPrimegen:
          case aGenRandom:
          case aPrintMD:
-         case aPrintMDs: 
-         case aListTrustDB: 
+         case aPrintMDs:
+         case aListTrustDB:
          case aCheckTrustDB:
-         case aUpdateTrustDB: 
-         case aFixTrustDB: 
-         case aListTrustPath: 
-         case aDeArmor: 
-         case aEnArmor: 
-         case aSign: 
-         case aSignKey: 
+         case aUpdateTrustDB:
+         case aFixTrustDB:
+         case aListTrustPath:
+         case aDeArmor:
+         case aEnArmor:
+         case aSign:
+         case aQuickSignKey:
+         case aQuickLSignKey:
+         case aSignKey:
          case aLSignKey:
-         case aStore: 
-         case aExportOwnerTrust: 
-         case aImportOwnerTrust: 
+         case aStore:
+         case aQuickKeygen:
+         case aQuickAddUid:
+         case aQuickAddKey:
+         case aQuickRevUid:
+         case aQuickSetExpire:
+         case aExportOwnerTrust:
+         case aImportOwnerTrust:
           case aRebuildKeydbCaches:
             set_cmd (&cmd, pargs.r_opt);
             break;
 
-         case aKeygen: 
+         case aKeygen:
+         case aFullKeygen:
          case aEditKey:
          case aDeleteSecretKeys:
          case aDeleteSecretAndPublicKeys:
@@ -2216,9 +2611,19 @@ main (int argc, char **argv)
             opt.batch = 1;
             break;
 
+          case aTOFUPolicy:
+            set_cmd (&cmd, pargs.r_opt);
+            break;
+
          case oArmor: opt.armor = 1; opt.no_armor=0; break;
          case oOutput: opt.outfile = pargs.r.ret_str; break;
+
          case oMaxOutput: opt.max_output = pargs.r.ret_ulong; break;
+
+          case oInputSizeHint:
+            opt.input_size_hint = string_to_u64 (pargs.r.ret_str);
+            break;
+
          case oQuiet: opt.quiet = 1; break;
          case oNoTTY: tty_no_terminal(1); break;
          case oDryRun: opt.dry_run = 1; break;
@@ -2237,19 +2642,35 @@ main (int argc, char **argv)
 
           case oUseAgent: /* Dummy. */
             break;
+
           case oNoUseAgent:
-           obsolete_option (configname, configlineno, "--no-use-agent");
+           obsolete_option (configname, configlineno, "no-use-agent");
+            break;
+         case oGpgAgentInfo:
+           obsolete_option (configname, configlineno, "gpg-agent-info");
             break;
-         case oGpgAgentInfo: 
-           obsolete_option (configname, configlineno, "--gpg-agent-info");
+          case oReaderPort:
+           obsolete_scdaemon_option (configname, configlineno, "reader-port");
+            break;
+          case octapiDriver:
+           obsolete_scdaemon_option (configname, configlineno, "ctapi-driver");
+            break;
+          case opcscDriver:
+           obsolete_scdaemon_option (configname, configlineno, "pcsc-driver");
+            break;
+          case oDisableCCID:
+           obsolete_scdaemon_option (configname, configlineno, "disable-ccid");
+            break;
+          case oHonorHttpProxy:
+           obsolete_option (configname, configlineno, "honor-http-proxy");
             break;
 
          case oAnswerYes: opt.answer_yes = 1; break;
          case oAnswerNo: opt.answer_no = 1; break;
          case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
          case oPrimaryKeyring:
-           sl=append_to_strlist( &nrings, pargs.r.ret_str);
-           sl->flags=2;
+           sl = append_to_strlist (&nrings, pargs.r.ret_str);
+           sl->flags = KEYDB_RESOURCE_FLAG_PRIMARY;
            break;
          case oShowKeyring:
            deprecated_warning(configname,configlineno,"--show-keyring",
@@ -2257,10 +2678,19 @@ main (int argc, char **argv)
            opt.list_options|=LIST_SHOW_KEYRING;
            break;
 
-         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
+         case oDebug:
+            if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags))
+              {
+                pargs.r_opt = ARGPARSE_INVALID_ARG;
+                pargs.err = ARGPARSE_PRINT_ERROR;
+              }
+            break;
+
          case oDebugAll: opt.debug = ~0; break;
           case oDebugLevel: debug_level = pargs.r.ret_str; break;
 
+          case oDebugIOLBF: break; /* Already set in pre-parse step.  */
+
          case oStatusFD:
             set_status_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) );
             break;
@@ -2284,6 +2714,12 @@ main (int argc, char **argv)
             opt.with_fingerprint = 1;
             opt.fingerprint++;
             break;
+         case oWithSubkeyFingerprint:
+            opt.with_subkey_fingerprint = 1;
+            break;
+         case oWithICAOSpelling:
+            opt.with_icao_spelling = 1;
+            break;
          case oFingerprint:
             opt.fingerprint++;
             fpr_maybe_cmd = 1;
@@ -2293,6 +2729,14 @@ main (int argc, char **argv)
             opt.with_keygrip = 1;
             break;
 
+         case oWithSecret:
+            opt.with_secret = 1;
+            break;
+
+         case oWithWKDHash:
+            opt.with_wkd_hash = 1;
+            break;
+
          case oSecretKeyring:
             /* Ignore this old option.  */
             break;
@@ -2306,26 +2750,46 @@ main (int argc, char **argv)
            }
            break;
          case oNoArmor: opt.no_armor=1; opt.armor=0; break;
-         case oNoDefKeyring: default_keyring = 0; break;
+
+         case oNoDefKeyring:
+            if (default_keyring > 0)
+              default_keyring = 0;
+            break;
+         case oNoKeyring:
+            default_keyring = -1;
+            break;
+
          case oNoGreeting: nogreeting = 1; break;
-         case oNoVerbose: 
+         case oNoVerbose:
             opt.verbose = 0;
             gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
             opt.list_sigs=0;
             break;
-          case oQuickRandom: 
+          case oQuickRandom:
             gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
             break;
-         case oEmitVersion: opt.no_version=0; break;
-         case oNoEmitVersion: opt.no_version=1; break;
+         case oEmitVersion: opt.emit_version++; break;
+         case oNoEmitVersion: opt.emit_version=0; break;
          case oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
          case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
          case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
+
+#ifndef NO_TRUST_MODELS
          case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
-         case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
+
+#endif /*!NO_TRUST_MODELS*/
+         case oDefaultKey:
+            sl = add_to_strlist (&opt.def_secret_key, pargs.r.ret_str);
+            sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
+            if (configfp)
+              sl->flags |= PK_LIST_CONFIG;
+            break;
          case oDefRecipient:
             if( *pargs.r.ret_str )
-              opt.def_recipient = make_username(pargs.r.ret_str);
+             {
+               xfree (opt.def_recipient);
+               opt.def_recipient = make_username(pargs.r.ret_str);
+             }
             break;
          case oDefRecipientSelf:
             xfree(opt.def_recipient); opt.def_recipient = NULL;
@@ -2339,19 +2803,22 @@ main (int argc, char **argv)
          case oHomedir: break;
          case oNoBatch: opt.batch = 0; break;
 
+          case oWithTofuInfo: opt.with_tofu_info = 1; break;
+
          case oWithKeyData: opt.with_key_data=1; /*FALLTHRU*/
          case oWithColons: opt.with_colons=':'; break;
 
           case oWithSigCheck: opt.check_sigs = 1; /*FALLTHRU*/
-          case oWithSigList: opt.list_sigs = 1; break;  
+          case oWithSigList: opt.list_sigs = 1; break;
 
          case oSkipVerify: opt.skip_verify=1; break;
 
          case oSkipHiddenRecipients: opt.skip_hidden_recipients = 1; break;
          case oNoSkipHiddenRecipients: opt.skip_hidden_recipients = 0; break;
 
-         case oCompressKeys: opt.compress_keys = 1; break;
          case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
+
+#ifndef NO_TRUST_MODELS
            /* There are many programs (like mutt) that call gpg with
               --always-trust so keep this option around for a long
               time. */
@@ -2359,13 +2826,21 @@ main (int argc, char **argv)
          case oTrustModel:
            parse_trust_model(pargs.r.ret_str);
            break;
+#endif /*!NO_TRUST_MODELS*/
+         case oTOFUDefaultPolicy:
+           opt.tofu_default_policy = parse_tofu_policy (pargs.r.ret_str);
+           break;
+         case oTOFUDBFormat:
+           obsolete_option (configname, configlineno, "tofu-db-format");
+           break;
+
          case oForceOwnertrust:
-           log_info(_("NOTE: %s is not for normal use!\n"),
+           log_info(_("Note: %s is not for normal use!\n"),
                     "--force-ownertrust");
            opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str);
            if(opt.force_ownertrust==-1)
              {
-               log_error("invalid ownertrust `%s'\n",pargs.r.ret_str);
+               log_error("invalid ownertrust '%s'\n",pargs.r.ret_str);
                opt.force_ownertrust=0;
              }
            break;
@@ -2373,64 +2848,24 @@ main (int argc, char **argv)
             /* Dummy so that gpg 1.4 conf files can work. Should
                eventually be removed.  */
            break;
-         case oRFC1991:
-           opt.compliance = CO_RFC1991;
-           opt.force_v4_certs = 0;
-           opt.escape_from = 1;
-           break;
-         case oOpenPGP:
-         case oRFC4880:
-           /* This is effectively the same as RFC2440, but with
-              "--enable-dsa2 --no-rfc2440-text --escape-from-lines
-              --require-cross-certification". */
-           opt.compliance = CO_RFC4880;
-           opt.flags.dsa2 = 1;
-           opt.flags.require_cross_cert = 1;
-           opt.rfc2440_text = 0;
-           opt.allow_non_selfsigned_uid = 1;
-           opt.allow_freeform_uid = 1;
-           opt.pgp2_workarounds = 0;
-           opt.escape_from = 1;
-           opt.force_v3_sigs = 0;
-           opt.compress_keys = 0;          /* not mandated, but we do it */
-           opt.compress_sigs = 0;          /* ditto. */
-           opt.not_dash_escaped = 0;
-           opt.def_cipher_algo = 0;
-           opt.def_digest_algo = 0;
-           opt.cert_digest_algo = 0;
-           opt.compress_algo = -1;
-            opt.s2k_mode = 3; /* iterated+salted */
-           opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
-           opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
-           break;
-         case oRFC2440:
-           opt.compliance = CO_RFC2440;
-           opt.flags.dsa2 = 0;
-           opt.rfc2440_text = 1;
-           opt.allow_non_selfsigned_uid = 1;
-           opt.allow_freeform_uid = 1;
-           opt.pgp2_workarounds = 0;
-           opt.escape_from = 0;
-           opt.force_v3_sigs = 0;
-           opt.compress_keys = 0;          /* not mandated, but we do it */
-           opt.compress_sigs = 0;          /* ditto. */
-           opt.not_dash_escaped = 0;
-           opt.def_cipher_algo = 0;
-           opt.def_digest_algo = 0;
-           opt.cert_digest_algo = 0;
-           opt.compress_algo = -1;
-            opt.s2k_mode = 3; /* iterated+salted */
-           opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
-           opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
-           break;
-         case oPGP2:  opt.compliance = CO_PGP2;  break;
-         case oPGP6:  opt.compliance = CO_PGP6;  break;
-         case oPGP7:  opt.compliance = CO_PGP7;  break;
-         case oPGP8:  opt.compliance = CO_PGP8;  break;
-         case oGnuPG: opt.compliance = CO_GNUPG; break;
-         case oCompressSigs: opt.compress_sigs = 1; break;
-         case oRFC2440Text: opt.rfc2440_text=1; break;
-         case oNoRFC2440Text: opt.rfc2440_text=0; break;
+
+          case oCompliance:
+            set_compliance_option (parse_compliance_option (pargs.r.ret_str));
+            break;
+          case oOpenPGP:
+          case oRFC2440:
+          case oRFC4880:
+          case oRFC4880bis:
+          case oPGP6:
+          case oPGP7:
+          case oPGP8:
+          case oGnuPG:
+            set_compliance_option (pargs.r_opt);
+            break;
+
+          case oRFC2440Text: opt.rfc2440_text=1; break;
+          case oNoRFC2440Text: opt.rfc2440_text=0; break;
+
          case oSetFilename:
             if(utf8_strings)
               opt.set_filename = pargs.r.ret_str;
@@ -2480,8 +2915,8 @@ main (int argc, char **argv)
            free_strlist(opt.comments);
            opt.comments=NULL;
            break;
-         case oThrowKeyids: opt.throw_keyid = 1; break;
-         case oNoThrowKeyids: opt.throw_keyid = 0; break;
+         case oThrowKeyids: opt.throw_keyids = 1; break;
+         case oNoThrowKeyids: opt.throw_keyids = 0; break;
          case oShowPhotos:
            deprecated_warning(configname,configlineno,"--show-photos",
                               "--list-options ","show-photos");
@@ -2499,14 +2934,14 @@ main (int argc, char **argv)
            opt.verify_options&=~VERIFY_SHOW_PHOTOS;
            break;
          case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
-         case oForceV3Sigs: opt.force_v3_sigs = 1; break;
-         case oNoForceV3Sigs: opt.force_v3_sigs = 0; break;
-          case oForceV4Certs: opt.force_v4_certs = 1; break;
-          case oNoForceV4Certs: opt.force_v4_certs = 0; break;
+
          case oForceMDC: opt.force_mdc = 1; break;
          case oNoForceMDC: opt.force_mdc = 0; break;
          case oDisableMDC: opt.disable_mdc = 1; break;
          case oNoDisableMDC: opt.disable_mdc = 0; break;
+
+          case oDisableSignerUID: opt.flags.disable_signer_uid = 1; break;
+
          case oS2KMode:   opt.s2k_mode = pargs.r.ret_int; break;
          case oS2KDigest: s2k_digest_string = xstrdup(pargs.r.ret_str); break;
          case oS2KCipher: s2k_cipher_string = xstrdup(pargs.r.ret_str); break;
@@ -2516,40 +2951,63 @@ main (int argc, char **argv)
             else
               opt.s2k_count = 0;  /* Auto-calibrate when needed.  */
            break;
-         case oNoEncryptTo: opt.no_encrypt_to = 1; break;
-         case oEncryptTo: /* store the recipient in the second list */
-           sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
-           sl->flags = 1;
-           break;
-         case oHiddenEncryptTo: /* store the recipient in the second list */
+
+         case oRecipient:
+         case oHiddenRecipient:
+         case oRecipientFile:
+         case oHiddenRecipientFile:
+            /* Store the recipient.  Note that we also store the
+             * option as private data in the flags.  This is achieved
+             * by shifting the option value to the left so to keep
+             * enough space for the flags.  */
            sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
-           sl->flags = 1|2;
-           break;
-         case oRecipient: /* store the recipient */
-           add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
+           sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
+            if (configfp)
+              sl->flags |= PK_LIST_CONFIG;
+            if (pargs.r_opt == oHiddenRecipient
+                || pargs.r_opt == oHiddenRecipientFile)
+              sl->flags |= PK_LIST_HIDDEN;
+            if (pargs.r_opt == oRecipientFile
+                || pargs.r_opt == oHiddenRecipientFile)
+              sl->flags |= PK_LIST_FROM_FILE;
             any_explicit_recipient = 1;
            break;
-         case oHiddenRecipient: /* store the recipient with a flag */
+
+         case oEncryptTo:
+         case oHiddenEncryptTo:
+            /* Store an additional recipient.  */
            sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
-           sl->flags = 2;
-            any_explicit_recipient = 1;
+           sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_ENCRYPT_TO);
+            if (configfp)
+              sl->flags |= PK_LIST_CONFIG;
+            if (pargs.r_opt == oHiddenEncryptTo)
+              sl->flags |= PK_LIST_HIDDEN;
            break;
 
-         case oTrySecretKey: 
+         case oNoEncryptTo:
+            opt.no_encrypt_to = 1;
+            break;
+          case oEncryptToDefaultKey:
+            opt.encrypt_to_default_key = configfp ? 2 : 1;
+            break;
+
+         case oTrySecretKey:
            add_to_strlist2 (&opt.secret_keys_to_try,
                              pargs.r.ret_str, utf8_strings);
            break;
 
+          case oMimemode: opt.mimemode = opt.textmode = 1; break;
          case oTextmodeShort: opt.textmode = 2; break;
          case oTextmode: opt.textmode=1;  break;
-         case oNoTextmode: opt.textmode=0;  break;
+         case oNoTextmode: opt.textmode=opt.mimemode=0;  break;
+
          case oExpert: opt.expert = 1; break;
          case oNoExpert: opt.expert = 0; break;
          case oDefSigExpire:
            if(*pargs.r.ret_str!='\0')
              {
                if(parse_expire_string(pargs.r.ret_str)==(u32)-1)
-                 log_error(_("`%s' is not a valid signature expiration\n"),
+                 log_error(_("'%s' is not a valid signature expiration\n"),
                            pargs.r.ret_str);
                else
                  opt.def_sig_expire=pargs.r.ret_str;
@@ -2561,7 +3019,7 @@ main (int argc, char **argv)
            if(*pargs.r.ret_str!='\0')
              {
                if(parse_expire_string(pargs.r.ret_str)==(u32)-1)
-                 log_error(_("`%s' is not a valid signature expiration\n"),
+                 log_error(_("'%s' is not a valid signature expiration\n"),
                            pargs.r.ret_str);
                else
                  opt.def_cert_expire=pargs.r.ret_str;
@@ -2574,7 +3032,23 @@ main (int argc, char **argv)
          case oAskCertLevel: opt.ask_cert_level = 1; break;
          case oNoAskCertLevel: opt.ask_cert_level = 0; break;
          case oLocalUser: /* store the local users */
-           add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
+           sl = add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
+            sl->flags = (pargs.r_opt << PK_LIST_SHIFT);
+            if (configfp)
+              sl->flags |= PK_LIST_CONFIG;
+           break;
+         case oSender:
+            {
+              char *mbox = mailbox_from_userid (pargs.r.ret_str);
+              if (!mbox)
+                log_error (_("\"%s\" is not a proper mail address\n"),
+                           pargs.r.ret_str);
+              else
+                {
+                  add_to_strlist (&opt.sender_list, mbox);
+                  xfree (mbox);
+                }
+            }
            break;
          case oCompress:
            /* this is the -z command line option */
@@ -2592,14 +3066,23 @@ main (int argc, char **argv)
          case oPassphraseFile:
             pwfd = open_info_file (pargs.r.ret_str, 0, 1);
             break;
-         case oPassphraseRepeat: opt.passphrase_repeat=pargs.r.ret_int; break;
+         case oPassphraseRepeat:
+            opt.passphrase_repeat = pargs.r.ret_int;
+            break;
+
+          case oPinentryMode:
+           opt.pinentry_mode = parse_pinentry_mode (pargs.r.ret_str);
+           if (opt.pinentry_mode == -1)
+              log_error (_("invalid pinentry mode '%s'\n"), pargs.r.ret_str);
+           break;
+
          case oCommandFD:
             opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
             break;
          case oCommandFile:
             opt.command_fd = open_info_file (pargs.r.ret_str, 0, 1);
             break;
-         case oCipherAlgo: 
+         case oCipherAlgo:
             def_cipher_string = xstrdup(pargs.r.ret_str);
             break;
          case oDigestAlgo:
@@ -2629,12 +3112,12 @@ main (int argc, char **argv)
                compress_algo_string = xstrdup(pargs.r.ret_str);
            }
            break;
-         case oCertDigestAlgo: 
+         case oCertDigestAlgo:
             cert_digest_string = xstrdup(pargs.r.ret_str);
             break;
 
-         case oNoSecmemWarn: 
-            gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); 
+         case oNoSecmemWarn:
+            gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);
             break;
 
          case oRequireSecmem: require_secmem=1; break;
@@ -2643,7 +3126,7 @@ main (int argc, char **argv)
          case oNoMDCWarn: opt.no_mdc_warn=1; break;
           case oDisplayCharset:
            if( set_native_charset( pargs.r.ret_str ) )
-               log_error(_("`%s' is not a valid character set\n"),
+               log_error(_("'%s' is not a valid character set\n"),
                          pargs.r.ret_str);
            break;
          case oNotDashEscaped: opt.not_dash_escaped = 1; break;
@@ -2651,7 +3134,7 @@ main (int argc, char **argv)
          case oNoEscapeFrom: opt.escape_from = 0; break;
          case oLockOnce: opt.lock_once = 1; break;
          case oLockNever:
-            disable_dotlock ();
+            dotlock_disable ();
             break;
          case oLockMultiple:
 #ifndef __riscos__
@@ -2663,13 +3146,18 @@ main (int argc, char **argv)
          case oKeyServer:
            {
              keyserver_spec_t keyserver;
-             keyserver = parse_keyserver_uri (pargs.r.ret_str,0,
-                                               configname,configlineno);
+             keyserver = parse_keyserver_uri (pargs.r.ret_str, 0);
              if (!keyserver)
                log_error (_("could not parse keyserver URL\n"));
              else
                {
-                 keyserver->next = opt.keyserver;
+                 /* We only support a single keyserver.  Later ones
+                    override earlier ones.  (Since we parse the
+                    config file first and then the command line
+                    arguments, the command line takes
+                    precedence.)  */
+                 if (opt.keyserver)
+                   free_keyserver_spec (opt.keyserver);
                  opt.keyserver = keyserver;
                }
            }
@@ -2694,6 +3182,11 @@ main (int argc, char **argv)
                  log_error(_("invalid import options\n"));
              }
            break;
+         case oImportFilter:
+           rc = parse_and_set_import_filter (pargs.r.ret_str);
+           if (rc)
+              log_error (_("invalid filter option: %s\n"), gpg_strerror (rc));
+           break;
          case oExportOptions:
            if(!parse_export_options(pargs.r.ret_str,&opt.export_options,1))
              {
@@ -2704,6 +3197,11 @@ main (int argc, char **argv)
                  log_error(_("invalid export options\n"));
              }
            break;
+         case oExportFilter:
+           rc = parse_and_set_export_filter (pargs.r.ret_str);
+           if (rc)
+              log_error (_("invalid filter option: %s\n"), gpg_strerror (rc));
+           break;
          case oListOptions:
            if(!parse_list_options(pargs.r.ret_str))
              {
@@ -2799,21 +3297,17 @@ main (int argc, char **argv)
             }
             break;
           case oNoSigCache: opt.no_sig_cache = 1; break;
-          case oNoSigCreateCheck: opt.no_sig_create_check = 1; break;
          case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; break;
          case oNoAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid=0; break;
          case oAllowFreeformUID: opt.allow_freeform_uid = 1; break;
          case oNoAllowFreeformUID: opt.allow_freeform_uid = 0; break;
          case oNoLiteral: opt.no_literal = 1; break;
          case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
-         case oHonorHttpProxy:
-               add_to_strlist(&opt.keyserver_options.other,"http-proxy");
-               deprecated_warning(configname,configlineno,
-                                  "--honor-http-proxy",
-                                  "--keyserver-options ","http-proxy");
-               break;
          case oFastListMode: opt.fast_list_mode = 1; break;
          case oFixedListMode: /* Dummy */ break;
+          case oLegacyListMode: opt.legacy_list_mode = 1; break;
+         case oPrintPKARecords: print_pka_records = 1; break;
+         case oPrintDANERecords: print_dane_records = 1; break;
          case oListOnly: opt.list_only=1; break;
          case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
          case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
@@ -2826,17 +3320,14 @@ main (int argc, char **argv)
                  opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
                else
                  opt.keyserver_options.options&=~KEYSERVER_AUTO_KEY_RETRIEVE;
-
-               deprecated_warning(configname,configlineno,
-                          pargs.r_opt==oAutoKeyRetrieve?"--auto-key-retrieve":
-                              "--no-auto-key-retrieve","--keyserver-options ",
-                          pargs.r_opt==oAutoKeyRetrieve?"auto-key-retrieve":
-                              "no-auto-key-retrieve");
                break;
          case oShowSessionKey: opt.show_session_key = 1; break;
          case oOverrideSessionKey:
                opt.override_session_key = pargs.r.ret_str;
                break;
+         case oOverrideSessionKeyFD:
+                ovrseskeyfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
+               break;
          case oMergeOnly:
                deprecated_warning(configname,configlineno,"--merge-only",
                                   "--import-options ","merge-only");
@@ -2845,9 +3336,11 @@ main (int argc, char **argv)
           case oAllowSecretKeyImport: /* obsolete */ break;
          case oTryAllSecrets: opt.try_all_secrets = 1; break;
           case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
+
           case oEnableSpecialFilenames:
-            iobuf_enable_special_filenames (1);
+            enable_special_filenames ();
             break;
+
           case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break;
           case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break;
           case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break;
@@ -2858,13 +3351,12 @@ main (int argc, char **argv)
          case oDefaultKeyserverURL:
            {
              keyserver_spec_t keyserver;
-             keyserver = parse_keyserver_uri (pargs.r.ret_str,1,
-                                               configname,configlineno);
+             keyserver = parse_keyserver_uri (pargs.r.ret_str,1 );
              if (!keyserver)
                log_error (_("could not parse keyserver URL\n"));
              else
                free_keyserver_spec (keyserver);
-              
+
              opt.def_keyserver_url = pargs.r.ret_str;
            }
            break;
@@ -2878,6 +3370,16 @@ main (int argc, char **argv)
            pers_compress_list=pargs.r.ret_str;
            break;
           case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
+          case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break;
+          case oWeakDigest:
+           additional_weak_digest(pargs.r.ret_str);
+           break;
+          case oUnwrap:
+            opt.unwrap_encryption = 1;
+            break;
+          case oOnlySignTextIDs:
+            opt.only_sign_text_ids = 1;
+            break;
 
           case oDisplay:
             set_opt_session_env ("DISPLAY", pargs.r.ret_str);
@@ -2907,8 +3409,8 @@ main (int argc, char **argv)
              }
            break;
 
-         case oStrict: 
-         case oNoStrict: 
+         case oStrict:
+         case oNoStrict:
            /* Not used */
             break;
 
@@ -2925,16 +3427,18 @@ main (int argc, char **argv)
              opt.keyid_format=KF_0xSHORT;
            else if(ascii_strcasecmp(pargs.r.ret_str,"0xlong")==0)
              opt.keyid_format=KF_0xLONG;
+           else if(ascii_strcasecmp(pargs.r.ret_str,"none")==0)
+             opt.keyid_format = KF_NONE;
            else
-             log_error("unknown keyid-format `%s'\n",pargs.r.ret_str);
+             log_error("unknown keyid-format '%s'\n",pargs.r.ret_str);
            break;
 
           case oExitOnStatusWriteError:
             opt.exit_on_status_write_error = 1;
             break;
 
-         case oLimitCardInsertTries: 
-            opt.limit_card_insert_tries = pargs.r.ret_int; 
+         case oLimitCardInsertTries:
+            opt.limit_card_insert_tries = pargs.r.ret_int;
             break;
 
          case oRequireCrossCert: opt.flags.require_cross_cert=1; break;
@@ -2954,6 +3458,22 @@ main (int argc, char **argv)
            release_akl();
            break;
 
+         case oEnableLargeRSA:
+#if SECMEM_BUFFER_SIZE >= 65536
+            opt.flags.large_rsa=1;
+#else
+            if (configname)
+              log_info("%s:%d: WARNING: gpg not built with large secure "
+                         "memory buffer.  Ignoring enable-large-rsa\n",
+                        configname,configlineno);
+            else
+              log_info("WARNING: gpg not built with large secure "
+                         "memory buffer.  Ignoring --enable-large-rsa\n");
+#endif /* SECMEM_BUFFER_SIZE >= 65536 */
+            break;
+         case oDisableLargeRSA: opt.flags.large_rsa=0;
+            break;
+
          case oEnableDSA2: opt.flags.dsa2=1; break;
          case oDisableDSA2: opt.flags.dsa2=0; break;
 
@@ -2966,18 +3486,28 @@ main (int argc, char **argv)
            opt.flags.allow_multiple_messages=0;
            break;
 
+          case oAllowWeakDigestAlgos:
+            opt.flags.allow_weak_digest_algos = 1;
+            break;
+
           case oFakedSystemTime:
             {
-              time_t faked_time = isotime2epoch (pargs.r.ret_str); 
+              time_t faked_time = isotime2epoch (pargs.r.ret_str);
               if (faked_time == (time_t)(-1))
                 faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10);
               gnupg_set_time (faked_time, 0);
             }
             break;
 
+          case oNoAutostart: opt.autostart = 0; break;
+
+         case oDefaultNewKeyAlgo:
+            opt.def_new_key_algo = pargs.r.ret_str;
+            break;
+
          case oNoop: break;
 
-         default: 
+         default:
             pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
             break;
          }
@@ -3009,6 +3539,18 @@ main (int argc, char **argv)
     xfree (save_configname);
     xfree (default_configname);
 
+    if (print_dane_records)
+      log_error ("invalid option \"%s\"; use \"%s\" instead\n",
+                 "--print-dane-records",
+                 "--export-options export-dane");
+    if (print_pka_records)
+      log_error ("invalid option \"%s\"; use \"%s\" instead\n",
+                 "--print-pks-records",
+                 "--export-options export-pka");
+    if (log_get_errorcount (0))
+      g10_exit(2);
+
+
     if( nogreeting )
        greeting = 0;
 
@@ -3039,24 +3581,22 @@ main (int argc, char **argv)
     if (logfile && opt.batch)
       {
         log_set_file (logfile);
-        log_set_prefix (NULL, 1|2|4);
-      }
-
-    /* Older Libgcrypts fail with an assertion during DSA key
-       generation.  Better disable DSA2 entirely. */
-    if (opt.flags.dsa2 && !gcry_check_version ("1.4.0") )
-      {
-        log_info ("WARNING: "
-                  "DSA2 is only available with Libgcrypt 1.4 and later\n");
-        opt.flags.dsa2 = 0;
+        log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID);
       }
 
     if (opt.verbose > 2)
-        log_info ("using character set `%s'\n", get_native_charset ());
+        log_info ("using character set '%s'\n", get_native_charset ());
 
     if( may_coredump && !opt.quiet )
        log_info(_("WARNING: program may create a core file!\n"));
 
+    if (opt.flags.rfc4880bis)
+       log_info ("WARNING: using experimental features from RFC4880bis!\n");
+    else
+      {
+        opt.mimemode = 0; /* This will use text mode instead.  */
+      }
+
     if (eyes_only) {
       if (opt.set_filename)
          log_info(_("WARNING: %s overrides %s\n"),
@@ -3066,7 +3606,7 @@ main (int argc, char **argv)
     }
 
     if (opt.no_literal) {
-       log_info(_("NOTE: %s is not for normal use!\n"), "--no-literal");
+       log_info(_("Note: %s is not for normal use!\n"), "--no-literal");
        if (opt.textmode)
            log_error(_("%s not allowed with %s!\n"),
                       "--textmode", "--no-literal" );
@@ -3078,20 +3618,30 @@ main (int argc, char **argv)
 
 
     if (opt.set_filesize)
-       log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize");
+       log_info(_("Note: %s is not for normal use!\n"), "--set-filesize");
     if( opt.batch )
        tty_batchmode( 1 );
 
     if (gnupg_faked_time_p ())
       {
         gnupg_isotime_t tbuf;
-        
+
         log_info (_("WARNING: running with faked system time: "));
         gnupg_get_isotime (tbuf);
         dump_isotime (tbuf);
         log_printf ("\n");
       }
-    
+
+    /* Print a warning if an argument looks like an option.  */
+    if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
+      {
+        int i;
+
+        for (i=0; i < argc; i++)
+          if (argv[i][0] == '-' && argv[i][1] == '-')
+            log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
+      }
+
 
     gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
 
@@ -3103,90 +3653,23 @@ main (int argc, char **argv)
       }
 
     set_debug (debug_level);
+    if (DBG_CLOCK)
+      log_clock ("start");
 
     /* Do these after the switch(), so they can override settings. */
-    if(PGP2)
-      {
-       int unusable=0;
-
-       if(cmd==aSign && !detached_sig)
-         {
-           log_info(_("you can only make detached or clear signatures "
-                      "while in --pgp2 mode\n"));
-           unusable=1;
-         }
-       else if(cmd==aSignEncr || cmd==aSignSym)
-         {
-           log_info(_("you can't sign and encrypt at the "
-                      "same time while in --pgp2 mode\n"));
-           unusable=1;
-         }
-       else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym))
-         {
-           log_info(_("you must use files (and not a pipe) when "
-                      "working with --pgp2 enabled.\n"));
-           unusable=1;
-         }
-       else if(cmd==aEncr || cmd==aSym)
-         {
-           /* Everything else should work without IDEA (except using
-              a secret key encrypted with IDEA and setting an IDEA
-              preference, but those have their own error
-              messages). */
-
-           if (openpgp_cipher_test_algo(CIPHER_ALGO_IDEA))
-             {
-               log_info(_("encrypting a message in --pgp2 mode requires "
-                          "the IDEA cipher\n"));
-               idea_cipher_warn(1);
-               unusable=1;
-             }
-           else if(cmd==aSym)
-             {
-               /* This only sets IDEA for symmetric encryption
-                  since it is set via select_algo_from_prefs for
-                  pk encryption. */
-               xfree(def_cipher_string);
-               def_cipher_string = xstrdup("idea");
-             }
-
-           /* PGP2 can't handle the output from the textmode
-              filter, so we disable it for anything that could
-              create a literal packet (only encryption and
-              symmetric encryption, since we disable signing
-              above). */
-           if(!unusable)
-             opt.textmode=0;
-         }
-
-       if(unusable)
-         compliance_failure();
-       else
-         {
-           opt.force_v4_certs = 0;
-           opt.escape_from = 1;
-           opt.force_v3_sigs = 1;
-           opt.pgp2_workarounds = 1;
-           opt.ask_sig_expire = 0;
-           opt.ask_cert_expire = 0;
-           xfree(def_digest_string);
-           def_digest_string = xstrdup("md5");
-           xfree(s2k_digest_string);
-           s2k_digest_string = xstrdup("md5");
-           opt.compress_algo = COMPRESS_ALGO_ZIP;
-         }
-      }
-    else if(PGP6)
+    if(PGP6)
       {
+        /* That does not anymore work because we have no more support
+           for v3 signatures.  */
        opt.disable_mdc=1;
        opt.escape_from=1;
-       opt.force_v3_sigs=1;
        opt.ask_sig_expire=0;
       }
     else if(PGP7)
       {
+        /* That does not anymore work because we have no more support
+           for v3 signatures.  */
        opt.escape_from=1;
-       opt.force_v3_sigs=1;
        opt.ask_sig_expire=0;
       }
     else if(PGP8)
@@ -3197,10 +3680,6 @@ main (int argc, char **argv)
 
     if( def_cipher_string ) {
        opt.def_cipher_algo = string_to_cipher_algo (def_cipher_string);
-       if(opt.def_cipher_algo==0 &&
-          (ascii_strcasecmp(def_cipher_string,"idea")==0
-           || ascii_strcasecmp(def_cipher_string,"s1")==0))
-         idea_cipher_warn(1);
        xfree(def_cipher_string); def_cipher_string = NULL;
        if ( openpgp_cipher_test_algo (opt.def_cipher_algo) )
            log_error(_("selected cipher algorithm is invalid\n"));
@@ -3247,7 +3726,7 @@ main (int argc, char **argv)
       log_error(_("invalid min-cert-level; must be 1, 2, or 3\n"));
     switch( opt.s2k_mode ) {
       case 0:
-       log_info(_("NOTE: simple S2K mode (0) is strongly discouraged\n"));
+       log_info(_("Note: simple S2K mode (0) is strongly discouraged\n"));
        break;
       case 1: case 3: break;
       default:
@@ -3282,8 +3761,11 @@ main (int argc, char **argv)
          case aSign:
            cmdname="--sign";
            break;
+         case aSignEncr:
+           cmdname="--sign --encrypt";
+           break;
          case aClearsign:
-           cmdname="--clearsign";
+           cmdname="--clear-sign";
            break;
          case aDetachedSign:
            cmdname="--detach-sign";
@@ -3350,17 +3832,17 @@ main (int argc, char **argv)
            switch(badtype)
              {
              case PREFTYPE_SYM:
-               log_info(_("you may not use cipher algorithm `%s'"
+               log_info(_("you may not use cipher algorithm '%s'"
                           " while in %s mode\n"),
                         badalg,compliance_option_string());
                break;
              case PREFTYPE_HASH:
-               log_info(_("you may not use digest algorithm `%s'"
+               log_info(_("you may not use digest algorithm '%s'"
                           " while in %s mode\n"),
                         badalg,compliance_option_string());
                break;
              case PREFTYPE_ZIP:
-               log_info(_("you may not use compression algorithm `%s'"
+               log_info(_("you may not use compression algorithm '%s'"
                           " while in %s mode\n"),
                         badalg,compliance_option_string());
                break;
@@ -3374,7 +3856,7 @@ main (int argc, char **argv)
 
     /* Set the random seed file. */
     if( use_random_seed ) {
-       char *p = make_filename(opt.homedir, "random_seed", NULL );
+      char *p = make_filename (gnupg_homedir (), "random_seed", NULL );
        gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
         if (!access (p, F_OK))
           register_secured_file (p);
@@ -3392,30 +3874,38 @@ main (int argc, char **argv)
     if( opt.verbose > 1 )
        set_packet_list_mode(1);
 
-    /* Add the keyrings, but not for some special commands.  Also
-       avoid adding the secret keyring for a couple of commands to
-       avoid unneeded access in case the secrings are stored on a
-       floppy.
-       
-       We always need to add the keyrings if we are running under
-       SELinux, this is so that the rings are added to the list of
-       secured files. */
-    if( ALWAYS_ADD_KEYRINGS 
-        || (cmd != aDeArmor && cmd != aEnArmor && cmd != aGPGConfTest) ) 
+    /* Add the keyrings, but not for some special commands.  We always
+     * need to add the keyrings if we are running under SELinux, this
+     * is so that the rings are added to the list of secured files.
+     * We do not add any keyring if --no-keyring has been used.  */
+    if (default_keyring >= 0
+        && (ALWAYS_ADD_KEYRINGS
+            || (cmd != aDeArmor && cmd != aEnArmor && cmd != aGPGConfTest)))
       {
-       if (!nrings || default_keyring)  /* Add default ring. */
-           keydb_add_resource ("pubring" EXTSEP_S "gpg", 4);
+       if (!nrings || default_keyring > 0)  /* Add default ring. */
+           keydb_add_resource ("pubring" EXTSEP_S GPGEXT_GPG,
+                                KEYDB_RESOURCE_FLAG_DEFAULT);
        for (sl = nrings; sl; sl = sl->next )
           keydb_add_resource (sl->d, sl->flags);
       }
     FREE_STRLIST(nrings);
 
+    if (opt.pinentry_mode == PINENTRY_MODE_LOOPBACK)
+      /* In loopback mode, never ask for the password multiple
+        times.  */
+      {
+       opt.passphrase_repeat = 0;
+      }
+
     if (cmd == aGPGConfTest)
       g10_exit(0);
 
 
-    if( pwfd != -1 )  /* Read the passphrase now. */
-       read_passphrase_from_fd( pwfd );
+    if (pwfd != -1)  /* Read the passphrase now. */
+      read_passphrase_from_fd (pwfd);
+
+    if (ovrseskeyfd != -1 )  /* Read the sessionkey now. */
+      read_sessionkey_from_fd (ovrseskeyfd);
 
     fname = argc? *argv : NULL;
 
@@ -3425,30 +3915,43 @@ main (int argc, char **argv)
     ctrl = xcalloc (1, sizeof *ctrl);
     gpg_init_default_ctrl (ctrl);
 
-    switch( cmd ) {
+#ifndef NO_TRUST_MODELS
+    switch (cmd)
+      {
       case aPrimegen:
       case aPrintMD:
       case aPrintMDs:
       case aGenRandom:
       case aDeArmor:
       case aEnArmor:
+      case aListConfig:
+      case aListGcryptConfig:
        break;
       case aFixTrustDB:
-      case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break;
-      case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break;
-      default: rc = setup_trustdb(1, trustdb_name ); break;
-    }
-    if( rc )
-       log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
-
+      case aExportOwnerTrust:
+        rc = setup_trustdb (0, trustdb_name);
+        break;
+      case aListTrustDB:
+        rc = setup_trustdb (argc? 1:0, trustdb_name);
+        break;
+      default:
+        /* If we are using TM_ALWAYS, we do not need to create the
+           trustdb.  */
+        rc = setup_trustdb (opt.trust_model != TM_ALWAYS, trustdb_name);
+        break;
+      }
+    if (rc)
+      log_error (_("failed to initialize the TrustDB: %s\n"),
+                 gpg_strerror (rc));
+#endif /*!NO_TRUST_MODELS*/
 
     switch (cmd)
       {
-      case aStore: 
-      case aSym:  
-      case aSign: 
-      case aSignSym: 
-      case aClearsign: 
+      case aStore:
+      case aSym:
+      case aSign:
+      case aSignSym:
+      case aClearsign:
         if (!opt.quiet && any_explicit_recipient)
           log_info (_("WARNING: recipients (-r) given "
                       "without using public key encryption\n"));
@@ -3457,6 +3960,48 @@ main (int argc, char **argv)
         break;
       }
 
+
+    /* Check for certain command whether we need to migrate a
+       secring.gpg to the gpg-agent. */
+    switch (cmd)
+      {
+      case aListSecretKeys:
+      case aSign:
+      case aSignEncr:
+      case aSignEncrSym:
+      case aSignSym:
+      case aClearsign:
+      case aDecrypt:
+      case aSignKey:
+      case aLSignKey:
+      case aEditKey:
+      case aPasswd:
+      case aDeleteSecretKeys:
+      case aDeleteSecretAndPublicKeys:
+      case aQuickKeygen:
+      case aQuickAddUid:
+      case aQuickAddKey:
+      case aQuickRevUid:
+      case aFullKeygen:
+      case aKeygen:
+      case aImport:
+      case aExportSecret:
+      case aExportSecretSub:
+      case aGenRevoke:
+      case aDesigRevoke:
+      case aCardEdit:
+      case aChangePIN:
+        migrate_secring (ctrl);
+       break;
+      case aListKeys:
+        if (opt.with_secret)
+          migrate_secring (ctrl);
+        break;
+      default:
+        break;
+      }
+
+    /* The command dispatcher.  */
     switch( cmd )
       {
       case aServer:
@@ -3465,17 +4010,23 @@ main (int argc, char **argv)
 
       case aStore: /* only store the file */
        if( argc > 1 )
-           wrong_args(_("--store [filename]"));
+           wrong_args("--store [filename]");
        if( (rc = encrypt_store(fname)) )
-           log_error ("storing `%s' failed: %s\n",
-                       print_fname_stdin(fname),g10_errstr(rc) );
+          {
+            write_status_failure ("store", rc);
+           log_error ("storing '%s' failed: %s\n",
+                       print_fname_stdin(fname),gpg_strerror (rc) );
+          }
        break;
       case aSym: /* encrypt the given file only with the symmetric cipher */
        if( argc > 1 )
-           wrong_args(_("--symmetric [filename]"));
+           wrong_args("--symmetric [filename]");
        if( (rc = encrypt_symmetric(fname)) )
-            log_error (_("symmetric encryption of `%s' failed: %s\n"),
-                        print_fname_stdin(fname),g10_errstr(rc) );
+          {
+            write_status_failure ("symencrypt", rc);
+            log_error (_("symmetric encryption of '%s' failed: %s\n"),
+                        print_fname_stdin(fname),gpg_strerror (rc) );
+          }
        break;
 
       case aEncr: /* encrypt the given file */
@@ -3484,10 +4035,13 @@ main (int argc, char **argv)
        else
          {
            if( argc > 1 )
-             wrong_args(_("--encrypt [filename]"));
+             wrong_args("--encrypt [filename]");
            if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 0, NULL, -1)) )
-             log_error("%s: encryption failed: %s\n",
-                       print_fname_stdin(fname), g10_errstr(rc) );
+              {
+                write_status_failure ("encrypt", rc);
+                log_error("%s: encryption failed: %s\n",
+                          print_fname_stdin(fname), gpg_strerror (rc) );
+              }
          }
        break;
 
@@ -3497,18 +4051,21 @@ main (int argc, char **argv)
           might work with 7, but alas, I don't have a copy to test
           with right now. */
        if( argc > 1 )
-         wrong_args(_("--symmetric --encrypt [filename]"));
+         wrong_args("--symmetric --encrypt [filename]");
        else if(opt.s2k_mode==0)
          log_error(_("you cannot use --symmetric --encrypt"
                      " with --s2k-mode 0\n"));
-       else if(PGP2 || PGP6 || PGP7 || RFC1991)
+       else if(PGP6 || PGP7)
          log_error(_("you cannot use --symmetric --encrypt"
                      " while in %s mode\n"),compliance_option_string());
        else
          {
            if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 1, NULL, -1)) )
-             log_error("%s: encryption failed: %s\n",
-                       print_fname_stdin(fname), g10_errstr(rc) );
+              {
+                write_status_failure ("encrypt", rc);
+                log_error ("%s: encryption failed: %s\n",
+                           print_fname_stdin(fname), gpg_strerror (rc) );
+              }
          }
        break;
 
@@ -3520,20 +4077,23 @@ main (int argc, char **argv)
        }
        else {
            if( argc > 1 )
-               wrong_args(_("--sign [filename]"));
+               wrong_args("--sign [filename]");
            if( argc ) {
                sl = xmalloc_clear( sizeof *sl + strlen(fname));
                strcpy(sl->d, fname);
            }
        }
-       if( (rc = sign_file (ctrl, sl, detached_sig, locusr, 0, NULL, NULL)) )
-           log_error("signing failed: %s\n", g10_errstr(rc) );
+       if ((rc = sign_file (ctrl, sl, detached_sig, locusr, 0, NULL, NULL)))
+          {
+            write_status_failure ("sign", rc);
+           log_error ("signing failed: %s\n", gpg_strerror (rc) );
+          }
        free_strlist(sl);
        break;
 
       case aSignEncr: /* sign and encrypt the given file */
        if( argc > 1 )
-           wrong_args(_("--sign --encrypt [filename]"));
+           wrong_args("--sign --encrypt [filename]");
        if( argc ) {
            sl = xmalloc_clear( sizeof *sl + strlen(fname));
            strcpy(sl->d, fname);
@@ -3541,18 +4101,21 @@ main (int argc, char **argv)
        else
            sl = NULL;
        if ((rc = sign_file (ctrl, sl, detached_sig, locusr, 1, remusr, NULL)))
+          {
+            write_status_failure ("sign-encrypt", rc);
            log_error("%s: sign+encrypt failed: %s\n",
-                     print_fname_stdin(fname), g10_errstr(rc) );
+                     print_fname_stdin(fname), gpg_strerror (rc) );
+          }
        free_strlist(sl);
        break;
 
       case aSignEncrSym: /* sign and encrypt the given file */
        if( argc > 1 )
-           wrong_args(_("--symmetric --sign --encrypt [filename]"));
+           wrong_args("--symmetric --sign --encrypt [filename]");
        else if(opt.s2k_mode==0)
          log_error(_("you cannot use --symmetric --sign --encrypt"
                      " with --s2k-mode 0\n"));
-       else if(PGP2 || PGP6 || PGP7 || RFC1991)
+       else if(PGP6 || PGP7)
          log_error(_("you cannot use --symmetric --sign --encrypt"
                      " while in %s mode\n"),compliance_option_string());
        else
@@ -3566,40 +4129,51 @@ main (int argc, char **argv)
              sl = NULL;
            if ((rc = sign_file (ctrl, sl, detached_sig, locusr,
                                  2, remusr, NULL)))
-             log_error("%s: symmetric+sign+encrypt failed: %s\n",
-                       print_fname_stdin(fname), g10_errstr(rc) );
+              {
+                write_status_failure ("sign-encrypt", rc);
+                log_error("%s: symmetric+sign+encrypt failed: %s\n",
+                          print_fname_stdin(fname), gpg_strerror (rc) );
+              }
            free_strlist(sl);
          }
        break;
 
       case aSignSym: /* sign and conventionally encrypt the given file */
        if (argc > 1)
-           wrong_args(_("--sign --symmetric [filename]"));
-       rc = sign_symencrypt_file (fname, locusr);
+           wrong_args("--sign --symmetric [filename]");
+       rc = sign_symencrypt_file (ctrl, fname, locusr);
         if (rc)
+          {
+            write_status_failure ("sign-symencrypt", rc);
            log_error("%s: sign+symmetric failed: %s\n",
-                      print_fname_stdin(fname), g10_errstr(rc) );
+                      print_fname_stdin(fname), gpg_strerror (rc) );
+          }
        break;
 
       case aClearsign: /* make a clearsig */
        if( argc > 1 )
-           wrong_args(_("--clearsign [filename]"));
-       if( (rc = clearsign_file(fname, locusr, NULL)) )
-           log_error("%s: clearsign failed: %s\n",
-                      print_fname_stdin(fname), g10_errstr(rc) );
+           wrong_args("--clear-sign [filename]");
+       if( (rc = clearsign_file (ctrl, fname, locusr, NULL)) )
+          {
+            write_status_failure ("sign", rc);
+           log_error("%s: clear-sign failed: %s\n",
+                      print_fname_stdin(fname), gpg_strerror (rc) );
+          }
        break;
 
       case aVerify:
        if (multifile)
          {
            if ((rc = verify_files (ctrl, argc, argv)))
-             log_error("verify files failed: %s\n", g10_errstr(rc) );
+             log_error("verify files failed: %s\n", gpg_strerror (rc) );
          }
        else
          {
            if ((rc = verify_signatures (ctrl, argc, argv)))
-             log_error("verify signatures failed: %s\n", g10_errstr(rc) );
+             log_error("verify signatures failed: %s\n", gpg_strerror (rc) );
          }
+        if (rc)
+          write_status_failure ("verify", rc);
        break;
 
       case aDecrypt:
@@ -3608,19 +4182,38 @@ main (int argc, char **argv)
        else
          {
            if( argc > 1 )
-             wrong_args(_("--decrypt [filename]"));
+             wrong_args("--decrypt [filename]");
            if( (rc = decrypt_message (ctrl, fname) ))
-             log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
+              {
+                write_status_failure ("decrypt", rc);
+                log_error("decrypt_message failed: %s\n", gpg_strerror (rc) );
+              }
          }
        break;
-            
+
+      case aQuickSignKey:
+      case aQuickLSignKey:
+        {
+          const char *fpr;
+
+          if (argc < 1)
+            wrong_args ("--quick-[l]sign-key fingerprint [userids]");
+          fpr = *argv++; argc--;
+          sl = NULL;
+          for( ; argc; argc--, argv++)
+           append_to_strlist2 (&sl, *argv, utf8_strings);
+          keyedit_quick_sign (ctrl, fpr, sl, locusr, (cmd == aQuickLSignKey));
+          free_strlist (sl);
+        }
+       break;
+
       case aSignKey:
        if( argc != 1 )
-         wrong_args(_("--sign-key user-id"));
+         wrong_args("--sign-key user-id");
        /* fall through */
       case aLSignKey:
        if( argc != 1 )
-         wrong_args(_("--lsign-key user-id"));
+         wrong_args("--lsign-key user-id");
        /* fall through */
 
        sl=NULL;
@@ -3641,7 +4234,7 @@ main (int argc, char **argv)
 
       case aEditKey: /* Edit a key signature */
        if( !argc )
-           wrong_args(_("--edit-key user-id [commands]"));
+           wrong_args("--edit-key user-id [commands]");
        username = make_username( fname );
        if( argc > 1 ) {
            sl = NULL;
@@ -3657,7 +4250,7 @@ main (int argc, char **argv)
 
       case aPasswd:
         if (argc != 1)
-          wrong_args (_("--passwd <user-id>"));
+          wrong_args("--change-passphrase <user-id>");
         else
           {
             username = make_username (fname);
@@ -3705,19 +4298,133 @@ main (int argc, char **argv)
        free_strlist (sl);
        break;
 
+      case aQuickKeygen:
+        {
+          const char *x_algo, *x_usage, *x_expire;
+
+          if (argc < 1 || argc > 4)
+            wrong_args("--quick-generate-key USER-ID [ALGO [USAGE [EXPIRE]]]");
+          username = make_username (fname);
+          argv++, argc--;
+          x_algo = "";
+          x_usage = "";
+          x_expire = "";
+          if (argc)
+            {
+              x_algo = *argv++; argc--;
+              if (argc)
+                {
+                  x_usage = *argv++; argc--;
+                  if (argc)
+                    {
+                      x_expire = *argv++; argc--;
+                    }
+                }
+            }
+          quick_generate_keypair (ctrl, username, x_algo, x_usage, x_expire);
+          xfree (username);
+        }
+        break;
+
       case aKeygen: /* generate a key */
        if( opt.batch ) {
            if( argc > 1 )
-               wrong_args("--gen-key [parameterfile]");
-           generate_keypair (argc? *argv : NULL, NULL, 0);
+               wrong_args("--generate-key [parameterfile]");
+           generate_keypair (ctrl, 0, argc? *argv : NULL, NULL, 0);
        }
        else {
-           if( argc )
-               wrong_args("--gen-key");
-           generate_keypair (NULL, NULL, 0);
+            if (opt.command_fd != -1 && argc)
+              {
+                if( argc > 1 )
+                  wrong_args("--generate-key [parameterfile]");
+
+                opt.batch = 1;
+                generate_keypair (ctrl, 0, argc? *argv : NULL, NULL, 0);
+              }
+            else if (argc)
+              wrong_args ("--generate-key");
+            else
+              generate_keypair (ctrl, 0, NULL, NULL, 0);
        }
        break;
 
+      case aFullKeygen: /* Generate a key with all options. */
+       if (opt.batch)
+          {
+           if (argc > 1)
+              wrong_args ("--full-generate-key [parameterfile]");
+           generate_keypair (ctrl, 1, argc? *argv : NULL, NULL, 0);
+          }
+       else
+          {
+           if (argc)
+              wrong_args("--full-generate-key");
+           generate_keypair (ctrl, 1, NULL, NULL, 0);
+       }
+       break;
+
+      case aQuickAddUid:
+        {
+          const char *uid, *newuid;
+
+          if (argc != 2)
+            wrong_args ("--quick-add-uid USER-ID NEW-USER-ID");
+          uid = *argv++; argc--;
+          newuid = *argv++; argc--;
+          keyedit_quick_adduid (ctrl, uid, newuid);
+        }
+       break;
+
+      case aQuickAddKey:
+        {
+          const char *x_fpr, *x_algo, *x_usage, *x_expire;
+
+          if (argc < 1 || argc > 4)
+            wrong_args ("--quick-add-key FINGERPRINT [ALGO [USAGE [EXPIRE]]]");
+          x_fpr = *argv++; argc--;
+          x_algo = "";
+          x_usage = "";
+          x_expire = "";
+          if (argc)
+            {
+              x_algo = *argv++; argc--;
+              if (argc)
+                {
+                  x_usage = *argv++; argc--;
+                  if (argc)
+                   {
+                     x_expire = *argv++; argc--;
+                   }
+                }
+            }
+          keyedit_quick_addkey (ctrl, x_fpr, x_algo, x_usage, x_expire);
+        }
+       break;
+
+      case aQuickRevUid:
+        {
+          const char *uid, *uidtorev;
+
+          if (argc != 2)
+            wrong_args ("--quick-revoke-uid USER-ID USER-ID-TO-REVOKE");
+          uid = *argv++; argc--;
+          uidtorev = *argv++; argc--;
+          keyedit_quick_revuid (ctrl, uid, uidtorev);
+        }
+       break;
+
+      case aQuickSetExpire:
+        {
+          const char *x_fpr, *x_expire;
+
+          if (argc != 2)
+            wrong_args ("--quick-set-exipre FINGERPRINT EXPIRE");
+          x_fpr = *argv++; argc--;
+          x_expire = *argv++; argc--;
+          keyedit_quick_set_expire (ctrl, x_fpr, x_expire);
+        }
+       break;
+
       case aFastImport:
         opt.import_options |= IMPORT_FAST;
       case aImport:
@@ -3740,26 +4447,55 @@ main (int argc, char **argv)
        else if( cmd == aRecvKeys )
             rc = keyserver_import (ctrl, sl );
        else
-            rc = export_pubkeys (ctrl, sl, opt.export_options);
+          {
+            export_stats_t stats = export_new_stats ();
+            rc = export_pubkeys (ctrl, sl, opt.export_options, stats);
+            export_print_stats (stats);
+            export_release_stats (stats);
+          }
        if(rc)
          {
            if(cmd==aSendKeys)
-             log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
+              {
+                write_status_failure ("send-keys", rc);
+                log_error(_("keyserver send failed: %s\n"),gpg_strerror (rc));
+              }
            else if(cmd==aRecvKeys)
-             log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
+              {
+                write_status_failure ("recv-keys", rc);
+                log_error (_("keyserver receive failed: %s\n"),
+                           gpg_strerror (rc));
+              }
            else
-             log_error(_("key export failed: %s\n"),g10_errstr(rc));
+              {
+                write_status_failure ("export", rc);
+                log_error (_("key export failed: %s\n"), gpg_strerror (rc));
+              }
          }
        free_strlist(sl);
        break;
 
+      case aExportSshKey:
+        if (argc != 1)
+          wrong_args ("--export-ssh-key <user-id>");
+        rc = export_ssh_key (ctrl, argv[0]);
+        if (rc)
+          {
+            write_status_failure ("export-ssh-key", rc);
+            log_error (_("export as ssh key failed: %s\n"), gpg_strerror (rc));
+          }
+       break;
+
      case aSearchKeys:
        sl = NULL;
        for (; argc; argc--, argv++)
          append_to_strlist2 (&sl, *argv, utf8_strings);
        rc = keyserver_search (ctrl, sl);
        if (rc)
-         log_error (_("keyserver search failed: %s\n"), gpg_strerror (rc));
+          {
+            write_status_failure ("search-keys", rc);
+            log_error (_("keyserver search failed: %s\n"), gpg_strerror (rc));
+          }
        free_strlist (sl);
        break;
 
@@ -3769,7 +4505,10 @@ main (int argc, char **argv)
            append_to_strlist2( &sl, *argv, utf8_strings );
        rc = keyserver_refresh (ctrl, sl);
        if(rc)
-         log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
+          {
+            write_status_failure ("refresh-keys", rc);
+            log_error (_("keyserver refresh failed: %s\n"),gpg_strerror (rc));
+          }
        free_strlist(sl);
        break;
 
@@ -3779,7 +4518,10 @@ main (int argc, char **argv)
            append_to_strlist2( &sl, *argv, utf8_strings );
        rc = keyserver_fetch (ctrl, sl);
        if(rc)
-         log_error("key fetch failed: %s\n",g10_errstr(rc));
+          {
+            write_status_failure ("fetch-keys", rc);
+            log_error ("key fetch failed: %s\n",gpg_strerror (rc));
+          }
        free_strlist(sl);
        break;
 
@@ -3787,7 +4529,12 @@ main (int argc, char **argv)
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist2( &sl, *argv, utf8_strings );
-       export_seckeys (ctrl, sl);
+        {
+          export_stats_t stats = export_new_stats ();
+          export_seckeys (ctrl, sl, stats);
+          export_print_stats (stats);
+          export_release_stats (stats);
+        }
        free_strlist(sl);
        break;
 
@@ -3795,24 +4542,29 @@ main (int argc, char **argv)
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist2( &sl, *argv, utf8_strings );
-       export_secsubkeys (ctrl, sl);
+        {
+          export_stats_t stats = export_new_stats ();
+          export_secsubkeys (ctrl, sl, stats);
+          export_print_stats (stats);
+          export_release_stats (stats);
+        }
        free_strlist(sl);
        break;
 
       case aGenRevoke:
        if( argc != 1 )
-           wrong_args("--gen-revoke user-id");
+           wrong_args("--generate-revocation user-id");
        username =  make_username(*argv);
        gen_revoke( username );
        xfree( username );
        break;
 
       case aDesigRevoke:
-       if( argc != 1 )
-           wrong_args("--desig-revoke user-id");
-       username =  make_username(*argv);
-       gen_desig_revoke( username, locusr );
-       xfree( username );
+       if (argc != 1)
+           wrong_args ("--generate-designated-revocation user-id");
+       username = make_username (*argv);
+       gen_desig_revoke (ctrl, username, locusr);
+       xfree (username);
        break;
 
       case aDeArmor:
@@ -3820,7 +4572,10 @@ main (int argc, char **argv)
            wrong_args("--dearmor [file]");
        rc = dearmor_file( argc? *argv: NULL );
        if( rc )
-           log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
+          {
+            write_status_failure ("dearmor", rc);
+            log_error (_("dearmoring failed: %s\n"), gpg_strerror (rc));
+          }
        break;
 
       case aEnArmor:
@@ -3828,7 +4583,10 @@ main (int argc, char **argv)
            wrong_args("--enarmor [file]");
        rc = enarmor_file( argc? *argv: NULL );
        if( rc )
-           log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
+          {
+            write_status_failure ("enarmor", rc);
+           log_error (_("enarmoring failed: %s\n"), gpg_strerror (rc));
+          }
        break;
 
 
@@ -3850,7 +4608,7 @@ main (int argc, char **argv)
                mpi_print (es_stdout, generate_elg_prime(
                                             1, atoi(argv[1]),
                                             atoi(argv[2]), NULL,&factors ), 1);
-               putchar('\n');
+               es_putc ('\n', es_stdout);
                mpi_print (es_stdout, factors[0], 1 ); /* print q */
            }
            else if( mode == 4 && argc == 3 ) {
@@ -3858,13 +4616,13 @@ main (int argc, char **argv)
                mpi_print (es_stdout, generate_elg_prime(
                                                 0, atoi(argv[1]),
                                                 atoi(argv[2]), g, NULL ), 1);
-               putchar('\n');
+               es_putc ('\n', es_stdout);
                mpi_print (es_stdout, g, 1 );
                mpi_free (g);
            }
            else
                wrong_args("--gen-prime mode bits [qbits] ");
-           putchar('\n');
+           es_putc ('\n', es_stdout);
        }
 #endif
         wrong_args("--gen-prime not yet supported ");
@@ -3893,21 +4651,21 @@ main (int argc, char **argv)
 #endif
                 if (opt.armor) {
                     char *tmp = make_radix64_string (p, n);
-                    fputs (tmp, stdout);
+                    es_fputs (tmp, es_stdout);
                     xfree (tmp);
                     if (n%3 == 1)
-                      putchar ('=');
+                      es_putc ('=', es_stdout);
                     if (n%3)
-                      putchar ('=');
+                      es_putc ('=', es_stdout);
                 } else {
-                    fwrite( p, n, 1, stdout );
+                    es_fwrite( p, n, 1, es_stdout );
                 }
                xfree(p);
                if( !endless )
                    count -= n;
            }
             if (opt.armor)
-                putchar ('\n');
+              es_putc ('\n', es_stdout);
        }
        break;
 
@@ -3919,7 +4677,7 @@ main (int argc, char **argv)
            int algo = all_algos? 0 : gcry_md_map_name (*argv);
 
            if( !algo && !all_algos )
-               log_error(_("invalid hash algorithm `%s'\n"), *argv );
+               log_error(_("invalid hash algorithm '%s'\n"), *argv );
            else {
                argc--; argv++;
                if( !argc )
@@ -3941,24 +4699,25 @@ main (int argc, char **argv)
        }
        break;
 
+#ifndef NO_TRUST_MODELS
       case aListTrustDB:
        if( !argc )
-           list_trustdb(NULL);
+          list_trustdb (es_stdout, NULL);
        else {
            for( ; argc; argc--, argv++ )
-               list_trustdb( *argv );
+              list_trustdb (es_stdout, *argv );
        }
        break;
 
       case aUpdateTrustDB:
        if( argc )
            wrong_args("--update-trustdb");
-       update_trustdb();
+       update_trustdb (ctrl);
        break;
 
       case aCheckTrustDB:
         /* Old versions allowed for arguments - ignore them */
-        check_trustdb();
+        check_trustdb (ctrl);
        break;
 
       case aFixTrustDB:
@@ -3986,7 +4745,8 @@ main (int argc, char **argv)
            wrong_args("--import-ownertrust [file]");
        import_ownertrust( argc? *argv:NULL );
        break;
-      
+#endif /*!NO_TRUST_MODELS*/
+
       case aRebuildKeydbCaches:
         if (argc)
             wrong_args ("--rebuild-keydb-caches");
@@ -4018,7 +4778,7 @@ main (int argc, char **argv)
         else if (argc == 1)
             change_pin (atoi (*argv),1);
         else
-        wrong_args ("--change-pin [no]");
+            wrong_args ("--change-pin [no]");
         break;
 #endif /* ENABLE_CARD_SUPPORT*/
 
@@ -4030,11 +4790,101 @@ main (int argc, char **argv)
        }
        break;
 
+      case aListGcryptConfig:
+        /* Fixme: It would be nice to integrate that with
+           --list-config but unfortunately there is no way yet to have
+           libgcrypt print it to an estream for further parsing.  */
+        gcry_control (GCRYCTL_PRINT_CONFIG, stdout);
+        break;
+
+      case aTOFUPolicy:
+#ifdef USE_TOFU
+       {
+         int policy;
+         int i;
+         KEYDB_HANDLE hd;
+
+         if (argc < 2)
+           wrong_args ("--tofu-policy POLICY KEYID [KEYID...]");
+
+         policy = parse_tofu_policy (argv[0]);
+
+         hd = keydb_new ();
+         if (! hd)
+            g10_exit (1);
+
+          tofu_begin_batch_update (ctrl);
+
+         for (i = 1; i < argc; i ++)
+           {
+             KEYDB_SEARCH_DESC desc;
+             kbnode_t kb;
+
+             rc = classify_user_id (argv[i], &desc, 0);
+             if (rc)
+               {
+                 log_error (_("error parsing key specification '%s': %s\n"),
+                             argv[i], gpg_strerror (rc));
+                 g10_exit (1);
+               }
+
+             if (! (desc.mode == KEYDB_SEARCH_MODE_SHORT_KID
+                    || desc.mode == KEYDB_SEARCH_MODE_LONG_KID
+                    || desc.mode == KEYDB_SEARCH_MODE_FPR16
+                    || desc.mode == KEYDB_SEARCH_MODE_FPR20
+                    || desc.mode == KEYDB_SEARCH_MODE_FPR
+                    || desc.mode == KEYDB_SEARCH_MODE_KEYGRIP))
+               {
+                 log_error (_("'%s' does not appear to be a valid"
+                              " key ID, fingerprint or keygrip\n"),
+                            argv[i]);
+                 g10_exit (1);
+               }
+
+             rc = keydb_search_reset (hd);
+             if (rc)
+               {
+                  /* This should not happen, thus no need to tranalate
+                     the string.  */
+                  log_error ("keydb_search_reset failed: %s\n",
+                             gpg_strerror (rc));
+                 g10_exit (1);
+               }
+
+             rc = keydb_search (hd, &desc, 1, NULL);
+             if (rc)
+               {
+                 log_error (_("key \"%s\" not found: %s\n"), argv[i],
+                             gpg_strerror (rc));
+                 g10_exit (1);
+               }
+
+             rc = keydb_get_keyblock (hd, &kb);
+             if (rc)
+               {
+                 log_error (_("error reading keyblock: %s\n"),
+                             gpg_strerror (rc));
+                 g10_exit (1);
+               }
+
+             merge_keys_and_selfsig (kb);
+             if (tofu_set_policy (ctrl, kb, policy))
+               g10_exit (1);
+
+              release_kbnode (kb);
+           }
+
+          tofu_end_batch_update (ctrl);
+
+         keydb_release (hd);
+       }
+#endif /*USE_TOFU*/
+       break;
+
       case aListPackets:
-       opt.list_packets=2;
       default:
        if( argc > 1 )
-           wrong_args(_("[filename]"));
+           wrong_args("[filename]");
        /* Issue some output for the unix newbie */
        if (!fname && !opt.outfile
             && gnupg_isatty (fileno (stdin))
@@ -4050,7 +4900,7 @@ main (int argc, char **argv)
             gpg_err_set_errno (EPERM);
           }
        if( !a )
-           log_error(_("can't open `%s'\n"), print_fname_stdin(fname));
+           log_error(_("can't open '%s'\n"), print_fname_stdin(fname));
        else {
 
            if( !opt.no_armor ) {
@@ -4060,12 +4910,16 @@ main (int argc, char **argv)
                }
            }
            if( cmd == aListPackets ) {
-               set_packet_list_mode(1);
                opt.list_packets=1;
+               set_packet_list_mode(1);
            }
            rc = proc_packets (ctrl, NULL, a );
            if( rc )
-               log_error("processing message failed: %s\n", g10_errstr(rc) );
+              {
+                write_status_failure ("-", rc);
+                log_error ("processing message failed: %s\n",
+                           gpg_strerror (rc));
+              }
            iobuf_close(a);
        }
        break;
@@ -4094,8 +4948,12 @@ void
 g10_exit( int rc )
 {
   gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
+  if (DBG_CLOCK)
+    log_clock ("stop");
+
   if ( (opt.debug & DBG_MEMSTAT_VALUE) )
     {
+      keydb_dump_stats ();
       gcry_control (GCRYCTL_DUMP_MEMORY_STATS);
       gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
     }
@@ -4103,7 +4961,7 @@ g10_exit( int rc )
     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
 
   emergency_cleanup ();
-  
+
   rc = rc? rc : log_get_errorcount(0)? 2 : g10_errors_seen? 1 : 0;
   exit (rc);
 }
@@ -4123,7 +4981,7 @@ print_hex (gcry_md_hd_t md, int algo, const char *fname)
 
   if (indent>40)
     {
-      printf("\n");
+      es_printf ("\n");
       indent=0;
     }
 
@@ -4197,14 +5055,14 @@ print_hashline( gcry_md_hd_t md, int algo, const char *fname )
 {
   int i, n;
   const byte *p;
-    
+
   if ( fname )
     {
-      for (p = fname; *p; p++ ) 
+      for (p = fname; *p; p++ )
         {
           if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' )
             es_printf ("%%%02X", *p );
-          else 
+          else
             es_putc (*p, es_stdout);
         }
     }
@@ -4212,103 +5070,116 @@ print_hashline( gcry_md_hd_t md, int algo, const char *fname )
   es_printf ("%d:", algo);
   p = gcry_md_read (md, algo);
   n = gcry_md_get_algo_dlen (algo);
-  for(i=0; i < n ; i++, p++ ) 
+  for(i=0; i < n ; i++, p++ )
     es_printf ("%02X", *p);
   es_fputs (":\n", es_stdout);
 }
 
+
 static void
 print_mds( const char *fname, int algo )
 {
-    FILE *fp;
-    char buf[1024];
-    size_t n;
-    gcry_md_hd_t md;
+  estream_t fp;
+  char buf[1024];
+  size_t n;
+  gcry_md_hd_t md;
 
-    if( !fname ) {
-       fp = stdin;
-#ifdef HAVE_DOSISH_SYSTEM
-       setmode ( fileno(fp) , O_BINARY );
-#endif
+  if (!fname)
+    {
+      fp = es_stdin;
+      es_set_binary (fp);
     }
-    else {
-       fp = fopen( fname, "rb" );
-        if (fp && is_secured_file (fileno (fp)))
-          {
-            fclose (fp);
-            fp = NULL;
-            gpg_err_set_errno (EPERM);
-          }
+  else
+    {
+      fp = es_fopen (fname, "rb" );
+      if (fp && is_secured_file (es_fileno (fp)))
+        {
+          es_fclose (fp);
+          fp = NULL;
+          gpg_err_set_errno (EPERM);
+        }
     }
-    if( !fp ) {
-       log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
-       return;
+  if (!fp)
+    {
+      log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
+      return;
     }
 
-    gcry_md_open (&md, 0, 0);
-    if( algo )
-        gcry_md_enable (md, algo);
-    else {
-       gcry_md_enable (md, GCRY_MD_MD5);
-       gcry_md_enable (md, GCRY_MD_SHA1);
-       gcry_md_enable (md, GCRY_MD_RMD160);
-        if (!openpgp_md_test_algo (GCRY_MD_SHA224))
-          gcry_md_enable (md, GCRY_MD_SHA224);
-        if (!openpgp_md_test_algo (GCRY_MD_SHA256))
-          gcry_md_enable (md, GCRY_MD_SHA256);
-        if (!openpgp_md_test_algo (GCRY_MD_SHA384))
-          gcry_md_enable (md, GCRY_MD_SHA384);
-        if (!openpgp_md_test_algo (GCRY_MD_SHA512))
-          gcry_md_enable (md, GCRY_MD_SHA512);
+  gcry_md_open (&md, 0, 0);
+  if (algo)
+    gcry_md_enable (md, algo);
+  else
+    {
+      if (!gcry_md_test_algo (GCRY_MD_MD5))
+        gcry_md_enable (md, GCRY_MD_MD5);
+      gcry_md_enable (md, GCRY_MD_SHA1);
+      if (!gcry_md_test_algo (GCRY_MD_RMD160))
+        gcry_md_enable (md, GCRY_MD_RMD160);
+      if (!gcry_md_test_algo (GCRY_MD_SHA224))
+        gcry_md_enable (md, GCRY_MD_SHA224);
+      if (!gcry_md_test_algo (GCRY_MD_SHA256))
+        gcry_md_enable (md, GCRY_MD_SHA256);
+      if (!gcry_md_test_algo (GCRY_MD_SHA384))
+        gcry_md_enable (md, GCRY_MD_SHA384);
+      if (!gcry_md_test_algo (GCRY_MD_SHA512))
+        gcry_md_enable (md, GCRY_MD_SHA512);
     }
 
-    while( (n=fread( buf, 1, DIM(buf), fp )) )
-       gcry_md_write (md, buf, n);
-    if( ferror(fp) )
-       log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
-    else {
-       gcry_md_final (md);
-        if ( opt.with_colons ) {
-            if ( algo ) 
-                print_hashline( md, algo, fname );
-            else {
+  while ((n=es_fread (buf, 1, DIM(buf), fp)))
+    gcry_md_write (md, buf, n);
+
+  if (es_ferror(fp))
+    log_error ("%s: %s\n", fname?fname:"[stdin]", strerror(errno));
+  else
+    {
+      gcry_md_final (md);
+      if (opt.with_colons)
+        {
+          if ( algo )
+            print_hashline (md, algo, fname);
+          else
+            {
+              if (!gcry_md_test_algo (GCRY_MD_MD5))
                 print_hashline( md, GCRY_MD_MD5, fname );
-                print_hashline( md, GCRY_MD_SHA1, fname );
-                if (!gcry_md_test_algo (GCRY_MD_RMD160))
-                    print_hashline( md, GCRY_MD_RMD160, fname );
-                if (!gcry_md_test_algo (GCRY_MD_SHA224))
-                    print_hashline (md, GCRY_MD_SHA224, fname);
-                if (!gcry_md_test_algo (GCRY_MD_SHA256))
-                    print_hashline( md, GCRY_MD_SHA256, fname );
-                if (!gcry_md_test_algo (GCRY_MD_SHA384))
-                    print_hashline ( md, GCRY_MD_SHA384, fname );
-                if (!gcry_md_test_algo (GCRY_MD_SHA512))
-                    print_hashline ( md, GCRY_MD_SHA512, fname );
+              print_hashline( md, GCRY_MD_SHA1, fname );
+              if (!gcry_md_test_algo (GCRY_MD_RMD160))
+                print_hashline( md, GCRY_MD_RMD160, fname );
+              if (!gcry_md_test_algo (GCRY_MD_SHA224))
+                print_hashline (md, GCRY_MD_SHA224, fname);
+              if (!gcry_md_test_algo (GCRY_MD_SHA256))
+                print_hashline( md, GCRY_MD_SHA256, fname );
+              if (!gcry_md_test_algo (GCRY_MD_SHA384))
+                print_hashline ( md, GCRY_MD_SHA384, fname );
+              if (!gcry_md_test_algo (GCRY_MD_SHA512))
+                print_hashline ( md, GCRY_MD_SHA512, fname );
             }
         }
-        else {
-            if( algo )
-              print_hex(md,-algo,fname);
-            else {
-                print_hex( md, GCRY_MD_MD5, fname );
-                print_hex( md, GCRY_MD_SHA1, fname );
-                if (!gcry_md_test_algo (GCRY_MD_RMD160))
-                    print_hex( md, GCRY_MD_RMD160, fname );
-                if (!gcry_md_test_algo (GCRY_MD_SHA224))
-                    print_hex (md, GCRY_MD_SHA224, fname);
-                if (!gcry_md_test_algo (GCRY_MD_SHA256))
-                    print_hex( md, GCRY_MD_SHA256, fname );
-                if (!gcry_md_test_algo (GCRY_MD_SHA384))
-                    print_hex( md, GCRY_MD_SHA384, fname );
-                if (!gcry_md_test_algo (GCRY_MD_SHA512))
-                    print_hex( md, GCRY_MD_SHA512, fname );
+      else
+        {
+          if (algo)
+            print_hex (md, -algo, fname);
+          else
+            {
+              if (!gcry_md_test_algo (GCRY_MD_MD5))
+                print_hex (md, GCRY_MD_MD5, fname);
+              print_hex (md, GCRY_MD_SHA1, fname );
+              if (!gcry_md_test_algo (GCRY_MD_RMD160))
+                print_hex (md, GCRY_MD_RMD160, fname );
+              if (!gcry_md_test_algo (GCRY_MD_SHA224))
+                print_hex (md, GCRY_MD_SHA224, fname);
+              if (!gcry_md_test_algo (GCRY_MD_SHA256))
+                print_hex (md, GCRY_MD_SHA256, fname );
+              if (!gcry_md_test_algo (GCRY_MD_SHA384))
+                print_hex (md, GCRY_MD_SHA384, fname );
+              if (!gcry_md_test_algo (GCRY_MD_SHA512))
+                print_hex (md, GCRY_MD_SHA512, fname );
             }
         }
     }
-    gcry_md_close(md);
+  gcry_md_close (md);
 
-    if( fp != stdin )
-       fclose(fp);
+  if (fp != es_stdin)
+    es_fclose (fp);
 }
 
 
@@ -4368,7 +5239,7 @@ add_policy_url( const char *string, int which )
     sl=add_to_strlist( &opt.sig_policy_url, string );
 
   if(critical)
-    sl->flags |= 1;    
+    sl->flags |= 1;
 }
 
 static void
@@ -4401,5 +5272,36 @@ add_keyserver_url( const char *string, int which )
     sl=add_to_strlist( &opt.sig_keyserver_url, string );
 
   if(critical)
-    sl->flags |= 1;    
+    sl->flags |= 1;
+}
+
+
+static void
+read_sessionkey_from_fd (int fd)
+{
+  int i, len;
+  char *line;
+
+  for (line = NULL, i = len = 100; ; i++ )
+    {
+      if (i >= len-1 )
+        {
+          char *tmp = line;
+          len += 100;
+          line = xmalloc_secure (len);
+          if (tmp)
+            {
+              memcpy (line, tmp, i);
+              xfree (tmp);
+            }
+          else
+            i=0;
+       }
+      if (read (fd, line + i, 1) != 1 || line[i] == '\n')
+        break;
+    }
+  line[i] = 0;
+  log_debug ("seskey: %s\n", line);
+  gpgrt_annotate_leaked_object (line);
+  opt.override_session_key = line;
 }