Changed default hash algorithm preferences
[gnupg.git] / g10 / gpg.c
index 10eb24c..d7ac019 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1,12 +1,12 @@
 /* gpg.c - The GnuPG utility (main for gpg)
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- *               2005 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ *               2006, 2007, 2008, 2009 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
  * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
@@ -15,9 +15,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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
 #include <ctype.h>
 #include <unistd.h>
 #include <assert.h>
-#ifdef HAVE_DOSISH_SYSTEM
-#include <fcntl.h> /* for setmode() */
-#endif
 #ifdef HAVE_STAT
 #include <sys/stat.h> /* for stat() */
 #endif
 #include <fcntl.h>
+#include <assuan.h>
+#ifdef HAVE_W32_SYSTEM
+#include <windows.h>
+#endif
 
 #define INCLUDED_BY_MAIN_MODULE 1
+#include "gpg.h"
 #include "packet.h"
-#include "iobuf.h"
-#include "memory.h"
+#include "../common/iobuf.h"
 #include "util.h"
 #include "main.h"
 #include "options.h"
 #include "keydb.h"
 #include "trustdb.h"
-#include "mpi.h"
 #include "cipher.h"
 #include "filter.h"
 #include "ttyio.h"
 #include "i18n.h"
+#include "sysutils.h"
 #include "status.h"
-#include "g10defs.h"
 #include "keyserver-internal.h"
 #include "exec.h"
-#include "cardglue.h"
-#ifdef ENABLE_CARD_SUPPORT
-#include "ccid-driver.h"
-#endif
+#include "gc-opt-flags.h"
 
 #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
 #define MY_O_BINARY  O_BINARY
@@ -79,7 +74,7 @@ enum cmd_and_opt_values
     aDecrypt     = 'd',
     aEncr        = 'e',
     oInteractive  = 'i',
-    oKOption     = 'k',
+    aListKeys    = 'k',
     oDryRun      = 'n',
     oOutput      = 'o',
     oQuiet       = 'q',
@@ -111,22 +106,23 @@ enum cmd_and_opt_values
     aLSignKey,
     aListConfig,
     aGPGConfList,
+    aGPGConfTest,
     aListPackets,
     aEditKey,
     aDeleteKeys,
     aDeleteSecretKeys,
     aDeleteSecretAndPublicKeys,
-    aKMode,
-    aKModeC,
     aImport,
     aFastImport,
     aVerify,
     aVerifyFiles,
-    aListKeys,
     aListSigs,
     aSendKeys,
     aRecvKeys,
+    aLocateKeys,
     aSearchKeys,
+    aRefreshKeys,
+    aFetchKeys,
     aExport,
     aExportSecret,
     aExportSecretSub,
@@ -142,17 +138,15 @@ enum cmd_and_opt_values
     aListTrustDB,
     aListTrustPath,
     aExportOwnerTrust,
-    aListOwnerTrust,
     aImportOwnerTrust,
     aDeArmor,
     aEnArmor,
     aGenRandom,
-    aPipeMode,
     aRebuildKeydbCaches,
-    aRefreshKeys,
     aCardStatus,
     aCardEdit,
     aChangePIN,
+    aServer,
 
     oTextmode,
     oNoTextmode,
@@ -182,6 +176,7 @@ enum cmd_and_opt_values
     oNoDefRecipient,
     oOptions,
     oDebug,
+    oDebugLevel,
     oDebugAll,
     oDebugCCIDDriver,
     oStatusFD,
@@ -197,6 +192,7 @@ enum cmd_and_opt_values
     oGnuPG,
     oRFC1991,
     oRFC2440,
+    oRFC4880,
     oOpenPGP,
     oPGP2,
     oPGP6,
@@ -214,6 +210,7 @@ enum cmd_and_opt_values
     oPasswd,
     oPasswdFD,
     oPasswdFile,
+    oPasswdRepeat,
     oCommandFD,
     oCommandFile,
     oQuickRandom,
@@ -233,13 +230,14 @@ enum cmd_and_opt_values
     oHomedir,
     oWithColons,
     oWithKeyData,
+    oWithSigList,
+    oWithSigCheck,
     oSkipVerify,
     oCompressKeys,
     oCompressSigs,
     oAlwaysTrust,
     oTrustModel,
     oForceOwnertrust,
-    oRunAsShmCP,
     oSetFilename,
     oForYourEyesOnly,
     oNoForYourEyesOnly,
@@ -270,6 +268,7 @@ enum cmd_and_opt_values
     oS2KMode,
     oS2KDigest,
     oS2KCipher,
+    oS2KCount,
     oSimpleSKChecksum,                          
     oDisplayCharset,
     oNotDashEscaped,
@@ -329,14 +328,17 @@ enum cmd_and_opt_values
     oNoAutoCheckTrustDB,
     oPreservePermissions,
     oDefaultPreferenceList,
+    oDefaultKeyserverURL,
     oPersonalCipherPreferences,
     oPersonalDigestPreferences,
     oPersonalCompressPreferences,
+    oAgentProgram,
     oDisplay,
     oTTYname,
     oTTYtype,
     oLCctype,
     oLCmessages,
+    oXauthority,
     oGroup,
     oUnGroup,
     oNoGroups,
@@ -349,11 +351,15 @@ enum cmd_and_opt_values
     oKeyidFormat,
     oExitOnStatusWriteError,
     oLimitCardInsertTries,
-
-    oReaderPort,
-    octapiDriver,
-    opcscDriver,
-    oDisableCCID,
+    oRequireCrossCert,
+    oNoRequireCrossCert,
+    oAutoKeyLocate,
+    oNoAutoKeyLocate,
+    oAllowMultisigVerification,
+    oEnableDSA2,
+    oDisableDSA2,
+    oAllowMultipleMessages,
+    oNoAllowMultipleMessages,
 
     oNoop
   };
@@ -361,341 +367,388 @@ enum cmd_and_opt_values
 
 static ARGPARSE_OPTS opts[] = {
 
-    { 300, NULL, 0, N_("@Commands:\n ") },
-
-    { aSign, "sign",      256, N_("|[file]|make a signature")},
-    { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature")},
-    { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
-    { aEncr, "encrypt",   256, N_("encrypt data")},
-    { aEncrFiles, "encrypt-files", 256, "@"},
-    { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
-    { aStore, "store",     256, "@"},
-    { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
-    { aDecryptFiles, "decrypt-files", 256, "@"},
-    { aVerify, "verify"   , 256, N_("verify a signature")},
-    { aVerifyFiles, "verify-files" , 256, "@" },
-    { aListKeys, "list-keys", 256, N_("list keys")},
-    { aListKeys, "list-public-keys", 256, "@" },
-    { aListSigs, "list-sigs", 256, N_("list keys and signatures")},
-    { aCheckKeys, "check-sigs",256, N_("list and check key signatures")},
-    { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
-    { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
-    { aKeygen,    "gen-key",  256, N_("generate a new key pair")},
-    { aDeleteKeys,"delete-keys",256,N_("remove keys from the public keyring")},
-    { aDeleteSecretKeys, "delete-secret-keys",256,
-                                   N_("remove keys from the secret keyring")},
-    { aSignKey,  "sign-key"   ,256, N_("sign a key")},
-    { aLSignKey, "lsign-key"  ,256, N_("sign a key locally")},
-    { aEditKey,  "edit-key"   ,256, N_("sign or edit a key")},
-    { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
-    { aDesigRevoke, "desig-revoke",256, "@" },
-    { aExport, "export"           , 256, N_("export keys") },
-    { aSendKeys, "send-keys"     , 256, N_("export keys to a key server") },
-    { aRecvKeys, "recv-keys"     , 256, N_("import keys from a key server") },
-    { aSearchKeys, "search-keys" , 256,
-                                    N_("search for keys on a key server") },
-    { aRefreshKeys, "refresh-keys", 256,
-                                    N_("update all keys from a keyserver")},
-    { aExportSecret, "export-secret-keys" , 256, "@" },
-    { aExportSecretSub, "export-secret-subkeys" , 256, "@" },
-    { aImport, "import",      256     , N_("import/merge keys")},
-    { aFastImport, "fast-import",  256 , "@"},
+  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 (aDetachedSign, "detach-sign", N_("make a detached signature")),
+  ARGPARSE_c (aEncr, "encrypt",   N_("encrypt data")),
+  ARGPARSE_c (aEncrFiles, "encrypt-files", "@"),
+  ARGPARSE_c (aSym, "symmetric", N_("encryption only with symmetric cipher")),
+  ARGPARSE_c (aStore, "store",     "@"),
+  ARGPARSE_c (aDecrypt, "decrypt",   N_("decrypt data (default)")),
+  ARGPARSE_c (aDecryptFiles, "decrypt-files", "@"),
+  ARGPARSE_c (aVerify, "verify"   , N_("verify a signature")),
+  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 (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 (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 (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 (aGenRevoke, "gen-revoke",N_("generate a revocation certificate")),
+  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", 
+              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 (aImport, "import", N_("import/merge keys")),
+  ARGPARSE_c (aFastImport, "fast-import", "@"),
 #ifdef ENABLE_CARD_SUPPORT
-    { aCardStatus,  "card-status", 256, N_("print the card status")},
-    { aCardEdit,   "card-edit",  256, N_("change data on a card")},
-    { aChangePIN,  "change-pin", 256, N_("change a card's PIN")},
+  ARGPARSE_c (aCardStatus,  "card-status", N_("print the card status")),
+  ARGPARSE_c (aCardEdit,   "card-edit",  N_("change data on a card")),
+  ARGPARSE_c (aChangePIN,  "change-pin", N_("change a card's PIN")),
 #endif
-    { aListConfig, "list-config", 256, "@"},
-    { aGPGConfList, "gpgconf-list", 256, "@" },
-    { aListPackets, "list-packets",256, "@"},
-    { aExportOwnerTrust, "export-ownertrust", 256, "@"},
-    { aImportOwnerTrust, "import-ownertrust", 256, "@"},
-    { aUpdateTrustDB,
-             "update-trustdb",0 , N_("update the trust database")},
-    { aCheckTrustDB, "check-trustdb", 0, "@"},
-    { aFixTrustDB, "fix-trustdb", 0, "@"},
-    { aDeArmor, "dearmor", 256, "@"},
-    { aDeArmor, "dearmour", 256, "@"},
-    { aEnArmor, "enarmor", 256, "@"},
-    { aEnArmor, "enarmour", 256, "@"},
-    { aPrintMD,  "print-md" , 256, N_("|algo [files]|print message digests")},
-    { aPrimegen, "gen-prime" , 256, "@" },
-    { aGenRandom, "gen-random" , 256, "@" },
-
-    { 301, NULL, 0, N_("@\nOptions:\n ") },
-
-    { oArmor, "armor",     0, N_("create ascii armored output")},
-    { oArmor, "armour",     0, "@" },
-    { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
-    { oHiddenRecipient, "hidden-recipient", 2, "@" },
-    { oRecipient, "remote-user", 2, "@"},  /* old option name */
-    { oDefRecipient, "default-recipient", 2, "@"},
-    { oDefRecipientSelf, "default-recipient-self", 0, "@"},
-    { oNoDefRecipient, "no-default-recipient", 0, "@" },
-    { oTempDir, "temp-directory", 2, "@" },
-    { oExecPath, "exec-path", 2, "@" },
-    { oEncryptTo, "encrypt-to", 2, "@" },
-    { oHiddenEncryptTo, "hidden-encrypt-to", 2, "@" },
-    { oNoEncryptTo, "no-encrypt-to", 0, "@" },
-    { oLocalUser, "local-user",2, N_("use this user-id to sign or decrypt")},
-    { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") },
-    { oCompressLevel, "compress-level", 1, "@" },
-    { oBZ2CompressLevel, "bzip2-compress-level", 1, "@" },
-    { oBZ2DecompressLowmem, "bzip2-decompress-lowmem", 0, "@" },
-    { oTextmodeShort, NULL,   0, "@"},
-    { oTextmode, "textmode",  0, N_("use canonical text mode")},
-    { oNoTextmode, "no-textmode",  0, "@"},
-    { oExpert, "expert",   0, "@"},
-    { oNoExpert, "no-expert",   0, "@"},
-    { oDefSigExpire, "default-sig-expire", 2, "@"},
-    { oAskSigExpire, "ask-sig-expire",   0, "@"},
-    { oNoAskSigExpire, "no-ask-sig-expire",   0, "@"},
-    { oDefCertExpire, "default-cert-expire", 2, "@"},
-    { oAskCertExpire, "ask-cert-expire",   0, "@"},
-    { oNoAskCertExpire, "no-ask-cert-expire",   0, "@"},
-    { oDefCertLevel, "default-cert-level", 1, "@"},
-    { oMinCertLevel, "min-cert-level", 1, "@"},
-    { oAskCertLevel, "ask-cert-level",   0, "@"},
-    { oNoAskCertLevel, "no-ask-cert-level",   0, "@"},
-    { oOutput, "output",    2, N_("use as output file")},
-    { oMaxOutput, "max-output", 16|4, "@" },
-    { oVerbose, "verbose",   0, N_("verbose") },
-    { oQuiet,  "quiet",   0, "@"},
-    { oNoTTY, "no-tty", 0, "@"},
-    { oForceV3Sigs, "force-v3-sigs", 0, "@"},
-    { oNoForceV3Sigs, "no-force-v3-sigs", 0, "@"},
-    { oForceV4Certs, "force-v4-certs", 0, "@"},
-    { oNoForceV4Certs, "no-force-v4-certs", 0, "@"},
-    { oForceMDC, "force-mdc", 0, "@"},
-    { oNoForceMDC, "no-force-mdc", 0, "@" },
-    { oDisableMDC, "disable-mdc", 0, "@"},
-    { oNoDisableMDC, "no-disable-mdc", 0, "@" },
-    { oDryRun, "dry-run",   0, N_("do not make any changes") },
-    { oInteractive, "interactive", 0, N_("prompt before overwriting") },
-    { oUseAgent, "use-agent",0, "@"},
-    { oNoUseAgent, "no-use-agent",0, "@"},
-    { oGpgAgentInfo, "gpg-agent-info",2, "@"},
-    { oBatch, "batch", 0, "@"},
-    { oAnswerYes, "yes", 0, "@"},
-    { oAnswerNo, "no", 0, "@"},
-    { oKeyring, "keyring", 2, "@"},
-    { oPrimaryKeyring, "primary-keyring",2, "@" },
-    { oSecretKeyring, "secret-keyring", 2, "@"},
-    { oShowKeyring, "show-keyring", 0, "@"},
-    { oDefaultKey, "default-key", 2, "@"},
-    { oKeyServer, "keyserver", 2, "@"},
-    { oKeyServerOptions, "keyserver-options",2,"@"},
-    { oImportOptions, "import-options",2,"@"},
-    { oExportOptions, "export-options",2,"@"},
-    { oListOptions, "list-options",2,"@"},
-    { oVerifyOptions, "verify-options",2,"@"},
-    { oDisplayCharset, "display-charset", 2, "@"},
-    { oDisplayCharset, "charset", 2, "@"},
-    { oOptions, "options", 2, "@"},
-    { oDebug, "debug"     ,4|16, "@"},
-    { oDebugAll, "debug-all" ,0, "@"},
-    { oStatusFD, "status-fd" ,1, "@"},
-    { oStatusFile, "status-file" ,2, "@"},
-    { oAttributeFD, "attribute-fd" ,1, "@" },
-    { oAttributeFile, "attribute-file" ,2, "@" },
-    { oNoop, "sk-comments", 0,   "@"},
-    { oNoop, "no-sk-comments", 0,   "@"},
-    { oCompletesNeeded, "completes-needed", 1, "@"},
-    { oMarginalsNeeded, "marginals-needed", 1, "@"},
-    { oMaxCertDepth,   "max-cert-depth", 1, "@" },
-    { oTrustedKey, "trusted-key", 2, "@"},
-    { oLoadExtension, "load-extension", 2, "@"},
-    { oGnuPG, "gnupg",   0, "@"},
-    { oGnuPG, "no-pgp2", 0, "@"},
-    { oGnuPG, "no-pgp6", 0, "@"},
-    { oGnuPG, "no-pgp7", 0, "@"},
-    { oGnuPG, "no-pgp8", 0, "@"},
-    { oRFC1991, "rfc1991",   0, "@"},
-    { oRFC2440, "rfc2440", 0, "@" },
-    { oOpenPGP, "openpgp", 0, N_("use strict OpenPGP behavior")},
-    { oPGP2, "pgp2", 0, N_("generate PGP 2.x compatible messages")},
-    { oPGP6, "pgp6", 0, "@"},
-    { oPGP7, "pgp7", 0, "@"},
-    { oPGP8, "pgp8", 0, "@"},
-    { oRFC2440Text, "rfc2440-text", 0, "@"},
-    { oNoRFC2440Text, "no-rfc2440-text", 0, "@"},
-    { oS2KMode, "s2k-mode", 1, "@"},
-    { oS2KDigest, "s2k-digest-algo", 2, "@"},
-    { oS2KCipher, "s2k-cipher-algo", 2, "@"},
-    { oSimpleSKChecksum, "simple-sk-checksum", 0, "@"},
-    { oCipherAlgo, "cipher-algo", 2, "@"},
-    { oDigestAlgo, "digest-algo", 2, "@"},
-    { oCertDigestAlgo, "cert-digest-algo", 2 , "@" },
-    { oCompressAlgo,"compress-algo", 2, "@"},
-    { oCompressAlgo, "compression-algo", 2, "@"}, /* Alias */
-    { oThrowKeyids, "throw-keyid", 0, "@"},
-    { oThrowKeyids, "throw-keyids", 0, "@"},
-    { oNoThrowKeyids, "no-throw-keyid", 0, "@" },
-    { oNoThrowKeyids, "no-throw-keyids", 0, "@" },
-    { oShowPhotos,   "show-photos", 0, "@" },
-    { oNoShowPhotos, "no-show-photos", 0, "@" },
-    { oPhotoViewer,  "photo-viewer", 2, "@" },
-    { oSetNotation,  "set-notation", 2, "@" },
-    { oSetNotation,  "notation-data", 2, "@" }, /* Alias */
-    { oSigNotation,  "sig-notation", 2, "@" },
-    { oCertNotation, "cert-notation", 2, "@" },
-
-    { 302, NULL, 0, N_(
+  ARGPARSE_c (aListConfig, "list-config", "@"),
+  ARGPARSE_c (aGPGConfList, "gpgconf-list", "@" ),
+  ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@" ),
+  ARGPARSE_c (aListPackets, "list-packets","@"),
+  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", "@"),
+  ARGPARSE_c (aDeArmor, "dearmor", "@"),
+  ARGPARSE_c (aDeArmor, "dearmour", "@"),
+  ARGPARSE_c (aEnArmor, "enarmor", "@"),
+  ARGPARSE_c (aEnArmor, "enarmour", "@"),
+  ARGPARSE_c (aPrintMD, "print-md", N_("print message digests")),
+  ARGPARSE_c (aPrimegen, "gen-prime", "@" ),
+  ARGPARSE_c (aGenRandom,"gen-random", "@" ),
+  ARGPARSE_c (aServer,   "server",  N_("run in server mode")),
+
+  ARGPARSE_group (301, N_("@\nOptions:\n ")),
+
+  ARGPARSE_s_n (oArmor, "armor", N_("create ascii armored output")),
+  ARGPARSE_s_n (oArmor, "armour", "@"),
+
+  ARGPARSE_s_s (oRecipient, "recipient", N_("|USER-ID|encrypt for USER-ID")),
+  ARGPARSE_s_s (oHiddenRecipient, "hidden-recipient", "@"),
+  ARGPARSE_s_s (oRecipient, "remote-user", "@"),  /* (old option name) */
+  ARGPARSE_s_s (oDefRecipient, "default-recipient", "@"),
+  ARGPARSE_s_n (oDefRecipientSelf,  "default-recipient-self", "@"),
+  ARGPARSE_s_n (oNoDefRecipient, "no-default-recipient", "@"),
+
+  ARGPARSE_s_s (oTempDir,  "temp-directory", "@"),
+  ARGPARSE_s_s (oExecPath, "exec-path", "@"),
+  ARGPARSE_s_s (oEncryptTo,      "encrypt-to", "@"),
+  ARGPARSE_s_n (oNoEncryptTo, "no-encrypt-to", "@"),
+  ARGPARSE_s_s (oHiddenEncryptTo, "hidden-encrypt-to", "@"),
+  ARGPARSE_s_s (oLocalUser, "local-user",
+                N_("|USER-ID|use USER-ID to sign or decrypt")),
+
+  ARGPARSE_s_i (oCompress, NULL,
+                N_("|N|set compress level to N (0 disables)")),
+  ARGPARSE_s_i (oCompressLevel, "compress-level", "@"),
+  ARGPARSE_s_i (oBZ2CompressLevel, "bzip2-compress-level", "@"),
+  ARGPARSE_s_n (oBZ2DecompressLowmem, "bzip2-decompress-lowmem", "@"),
+
+  ARGPARSE_s_n (oTextmodeShort, NULL, "@"),
+  ARGPARSE_s_n (oTextmode,      "textmode", N_("use canonical text mode")),
+  ARGPARSE_s_n (oNoTextmode, "no-textmode", "@"),
+
+  ARGPARSE_s_n (oExpert,      "expert", "@"),
+  ARGPARSE_s_n (oNoExpert, "no-expert", "@"),
+
+  ARGPARSE_s_s (oDefSigExpire, "default-sig-expire", "@"),
+  ARGPARSE_s_n (oAskSigExpire,      "ask-sig-expire", "@"),
+  ARGPARSE_s_n (oNoAskSigExpire, "no-ask-sig-expire", "@"),
+  ARGPARSE_s_s (oDefCertExpire, "default-cert-expire", "@"),
+  ARGPARSE_s_n (oAskCertExpire,      "ask-cert-expire", "@"),
+  ARGPARSE_s_n (oNoAskCertExpire, "no-ask-cert-expire", "@"),
+  ARGPARSE_s_i (oDefCertLevel, "default-cert-level", "@"),
+  ARGPARSE_s_i (oMinCertLevel, "min-cert-level", "@"),
+  ARGPARSE_s_n (oAskCertLevel,      "ask-cert-level", "@"),
+  ARGPARSE_s_n (oNoAskCertLevel, "no-ask-cert-level", "@"),
+
+  ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")),
+  ARGPARSE_p_u (oMaxOutput, "max-output", "@"),
+
+  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 (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", "@"),
+  ARGPARSE_s_s (oKeyring, "keyring", "@"),
+  ARGPARSE_s_s (oPrimaryKeyring, "primary-keyring", "@"),
+  ARGPARSE_s_s (oSecretKeyring, "secret-keyring", "@"),
+  ARGPARSE_s_n (oShowKeyring, "show-keyring", "@"),
+  ARGPARSE_s_s (oDefaultKey, "default-key", "@"),
+
+  ARGPARSE_s_s (oKeyServer, "keyserver", "@"),
+  ARGPARSE_s_s (oKeyServerOptions, "keyserver-options", "@"),
+  ARGPARSE_s_s (oImportOptions, "import-options", "@"),
+  ARGPARSE_s_s (oExportOptions, "export-options", "@"),
+  ARGPARSE_s_s (oListOptions,   "list-options", "@"),
+  ARGPARSE_s_s (oVerifyOptions, "verify-options", "@"),
+
+  ARGPARSE_s_s (oDisplayCharset, "display-charset", "@"),
+  ARGPARSE_s_s (oDisplayCharset, "charset", "@"),
+  ARGPARSE_s_s (oOptions, "options", "@"),
+
+  ARGPARSE_p_u (oDebug, "debug", "@"),
+  ARGPARSE_s_s (oDebugLevel, "debug-level", "@"),
+  ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
+  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", "@" ),
+  ARGPARSE_s_s (oTrustedKey, "trusted-key", "@"),
+
+  ARGPARSE_s_s (oLoadExtension, "load-extension", "@"),  /* Dummy.  */
+
+  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 (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", "@"),
+
+  ARGPARSE_s_n (oRFC2440Text,      "rfc2440-text", "@"),
+  ARGPARSE_s_n (oNoRFC2440Text, "no-rfc2440-text", "@"),
+  ARGPARSE_s_i (oS2KMode, "s2k-mode", "@"),
+  ARGPARSE_s_s (oS2KDigest, "s2k-digest-algo", "@"),
+  ARGPARSE_s_s (oS2KCipher, "s2k-cipher-algo", "@"),
+  ARGPARSE_s_i (oS2KCount, "s2k-count", "@"),
+  ARGPARSE_s_n (oSimpleSKChecksum, "simple-sk-checksum", "@"),
+  ARGPARSE_s_s (oCipherAlgo, "cipher-algo", "@"),
+  ARGPARSE_s_s (oDigestAlgo, "digest-algo", "@"),
+  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", "@"),
+
+  ARGPARSE_group (302, N_(
   "@\n(See the man page for a complete listing of all commands and options)\n"
-                     )},
+                     )),
 
-    { 303, NULL, 0, N_("@\nExamples:\n\n"
+  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"
     " --detach-sign [file]       make a detached signature\n"
     " --list-keys [names]        show keys\n"
-    " --fingerprint [names]      show fingerprints\n"  ) },
-
-  /* hidden options */
-    { aListOwnerTrust, "list-ownertrust", 256, "@"}, /* deprecated */
-    { aPrintMDs, "print-mds" , 256, "@"}, /* old */
-    { aListTrustDB, "list-trustdb",0 , "@"},
-    /* Not yet used */
-    /* { aListTrustPath, "list-trust-path",0, "@"}, */
-    { aPipeMode,  "pipemode", 0, "@" },
-    { oKOption, NULL,   0, "@"},
-    { oPasswd, "passphrase",2, "@" },
-    { oPasswdFD, "passphrase-fd",1, "@" },
-    { oPasswdFile, "passphrase-file",2, "@" },
-    { oCommandFD, "command-fd",1, "@" },
-    { oCommandFile, "command-file",2, "@" },
-    { oQuickRandom, "quick-random", 0, "@"},
-    { oNoVerbose, "no-verbose", 0, "@"},
-    { oTrustDBName, "trustdb-name", 2, "@" },
-    { oNoSecmemWarn, "no-secmem-warning", 0, "@" },
-    { oRequireSecmem,"require-secmem", 0, "@" },
-    { oNoRequireSecmem,"no-require-secmem", 0, "@" },
-    { oNoPermissionWarn, "no-permission-warning", 0, "@" },
-    { oNoMDCWarn, "no-mdc-warning", 0, "@" },
-    { oNoArmor, "no-armor",   0, "@"},
-    { oNoArmor, "no-armour",   0, "@"},
-    { oNoDefKeyring, "no-default-keyring", 0, "@" },
-    { oNoGreeting, "no-greeting", 0, "@" },
-    { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
-    { oHomedir, "homedir", 2, "@" },   /* defaults to "~/.gnupg" */
-    { oNoBatch, "no-batch", 0, "@" },
-    { oWithColons, "with-colons", 0, "@"},
-    { oWithKeyData,"with-key-data", 0, "@"},
-    { aListKeys, "list-key", 0, "@" }, /* alias */
-    { aListSigs, "list-sig", 0, "@" }, /* alias */
-    { aCheckKeys, "check-sig",0, "@" }, /* alias */
-    { oSkipVerify, "skip-verify",0, "@" },
-    { oCompressKeys, "compress-keys",0, "@"},
-    { oCompressSigs, "compress-sigs",0, "@"},
-    { oDefCertLevel, "default-cert-check-level", 1, "@"}, /* Old option */
-    { oAlwaysTrust, "always-trust", 0, "@"},
-    { oTrustModel, "trust-model", 2, "@"},
-    { oForceOwnertrust, "force-ownertrust", 2, "@"},
-    { oRunAsShmCP, "run-as-shm-coprocess", 4, "@" },
-    { oSetFilename, "set-filename", 2, "@" },
-    { oForYourEyesOnly, "for-your-eyes-only", 0, "@" },
-    { oNoForYourEyesOnly, "no-for-your-eyes-only", 0, "@" },
-    { oSetPolicyURL, "set-policy-url", 2, "@" },
-    { oSigPolicyURL, "sig-policy-url", 2, "@" },
-    { oCertPolicyURL, "cert-policy-url", 2, "@" },
-    { oShowPolicyURL, "show-policy-url", 0, "@" },
-    { oNoShowPolicyURL, "no-show-policy-url", 0, "@" },
-    { oSigKeyserverURL, "sig-keyserver-url", 2, "@" },
-    { oShowNotation, "show-notation", 0, "@" },
-    { oNoShowNotation, "no-show-notation", 0, "@" },
-    { oComment, "comment", 2, "@" },
-    { oDefaultComment, "default-comment", 0, "@" },
-    { oNoComments, "no-comments", 0, "@" },
-    { oEmitVersion, "emit-version", 0, "@"},
-    { oNoEmitVersion, "no-emit-version", 0, "@"},
-    { oNoEmitVersion, "no-version", 0, "@"}, /* alias */
-    { oNotDashEscaped, "not-dash-escaped", 0, "@" },
-    { oEscapeFrom, "escape-from-lines", 0, "@" },
-    { oNoEscapeFrom, "no-escape-from-lines", 0, "@" },
-    { oLockOnce, "lock-once", 0, "@" },
-    { oLockMultiple, "lock-multiple", 0, "@" },
-    { oLockNever, "lock-never", 0, "@" },
-    { oLoggerFD, "logger-fd",1, "@" },
-    { oLoggerFile, "logger-file",2, "@" },
-    { oUseEmbeddedFilename, "use-embedded-filename", 0, "@" },
-    { oNoUseEmbeddedFilename, "no-use-embedded-filename", 0, "@" },
-    { oUtf8Strings, "utf8-strings", 0, "@" },
-    { oNoUtf8Strings, "no-utf8-strings", 0, "@" },
-    { oWithFingerprint, "with-fingerprint", 0, "@" },
-    { oDisableCipherAlgo,  "disable-cipher-algo", 2, "@" },
-    { oDisablePubkeyAlgo,  "disable-pubkey-algo", 2, "@" },
-    { oAllowNonSelfsignedUID, "allow-non-selfsigned-uid", 0, "@" },
-    { oNoAllowNonSelfsignedUID, "no-allow-non-selfsigned-uid", 0, "@" },
-    { oAllowFreeformUID, "allow-freeform-uid", 0, "@" },
-    { oNoAllowFreeformUID, "no-allow-freeform-uid", 0, "@" },
-    { oNoLiteral, "no-literal", 0, "@" },
-    { oSetFilesize, "set-filesize", 20, "@" },
-    { oHonorHttpProxy,"honor-http-proxy", 0, "@" },
-    { oFastListMode,"fast-list-mode", 0, "@" },
-    { oFixedListMode,"fixed-list-mode", 0, "@" },
-    { oListOnly, "list-only", 0, "@"},
-    { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
-    { oIgnoreValidFrom,    "ignore-valid-from",    0, "@" },
-    { oIgnoreCrcError, "ignore-crc-error", 0,"@" },
-    { oIgnoreMDCError, "ignore-mdc-error", 0,"@" },
-    { oShowSessionKey, "show-session-key", 0, "@" },
-    { oOverrideSessionKey, "override-session-key", 2, "@" },
-    { oNoRandomSeedFile,  "no-random-seed-file", 0, "@" },
-    { oAutoKeyRetrieve, "auto-key-retrieve", 0, "@" },
-    { oNoAutoKeyRetrieve, "no-auto-key-retrieve", 0, "@" },
-    { oNoSigCache,         "no-sig-cache", 0, "@" },
-    { oNoSigCreateCheck,   "no-sig-create-check", 0, "@" },
-    { oAutoCheckTrustDB, "auto-check-trustdb", 0, "@"},
-    { oNoAutoCheckTrustDB, "no-auto-check-trustdb", 0, "@"},
-    { oMergeOnly,        "merge-only", 0, "@" },
-    { oAllowSecretKeyImport, "allow-secret-key-import", 0, "@" },
-    { oTryAllSecrets,  "try-all-secrets", 0, "@" },
-    { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" },
-    { oNoExpensiveTrustChecks, "no-expensive-trust-checks", 0, "@" },
-    { aDeleteSecretAndPublicKeys, "delete-secret-and-public-keys",256, "@" },
-    { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"},
-    { oPreservePermissions, "preserve-permissions", 0, "@"},
-    { oDefaultPreferenceList,  "default-preference-list", 2, "@"},
-    { oPersonalCipherPreferences,  "personal-cipher-preferences", 2, "@"},
-    { oPersonalDigestPreferences,  "personal-digest-preferences", 2, "@"},
-    { oPersonalCompressPreferences,  "personal-compress-preferences", 2, "@"},
-    /* Aliases.  I constantly mistype these, and assume other people
-       do as well. */
-    { oPersonalCipherPreferences, "personal-cipher-prefs", 2, "@"},
-    { oPersonalDigestPreferences, "personal-digest-prefs", 2, "@"},
-    { oPersonalCompressPreferences, "personal-compress-prefs", 2, "@"},
-    { oDisplay,    "display",     2, "@" },
-    { oTTYname,    "ttyname",     2, "@" },
-    { oTTYtype,    "ttytype",     2, "@" },
-    { oLCctype,    "lc-ctype",    2, "@" },
-    { oLCmessages, "lc-messages", 2, "@" },
-    { oGroup,      "group",       2, "@" },
-    { oUnGroup,    "ungroup",     2, "@" },
-    { oNoGroups,   "no-groups",    0, "@" },
-    { oStrict,     "strict",      0, "@" },
-    { oNoStrict,   "no-strict",   0, "@" },
-    { oMangleDosFilenames, "mangle-dos-filenames", 0, "@" },
-    { oNoMangleDosFilenames, "no-mangle-dos-filenames", 0, "@" },
-    { oEnableProgressFilter, "enable-progress-filter", 0, "@" },
-    { oMultifile, "multifile", 0, "@" },
-    { oKeyidFormat, "keyid-format", 2, "@" },
-    { oExitOnStatusWriteError, "exit-on-status-write-error", 0, "@" },
-    { oLimitCardInsertTries, "limit-card-insert-tries", 1, "@"},
-
-    { oReaderPort, "reader-port",    2, "@"},
-    { octapiDriver, "ctapi-driver",  2, "@"},
-    { opcscDriver, "pcsc-driver",    2, "@"},
-    { oDisableCCID, "disable-ccid", 0, "@"},
-#if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB)
-    { oDebugCCIDDriver, "debug-ccid-driver", 0, "@"},
-#endif
-    /* These 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 returning
-       the favor. */
-    { oLocalUser, "sign-with", 2, "@" },
-    { oRecipient, "user", 2, "@" },
-    {0,NULL,0,NULL}
+    " --fingerprint [names]      show fingerprints\n")),
+
+  /* More hidden commands and options. */
+  ARGPARSE_c (aPrintMDs, "print-mds", "@"), /* old */
+  ARGPARSE_c (aListTrustDB, "list-trustdb", "@"),
+  /* Not yet used: 
+     ARGPARSE_c (aListTrustPath, "list-trust-path", "@"), */
+  ARGPARSE_c (aDeleteSecretAndPublicKeys,
+              "delete-secret-and-public-keys", "@"),
+  ARGPARSE_c (aRebuildKeydbCaches, "rebuild-keydb-caches", "@"),
+
+  ARGPARSE_s_s (oPasswd, "passphrase", "@"),
+  ARGPARSE_s_i (oPasswdFD, "passphrase-fd", "@"),
+  ARGPARSE_s_s (oPasswdFile, "passphrase-file", "@"),
+  ARGPARSE_s_i (oPasswdRepeat, "passphrase-repeat", "@"),
+  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", "@"),
+  ARGPARSE_s_s (oTrustDBName, "trustdb-name", "@"),
+  ARGPARSE_s_n (oNoSecmemWarn, "no-secmem-warning", "@"),
+  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", "@"),
+  ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
+  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 (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_s_n (oSkipVerify, "skip-verify", "@"),
+  ARGPARSE_s_n (oCompressKeys, "compress-keys", "@"),
+  ARGPARSE_s_n (oCompressSigs, "compress-sigs", "@"),
+  ARGPARSE_s_i (oDefCertLevel, "default-cert-check-level", "@"), /* old */
+  ARGPARSE_s_n (oAlwaysTrust, "always-trust", "@"),
+  ARGPARSE_s_s (oTrustModel, "trust-model", "@"),
+  ARGPARSE_s_s (oForceOwnertrust, "force-ownertrust", "@"),
+  ARGPARSE_s_s (oSetFilename, "set-filename", "@"),
+  ARGPARSE_s_n (oForYourEyesOnly, "for-your-eyes-only", "@"),
+  ARGPARSE_s_n (oNoForYourEyesOnly, "no-for-your-eyes-only", "@"),
+  ARGPARSE_s_s (oSetPolicyURL,  "set-policy-url", "@"),
+  ARGPARSE_s_s (oSigPolicyURL,  "sig-policy-url", "@"),
+  ARGPARSE_s_s (oCertPolicyURL, "cert-policy-url", "@"),
+  ARGPARSE_s_n (oShowPolicyURL,      "show-policy-url", "@"),
+  ARGPARSE_s_n (oNoShowPolicyURL, "no-show-policy-url", "@"),
+  ARGPARSE_s_s (oSigKeyserverURL, "sig-keyserver-url", "@"),
+  ARGPARSE_s_n (oShowNotation,      "show-notation", "@"),
+  ARGPARSE_s_n (oNoShowNotation, "no-show-notation", "@"),
+  ARGPARSE_s_s (oComment, "comment", "@"),
+  ARGPARSE_s_n (oDefaultComment, "default-comment", "@"),
+  ARGPARSE_s_n (oNoComments, "no-comments", "@"),
+  ARGPARSE_s_n (oEmitVersion,      "emit-version", "@"),
+  ARGPARSE_s_n (oNoEmitVersion, "no-emit-version", "@"),
+  ARGPARSE_s_n (oNoEmitVersion, "no-version", "@"), /* alias */
+  ARGPARSE_s_n (oNotDashEscaped, "not-dash-escaped", "@"),
+  ARGPARSE_s_n (oEscapeFrom,      "escape-from-lines", "@"),
+  ARGPARSE_s_n (oNoEscapeFrom, "no-escape-from-lines", "@"),
+  ARGPARSE_s_n (oLockOnce,     "lock-once", "@"),
+  ARGPARSE_s_n (oLockMultiple, "lock-multiple", "@"),
+  ARGPARSE_s_n (oLockNever,    "lock-never", "@"),
+  ARGPARSE_s_i (oLoggerFD,   "logger-fd", "@"),
+  ARGPARSE_s_s (oLoggerFile, "log-file", "@"),
+  ARGPARSE_s_s (oLoggerFile, "logger-file", "@"),  /* 1.4 compatibility.  */
+  ARGPARSE_s_n (oUseEmbeddedFilename,      "use-embedded-filename", "@"),
+  ARGPARSE_s_n (oNoUseEmbeddedFilename, "no-use-embedded-filename", "@"),
+  ARGPARSE_s_n (oUtf8Strings,      "utf8-strings", "@"),
+  ARGPARSE_s_n (oNoUtf8Strings, "no-utf8-strings", "@"),
+  ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"),
+  ARGPARSE_s_s (oDisableCipherAlgo,  "disable-cipher-algo", "@"),
+  ARGPARSE_s_s (oDisablePubkeyAlgo,  "disable-pubkey-algo", "@"),
+  ARGPARSE_s_n (oAllowNonSelfsignedUID,      "allow-non-selfsigned-uid", "@"),
+  ARGPARSE_s_n (oNoAllowNonSelfsignedUID, "no-allow-non-selfsigned-uid", "@"),
+  ARGPARSE_s_n (oAllowFreeformUID,      "allow-freeform-uid", "@"),
+  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 (oListOnly, "list-only", "@"),
+  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_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", "@"),
+  ARGPARSE_s_n (oEnableSpecialFilenames, "enable-special-filenames", "@"),
+  ARGPARSE_s_n (oNoExpensiveTrustChecks, "no-expensive-trust-checks", "@"),
+  ARGPARSE_s_n (oPreservePermissions, "preserve-permissions", "@"),
+  ARGPARSE_s_s (oDefaultPreferenceList,  "default-preference-list", "@"),
+  ARGPARSE_s_s (oDefaultKeyserverURL,  "default-keyserver-url", "@"),
+  ARGPARSE_s_s (oPersonalCipherPreferences, "personal-cipher-preferences","@"),
+  ARGPARSE_s_s (oPersonalDigestPreferences, "personal-digest-preferences","@"),
+  ARGPARSE_s_s (oPersonalCompressPreferences,
+                                         "personal-compress-preferences", "@"),
+
+  /* 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 (oDisplay,    "display",    "@"),
+  ARGPARSE_s_s (oTTYname,    "ttyname",    "@"),
+  ARGPARSE_s_s (oTTYtype,    "ttytype",    "@"),
+  ARGPARSE_s_s (oLCctype,    "lc-ctype",   "@"),
+  ARGPARSE_s_s (oLCmessages, "lc-messages","@"),
+  ARGPARSE_s_s (oXauthority, "xauthority", "@"),
+  ARGPARSE_s_s (oGroup,      "group",      "@"),
+  ARGPARSE_s_s (oUnGroup,    "ungroup",    "@"),
+  ARGPARSE_s_n (oNoGroups,   "no-groups",  "@"),
+  ARGPARSE_s_n (oStrict,     "strict",     "@"),
+  ARGPARSE_s_n (oNoStrict,   "no-strict",  "@"),
+  ARGPARSE_s_n (oMangleDosFilenames,      "mangle-dos-filenames", "@"),
+  ARGPARSE_s_n (oNoMangleDosFilenames, "no-mangle-dos-filenames", "@"),
+  ARGPARSE_s_n (oEnableProgressFilter, "enable-progress-filter", "@"),
+  ARGPARSE_s_n (oMultifile, "multifile", "@"),
+  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, 
+                "allow-multisig-verification", "@"),
+  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", "@"),
+
+  /* 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
+     returning the favor. */
+  ARGPARSE_s_s (oLocalUser, "sign-with", "@"),
+  ARGPARSE_s_s (oRecipient, "user", "@"),
+
+  ARGPARSE_s_n (oRequireCrossCert, "require-backsigs", "@"),
+  ARGPARSE_s_n (oRequireCrossCert, "require-cross-certification", "@"),
+  ARGPARSE_s_n (oNoRequireCrossCert, "no-require-backsigs", "@"),
+  ARGPARSE_s_n (oNoRequireCrossCert, "no-require-cross-certification", "@"),
+
+  /* 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_end ()
 };
 
 
@@ -719,12 +772,33 @@ static void print_mds( const char *fname, int algo );
 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);
+
 
-const char *
-strusage( int level )
+static char *
+make_libversion (const char *libname, const char *(*getfnc)(const char*))
 {
-  static char *digests, *pubkeys, *ciphers, *zips;
-    const char *p;
+  const char *s;
+  char *result;
+  
+  if (maybe_setuid)
+    {
+      gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
+      maybe_setuid = 0;
+    }
+  s = getfnc (NULL);
+  result = xmalloc (strlen (libname) + 1 + strlen (s) + 1);
+  strcpy (stpcpy (stpcpy (result, libname), " "), s);
+  return result;
+}
+
+
+static const char *
+my_strusage( int level )
+{
+  static char *digests, *pubkeys, *ciphers, *zips, *ver_gcry;
+  const char *p;
+
     switch( level ) {
       case 11: p = "gpg (GnuPG)";
        break;
@@ -734,14 +808,20 @@ strusage( int level )
            _("Please report bugs to <gnupg-bugs@gnu.org>.\n");
        break;
 
+    case 20:
+      if (!ver_gcry)
+        ver_gcry = make_libversion ("libgcrypt", gcry_check_version);
+      p = ver_gcry;
+      break;
+
 #ifdef IS_DEVELOPMENT_VERSION
-      case 20:
+      case 25:
        p="NOTE: THIS IS A DEVELOPMENT VERSION!";
        break;
-      case 21:
+      case 26:
        p="It is only intended for test purposes and should NOT be";
        break;
-      case 22:
+      case 27:
        p="used in a production environment or with production keys!";
        break;
 #endif
@@ -764,31 +844,35 @@ strusage( int level )
 #endif /* __riscos__ */
       case 33: p = _("\nSupported algorithms:\n"); break;
       case 34:
-       if( !pubkeys )
-           pubkeys = build_list(_("Pubkey: "), 0, pubkey_algo_to_string,
-                                                       check_pubkey_algo );
+       if (!pubkeys)
+            pubkeys = build_list (_("Pubkey: "), 0,
+                                  gcry_pk_algo_name,
+                                  openpgp_pk_test_algo );
        p = pubkeys;
        break;
       case 35:
        if( !ciphers )
-           ciphers = build_list(_("Cipher: "), 'S', cipher_algo_to_string,
-                                                       check_cipher_algo );
+           ciphers = build_list(_("Cipher: "), 'S', 
+                                 openpgp_cipher_algo_name,
+                                 openpgp_cipher_test_algo );
        p = ciphers;
        break;
       case 36:
        if( !digests )
-           digests = build_list(_("Hash: "), 'H', digest_algo_to_string,
-                                                       check_digest_algo );
+           digests = build_list(_("Hash: "), 'H', 
+                                 gcry_md_algo_name,
+                                 openpgp_md_test_algo );
        p = digests;
        break;
       case 37:
        if( !zips )
-           zips = build_list(_("Compression: "),'Z',compress_algo_to_string,
-                                                       check_compress_algo);
+           zips = build_list(_("Compression: "),'Z',
+                              compress_algo_to_string,
+                              check_compress_algo);
        p = zips;
        break;
 
-      default: p = default_strusage(level);
+      default: p = NULL;
     }
     return p;
 }
@@ -803,8 +887,8 @@ build_list( const char *text, char letter,
     size_t n=strlen(text)+2;
     char *list, *p, *line=NULL;
 
-    if( maybe_setuid )
-       secmem_init( 0 );    /* drop setuid */
+    if (maybe_setuid)
+      gcry_control (GCRYCTL_INIT_SECMEM, 0, 0);  /* Drop setuid. */
 
     for(i=0; i <= 110; i++ )
        if( !chkf(i) && (s=mapf(i)) )
@@ -850,20 +934,6 @@ build_list( const char *text, char letter,
 
 
 static void
-i18n_init(void)
-{
-#ifdef USE_SIMPLE_GETTEXT
-    set_gettext_file (PACKAGE, "Software\\GNU\\GnuPG");
-#else
-#ifdef ENABLE_NLS
-    setlocale( LC_ALL, "" );
-    bindtextdomain( PACKAGE, G10_LOCALEDIR );
-    textdomain( PACKAGE );
-#endif
-#endif
-}
-
-static void
 wrong_args( const char *text)
 {
     fputs(_("usage: gpg [options] "),stderr);
@@ -886,30 +956,65 @@ make_username( const char *string )
 
 
 static void
-set_debug(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
+   set. */
+static void
+set_debug (const char *level)
 {
-    if( opt.debug & DBG_MEMORY_VALUE )
-       memory_debug_mode = 1;
-    if( opt.debug & DBG_MEMSTAT_VALUE )
-       memory_stat_debug_mode = 1;
-    if( opt.debug & DBG_MPI_VALUE )
-       mpi_debug_mode = 1;
-    if( opt.debug & DBG_CIPHER_VALUE )
-       g10c_debug_mode = 1;
-    if( opt.debug & DBG_IOBUF_VALUE )
-       iobuf_debug_mode = 1;
+  if (!level)
+    ;
+  else if (!strcmp (level, "none"))
+    opt.debug = 0;
+  else if (!strcmp (level, "basic"))
+    opt.debug = DBG_MEMSTAT_VALUE;
+  else if (!strcmp (level, "advanced"))
+    opt.debug = DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE;
+  else if (!strcmp (level, "expert"))
+    opt.debug = (DBG_MEMSTAT_VALUE|DBG_TRUST_VALUE|DBG_EXTPROG_VALUE
+                 |DBG_CACHE_VALUE|DBG_FILTER_VALUE|DBG_PACKET_VALUE);
+  else if (!strcmp (level, "guru"))
+    opt.debug = ~0;
+  else
+    {
+      log_error (_("invalid debug-level `%s' given\n"), level);
+      g10_exit (2);
+    }
 
+  if (opt.debug & DBG_MEMORY_VALUE )
+    memory_debug_mode = 1;
+  if (opt.debug & DBG_MEMSTAT_VALUE )
+    memory_stat_debug_mode = 1;
+  if (opt.debug & DBG_MPI_VALUE)
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
+  if (opt.debug & DBG_CIPHER_VALUE )
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
+  if (opt.debug & DBG_IOBUF_VALUE )
+    iobuf_debug_mode = 1;
+  gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
 }
 
 
+
 /* We need the home directory also in some other directories, so make
    sure that both variables are always in sync. */
 static void
-set_homedir (char *dir)
+set_homedir (const char *dir)
 {
   if (!dir)
     dir = "";
-  g10_opt_homedir = opt.homedir = dir;
+  opt.homedir = dir;
 }
 
 
@@ -918,7 +1023,7 @@ set_homedir (char *dir)
 static void
 set_screen_dimensions(void)
 {
-#ifndef _WIN32
+#ifndef HAVE_W32_SYSTEM
   char *str;
 
   str=getenv("COLUMNS");
@@ -942,9 +1047,9 @@ set_screen_dimensions(void)
    used with --status-file etc functions.  Not generally useful but it
    avoids the riscos specific functions and well some Windows people
    might like it too.  Prints an error message and returns -1 on
-   error. On success the file descriptor is returned.  */
+   error.  On success the file descriptor is returned.  */
 static int
-open_info_file (const char *fname, int for_write)
+open_info_file (const char *fname, int for_write, int binary)
 {
 #ifdef __riscos__
   return riscos_fdopenfile (fname, for_write);
@@ -954,10 +1059,16 @@ open_info_file (const char *fname, int for_write)
      similar to the option file but in that case it is unlikely that
      sensitive information may be retrieved by means of error
      messages.  */
+  (void)fname;
+  (void)for_write;
+  (void)binary;
   return -1;
 #else 
   int fd;
 
+  if (binary)
+    binary = MY_O_BINARY;
+
 /*   if (is_secured_filename (fname)) */
 /*     { */
 /*       fd = -1; */
@@ -968,10 +1079,10 @@ open_info_file (const char *fname, int for_write)
       do
         {
           if (for_write)
-            fd = open (fname, O_CREAT | O_TRUNC | O_WRONLY,
+            fd = open (fname, O_CREAT | O_TRUNC | O_WRONLY | binary,
                         S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
           else
-            fd = open (fname, O_RDONLY | MY_O_BINARY);
+            fd = open (fname, O_RDONLY | binary);
         }
       while (fd == -1 && errno == EINTR);
 /*     } */
@@ -1002,8 +1113,6 @@ set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
        cmd = aEncrSym;
     else if( cmd == aEncr && new_cmd == aSym )
        cmd = aEncrSym;
-    else if( cmd == aKMode && new_cmd == aSym )
-       cmd = aKModeC;
     else if (cmd == aSignEncr && new_cmd == aSym)
         cmd = aSignEncrSym;
     else if (cmd == aSignSym && new_cmd == aEncr)
@@ -1118,7 +1227,7 @@ check_permissions(const char *path,int item)
       if(strchr(path,DIRSEP_C))
        tmppath=make_filename(path,NULL);
       else
-       tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
+       tmppath=make_filename(gnupg_libdir (),path,NULL);
     }
   else
     tmppath=xstrdup(path);
@@ -1309,6 +1418,24 @@ print_algo_numbers(int (*checker)(int))
 }
 
 
+static void
+print_algo_names(int (*checker)(int),const char *(*mapper)(int))
+{
+  int i,first=1;
+
+  for(i=0;i<=110;i++)
+    {
+      if(!checker(i))
+       {
+         if(first)
+           first=0;
+         else
+           printf(";");
+         printf("%s",mapper(i));
+       }
+    }
+}
+
 /* In the future, we can do all sorts of interesting configuration
    output here.  For now, just give "group" as the Enigmail folks need
    it, and pubkey, cipher, hash, and compress as they may be useful
@@ -1332,7 +1459,7 @@ list_config(char *items)
 
          for(iter=opt.grouplist;iter;iter=iter->next)
            {
-             STRLIST sl;
+             strlist_t sl;
 
              printf("cfg:group:");
              print_string(stdout,iter->name,strlen(iter->name),':');
@@ -1340,7 +1467,7 @@ list_config(char *items)
 
              for(sl=iter->values;sl;sl=sl->next)
                {
-                 print_string2(stdout,sl->d,strlen(sl->d),':',';');
+                 print_sanitized_string2 (stdout, sl->d, ':',';');
                  if(sl->next)
                    printf(";");
                }
@@ -1362,7 +1489,7 @@ list_config(char *items)
       if(show_all || ascii_strcasecmp(name,"pubkey")==0)
        {
          printf("cfg:pubkey:");
-         print_algo_numbers(check_pubkey_algo);
+         print_algo_numbers (openpgp_pk_test_algo);
          printf("\n");
          any=1;
        }
@@ -1370,21 +1497,39 @@ list_config(char *items)
       if(show_all || ascii_strcasecmp(name,"cipher")==0)
        {
          printf("cfg:cipher:");
-         print_algo_numbers(check_cipher_algo);
+         print_algo_numbers(openpgp_cipher_test_algo);
          printf("\n");
          any=1;
        }
 
+      if (show_all || !ascii_strcasecmp (name,"ciphername"))
+       {
+         printf ("cfg:ciphername:");
+         print_algo_names (openpgp_cipher_test_algo,openpgp_cipher_algo_name);
+         printf ("\n");
+         any = 1;
+       }
+
       if(show_all
         || ascii_strcasecmp(name,"digest")==0
         || ascii_strcasecmp(name,"hash")==0)
        {
          printf("cfg:digest:");
-         print_algo_numbers(check_digest_algo);
+         print_algo_numbers(openpgp_md_test_algo);
          printf("\n");
          any=1;
        }
 
+      if (show_all
+          || !ascii_strcasecmp(name,"digestname")
+          || !ascii_strcasecmp(name,"hashname"))
+       {
+         printf ("cfg:digestname:");
+         print_algo_names (openpgp_md_test_algo, gcry_md_algo_name);
+         printf("\n");
+         any=1;
+       }
+      
       if(show_all || ascii_strcasecmp(name,"compress")==0)
        {
          printf("cfg:compress:");
@@ -1395,7 +1540,9 @@ list_config(char *items)
 
       if(show_all || ascii_strcasecmp(name,"ccid-reader-id")==0)
        {
-#if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB)
+#if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB) \
+    && GNUPG_MAJOR_VERSION == 1
+
           char *p, *p2, *list = ccid_get_reader_list ();
 
           for (p=list; p && (p2 = strchr (p, '\n')); p = p2+1)
@@ -1425,16 +1572,22 @@ list_config(char *items)
 static void
 gpgconf_list (const char *configfile)
 {
-  /* The following definitions are taken from gnupg/tools/gpgconf-comp.c.  */
-#define GC_OPT_FLAG_NONE       0UL
-#define GC_OPT_FLAG_DEFAULT    (1UL << 4)
+  char *configfile_esc = percent_escape (configfile, NULL);
 
   printf ("gpgconf-gpg.conf:%lu:\"%s\n",
-          GC_OPT_FLAG_DEFAULT,configfile?configfile:"/dev/null");
+          GC_OPT_FLAG_DEFAULT, configfile_esc ? configfile_esc : "/dev/null");
   printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
   printf ("quiet:%lu:\n",   GC_OPT_FLAG_NONE);
   printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE);
   printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE);
+  printf ("default-key:%lu:\n", GC_OPT_FLAG_NONE);
+  printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE);
+  printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE);
+  printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
+  printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
+  printf ("group:%lu:\n", GC_OPT_FLAG_NONE);
+
+  xfree (configfile_esc);
 }
 
 
@@ -1604,8 +1757,112 @@ parse_trust_model(const char *model)
     log_error("unknown trust model `%s'\n",model);
 }
 
+
+/* Pack an s2k iteration count into the form specified in 2440.  If
+   we're in between valid values, round up. */
+static unsigned char
+encode_s2k_iterations(int iterations)
+{
+  unsigned char c=0,result;
+  unsigned int count;
+
+  if(iterations<=1024)
+    return 0;
+
+  if(iterations>=65011712)
+    return 255;
+
+  /* Need count to be in the range 16-31 */
+  for(count=iterations>>6;count>=32;count>>=1)
+    c++;
+
+  result=(c<<4)|(count-16);
+
+  if(S2K_DECODE_COUNT(result)<iterations)
+    result++;
+
+  return result;
+}
+
+
+/* This fucntion 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;
+}
+
+
+/* This function is called to deinitialize a control object.  It is
+   not deallocated. */
+static void
+gpg_deinit_default_ctrl (ctrl_t ctrl)
+{
+  (void)ctrl;
+}
+
+
+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-")];
+
+  do
+    {
+      if (configname)
+       {
+         char *tok;
+         
+         xfree (configname);
+         configname = NULL;
+
+         if ((tok = strrchr (ver, SAFE_VERSION_DASH)))
+           *tok='\0';
+         else if ((tok = strrchr (ver, SAFE_VERSION_DOT)))
+           *tok='\0';
+         else
+           break;
+       }
+      
+      configname = make_filename (opt.homedir, name, NULL);
+    }
+  while (access (configname, R_OK));
+
+  xfree(name);
+  
+  if (! configname)
+    configname = make_filename (opt.homedir, "gpg" 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);
+      if (! access (p, R_OK))
+       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);
+      if (!access (p, R_OK))
+       {
+         xfree (configname);
+         configname = p;
+       }
+      else
+       xfree (p);
+    }
+
+  return configname;
+}
+
+
 int
-main (int argc, char **argv )
+main (int argc, char **argv)
 {
     ARGPARSE_ARGS pargs;
     IOBUF a;
@@ -1615,21 +1872,24 @@ main (int argc, char **argv )
     const char *fname;
     char *username;
     int may_coredump;
-    STRLIST sl, remusr= NULL, locusr=NULL;
-    STRLIST nrings=NULL, sec_nrings=NULL;
-    armor_filter_context_t afx;
+    strlist_t sl, remusr= NULL, locusr=NULL;
+    strlist_t nrings=NULL, sec_nrings=NULL;
+    armor_filter_context_t *afx = NULL;
     int detached_sig = 0;
     FILE *configfp = NULL;
     char *configname = NULL;
     char *save_configname = NULL;
+    char *default_configname = NULL;
     unsigned configlineno;
     int parse_debug = 0;
     int default_config = 1;
     int default_keyring = 1;
     int greeting = 0;
     int nogreeting = 0;
+    char *logfile = NULL;
     int use_random_seed = 1;
     enum cmd_and_opt_values cmd = 0;
+    const char *debug_level = NULL;
     const char *trustdb_name = NULL;
     char *def_cipher_string = NULL;
     char *def_digest_string = NULL;
@@ -1643,29 +1903,54 @@ main (int argc, char **argv )
     int eyes_only=0;
     int multifile=0;
     int pwfd = -1;
-    int with_fpr = 0; /* make an option out of --fingerprint */
+    int fpr_maybe_cmd = 0; /* --fingerprint maybe a command.  */
     int any_explicit_recipient = 0;
     int require_secmem=0,got_secmem=0;
-#ifdef USE_SHM_COPROCESSING
-    ulong requested_shm_size=0;
-#endif
 
 #ifdef __riscos__
     opt.lock_once = 1;
 #endif /* __riscos__ */
 
-    trap_unaligned();
-    secmem_set_flags( secmem_get_flags() | 2 ); /* suspend warnings */
+
     /* 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
-     */
-    log_set_name("gpg");
-    secure_randoxmalloc(); /* put random number into secure memory */
-    may_coredump = disable_core_dumps();
-    init_signals();
-    create_dotlock(NULL); /* register locking cleanup */
+       when adding any stuff between here and the call to
+       secmem_init() somewhere after the option parsing. */
+    gnupg_reopen_std ("gpg");
+    trap_unaligned ();
+    gnupg_rl_initialize ();
+    set_strusage (my_strusage);
+    gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
+    /* We don't need any locking in libgcrypt unless we use any kind of
+       threading. */
+    gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING);
+    log_set_prefix ("gpg", 1);
+
+    /* Make sure that our subsystems are ready.  */
     i18n_init();
+    init_common_subsystems ();
+
+    /* 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) );
+      }
+
+    /* Put random number into secure memory */
+    gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
+
+    may_coredump = disable_core_dumps();
+
+    gnupg_init_signals (0, emergency_cleanup);
+
+    create_dotlock(NULL); /* Register locking cleanup. */
+
+    opt.session_env = session_env_new ();
+    if (!opt.session_env)
+      log_fatal ("error allocating session environment block: %s\n",
+                 strerror (errno));
+
     opt.command_fd = -1; /* no command fd */
     opt.compress_level = -1; /* defaults to standard compress level */
     opt.bz2_compress_level = -1; /* defaults to standard compress level */
@@ -1675,6 +1960,7 @@ main (int argc, char **argv )
     opt.cert_digest_algo = 0;
     opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */
     opt.s2k_mode = 3; /* iterated+salted */
+    opt.s2k_count = 96; /* 65536 iterations */
 #ifdef USE_CAST5
     opt.s2k_cipher_algo = CIPHER_ALGO_CAST5;
 #else
@@ -1684,14 +1970,14 @@ main (int argc, char **argv )
     opt.marginals_needed = 3;
     opt.max_cert_depth = 5;
     opt.pgp2_workarounds = 1;
-    opt.force_v3_sigs = 1;
     opt.escape_from = 1;
+    opt.flags.require_cross_cert = 1;
     opt.import_options=IMPORT_SK2PK;
     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_INCLUDE_SUBKEYS|KEYSERVER_INCLUDE_REVOKED|KEYSERVER_TRY_DNS_SRV|KEYSERVER_HONOR_KEYSERVER_URL;
+      KEYSERVER_HONOR_KEYSERVER_URL|KEYSERVER_HONOR_PKA_RECORD;
     opt.verify_options=
       VERIFY_SHOW_POLICY_URLS|VERIFY_SHOW_STD_NOTATIONS|VERIFY_SHOW_KEYSERVER_URLS;
     opt.trust_model=TM_AUTO;
@@ -1699,20 +1985,12 @@ main (int argc, char **argv )
     opt.min_cert_level=2;
     set_screen_dimensions();
     opt.keyid_format=KF_SHORT;
-    opt.rfc2440_text=1;
     opt.def_sig_expire="0";
     opt.def_cert_expire="0";
     set_homedir ( default_homedir () );
+    opt.passwd_repeat=1;
 
-#ifdef ENABLE_CARD_SUPPORT
-# ifdef _WIN32
-    opt.pcsc_driver = "winscard.dll"; 
-#else
-    opt.pcsc_driver = "libpcsclite.so"; 
-#endif
-#endif /*ENABLE_CARD_SUPPORT*/
-
-    /* check whether we have a config file on the commandline */
+    /* Check whether we have a config file on the command line.  */
     orig_argc = argc;
     orig_argv = argv;
     pargs.argc = &argc;
@@ -1728,34 +2006,22 @@ main (int argc, char **argv )
            default_config = 0;
        }
        else if( pargs.r_opt == oNoOptions )
+          {
            default_config = 0; /* --no-options */
-       else if( pargs.r_opt == oHomedir )
+            opt.no_homedir_creation = 1;
+          }
+        else if( pargs.r_opt == oHomedir )
            set_homedir ( pargs.r.ret_str );
        else if( pargs.r_opt == oNoPermissionWarn )
            opt.no_perm_warn=1;
        else if (pargs.r_opt == oStrict )
          {
-           opt.strict=1;
-           log_set_strict(1);
+           /* Not used */
          }
        else if (pargs.r_opt == oNoStrict )
          {
-           opt.strict=0;
-           log_set_strict(0);
+           /* Not used */
          }
-#ifdef USE_SHM_COPROCESSING
-       else if( pargs.r_opt == oRunAsShmCP ) {
-           /* does not make sense in a options file, we do it here,
-            * so that we are the able to drop setuid as soon as possible */
-           opt.shm_coprocess = 1;
-           requested_shm_size = pargs.r.ret_ulong;
-       }
-       else if ( pargs.r_opt == oStatusFD ) {
-           /* this is needed to ensure that the status-fd filedescriptor is
-            * initialized when init_shm_coprocessing() is called */
-           set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) );
-       }
-#endif
     }
 
 #ifdef HAVE_DOSISH_SYSTEM
@@ -1763,74 +2029,41 @@ main (int argc, char **argv )
         char *d, *buf = xmalloc (strlen (opt.homedir)+1);
         const char *s = opt.homedir;
         for (d=buf,s=opt.homedir; *s; s++)
+          {
             *d++ = *s == '\\'? '/': *s;
+#ifdef HAVE_W32_SYSTEM
+            if (s[1] && IsDBCSLeadByte (*s))
+              *d++ = *++s;
+#endif
+          }
         *d = 0;
         set_homedir (buf);
     }
 #endif
-#ifdef USE_SHM_COPROCESSING
-    if( opt.shm_coprocess ) {
-       init_shm_coprocessing(requested_shm_size, 1 );
-    }
-#endif
-    /* initialize the secure memory. */
-    got_secmem=secmem_init( 32768 );
-    maybe_setuid = 0;
-    /* Okay, we are now working under our real uid */
 
+    /* Initialize the secure memory. */
+    if (!gcry_control (GCRYCTL_INIT_SECMEM, 32768, 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. */
-    if(getuid()!=geteuid())
-      BUG();
+    if ( getuid () != geteuid () )
+      BUG ();
 #endif
+    maybe_setuid = 0;
 
-    set_native_charset (NULL); /* Try to auto set the character set */
-
-    /* Try for a version specific config file first */
-    if( default_config )
-      {
-       char *name=xstrdup("gpg" EXTSEP_S "conf-" SAFE_VERSION);
-       char *ver=&name[strlen("gpg" EXTSEP_S "conf-")];
-
-       do
-         {
-           if(configname)
-             {
-               char *tok;
+    /* Okay, we are now working under our real uid */
 
-               xfree(configname);
-               configname=NULL;
+    /* malloc hooks go here ... */
+    assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
+    assuan_set_assuan_err_source (GPG_ERR_SOURCE_DEFAULT);
 
-               if((tok=strrchr(ver,SAFE_VERSION_DASH)))
-                 *tok='\0';
-               else if((tok=strrchr(ver,SAFE_VERSION_DOT)))
-                 *tok='\0';
-               else
-                 break;
-             }
+    /* Try for a version specific config file first */
+    default_configname = get_default_configname ();
+    if (default_config)
+      configname = xstrdup (default_configname);
 
-           configname = make_filename(opt.homedir,name,NULL);
-         }
-       while(access(configname,R_OK));
-
-       xfree(name);
-
-       if(!configname)
-         configname=make_filename(opt.homedir, "gpg" 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 );
-            if (!access (p, R_OK))
-              log_info (_("NOTE: old default options file `%s' ignored\n"), p);
-            xfree (p);
-          }
-        else
-          { /* Keep on using the old default one. */
-            xfree (configname);
-            configname = make_filename(opt.homedir, "options", NULL );
-          }
-      }
     argc = orig_argc;
     argv = orig_argv;
     pargs.argc = &argc;
@@ -1887,6 +2120,7 @@ main (int argc, char **argv )
          case aCheckKeys: 
          case aListConfig:
           case aGPGConfList:
+          case aGPGConfTest:
          case aListPackets:
          case aImport: 
          case aFastImport: 
@@ -1894,25 +2128,53 @@ main (int argc, char **argv )
          case aRecvKeys: 
          case aSearchKeys:
          case aRefreshKeys:
+         case aFetchKeys:
          case aExport: 
+#ifdef ENABLE_CARD_SUPPORT
+          case aCardStatus:
+          case aCardEdit: 
+          case aChangePIN:
+#endif /* ENABLE_CARD_SUPPORT*/
+         case aListKeys: 
+         case aLocateKeys:
+         case aListSigs: 
+         case aExportSecret: 
+         case aExportSecretSub: 
+         case aSym:
+         case aClearsign: 
+         case aGenRevoke: 
+         case aDesigRevoke: 
+         case aPrimegen: 
+         case aGenRandom:
+         case aPrintMD:
+         case aPrintMDs: 
+         case aListTrustDB: 
+         case aCheckTrustDB:
+         case aUpdateTrustDB: 
+         case aFixTrustDB: 
+         case aListTrustPath: 
+         case aDeArmor: 
+         case aEnArmor: 
+         case aSign: 
+         case aSignKey: 
+         case aLSignKey:
+         case aStore: 
+         case aExportOwnerTrust: 
+         case aImportOwnerTrust: 
+          case aRebuildKeydbCaches:
             set_cmd (&cmd, pargs.r_opt);
             break;
-         case aListKeys: set_cmd( &cmd, aListKeys); break;
-         case aListSigs: set_cmd( &cmd, aListSigs); break;
-         case aExportSecret: set_cmd( &cmd, aExportSecret); break;
-         case aExportSecretSub: set_cmd( &cmd, aExportSecretSub); break;
+
+         case aKeygen: 
+         case aEditKey:
          case aDeleteSecretKeys:
-           set_cmd( &cmd, aDeleteSecretKeys);
-           greeting=1;
-           break;
          case aDeleteSecretAndPublicKeys:
-            set_cmd( &cmd, aDeleteSecretAndPublicKeys);
-            greeting=1; 
+         case aDeleteKeys:
+            set_cmd (&cmd, pargs.r_opt);
+            greeting=1;
             break;
-         case aDeleteKeys: set_cmd( &cmd, aDeleteKeys); greeting=1; break;
 
          case aDetachedSign: detached_sig = 1; set_cmd( &cmd, aSign ); break;
-         case aSym: set_cmd( &cmd, aSym); break;
 
          case aDecryptFiles: multifile=1; /* fall through */
          case aDecrypt: set_cmd( &cmd, aDecrypt); break;
@@ -1923,49 +2185,10 @@ main (int argc, char **argv )
          case aVerifyFiles: multifile=1; /* fall through */
          case aVerify: set_cmd( &cmd, aVerify); break;
 
-         case aSign: set_cmd( &cmd, aSign );  break;
-         case aKeygen: set_cmd( &cmd, aKeygen); greeting=1; break;
-         case aSignKey: set_cmd( &cmd, aSignKey); break;
-         case aLSignKey: set_cmd( &cmd, aLSignKey); break;
-         case aStore: set_cmd( &cmd, aStore); break;
-         case aEditKey: set_cmd( &cmd, aEditKey); greeting=1; break;
-         case aClearsign: set_cmd( &cmd, aClearsign); break;
-         case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
-         case aDesigRevoke: set_cmd( &cmd, aDesigRevoke); break;
-         case aPrimegen: set_cmd( &cmd, aPrimegen); break;
-         case aGenRandom: set_cmd( &cmd, aGenRandom); break;
-         case aPrintMD: set_cmd( &cmd, aPrintMD); break;
-         case aPrintMDs: set_cmd( &cmd, aPrintMDs); break;
-         case aListTrustDB: set_cmd( &cmd, aListTrustDB); break;
-         case aCheckTrustDB: set_cmd( &cmd, aCheckTrustDB); break;
-         case aUpdateTrustDB: set_cmd( &cmd, aUpdateTrustDB); break;
-         case aFixTrustDB: set_cmd( &cmd, aFixTrustDB); break;
-         case aListTrustPath: set_cmd( &cmd, aListTrustPath); break;
-         case aDeArmor: set_cmd( &cmd, aDeArmor); break;
-         case aEnArmor: set_cmd( &cmd, aEnArmor); break;
-         case aListOwnerTrust:
-           deprecated_warning(configname,configlineno,
-                              "--list-ownertrust","--export-ownertrust","");
-         case aExportOwnerTrust: set_cmd( &cmd, aExportOwnerTrust); break;
-         case aImportOwnerTrust: set_cmd( &cmd, aImportOwnerTrust); break;
-          case aPipeMode:
-           deprecated_command ("--pipemode");
-            set_cmd( &cmd, aPipeMode);
-            break;
-
-          case aRebuildKeydbCaches: set_cmd( &cmd, aRebuildKeydbCaches); break;
-
-#ifdef ENABLE_CARD_SUPPORT
-          case aCardStatus: set_cmd (&cmd, aCardStatus); break;
-          case aCardEdit: set_cmd (&cmd, aCardEdit); break;
-          case aChangePIN: set_cmd (&cmd, aChangePIN); break;
-          case oReaderPort:
-            card_set_reader_port (pargs.r.ret_str);
+          case aServer:
+            set_cmd (&cmd, pargs.r_opt);
+            opt.batch = 1;
             break;
-          case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break;
-          case opcscDriver: opt.pcsc_driver = pargs.r.ret_str; break;
-          case oDisableCCID: opt.disable_ccid = 1; break;
-#endif /* ENABLE_CARD_SUPPORT*/
 
          case oArmor: opt.armor = 1; opt.no_armor=0; break;
          case oOutput: opt.outfile = pargs.r.ret_str; break;
@@ -1975,24 +2198,26 @@ main (int argc, char **argv )
          case oDryRun: opt.dry_run = 1; break;
          case oInteractive: opt.interactive = 1; break;
          case oVerbose:
-           g10_opt_verbose++;
            opt.verbose++;
+            gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
            opt.list_options|=LIST_SHOW_UNUSABLE_UIDS;
            opt.list_options|=LIST_SHOW_UNUSABLE_SUBKEYS;
            break;
-         case oKOption: set_cmd( &cmd, aKMode ); break;
 
-         case oBatch: opt.batch = 1; nogreeting = 1; break;
-          case oUseAgent:
-#ifndef __riscos__
-            opt.use_agent = 1;
-#else /* __riscos__ */
-            opt.use_agent = 0;
-            riscos_not_implemented("use-agent");
-#endif /* __riscos__ */
+         case oBatch:
+            opt.batch = 1;
+            nogreeting = 1;
+            break;
+
+          case oUseAgent: /* Dummy. */
+            break;
+          case oNoUseAgent:
+           obsolete_option (configname, configlineno, "--no-use-agent");
+            break;
+         case oGpgAgentInfo: 
+           obsolete_option (configname, configlineno, "--gpg-agent-info");
             break;
-          case oNoUseAgent: opt.use_agent = 0; break;
-         case oGpgAgentInfo: opt.gpg_agent_info = pargs.r.ret_str; 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;
@@ -2005,37 +2230,39 @@ main (int argc, char **argv )
                               "--list-options ","show-keyring");
            opt.list_options|=LIST_SHOW_KEYRING;
            break;
+
          case oDebug: opt.debug |= pargs.r.ret_ulong; break;
          case oDebugAll: opt.debug = ~0; break;
-          case oDebugCCIDDriver: 
-#if defined(ENABLE_CARD_SUPPORT) && defined(HAVE_LIBUSB)
-            ccid_set_debug_level (ccid_set_debug_level (1)+1);
-#endif
-            break;
+          case oDebugLevel: debug_level = pargs.r.ret_str; break;
+
          case oStatusFD:
-            set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) );
+            set_status_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) );
             break;
          case oStatusFile:
-            set_status_fd ( open_info_file (pargs.r.ret_str, 1) );
+            set_status_fd ( open_info_file (pargs.r.ret_str, 1, 0) );
             break;
          case oAttributeFD:
-            set_attrib_fd(iobuf_translate_file_handle (pargs.r.ret_int, 1));
+            set_attrib_fd ( translate_sys2libc_fd_int (pargs.r.ret_int, 1) );
             break;
          case oAttributeFile:
-            set_attrib_fd ( open_info_file (pargs.r.ret_str, 1) );
+            set_attrib_fd ( open_info_file (pargs.r.ret_str, 1, 1) );
             break;
          case oLoggerFD:
-            log_set_logfile( NULL,
-                             iobuf_translate_file_handle (pargs.r.ret_int, 1));
+            log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1));
             break;
-         case oLoggerFile:
-            log_set_logfile( NULL, open_info_file (pargs.r.ret_str, 1) );
+          case oLoggerFile:
+            logfile = pargs.r.ret_str;
             break;
 
          case oWithFingerprint:
             opt.with_fingerprint = 1;
-            with_fpr=1; /*fall thru*/
-         case oFingerprint: opt.fingerprint++; break;
+            opt.fingerprint++;
+            break;
+         case oFingerprint:
+            opt.fingerprint++;
+            fpr_maybe_cmd = 1;
+            break;
+
          case oSecretKeyring:
             append_to_strlist( &sec_nrings, pargs.r.ret_str);
             break;
@@ -2050,9 +2277,14 @@ main (int argc, char **argv )
          case oNoArmor: opt.no_armor=1; opt.armor=0; break;
          case oNoDefKeyring: default_keyring = 0; break;
          case oNoGreeting: nogreeting = 1; break;
-         case oNoVerbose: g10_opt_verbose = 0;
-                          opt.verbose = 0; opt.list_sigs=0; break;
-         case oQuickRandom: quick_random_gen(1); break;
+         case oNoVerbose: 
+            opt.verbose = 0;
+            gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
+            opt.list_sigs=0;
+            break;
+          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 oCompletesNeeded: opt.completes_needed = pargs.r.ret_int; break;
@@ -2061,23 +2293,27 @@ main (int argc, char **argv )
          case oTrustDBName: trustdb_name = pargs.r.ret_str; break;
          case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break;
          case oDefRecipient:
-                   if( *pargs.r.ret_str )
-                       opt.def_recipient = make_username(pargs.r.ret_str);
-                   break;
+            if( *pargs.r.ret_str )
+              opt.def_recipient = make_username(pargs.r.ret_str);
+            break;
          case oDefRecipientSelf:
-                   xfree(opt.def_recipient); opt.def_recipient = NULL;
-                   opt.def_recipient_self = 1;
-                   break;
+            xfree(opt.def_recipient); opt.def_recipient = NULL;
+            opt.def_recipient_self = 1;
+            break;
          case oNoDefRecipient:
-                   xfree(opt.def_recipient); opt.def_recipient = NULL;
-                   opt.def_recipient_self = 0;
-                   break;
+            xfree(opt.def_recipient); opt.def_recipient = NULL;
+            opt.def_recipient_self = 0;
+            break;
          case oNoOptions: opt.no_homedir_creation = 1; break; /* no-options */
          case oHomedir: break;
          case oNoBatch: opt.batch = 0; break;
-         case oWithKeyData: opt.with_key_data=1; /* fall thru */
+
+         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 oSkipVerify: opt.skip_verify=1; break;
          case oCompressKeys: opt.compress_keys = 1; break;
          case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
@@ -2099,18 +2335,8 @@ main (int argc, char **argv )
              }
            break;
          case oLoadExtension:
-#ifndef __riscos__
-#if defined(USE_DYNAMIC_LINKING) || defined(_WIN32)
-           if(check_permissions(pargs.r.ret_str,2))
-             log_info(_("cipher extension `%s' not loaded due to"
-                        " unsafe permissions\n"),pargs.r.ret_str);
-           else
-             register_cipher_extension(orig_argc? *orig_argv:NULL,
-                                       pargs.r.ret_str);
-#endif
-#else /* __riscos__ */
-            riscos_not_implemented("load-extension");
-#endif /* __riscos__ */
+            /* Dummy so that gpg 1.4 conf files can work. Should
+               eventually be removed.  */
            break;
          case oRFC1991:
            opt.compliance = CO_RFC1991;
@@ -2118,11 +2344,34 @@ main (int argc, char **argv )
            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:
-           /* TODO: When 2440bis becomes a RFC, set new values for
-              oOpenPGP. */
-           opt.rfc2440_text=1;
            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;
@@ -2147,18 +2396,12 @@ main (int argc, char **argv )
          case oCompressSigs: opt.compress_sigs = 1; break;
          case oRFC2440Text: opt.rfc2440_text=1; break;
          case oNoRFC2440Text: opt.rfc2440_text=0; break;
-         case oRunAsShmCP:
-#ifndef __riscos__
-# ifndef USE_SHM_COPROCESSING
-           /* not possible in the option file,
-            * but we print the warning here anyway */
-           log_error("shared memory coprocessing is not available\n");
-# endif
-#else /* __riscos__ */
-            riscos_not_implemented("run-as-shm-coprocess");
-#endif /* __riscos__ */
-           break;
-         case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
+         case oSetFilename:
+            if(utf8_strings)
+              opt.set_filename = pargs.r.ret_str;
+            else
+              opt.set_filename = native_to_utf8(pargs.r.ret_str);
+           break;
          case oForYourEyesOnly: eyes_only = 1; break;
          case oNoForYourEyesOnly: eyes_only = 0; break;
          case oSetPolicyURL:
@@ -2184,8 +2427,12 @@ main (int argc, char **argv )
            opt.verify_options&=~VERIFY_SHOW_POLICY_URLS;
            break;
          case oSigKeyserverURL: add_keyserver_url(pargs.r.ret_str,0); break;
-         case oUseEmbeddedFilename: opt.use_embedded_filename = 1; break;
-         case oNoUseEmbeddedFilename: opt.use_embedded_filename = 0; break;
+         case oUseEmbeddedFilename:
+           opt.flags.use_embedded_filename=1;
+           break;
+         case oNoUseEmbeddedFilename:
+           opt.flags.use_embedded_filename=0;
+           break;
          case oComment:
            if(pargs.r.ret_str[0])
              append_to_strlist(&opt.comments,pargs.r.ret_str);
@@ -2228,6 +2475,9 @@ main (int argc, char **argv )
          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;
+         case oS2KCount:
+           opt.s2k_count=encode_s2k_iterations(pargs.r.ret_int);
+           break;
           case oSimpleSKChecksum: opt.simple_sk_checksum = 1; break;
          case oNoEncryptTo: opt.no_encrypt_to = 1; break;
          case oEncryptTo: /* store the recipient in the second list */
@@ -2294,17 +2544,17 @@ main (int argc, char **argv )
            set_passphrase_from_string(pargs.r.ret_str);
            break;
          case oPasswdFD:
-            pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
-            opt.use_agent = 0;
+            pwfd = translate_sys2libc_fd_int (pargs.r.ret_int, 0);
             break;
          case oPasswdFile:
-            pwfd = open_info_file (pargs.r.ret_str, 0);
+            pwfd = open_info_file (pargs.r.ret_str, 0, 1);
             break;
+         case oPasswdRepeat: opt.passwd_repeat=pargs.r.ret_int; break;
          case oCommandFD:
-            opt.command_fd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
+            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);
+            opt.command_fd = open_info_file (pargs.r.ret_str, 0, 1);
             break;
          case oCipherAlgo: 
             def_cipher_string = xstrdup(pargs.r.ret_str);
@@ -2336,8 +2586,14 @@ main (int argc, char **argv )
                compress_algo_string = xstrdup(pargs.r.ret_str);
            }
            break;
-         case oCertDigestAlgo: cert_digest_string = xstrdup(pargs.r.ret_str); break;
-         case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
+         case oCertDigestAlgo: 
+            cert_digest_string = xstrdup(pargs.r.ret_str);
+            break;
+
+         case oNoSecmemWarn: 
+            gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); 
+            break;
+
          case oRequireSecmem: require_secmem=1; break;
          case oNoRequireSecmem: require_secmem=0; break;
          case oNoPermissionWarn: opt.no_perm_warn=1; break;
@@ -2351,7 +2607,9 @@ main (int argc, char **argv )
          case oEscapeFrom: opt.escape_from = 1; break;
          case oNoEscapeFrom: opt.escape_from = 0; break;
          case oLockOnce: opt.lock_once = 1; break;
-         case oLockNever: disable_dotlock(); break;
+         case oLockNever:
+            disable_dotlock ();
+            break;
          case oLockMultiple:
 #ifndef __riscos__
            opt.lock_once = 0;
@@ -2360,10 +2618,18 @@ main (int argc, char **argv )
 #endif /* __riscos__ */
             break;
          case oKeyServer:
-           opt.keyserver=parse_keyserver_uri(pargs.r.ret_str,0,
-                                             configname,configlineno);
-           if(!opt.keyserver)
-             log_error(_("could not parse keyserver URL\n"));
+           {
+             struct keyserver_spec *keyserver;
+             keyserver=parse_keyserver_uri(pargs.r.ret_str,0,
+                                           configname,configlineno);
+             if(!keyserver)
+               log_error(_("could not parse keyserver URL\n"));
+             else
+               {
+                 keyserver->next=opt.keyserver;
+                 opt.keyserver=keyserver;
+               }
+           }
            break;
          case oKeyServerOptions:
            if(!parse_keyserver_options(pargs.r.ret_str))
@@ -2427,6 +2693,12 @@ main (int argc, char **argv )
                   N_("show user ID validity during signature verification")},
                  {"show-unusable-uids",VERIFY_SHOW_UNUSABLE_UIDS,NULL,
                   N_("show revoked and expired user IDs in signature verification")},
+                 {"show-primary-uid-only",VERIFY_SHOW_PRIMARY_UID_ONLY,NULL,
+                  N_("show only the primary user ID in signature verification")},
+                 {"pka-lookups",VERIFY_PKA_LOOKUPS,NULL,
+                  N_("validate signatures with PKA data")},
+                 {"pka-trust-increase",VERIFY_PKA_TRUST_INCREASE,NULL,
+                  N_("elevate the trust of signatures with valid PKA data")},
                  {NULL,0,NULL,NULL}
                };
 
@@ -2472,11 +2744,17 @@ main (int argc, char **argv )
          case oUtf8Strings: utf8_strings = 1; break;
          case oNoUtf8Strings: utf8_strings = 0; break;
          case oDisableCipherAlgo:
-               disable_cipher_algo( string_to_cipher_algo(pargs.r.ret_str) );
-               break;
+            {
+              int algo = string_to_cipher_algo (pargs.r.ret_str);
+              gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
+            }
+            break;
          case oDisablePubkeyAlgo:
-               disable_pubkey_algo( string_to_pubkey_algo(pargs.r.ret_str) );
-               break;
+            {
+              int algo = gcry_pk_map_name (pargs.r.ret_str);
+              gcry_pk_ctl (GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
+            }
+            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;
@@ -2492,7 +2770,7 @@ main (int argc, char **argv )
                                   "--keyserver-options ","http-proxy");
                break;
          case oFastListMode: opt.fast_list_mode = 1; break;
-         case oFixedListMode: opt.fixed_list_mode = 1; break;
+         case oFixedListMode: /* Dummy */ break;
          case oListOnly: opt.list_only=1; break;
          case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
          case oIgnoreValidFrom: opt.ignore_valid_from = 1; break;
@@ -2534,6 +2812,19 @@ main (int argc, char **argv )
           case oDefaultPreferenceList:
            opt.def_preference_list = pargs.r.ret_str;
            break;
+         case oDefaultKeyserverURL:
+           {
+             struct keyserver_spec *keyserver;
+             keyserver=parse_keyserver_uri(pargs.r.ret_str,1,
+                                           configname,configlineno);
+             if(!keyserver)
+               log_error(_("could not parse keyserver URL\n"));
+             else
+               free_keyserver_spec(keyserver);
+
+             opt.def_keyserver_url = pargs.r.ret_str;
+           }
+           break;
           case oPersonalCipherPreferences:
            pers_cipher_list=pargs.r.ret_str;
            break;
@@ -2543,11 +2834,24 @@ main (int argc, char **argv )
           case oPersonalCompressPreferences:
            pers_compress_list=pargs.r.ret_str;
            break;
-          case oDisplay: opt.display = pargs.r.ret_str; break;
-          case oTTYname: opt.ttyname = pargs.r.ret_str; break;
-          case oTTYtype: opt.ttytype = pargs.r.ret_str; break;
+          case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
+
+          case oDisplay:
+            set_opt_session_env ("DISPLAY", pargs.r.ret_str);
+            break;
+          case oTTYname:
+            set_opt_session_env ("GPG_TTY", pargs.r.ret_str);
+            break;
+          case oTTYtype:
+            set_opt_session_env ("TERM", pargs.r.ret_str);
+            break;
+          case oXauthority:
+            set_opt_session_env ("XAUTHORITY", pargs.r.ret_str);
+            break;
+
           case oLCctype: opt.lc_ctype = pargs.r.ret_str; break;
           case oLCmessages: opt.lc_messages = pargs.r.ret_str; break;
+
          case oGroup: add_group(pargs.r.ret_str); break;
          case oUnGroup: rm_group(pargs.r.ret_str); break;
          case oNoGroups:
@@ -2559,8 +2863,12 @@ main (int argc, char **argv )
                xfree(iter);
              }
            break;
-         case oStrict: opt.strict=1; log_set_strict(1); break;
-         case oNoStrict: opt.strict=0; log_set_strict(0); break;
+
+         case oStrict: 
+         case oNoStrict: 
+           /* Not used */
+            break;
+
           case oMangleDosFilenames: opt.mangle_dos_filenames = 1; break;
           case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break;
           case oEnableProgressFilter: opt.enable_progress_filter = 1; break;
@@ -2586,10 +2894,40 @@ main (int argc, char **argv )
             opt.limit_card_insert_tries = pargs.r.ret_int; 
             break;
 
-  
+         case oRequireCrossCert: opt.flags.require_cross_cert=1; break;
+         case oNoRequireCrossCert: opt.flags.require_cross_cert=0; break;
+
+         case oAutoKeyLocate:
+           if(!parse_auto_key_locate(pargs.r.ret_str))
+             {
+               if(configname)
+                 log_error(_("%s:%d: invalid auto-key-locate list\n"),
+                           configname,configlineno);
+               else
+                 log_error(_("invalid auto-key-locate list\n"));
+             }
+           break;
+         case oNoAutoKeyLocate:
+           release_akl();
+           break;
+
+         case oEnableDSA2: opt.flags.dsa2=1; break;
+         case oDisableDSA2: opt.flags.dsa2=0; break;
+
+          case oAllowMultisigVerification:
+         case oAllowMultipleMessages:
+           opt.flags.allow_multiple_messages=1;
+           break;
+
+         case oNoAllowMultipleMessages:
+           opt.flags.allow_multiple_messages=0;
+           break;
+
          case oNoop: break;
 
-         default : pargs.err = configfp? 1:2; break;
+         default: 
+            pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
+            break;
          }
       }
 
@@ -2613,10 +2951,11 @@ main (int argc, char **argv )
        directly after the option parsing. */
     if (cmd == aGPGConfList)
       {
-        gpgconf_list (save_configname);
+        gpgconf_list (save_configname ? save_configname : default_configname);
         g10_exit (0);
       }
     xfree (save_configname);
+    xfree (default_configname);
 
     if( nogreeting )
        greeting = 0;
@@ -2627,19 +2966,38 @@ main (int argc, char **argv )
        fprintf(stderr, "%s\n", strusage(15) );
     }
 #ifdef IS_DEVELOPMENT_VERSION
-    if( !opt.batch )
+    if (!opt.batch)
       {
        const char *s;
 
-       if((s=strusage(20)))
+       if((s=strusage(25)))
          log_info("%s\n",s);
-       if((s=strusage(21)))
+       if((s=strusage(26)))
          log_info("%s\n",s);
-       if((s=strusage(22)))
+       if((s=strusage(27)))
          log_info("%s\n",s);
       }
 #endif
 
+    /* FIXME: We should use logging to a file only in server mode;
+       however we have not yet implemetyed that.  Thus we try to get
+       away with --batch as indication for logging to file
+       required. */
+    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;
+      }
+
     if (opt.verbose > 2)
         log_info ("using character set `%s'\n", get_native_charset ());
 
@@ -2665,20 +3023,13 @@ main (int argc, char **argv )
                        "--no-literal" );
     }
 
-#ifndef ENABLE_AGENT_SUPPORT   
-    if (opt.use_agent) {
-      log_info(_("NOTE: %s is not available in this version\n"),
-               "--use-agent");
-      opt.use_agent = 0;
-    }
-#endif /*!ENABLE_AGENT_SUPPORT*/
 
     if (opt.set_filesize)
        log_info(_("NOTE: %s is not for normal use!\n"), "--set-filesize");
     if( opt.batch )
        tty_batchmode( 1 );
 
-    secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
+    gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
 
     if(require_secmem && !got_secmem)
       {
@@ -2687,7 +3038,7 @@ main (int argc, char **argv )
        g10_exit(2);
       }
 
-    set_debug();
+    set_debug (debug_level);
 
     /* Do these after the switch(), so they can override settings. */
     if(PGP2)
@@ -2719,7 +3070,7 @@ main (int argc, char **argv )
               preference, but those have their own error
               messages). */
 
-           if(check_cipher_algo(CIPHER_ALGO_IDEA))
+           if (openpgp_cipher_test_algo(CIPHER_ALGO_IDEA))
              {
                log_info(_("encrypting a message in --pgp2 mode requires "
                           "the IDEA cipher\n"));
@@ -2778,47 +3129,46 @@ main (int argc, char **argv )
        opt.escape_from=1;
       }
 
-    /* must do this after dropping setuid, because string_to...
-     * may try to load an module */
+
     if( def_cipher_string ) {
-       opt.def_cipher_algo = string_to_cipher_algo(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( check_cipher_algo(opt.def_cipher_algo) )
+       if ( openpgp_cipher_test_algo (opt.def_cipher_algo) )
            log_error(_("selected cipher algorithm is invalid\n"));
     }
     if( def_digest_string ) {
-       opt.def_digest_algo = string_to_digest_algo(def_digest_string);
+       opt.def_digest_algo = string_to_digest_algo (def_digest_string);
        xfree(def_digest_string); def_digest_string = NULL;
-       if( check_digest_algo(opt.def_digest_algo) )
+       if ( openpgp_md_test_algo (opt.def_digest_algo) )
            log_error(_("selected digest algorithm is invalid\n"));
     }
     if( compress_algo_string ) {
        opt.compress_algo = string_to_compress_algo(compress_algo_string);
        xfree(compress_algo_string); compress_algo_string = NULL;
        if( check_compress_algo(opt.compress_algo) )
-           log_error(_("selected compression algorithm is invalid\n"));
+          log_error(_("selected compression algorithm is invalid\n"));
     }
     if( cert_digest_string ) {
-       opt.cert_digest_algo = string_to_digest_algo(cert_digest_string);
+       opt.cert_digest_algo = string_to_digest_algo (cert_digest_string);
        xfree(cert_digest_string); cert_digest_string = NULL;
-       if( check_digest_algo(opt.cert_digest_algo) )
-           log_error(_("selected certification digest algorithm is invalid\n"));
+       if (openpgp_md_test_algo(opt.cert_digest_algo))
+          log_error(_("selected certification digest algorithm is invalid\n"));
     }
     if( s2k_cipher_string ) {
-       opt.s2k_cipher_algo = string_to_cipher_algo(s2k_cipher_string);
+       opt.s2k_cipher_algo = string_to_cipher_algo (s2k_cipher_string);
        xfree(s2k_cipher_string); s2k_cipher_string = NULL;
-       if( check_cipher_algo(opt.s2k_cipher_algo) )
-           log_error(_("selected cipher algorithm is invalid\n"));
+       if (openpgp_cipher_test_algo (opt.s2k_cipher_algo))
+          log_error(_("selected cipher algorithm is invalid\n"));
     }
     if( s2k_digest_string ) {
-       opt.s2k_digest_algo = string_to_digest_algo(s2k_digest_string);
+       opt.s2k_digest_algo = string_to_digest_algo (s2k_digest_string);
        xfree(s2k_digest_string); s2k_digest_string = NULL;
-       if( check_digest_algo(opt.s2k_digest_algo) )
-           log_error(_("selected digest algorithm is invalid\n"));
+       if (openpgp_md_test_algo(opt.s2k_digest_algo))
+          log_error(_("selected digest algorithm is invalid\n"));
     }
     if( opt.completes_needed < 1 )
       log_error(_("completes-needed must be greater than 0\n"));
@@ -2845,11 +3195,6 @@ main (int argc, char **argv )
        keygen_set_std_prefs(opt.def_preference_list,0))
       log_error(_("invalid default preferences\n"));
 
-    /* We provide defaults for the personal digest list.  This is
-       SHA-1. */
-    if(!pers_digest_list)
-      pers_digest_list="h2";
-
     if(pers_cipher_list &&
        keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM))
       log_error(_("invalid personal cipher preferences\n"));
@@ -2913,26 +3258,26 @@ main (int argc, char **argv )
        if(opt.def_cipher_algo
           && !algo_available(PREFTYPE_SYM,opt.def_cipher_algo,NULL))
          {
-           badalg=cipher_algo_to_string(opt.def_cipher_algo);
-           badtype=PREFTYPE_SYM;
+           badalg = openpgp_cipher_algo_name (opt.def_cipher_algo);
+           badtype = PREFTYPE_SYM;
          }
        else if(opt.def_digest_algo
                && !algo_available(PREFTYPE_HASH,opt.def_digest_algo,NULL))
          {
-           badalg=digest_algo_to_string(opt.def_digest_algo);
-           badtype=PREFTYPE_HASH;
+           badalg = gcry_md_algo_name (opt.def_digest_algo);
+           badtype = PREFTYPE_HASH;
          }
        else if(opt.cert_digest_algo
                && !algo_available(PREFTYPE_HASH,opt.cert_digest_algo,NULL))
          {
-           badalg=digest_algo_to_string(opt.cert_digest_algo);
-           badtype=PREFTYPE_HASH;
+           badalg = gcry_md_algo_name (opt.cert_digest_algo);
+           badtype = PREFTYPE_HASH;
          }
        else if(opt.compress_algo!=-1
                && !algo_available(PREFTYPE_ZIP,opt.compress_algo,NULL))
          {
-           badalg=compress_algo_to_string(opt.compress_algo);
-           badtype=PREFTYPE_ZIP;
+           badalg = compress_algo_to_string(opt.compress_algo);
+           badtype = PREFTYPE_ZIP;
          }
 
        if(badalg)
@@ -2962,56 +3307,40 @@ main (int argc, char **argv )
          }
       }
 
-    /* set the random seed file */
+    /* Set the random seed file. */
     if( use_random_seed ) {
        char *p = make_filename(opt.homedir, "random_seed", NULL );
-       set_random_seed_file(p);
+       gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
         if (!access (p, F_OK))
           register_secured_file (p);
        xfree(p);
     }
 
-    if( !cmd && opt.fingerprint && !with_fpr ) {
-       set_cmd( &cmd, aListKeys);
-    }
-
-    if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
-       if( cmd == aKModeC ) {
-           opt.fingerprint = 1;
-           cmd = aKMode;
-       }
-       opt.list_sigs = 0;
-       if( opt.verbose > 2 )
-           opt.check_sigs++;
-       if( opt.verbose > 1 )
-           opt.list_sigs++;
-
-       opt.verbose = opt.verbose > 1;
-       g10_opt_verbose = opt.verbose;
-    }
+    /* If there is no command but the --fingerprint is given, default
+       to the --list-keys command.  */
+    if (!cmd && fpr_maybe_cmd)
+      {
+       set_cmd (&cmd, aListKeys);
+      }
 
-    /* kludge to let -sat generate a clear text signature */
-    if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
-       cmd = aClearsign;
 
     if( opt.verbose > 1 )
        set_packet_list_mode(1);
 
-    /* Add the keyrings, but not for some special commands and not in
-       case of "-kvv userid keyring".  Also avoid adding the secret
-       keyring for a couple of commands to avoid unneeded access in
-       case the secrings are stored on a floppy.
+    /* 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 == aKMode && argc == 2 )) ) 
+        || (cmd != aDeArmor && cmd != aEnArmor && cmd != aGPGConfTest) ) 
       {
         if (ALWAYS_ADD_KEYRINGS
             || (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
-                && cmd != aVerify && cmd != aSym))
+                && cmd != aVerify && cmd != aSym && cmd != aLocateKeys))
           {
             if (!sec_nrings || default_keyring) /* add default secret rings */
               keydb_add_resource ("secring" EXTSEP_S "gpg", 4, 1);
@@ -3026,12 +3355,18 @@ main (int argc, char **argv )
     FREE_STRLIST(nrings);
     FREE_STRLIST(sec_nrings);
 
+    if (cmd == aGPGConfTest)
+      g10_exit(0);
 
-    if( pwfd != -1 )  /* read the passphrase now. */
+
+    if( pwfd != -1 )  /* Read the passphrase now. */
        read_passphrase_from_fd( pwfd );
 
     fname = argc? *argv : NULL;
 
+    if(fname && utf8_strings)
+      opt.flags.utf8_filename=1;
+
     switch( cmd ) {
       case aPrimegen:
       case aPrintMD:
@@ -3066,6 +3401,16 @@ main (int argc, char **argv )
 
     switch( cmd )
       {
+      case aServer:
+        {
+          ctrl_t ctrl = xtrycalloc (1, sizeof *ctrl);
+          gpg_init_default_ctrl (ctrl);
+          gpg_server (ctrl);
+          gpg_deinit_default_ctrl (ctrl);
+          xfree (ctrl);
+        }
+        break;
+
       case aStore: /* only store the file */
        if( argc > 1 )
            wrong_args(_("--store [filename]"));
@@ -3236,7 +3581,7 @@ main (int argc, char **argv )
 
        append_to_strlist( &sl, "save" );
        username = make_username( fname );
-       keyedit_menu(fname, locusr, sl, 0, 0 );
+       keyedit_menu (username, locusr, sl, 0, 0 );
        xfree(username);
        free_strlist(sl);
        break;
@@ -3278,7 +3623,7 @@ main (int argc, char **argv )
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist2( &sl, *argv, utf8_strings );
-       public_key_list( sl );
+       public_key_list( sl, 0 );
        free_strlist(sl);
        break;
       case aListSecretKeys:
@@ -3288,33 +3633,12 @@ main (int argc, char **argv )
        secret_key_list( sl );
        free_strlist(sl);
        break;
-
-      case aKMode: /* list keyring -- NOTE: This will be removed soon */
-       if( argc < 2 ) { /* -kv [userid] */
-           sl = NULL;
-           if (argc && **argv)
-               add_to_strlist2( &sl, *argv, utf8_strings );
-           public_key_list( sl );
-           free_strlist(sl);
-       }
-       else if( argc == 2 ) { /* -kv userid keyring */
-           if( access( argv[1], R_OK ) ) {
-               log_error(_("can't open `%s': %s\n"),
-                              print_fname_stdin(argv[1]), strerror(errno));
-           }
-           else {
-               /* add keyring (default keyrings are not registered in this
-                * special case */
-               keydb_add_resource( argv[1], 0, 0 );
-               sl = NULL;
-               if (**argv)
-                   add_to_strlist2( &sl, *argv, utf8_strings );
-               public_key_list( sl );
-               free_strlist(sl);
-           }
-       }
-       else
-           wrong_args(_("-k[v][v][v][c] [user-id] [keyring]") );
+      case aLocateKeys:
+       sl = NULL;
+       for (; argc; argc--, argv++)
+          add_to_strlist2( &sl, *argv, utf8_strings );
+       public_key_list (sl, 1);
+       free_strlist (sl);
        break;
 
       case aKeygen: /* generate a key */
@@ -3336,12 +3660,17 @@ main (int argc, char **argv )
        import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
        break;
 
+       /* TODO: There are a number of command that use this same
+          "make strlist, call function, report error, free strlist"
+          pattern.  Join them together here and avoid all that
+          duplicated code. */
+
       case aExport:
       case aSendKeys:
       case aRecvKeys:
        sl = NULL;
        for( ; argc; argc--, argv++ )
-           add_to_strlist2( &sl, *argv, utf8_strings );
+           append_to_strlist2( &sl, *argv, utf8_strings );
        if( cmd == aSendKeys )
            rc=keyserver_export( sl );
        else if( cmd == aRecvKeys )
@@ -3373,13 +3702,23 @@ main (int argc, char **argv )
       case aRefreshKeys:
        sl = NULL;
        for( ; argc; argc--, argv++ )
-           add_to_strlist2( &sl, *argv, utf8_strings );
+           append_to_strlist2( &sl, *argv, utf8_strings );
        rc=keyserver_refresh(sl);
        if(rc)
          log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
        free_strlist(sl);
        break;
 
+      case aFetchKeys:
+       sl = NULL;
+       for( ; argc; argc--, argv++ )
+           append_to_strlist2( &sl, *argv, utf8_strings );
+       rc=keyserver_fetch(sl);
+       if(rc)
+         log_error("key fetch failed: %s\n",g10_errstr(rc));
+       free_strlist(sl);
+       break;
+
       case aExportSecret:
        sl = NULL;
        for( ; argc; argc--, argv++ )
@@ -3408,7 +3747,7 @@ main (int argc, char **argv )
        if( argc != 1 )
            wrong_args("--desig-revoke user-id");
        username =  make_username(*argv);
-       gen_desig_revoke( username );
+       gen_desig_revoke( username, locusr );
        xfree( username );
        break;
 
@@ -3430,6 +3769,7 @@ main (int argc, char **argv )
 
 
       case aPrimegen:
+#if 0 /*FIXME*/
        {   int mode = argc < 2 ? 0 : atoi(*argv);
 
            if( mode == 1 && argc == 2 ) {
@@ -3461,6 +3801,8 @@ main (int argc, char **argv )
                wrong_args("--gen-prime mode bits [qbits] ");
            putchar('\n');
        }
+#endif
+        wrong_args("--gen-prime not yet supported ");
        break;
 
       case aGenRandom:
@@ -3480,7 +3822,7 @@ main (int argc, char **argv )
                    other tools */
                size_t n = !endless && count < 99? count : 99;
 
-               p = get_random_bits( n*8, level, 0);
+               p = gcry_random_bytes (n, level);
 #ifdef HAVE_DOSISH_SYSTEM
                setmode ( fileno(stdout), O_BINARY );
 #endif
@@ -3509,7 +3851,7 @@ main (int argc, char **argv )
            wrong_args("--print-md algo [files]");
        {
            int all_algos = (**argv=='*' && !(*argv)[1]);
-           int algo = all_algos? 0 : string_to_digest_algo(*argv);
+           int algo = all_algos? 0 : gcry_md_map_name (*argv);
 
            if( !algo && !all_algos )
                log_error(_("invalid hash algorithm `%s'\n"), *argv );
@@ -3582,12 +3924,6 @@ main (int argc, char **argv )
        import_ownertrust( argc? *argv:NULL );
        break;
       
-      case aPipeMode:
-        if ( argc )
-            wrong_args ("--pipemode");
-        run_in_pipemode ();
-        break;
-
       case aRebuildKeydbCaches:
         if (argc)
             wrong_args ("--rebuild-keydb-caches");
@@ -3654,8 +3990,8 @@ main (int argc, char **argv )
 
            if( !opt.no_armor ) {
                if( use_armor_filter( a ) ) {
-                   memset( &afx, 0, sizeof afx);
-                   iobuf_push_filter( a, armor_filter, &afx );
+                   afx = new_armor_context ();
+                   push_armor_filter (afx, a);
                }
            }
            if( cmd == aListPackets ) {
@@ -3671,6 +4007,7 @@ main (int argc, char **argv )
       }
 
     /* cleanup */
+    release_armor_context (afx);
     FREE_STRLIST(remusr);
     FREE_STRLIST(locusr);
     g10_exit(0);
@@ -3678,23 +4015,30 @@ main (int argc, char **argv )
 }
 
 
+/* Note: This function is used by signal handlers!. */
+static void
+emergency_cleanup (void)
+{
+  gcry_control (GCRYCTL_TERM_SECMEM );
+}
+
+
 void
 g10_exit( int rc )
 {
-#ifdef ENABLE_CARD_SUPPORT
-    card_close ();
-#endif
-    update_random_seed_file();
-    if( opt.debug & DBG_MEMSTAT_VALUE ) {
-       m_print_stats("on exit");
-       random_dump_stats();
+  gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
+  if ( (opt.debug & DBG_MEMSTAT_VALUE) )
+    {
+      gcry_control (GCRYCTL_DUMP_MEMORY_STATS);
+      gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
     }
-    if( opt.debug )
-       secmem_dump_stats();
-    secmem_term();
-    rc = rc? rc : log_get_errorcount(0)? 2 :
-                       g10_errors_seen? 1 : 0;
-    exit(rc );
+  if (opt.debug)
+    gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
+
+  emergency_cleanup ();
+  
+  rc = rc? rc : log_get_errorcount(0)? 2 : g10_errors_seen? 1 : 0;
+  exit (rc);
 }
 
 
@@ -3702,7 +4046,7 @@ g10_exit( int rc )
    display, but there are a few other similar assumptions in the
    display code. */
 static void
-print_hex( MD_HANDLE md, int algo, const char *fname )
+print_hex( gcry_md_hd_t md, int algo, const char *fname )
 {
   int i,n,count,indent=0;
   const byte *p;
@@ -3719,16 +4063,16 @@ print_hex( MD_HANDLE md, int algo, const char *fname )
   if(algo==DIGEST_ALGO_RMD160)
     indent+=printf("RMD160 = ");
   else if(algo>0)
-    indent+=printf("%6s = ",digest_algo_to_string(algo));
+    indent+=printf("%6s = ", gcry_md_algo_name (algo));
   else
     algo=abs(algo);
 
   count=indent;
 
-  p = md_read( md, algo );
-  n = md_digest_length(algo);
+  p = gcry_md_read (md, algo);
+  n = gcry_md_get_algo_dlen (algo);
 
-  count+=printf("%02X",*p++);
+  count += printf ("%02X",*p++);
 
   for(i=1;i<n;i++,p++)
     {
@@ -3782,7 +4126,7 @@ print_hex( MD_HANDLE md, int algo, const char *fname )
 }
 
 static void
-print_hashline( MD_HANDLE md, int algo, const char *fname )
+print_hashline( gcry_md_hd_t md, int algo, const char *fname )
 {
     int i, n;
     const byte *p;
@@ -3797,8 +4141,8 @@ print_hashline( MD_HANDLE md, int algo, const char *fname )
     }
     putchar(':');
     printf("%d:", algo );
-    p = md_read( md, algo );
-    n = md_digest_length(algo);
+    p = gcry_md_read (md, algo);
+    n = gcry_md_get_algo_dlen (algo);
     for(i=0; i < n ; i++, p++ ) 
         printf("%02X", *p );
     putchar(':');
@@ -3811,7 +4155,7 @@ print_mds( const char *fname, int algo )
     FILE *fp;
     char buf[1024];
     size_t n;
-    MD_HANDLE md;
+    gcry_md_hd_t md;
 
     if( !fname ) {
        fp = stdin;
@@ -3833,62 +4177,67 @@ print_mds( const char *fname, int algo )
        return;
     }
 
-    md = md_open( 0, 0 );
+    gcry_md_open (&md, 0, 0);
     if( algo )
-       md_enable( md, algo );
+        gcry_md_enable (md, algo);
     else {
-       md_enable( md, DIGEST_ALGO_MD5 );
-       md_enable( md, DIGEST_ALGO_SHA1 );
-       md_enable( md, DIGEST_ALGO_RMD160 );
-#ifdef USE_SHA256
-       md_enable( md, DIGEST_ALGO_SHA256 );
-#endif
-#ifdef USE_SHA512
-       md_enable( md, DIGEST_ALGO_SHA384 );
-       md_enable( md, DIGEST_ALGO_SHA512 );
-#endif
+       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);
     }
 
     while( (n=fread( buf, 1, DIM(buf), fp )) )
-       md_write( md, buf, n );
+       gcry_md_write (md, buf, n);
     if( ferror(fp) )
        log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
     else {
-       md_final(md);
+       gcry_md_final (md);
         if ( opt.with_colons ) {
             if ( algo ) 
                 print_hashline( md, algo, fname );
             else {
-                print_hashline( md, DIGEST_ALGO_MD5, fname );
-                print_hashline( md, DIGEST_ALGO_SHA1, fname );
-                print_hashline( md, DIGEST_ALGO_RMD160, fname );
-#ifdef USE_SHA256
-                print_hashline( md, DIGEST_ALGO_SHA256, fname );
-#endif
-#ifdef USE_SHA512
-               print_hashline( md, DIGEST_ALGO_SHA384, fname );
-               print_hashline( md, DIGEST_ALGO_SHA512, fname );
-#endif
+                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 );
             }
         }
         else {
             if( algo )
               print_hex(md,-algo,fname);
             else {
-                print_hex( md, DIGEST_ALGO_MD5, fname );
-                print_hex( md, DIGEST_ALGO_SHA1, fname );
-                print_hex( md, DIGEST_ALGO_RMD160, fname );
-#ifdef USE_SHA256
-                print_hex( md, DIGEST_ALGO_SHA256, fname );
-#endif
-#ifdef USE_SHA512
-               print_hex( md, DIGEST_ALGO_SHA384, fname );
-               print_hex( md, DIGEST_ALGO_SHA512, fname );
-#endif
+                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 );
             }
         }
     }
-    md_close(md);
+    gcry_md_close(md);
 
     if( fp != stdin )
        fclose(fp);
@@ -3903,76 +4252,29 @@ print_mds( const char *fname, int algo )
 static void
 add_notation_data( const char *string, int which )
 {
-    const char *s;
-    STRLIST sl,*notation_data;
-    int critical=0;
-    int highbit=0;
-    int saw_at=0;
-
-    if(which)
-      notation_data=&opt.cert_notation_data;
-    else
-      notation_data=&opt.sig_notation_data;
-
-    if( *string == '!' ) {
-       critical = 1;
-       string++;
-    }
-
-    /* If and when the IETF assigns some official name tags, we'll
-       have to add them here. */
+  struct notation *notation;
 
-    for( s=string ; *s != '='; s++ )
-      {
-       if( *s=='@')
-         saw_at++;
-
-       if( !*s || !isascii (*s) || (!isgraph(*s) && !isspace(*s)) )
-         {
-           log_error(_("a notation name must have only printable characters "
-                       "or spaces, and end with an '='\n") );
-           return;
-         }
-      }
-
-    if(!saw_at && !opt.expert)
-      {
-       log_error(_("a user notation name must contain the '@' character\n"));
-       return;
-      }
-    if (saw_at > 1)
-      {
-       log_error(_("a notation name must not contain more than "
-                    "one '@' character\n"));
-       return;
-      }
-
-    /* we only support printable text - therefore we enforce the use
-     * of only printable characters (an empty value is valid) */
-    for( s++; *s ; s++ ) {
-       if ( isascii (*s) )
-          highbit = 1;
-       else if (iscntrl(*s)) {
-           log_error(_("a notation value must not use"
-                       " any control characters\n") );
-           return;
+  notation=string_to_notation(string,utf8_strings);
+  if(notation)
+    {
+      if(which)
+       {
+         notation->next=opt.cert_notations;
+         opt.cert_notations=notation;
+       }
+      else
+       {
+         notation->next=opt.sig_notations;
+         opt.sig_notations=notation;
        }
     }
-
-    if( highbit )   /* must use UTF8 encoding */
-       sl = add_to_strlist2( notation_data, string, utf8_strings );
-    else
-       sl = add_to_strlist( notation_data, string );
-
-    if( critical )
-       sl->flags |= 1;
 }
 
 static void
 add_policy_url( const char *string, int which )
 {
   unsigned int i,critical=0;
-  STRLIST sl;
+  strlist_t sl;
 
   if(*string=='!')
     {
@@ -4005,7 +4307,7 @@ static void
 add_keyserver_url( const char *string, int which )
 {
   unsigned int i,critical=0;
-  STRLIST sl;
+  strlist_t sl;
 
   if(*string=='!')
     {