* options.h, g10.c (main), import.c (parse_import_options, import_one,
[gnupg.git] / g10 / g10.c
index 545c5b8..20d781c 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -1,5 +1,6 @@
 /* g10.c - The GnuPG utility (main for gpg)
- * Copyright (C) 1998,1999,2000,2001,2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -25,8 +26,9 @@
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
+#include <assert.h>
 #ifdef HAVE_DOSISH_SYSTEM
-  #include <fcntl.h> /* for setmode() */
+#include <fcntl.h> /* for setmode() */
 #endif
 #ifdef HAVE_STAT
 #include <sys/stat.h> /* for stat() */
 #include "g10defs.h"
 #include "keyserver-internal.h"
 #include "exec.h"
+#include "cardglue.h"
 
-enum cmd_and_opt_values { aNull = 0,
+enum cmd_and_opt_values
+  {
+    aNull = 0,
     oArmor       = 'a',
     aDetachedSign = 'b',
     aSym         = 'c',
     aDecrypt     = 'd',
     aEncr        = 'e',
-    aEncrFiles,
     oInteractive  = 'i',
     oKOption     = 'k',
     oDryRun      = 'n',
     oOutput      = 'o',
     oQuiet       = 'q',
     oRecipient   = 'r',
+    oHiddenRecipient = 'R',
     aSign        = 's',
     oTextmodeShort= 't',
     oUser        = 'u',
     oVerbose     = 'v',
     oCompress    = 'z',
-    oNotation    = 'N',
+    oSetNotation  = 'N',
     oBatch       = 500,
     oSigNotation,
     oCertNotation,
     oShowNotation,
     oNoShowNotation,
-    aDecryptFiles,                          
+    aEncrFiles,
+    aEncrSym,
+    aDecryptFiles,
     aClearsign,
     aStore,
     aKeygen,
     aSignEncr,
+    aSignEncrSym,
     aSignSym,
     aSignKey,
     aLSignKey,
@@ -118,6 +126,7 @@ enum cmd_and_opt_values { aNull = 0,
     aListTrustDB,
     aListTrustPath,
     aExportOwnerTrust,
+    aListOwnerTrust,
     aImportOwnerTrust,
     aDeArmor,
     aEnArmor,
@@ -125,8 +134,12 @@ enum cmd_and_opt_values { aNull = 0,
     aPipeMode,
     aRebuildKeydbCaches,
     aRefreshKeys,
+    aCardStatus,
+    aCardEdit,
+    aChangePIN,
 
     oTextmode,
+    oNoTextmode,
     oExpert,
     oNoExpert,
     oAskSigExpire,
@@ -139,6 +152,7 @@ enum cmd_and_opt_values { aNull = 0,
     oAnswerNo,
     oDefCertCheckLevel,
     oKeyring,
+    oPrimaryKeyring,
     oSecretKeyring,
     oShowKeyring,
     oDefaultKey,
@@ -158,24 +172,27 @@ enum cmd_and_opt_values { aNull = 0,
 #endif /* __riscos__ */
     oSKComments,
     oNoSKComments,
-    oNoVersion,
     oEmitVersion,
+    oNoEmitVersion,
     oCompletesNeeded,
     oMarginalsNeeded,
     oMaxCertDepth,
     oLoadExtension,
+    oGnuPG,
     oRFC1991,
+    oRFC2440,
     oOpenPGP,
     oPGP2,
-    oNoPGP2,
     oPGP6,
-    oNoPGP6,
     oPGP7,
-    oNoPGP7,
+    oPGP8,
     oCipherAlgo,
     oDigestAlgo,
     oCertDigestAlgo,
     oCompressAlgo,
+    oCompressLevel,
+    oBZ2CompressLevel,
+    oBZ2CompressLowmem,
     oPasswdFD,
 #ifdef __riscos__
     oPasswdFile,
@@ -203,7 +220,8 @@ enum cmd_and_opt_values { aNull = 0,
     oCompressKeys,
     oCompressSigs,
     oAlwaysTrust,
-    oEmuChecksumBug,
+    oTrustModel,
+    oForceOwnertrust,
     oRunAsShmCP,
     oSetFilename,
     oForYourEyesOnly,
@@ -213,10 +231,13 @@ enum cmd_and_opt_values { aNull = 0,
     oCertPolicyURL,
     oShowPolicyURL,
     oNoShowPolicyURL,
+    oSigKeyserverURL,
     oUseEmbeddedFilename,
     oComment,
     oDefaultComment,
+    oNoComments,
     oThrowKeyid,
+    oNoThrowKeyid,
     oShowPhotos,
     oNoShowPhotos,
     oPhotoViewer,
@@ -243,9 +264,12 @@ enum cmd_and_opt_values { aNull = 0,
     oKeyServerOptions,
     oImportOptions,
     oExportOptions,
+    oListOptions,
+    oVerifyOptions,
     oTempDir,
     oExecPath,
     oEncryptTo,
+    oHiddenEncryptTo,
     oNoEncryptTo,
     oLoggerFD,
 #ifdef __riscos__
@@ -292,15 +316,27 @@ enum cmd_and_opt_values { aNull = 0,
     oPersonalCipherPreferences,
     oPersonalDigestPreferences,
     oPersonalCompressPreferences,
-    oEmu3DESS2KBug,  /* will be removed in 1.1 */
-    oEmuMDEncodeBug,
     oDisplay,
     oTTYname,
     oTTYtype,
     oLCctype,
     oLCmessages,
     oGroup,
-aTest };
+    oNoGroups,
+    oStrict,
+    oNoStrict,
+    oMangleDosFilenames,
+    oNoMangleDosFilenames,
+    oEnableProgressFilter,
+    oMultifile,
+
+    oReaderPort,
+    octapiDriver,
+    opcscDriver,
+    oDisableCCID,
+
+    aTest
+  };
 
 
 static ARGPARSE_OPTS opts[] = {
@@ -308,20 +344,20 @@ 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") },
+    { 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, N_("|[files]|encrypt files")},
+    { aEncrFiles, "encrypt-files", 256, "@"},
     { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
-    { aStore, "store",     256, N_("store only")},
+    { aStore, "store",     256, "@"},
     { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
-    { aDecryptFiles, "decrypt-files", 256, N_("|[files]|decrypt files")},
+    { 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_("check key 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")},
@@ -330,8 +366,8 @@ static ARGPARSE_OPTS opts[] = {
                                    N_("remove keys from the secret keyring")},
     { aSignKey,  "sign-key"   ,256, N_("sign a key")},
     { aLSignKey, "lsign-key"  ,256, N_("sign a key locally")},
-    { aNRSignKey, "nrsign-key"  ,256, N_("sign a key non-revocably")},
-    { aNRLSignKey, "nrlsign-key"  ,256, N_("sign a key locally and non-revocably")},
+    { aNRSignKey, "nrsign-key"  ,256, "@"},
+    { aNRLSignKey, "nrlsign-key"  ,256, "@"},
     { aEditKey,  "edit-key"   ,256, N_("sign or edit a key")},
     { aGenRevoke, "gen-revoke",256, N_("generate a revocation certificate")},
     { aDesigRevoke, "desig-revoke",256, "@" },
@@ -347,20 +383,22 @@ static ARGPARSE_OPTS opts[] = {
     { aExportSecretSub, "export-secret-subkeys" , 256, "@" },
     { aImport, "import",      256     , N_("import/merge keys")},
     { aFastImport, "fast-import",  256 , "@"},
-    { aListPackets, "list-packets",256,N_("list only the sequence of packets")},
-    { aExportOwnerTrust,
-             "export-ownertrust", 256, N_("export the ownertrust values")},
-    { aImportOwnerTrust,
-             "import-ownertrust", 256 , N_("import ownertrust values")},
+#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")},
+#endif
+    { 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 , N_("unattended trust database update")},
-    { aFixTrustDB, "fix-trustdb",0 , N_("fix a corrupted trust database")},
-    { aDeArmor, "dearmor", 256, N_("De-Armor a file or stdin") },
-    { aDeArmor, "dearmour", 256, "@" },
-    { aEnArmor, "enarmor", 256, N_("En-Armor a file or stdin") },
-    { aEnArmor, "enarmour", 256, "@" },
+    { 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, "@" },
@@ -370,20 +408,24 @@ static ARGPARSE_OPTS opts[] = {
     { 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,
-                                 N_("|NAME|use NAME as default recipient")},
-    { oDefRecipientSelf, "default-recipient-self" ,0,
-                               N_("use the default key as default recipient")},
+    { 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, "@" },
     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
-    { oCompress, NULL,       1, N_("|N|set compress level N (0 disables)") },
+    { oCompress, NULL, 1, N_("|N|set compress level N (0 disables)") },
+    { oCompressLevel, "compress-level", 1, "@" },
+    { oBZ2CompressLevel, "bzip2-compress-level", 1, "@" },
+    { oBZ2CompressLowmem, "bzip2-compress-lowmem", 0, "@" },
     { oTextmodeShort, NULL,   0, "@"},
     { oTextmode, "textmode",  0, N_("use canonical text mode")},
+    { oNoTextmode, "no-textmode",  0, "@"},
     { oExpert, "expert",   0, "@"},
     { oNoExpert, "no-expert",   0, "@"},
     { oAskSigExpire, "ask-sig-expire",   0, "@"},
@@ -392,78 +434,83 @@ static ARGPARSE_OPTS opts[] = {
     { oNoAskCertExpire, "no-ask-cert-expire",   0, "@"},
     { oOutput, "output",    2, N_("use as output file")},
     { oVerbose, "verbose",   0, N_("verbose") },
-    { oQuiet,  "quiet",   0, N_("be somewhat more quiet") },
-    { oNoTTY, "no-tty", 0, N_("don't use the terminal at all") },
-    { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
-    { oNoForceV3Sigs, "no-force-v3-sigs", 0, N_("do not force v3 signatures") },
-    { oForceV4Certs, "force-v4-certs", 0, N_("force v4 key signatures") },
-    { oNoForceV4Certs, "no-force-v4-certs", 0, N_("do not force v4 key signatures") },
-    { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") },
+    { 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, N_("never use a MDC for encryption") },
+    { 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, N_("use the gpg-agent")},
+    { oInteractive, "interactive", 0, N_("prompt before overwriting") },
+    { oUseAgent, "use-agent",0, "@"},
     { oNoUseAgent, "no-use-agent",0, "@"},
     { oGpgAgentInfo, "gpg-agent-info",2, "@"},
-    { oBatch, "batch",     0, N_("batch mode: never ask")},
-    { oAnswerYes, "yes",       0, N_("assume yes on most questions")},
-    { oAnswerNo,  "no",        0, N_("assume no on most questions")},
-    { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
-    { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
-    { oShowKeyring, "show-keyring", 0, N_("show which keyring a listed key is on")},
-    { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
-    { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
+    { 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,"@"},
-    { oCharset, "charset"   , 2, N_("|NAME|set terminal charset to NAME") },
-    { oOptions, "options"   , 2, N_("read options from file")},
-
+    { oListOptions, "list-options",2,"@"},
+    { oVerifyOptions, "verify-options",2,"@"},
+    { oCharset, "charset", 2, "@"},
+    { oOptions, "options", 2, "@"},
     { oDebug, "debug"     ,4|16, "@"},
     { oDebugAll, "debug-all" ,0, "@"},
-    { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
+    { oStatusFD, "status-fd" ,1, "@"},
 #ifdef __riscos__
-    { oStatusFile, "status-file" ,2, N_("|[file]|write status info to file") },
+    { oStatusFile, "status-file" ,2, "@"},
 #endif /* __riscos__ */
     { oAttributeFD, "attribute-fd" ,1, "@" },
 #ifdef __riscos__
     { oAttributeFile, "attribute-file" ,2, "@" },
 #endif /* __riscos__ */
-    { oNoSKComments, "no-comment", 0,   "@"},
     { oNoSKComments, "no-sk-comments", 0,   "@"},
     { oSKComments, "sk-comments", 0,   "@"},
     { oCompletesNeeded, "completes-needed", 1, "@"},
     { oMarginalsNeeded, "marginals-needed", 1, "@"},
     { oMaxCertDepth,   "max-cert-depth", 1, "@" },
-    { oTrustedKey, "trusted-key", 2, N_("|KEYID|ultimately trust this key")},
-    { oLoadExtension, "load-extension" ,2, N_("|FILE|load extension module FILE")},
-    { oRFC1991, "rfc1991",   0, N_("emulate the mode described in RFC1991")},
-    { oOpenPGP, "openpgp", 0, N_("set all packet, cipher and digest options to OpenPGP behavior")},
-    { oPGP2, "pgp2", 0, N_("set all packet, cipher and digest options to PGP 2.x behavior")},
-    { oNoPGP2, "no-pgp2", 0, "@"},
+    { 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, "@"},
-    { oNoPGP6, "no-pgp6", 0, "@"},
     { oPGP7, "pgp7", 0, "@"},
-    { oNoPGP7, "no-pgp7", 0, "@"},
-    { oS2KMode, "s2k-mode",  1, N_("|N|use passphrase mode N")},
-    { oS2KDigest, "s2k-digest-algo",2,
-               N_("|NAME|use message digest algorithm NAME for passphrases")},
-    { oS2KCipher, "s2k-cipher-algo",2,
-               N_("|NAME|use cipher algorithm NAME for passphrases")},
+    { oPGP8, "pgp8", 0, "@"},
+    { oS2KMode, "s2k-mode", 1, "@"},
+    { oS2KDigest, "s2k-digest-algo", 2, "@"},
+    { oS2KCipher, "s2k-cipher-algo", 2, "@"},
     { oSimpleSKChecksum, "simple-sk-checksum", 0, "@"},
-    { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
-    { oDigestAlgo, "digest-algo", 2 , N_("|NAME|use message digest algorithm NAME")},
+    { oCipherAlgo, "cipher-algo", 2, "@"},
+    { oDigestAlgo, "digest-algo", 2, "@"},
     { oCertDigestAlgo, "cert-digest-algo", 2 , "@" },
-    { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
-    { oThrowKeyid, "throw-keyid", 0, N_("throw keyid field of encrypted packets")},
-    { oShowPhotos,   "show-photos", 0, N_("Show Photo IDs")},
-    { oNoShowPhotos, "no-show-photos", 0, N_("Don't show Photo IDs")},
-    { oPhotoViewer,  "photo-viewer", 2, N_("Set command line to view Photo IDs")},
-    { oNotation,   "notation-data", 2, "@" },
-    { oSigNotation,   "sig-notation", 2, "@" },
-    { oCertNotation,  "cert-notation", 2, "@" },
+    { oCompressAlgo,"compress-algo", 2, "@"},
+    { oThrowKeyid, "throw-keyid", 0, "@"},
+    { oNoThrowKeyid, "no-throw-keyid", 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_(
   "@\n(See the man page for a complete listing of all commands and options)\n"
@@ -477,10 +524,12 @@ static ARGPARSE_OPTS opts[] = {
     " --fingerprint [names]      show fingerprints\n"  ) },
 
   /* hidden options */
-    { aExportOwnerTrust, "list-ownertrust",0 , "@"},  /* alias */
+    { aListOwnerTrust, "list-ownertrust", 256, "@"}, /* deprecated */
+    { oCompressAlgo, "compression-algo", 1, "@"}, /* alias */
     { aPrintMDs, "print-mds" , 256, "@"}, /* old */
     { aListTrustDB, "list-trustdb",0 , "@"},
-    { aListTrustPath, "list-trust-path",0, "@"},
+    /* Not yet used */
+    /* { aListTrustPath, "list-trust-path",0, "@"}, */
     { aPipeMode,  "pipemode", 0, "@" },
     { oKOption, NULL,   0, "@"},
     { oPasswdFD, "passphrase-fd",1, "@" },
@@ -514,7 +563,8 @@ static ARGPARSE_OPTS opts[] = {
     { oCompressSigs, "compress-sigs",0, "@"},
     { oDefCertCheckLevel, "default-cert-check-level", 1, "@"},
     { oAlwaysTrust, "always-trust", 0, "@"},
-    { oEmuChecksumBug, "emulate-checksum-bug", 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, "@" },
@@ -524,12 +574,15 @@ static ARGPARSE_OPTS opts[] = {
     { 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, "@" },
-    { oNoVersion, "no-version", 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, "@" },
@@ -581,16 +634,31 @@ static ARGPARSE_OPTS opts[] = {
     { oPersonalCipherPreferences,  "personal-cipher-preferences", 2, "@"},
     { oPersonalDigestPreferences,  "personal-digest-preferences", 2, "@"},
     { oPersonalCompressPreferences,  "personal-compress-preferences", 2, "@"},
-    { oEmu3DESS2KBug,  "emulate-3des-s2k-bug", 0, "@"},
-    { oEmuMDEncodeBug, "emulate-md-encode-bug", 0, "@"},
+    /* 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, "@" },
-{0} };
+    { 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, "@" },
+
+    { oReaderPort, "reader-port",    2, "@"},
+    { octapiDriver, "ctapi-driver",  2, "@"},
+    { opcscDriver, "pcsc-driver",    2, "@"},
+    { oDisableCCID, "disable-ccid", 0, "@"},
 
+{0} };
 
 
 int g10_errors_seen = 0;
@@ -602,14 +670,10 @@ static char *build_list( const char *text, char letter,
                         const char *(*mapf)(int), int (*chkf)(int) );
 static void set_cmd( enum cmd_and_opt_values *ret_cmd,
                        enum cmd_and_opt_values new_cmd );
-static void print_hex( byte *p, size_t n );
 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 );
-
-#ifdef __riscos__
-RISCOS_GLOBAL_STATICS("GnuPG Heap")
-#endif /* __riscos__ */
+static void add_keyserver_url( const char *string, int which );
 
 const char *
 strusage( int level )
@@ -624,6 +688,19 @@ strusage( int level )
       case 19: p =
            _("Please report bugs to <gnupg-bugs@gnu.org>.\n");
        break;
+
+#ifdef IS_DEVELOPMENT_VERSION
+      case 20:
+       p="NOTE: THIS IS A DEVELOPMENT VERSION!";
+       break;
+      case 21:
+       p="It is only intended for test purposes and should NOT be";
+       break;
+      case 22:
+       p="used in a production environment or with production keys!";
+       break;
+#endif
+
       case 1:
       case 40: p =
            _("Usage: gpg [options] [files] (-h for help)");
@@ -643,25 +720,25 @@ strusage( int level )
       case 33: p = _("\nSupported algorithms:\n"); break;
       case 34:
        if( !pubkeys )
-           pubkeys = build_list("Pubkey: ", 0, pubkey_algo_to_string,
+           pubkeys = build_list(_("Pubkey: "), 0, pubkey_algo_to_string,
                                                        check_pubkey_algo );
        p = pubkeys;
        break;
       case 35:
        if( !ciphers )
-           ciphers = build_list("Cipher: ", 'S', cipher_algo_to_string,
+           ciphers = build_list(_("Cipher: "), 'S', cipher_algo_to_string,
                                                        check_cipher_algo );
        p = ciphers;
        break;
       case 36:
        if( !digests )
-           digests = build_list("Hash: ", 'H', digest_algo_to_string,
+           digests = build_list(_("Hash: "), 'H', digest_algo_to_string,
                                                        check_digest_algo );
        p = digests;
        break;
       case 37:
        if( !zips )
-           zips = build_list("Compress: ",'Z',compress_algo_to_string,
+           zips = build_list(_("Compression: "),'Z',compress_algo_to_string,
                                                        check_compress_algo);
        p = zips;
        break;
@@ -730,15 +807,15 @@ build_list( const char *text, char letter,
 static void
 i18n_init(void)
 {
-  #ifdef USE_SIMPLE_GETTEXT
+#ifdef USE_SIMPLE_GETTEXT
     set_gettext_file( PACKAGE );
-  #else
-  #ifdef ENABLE_NLS
+#else
+#ifdef ENABLE_NLS
     setlocale( LC_ALL, "" );
     bindtextdomain( PACKAGE, G10_LOCALEDIR );
     textdomain( PACKAGE );
-  #endif
-  #endif
+#endif
+#endif
 }
 
 static void
@@ -780,6 +857,17 @@ set_debug(void)
 }
 
 
+/* 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)
+{
+  if (!dir)
+    dir = "";
+  g10_opt_homedir = opt.homedir = dir;
+}
+
+
 static void
 set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
 {
@@ -795,8 +883,18 @@ set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd )
        cmd = aSignSym;
     else if( cmd == aSym && new_cmd == aSign )
        cmd = aSignSym;
+    else if( cmd == aSym && new_cmd == aEncr )
+       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)
+        cmd = aSignEncrSym;
+    else if (cmd == aEncrSym && new_cmd == aSign)
+        cmd = aSignEncrSym;
     else if(   ( cmd == aSign     && new_cmd == aClearsign )
             || ( cmd == aClearsign && new_cmd == aSign )  )
        cmd = aClearsign;
@@ -816,16 +914,21 @@ static void add_group(char *string)
   STRLIST values=NULL;
 
   /* Break off the group name */
-  name=strsep(&string," ");
+  name=strsep(&string,"=");
   if(string==NULL)
     {
-      log_error(_("no values for group \"%s\"\n"),name);
+      log_error(_("no = sign found in group definition \"%s\"\n"),name);
       return;
     }
 
+  trim_trailing_ws(name,strlen(name));
+
   /* Break apart the values */
-  while((value=strsep(&string," ")) && *value!='\0')
-    add_to_strlist2(&values,value,utf8_strings);
+  while ((value= strsep(&string," \t")))
+    {
+      if (*value)
+        add_to_strlist2 (&values,value,utf8_strings);
+    }
 
   item=m_alloc(sizeof(struct groupitem));
   item->name=name;
@@ -852,7 +955,7 @@ check_permissions(const char *path,int item)
 {
 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
   static int homedir_cache=-1;
-  char *tmppath,*isa,*dir;
+  char *tmppath,*dir;
   struct stat statbuf,dirbuf;
   int homedir=0,ret=0,checkonly=0;
   int perm=0,own=0,enc_dir_perm=0,enc_dir_own=0;
@@ -860,6 +963,8 @@ check_permissions(const char *path,int item)
   if(opt.no_perm_warn)
     return 0;
 
+  assert(item==0 || item==1 || item==2);
+
   /* extensions may attach a path */
   if(item==2 && path[0]!=DIRSEP_C)
     {
@@ -876,8 +981,8 @@ check_permissions(const char *path,int item)
      to avoid user confusion with an extra options file warning which
      could be rectified if the homedir itself had proper
      permissions. */
-  if(item!=0 && homedir_cache>-1 &&
-     ascii_memcasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0)
+  if(item!=0 && homedir_cache>-1
+     && ascii_strncasecmp(opt.homedir,tmppath,strlen(opt.homedir))==0)
     {
       ret=homedir_cache;
       goto end;
@@ -909,8 +1014,6 @@ check_permissions(const char *path,int item)
 
   if(item==0)
     {
-      isa="homedir";
-
       /* The homedir must be x00, a directory, and owned by the user. */
 
       if(S_ISDIR(statbuf.st_mode))
@@ -930,11 +1033,6 @@ check_permissions(const char *path,int item)
     }
   else if(item==1 || item==2)
     {
-      if(item==1)
-       isa="configuration file";
-      else
-       isa="extension";
-
       /* The options or extension file.  Okay unless it or its
         containing directory is group or other writable or not owned
         by us or root. */
@@ -982,19 +1080,53 @@ check_permissions(const char *path,int item)
   if(!checkonly)
     {
       if(own)
-       log_info(_("WARNING: unsafe ownership on %s \"%s\"\n"),
-                isa,tmppath);
+       {
+         if(item==0)
+           log_info(_("WARNING: unsafe ownership on "
+                      "homedir \"%s\"\n"),tmppath);
+         else if(item==1)
+           log_info(_("WARNING: unsafe ownership on "
+                      "configuration file \"%s\"\n"),tmppath);
+         else
+           log_info(_("WARNING: unsafe ownership on "
+                      "extension \"%s\"\n"),tmppath);
+       }
       if(perm)
-       log_info(_("WARNING: unsafe permissions on %s \"%s\"\n"),
-                isa,tmppath);
+       {
+         if(item==0)
+           log_info(_("WARNING: unsafe permissions on "
+                      "homedir \"%s\"\n"),tmppath);
+         else if(item==1)
+           log_info(_("WARNING: unsafe permissions on "
+                      "configuration file \"%s\"\n"),tmppath);
+         else
+           log_info(_("WARNING: unsafe permissions on "
+                      "extension \"%s\"\n"),tmppath);
+       }
       if(enc_dir_own)
-       log_info(_("WARNING: unsafe enclosing directory "
-                  "ownership on %s \"%s\"\n"),
-                isa,tmppath);
+       {
+         if(item==0)
+           log_info(_("WARNING: unsafe enclosing directory ownership on "
+                      "homedir \"%s\"\n"),tmppath);
+         else if(item==1)
+           log_info(_("WARNING: unsafe enclosing directory ownership on "
+                      "configuration file \"%s\"\n"),tmppath);
+         else
+           log_info(_("WARNING: unsafe enclosing directory ownership on "
+                      "extension \"%s\"\n"),tmppath);
+       }
       if(enc_dir_perm)
-       log_info(_("WARNING: unsafe enclosing directory "
-                  "permissions on %s \"%s\"\n"),
-                isa,tmppath);
+       {
+         if(item==0)
+           log_info(_("WARNING: unsafe enclosing directory permissions on "
+                      "homedir \"%s\"\n"),tmppath);
+         else if(item==1)
+           log_info(_("WARNING: unsafe enclosing directory permissions on "
+                      "configuration file \"%s\"\n"),tmppath);
+         else
+           log_info(_("WARNING: unsafe enclosing directory permissions on "
+                      "extension \"%s\"\n"),tmppath);
+       }
     }
 
  end:
@@ -1038,6 +1170,7 @@ main( int argc, char **argv )
     const char *trustdb_name = NULL;
     char *def_cipher_string = NULL;
     char *def_digest_string = NULL;
+    char *compress_algo_string = NULL;
     char *cert_digest_string = NULL;
     char *s2k_cipher_string = NULL;
     char *s2k_digest_string = NULL;
@@ -1045,17 +1178,17 @@ main( int argc, char **argv )
     char *pers_digest_list = NULL;
     char *pers_compress_list = NULL;
     int eyes_only=0;
+    int multifile=0;
     int pwfd = -1;
     int with_fpr = 0; /* make an option out of --fingerprint */
     int any_explicit_recipient = 0;
-  #ifdef USE_SHM_COPROCESSING
+#ifdef USE_SHM_COPROCESSING
     ulong requested_shm_size=0;
-  #endif
+#endif
 
-  #ifdef __riscos__
-    riscos_global_defaults();
+#ifdef __riscos__
     opt.lock_once = 1;
-  #endif /* __riscos__ */
+#endif /* __riscos__ */
 
     trap_unaligned();
     secmem_set_flags( secmem_get_flags() | 2 ); /* suspend warnings */
@@ -1070,36 +1203,55 @@ main( int argc, char **argv )
     create_dotlock(NULL); /* register locking cleanup */
     i18n_init();
     opt.command_fd = -1; /* no command fd */
-    opt.compress = -1; /* defaults to standard compress level */
+    opt.compress_level = -1; /* defaults to standard compress level */
+    opt.bz2_compress_level = -1; /* defaults to standard compress level */
     /* note: if you change these lines, look at oOpenPGP */
     opt.def_cipher_algo = 0;
     opt.def_digest_algo = 0;
     opt.cert_digest_algo = 0;
-    opt.def_compress_algo = -1;
+    opt.compress_algo = -1; /* defaults to DEFAULT_COMPRESS_ALGO */
     opt.s2k_mode = 3; /* iterated+salted */
     opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
+#ifdef USE_CAST5
     opt.s2k_cipher_algo = CIPHER_ALGO_CAST5;
+#else
+    opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
+#endif
     opt.completes_needed = 1;
     opt.marginals_needed = 3;
     opt.max_cert_depth = 5;
     opt.pgp2_workarounds = 1;
     opt.force_v3_sigs = 1;
     opt.escape_from = 1;
-    opt.import_options=0;
+    opt.import_options=IMPORT_SK2PK;
     opt.export_options=
       EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES;
-    opt.keyserver_options.import_options=IMPORT_REPAIR_HKP_SUBKEY_BUG;
+    opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG;
     opt.keyserver_options.export_options=
       EXPORT_INCLUDE_NON_RFC|EXPORT_INCLUDE_ATTRIBUTES;
     opt.keyserver_options.include_subkeys=1;
-#if defined (__MINGW32__) || defined (__CYGWIN32__)
-    opt.homedir = read_w32_registry_string( NULL, "Software\\GNU\\GnuPG", "HomeDir" );
+    opt.keyserver_options.include_revoked=1;
+    opt.keyserver_options.try_dns_srv=1;
+    opt.verify_options=
+      VERIFY_SHOW_POLICY_URLS|VERIFY_SHOW_NOTATIONS|VERIFY_SHOW_KEYSERVER_URLS;
+    opt.trust_model=TM_AUTO;
+    opt.mangle_dos_filenames = 0;
+#if defined (_WIN32)
+    set_homedir ( read_w32_registry_string( NULL,
+                                    "Software\\GNU\\GnuPG", "HomeDir" ));
 #else
-    opt.homedir = getenv("GNUPGHOME");
+    set_homedir ( getenv("GNUPGHOME") );
 #endif
-    if( !opt.homedir || !*opt.homedir ) {
-       opt.homedir = GNUPG_HOMEDIR;
-    }
+    if( !*opt.homedir )
+       set_homedir ( GNUPG_HOMEDIR );
+
+#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 */
     orig_argc = argc;
@@ -1119,10 +1271,20 @@ main( int argc, char **argv )
        else if( pargs.r_opt == oNoOptions )
            default_config = 0; /* --no-options */
        else if( pargs.r_opt == oHomedir )
-           opt.homedir = pargs.r.ret_str;
+           set_homedir ( pargs.r.ret_str );
        else if( pargs.r_opt == oNoPermissionWarn )
            opt.no_perm_warn=1;
-      #ifdef USE_SHM_COPROCESSING
+       else if (pargs.r_opt == oStrict )
+         {
+           opt.strict=1;
+           log_set_strict(1);
+         }
+       else if (pargs.r_opt == oNoStrict )
+         {
+           opt.strict=0;
+           log_set_strict(0);
+         }
+#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 */
@@ -1134,7 +1296,7 @@ main( int argc, char **argv )
             * initialized when init_shm_coprocessing() is called */
            set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) );
        }
-      #endif
+#endif
     }
 
 #ifdef HAVE_DOSISH_SYSTEM
@@ -1144,7 +1306,7 @@ main( int argc, char **argv )
         for (d=buf,s=opt.homedir; *s; s++)
             *d++ = *s == '\\'? '/': *s;
         *d = 0;
-        opt.homedir = buf;
+        set_homedir (buf);
     }
 #endif
 #ifdef USE_SHM_COPROCESSING
@@ -1153,13 +1315,43 @@ main( int argc, char **argv )
     }
 #endif
     /* initialize the secure memory. */
-    secmem_init( 16384 );
+    secmem_init( 32768 );
     maybe_setuid = 0;
     /* Okay, we are now working under our real uid */
 
+    set_native_charset (NULL); /* Try to auto set the character set */
+
+    /* Try for a version specific config file first */
     if( default_config )
       {
-       configname = make_filename(opt.homedir, "gpg" EXTSEP_S "conf", NULL );
+       char *name=m_strdup("gpg" EXTSEP_S "conf-" SAFE_VERSION);
+       char *ver=&name[strlen("gpg" EXTSEP_S "conf-")];
+
+       do
+         {
+           if(configname)
+             {
+               char *tok;
+
+               m_free(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));
+
+       m_free(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 );
@@ -1216,8 +1408,10 @@ main( int argc, char **argv )
     }
 
     while( optfile_parse( configfp, configname, &configlineno,
-                                               &pargs, opts) ) {
-       switch( pargs.r_opt ) {
+                                               &pargs, opts) )
+      {
+       switch( pargs.r_opt )
+         {
          case aCheckKeys: set_cmd( &cmd, aCheckKeys); break;
          case aListPackets: set_cmd( &cmd, aListPackets); break;
          case aImport: set_cmd( &cmd, aImport); break;
@@ -1227,7 +1421,10 @@ main( int argc, char **argv )
          case aSearchKeys: set_cmd( &cmd, aSearchKeys); break;
          case aRefreshKeys: set_cmd( &cmd, aRefreshKeys); break;
          case aExport: set_cmd( &cmd, aExport); break;
-         case aExportAll: set_cmd( &cmd, aExportAll); break;
+         case aExportAll:
+           opt.export_options|=EXPORT_INCLUDE_NON_RFC;
+           set_cmd(&cmd,aExport);
+           break;
          case aListKeys: set_cmd( &cmd, aListKeys); break;
          case aListSigs: set_cmd( &cmd, aListSigs); break;
          case aExportSecret: set_cmd( &cmd, aExportSecret); break;
@@ -1243,11 +1440,15 @@ main( int argc, char **argv )
          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;
-          case aDecryptFiles: set_cmd( &cmd, aDecryptFiles); break;
 
+         case aEncrFiles: multifile=1; /* fall through */
          case aEncr: set_cmd( &cmd, aEncr); break;
-         case aEncrFiles: set_cmd( &cmd, aEncrFiles ); break;
+
+         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;
@@ -1259,8 +1460,6 @@ main( int argc, char **argv )
          case aClearsign: set_cmd( &cmd, aClearsign); break;
          case aGenRevoke: set_cmd( &cmd, aGenRevoke); break;
          case aDesigRevoke: set_cmd( &cmd, aDesigRevoke); break;
-         case aVerify: set_cmd( &cmd, aVerify); break;
-         case aVerifyFiles: set_cmd( &cmd, aVerifyFiles); break;
          case aPrimegen: set_cmd( &cmd, aPrimegen); break;
          case aGenRandom: set_cmd( &cmd, aGenRandom); break;
          case aPrintMD: set_cmd( &cmd, aPrintMD); break;
@@ -1272,19 +1471,37 @@ main( int argc, char **argv )
          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: 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);
+            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;
          case oQuiet: opt.quiet = 1; break;
          case oNoTTY: tty_no_terminal(1); break;
          case oDryRun: opt.dry_run = 1; break;
          case oInteractive: opt.interactive = 1; break;
-         case oVerbose: g10_opt_verbose++;
-                   opt.verbose++; opt.list_sigs=1; break;
+         case oVerbose:
+           g10_opt_verbose++;
+           opt.verbose++;
+           opt.list_options|=LIST_SHOW_UNUSABLE_UIDS;
+           break;
          case oKOption: set_cmd( &cmd, aKMode ); break;
 
          case oBatch: opt.batch = 1; nogreeting = 1; break;
@@ -1293,7 +1510,7 @@ main( int argc, char **argv )
             opt.use_agent = 1;
 #else /* __riscos__ */
             opt.use_agent = 0;
-            not_implemented("use-agent");
+            riscos_not_implemented("use-agent");
 #endif /* __riscos__ */
             break;
           case oNoUseAgent: opt.use_agent = 0; break;
@@ -1301,7 +1518,15 @@ main( int argc, char **argv )
          case oAnswerYes: opt.answer_yes = 1; break;
          case oAnswerNo: opt.answer_no = 1; break;
          case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break;
-         case oShowKeyring: opt.show_keyring = 1; break;
+         case oPrimaryKeyring:
+           sl=append_to_strlist( &nrings, pargs.r.ret_str);
+           sl->flags=2;
+           break;
+         case oShowKeyring:
+           deprecated_warning(configname,configlineno,"--show-keyring",
+                              "--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 oStatusFD:
@@ -1309,7 +1534,7 @@ main( int argc, char **argv )
             break;
 #ifdef __riscos__
          case oStatusFile:
-            set_status_fd( iobuf_translate_file_handle ( fdopenfile (pargs.r.ret_str, 1), 1) );
+            set_status_fd( iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) );
             break;
 #endif /* __riscos__ */
          case oAttributeFD:
@@ -1317,7 +1542,7 @@ main( int argc, char **argv )
             break;
 #ifdef __riscos__
          case oAttributeFile:
-            set_attrib_fd(iobuf_translate_file_handle ( fdopenfile (pargs.r.ret_str, 1), 1) );
+            set_attrib_fd(iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) );
             break;
 #endif /* __riscos__ */
          case oLoggerFD:
@@ -1327,7 +1552,7 @@ main( int argc, char **argv )
 #ifdef __riscos__
          case oLoggerFile:
             log_set_logfile( NULL,
-                             iobuf_translate_file_handle ( fdopenfile (pargs.r.ret_str, 1), 1) );
+                             iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) );
             break;
 #endif /* __riscos__ */
          case oWithFingerprint:
@@ -1352,8 +1577,8 @@ main( int argc, char **argv )
          case oQuickRandom: quick_random_gen(1); break;
          case oSKComments: opt.sk_comments=1; break;
          case oNoSKComments: opt.sk_comments=0; break;
-         case oNoVersion: opt.no_version=1; 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;
          case oMarginalsNeeded: opt.marginals_needed = pargs.r.ret_int; break;
          case oMaxCertDepth: opt.max_cert_depth = pargs.r.ret_int; break;
@@ -1378,13 +1603,37 @@ main( int argc, char **argv )
          case oWithColons: opt.with_colons=':'; break;
 
          case oSkipVerify: opt.skip_verify=1; break;
-         case oCompressAlgo: opt.def_compress_algo = pargs.r.ret_int; break;
          case oCompressKeys: opt.compress_keys = 1; break;
          case aListSecretKeys: set_cmd( &cmd, aListSecretKeys); break;
-         case oAlwaysTrust: opt.always_trust = 1; break;
+           /* There are many programs (like mutt) that call gpg with
+              --always-trust so keep this option around for a long
+              time. */
+         case oAlwaysTrust: opt.trust_model=TM_ALWAYS; break;
+         case oTrustModel:
+           if(ascii_strcasecmp(pargs.r.ret_str,"pgp")==0)
+             opt.trust_model=TM_PGP;
+           else if(ascii_strcasecmp(pargs.r.ret_str,"classic")==0)
+             opt.trust_model=TM_CLASSIC;
+           else if(ascii_strcasecmp(pargs.r.ret_str,"always")==0)
+             opt.trust_model=TM_ALWAYS;
+           else if(ascii_strcasecmp(pargs.r.ret_str,"auto")==0)
+             opt.trust_model=TM_AUTO;
+           else
+             log_error("unknown trust model \"%s\"\n",pargs.r.ret_str);
+           break;
+         case oForceOwnertrust:
+           log_info(_("NOTE: %s is not for normal use!\n"),
+                    "--force-ownertrust");
+           opt.force_ownertrust=string_to_trust_value(pargs.r.ret_str);
+           if(opt.force_ownertrust==-1)
+             {
+               log_error("invalid ownertrust \"%s\"\n",pargs.r.ret_str);
+               opt.force_ownertrust=0;
+             }
+           break;
          case oLoadExtension:
 #ifndef __riscos__
-#ifdef USE_DYNAMIC_LINKING
+#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);
@@ -1393,19 +1642,19 @@ main( int argc, char **argv )
                                        pargs.r.ret_str);
 #endif
 #else /* __riscos__ */
-            not_implemented("load-extension");
+            riscos_not_implemented("load-extension");
 #endif /* __riscos__ */
            break;
          case oRFC1991:
-           opt.rfc1991 = 1;
-           opt.rfc2440 = 0;
+           opt.compliance = CO_RFC1991;
            opt.force_v4_certs = 0;
-           opt.sk_comments = 0;
            opt.escape_from = 1;
            break;
+         case oRFC2440:
          case oOpenPGP:
-           opt.rfc1991 = 0;
-           opt.rfc2440 = 1;
+           /* TODO: When 2440bis becomes a RFC, these may need
+               changing. */
+           opt.compliance = CO_RFC2440;
            opt.allow_non_selfsigned_uid = 1;
            opt.allow_freeform_uid = 1;
            opt.pgp2_workarounds = 0;
@@ -1417,30 +1666,26 @@ main( int argc, char **argv )
            opt.def_cipher_algo = 0;
            opt.def_digest_algo = 0;
            opt.cert_digest_algo = 0;
-           opt.def_compress_algo = 1;
+           opt.compress_algo = -1;
             opt.s2k_mode = 3; /* iterated+salted */
            opt.s2k_digest_algo = DIGEST_ALGO_SHA1;
-           opt.s2k_cipher_algo = CIPHER_ALGO_CAST5;
+           opt.s2k_cipher_algo = CIPHER_ALGO_3DES;
            break;
-         case oPGP2: opt.pgp2 = 1; break;
-         case oNoPGP2: opt.pgp2 = 0; break;
-         case oPGP6: opt.pgp6 = 1; break;
-         case oNoPGP6: opt.pgp6 = 0; break;
-         case oPGP7: opt.pgp7 = 1; break;
-         case oNoPGP7: opt.pgp7 = 0; break;
-         case oEmuChecksumBug: opt.emulate_bugs |= EMUBUG_GPGCHKSUM; break;
-         case oEmu3DESS2KBug:  opt.emulate_bugs |= EMUBUG_3DESS2K; break;
-         case oEmuMDEncodeBug: opt.emulate_bugs |= EMUBUG_MDENCODE; break;
+         case oPGP2:  opt.compliance = CO_PGP2;  break;
+         case oPGP6:  opt.compliance = CO_PGP6;  break;
+         case oPGP7:  opt.compliance = CO_PGP7;  break;
+         case oPGP8:  opt.compliance = CO_PGP8;  break;
+         case oGnuPG: opt.compliance = CO_GNUPG; break;
          case oCompressSigs: opt.compress_sigs = 1; break;
          case oRunAsShmCP:
 #ifndef __riscos__
-         #ifndef USE_SHM_COPROCESSING
+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
+endif
 #else /* __riscos__ */
-            not_implemented("run-as-shm-coprocess");
+            riscos_not_implemented("run-as-shm-coprocess");
 #endif /* __riscos__ */
            break;
          case oSetFilename: opt.set_filename = pargs.r.ret_str; break;
@@ -1452,14 +1697,54 @@ main( int argc, char **argv )
            break;
          case oSigPolicyURL: add_policy_url(pargs.r.ret_str,0); break;
          case oCertPolicyURL: add_policy_url(pargs.r.ret_str,1); break;
-          case oShowPolicyURL: opt.show_policy_url=1; break;
-         case oNoShowPolicyURL: opt.show_policy_url=0; break;
+          case oShowPolicyURL:
+           deprecated_warning(configname,configlineno,"--show-policy-url",
+                              "--list-options ","show-policy-urls");
+           deprecated_warning(configname,configlineno,"--show-policy-url",
+                              "--verify-options ","show-policy-urls");
+           opt.list_options|=LIST_SHOW_POLICY_URLS;
+           opt.verify_options|=VERIFY_SHOW_POLICY_URLS;
+           break;
+         case oNoShowPolicyURL:
+           deprecated_warning(configname,configlineno,"--no-show-policy-url",
+                              "--list-options ","no-show-policy-urls");
+           deprecated_warning(configname,configlineno,"--no-show-policy-url",
+                              "--verify-options ","no-show-policy-urls");
+           opt.list_options&=~LIST_SHOW_POLICY_URLS;
+           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 oComment: opt.comment_string = pargs.r.ret_str; break;
-         case oDefaultComment: opt.comment_string = NULL; break;
+         case oComment:
+           if(pargs.r.ret_str[0])
+             add_to_strlist(&opt.comments,pargs.r.ret_str);
+           break;
+         case oDefaultComment:
+           deprecated_warning(configname,configlineno,
+                              "--default-comment","--no-comments","");
+           /* fall through */
+         case oNoComments:
+           free_strlist(opt.comments);
+           opt.comments=NULL;
+           break;
          case oThrowKeyid: opt.throw_keyid = 1; break;
-         case oShowPhotos: opt.show_photos = 1; break;
-         case oNoShowPhotos: opt.show_photos = 0; break;
+         case oNoThrowKeyid: opt.throw_keyid = 0; break;
+         case oShowPhotos:
+           deprecated_warning(configname,configlineno,"--show-photos",
+                              "--list-options ","show-photos");
+           deprecated_warning(configname,configlineno,"--show-photos",
+                              "--verify-options ","show-photos");
+           opt.list_options|=LIST_SHOW_PHOTOS;
+           opt.verify_options|=VERIFY_SHOW_PHOTOS;
+           break;
+         case oNoShowPhotos:
+           deprecated_warning(configname,configlineno,"--no-show-photos",
+                              "--list-options ","no-show-photos");
+           deprecated_warning(configname,configlineno,"--no-show-photos",
+                              "--verify-options ","no-show-photos");
+           opt.list_options&=~LIST_SHOW_PHOTOS;
+           opt.verify_options&=~VERIFY_SHOW_PHOTOS;
+           break;
          case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break;
          case oForceV3Sigs: opt.force_v3_sigs = 1; break;
          case oNoForceV3Sigs: opt.force_v3_sigs = 0; break;
@@ -1478,12 +1763,22 @@ main( int argc, char **argv )
            sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
            sl->flags = 1;
            break;
+         case oHiddenEncryptTo: /* store the recipient in the second list */
+           sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
+           sl->flags = 1|2;
+           break;
          case oRecipient: /* store the recipient */
            add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
             any_explicit_recipient = 1;
            break;
+         case oHiddenRecipient: /* store the recipient with a flag */
+           sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings );
+           sl->flags = 2;
+            any_explicit_recipient = 1;
+           break;
          case oTextmodeShort: opt.textmode = 2; break;
          case oTextmode: opt.textmode=1;  break;
+         case oNoTextmode: opt.textmode=0;  break;
          case oExpert: opt.expert = 1; break;
          case oNoExpert: opt.expert = 0; break;
          case oAskSigExpire: opt.ask_sig_expire = 1; break;
@@ -1493,13 +1788,20 @@ main( int argc, char **argv )
          case oUser: /* store the local users */
            add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings );
            break;
-         case oCompress: opt.compress = pargs.r.ret_int; break;
+         case oCompress:
+           /* this is the -z command line option */
+           opt.compress_level = opt.bz2_compress_level = pargs.r.ret_int;
+           break;
+         case oCompressLevel: opt.compress_level = pargs.r.ret_int; break;
+         case oBZ2CompressLevel: opt.bz2_compress_level = pargs.r.ret_int; break;
+         case oBZ2CompressLowmem: opt.bz2_compress_lowmem=1; break;
          case oPasswdFD:
             pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0);
+            opt.use_agent = 0;
             break;
 #ifdef __riscos__
          case oPasswdFile:
-            pwfd = iobuf_translate_file_handle ( fdopenfile (pargs.r.ret_str, 0), 0);
+            pwfd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0);
             break;
 #endif /* __riscos__ */
          case oCommandFD:
@@ -1507,16 +1809,40 @@ main( int argc, char **argv )
             break;
 #ifdef __riscos__
          case oCommandFile:
-            opt.command_fd = iobuf_translate_file_handle ( fdopenfile (pargs.r.ret_str, 0), 0);
+            opt.command_fd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0);
             break;
 #endif /* __riscos__ */
          case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break;
          case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break;
+         case oCompressAlgo:
+           /* If it is all digits, stick a Z in front of it for
+              later.  This is for backwards compatibility with
+              versions that took the compress algorithm number. */
+           {
+             char *pt=pargs.r.ret_str;
+             while(*pt)
+               {
+                 if(!isdigit(*pt))
+                   break;
+
+                 pt++;
+               }
+
+             if(*pt=='\0')
+               {
+                 compress_algo_string=m_alloc(strlen(pargs.r.ret_str)+2);
+                 strcpy(compress_algo_string,"Z");
+                 strcat(compress_algo_string,pargs.r.ret_str);
+               }
+             else
+               compress_algo_string = m_strdup(pargs.r.ret_str);
+           }
+           break;
          case oCertDigestAlgo: cert_digest_string = m_strdup(pargs.r.ret_str); break;
          case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break;
          case oNoPermissionWarn: opt.no_perm_warn=1; break;
          case oNoMDCWarn: opt.no_mdc_warn=1; break;
-         case oCharset:
+          case oCharset:
            if( set_native_charset( pargs.r.ret_str ) )
                log_error(_("%s is not a valid character set\n"),
                                                    pargs.r.ret_str);
@@ -1530,7 +1856,7 @@ main( int argc, char **argv )
 #ifndef __riscos__
            opt.lock_once = 0;
 #else /* __riscos__ */
-            not_implemented("lock-multiple");
+            riscos_not_implemented("lock-multiple");
 #endif /* __riscos__ */
             break;
          case oKeyServer:
@@ -1542,7 +1868,7 @@ main( int argc, char **argv )
            parse_keyserver_options(pargs.r.ret_str);
            break;
          case oImportOptions:
-           if(!parse_import_options(pargs.r.ret_str,&opt.import_options))
+           if(!parse_import_options(pargs.r.ret_str,&opt.import_options,1))
              {
                if(configname)
                  log_error(_("%s:%d: invalid import options\n"),
@@ -1552,7 +1878,7 @@ main( int argc, char **argv )
              }
            break;
          case oExportOptions:
-           if(!parse_export_options(pargs.r.ret_str,&opt.export_options))
+           if(!parse_export_options(pargs.r.ret_str,&opt.export_options,1))
              {
                if(configname)
                  log_error(_("%s:%d: invalid export options\n"),
@@ -1561,6 +1887,56 @@ main( int argc, char **argv )
                  log_error(_("invalid export options\n"));
              }
            break;
+         case oListOptions:
+           {
+             struct parse_options lopts[]=
+               {
+                 {"show-photos",LIST_SHOW_PHOTOS},
+                 {"show-policy-urls",LIST_SHOW_POLICY_URLS},
+                 {"show-notations",LIST_SHOW_NOTATIONS},
+                 {"show-keyserver-urls",LIST_SHOW_KEYSERVER_URLS},
+                 {"show-validity",LIST_SHOW_VALIDITY},
+                 {"show-long-keyids",LIST_SHOW_LONG_KEYIDS},
+                 {"show-unusable-uids",LIST_SHOW_UNUSABLE_UIDS},
+                 {"show-keyring",LIST_SHOW_KEYRING},
+                 {"show-sig-expire",LIST_SHOW_SIG_EXPIRE},
+                 {NULL,0}
+               };
+
+             if(!parse_options(pargs.r.ret_str,&opt.list_options,lopts,1))
+               {
+                 if(configname)
+                   log_error(_("%s:%d: invalid list options\n"),
+                             configname,configlineno);
+                 else
+                   log_error(_("invalid list options\n"));
+               }
+           }
+           break;
+         case oVerifyOptions:
+           {
+             struct parse_options vopts[]=
+               {
+                 {"show-photos",VERIFY_SHOW_PHOTOS},
+                 {"show-policy-urls",VERIFY_SHOW_POLICY_URLS},
+                 {"show-notations",VERIFY_SHOW_NOTATIONS},
+                 {"show-keyserver-urls",VERIFY_SHOW_KEYSERVER_URLS},
+                 {"show-validity",VERIFY_SHOW_VALIDITY},
+                 {"show-long-keyids",VERIFY_SHOW_LONG_KEYIDS},
+                 {"show-unusable-uids",VERIFY_SHOW_UNUSABLE_UIDS},
+                 {NULL,0}
+               };
+
+             if(!parse_options(pargs.r.ret_str,&opt.verify_options,vopts,1))
+               {
+                 if(configname)
+                   log_error(_("%s:%d: invalid verify options\n"),
+                             configname,configlineno);
+                 else
+                   log_error(_("invalid verify options\n"));
+               }
+           }
+           break;
          case oTempDir: opt.temp_dir=pargs.r.ret_str; break;
          case oExecPath:
            if(set_exec_path(pargs.r.ret_str,0))
@@ -1568,14 +1944,28 @@ main( int argc, char **argv )
            else
              opt.exec_path_set=1;
            break;
-         case oNotation:
+         case oSetNotation:
            add_notation_data( pargs.r.ret_str, 0 );
            add_notation_data( pargs.r.ret_str, 1 );
            break;
          case oSigNotation: add_notation_data( pargs.r.ret_str, 0 ); break;
          case oCertNotation: add_notation_data( pargs.r.ret_str, 1 ); break;
-         case oShowNotation: opt.show_notation=1; break;
-         case oNoShowNotation: opt.show_notation=0; break;
+         case oShowNotation:
+           deprecated_warning(configname,configlineno,"--show-notation",
+                              "--list-options ","show-notations");
+           deprecated_warning(configname,configlineno,"--show-notation",
+                              "--verify-options ","show-notations");
+           opt.list_options|=LIST_SHOW_NOTATIONS;
+           opt.verify_options|=VERIFY_SHOW_NOTATIONS;
+           break;
+         case oNoShowNotation:
+           deprecated_warning(configname,configlineno,"--no-show-notation",
+                              "--list-options ","no-show-notations");
+           deprecated_warning(configname,configlineno,"--no-show-notation",
+                              "--verify-options ","no-show-notations");
+           opt.list_options&=~LIST_SHOW_NOTATIONS;
+           opt.verify_options&=~VERIFY_SHOW_NOTATIONS;
+           break;
          case oUtf8Strings: utf8_strings = 1; break;
          case oNoUtf8Strings: utf8_strings = 0; break;
          case oDisableCipherAlgo:
@@ -1593,11 +1983,10 @@ main( int argc, char **argv )
          case oNoLiteral: opt.no_literal = 1; break;
          case oSetFilesize: opt.set_filesize = pargs.r.ret_ulong; break;
          case oHonorHttpProxy:
-                opt.keyserver_options.honor_http_proxy = 1;
+               add_to_strlist(&opt.keyserver_options.other,"http-proxy");
                deprecated_warning(configname,configlineno,
                                   "--honor-http-proxy",
-                                  "--keyserver-options ",
-                                  "honor-http-proxy");
+                                  "--keyserver-options ","http-proxy");
                break;
          case oFastListMode: opt.fast_list_mode = 1; break;
          case oFixedListMode: opt.fixed_list_mode = 1; break;
@@ -1621,7 +2010,11 @@ main( int argc, char **argv )
          case oOverrideSessionKey:
                opt.override_session_key = pargs.r.ret_str;
                break;
-         case oMergeOnly: opt.merge_only = 1; break;
+         case oMergeOnly:
+               deprecated_warning(configname,configlineno,"--merge-only",
+                                  "--import-options ","merge-only");
+               opt.import_options|=IMPORT_MERGE_ONLY;
+           break;
           case oAllowSecretKeyImport: /* obsolete */ break;
          case oTryAllSecrets: opt.try_all_secrets = 1; break;
           case oTrustedKey: register_trusted_key( pargs.r.ret_str ); break;
@@ -1650,9 +2043,25 @@ main( int argc, char **argv )
           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 oNoGroups:
+           while(opt.grouplist)
+             {
+               struct groupitem *iter=opt.grouplist;
+               free_strlist(iter->values);
+               opt.grouplist=opt.grouplist->next;
+               m_free(iter);
+             }
+           break;
+         case oStrict: opt.strict=1; log_set_strict(1); break;
+         case oNoStrict: opt.strict=0; log_set_strict(0); 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;
+         case oMultifile: multifile=1; break;
+
          default : pargs.err = configfp? 1:2; break;
-       }
-    }
+         }
+      }
 
     if( configfp ) {
        fclose( configfp );
@@ -1671,13 +2080,22 @@ main( int argc, char **argv )
                        strusage(11), strusage(13), strusage(14) );
        fprintf(stderr, "%s\n", strusage(15) );
     }
-  #ifdef IS_DEVELOPMENT_VERSION
-    if( !opt.batch ) {
-       log_info("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
-       log_info("It is only intended for test purposes and should NOT be\n");
-       log_info("used in a production environment or with production keys!\n");
-    }
-  #endif
+#ifdef IS_DEVELOPMENT_VERSION
+    if( !opt.batch )
+      {
+       const char *s;
+
+       if((s=strusage(20)))
+         log_info("%s\n",s);
+       if((s=strusage(21)))
+         log_info("%s\n",s);
+       if((s=strusage(22)))
+         log_info("%s\n",s);
+      }
+#endif
+
+    if (opt.verbose > 2)
+        log_info ("using character set `%s'\n", get_native_charset ());
 
     if( may_coredump && !opt.quiet )
        log_info(_("WARNING: program may create a core file!\n"));
@@ -1709,104 +2127,104 @@ main( int argc, char **argv )
     secmem_set_flags( secmem_get_flags() & ~2 ); /* resume warnings */
 
     set_debug();
-    g10_opt_homedir = opt.homedir;
 
     /* Do these after the switch(), so they can override settings. */
-    if(opt.pgp2 && (opt.pgp6 || opt.pgp7))
-      log_error(_("%s not allowed with %s!\n"),
-               "--pgp2",opt.pgp6?"--pgp6":"--pgp7");
-    else
+    if(PGP2)
       {
-       if(opt.pgp2)
+       int unusable=0;
+
+       if(cmd==aSign && !detached_sig)
+         {
+           log_info(_("you can only make detached or clear signatures "
+                      "while in --pgp2 mode\n"));
+           unusable=1;
+         }
+       else if(cmd==aSignEncr || cmd==aSignSym)
          {
-           int unusable=0;
+           log_info(_("you can't sign and encrypt at the "
+                      "same time while in --pgp2 mode\n"));
+           unusable=1;
+         }
+       else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym))
+         {
+           log_info(_("you must use files (and not a pipe) when "
+                      "working with --pgp2 enabled.\n"));
+           unusable=1;
+         }
+       else if(cmd==aEncr || cmd==aSym)
+         {
+           /* Everything else should work without IDEA (except using
+              a secret key encrypted with IDEA and setting an IDEA
+              preference, but those have their own error
+              messages). */
 
-           if(cmd==aSign && !detached_sig)
+           if(check_cipher_algo(CIPHER_ALGO_IDEA))
              {
-               log_info(_("you can only make detached or clear signatures "
-                          "while in --pgp2 mode\n"));
+               log_info(_("encrypting a message in --pgp2 mode requires "
+                          "the IDEA cipher\n"));
+               idea_cipher_warn(1);
                unusable=1;
              }
-           else if(cmd==aSignEncr || cmd==aSignSym)
+           else if(cmd==aSym)
              {
-               log_info(_("you can't sign and encrypt at the "
-                          "same time while in --pgp2 mode\n"));
-               unusable=1;
-             }
-           else if(argc==0 && (cmd==aSign || cmd==aEncr || cmd==aSym))
-             {
-               log_info(_("you must use files (and not a pipe) when "
-                          "working with --pgp2 enabled.\n"));
-               unusable=1;
-             }
-           else if(cmd==aEncr || cmd==aSym)
-             {
-               /* Everything else should work without IDEA (except using
-                  a secret key encrypted with IDEA and setting an IDEA
-                  preference, but those have their own error
-                  messages). */
-
-               if(check_cipher_algo(CIPHER_ALGO_IDEA))
-                 {
-                   log_info(_("encrypting a message in --pgp2 mode requires "
-                              "the IDEA cipher\n"));
-                   idea_cipher_warn(1);
-                   unusable=1;
-                 }
-               else if(cmd==aSym)
-                 {
-                   m_free(def_cipher_string);
-                   def_cipher_string = m_strdup("idea");
-                 }
+               /* This only sets IDEA for symmetric encryption
+                  since it is set via select_algo_from_prefs for
+                  pk encryption. */
+               m_free(def_cipher_string);
+               def_cipher_string = m_strdup("idea");
              }
 
-           if(unusable)
-             {
-               log_info(_("this message may not be usable by %s\n"),
-                        "PGP 2.x");
-               opt.pgp2=0;
-             }
-           else
-             {
-               opt.rfc1991 = 1;
-               opt.rfc2440 = 0;
-               opt.force_mdc = 0;
-               opt.disable_mdc = 1;
-               opt.force_v4_certs = 0;
-               opt.sk_comments = 0;
-               opt.escape_from = 1;
-               opt.force_v3_sigs = 1;
-               opt.pgp2_workarounds = 1;
-               opt.ask_sig_expire = 0;
-               opt.ask_cert_expire = 0;
-               m_free(def_digest_string);
-               def_digest_string = m_strdup("md5");
-               opt.def_compress_algo = 1;
-             }
+           /* PGP2 can't handle the output from the textmode
+              filter, so we disable it for anything that could
+              create a literal packet (only encryption and
+              symmetric encryption, since we disable signing
+              above). */
+           if(!unusable)
+             opt.textmode=0;
          }
 
-       if(opt.pgp6 || opt.pgp7)
+       if(unusable)
+         compliance_failure();
+       else
          {
-           opt.sk_comments=0;
-           opt.escape_from=1;
-           opt.force_v3_sigs=1;
-           opt.ask_sig_expire=0;
-           opt.def_compress_algo=1;
-
-           if(opt.pgp6) /* pgp7 has MDC */
-             {
-               opt.force_mdc=0;
-               opt.disable_mdc=1;
-             }
+           opt.force_v4_certs = 0;
+           opt.sk_comments = 0;
+           opt.escape_from = 1;
+           opt.force_v3_sigs = 1;
+           opt.pgp2_workarounds = 1;
+           opt.ask_sig_expire = 0;
+           opt.ask_cert_expire = 0;
+           m_free(def_digest_string);
+           def_digest_string = m_strdup("md5");
+           opt.compress_algo = COMPRESS_ALGO_ZIP;
          }
       }
+    else if(PGP6)
+      {
+       opt.sk_comments=0;
+       opt.escape_from=1;
+       opt.force_v3_sigs=1;
+       opt.ask_sig_expire=0;
+      }
+    else if(PGP7)
+      {
+       opt.sk_comments=0;
+       opt.escape_from=1;
+       opt.force_v3_sigs=1;
+       opt.ask_sig_expire=0;
+      }
+    else if(PGP8)
+      {
+       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);
        if(opt.def_cipher_algo==0 &&
-          ascii_strcasecmp(def_cipher_string,"idea")==0)
+          (ascii_strcasecmp(def_cipher_string,"idea")==0
+           || ascii_strcasecmp(def_cipher_string,"s1")==0))
          idea_cipher_warn(1);
        m_free(def_cipher_string); def_cipher_string = NULL;
        if( check_cipher_algo(opt.def_cipher_algo) )
@@ -1818,6 +2236,12 @@ main( int argc, char **argv )
        if( check_digest_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);
+       m_free(compress_algo_string); compress_algo_string = NULL;
+       if( check_compress_algo(opt.compress_algo) )
+           log_error(_("selected compression algorithm is invalid\n"));
+    }
     if( cert_digest_string ) {
        opt.cert_digest_algo = string_to_digest_algo(cert_digest_string);
        m_free(cert_digest_string); cert_digest_string = NULL;
@@ -1836,8 +2260,6 @@ main( int argc, char **argv )
        if( check_digest_algo(opt.s2k_digest_algo) )
            log_error(_("selected digest algorithm is invalid\n"));
     }
-    if( opt.def_compress_algo < -1 || opt.def_compress_algo > 2 )
-       log_error(_("compress algorithm must be in range %d..%d\n"), 0, 2);
     if( opt.completes_needed < 1 )
        log_error(_("completes-needed must be greater than 0\n"));
     if( opt.marginals_needed < 2 )
@@ -1878,9 +2300,103 @@ main( int argc, char **argv )
        keygen_set_std_prefs(pers_compress_list,PREFTYPE_ZIP))
       log_error(_("invalid personal compress preferences\n"));
 
+    /* We don't support all possible commands with multifile yet */
+    if(multifile)
+      {
+       char *cmdname;
+
+       switch(cmd)
+         {
+         case aSign:
+           cmdname="--sign";
+           break;
+         case aClearsign:
+           cmdname="--clearsign";
+           break;
+         case aDetachedSign:
+           cmdname="--detach-sign";
+           break;
+         case aSym:
+           cmdname="--symmetric";
+           break;
+         case aEncrSym:
+           cmdname="--symmetric --encrypt";
+           break;
+         case aStore:
+           cmdname="--store";
+           break;
+         default:
+           cmdname=NULL;
+           break;
+         }
+
+       if(cmdname)
+         log_error(_("%s does not yet work with %s\n"),cmdname,"--multifile");
+      }
+
     if( log_get_errorcount(0) )
        g10_exit(2);
 
+    /* Check our chosen algorithms against the list of legal
+       algorithms. */
+
+    if(!GNUPG)
+      {
+       const char *badalg=NULL;
+       preftype_t badtype=PREFTYPE_NONE;
+
+       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;
+         }
+       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;
+         }
+       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;
+         }
+       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;
+         }
+
+       if(badalg)
+         {
+           switch(badtype)
+             {
+             case PREFTYPE_SYM:
+               log_info(_("you may not use cipher algorithm \"%s\" "
+                          "while in %s mode\n"),
+                        badalg,compliance_option_string());
+               break;
+             case PREFTYPE_HASH:
+               log_info(_("you may not use digest algorithm \"%s\" "
+                          "while in %s mode\n"),
+                        badalg,compliance_option_string());
+               break;
+             case PREFTYPE_ZIP:
+               log_info(_("you may not use compression algorithm \"%s\" "
+                          "while in %s mode\n"),
+                        badalg,compliance_option_string());
+               break;
+             default:
+               BUG();
+             }
+
+           compliance_failure();
+         }
+      }
+
     /* set the random seed file */
     if( use_random_seed ) {
        char *p = make_filename(opt.homedir, "random_seed", NULL );
@@ -1907,10 +2423,6 @@ main( int argc, char **argv )
        g10_opt_verbose = opt.verbose;
     }
 
-    /* Compression algorithm 0 means no compression at all */
-    if( opt.def_compress_algo == 0)
-        opt.compress = 0;
-
     /* kludge to let -sat generate a clear text signature */
     if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign )
        cmd = aClearsign;
@@ -1926,8 +2438,7 @@ main( int argc, char **argv )
        && !(cmd == aKMode && argc == 2 ) ) 
       {
         if (cmd != aCheckKeys && cmd != aListSigs && cmd != aListKeys
-            && cmd != aVerify && cmd != aVerifyFiles
-            && cmd != aSym)
+            && cmd != aVerify && cmd != aSym)
           {
             if (!sec_nrings || default_keyring) /* add default secret rings */
               keydb_add_resource ("secring" EXTSEP_S "gpg", 0, 1);
@@ -1937,7 +2448,7 @@ main( int argc, char **argv )
        if( !nrings || default_keyring )  /* add default ring */
            keydb_add_resource ("pubring" EXTSEP_S "gpg", 0, 0);
        for(sl = nrings; sl; sl = sl->next )
-           keydb_add_resource ( sl->d, 0, 0 );
+           keydb_add_resource ( sl->d, sl->flags, 0 );
       }
     FREE_STRLIST(nrings);
     FREE_STRLIST(sec_nrings);
@@ -1957,13 +2468,6 @@ main( int argc, char **argv )
       case aEnArmor:
       case aFixTrustDB:
        break;
-      case aKMode:
-      case aListKeys:
-      case aListSecretKeys:
-      case aCheckKeys:
-       if( opt.with_colons ) /* need this to list the trust */
-           rc = setup_trustdb(1, trustdb_name );
-       break;
       case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break;
       case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break;
       default: rc = setup_trustdb(1, trustdb_name ); break;
@@ -2003,16 +2507,39 @@ main( int argc, char **argv )
        break;
 
       case aEncr: /* encrypt the given file */
+       if(multifile)
+         encode_crypt_files(argc, argv, remusr);
+       else
+         {
+           if( argc > 1 )
+             wrong_args(_("--encrypt [filename]"));
+           if( (rc = encode_crypt(fname,remusr,0)) )
+             log_error("%s: encryption failed: %s\n",
+                       print_fname_stdin(fname), g10_errstr(rc) );
+         }
+       break;
+
+      case aEncrSym:
+       /* This works with PGP 8 in the sense that it acts just like a
+          symmetric message.  It doesn't work at all with 2 or 6.  It
+          might work with 7, but alas, I don't have a copy to test
+          with right now. */
        if( argc > 1 )
-           wrong_args(_("--encrypt [filename]"));
-       if( (rc = encode_crypt(fname,remusr)) )
-           log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
+         wrong_args(_("--symmetric --encrypt [filename]"));
+       else if(opt.s2k_mode==0)
+         log_error(_("you cannot use --symmetric --encrypt"
+                     " with --s2k-mode 0\n"));
+       else if(PGP2 || PGP6 || PGP7 || RFC1991)
+         log_error(_("you cannot use --symmetric --encrypt"
+                     " while in %s mode\n"),compliance_option_string());
+       else
+         {
+           if( (rc = encode_crypt(fname,remusr,1)) )
+             log_error("%s: encryption failed: %s\n",
+                       print_fname_stdin(fname), g10_errstr(rc) );
+         }
        break;
 
-      case aEncrFiles: /* encrypt the given files */
-        encode_crypt_files(argc, argv, remusr);
-       break;
-          
       case aSign: /* sign the given file */
        sl = NULL;
        if( detached_sig ) { /* sign all files */
@@ -2042,10 +2569,36 @@ main( int argc, char **argv )
        else
            sl = NULL;
        if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
-           log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
+           log_error("%s: sign+encrypt failed: %s\n",
+                     print_fname_stdin(fname), g10_errstr(rc) );
        free_strlist(sl);
        break;
 
+      case aSignEncrSym: /* sign and encrypt the given file */
+       if( argc > 1 )
+           wrong_args(_("--symmetric --sign --encrypt [filename]"));
+       else if(opt.s2k_mode==0)
+         log_error(_("you cannot use --symmetric --sign --encrypt"
+                     " with --s2k-mode 0\n"));
+       else if(PGP2 || PGP6 || PGP7 || RFC1991)
+         log_error(_("you cannot use --symmetric --sign --encrypt"
+                     " while in %s mode\n"),compliance_option_string());
+       else
+         {
+           if( argc )
+             {
+               sl = m_alloc_clear( sizeof *sl + strlen(fname));
+               strcpy(sl->d, fname);
+             }
+           else
+             sl = NULL;
+           if( (rc = sign_file(sl, detached_sig, locusr, 2, remusr, NULL)) )
+             log_error("%s: symmetric+sign+encrypt failed: %s\n",
+                       print_fname_stdin(fname), g10_errstr(rc) );
+           free_strlist(sl);
+         }
+       break;
+
       case aSignSym: /* sign and conventionally encrypt the given file */
        if (argc > 1)
            wrong_args(_("--sign --symmetric [filename]"));
@@ -2064,25 +2617,29 @@ main( int argc, char **argv )
        break;
 
       case aVerify:
-       if( (rc = verify_signatures( argc, argv ) ))
-           log_error("verify signatures failed: %s\n", g10_errstr(rc) );
-       break;
-
-      case aVerifyFiles:
-       if( (rc = verify_files( argc, argv ) ))
-           log_error("verify files failed: %s\n", g10_errstr(rc) );
+       if(multifile)
+         {
+           if( (rc = verify_files( argc, argv ) ))
+             log_error("verify files failed: %s\n", g10_errstr(rc) );
+         }
+       else
+         {
+           if( (rc = verify_signatures( argc, argv ) ))
+             log_error("verify signatures failed: %s\n", g10_errstr(rc) );
+         }
        break;
 
       case aDecrypt:
-       if( argc > 1 )
-           wrong_args(_("--decrypt [filename]"));
-       if( (rc = decrypt_message( fname ) ))
-           log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
+        if(multifile)
+         decrypt_messages(argc, argv);
+       else
+         {
+           if( argc > 1 )
+             wrong_args(_("--decrypt [filename]"));
+           if( (rc = decrypt_message( fname ) ))
+             log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
+         }
        break;
-
-      case aDecryptFiles:
-        decrypt_messages(argc, argv);
-        break;
             
       case aSignKey: /* sign the key given as argument */
        if( argc != 1 )
@@ -2196,34 +2753,42 @@ main( int argc, char **argv )
        if( opt.batch ) {
            if( argc > 1 )
                wrong_args("--gen-key [parameterfile]");
-           generate_keypair( argc? *argv : NULL );
+           generate_keypair( argc? *argv : NULL, NULL );
        }
        else {
            if( argc )
                wrong_args("--gen-key");
-           generate_keypair(NULL);
+           generate_keypair(NULL, NULL);
        }
        break;
 
       case aFastImport:
+        opt.import_options |= IMPORT_FAST_IMPORT;
       case aImport:
-       import_keys( argc? argv:NULL, argc, (cmd == aFastImport),
-                    NULL, opt.import_options );
+       import_keys( argc? argv:NULL, argc, NULL, opt.import_options );
        break;
 
       case aExport:
-      case aExportAll:
       case aSendKeys:
       case aRecvKeys:
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist2( &sl, *argv, utf8_strings );
        if( cmd == aSendKeys )
-           keyserver_export( sl );
+           rc=keyserver_export( sl );
        else if( cmd == aRecvKeys )
-           keyserver_import( sl );
+           rc=keyserver_import( sl );
        else
-           export_pubkeys( sl, opt.export_options );
+           rc=export_pubkeys( sl, opt.export_options );
+       if(rc)
+         {
+           if(cmd==aSendKeys)
+             log_error(_("keyserver send failed: %s\n"),g10_errstr(rc));
+           else if(cmd==aRecvKeys)
+             log_error(_("keyserver receive failed: %s\n"),g10_errstr(rc));
+           else
+             log_error(_("key export failed: %s\n"),g10_errstr(rc));
+         }
        free_strlist(sl);
        break;
 
@@ -2231,8 +2796,9 @@ main( int argc, char **argv )
        sl = NULL;
        for( ; argc; argc--, argv++ )
          append_to_strlist2( &sl, *argv, utf8_strings );
-
-       keyserver_search( sl );
+       rc=keyserver_search( sl );
+       if(rc)
+         log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
        free_strlist(sl);
        break;
 
@@ -2240,7 +2806,9 @@ main( int argc, char **argv )
        sl = NULL;
        for( ; argc; argc--, argv++ )
            add_to_strlist2( &sl, *argv, utf8_strings );
-       keyserver_refresh(sl);
+       rc=keyserver_refresh(sl);
+       if(rc)
+         log_error(_("keyserver refresh failed: %s\n"),g10_errstr(rc));
        free_strlist(sl);
        break;
 
@@ -2345,9 +2913,9 @@ main( int argc, char **argv )
                size_t n = !endless && count < 99? count : 99;
 
                p = get_random_bits( n*8, level, 0);
-             #ifdef HAVE_DOSISH_SYSTEM
+#ifdef HAVE_DOSISH_SYSTEM
                setmode ( fileno(stdout), O_BINARY );
-             #endif
+#endif
                 if (opt.armor) {
                     char *tmp = make_radix64_string (p, n);
                     fputs (tmp, stdout);
@@ -2458,6 +3026,36 @@ main( int argc, char **argv )
         keydb_rebuild_caches ();
         break;
 
+#ifdef ENABLE_CARD_SUPPORT
+      case aCardStatus:
+        if (argc)
+            wrong_args ("--card-status");
+        card_status (stdout, NULL, 0);
+        break;
+
+      case aCardEdit:
+        if (argc) {
+            sl = NULL;
+            for (argc--, argv++ ; argc; argc--, argv++)
+                append_to_strlist (&sl, *argv);
+            card_edit (sl);
+            free_strlist (sl);
+       }
+        else
+            card_edit (NULL);
+        break;
+
+      case aChangePIN:
+        if (!argc)
+            change_pin (0);
+        else if (argc == 1)
+            change_pin ( atoi (*argv));
+        else
+        wrong_args ("--change-pin [no]");
+        break;
+#endif /* ENABLE_CARD_SUPPORT*/
+
+
       case aListPackets:
        opt.list_packets=2;
       default:
@@ -2501,6 +3099,9 @@ main( int argc, char **argv )
 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");
@@ -2515,40 +3116,87 @@ g10_exit( int rc )
 }
 
 
-
-
+/* Pretty-print hex hashes.  This assumes at least an 80-character
+   display, but there are a few other similar assumptions in the
+   display code. */
 static void
-print_hex( byte *p, size_t n )
+print_hex( MD_HANDLE md, int algo, const char *fname )
 {
-    int i;
+  int i,n,count,indent=0;
+  const byte *p;
 
-    if( n == 20 ) {
-       for(i=0; i < n ; i++, i++, p += 2 ) {
-           if( i )
-               putchar(' ');
-           if( i == 10 )
-               putchar(' ');
-           printf("%02X%02X", *p, p[1] );
-       }
+  if(fname)
+    indent=printf("%s: ",fname);
+
+  if(indent>40)
+    {
+      printf("\n");
+      indent=0;
     }
-    else if( n == 24 ) {
-       for(i=0; i < n ; i += 4, p += 4 ) {
-           if( i )
-               putchar(' ');
-           if( i == 12 )
-               putchar(' ');
-           printf("%02X%02X%02X%02X", *p, p[1], p[2], p[3] );
+
+  if(algo==DIGEST_ALGO_RMD160)
+    indent+=printf("RMD160 = ");
+  else if(algo>0)
+    indent+=printf("%6s = ",digest_algo_to_string(algo));
+  else
+    algo=abs(algo);
+
+  count=indent;
+
+  p = md_read( md, algo );
+  n = md_digest_length(algo);
+
+  count+=printf("%02X",*p++);
+
+  for(i=1;i<n;i++,p++)
+    {
+      if(n==16)
+       {
+         if(count+2>79)
+           {
+             printf("\n%*s",indent," ");
+             count=indent;
+           }
+         else
+           count+=printf(" ");
+
+         if(!(i%8))
+           count+=printf(" ");
        }
-    }
-    else {
-       for(i=0; i < n ; i++, p++ ) {
-           if( i )
-               putchar(' ');
-           if( i && !(i%8) )
-               putchar(' ');
-           printf("%02X", *p );
+      else if (n==20)
+       {
+         if(!(i%2))
+           {
+             if(count+4>79)
+               {
+                 printf("\n%*s",indent," ");
+                 count=indent;
+               }
+             else
+               count+=printf(" ");
+           }
+
+         if(!(i%10))
+           count+=printf(" ");
+       }
+      else
+       {
+         if(!(i%4))
+           {
+             if(count+8>79)
+               {
+                 printf("\n%*s",indent," ");
+                 count=indent;
+               }
+             else
+               count+=printf(" ");
+           }
        }
+
+      count+=printf("%02X",*p);
     }
+
+  printf("\n");
 }
 
 static void
@@ -2582,23 +3230,18 @@ print_mds( const char *fname, int algo )
     char buf[1024];
     size_t n;
     MD_HANDLE md;
-    char *pname;
 
     if( !fname ) {
        fp = stdin;
-      #ifdef HAVE_DOSISH_SYSTEM
+#ifdef HAVE_DOSISH_SYSTEM
        setmode ( fileno(fp) , O_BINARY );
-      #endif
-       pname = m_strdup("[stdin]: ");
+#endif
     }
     else {
-       pname = m_alloc(strlen(fname)+3);
-       strcpy(stpcpy(pname,fname),": ");
        fp = fopen( fname, "rb" );
     }
     if( !fp ) {
-       log_error("%s%s\n", pname, strerror(errno) );
-       m_free(pname);
+       log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
        return;
     }
 
@@ -2609,14 +3252,19 @@ print_mds( const char *fname, int algo )
        md_enable( md, DIGEST_ALGO_MD5 );
        md_enable( md, DIGEST_ALGO_SHA1 );
        md_enable( md, DIGEST_ALGO_RMD160 );
-       if( !check_digest_algo(DIGEST_ALGO_TIGER) )
-           md_enable( md, DIGEST_ALGO_TIGER );
+#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
     }
 
     while( (n=fread( buf, 1, DIM(buf), fp )) )
        md_write( md, buf, n );
     if( ferror(fp) )
-       log_error("%s%s\n", pname, strerror(errno) );
+       log_error("%s: %s\n", fname?fname:"[stdin]", strerror(errno) );
     else {
        md_final(md);
         if ( opt.with_colons ) {
@@ -2626,29 +3274,30 @@ print_mds( const char *fname, int algo )
                 print_hashline( md, DIGEST_ALGO_MD5, fname );
                 print_hashline( md, DIGEST_ALGO_SHA1, fname );
                 print_hashline( md, DIGEST_ALGO_RMD160, fname );
-                if( !check_digest_algo(DIGEST_ALGO_TIGER) ) 
-                    print_hashline( md, DIGEST_ALGO_TIGER, 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
             }
         }
         else {
-            if( algo ) {
-                if( fname )
-                    fputs( pname, stdout );
-                print_hex(md_read(md, algo), md_digest_length(algo) );
-            }
+            if( algo )
+              print_hex(md,-algo,fname);
             else {
-                printf(  "%s   MD5 = ", fname?pname:"" );
-                print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
-                printf("\n%s  SHA1 = ", fname?pname:""  );
-                print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
-                printf("\n%sRMD160 = ", fname?pname:""  );
-                print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
-                if( !check_digest_algo(DIGEST_ALGO_TIGER) ) {
-                    printf("\n%s TIGER = ", fname?pname:""  );
-                    print_hex(md_read(md, DIGEST_ALGO_TIGER), 24 );
-                }
+                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
             }
-            putchar('\n');
         }
     }
     md_close(md);
@@ -2670,6 +3319,7 @@ add_notation_data( const char *string, int which )
     STRLIST sl,*notation_data;
     int critical=0;
     int highbit=0;
+    int saw_at=0;
 
     if(which)
       notation_data=&opt.cert_notation_data;
@@ -2681,23 +3331,39 @@ add_notation_data( const char *string, int which )
        string++;
     }
 
-    for( s=string ; *s != '='; s++ ) {
-       if( !*s || (*s & 0x80) || (!isgraph(*s) && !isspace(*s)) ) {
+    /* If and when the IETF assigns some official name tags, we'll
+       have to add them here. */
+
+    for( s=string ; *s != '='; s++ )
+      {
+       if( *s=='@')
+         saw_at=1;
+
+       if( !*s || (*s & 0x80) || (!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;
+      }
+
     /* we only support printable text - therefore we enforce the use
      * of only printable characters (an empty value is valid) */
     for( s++; *s ; s++ ) {
-       if( iscntrl(*s) ) {
+       if ((*s & 0x80))
+          highbit = 1;
+       else if (iscntrl(*s)) {
            log_error(_("a notation value must not use "
                        "any control characters\n") );
            return;
        }
-       else if( *s & 0x80 )
-           highbit = 1;
     }
 
     if( highbit )   /* must use UTF8 encoding */
@@ -2709,7 +3375,6 @@ add_notation_data( const char *string, int which )
        sl->flags |= 1;
 }
 
-
 static void
 add_policy_url( const char *string, int which )
 {
@@ -2742,3 +3407,37 @@ add_policy_url( const char *string, int which )
   if(critical)
     sl->flags |= 1;    
 }
+
+static void
+add_keyserver_url( const char *string, int which )
+{
+  int i,critical=0;
+  STRLIST sl;
+
+  if(*string=='!')
+    {
+      string++;
+      critical=1;
+    }
+
+  for(i=0;i<strlen(string);i++)
+    if(string[i]&0x80 || iscntrl(string[i]))
+      break;
+
+  if(i==0 || i<strlen(string))
+    {
+      if(which)
+       BUG();
+      else
+       log_error(_("the given signature preferred"
+                   " keyserver URL is invalid\n"));
+    }
+
+  if(which)
+    BUG();
+  else
+    sl=add_to_strlist( &opt.sig_keyserver_url, string );
+
+  if(critical)
+    sl->flags |= 1;    
+}