Added iconv support and doc cleanups.
authorWerner Koch <wk@gnupg.org>
Fri, 22 Sep 2006 18:15:18 +0000 (18:15 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 22 Sep 2006 18:15:18 +0000 (18:15 +0000)
12 files changed:
NEWS
TODO
configure.ac
doc/ChangeLog
doc/Makefile.am
doc/assuan.texi [deleted file]
doc/glossary.texi
doc/gnupg.texi
doc/instguide.texi [new file with mode: 0644]
jnlib/ChangeLog
jnlib/utf8conv.c
po/de.po

diff --git a/NEWS b/NEWS
index 77860a8..6896fd3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,9 @@
-Noteworthy changes in version 1.9.24
+Noteworthy changes in version 1.9.90
 -------------------------------------------------
 
+ * Made readline work for gpg.
+
+ * Cleanups und minor bug fixes.
 
 
 Noteworthy changes in version 1.9.23 (2006-09-18)
diff --git a/TODO b/TODO
index 661f3eb..3bf925c 100644 (file)
--- a/TODO
+++ b/TODO
@@ -77,10 +77,6 @@ might want to have an agent context for each service request
 
 ** Add a test to check the extkeyusage.
 
-* doc/
-** Explain how to setup a root CA key as trusted
-** Explain how trustlist.txt might be managed.
-
 * Windows port
 ** gpgsm's LISTKEYS does not yet work
     Fix is to change everything to libestream
@@ -90,12 +86,10 @@ might want to have an agent context for each service request
 
 * sm/
 ** check that we issue NO_SECKEY xxx if a -u key was not found
-   We don't. The messages retruned are also wrong (recipient vs. signer).
+   We don't. The messages returned are also wrong (recipient vs. signer).
 
 * jnlib/
 ** provide jnlib_malloc and try to remove all jnlib_xmalloc.
-** Extend utf8conv.c to make use of iconv.
-   Need to merge with the code in 1.4/util/strgutil.c.
 
 * g10/
 ** issue a NO_SECKEY xxxx if a -u key was not found.
@@ -109,13 +103,5 @@ might want to have an agent context for each service request
    As soon as we switch to libgcrypt 1.3 we should remove the hard
    coded constant in random_is_faked.
 
-
-* common/
-** ttyio
-  Add completion support.
-** yesno
-  Update to gpg 1.4.3 version
-
-
 * Extend selinux support to other modules
 
index 3478c71..616baed 100644 (file)
@@ -895,9 +895,6 @@ fi
 AC_HEADER_STDC
 AC_CHECK_HEADERS([string.h unistd.h langinfo.h termio.h locale.h getopt.h])
 AC_CHECK_HEADERS([pwd.h inttypes.h])
-# Note that we do not check for iconv here because this is done anyway
-# by the gettext checks and thus it allows us to disable the use of
-# iconv by using --disable-nls.
 
 
 #
index 261adfb..bb12bcf 100644 (file)
@@ -1,5 +1,9 @@
 2006-09-22  Werner Koch  <wk@g10code.com>
 
+       * instguide.texi (Installation): New.
+       * assuan.texi (Assuan): Removed.  Use the libassuan manual instead.
+       * gnupg.texi: Reflect these changes. 
+
        * gpg.texi: Make some parts depend on the "gpgone" set
        command. This allows us to use the same source for gpg1 and gpg2.
 
index 8258e83..06b02f6 100644 (file)
@@ -40,7 +40,7 @@ info_TEXINFOS = gnupg.texi
 dist_pkgdata_DATA = qualified.txt FAQ faq.html com-certs.pem
 
 gnupg_TEXINFOS = \
-       gpg.texi gpgsm.texi gpg-agent.texi scdaemon.texi assuan.texi \
+       gpg.texi gpgsm.texi gpg-agent.texi scdaemon.texi instguide.texi \
        tools.texi debugging.texi glossary.texi contrib.texi gpl.texi \
        sysnotes.texi gnupg-card-architecture.fig
 
diff --git a/doc/assuan.texi b/doc/assuan.texi
deleted file mode 100644 (file)
index cb6eb9c..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-@c Copyright (C) 2002 Free Software Foundation, Inc.
-@c This is part of the GnuPG manual.
-@c For copying conditions, see the file gnupg.texi.
-
-@node Assuan
-@appendix Description of the Assuan protocol.
-@cindex Assuan, IPC
-
-The architecture of the modular GnuPG system is based on a couple of
-highly specialized modules which make up a network of client server
-communication.  A common framework for intermodule communication is
-therefore needed and should be implemented in a library.
-
-@appendixsubsec Goals
-
-@itemize @bullet
-@item Common framework for module communication
-@item Easy debugging
-@item Easy module testing 
-@item Extendible
-@item Optional authentication and encryption facility
-@item Usable to access external hardware
-@end itemize
-
-
-@appendixsubsec Design criteria
-
-@itemize @bullet
-@item Client Server with back channel
-@item Use a mainly text based protocol
-@item Escape certain control characters
-@item Allow indefinite data length
-@item Request confidentiality for parts of the communication
-@item Dummy module should allow direct linking of client and server.
-@item Inline data or descriptor passing for bulk data
-@item No protection against DoS needed
-@item Subliminal channels are not an issue
-@end itemize
-
-
-@appendixsubsec Implementation
-
-@noindent
-The implementation is line based with a maximum line size of 1000
-octects.  The default IPC mechanism are Unix Domain Sockets.
-
-On a connect request the server responds either with an okay or an error
-status.  For authentication check the server may send an Inquiry
-Response prior to the first Okay, it may also issue Status messages.
-The server must check that the client is allowed to connect, this is
-done by requesting the credentials for the peer and comparing them to
-those of the server.  This avoids attacks based on wrong socket
-permissions.
-
-It may choose to delay the first response in case of an error.  The
-server never closes the connection - however the lower protocol may do
-so after some time of inactivity or when the connection is in an error
-state.
-
-All textual messages are assumed to be in UTF-8 unless otherwise noted.
-
-
-@appendixsubsec Server responses
-
-@table @code
-@item OK  [<arbitary debugging information>]
-Request was successful.
-
-@item ERR @var{errorcode} [<human readable error description>]
-Request could not be fulfilled.  The error codes are mostly application
-specific except for a few common ones.
-
-@item S @var{keyword} <status information depending on keyword>
-Informational output by the server, still processing the request.
-
-@item # <string>
-Comment line issued only for debugging purposes.  Totally ignored.
-
-@item D <raw data>
-Raw data returned to client. There must be exactly one space after the
-'D'.  The values for '%', CR and LF must be percent escaped; this is
-encoded as %25, %0D and %0A.  Only uppercase letters should be used in
-the hexadecimal representation.  Other characters may be percent escaped
-for easier debugging.  All these Data lines are considered one data
-stream up to the OK or ERR response.  Status and Inquiry Responses
-may be mixed with the Data lines.
-
-@item INQUIRE @var{keyword}> <parameters>
-Server needs further information from the client.  The client should
-answer with a command which is allowed after an inquiry.  Note that the
-server does not confirm that client command but either continues
-processing or ends processing with an error status.  Not all commands
-are allowed.
-@end table
-
-
-A client should only check the first letter of each line and then skip
-over to the next token (except for data lines where the raw data starts
-exactly after 2 bytes).  Lines larger than 1000 bytes should be
-treated as a communication error. (The rationale for having a line
-length limit is to allow for easier multiplexing of multiple channels).
-
-
-@appendixsubsec Client requests
-
-The server waits for client requests after he sent an Okay or Error.
-The client should not issue a request in other cases with the
-exception of the CANCEL command.
-
-@example
-@var{command} <parameters>
-@end example
-
-@var{command} is a one word string without preceding white space.
-Parameters are command specific, CR, LF and the percent signs should be
-percent escaped as described above.  To send a backslash as the last
-character it should also be percent escaped.  Percent escaping is
-allowed anywhere in the parameters but not in the command.  The line
-ends with a CR, LF or just a LF.
-
-Not yet implemented feature: If there is a need for a parameter list
-longer than the line length limit (1000 characters including command and
-CR, LF), the last character of the line (right before the CR/LF or LF)
-must be a non-escape encoded backslash. The following line is then
-expected to be a continuation of the line with the backslash replaced by
-a blank and the line ending removed.
-
-@example
-D <raw data>
-@end example
-
-Raw data to the server. There must be exactly one space after the 'D'.
-The values for '%', CR and LF must be percent escaped; this is encoded
-as %25, %0D and %0A.  Only uppercase letters should be used in the
-hexadecimal representation.  Other characters may be percent escaped for
-easier debugging.  All these Data lines are considered one data stream
-up to the OKAY or ERROR response.  Status and Inquiry Responses may be
-mixed with the Data lines.
-
-@example
-END
-@end example
-
-
-
-Lines beginning with a @code{#} or empty lines are ignored.  This is
-useful to comment test scripts.
-
-
-Although the commands are application specific, some of them are used by
-all protocols and partly directly supported by the Assuan library:
-
-@table @code
-@item CANCEL
-his is the one special command which aborts the current request.  it can
-be sent at any time and the server will stop its operation right before
-it would send the next response line (of any type).
-
-@item BYE
-Close the connect, the server will reply with an @code{OK}.
-
-@item AUTH
-Not yet specified as we don't implement it in the first phase.  See my
-mail to gpa-dev on 2001-10-25 about the rationale for measurements
-against local attacks.
-
-@item RESET
-Reset the connection but not any existing authentication.  The server
-should release all resources associated with the connection.
-
-@item END
-Used by a client to mark the end of raw data.  The server may send END
-to indicate a partial end of data.
-@end table
-
-
-
-@appendixsubsec Error Codes
-
-Here we keep a list of error codes used in any Assuan based
-protocol.  The format is the string @code{ERR}, white space, the error
-number, white space, a textual description of the error.
-
-@table @code
-
-@item 100 Unknown Command
-@item 101 Not Implemented
-
-@item 301 certificate has been revoked [DirMngr]
-@item 302 no CRL known for this certificate [DirMngr]
-@item 303 CRL is too old and a new one could not be retrieved [DirMngr]
-
-@end table
index e739947..5ea4a95 100644 (file)
@@ -13,7 +13,7 @@
 certificates.
 
 @item CRL
-      The @emph{Certificate Revocation List} is a list containing
+     The @emph{Certificate Revocation List} is a list containing
 certificates revoked by the issuer.
 
 @item Keygrip
index e674486..48151f7 100644 (file)
@@ -114,6 +114,8 @@ the administration and the architecture.
 @end ifnottex
 
 @menu
+* Installation::        A short installation guide.
+
 * Invoking GPG::        Using the OpenPGP protocol.
 * Invoking GPGSM::      Using the S/MIME protocol.
 * Invoking GPG-AGENT::  How to launch the secret key daemon.
@@ -124,7 +126,7 @@ the administration and the architecture.
 
 * System Notes::        Notes pertaining to certain OSes.
 * Debugging::           How to solve problems
-* Assuan::              Description of the Assuan protocol.
+
 * Copying::             GNU General Public License says
                         how you can copy and share GnuPG
 * Contributors::        People who have contributed to GnuPG.
@@ -148,6 +150,8 @@ the administration and the architecture.
 @end ifhtml
 
 
+@include instguide.texi
+
 @include gpg.texi
 @include gpgsm.texi
 @include gpg-agent.texi
@@ -165,7 +169,6 @@ the administration and the architecture.
 
 @include debugging.texi
 
-@include assuan.texi
 @include gpl.texi
 
 @include contrib.texi
diff --git a/doc/instguide.texi b/doc/instguide.texi
new file mode 100644 (file)
index 0000000..1a65afb
--- /dev/null
@@ -0,0 +1,19 @@
+@c instguide.texi - Installation guide for GnuPG
+@c Copyright (C) 2006 Free Software Foundation, Inc.
+@c This is part of the GnuPG manual.
+@c For copying conditions, see the file gnupg.texi.
+
+@node Installation
+@chapter A short installation guide.
+
+[to be written]
+
+Tell how to setup the system, install certificates, how dirmngr relates
+to GnuPG etc.
+
+** Explain how to setup a root CA key as trusted
+** Explain how trustlist.txt might be managed.
+
+
+
+
index f601d9b..6c38de2 100644 (file)
@@ -1,3 +1,9 @@
+2006-09-22  Werner Koch  <wk@g10code.com>
+
+       * utf8conv.c: Reworked to match the gnupg 1.4.5 code.  This now
+       requires iconv support but this is reasonable for all modern
+       systems.
+
 2006-08-29  Werner Koch  <wk@g10code.com>
 
        * logging.c (do_logv): Emit a missing LF for fatal errors.
index 9fba1ed..ebb6ef3 100644 (file)
 #ifdef HAVE_LANGINFO_CODESET
 #include <langinfo.h>
 #endif
+#include <errno.h>
+#include <iconv.h>
 
 #include "libjnlib-config.h"
 #include "stringhelp.h"
 #include "utf8conv.h"
 
+#ifndef MB_LEN_MAX
+#define MB_LEN_MAX 16
+#endif
+
+static const char *active_charset_name = "iso-8859-1";
+static unsigned short *active_charset;
+static int no_translation;     /* Set to true if we let simply pass through. */
+static int use_iconv;          /* iconv comversion fucntions required. */
 
-static ushort koi8_unicode[128] = {
-  0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524,
-  0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590,
-  0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248,
-  0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7,
-  0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556,
-  0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e,
-  0x255f, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565,
-  0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x00a9,
-  0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
-  0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e,
-  0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
-  0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a,
-  0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
-  0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
-  0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
-  0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a
-};
-
-static ushort latin2_unicode[128] = {
-  0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
-  0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
-  0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
-  0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
-  0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7,
-  0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
-  0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7,
-  0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
-  0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
-  0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
-  0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
-  0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
-  0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
-  0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
-  0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
-  0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9
-};
 
 
-static const char *active_charset_name = "iso-8859-1";
-static ushort *active_charset = NULL;
-static int no_translation = 0;
+/* Error handler for iconv failures. This is needed to not clutter the
+   output with repeated diagnostics about a missing conversion. */
+static void
+handle_iconv_error (const char *to, const char *from, int use_fallback)
+{
+  if (errno == EINVAL)
+    {
+      static int shown1, shown2;
+      int x;
+
+      if (to && !strcmp (to, "utf-8"))
+        {
+          x = shown1;
+          shown1 = 1;
+        }
+      else
+        {
+          x = shown2;
+          shown2 = 1;
+        }
+
+      if (!x)
+        log_info (_("conversion from `%s' to `%s' not available\n"),
+                  from, to);
+    }
+  else
+    {
+      static int shown;
+
+      if (!shown)
+        log_info (_("iconv_open failed: %s\n"), strerror (errno));
+      shown = 1;
+    }
+
+  if (use_fallback)
+    {
+      /* To avoid further error messages we fallback to Latin-1 for the
+         native encoding.  This is justified as one can expect that on a
+         utf-8 enabled system nl_langinfo() will work and thus we won't
+         never get to here.  Thus Latin-1 seems to be a reasonable
+         default.  */
+      active_charset_name = "iso-8859-1";
+      no_translation = 0;
+      active_charset = NULL;
+      use_iconv = 0;
+    }
+}
+
 
 int
 set_native_charset (const char *newset)
 {
-  if (!newset)
+  const char *full_newset;
+
+  if (!newset) 
+    {
+#ifdef HABE_W32_SYSTEM
+      static char codepage[30];
+      unsigned int cpno;
+      const char *aliases;
+      
+      /* We are a console program thus we need to use the
+         GetConsoleOutputCP function and not the the GetACP which
+         would give the codepage for a GUI program.  Note this is not
+         a bulletproof detection because GetConsoleCP might return a
+         different one for console input.  Not sure how to cope with
+         that.  If the console Code page is not known we fall back to
+         the system code page.  */
+      cpno = GetConsoleOutputCP ();
+      if (!cpno)
+        cpno = GetACP ();
+      sprintf (codepage, "CP%u", cpno );
+      /* Resolve alias.  We use a long string string and not the usual
+         array to optimize if the code is taken to a DSO.  Taken from
+         libiconv 1.9.2. */
+      newset = codepage;
+      for (aliases = ("CP936"   "\0" "GBK" "\0"
+                      "CP1361"  "\0" "JOHAB" "\0"
+                      "CP20127" "\0" "ASCII" "\0"
+                      "CP20866" "\0" "KOI8-R" "\0"
+                      "CP21866" "\0" "KOI8-RU" "\0"
+                      "CP28591" "\0" "ISO-8859-1" "\0"
+                      "CP28592" "\0" "ISO-8859-2" "\0"
+                      "CP28593" "\0" "ISO-8859-3" "\0"
+                      "CP28594" "\0" "ISO-8859-4" "\0"
+                      "CP28595" "\0" "ISO-8859-5" "\0"
+                      "CP28596" "\0" "ISO-8859-6" "\0"
+                      "CP28597" "\0" "ISO-8859-7" "\0"
+                      "CP28598" "\0" "ISO-8859-8" "\0"
+                      "CP28599" "\0" "ISO-8859-9" "\0"
+                      "CP28605" "\0" "ISO-8859-15" "\0"
+                      "CP65001" "\0" "UTF-8" "\0");
+           *aliases;
+           aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
+        {
+          if (!strcmp (codepage, aliases) ||(*aliases == '*' && !aliases[1]))
+            {
+              newset = aliases + strlen (aliases) + 1;
+              break;
+            }
+        }
+
+#else /*!HAVE_W32_SYSTEM*/
+      
 #ifdef HAVE_LANGINFO_CODESET
-    newset = nl_langinfo (CODESET);
-#else
-    newset = "8859-1";
-#endif
+      newset = nl_langinfo (CODESET);
+#else /*!HAVE_LANGINFO_CODESET*/
+      /* Try to get the used charset from environment variables.  */
+      static char codepage[30];
+      const char *lc, *dot, *mod;
+
+      strcpy (codepage, "iso-8859-1");
+      lc = getenv ("LC_ALL");
+      if (!lc || !*lc)
+        {
+          lc = getenv ("LC_CTYPE");
+          if (!lc || !*lc)
+            lc = getenv ("LANG");
+        }
+      if (lc && *lc)
+        {
+          dot = strchr (lc, '.');
+          if (dot)
+            {
+              mod = strchr (++dot, '@');
+              if (!mod)
+                mod = dot + strlen (dot);
+              if (mod - dot < sizeof codepage && dot != mod) 
+                {
+                  memcpy (codepage, dot, mod - dot);
+                  codepage [mod - dot] = 0;
+                }
+            }
+        }
+      newset = codepage;
+#endif /*!HAVE_LANGINFO_CODESET*/
+#endif /*!HAVE_W32_SYSTEM*/
+    }
 
+  full_newset = newset;
   if (strlen (newset) > 3 && !ascii_memcasecmp (newset, "iso", 3))
     {
       newset += 3;
       if (*newset == '-' || *newset == '_')
-       newset++;
+        newset++;
     }
 
-  if (!*newset
-      || !ascii_strcasecmp (newset, "8859-1")
-      || !ascii_strcasecmp (newset, "8859-15"))
+  /* Note that we silently assume that plain ASCII is actually meant
+     as Latin-1.  This makes sense because many Unix system don't have
+     their locale set up properly and thus would get annoying error
+     messages and we have to handle all the "bug" reports. Latin-1 has
+     always been the character set used for 8 bit characters on Unix
+     systems. */
+  if ( !*newset
+       || !ascii_strcasecmp (newset, "8859-1" )
+       || !ascii_strcasecmp (newset, "646" )
+       || !ascii_strcasecmp (newset, "ASCII" )
+       || !ascii_strcasecmp (newset, "ANSI_X3.4-1968" )
+       )
     {
       active_charset_name = "iso-8859-1";
       no_translation = 0;
       active_charset = NULL;
+      use_iconv = 0;
     }
-  else if (!ascii_strcasecmp (newset, "8859-2"))
-    {
-      active_charset_name = "iso-8859-2";
-      no_translation = 0;
-      active_charset = latin2_unicode;
-    }
-  else if (!ascii_strcasecmp (newset, "koi8-r"))
-    {
-      active_charset_name = "koi8-r";
-      no_translation = 0;
-      active_charset = koi8_unicode;
-    }
-  else if (!ascii_strcasecmp (newset, "utf8")
-          || !ascii_strcasecmp (newset, "utf-8"))
+  else if ( !ascii_strcasecmp (newset, "utf8" )
+            || !ascii_strcasecmp(newset, "utf-8") )
     {
       active_charset_name = "utf-8";
       no_translation = 1;
       active_charset = NULL;
+      use_iconv = 0;
     }
   else
-    return -1;
+    {
+      iconv_t cd;
+      
+#ifdef HAVE_W32_SYSTEM
+      if (load_libiconv ())
+        return -1;
+#endif /*HAVE_W32_SYSTEM*/      
+
+      cd = iconv_open (full_newset, "utf-8");
+      if (cd == (iconv_t)-1) 
+        {
+          handle_iconv_error (full_newset, "utf-8", 0);
+          return -1;
+        }
+      iconv_close (cd);
+      cd = iconv_open ("utf-8", full_newset);
+      if (cd == (iconv_t)-1) 
+        {
+          handle_iconv_error ("utf-8", full_newset, 0);
+          return -1;
+        }
+      iconv_close (cd);
+      active_charset_name = full_newset;
+      no_translation = 0;
+      active_charset = NULL; 
+      use_iconv = 1;
+    }
   return 0;
 }
 
@@ -132,10 +256,9 @@ get_native_charset ()
   return active_charset_name;
 }
 
-/****************
- * Convert string, which is in native encoding to UTF8 and return the
- * new allocated UTF8 string.
- */
+
+/* Convert string, which is in native encoding to UTF8 and return a
+   new allocated UTF-8 string.  */
 char *
 native_to_utf8 (const char *orig_string)
 {
@@ -147,41 +270,12 @@ native_to_utf8 (const char *orig_string)
 
   if (no_translation)
     {
+      /* Already utf-8 encoded. */
       buffer = jnlib_xstrdup (orig_string);
     }
-  else if (active_charset)
-    {
-      for (s = string; *s; s++)
-       {
-         length++;
-         if (*s & 0x80)
-           length += 2;        /* we may need 3 bytes */
-       }
-      buffer = jnlib_xmalloc (length + 1);
-      for (p = (unsigned char *)buffer, s = string; *s; s++)
-       {
-         if ((*s & 0x80))
-           {
-             ushort val = active_charset[*s & 0x7f];
-             if (val < 0x0800)
-               {
-                 *p++ = 0xc0 | ((val >> 6) & 0x1f);
-                 *p++ = 0x80 | (val & 0x3f);
-               }
-             else
-               {
-                 *p++ = 0xe0 | ((val >> 12) & 0x0f);
-                 *p++ = 0x80 | ((val >> 6) & 0x3f);
-                 *p++ = 0x80 | (val & 0x3f);
-               }
-           }
-         else
-           *p++ = *s;
-       }
-      *p = 0;
-    }
-  else
+  else if (!active_charset && !use_iconv)
     {
+      /* For Latin-1 we can avoid the iconv overhead. */
       for (s = string; *s; s++)
        {
          length++;
@@ -191,7 +285,7 @@ native_to_utf8 (const char *orig_string)
       buffer = jnlib_xmalloc (length + 1);
       for (p = (unsigned char *)buffer, s = string; *s; s++)
        {
-         if (*s & 0x80)
+         if ( (*s & 0x80 ))
            {
              *p++ = 0xc0 | ((*s >> 6) & 3);
              *p++ = 0x80 | (*s & 0x3f);
@@ -201,22 +295,68 @@ native_to_utf8 (const char *orig_string)
        }
       *p = 0;
     }
+  else
+    { 
+      /* Need to use iconv.  */
+      iconv_t cd;
+      const char *inptr;
+      char *outptr;
+      size_t inbytes, outbytes;
+     
+      cd = iconv_open ("utf-8", active_charset_name);
+      if (cd == (iconv_t)-1)
+        {
+          handle_iconv_error ("utf-8", active_charset_name, 1);
+          return native_to_utf8 (string);
+        }
+
+      for (s=string; *s; s++ ) 
+        {
+          length++;
+          if ((*s & 0x80))
+            length += 5; /* We may need up to 6 bytes for the utf8 output. */
+        }
+      buffer = jnlib_xmalloc (length + 1);
+      
+      inptr = string;
+      inbytes = strlen (string);
+      outptr = buffer;
+      outbytes = length;
+      if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
+                  &outptr, &outbytes) == (size_t)-1)
+        {
+          static int shown;
+
+          if (!shown)
+            log_info (_("conversion from `%s' to `%s' failed: %s\n"),
+                      active_charset_name, "utf-8", strerror (errno));
+          shown = 1;
+          /* We don't do any conversion at all but use the strings as is. */
+          strcpy (buffer, string);
+        }
+      else /* Success.  */
+        {
+          *outptr = 0;
+          /* We could realloc the buffer now but I doubt that it makes
+             much sense given that it will get freed anyway soon
+             after.  */
+        }
+      iconv_close (cd);
+    }
   return buffer;
 }
 
 
-/* Convert string, which is in UTF8 to native encoding.  Replace
- * illegal encodings by some "\xnn" and quote all control
- * characters. A character with value DELIM will always be quoted, it
- * must be a vanilla ASCII character.  */
-char *
-utf8_to_native (const char *string, size_t length, int delim)
+
+static char *
+do_utf8_to_native (const char *string, size_t length, int delim,
+                   int with_iconv)
 {
   int nleft;
   int i;
   unsigned char encbuf[8];
   int encidx;
-  const byte *s;
+  const unsigned char *s;
   size_t n;
   char *buffer = NULL;
   char *p = NULL;
@@ -224,19 +364,20 @@ utf8_to_native (const char *string, size_t length, int delim)
   size_t slen;
   int resync = 0;
 
-  /* 1. pass (p==NULL): count the extended utf-8 characters */
-  /* 2. pass (p!=NULL): create string */
+  /* First pass (p==NULL): count the extended utf-8 characters.  */
+  /* Second pass (p!=NULL): create string.  */
   for (;;)
     {
       for (slen = length, nleft = encidx = 0, n = 0,
-             s = (const unsigned char *)string; slen;
+             s = (const unsigned char *)string;
+           slen;
           s++, slen--)
        {
          if (resync)
            {
              if (!(*s < 128 || (*s >= 0xc0 && *s <= 0xfd)))
                {
-                 /* still invalid */
+                 /* Still invalid. */
                  if (p)
                    {
                      sprintf (p, "\\x%02x", *s);
@@ -250,45 +391,23 @@ utf8_to_native (const char *string, size_t length, int delim)
          if (!nleft)
            {
              if (!(*s & 0x80))
-               {               /* plain ascii */
-                 if (*s < 0x20 || *s == 0x7f || *s == delim ||
-                     (delim && *s == '\\'))
+               {       
+                  /* Plain ascii. */
+                 if ( delim != -1
+                       && (*s < 0x20 || *s == 0x7f || *s == delim 
+                           || (delim && *s == '\\')))
                    {
                      n++;
                      if (p)
                        *p++ = '\\';
                      switch (*s)
                        {
-                       case '\n':
-                         n++;
-                         if (p)
-                           *p++ = 'n';
-                         break;
-                       case '\r':
-                         n++;
-                         if (p)
-                           *p++ = 'r';
-                         break;
-                       case '\f':
-                         n++;
-                         if (p)
-                           *p++ = 'f';
-                         break;
-                       case '\v':
-                         n++;
-                         if (p)
-                           *p++ = 'v';
-                         break;
-                       case '\b':
-                         n++;
-                         if (p)
-                           *p++ = 'b';
-                         break;
-                       case 0:
-                         n++;
-                         if (p)
-                           *p++ = '0';
-                         break;
+                        case '\n': n++; if ( p ) *p++ = 'n'; break;
+                        case '\r': n++; if ( p ) *p++ = 'r'; break;
+                        case '\f': n++; if ( p ) *p++ = 'f'; break;
+                        case '\v': n++; if ( p ) *p++ = 'v'; break;
+                        case '\b': n++; if ( p ) *p++ = 'b'; break;
+                        case    0: n++; if ( p ) *p++ = '0'; break;
                        default:
                          n += 3;
                          if (p)
@@ -306,43 +425,43 @@ utf8_to_native (const char *string, size_t length, int delim)
                      n++;
                    }
                }
-             else if ((*s & 0xe0) == 0xc0)
-               {               /* 110x xxxx */
+             else if ((*s & 0xe0) == 0xc0) /* 110x xxxx */
+               {
                  val = *s & 0x1f;
                  nleft = 1;
                  encidx = 0;
                  encbuf[encidx++] = *s;
                }
-             else if ((*s & 0xf0) == 0xe0)
-               {               /* 1110 xxxx */
+             else if ((*s & 0xf0) == 0xe0) /* 1110 xxxx */
+               {       
                  val = *s & 0x0f;
                  nleft = 2;
                  encidx = 0;
                  encbuf[encidx++] = *s;
                }
-             else if ((*s & 0xf8) == 0xf0)
-               {               /* 1111 0xxx */
+             else if ((*s & 0xf8) == 0xf0) /* 1111 0xxx */
+               {       
                  val = *s & 0x07;
                  nleft = 3;
                  encidx = 0;
                  encbuf[encidx++] = *s;
                }
-             else if ((*s & 0xfc) == 0xf8)
-               {               /* 1111 10xx */
+             else if ((*s & 0xfc) == 0xf8) /* 1111 10xx */
+               {       
                  val = *s & 0x03;
                  nleft = 4;
                  encidx = 0;
                  encbuf[encidx++] = *s;
                }
-             else if ((*s & 0xfe) == 0xfc)
-               {               /* 1111 110x */
+             else if ((*s & 0xfe) == 0xfc) /* 1111 110x */
+               {               
                  val = *s & 0x01;
                  nleft = 5;
                  encidx = 0;
                  encbuf[encidx++] = *s;
                }
-             else
-               {               /* invalid encoding: print as \xnn */
+             else /* Invalid encoding: print as \xNN. */
+               {               
                  if (p)
                    {
                      sprintf (p, "\\x%02x", *s);
@@ -352,8 +471,8 @@ utf8_to_native (const char *string, size_t length, int delim)
                  resync = 1;
                }
            }
-         else if (*s < 0x80 || *s >= 0xc0)
-           {                   /* invalid */
+         else if (*s < 0x80 || *s >= 0xc0) /* Invalid utf-8 */
+           {
              if (p)
                {
                  for (i = 0; i < encidx; i++)
@@ -374,8 +493,8 @@ utf8_to_native (const char *string, size_t length, int delim)
              encbuf[encidx++] = *s;
              val <<= 6;
              val |= *s & 0x3f;
-             if (!--nleft)
-               {               /* ready */
+             if (!--nleft)  /* Ready. */
+               { 
                  if (no_translation)
                    {
                      if (p)
@@ -386,43 +505,41 @@ utf8_to_native (const char *string, size_t length, int delim)
                      n += encidx;
                      encidx = 0;
                    }
-                 else if (active_charset)
-                   {           /* table lookup */
-                     for (i = 0; i < 128; i++)
-                       {
-                         if (active_charset[i] == val)
-                           break;
-                       }
-                     if (i < 128)
-                       {       /* we can print this one */
-                         if (p)
-                           *p++ = i + 128;
-                         n++;
-                       }
-                     else
-                       {       /* we do not have a translation: print utf8 */
-                         if (p)
-                           {
-                             for (i = 0; i < encidx; i++)
-                               {
-                                 sprintf (p, "\\x%02x", encbuf[i]);
-                                 p += 4;
-                               }
-                           }
-                         n += encidx * 4;
-                         encidx = 0;
-                       }
-                   }
-                 else
-                   {           /* native set */
+                  else if (with_iconv)
+                    {
+                      /* Our strategy for using iconv is a bit strange
+                         but it better keeps compatibility with
+                         previous versions in regard to how invalid
+                         encodings are displayed.  What we do is to
+                         keep the utf-8 as is and have the real
+                         translation step then at the end.  Yes, I
+                         know that this is ugly.  However we are short
+                         of the 1.4 release and for this branch we
+                         should not mess too much around with iconv
+                         things.  One reason for this is that we don't
+                         know enough about non-GNU iconv
+                         implementation and want to minimize the risk
+                         of breaking the code on too many platforms.  */
+                        if ( p )
+                          {
+                            for (i=0; i < encidx; i++ )
+                              *p++ = encbuf[i];
+                          }
+                        n += encidx;
+                        encidx = 0;
+                    }
+                 else  /* Latin-1 case. */
+                    {
                      if (val >= 0x80 && val < 256)
                        {
-                         n++;  /* we can simply print this character */
+                          /* We can simply print this character */
+                         n++;  
                          if (p)
                            *p++ = val;
                        }
                      else
-                       {       /* we do not have a translation: print utf8 */
+                       {       
+                          /* We do not have a translation: print utf8. */
                          if (p)
                            {
                              for (i = 0; i < encidx; i++)
@@ -440,13 +557,78 @@ utf8_to_native (const char *string, size_t length, int delim)
            }
        }
       if (!buffer)
-       {                       /* allocate the buffer after the first pass */
+       {
+          /* Allocate the buffer after the first pass. */
          buffer = p = jnlib_xmalloc (n + 1);
        }
-      else
+      else if (with_iconv)
+        {
+          /* Note: See above for comments.  */
+          iconv_t cd;
+          const char *inptr;
+          char *outbuf, *outptr;
+          size_t inbytes, outbytes;
+          
+          *p = 0;  /* Terminate the buffer. */
+
+          cd = iconv_open (active_charset_name, "utf-8");
+          if (cd == (iconv_t)-1)
+            {
+              handle_iconv_error (active_charset_name, "utf-8", 1);
+              jnlib_free (buffer);
+              return utf8_to_native (string, length, delim);
+            }
+
+          /* Allocate a new buffer large enough to hold all possible
+             encodings. */
+          n = p - buffer + 1;
+          inbytes = n - 1;;
+          inptr = buffer;
+          outbytes = n * MB_LEN_MAX;
+          if (outbytes / MB_LEN_MAX != n) 
+            BUG (); /* Actually an overflow. */
+          outbuf = outptr = jnlib_xmalloc (outbytes);
+          if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
+                      &outptr, &outbytes) == (size_t)-1) 
+            {
+              static int shown;
+              
+              if (!shown)
+                log_info (_("conversion from `%s' to `%s' failed: %s\n"),
+                          "utf-8", active_charset_name, strerror (errno));
+              shown = 1;
+              /* Didn't worked out.  Try again but without iconv.  */
+              jnlib_free (buffer);
+              buffer = NULL;
+              jnlib_free (outbuf);
+              outbuf = do_utf8_to_native (string, length, delim, 0);
+            }
+            else /* Success.  */
+              { 
+                *outptr = 0; /* Make sure it is a string. */
+                /* We could realloc the buffer now but I doubt that it
+                   makes much sense given that it will get freed
+                   anyway soon after.  */
+                jnlib_free (buffer);
+              }
+          iconv_close (cd);
+          return outbuf;
+        }
+      else /* Not using iconv. */
        {
-         *p = 0;               /* make a string */
+         *p = 0; /* Make sure it is a string. */
          return buffer;
        }
     }
 }
+
+/* Convert string, which is in UTF-8 to native encoding.  Replace
+   illegal encodings by some "\xnn" and quote all control
+   characters. A character with value DELIM will always be quoted, it
+   must be a vanilla ASCII character.  A DELIM value of -1 is special:
+   it disables all quoting of control characters. */
+char *
+utf8_to_native (const char *string, size_t length, int delim)
+{
+  return do_utf8_to_native (string, length, delim, use_iconv);
+}
index 75eb8d3..b2cb2cb 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnupg2 1.9.18\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"POT-Creation-Date: 2006-09-18 14:18+0200\n"
+"POT-Creation-Date: 2006-09-22 19:24+0200\n"
 "PO-Revision-Date: 2006-06-20 20:04+0200\n"
 "Last-Translator: Werner Koch <wk@gnupg.org>\n"
 "Language-Team: de\n"
@@ -34,12 +34,12 @@ msgstr "Im Server Modus ausführen"
 msgid "run in daemon mode (background)"
 msgstr "Im Daemon Modus ausführen"
 
-#: agent/gpg-agent.c:113 kbx/kbxutil.c:82 scd/scdaemon.c:107 sm/gpgsm.c:334
+#: agent/gpg-agent.c:113 kbx/kbxutil.c:82 scd/scdaemon.c:107 sm/gpgsm.c:335
 #: tools/gpgconf.c:63
 msgid "verbose"
 msgstr "ausführlich"
 
-#: agent/gpg-agent.c:114 kbx/kbxutil.c:83 scd/scdaemon.c:108 sm/gpgsm.c:335
+#: agent/gpg-agent.c:114 kbx/kbxutil.c:83 scd/scdaemon.c:108 sm/gpgsm.c:336
 msgid "be somewhat more quiet"
 msgstr "Etwas weniger Ausgaben erzeugen"
 
@@ -63,7 +63,7 @@ msgstr "Im Vordergrund laufen lassen"
 msgid "do not grab keyboard and mouse"
 msgstr "Tastatur und Maus nicht \"grabben\""
 
-#: agent/gpg-agent.c:124 scd/scdaemon.c:120 sm/gpgsm.c:337
+#: agent/gpg-agent.c:124 scd/scdaemon.c:120 sm/gpgsm.c:338
 msgid "use a log file for the server"
 msgstr "Logausgaben in eine Datei umlenken"
 
@@ -116,12 +116,12 @@ msgid "|FILE|write environment settings also to FILE"
 msgstr "|DATEI|Schreibe die Umgebungsvariabeln auf DATEI"
 
 #: agent/gpg-agent.c:236 agent/protect-tool.c:143 scd/scdaemon.c:188
-#: sm/gpgsm.c:516 tools/gpgconf.c:86
+#: sm/gpgsm.c:517 tools/gpgconf.c:86
 msgid "Please report bugs to <"
 msgstr "Fehlerberichte bitte an <"
 
 #: agent/gpg-agent.c:236 agent/protect-tool.c:143 scd/scdaemon.c:188
-#: sm/gpgsm.c:516 tools/gpgconf.c:86
+#: sm/gpgsm.c:517 tools/gpgconf.c:86
 msgid ">.\n"
 msgstr ">.\n"
 
@@ -147,30 +147,30 @@ msgstr ""
 msgid "out of core while allocating %lu bytes"
 msgstr ""
 
-#: agent/gpg-agent.c:334 scd/scdaemon.c:262 sm/gpgsm.c:645
+#: agent/gpg-agent.c:334 scd/scdaemon.c:262 sm/gpgsm.c:646
 #, c-format
 msgid "invalid debug-level `%s' given\n"
 msgstr "ungültige Debugebene `%s' angegeben\n"
 
 #: agent/gpg-agent.c:505 agent/protect-tool.c:1073 kbx/kbxutil.c:432
-#: scd/scdaemon.c:354 sm/gpgsm.c:766
+#: scd/scdaemon.c:354 sm/gpgsm.c:767
 #, c-format
 msgid "libgcrypt is too old (need %s, have %s)\n"
 msgstr ""
 "Die Bibliothek \"libgcrypt\" is zu alt (benötigt wird %s, vorhanden ist %s)\n"
 
-#: agent/gpg-agent.c:599 scd/scdaemon.c:431 sm/gpgsm.c:868
+#: agent/gpg-agent.c:599 scd/scdaemon.c:431 sm/gpgsm.c:869
 #, c-format
 msgid "NOTE: no default option file `%s'\n"
 msgstr "Notiz: Voreingestellte Konfigurationsdatei `%s' fehlt\n"
 
 #: agent/gpg-agent.c:604 agent/gpg-agent.c:1115 scd/scdaemon.c:436
-#: sm/gpgsm.c:872
+#: sm/gpgsm.c:873
 #, c-format
 msgid "option file `%s': %s\n"
 msgstr "Konfigurationsdatei `%s': %s\n"
 
-#: agent/gpg-agent.c:612 scd/scdaemon.c:444 sm/gpgsm.c:879
+#: agent/gpg-agent.c:612 scd/scdaemon.c:444 sm/gpgsm.c:880
 #, c-format
 msgid "reading options from `%s'\n"
 msgstr "Optionen werden aus `%s' gelesen\n"
@@ -547,7 +547,7 @@ msgstr ""
 "@Kommandos:\n"
 " "
 
-#: kbx/kbxutil.c:77 sm/gpgsm.c:277 tools/gpgconf.c:60
+#: kbx/kbxutil.c:77 sm/gpgsm.c:278 tools/gpgconf.c:60
 msgid ""
 "@\n"
 "Options:\n"
@@ -557,7 +557,7 @@ msgstr ""
 "Optionen:\n"
 " "
 
-#: kbx/kbxutil.c:84 sm/gpgsm.c:343 tools/gpgconf.c:65
+#: kbx/kbxutil.c:84 sm/gpgsm.c:344 tools/gpgconf.c:65
 msgid "do not make any changes"
 msgstr "Keine Änderungen durchführen"
 
@@ -593,7 +593,7 @@ msgstr ""
 msgid "run in multi server mode (foreground)"
 msgstr "Im Multiserver Modus ausführen"
 
-#: scd/scdaemon.c:111 sm/gpgsm.c:355
+#: scd/scdaemon.c:111 sm/gpgsm.c:356
 msgid "read options from file"
 msgstr "Konfigurationsoptionen aus Datei lesen"
 
@@ -1195,151 +1195,151 @@ msgstr "Rufe das gpg-protect-tool auf"
 msgid "change a passphrase"
 msgstr "Das Mantra (Passphrase) ändern"
 
-#: sm/gpgsm.c:279
+#: sm/gpgsm.c:280
 msgid "create ascii armored output"
 msgstr "Ausgabe mit ASCII Hülle wird erzeugt"
 
-#: sm/gpgsm.c:281
+#: sm/gpgsm.c:282
 msgid "create base-64 encoded output"
 msgstr "Ausgabe im Basis-64 format erzeugen"
 
-#: sm/gpgsm.c:283
+#: sm/gpgsm.c:284
 msgid "assume input is in PEM format"
 msgstr "Eingabedaten sind im PEM Format"
 
-#: sm/gpgsm.c:285
+#: sm/gpgsm.c:286
 msgid "assume input is in base-64 format"
 msgstr "Eingabedaten sind im Basis-64 Format"
 
-#: sm/gpgsm.c:287
+#: sm/gpgsm.c:288
 msgid "assume input is in binary format"
 msgstr "Eingabedaten sind im Binärformat"
 
-#: sm/gpgsm.c:289
+#: sm/gpgsm.c:290
 msgid "|NAME|encrypt for NAME"
 msgstr "|NAME|Verschlüsseln für NAME"
 
-#: sm/gpgsm.c:292
+#: sm/gpgsm.c:293
 msgid "use system's dirmngr if available"
 msgstr "Benutze den System Dirmngr when verfügbar"
 
-#: sm/gpgsm.c:293
+#: sm/gpgsm.c:294
 msgid "never consult a CRL"
 msgstr "Niemals eine CRL konsultieren"
 
-#: sm/gpgsm.c:300
+#: sm/gpgsm.c:301
 msgid "check validity using OCSP"
 msgstr "Die Gültigkeit mittels OCSP prüfen"
 
-#: sm/gpgsm.c:303
+#: sm/gpgsm.c:304
 msgid "|N|number of certificates to include"
 msgstr "|N|Sende N Zertifikate mit"
 
-#: sm/gpgsm.c:306
+#: sm/gpgsm.c:307
 msgid "|FILE|take policy information from FILE"
 msgstr "|DATEI|Richtlinieninformationen DATEI entnehmen"
 
-#: sm/gpgsm.c:309
+#: sm/gpgsm.c:310
 msgid "do not check certificate policies"
 msgstr "Zertikikatrichtlinien nicht überprüfen"
 
-#: sm/gpgsm.c:313
+#: sm/gpgsm.c:314
 msgid "fetch missing issuer certificates"
 msgstr "Fehlende Zertifikate automatisch holen"
 
-#: sm/gpgsm.c:317
+#: sm/gpgsm.c:318
 msgid "|NAME|use NAME as default recipient"
 msgstr "|NAME|Benutze NAME als voreingestellten Empfänger"
 
-#: sm/gpgsm.c:319
+#: sm/gpgsm.c:320
 msgid "use the default key as default recipient"
 msgstr "Benuzte voreingestellten Schlüssel als Standardempfänger"
 
-#: sm/gpgsm.c:325
+#: sm/gpgsm.c:326
 msgid "use this user-id to sign or decrypt"
 msgstr "Benuzte diese Benutzer ID zum Signieren oder Entschlüsseln"
 
-#: sm/gpgsm.c:328
+#: sm/gpgsm.c:329
 msgid "|N|set compress level N (0 disables)"
 msgstr "|N|Benutze Komprimierungsstufe N"
 
-#: sm/gpgsm.c:330
+#: sm/gpgsm.c:331
 msgid "use canonical text mode"
 msgstr "Kanonischen Textmodus benutzen"
 
-#: sm/gpgsm.c:333 tools/gpgconf.c:62
+#: sm/gpgsm.c:334 tools/gpgconf.c:62
 msgid "use as output file"
 msgstr "als Ausgabedatei benutzen"
 
-#: sm/gpgsm.c:336
+#: sm/gpgsm.c:337
 msgid "don't use the terminal at all"
 msgstr "Das Terminal überhaupt nicht benutzen"
 
-#: sm/gpgsm.c:340
+#: sm/gpgsm.c:341
 msgid "force v3 signatures"
 msgstr "Version 3 Signaturen erzwingen"
 
-#: sm/gpgsm.c:341
+#: sm/gpgsm.c:342
 msgid "always use a MDC for encryption"
 msgstr "Immer das MDC Verfahren zum verschlüsseln mitbenutzen"
 
-#: sm/gpgsm.c:346
+#: sm/gpgsm.c:347
 msgid "batch mode: never ask"
 msgstr "Stapelverarbeitungs Modus: Nie nachfragen"
 
-#: sm/gpgsm.c:347
+#: sm/gpgsm.c:348
 msgid "assume yes on most questions"
 msgstr "\"Ja\" auf die meisten Anfragen annehmen"
 
-#: sm/gpgsm.c:348
+#: sm/gpgsm.c:349
 msgid "assume no on most questions"
 msgstr "\"Nein\" auf die meisten Anfragen annehmen"
 
-#: sm/gpgsm.c:350
+#: sm/gpgsm.c:351
 msgid "add this keyring to the list of keyrings"
 msgstr "Diesen Keyring in die Liste der Keyrings aufnehmen"
 
-#: sm/gpgsm.c:351
+#: sm/gpgsm.c:352
 msgid "add this secret keyring to the list"
 msgstr "Diese geheimen Keyring in die Liste aufnehmen"
 
-#: sm/gpgsm.c:352
+#: sm/gpgsm.c:353
 msgid "|NAME|use NAME as default secret key"
 msgstr "|NAME|Benutze NAME als voreingestellten Schlüssel"
 
-#: sm/gpgsm.c:353
+#: sm/gpgsm.c:354
 msgid "|HOST|use this keyserver to lookup keys"
 msgstr "|HOST|Benutze HOST als Schlüsselserver"
 
-#: sm/gpgsm.c:354
+#: sm/gpgsm.c:355
 msgid "|NAME|set terminal charset to NAME"
 msgstr "|NAME|Den Zeichensatz für das Terminal auf NAME setzen"
 
-#: sm/gpgsm.c:358
+#: sm/gpgsm.c:359
 msgid "|LEVEL|set the debugging level to LEVEL"
 msgstr "|NAME|Die Debugstufe auf NAME setzen"
 
-#: sm/gpgsm.c:366
+#: sm/gpgsm.c:367
 msgid "|FD|write status info to this FD"
 msgstr "|FD|Statusinformationen auf Dateidescriptor FD schreiben"
 
-#: sm/gpgsm.c:373
+#: sm/gpgsm.c:374
 msgid "|FILE|load extension module FILE"
 msgstr "|DATEI|Das Erweiterungsmodul DATEI laden"
 
-#: sm/gpgsm.c:379
+#: sm/gpgsm.c:380
 msgid "|NAME|use cipher algorithm NAME"
 msgstr "|NAME|Den Verschlüsselungsalgrithmus NAME benutzen"
 
-#: sm/gpgsm.c:381
+#: sm/gpgsm.c:382
 msgid "|NAME|use message digest algorithm NAME"
 msgstr "|NAME|Den Hashalgorithmus NAME benutzen"
 
-#: sm/gpgsm.c:383
+#: sm/gpgsm.c:384
 msgid "|N|use compress algorithm N"
 msgstr "|N|Den Kompressionsalgorithmus Nummer N benutzen"
 
-#: sm/gpgsm.c:391
+#: sm/gpgsm.c:392
 msgid ""
 "@\n"
 "(See the man page for a complete listing of all commands and options)\n"
@@ -1347,7 +1347,7 @@ msgstr ""
 "@\n"
 "(Die \"man\" Seite beschreibt alle Kommands und Optionen)\n"
 
-#: sm/gpgsm.c:394
+#: sm/gpgsm.c:395
 msgid ""
 "@\n"
 "Examples:\n"
@@ -1367,11 +1367,11 @@ msgstr ""
 " --list-keys [Namen]        Schlüssel anzeigenn\n"
 " --fingerprint [Namen]      \"Fingerabdrücke\" anzeigen\\n\n"
 
-#: sm/gpgsm.c:519
+#: sm/gpgsm.c:520
 msgid "Usage: gpgsm [options] [files] (-h for help)"
 msgstr "Gebrauch: gpgsm [Optionen] [Dateien] (-h für Hilfe)"
 
-#: sm/gpgsm.c:522
+#: sm/gpgsm.c:523
 msgid ""
 "Syntax: gpgsm [options] [files]\n"
 "sign, check, encrypt or decrypt using the S/MIME protocol\n"
@@ -1380,7 +1380,7 @@ msgstr ""
 "Gebrauch: gpgsm [Optionen] [Dateien]\n"
 "Signieren, prüfen, ver- und entschlüsseln mittels S/MIME protocol\n"
 
-#: sm/gpgsm.c:529
+#: sm/gpgsm.c:530
 msgid ""
 "\n"
 "Supported algorithms:\n"
@@ -1388,55 +1388,55 @@ msgstr ""
 "\n"
 "Unterstützte Algorithmen:\n"
 
-#: sm/gpgsm.c:616
+#: sm/gpgsm.c:617
 msgid "usage: gpgsm [options] "
 msgstr "Gebrauch: gpgsm [Optionen] "
 
-#: sm/gpgsm.c:681
+#: sm/gpgsm.c:682
 msgid "conflicting commands\n"
 msgstr "Widersprechende Kommandos\n"
 
-#: sm/gpgsm.c:697
+#: sm/gpgsm.c:698
 #, c-format
 msgid "can't encrypt to `%s': %s\n"
 msgstr "Verschlüsseln für `%s' nicht möglich: %s\n"
 
-#: sm/gpgsm.c:771
+#: sm/gpgsm.c:772
 #, c-format
 msgid "libksba is too old (need %s, have %s)\n"
 msgstr "Die Bibliothek Libksba is nicht aktuell (benötige %s, habe %s)\n"
 
-#: sm/gpgsm.c:1234
+#: sm/gpgsm.c:1235
 msgid "WARNING: program may create a core file!\n"
 msgstr "WARNUNG: Programm könnte eine core-dump-Datei schreiben!\n"
 
-#: sm/gpgsm.c:1251
+#: sm/gpgsm.c:1252
 msgid "WARNING: running with faked system time: "
 msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: "
 
-#: sm/gpgsm.c:1277
+#: sm/gpgsm.c:1278
 msgid "selected cipher algorithm is invalid\n"
 msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\n"
 
-#: sm/gpgsm.c:1285
+#: sm/gpgsm.c:1286
 msgid "selected digest algorithm is invalid\n"
 msgstr "Das ausgewählte Hashverfahren ist ungültig\n"
 
-#: sm/gpgsm.c:1316
+#: sm/gpgsm.c:1317
 #, fuzzy, c-format
 msgid "importing common certificates `%s'\n"
 msgstr "Fehler beim Importieren des Zertifikats: %s\n"
 
-#: sm/gpgsm.c:1334
+#: sm/gpgsm.c:1335
 #, c-format
 msgid "can't sign using `%s': %s\n"
 msgstr "Signieren mit `%s' nicht möglich: %s\n"
 
-#: sm/gpgsm.c:1518
+#: sm/gpgsm.c:1519
 msgid "this command has not yet been implemented\n"
 msgstr "Dieses Kommando wurde noch nicht implementiert\n"
 
-#: sm/gpgsm.c:1754 sm/gpgsm.c:1791 sm/qualified.c:74
+#: sm/gpgsm.c:1755 sm/gpgsm.c:1792 sm/qualified.c:74
 #, c-format
 msgid "can't open `%s': %s\n"
 msgstr "Datei `%s' kann nicht geöffnet werden: %s\n"