gpg: Remove MDC options
[gnupg.git] / g10 / gpg.c
index b33b61b..1a419f7 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1,7 +1,7 @@
 /* gpg.c - The GnuPG utility (main for gpg)
  * Copyright (C) 1998-2011 Free Software Foundation, Inc.
- * Copyright (C) 1997-2016 Werner Koch
- * Copyright (C) 2015-2016 g10 Code GmbH
+ * Copyright (C) 1997-2017 Werner Koch
+ * Copyright (C) 2015-2017 g10 Code GmbH
  *
  * This file is part of GnuPG.
  *
@@ -16,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 "gpg.h"
 #include <assuan.h>
 #include "../common/iobuf.h"
-#include "util.h"
+#include "../common/util.h"
 #include "packet.h"
-#include "membuf.h"
+#include "../common/membuf.h"
 #include "main.h"
 #include "options.h"
 #include "keydb.h"
 #include "trustdb.h"
 #include "filter.h"
-#include "ttyio.h"
-#include "i18n.h"
-#include "sysutils.h"
-#include "status.h"
+#include "../common/ttyio.h"
+#include "../common/i18n.h"
+#include "../common/sysutils.h"
+#include "../common/status.h"
 #include "keyserver-internal.h"
 #include "exec.h"
-#include "gc-opt-flags.h"
-#include "asshelp.h"
+#include "../common/gc-opt-flags.h"
+#include "../common/asshelp.h"
 #include "call-dirmngr.h"
 #include "tofu.h"
 #include "../common/init.h"
+#include "../common/mbox-util.h"
 #include "../common/shareddefs.h"
+#include "../common/compliance.h"
 
 #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
 #define MY_O_BINARY  O_BINARY
@@ -72,6 +74,9 @@
 #define MY_O_BINARY  0
 #endif
 
+#ifdef __MINGW32__
+int _dowildcard = -1;
+#endif
 
 enum cmd_and_opt_values
   {
@@ -99,6 +104,8 @@ enum cmd_and_opt_values
     aListSecretKeys = 'K',
     oBatch       = 500,
     oMaxOutput,
+    oInputSizeHint,
+    oChunkSize,
     oSigNotation,
     oCertNotation,
     oShowNotation,
@@ -121,6 +128,8 @@ enum cmd_and_opt_values
     aQuickAddUid,
     aQuickAddKey,
     aQuickRevUid,
+    aQuickSetExpire,
+    aQuickSetPrimaryUid,
     aListConfig,
     aListGcryptConfig,
     aGPGConfList,
@@ -189,8 +198,15 @@ enum cmd_and_opt_values
     oWithSubkeyFingerprint,
     oWithICAOSpelling,
     oWithKeygrip,
+    oWithKeyScreening,
     oWithSecret,
     oWithWKDHash,
+    oWithColons,
+    oWithKeyData,
+    oWithKeyOrigin,
+    oWithTofuInfo,
+    oWithSigList,
+    oWithSigCheck,
     oAnswerYes,
     oAnswerNo,
     oKeyring,
@@ -207,6 +223,7 @@ enum cmd_and_opt_values
     oDebugLevel,
     oDebugAll,
     oDebugIOLBF,
+    oDebugSetIobufSize,
     oStatusFD,
     oStatusFile,
     oAttributeFD,
@@ -217,6 +234,7 @@ enum cmd_and_opt_values
     oMarginalsNeeded,
     oMaxCertDepth,
     oLoadExtension,
+    oCompliance,
     oGnuPG,
     oRFC2440,
     oRFC4880,
@@ -225,9 +243,11 @@ enum cmd_and_opt_values
     oPGP6,
     oPGP7,
     oPGP8,
+    oDE_VS,
     oRFC2440Text,
     oNoRFC2440Text,
     oCipherAlgo,
+    oAEADAlgo,
     oDigestAlgo,
     oCertDigestAlgo,
     oCompressAlgo,
@@ -248,7 +268,6 @@ enum cmd_and_opt_values
     oRequireSecmem,
     oNoRequireSecmem,
     oNoPermissionWarn,
-    oNoMDCWarn,
     oNoArmor,
     oNoDefKeyring,
     oNoKeyring,
@@ -257,10 +276,6 @@ enum cmd_and_opt_values
     oNoOptions,
     oNoBatch,
     oHomedir,
-    oWithColons,
-    oWithKeyData,
-    oWithSigList,
-    oWithSigCheck,
     oSkipVerify,
     oSkipHiddenRecipients,
     oNoSkipHiddenRecipients,
@@ -286,10 +301,7 @@ enum cmd_and_opt_values
     oShowPhotos,
     oNoShowPhotos,
     oPhotoViewer,
-    oForceMDC,
-    oNoForceMDC,
-    oDisableMDC,
-    oNoDisableMDC,
+    oForceAEAD,
     oS2KMode,
     oS2KDigest,
     oS2KCipher,
@@ -338,6 +350,7 @@ enum cmd_and_opt_values
     oIgnoreMDCError,
     oShowSessionKey,
     oOverrideSessionKey,
+    oOverrideSessionKeyFD,
     oNoRandomSeedFile,
     oAutoKeyRetrieve,
     oNoAutoKeyRetrieve,
@@ -357,10 +370,12 @@ enum cmd_and_opt_values
     oDefaultPreferenceList,
     oDefaultKeyserverURL,
     oPersonalCipherPreferences,
+    oPersonalAEADPreferences,
     oPersonalDigestPreferences,
     oPersonalCompressPreferences,
     oAgentProgram,
     oDirmngrProgram,
+    oDisableDirmngr,
     oDisplay,
     oTTYname,
     oTTYtype,
@@ -401,10 +416,15 @@ enum cmd_and_opt_values
     oPrintDANERecords,
     oTOFUDefaultPolicy,
     oTOFUDBFormat,
+    oDefaultNewKeyAlgo,
     oWeakDigest,
     oUnwrap,
     oOnlySignTextIDs,
     oDisableSignerUID,
+    oSender,
+    oKeyOrigin,
+    oRequestOrigin,
+    oNoSymkeyCache,
 
     oNoop
   };
@@ -415,7 +435,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", "@"),
@@ -427,22 +448,36 @@ 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",
+  ARGPARSE_c (aKeygen,     "generate-key",
               N_("generate a new key pair")),
-  ARGPARSE_c (aQuickKeygen, "quick-gen-key" ,
+  ARGPARSE_c (aKeygen,     "gen-key", "@"),
+  ARGPARSE_c (aQuickKeygen, "quick-generate-key" ,
               N_("quickly generate a new key pair")),
-  ARGPARSE_c (aQuickAddUid,  "quick-adduid",
+  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-revuid",
+  ARGPARSE_c (aQuickRevUid,  "quick-revoke-uid",
               N_("quickly revoke a user-id")),
-  ARGPARSE_c (aFullKeygen,  "full-gen-key" ,
+  ARGPARSE_c (aQuickRevUid,  "quick-revuid", "@"),
+  ARGPARSE_c (aQuickSetExpire,  "quick-set-expire",
+              N_("quickly set a new expiration date")),
+  ARGPARSE_c (aQuickSetPrimaryUid,  "quick-set-primary-uid", "@"),
+  ARGPARSE_c (aFullKeygen,  "full-generate-key" ,
               N_("full featured key pair generation")),
-  ARGPARSE_c (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
+  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",
@@ -455,11 +490,14 @@ static ARGPARSE_OPTS opts[] = {
   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 keyserver") ),
-  ARGPARSE_c (aRecvKeys, "recv-keys"     , N_("import keys from 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",
@@ -473,7 +511,8 @@ static ARGPARSE_OPTS opts[] = {
   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", "@"),
@@ -524,6 +563,7 @@ static ARGPARSE_OPTS opts[] = {
   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", "@"),
 
@@ -554,15 +594,14 @@ 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_i (oChunkSize, "chunk-size", "@"),
 
   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
   ARGPARSE_s_n (oQuiet,          "quiet",   "@"),
   ARGPARSE_s_n (oNoTTY,   "no-tty",  "@"),
 
-  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 (oForceAEAD, "force-aead", "@"),
 
   ARGPARSE_s_n (oDisableSignerUID, "disable-signer-uid", "@"),
 
@@ -580,6 +619,7 @@ static ARGPARSE_OPTS opts[] = {
 
   ARGPARSE_s_s (oKeyServer, "keyserver", "@"),
   ARGPARSE_s_s (oKeyServerOptions, "keyserver-options", "@"),
+  ARGPARSE_s_s (oKeyOrigin, "key-origin", "@"),
   ARGPARSE_s_s (oImportOptions, "import-options", "@"),
   ARGPARSE_s_s (oImportFilter,  "import-filter", "@"),
   ARGPARSE_s_s (oExportOptions, "export-options", "@"),
@@ -595,6 +635,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oDebugLevel, "debug-level", "@"),
   ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
   ARGPARSE_s_n (oDebugIOLBF, "debug-iolbf", "@"),
+  ARGPARSE_s_u (oDebugSetIobufSize, "debug-set-iobuf-size", "@"),
   ARGPARSE_s_i (oStatusFD, "status-fd", "@"),
   ARGPARSE_s_s (oStatusFile, "status-file", "@"),
   ARGPARSE_s_i (oAttributeFD, "attribute-fd", "@"),
@@ -607,6 +648,7 @@ 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", "@"),
@@ -627,6 +669,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oS2KCipher, "s2k-cipher-algo", "@"),
   ARGPARSE_s_i (oS2KCount, "s2k-count", "@"),
   ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"),
+  ARGPARSE_s_s (oAEADAlgo,   "aead-algo", "@"),
   ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"),
   ARGPARSE_s_s (oCertDigestAlgo, "cert-digest-algo", "@"),
   ARGPARSE_s_s (oCompressAlgo,"compress-algo", "@"),
@@ -646,7 +689,7 @@ 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")),
@@ -668,6 +711,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oPassphraseFile,  "passphrase-file", "@"),
   ARGPARSE_s_i (oPassphraseRepeat,"passphrase-repeat", "@"),
   ARGPARSE_s_s (oPinentryMode,    "pinentry-mode", "@"),
+  ARGPARSE_s_s (oRequestOrigin,   "request-origin", "@"),
   ARGPARSE_s_i (oCommandFD, "command-fd", "@"),
   ARGPARSE_s_s (oCommandFile, "command-file", "@"),
   ARGPARSE_s_n (oQuickRandom, "debug-quick-random", "@"),
@@ -684,7 +728,6 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oRequireSecmem, "require-secmem", "@"),
   ARGPARSE_s_n (oNoRequireSecmem, "no-require-secmem", "@"),
   ARGPARSE_s_n (oNoPermissionWarn, "no-permission-warning", "@"),
-  ARGPARSE_s_n (oNoMDCWarn, "no-mdc-warning", "@"),
   ARGPARSE_s_n (oNoArmor, "no-armor", "@"),
   ARGPARSE_s_n (oNoArmor, "no-armour", "@"),
   ARGPARSE_s_n (oNoDefKeyring, "no-default-keyring", "@"),
@@ -694,12 +737,13 @@ static ARGPARSE_OPTS opts[] = {
   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", "@"),
-  ARGPARSE_s_n (aListKeys, "list-key", "@"),   /* alias */
-  ARGPARSE_s_n (aListSigs, "list-sig", "@"),   /* alias */
-  ARGPARSE_s_n (aCheckKeys, "check-sig", "@"), /* alias */
+  ARGPARSE_c (aListKeys, "list-key", "@"),   /* alias */
+  ARGPARSE_c (aListSigs, "list-sig", "@"),   /* alias */
+  ARGPARSE_c (aCheckKeys, "check-sig", "@"), /* alias */
   ARGPARSE_s_n (oSkipVerify, "skip-verify", "@"),
   ARGPARSE_s_n (oSkipHiddenRecipients, "skip-hidden-recipients", "@"),
   ARGPARSE_s_n (oNoSkipHiddenRecipients, "no-skip-hidden-recipients", "@"),
@@ -709,7 +753,6 @@ static ARGPARSE_OPTS opts[] = {
 #endif
   ARGPARSE_s_s (oTrustModel, "trust-model", "@"),
   ARGPARSE_s_s (oTOFUDefaultPolicy, "tofu-default-policy", "@"),
-  ARGPARSE_s_s (oTOFUDBFormat, "tofu-db-format", "@"),
   ARGPARSE_s_s (oSetFilename, "set-filename", "@"),
   ARGPARSE_s_n (oForYourEyesOnly, "for-your-eyes-only", "@"),
   ARGPARSE_s_n (oNoForYourEyesOnly, "no-for-your-eyes-only", "@"),
@@ -745,8 +788,10 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprints", "@"),
   ARGPARSE_s_n (oWithICAOSpelling, "with-icao-spelling", "@"),
   ARGPARSE_s_n (oWithKeygrip,     "with-keygrip", "@"),
+  ARGPARSE_s_n (oWithKeyScreening,"with-key-screening", "@"),
   ARGPARSE_s_n (oWithSecret,      "with-secret", "@"),
   ARGPARSE_s_n (oWithWKDHash,     "with-wkd-hash", "@"),
+  ARGPARSE_s_n (oWithKeyOrigin,   "with-key-origin", "@"),
   ARGPARSE_s_s (oDisableCipherAlgo,  "disable-cipher-algo", "@"),
   ARGPARSE_s_s (oDisablePubkeyAlgo,  "disable-pubkey-algo", "@"),
   ARGPARSE_s_n (oAllowNonSelfsignedUID,      "allow-non-selfsigned-uid", "@"),
@@ -767,6 +812,7 @@ static ARGPARSE_OPTS opts[] = {
   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", "@"),
@@ -780,6 +826,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oDefaultPreferenceList,  "default-preference-list", "@"),
   ARGPARSE_s_s (oDefaultKeyserverURL,  "default-keyserver-url", "@"),
   ARGPARSE_s_s (oPersonalCipherPreferences, "personal-cipher-preferences","@"),
+  ARGPARSE_s_s (oPersonalAEADPreferences, "personal-aead-preferences","@"),
   ARGPARSE_s_s (oPersonalDigestPreferences, "personal-digest-preferences","@"),
   ARGPARSE_s_s (oPersonalCompressPreferences,
                                          "personal-compress-preferences", "@"),
@@ -791,11 +838,13 @@ static ARGPARSE_OPTS opts[] = {
   /* Aliases.  I constantly mistype these, and assume other people do
      as well. */
   ARGPARSE_s_s (oPersonalCipherPreferences, "personal-cipher-prefs", "@"),
+  ARGPARSE_s_s (oPersonalAEADPreferences,   "personal-aead-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_n (oDisableDirmngr, "disable-dirmngr", "@"),
   ARGPARSE_s_s (oDisplay,    "display",    "@"),
   ARGPARSE_s_s (oTTYname,    "ttyname",    "@"),
   ARGPARSE_s_s (oTTYtype,    "ttytype",    "@"),
@@ -825,6 +874,8 @@ static ARGPARSE_OPTS opts[] = {
   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
      already as they seem to have borrowed commands from us.  Now I'm
@@ -841,6 +892,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_s (oAutoKeyLocate, "auto-key-locate", "@"),
   ARGPARSE_s_n (oNoAutoKeyLocate, "no-auto-key-locate", "@"),
   ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"),
+  ARGPARSE_s_n (oNoSymkeyCache, "no-symkey-cache", "@"),
 
   /* Dummy options with warnings.  */
   ARGPARSE_s_n (oUseAgent,      "use-agent", "@"),
@@ -851,6 +903,7 @@ static ARGPARSE_OPTS opts[] = {
   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", "@"),
@@ -861,6 +914,12 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_s_n (oNoop, "no-force-v3-sigs", "@"),
   ARGPARSE_s_n (oNoop, "force-v4-certs", "@"),
   ARGPARSE_s_n (oNoop, "no-force-v4-certs", "@"),
+  ARGPARSE_s_n (oNoop, "no-mdc-warning", "@"),
+  ARGPARSE_s_n (oNoop, "force-mdc", "@"),
+  ARGPARSE_s_n (oNoop, "no-force-mdc", "@"),
+  ARGPARSE_s_n (oNoop, "disable-mdc", "@"),
+  ARGPARSE_s_n (oNoop, "no-disable-mdc", "@"),
+
 
   ARGPARSE_end ()
 };
@@ -879,7 +938,6 @@ static struct debug_flags_s debug_flags [] =
     { 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"  },
@@ -899,6 +957,8 @@ int g10_errors_seen = 0;
 
 static int utf8_strings = 0;
 static int maybe_setuid = 1;
+static unsigned int opt_set_iobuf_size;
+static unsigned int opt_set_iobuf_size_used;
 
 static char *build_list( const char *text, char letter,
                         const char *(*mapf)(int), int (*chkf)(int) );
@@ -909,6 +969,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 *
@@ -960,6 +1021,18 @@ build_list_cipher_algo_name (int algo)
 }
 
 static int
+build_list_aead_test_algo (int algo)
+{
+  return openpgp_aead_test_algo (algo);
+}
+
+static const char *
+build_list_aead_algo_name (int algo)
+{
+  return openpgp_aead_algo_name (algo);
+}
+
+static int
 build_list_md_test_algo (int algo)
 {
   /* By default we do not accept MD5 based signatures.  To avoid
@@ -980,7 +1053,7 @@ build_list_md_algo_name (int algo)
 static const char *
 my_strusage( int level )
 {
-  static char *digests, *pubkeys, *ciphers, *zips, *ver_gcry;
+  static char *digests, *pubkeys, *ciphers, *zips, *aeads, *ver_gcry;
   const char *p;
 
     switch( level ) {
@@ -1040,13 +1113,20 @@ my_strusage( int level )
        p = ciphers;
        break;
       case 36:
+       if (!aeads)
+          aeads = build_list ("AEAD: ", 'A',
+                              build_list_aead_algo_name,
+                              build_list_aead_test_algo);
+       p = aeads;
+       break;
+      case 37:
        if( !digests )
            digests = build_list(_("Hash: "), 'H',
                                  build_list_md_algo_name,
                                  build_list_md_test_algo );
        p = digests;
        break;
-      case 37:
+      case 38:
        if( !zips )
            zips = build_list(_("Compression: "),'Z',
                               compress_algo_to_string,
@@ -1067,6 +1147,7 @@ build_list (const char *text, char letter,
   membuf_t mb;
   int indent;
   int i, j, len;
+  int limit;
   const char *s;
   char *string;
 
@@ -1077,7 +1158,8 @@ build_list (const char *text, char letter,
   len = 0;
   init_membuf (&mb, 512);
 
-  for (i=0; i <= 110; i++ )
+  limit = (letter == 'A')? 4 : 110;
+  for (i=0; i <= limit; i++ )
     {
       if (!chkf (i) && (s = mapf (i)))
         {
@@ -1118,6 +1200,7 @@ static void
 wrong_args( const char *text)
 {
   es_fprintf (es_stderr, _("usage: %s [options] %s\n"), GPG_NAME, text);
+  log_inc_errorcount ();
   g10_exit(2);
 }
 
@@ -1183,20 +1266,24 @@ set_debug (const char *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_CRYPTO_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)
     parse_debug_flag (NULL, &opt.debug, debug_flags);
+
+  if (opt_set_iobuf_size || opt_set_iobuf_size_used)
+    log_debug ("iobuf buffer size is %uk\n",
+               iobuf_set_buffer_size (opt_set_iobuf_size));
 }
 
 
@@ -1738,6 +1825,15 @@ list_config(char *items)
          any=1;
        }
 
+      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"))
        {
           /* We ignore this for GnuPG 1.4 backward compatibility.  */
@@ -1797,14 +1893,22 @@ gpgconf_list (const char *configfile)
   es_printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE);
   es_printf ("try-secret-key:%lu:\n", GC_OPT_FLAG_NONE);
   es_printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("auto-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE);
   es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
   es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
   es_printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("compliance:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, "gnupg");
+  es_printf ("default-new-key-algo:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("trust-model:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("disable-dirmngr:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("max-cert-depth:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("completes-needed:%lu:\n", GC_OPT_FLAG_NONE);
+  es_printf ("marginals-needed:%lu:\n", GC_OPT_FLAG_NONE);
 
   /* 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);
 }
@@ -2003,7 +2107,7 @@ parse_tofu_policy (const char *policystr)
 
   if (!ascii_strcasecmp (policystr, "help"))
     {
-      log_info (_("available TOFU policies:\n"));
+      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);
@@ -2020,39 +2124,100 @@ parse_tofu_policy (const char *policystr)
   g10_exit (1);
 }
 
-static int
-parse_tofu_db_format (const char *db_format)
+
+static struct gnupg_compliance_option compliance_options[] =
+  {
+    { "gnupg",      oGnuPG },
+    { "openpgp",    oOpenPGP },
+    { "rfc4880bis", oRFC4880bis },
+    { "rfc4880",    oRFC4880 },
+    { "rfc2440",    oRFC2440 },
+    { "pgp6",       oPGP6 },
+    { "pgp7",       oPGP7 },
+    { "pgp8",       oPGP8 },
+    { "de-vs",      oDE_VS }
+  };
+
+
+/* Helper to set compliance related options.  This is a separate
+ * function so that it can also be used by the --compliance option
+ * parser.  */
+static void
+set_compliance_option (enum cmd_and_opt_values option)
 {
-#ifdef USE_TOFU
-  if (ascii_strcasecmp (db_format, "auto") == 0)
-    return TOFU_DB_AUTO;
-  else if (ascii_strcasecmp (db_format, "split") == 0)
-    return TOFU_DB_SPLIT;
-  else if (ascii_strcasecmp (db_format, "flat") == 0)
-    return TOFU_DB_FLAT;
-  else if (ascii_strcasecmp (db_format, "help") == 0)
-    {
-      log_info ("available TOFU DB fomats: auto, split, flat\n");
-      g10_exit (1);
-    }
-  else
-#endif /*USE_TOFU*/
+  switch (option)
     {
-      log_error (_("unknown TOFU DB format '%s'\n"), db_format);
-      if (!opt.quiet)
-        log_info (_("(use \"help\" to list choices)\n"));
-      g10_exit (1);
+    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_aead_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_aead_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;
+      opt.def_aead_algo = 0;
+      /* Fixme: Change other options.  */
+      break;
+
+    default:
+      BUG ();
     }
 }
 
 
+
+
+
+
 /* 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
 gpg_init_default_ctrl (ctrl_t ctrl)
 {
-  (void)ctrl;
+  ctrl->magic = SERVER_CONTROL_MAGIC;
 }
 
 
@@ -2065,6 +2230,8 @@ gpg_deinit_default_ctrl (ctrl_t ctrl)
   tofu_closedbs (ctrl);
 #endif
   gpg_dirmngr_deinit_session_data (ctrl);
+
+  keydb_release (ctrl->cached_getkey_kdb);
 }
 
 
@@ -2160,19 +2327,23 @@ main (int argc, char **argv)
     const char *trustdb_name = NULL;
 #endif /*!NO_TRUST_MODELS*/
     char *def_cipher_string = NULL;
+    char *def_aead_string = NULL;
     char *def_digest_string = NULL;
     char *compress_algo_string = NULL;
     char *cert_digest_string = NULL;
     char *s2k_cipher_string = NULL;
     char *s2k_digest_string = NULL;
     char *pers_cipher_list = NULL;
+    char *pers_aead_list = NULL;
     char *pers_digest_list = NULL;
     char *pers_compress_list = NULL;
     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 default_akl = 1;
     int require_secmem = 0;
     int got_secmem = 0;
     struct assuan_malloc_hooks malloc_hooks;
@@ -2195,20 +2366,12 @@ main (int argc, char **argv)
     gnupg_rl_initialize ();
     set_strusage (my_strusage);
     gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
-    log_set_prefix (GPG_NAME, 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 ();
 
@@ -2221,6 +2384,9 @@ main (int argc, char **argv)
 
     dotlock_create (NULL, 0); /* Register lock file cleanup. */
 
+    /* Tell the compliance module who we are.  */
+    gnupg_initialize_compliance (GNUPG_MODULE_NAME_GPG);
+
     opt.autostart = 1;
     opt.session_env = session_env_new ();
     if (!opt.session_env)
@@ -2232,6 +2398,7 @@ main (int argc, char **argv)
     opt.bz2_compress_level = -1; /* defaults to standard compress level */
     /* note: if you change these lines, look at oOpenPGP */
     opt.def_cipher_algo = 0;
+    opt.def_aead_algo = 0;
     opt.def_digest_algo = 0;
     opt.cert_digest_algo = 0;
     opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */
@@ -2243,9 +2410,10 @@ main (int argc, char **argv)
     opt.max_cert_depth = 5;
     opt.escape_from = 1;
     opt.flags.require_cross_cert = 1;
-    opt.import_options = 0;
+    opt.import_options = IMPORT_REPAIR_KEYS;
     opt.export_options = EXPORT_ATTRIBUTES;
-    opt.keyserver_options.import_options = IMPORT_REPAIR_PKS_SUBKEY_BUG;
+    opt.keyserver_options.import_options = (IMPORT_REPAIR_KEYS
+                                           | IMPORT_REPAIR_PKS_SUBKEY_BUG);
     opt.keyserver_options.export_options = EXPORT_ATTRIBUTES;
     opt.keyserver_options.options = KEYSERVER_HONOR_PKA_RECORD;
     opt.verify_options = (LIST_SHOW_UID_VALIDITY
@@ -2260,7 +2428,6 @@ main (int argc, char **argv)
     opt.trust_model = TM_AUTO;
 #endif
     opt.tofu_default_policy = TOFU_POLICY_AUTO;
-    opt.tofu_db_format = TOFU_DB_AUTO;
     opt.mangle_dos_filenames = 0;
     opt.min_cert_level = 2;
     set_screen_dimensions ();
@@ -2271,7 +2438,6 @@ main (int argc, char **argv)
     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;
@@ -2345,7 +2511,11 @@ 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);
+
+    /* Set default options which require that malloc stuff is ready.  */
+    additional_weak_digest ("MD5");
+    parse_auto_key_locate ("local,wkd");
 
     /* Try for a version specific config file first */
     default_configname = get_default_configname ();
@@ -2405,11 +2575,16 @@ 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:
@@ -2455,6 +2630,8 @@ main (int argc, char **argv)
          case aQuickAddUid:
          case aQuickAddKey:
          case aQuickRevUid:
+         case aQuickSetExpire:
+         case aQuickSetPrimaryUid:
          case aExportOwnerTrust:
          case aImportOwnerTrust:
           case aRebuildKeydbCaches:
@@ -2494,7 +2671,17 @@ main (int argc, char **argv)
 
          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 oChunkSize:
+            opt.chunk_size = pargs.r.ret_int;
+            break;
+
          case oQuiet: opt.quiet = 1; break;
          case oNoTTY: tty_no_terminal(1); break;
          case oDryRun: opt.dry_run = 1; break;
@@ -2562,6 +2749,11 @@ main (int argc, char **argv)
 
           case oDebugIOLBF: break; /* Already set in pre-parse step.  */
 
+          case oDebugSetIobufSize:
+            opt_set_iobuf_size = pargs.r.ret_ulong;
+            opt_set_iobuf_size_used = 1;
+            break;
+
          case oStatusFD:
             set_status_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) );
             break;
@@ -2600,6 +2792,10 @@ main (int argc, char **argv)
             opt.with_keygrip = 1;
             break;
 
+         case oWithKeyScreening:
+            opt.with_key_screening = 1;
+            break;
+
          case oWithSecret:
             opt.with_secret = 1;
             break;
@@ -2608,6 +2804,10 @@ main (int argc, char **argv)
             opt.with_wkd_hash = 1;
             break;
 
+         case oWithKeyOrigin:
+            opt.with_key_origin = 1;
+            break;
+
          case oSecretKeyring:
             /* Ignore this old option.  */
             break;
@@ -2674,6 +2874,8 @@ 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;
 
@@ -2700,7 +2902,7 @@ main (int argc, char **argv)
            opt.tofu_default_policy = parse_tofu_policy (pargs.r.ret_str);
            break;
          case oTOFUDBFormat:
-           opt.tofu_db_format = parse_tofu_db_format (pargs.r.ret_str);
+           obsolete_option (configname, configlineno, "tofu-db-format");
            break;
 
          case oForceOwnertrust:
@@ -2717,52 +2919,32 @@ main (int argc, char **argv)
             /* Dummy so that gpg 1.4 conf files can work. Should
                eventually be removed.  */
            break;
+
+          case oCompliance:
+           {
+             int compliance = gnupg_parse_compliance_option
+                (pargs.r.ret_str,
+                 compliance_options, DIM (compliance_options),
+                 opt.quiet);
+             if (compliance < 0)
+               g10_exit (1);
+             set_compliance_option (compliance);
+           }
+            break;
+          case oOpenPGP:
+          case oRFC2440:
+          case oRFC4880:
           case oRFC4880bis:
-            opt.flags.rfc4880bis = 1;
-            /* fall thru.  */
-         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 oRFC2440Text: opt.rfc2440_text=1; break;
-         case oNoRFC2440Text: opt.rfc2440_text=0; break;
+          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;
@@ -2832,10 +3014,7 @@ main (int argc, char **argv)
            break;
          case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; 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 oForceAEAD: opt.force_aead = 1; break;
 
           case oDisableSignerUID: opt.flags.disable_signer_uid = 1; break;
 
@@ -2934,6 +3113,19 @@ main (int argc, char **argv)
             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 */
            opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int;
@@ -2960,8 +3152,16 @@ main (int argc, char **argv)
               log_error (_("invalid pinentry mode '%s'\n"), pargs.r.ret_str);
            break;
 
+          case oRequestOrigin:
+           opt.request_origin = parse_request_origin (pargs.r.ret_str);
+           if (opt.request_origin == -1)
+              log_error (_("invalid request origin '%s'\n"), pargs.r.ret_str);
+           break;
+
          case oCommandFD:
             opt.command_fd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
+           if (! gnupg_fd_valid (opt.command_fd))
+             log_error ("command-fd is invalid: %s\n", strerror (errno));
             break;
          case oCommandFile:
             opt.command_fd = open_info_file (pargs.r.ret_str, 0, 1);
@@ -2969,6 +3169,9 @@ main (int argc, char **argv)
          case oCipherAlgo:
             def_cipher_string = xstrdup(pargs.r.ret_str);
             break;
+         case oAEADAlgo:
+            def_aead_string = xstrdup (pargs.r.ret_str);
+            break;
          case oDigestAlgo:
             def_digest_string = xstrdup(pargs.r.ret_str);
             break;
@@ -3007,7 +3210,6 @@ main (int argc, char **argv)
          case oRequireSecmem: require_secmem=1; break;
          case oNoRequireSecmem: require_secmem=0; break;
          case oNoPermissionWarn: opt.no_perm_warn=1; break;
-         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"),
@@ -3198,17 +3400,21 @@ main (int argc, char **argv)
          case oIgnoreCrcError: opt.ignore_crc_error = 1; break;
          case oIgnoreMDCError: opt.ignore_mdc_error = 1; break;
          case oNoRandomSeedFile: use_random_seed = 0; break;
+
          case oAutoKeyRetrieve:
+            opt.keyserver_options.options |= KEYSERVER_AUTO_KEY_RETRIEVE;
+            break;
          case oNoAutoKeyRetrieve:
-               if(pargs.r_opt==oAutoKeyRetrieve)
-                 opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
-               else
-                 opt.keyserver_options.options&=~KEYSERVER_AUTO_KEY_RETRIEVE;
-               break;
+            opt.keyserver_options.options &= ~KEYSERVER_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");
@@ -3217,9 +3423,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;
@@ -3242,6 +3450,9 @@ main (int argc, char **argv)
           case oPersonalCipherPreferences:
            pers_cipher_list=pargs.r.ret_str;
            break;
+          case oPersonalAEADPreferences:
+           pers_aead_list = pargs.r.ret_str;
+           break;
           case oPersonalDigestPreferences:
            pers_digest_list=pargs.r.ret_str;
            break;
@@ -3250,6 +3461,7 @@ main (int argc, char **argv)
            break;
           case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
           case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break;
+         case oDisableDirmngr: opt.disable_dirmngr = 1;  break;
           case oWeakDigest:
            additional_weak_digest(pargs.r.ret_str);
            break;
@@ -3324,6 +3536,13 @@ main (int argc, char **argv)
          case oNoRequireCrossCert: opt.flags.require_cross_cert=0; break;
 
          case oAutoKeyLocate:
+            if (default_akl)
+              {
+                /* This is the first time --aito-key-locate is seen.
+                 * We need to reset the default akl.  */
+                default_akl = 0;
+                release_akl();
+              }
            if(!parse_auto_key_locate(pargs.r.ret_str))
              {
                if(configname)
@@ -3337,6 +3556,12 @@ main (int argc, char **argv)
            release_akl();
            break;
 
+         case oKeyOrigin:
+           if(!parse_key_origin (pargs.r.ret_str))
+              log_error (_("invalid argument for option \"%.50s\"\n"),
+                         "--key-origin");
+           break;
+
          case oEnableLargeRSA:
 #if SECMEM_BUFFER_SIZE >= 65536
             opt.flags.large_rsa=1;
@@ -3371,19 +3596,43 @@ main (int argc, char **argv)
 
           case oFakedSystemTime:
             {
-              time_t faked_time = isotime2epoch (pargs.r.ret_str);
+              size_t len = strlen (pargs.r.ret_str);
+              int freeze = 0;
+              time_t faked_time;
+
+              if (len > 0 && pargs.r.ret_str[len-1] == '!')
+                {
+                  freeze = 1;
+                  pargs.r.ret_str[len-1] = '\0';
+                }
+
+              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);
+              gnupg_set_time (faked_time, freeze);
             }
             break;
 
           case oNoAutostart: opt.autostart = 0; break;
+          case oNoSymkeyCache: opt.no_symkey_cache = 1; break;
+
+         case oDefaultNewKeyAlgo:
+            opt.def_new_key_algo = pargs.r.ret_str;
+            break;
 
          case oNoop: break;
 
          default:
-            pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
+            if (configfp)
+              pargs.err = ARGPARSE_PRINT_WARNING;
+            else
+              {
+                pargs.err = ARGPARSE_PRINT_ERROR;
+                /* The argparse fucntion calls a plain exit and thus
+                 * we need to print a status here.  */
+                write_status_failure ("option-parser",
+                                      gpg_error(GPG_ERR_GENERAL));
+              }
             break;
          }
       }
@@ -3402,7 +3651,10 @@ main (int argc, char **argv)
       }
     xfree(configname); configname = NULL;
     if (log_get_errorcount (0))
-      g10_exit(2);
+      {
+        write_status_failure ("option-parser", gpg_error(GPG_ERR_GENERAL));
+        g10_exit(2);
+      }
 
     /* The command --gpgconf-list is pretty simple and may be called
        directly after the option parsing. */
@@ -3423,7 +3675,10 @@ main (int argc, char **argv)
                  "--print-pks-records",
                  "--export-options export-pka");
     if (log_get_errorcount (0))
-      g10_exit(2);
+      {
+        write_status_failure ("option-checking", gpg_error(GPG_ERR_GENERAL));
+        g10_exit(2);
+      }
 
 
     if( nogreeting )
@@ -3456,7 +3711,7 @@ main (int argc, char **argv)
     if (logfile && opt.batch)
       {
         log_set_file (logfile);
-        log_set_prefix (NULL, 1|2|4);
+        log_set_prefix (NULL, GPGRT_LOG_WITH_PREFIX | GPGRT_LOG_WITH_TIME | GPGRT_LOG_WITH_PID);
       }
 
     if (opt.verbose > 2)
@@ -3524,6 +3779,7 @@ main (int argc, char **argv)
       {
        log_info(_("will not run with insecure memory due to %s\n"),
                 "--require-secmem");
+        write_status_failure ("option-checking", gpg_error(GPG_ERR_GENERAL));
        g10_exit(2);
       }
 
@@ -3536,7 +3792,6 @@ main (int argc, char **argv)
       {
         /* That does not anymore work because we have no more support
            for v3 signatures.  */
-       opt.disable_mdc=1;
        opt.escape_from=1;
        opt.ask_sig_expire=0;
       }
@@ -3559,6 +3814,13 @@ main (int argc, char **argv)
        if ( openpgp_cipher_test_algo (opt.def_cipher_algo) )
            log_error(_("selected cipher algorithm is invalid\n"));
     }
+    if (def_aead_string)
+      {
+       opt.def_aead_algo = string_to_aead_algo (def_aead_string);
+       xfree (def_aead_string); def_aead_string = NULL;
+       if (openpgp_aead_test_algo (opt.def_aead_algo))
+          log_error(_("selected AEAD algorithm is invalid\n"));
+      }
     if( def_digest_string ) {
        opt.def_digest_algo = string_to_digest_algo (def_digest_string);
        xfree(def_digest_string); def_digest_string = NULL;
@@ -3618,6 +3880,9 @@ main (int argc, char **argv)
        keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM))
       log_error(_("invalid personal cipher preferences\n"));
 
+    if (pers_aead_list && keygen_set_std_prefs (pers_aead_list, PREFTYPE_AEAD))
+      log_error(_("invalid personal AEAD preferences\n"));
+
     if(pers_digest_list &&
        keygen_set_std_prefs(pers_digest_list,PREFTYPE_HASH))
       log_error(_("invalid personal digest preferences\n"));
@@ -3626,6 +3891,21 @@ main (int argc, char **argv)
        keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
       log_error(_("invalid personal compress preferences\n"));
 
+    /* Check chunk size.  Please fix also the man page if you chnage
+     * the default.  The limits are given by the specs.  */
+    if (!opt.chunk_size)
+      opt.chunk_size = 30; /* Default to 1 GiB chunks.  */
+    else if (opt.chunk_size < 6)
+      {
+        opt.chunk_size = 6;
+        log_info (_("chunk size invalid - using %d\n"), opt.chunk_size);
+      }
+    else if (opt.chunk_size > 62)
+      {
+        opt.chunk_size = 62;
+        log_info (_("chunk size invalid - using %d\n"), opt.chunk_size);
+      }
+
     /* We don't support all possible commands with multifile yet */
     if(multifile)
       {
@@ -3640,7 +3920,7 @@ main (int argc, char **argv)
            cmdname="--sign --encrypt";
            break;
          case aClearsign:
-           cmdname="--clearsign";
+           cmdname="--clear-sign";
            break;
          case aDetachedSign:
            cmdname="--detach-sign";
@@ -3664,7 +3944,11 @@ main (int argc, char **argv)
       }
 
     if( log_get_errorcount(0) )
-       g10_exit(2);
+      {
+        write_status_failure ("option-postprocessing",
+                              gpg_error(GPG_ERR_GENERAL));
+       g10_exit (2);
+      }
 
     if(opt.compress_level==0)
       opt.compress_algo=COMPRESS_ALGO_NONE;
@@ -3672,7 +3956,7 @@ main (int argc, char **argv)
     /* Check our chosen algorithms against the list of legal
        algorithms. */
 
-    if(!GNUPG)
+    if(!GNUPG && !opt.flags.rfc4880bis)
       {
        const char *badalg=NULL;
        preftype_t badtype=PREFTYPE_NONE;
@@ -3683,6 +3967,12 @@ main (int argc, char **argv)
            badalg = openpgp_cipher_algo_name (opt.def_cipher_algo);
            badtype = PREFTYPE_SYM;
          }
+       else if(opt.def_aead_algo
+          && !algo_available(PREFTYPE_AEAD, opt.def_aead_algo, NULL))
+         {
+           badalg = openpgp_aead_algo_name (opt.def_aead_algo);
+           badtype = PREFTYPE_AEAD;
+         }
        else if(opt.def_digest_algo
                && !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL))
          {
@@ -3707,19 +3997,28 @@ main (int argc, char **argv)
            switch(badtype)
              {
              case PREFTYPE_SYM:
-               log_info(_("you may not use cipher algorithm '%s'"
-                          " while in %s mode\n"),
-                        badalg,compliance_option_string());
+               log_info (_("cipher algorithm '%s'"
+                            " may not be used in %s mode\n"),
+                        badalg,
+                          gnupg_compliance_option_string (opt.compliance));
+               break;
+             case PREFTYPE_AEAD:
+               log_info (_("AEAD algorithm '%s'"
+                            " may not be used in %s mode\n"),
+                          badalg,
+                          gnupg_compliance_option_string (opt.compliance));
                break;
              case PREFTYPE_HASH:
-               log_info(_("you may not use digest algorithm '%s'"
-                          " while in %s mode\n"),
-                        badalg,compliance_option_string());
+               log_info (_("digest algorithm '%s'"
+                            " may not be used in %s mode\n"),
+                          badalg,
+                          gnupg_compliance_option_string (opt.compliance));
                break;
              case PREFTYPE_ZIP:
-               log_info(_("you may not use compression algorithm '%s'"
-                          " while in %s mode\n"),
-                        badalg,compliance_option_string());
+               log_info (_("compression algorithm '%s'"
+                            " may not be used in %s mode\n"),
+                          badalg,
+                          gnupg_compliance_option_string (opt.compliance));
                break;
              default:
                BUG();
@@ -3729,6 +4028,45 @@ main (int argc, char **argv)
          }
       }
 
+    /* Check our chosen algorithms against the list of allowed
+     * algorithms in the current compliance mode, and fail hard if it
+     * is not.  This is us being nice to the user informing her early
+     * that the chosen algorithms are not available.  We also check
+     * and enforce this right before the actual operation.  */
+    /* FIXME: We also need to check the AEAD algo. */
+    if (opt.def_cipher_algo
+       && ! gnupg_cipher_is_allowed (opt.compliance,
+                                     cmd == aEncr
+                                     || cmd == aSignEncr
+                                     || cmd == aEncrSym
+                                     || cmd == aSym
+                                     || cmd == aSignSym
+                                     || cmd == aSignEncrSym,
+                                     opt.def_cipher_algo,
+                                     GCRY_CIPHER_MODE_NONE))
+      log_error (_("cipher algorithm '%s' may not be used in %s mode\n"),
+                openpgp_cipher_algo_name (opt.def_cipher_algo),
+                gnupg_compliance_option_string (opt.compliance));
+
+    if (opt.def_digest_algo
+       && ! gnupg_digest_is_allowed (opt.compliance,
+                                     cmd == aSign
+                                     || cmd == aSignEncr
+                                     || cmd == aSignEncrSym
+                                     || cmd == aSignSym
+                                     || cmd == aClearsign,
+                                     opt.def_digest_algo))
+      log_error (_("digest algorithm '%s' may not be used in %s mode\n"),
+                gcry_md_algo_name (opt.def_digest_algo),
+                gnupg_compliance_option_string (opt.compliance));
+
+    /* Fail hard.  */
+    if (log_get_errorcount (0))
+      {
+        write_status_failure ("option-checking", gpg_error(GPG_ERR_GENERAL));
+       g10_exit (2);
+      }
+
     /* Set the random seed file. */
     if( use_random_seed ) {
       char *p = make_filename (gnupg_homedir (), "random_seed", NULL );
@@ -3776,8 +4114,11 @@ main (int argc, char **argv)
       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;
 
@@ -3796,6 +4137,8 @@ main (int argc, char **argv)
       case aGenRandom:
       case aDeArmor:
       case aEnArmor:
+      case aListConfig:
+      case aListGcryptConfig:
        break;
       case aFixTrustDB:
       case aExportOwnerTrust:
@@ -3804,6 +4147,11 @@ main (int argc, char **argv)
       case aListTrustDB:
         rc = setup_trustdb (argc? 1:0, trustdb_name);
         break;
+      case aKeygen:
+      case aFullKeygen:
+      case aQuickKeygen:
+        rc = setup_trustdb (1, trustdb_name);
+        break;
       default:
         /* If we are using TM_ALWAYS, we do not need to create the
            trustdb.  */
@@ -3852,6 +4200,7 @@ main (int argc, char **argv)
       case aQuickAddUid:
       case aQuickAddKey:
       case aQuickRevUid:
+      case aQuickSetPrimaryUid:
       case aFullKeygen:
       case aKeygen:
       case aImport:
@@ -3880,7 +4229,7 @@ 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)) )
           {
             write_status_failure ("store", rc);
@@ -3890,7 +4239,7 @@ main (int argc, char **argv)
        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)) )
           {
             write_status_failure ("symencrypt", rc);
@@ -3905,7 +4254,7 @@ 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)) )
               {
                 write_status_failure ("encrypt", rc);
@@ -3921,13 +4270,14 @@ 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(PGP6 || PGP7)
          log_error(_("you cannot use --symmetric --encrypt"
-                     " while in %s mode\n"),compliance_option_string());
+                     " in %s mode\n"),
+                   gnupg_compliance_option_string (opt.compliance));
        else
          {
            if( (rc = encrypt_crypt (ctrl, -1, fname, remusr, 1, NULL, -1)) )
@@ -3947,7 +4297,7 @@ 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);
@@ -3963,7 +4313,7 @@ main (int argc, char **argv)
 
       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);
@@ -3981,13 +4331,14 @@ main (int argc, char **argv)
 
       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(PGP6 || PGP7)
          log_error(_("you cannot use --symmetric --sign --encrypt"
-                     " while in %s mode\n"),compliance_option_string());
+                     " in %s mode\n"),
+                   gnupg_compliance_option_string (opt.compliance));
        else
          {
            if( argc )
@@ -4010,7 +4361,7 @@ main (int argc, char **argv)
 
       case aSignSym: /* sign and conventionally encrypt the given file */
        if (argc > 1)
-           wrong_args(_("--sign --symmetric [filename]"));
+           wrong_args("--sign --symmetric [filename]");
        rc = sign_symencrypt_file (ctrl, fname, locusr);
         if (rc)
           {
@@ -4022,11 +4373,11 @@ main (int argc, char **argv)
 
       case aClearsign: /* make a clearsig */
        if( argc > 1 )
-           wrong_args(_("--clearsign [filename]"));
+           wrong_args("--clear-sign [filename]");
        if( (rc = clearsign_file (ctrl, fname, locusr, NULL)) )
           {
             write_status_failure ("sign", rc);
-           log_error("%s: clearsign failed: %s\n",
+           log_error("%s: clear-sign failed: %s\n",
                       print_fname_stdin(fname), gpg_strerror (rc) );
           }
        break;
@@ -4052,7 +4403,7 @@ main (int argc, char **argv)
        else
          {
            if( argc > 1 )
-             wrong_args(_("--decrypt [filename]"));
+             wrong_args("--decrypt [filename]");
            if( (rc = decrypt_message (ctrl, fname) ))
               {
                 write_status_failure ("decrypt", rc);
@@ -4079,11 +4430,11 @@ main (int argc, char **argv)
 
       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;
@@ -4104,7 +4455,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;
@@ -4120,7 +4471,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);
@@ -4138,14 +4489,15 @@ main (int argc, char **argv)
            proper order :) */
        for( ; argc; argc-- )
          add_to_strlist2( &sl, argv[argc-1], utf8_strings );
-       delete_keys(sl,cmd==aDeleteSecretKeys,cmd==aDeleteSecretAndPublicKeys);
+       delete_keys (ctrl, sl,
+                     cmd==aDeleteSecretKeys, cmd==aDeleteSecretAndPublicKeys);
        free_strlist(sl);
        break;
 
       case aCheckKeys:
-       opt.check_sigs = 1;
+       opt.check_sigs = 1; /* fall through */
       case aListSigs:
-       opt.list_sigs = 1;
+       opt.list_sigs = 1; /* fall through */
       case aListKeys:
        sl = NULL;
        for( ; argc; argc--, argv++ )
@@ -4173,7 +4525,7 @@ main (int argc, char **argv)
           const char *x_algo, *x_usage, *x_expire;
 
           if (argc < 1 || argc > 4)
-            wrong_args("--quick-gen-key USER-ID [ALGO [USAGE [EXPIRE]]]");
+            wrong_args("--quick-generate-key USER-ID [ALGO [USAGE [EXPIRE]]]");
           username = make_username (fname);
           argv++, argc--;
           x_algo = "";
@@ -4199,20 +4551,20 @@ main (int argc, char **argv)
       case aKeygen: /* generate a key */
        if( opt.batch ) {
            if( argc > 1 )
-               wrong_args("--gen-key [parameterfile]");
+               wrong_args("--generate-key [parameterfile]");
            generate_keypair (ctrl, 0, argc? *argv : NULL, NULL, 0);
        }
        else {
             if (opt.command_fd != -1 && argc)
               {
                 if( argc > 1 )
-                  wrong_args("--gen-key [parameterfile]");
+                  wrong_args("--generate-key [parameterfile]");
 
                 opt.batch = 1;
                 generate_keypair (ctrl, 0, argc? *argv : NULL, NULL, 0);
               }
             else if (argc)
-              wrong_args ("--gen-key");
+              wrong_args ("--generate-key");
             else
               generate_keypair (ctrl, 0, NULL, NULL, 0);
        }
@@ -4222,13 +4574,13 @@ main (int argc, char **argv)
        if (opt.batch)
           {
            if (argc > 1)
-              wrong_args ("--full-gen-key [parameterfile]");
+              wrong_args ("--full-generate-key [parameterfile]");
            generate_keypair (ctrl, 1, argc? *argv : NULL, NULL, 0);
           }
        else
           {
            if (argc)
-              wrong_args("--full-gen-key");
+              wrong_args("--full-generate-key");
            generate_keypair (ctrl, 1, NULL, NULL, 0);
        }
        break;
@@ -4238,7 +4590,7 @@ main (int argc, char **argv)
           const char *uid, *newuid;
 
           if (argc != 2)
-            wrong_args ("--quick-adduid USER-ID NEW-USER-ID");
+            wrong_args ("--quick-add-uid USER-ID NEW-USER-ID");
           uid = *argv++; argc--;
           newuid = *argv++; argc--;
           keyedit_quick_adduid (ctrl, uid, newuid);
@@ -4250,7 +4602,7 @@ main (int argc, char **argv)
           const char *x_fpr, *x_algo, *x_usage, *x_expire;
 
           if (argc < 1 || argc > 4)
-            wrong_args ("--quick-addkey FINGERPRINT [ALGO [USAGE [EXPIRE]]]");
+            wrong_args ("--quick-add-key FINGERPRINT [ALGO [USAGE [EXPIRE]]]");
           x_fpr = *argv++; argc--;
           x_algo = "";
           x_usage = "";
@@ -4276,17 +4628,42 @@ main (int argc, char **argv)
           const char *uid, *uidtorev;
 
           if (argc != 2)
-            wrong_args ("--quick-revuid USER-ID USER-ID-TO-REVOKE");
+            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 [SUBKEY-FPRS]");
+          x_fpr = *argv++; argc--;
+          x_expire = *argv++; argc--;
+          keyedit_quick_set_expire (ctrl, x_fpr, x_expire, argv);
+        }
+       break;
+
+      case aQuickSetPrimaryUid:
+        {
+          const char *uid, *primaryuid;
+
+          if (argc != 2)
+            wrong_args ("--quick-set-primary-uid USER-ID PRIMARY-USER-ID");
+          uid = *argv++; argc--;
+          primaryuid = *argv++; argc--;
+          keyedit_quick_set_primary (ctrl, uid, primaryuid);
+        }
+       break;
+
       case aFastImport:
-        opt.import_options |= IMPORT_FAST;
+        opt.import_options |= IMPORT_FAST; /* fall through */
       case aImport:
-       import_keys (ctrl, argc? argv:NULL, argc, NULL, opt.import_options);
+       import_keys (ctrl, argc? argv:NULL, argc, NULL,
+                     opt.import_options, opt.key_origin, opt.key_origin_url);
        break;
 
        /* TODO: There are a number of command that use this same
@@ -4374,7 +4751,7 @@ main (int argc, char **argv)
        sl = NULL;
        for( ; argc; argc--, argv++ )
            append_to_strlist2( &sl, *argv, utf8_strings );
-       rc = keyserver_fetch (ctrl, sl);
+       rc = keyserver_fetch (ctrl, sl, opt.key_origin);
        if(rc)
           {
             write_status_failure ("fetch-keys", rc);
@@ -4389,7 +4766,7 @@ main (int argc, char **argv)
            add_to_strlist2( &sl, *argv, utf8_strings );
         {
           export_stats_t stats = export_new_stats ();
-          export_seckeys (ctrl, sl, stats);
+          export_seckeys (ctrl, sl, opt.export_options, stats);
           export_print_stats (stats);
           export_release_stats (stats);
         }
@@ -4402,7 +4779,7 @@ main (int argc, char **argv)
            add_to_strlist2( &sl, *argv, utf8_strings );
         {
           export_stats_t stats = export_new_stats ();
-          export_secsubkeys (ctrl, sl, stats);
+          export_secsubkeys (ctrl, sl, opt.export_options, stats);
           export_print_stats (stats);
           export_release_stats (stats);
         }
@@ -4411,15 +4788,15 @@ main (int argc, char **argv)
 
       case aGenRevoke:
        if( argc != 1 )
-           wrong_args("--gen-revoke user-id");
+           wrong_args("--generate-revocation user-id");
        username =  make_username(*argv);
-       gen_revoke( username );
+       gen_revoke (ctrl, username );
        xfree( username );
        break;
 
       case aDesigRevoke:
        if (argc != 1)
-           wrong_args ("--desig-revoke user-id");
+           wrong_args ("--generate-designated-revocation user-id");
        username = make_username (*argv);
        gen_desig_revoke (ctrl, username, locusr);
        xfree (username);
@@ -4560,10 +4937,10 @@ main (int argc, char **argv)
 #ifndef NO_TRUST_MODELS
       case aListTrustDB:
        if( !argc )
-          list_trustdb (es_stdout, NULL);
+          list_trustdb (ctrl, es_stdout, NULL);
        else {
            for( ; argc; argc--, argv++ )
-              list_trustdb (es_stdout, *argv );
+              list_trustdb (ctrl, es_stdout, *argv );
        }
        break;
 
@@ -4595,27 +4972,30 @@ main (int argc, char **argv)
       case aExportOwnerTrust:
        if( argc )
            wrong_args("--export-ownertrust");
-       export_ownertrust();
+       export_ownertrust (ctrl);
        break;
 
       case aImportOwnerTrust:
        if( argc > 1 )
            wrong_args("--import-ownertrust [file]");
-       import_ownertrust( argc? *argv:NULL );
+       import_ownertrust (ctrl, argc? *argv:NULL );
        break;
 #endif /*!NO_TRUST_MODELS*/
 
       case aRebuildKeydbCaches:
         if (argc)
             wrong_args ("--rebuild-keydb-caches");
-        keydb_rebuild_caches (1);
+        keydb_rebuild_caches (ctrl, 1);
         break;
 
 #ifdef ENABLE_CARD_SUPPORT
       case aCardStatus:
-        if (argc)
-            wrong_args ("--card-status");
-        card_status (es_stdout, NULL, 0);
+        if (argc == 0)
+            card_status (ctrl, es_stdout, NULL);
+        else if (argc == 1)
+            card_status (ctrl, es_stdout, *argv);
+        else
+            wrong_args ("--card-status [serialno]");
         break;
 
       case aCardEdit:
@@ -4669,7 +5049,12 @@ main (int argc, char **argv)
 
          hd = keydb_new ();
          if (! hd)
-            g10_exit (1);
+            {
+              write_status_failure ("tofu-driver", gpg_error(GPG_ERR_GENERAL));
+              g10_exit (1);
+            }
+
+          tofu_begin_batch_update (ctrl);
 
          for (i = 1; i < argc; i ++)
            {
@@ -4681,6 +5066,7 @@ main (int argc, char **argv)
                {
                  log_error (_("error parsing key specification '%s': %s\n"),
                              argv[i], gpg_strerror (rc));
+                  write_status_failure ("tofu-driver", rc);
                  g10_exit (1);
                }
 
@@ -4694,6 +5080,8 @@ main (int argc, char **argv)
                  log_error (_("'%s' does not appear to be a valid"
                               " key ID, fingerprint or keygrip\n"),
                             argv[i]);
+                  write_status_failure ("tofu-driver",
+                                        gpg_error(GPG_ERR_GENERAL));
                  g10_exit (1);
                }
 
@@ -4704,6 +5092,7 @@ main (int argc, char **argv)
                      the string.  */
                   log_error ("keydb_search_reset failed: %s\n",
                              gpg_strerror (rc));
+                  write_status_failure ("tofu-driver", rc);
                  g10_exit (1);
                }
 
@@ -4712,6 +5101,7 @@ main (int argc, char **argv)
                {
                  log_error (_("key \"%s\" not found: %s\n"), argv[i],
                              gpg_strerror (rc));
+                  write_status_failure ("tofu-driver", rc);
                  g10_exit (1);
                }
 
@@ -4720,24 +5110,35 @@ main (int argc, char **argv)
                {
                  log_error (_("error reading keyblock: %s\n"),
                              gpg_strerror (rc));
+                  write_status_failure ("tofu-driver", rc);
                  g10_exit (1);
                }
 
-             merge_keys_and_selfsig (kb);
+             merge_keys_and_selfsig (ctrl, kb);
              if (tofu_set_policy (ctrl, kb, policy))
-               g10_exit (1);
+                {
+                  write_status_failure ("tofu-driver", rc);
+                  g10_exit (1);
+                }
+
+              release_kbnode (kb);
            }
 
-         keydb_release (hd);
+          tofu_end_batch_update (ctrl);
 
+         keydb_release (hd);
        }
 #endif /*USE_TOFU*/
        break;
 
-      case aListPackets:
       default:
+        if (!opt.quiet)
+          log_info (_("WARNING: no command supplied."
+                      "  Trying to guess what you mean ...\n"));
+        /*FALLTHRU*/
+      case aListPackets:
        if( argc > 1 )
-           wrong_args(_("[filename]"));
+           wrong_args("[filename]");
        /* Issue some output for the unix newbie */
        if (!fname && !opt.outfile
             && gnupg_isatty (fileno (stdin))
@@ -4800,6 +5201,12 @@ emergency_cleanup (void)
 void
 g10_exit( int rc )
 {
+  /* If we had an error but not printed an error message, do it now.
+   * Note that write_status_failure will never print a second failure
+   * status line. */
+  if (rc)
+    write_status_failure ("gpg-exit", gpg_error (GPG_ERR_GENERAL));
+
   gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
   if (DBG_CLOCK)
     log_clock ("stop");
@@ -4807,6 +5214,7 @@ g10_exit( int rc )
   if ( (opt.debug & DBG_MEMSTAT_VALUE) )
     {
       keydb_dump_stats ();
+      sig_check_dump_stats ();
       gcry_control (GCRYCTL_DUMP_MEMORY_STATS);
       gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
     }
@@ -5127,3 +5535,37 @@ add_keyserver_url( const char *string, int which )
   if(critical)
     sl->flags |= 1;
 }
+
+
+static void
+read_sessionkey_from_fd (int fd)
+{
+  int i, len;
+  char *line;
+
+  if (! gnupg_fd_valid (fd))
+    log_fatal ("override-session-key-fd is invalid: %s\n", strerror (errno));
+
+  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;
+}