Keyserver search and get basically works again.
authorWerner Koch <wk@gnupg.org>
Tue, 18 Jan 2011 11:51:16 +0000 (12:51 +0100)
committerWerner Koch <wk@gnupg.org>
Tue, 18 Jan 2011 11:51:16 +0000 (12:51 +0100)
14 files changed:
Makefile.am
dirmngr/ks-action.c
dirmngr/ks-action.h
dirmngr/ks-engine-hkp.c
dirmngr/ks-engine.h
dirmngr/server.c
g10/ChangeLog
g10/call-dirmngr.c
g10/call-dirmngr.h
g10/gpg.c
g10/import.c
g10/keyserver.c
g10/main.h
po/de.po

index c5c2a01..e2ad6d1 100644 (file)
@@ -35,7 +35,7 @@ endif
 if BUILD_GPG
 gpg = g10
 if !HAVE_W32CE_SYSTEM
-keyserver = keyserver
+keyserver = 
 endif
 else
 gpg =
index 5ad4b18..f376c27 100644 (file)
@@ -79,6 +79,7 @@ ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
             {
               err = copy_stream (infp, outfp);
               es_fclose (infp);
+              break;
             }
         }
     }
@@ -88,3 +89,62 @@ ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
   return err;
 }
 
+
+/* Get the requested keys (macthing PATTERNS) using all configured
+   keyservers and write the result to the provided output stream.  */
+gpg_error_t
+ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp)
+{
+  gpg_error_t err = 0;
+  gpg_error_t first_err = 0;
+  int any = 0;
+  strlist_t sl;
+  uri_item_t uri;
+  estream_t infp;
+
+  if (!patterns)
+    return gpg_error (GPG_ERR_NO_USER_ID);
+
+  /* FIXME: We only take care of the first keyserver.  To fully
+     support multiple keyservers we need to track the result for each
+     pattern and use the next keyserver if one key was not found.  The
+     keyservers might not all be fully synced thus it is not clear
+     whether the first keyserver has the freshest copy of the key.
+     Need to think about a better strategy.  */
+  for (uri = ctrl->keyservers; !err && uri; uri = uri->next)
+    {
+      if (uri->parsed_uri->is_http)
+        {
+          any = 1;
+          for (sl = patterns; !err && sl; sl = sl->next)
+            {
+              err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp);
+              if (err)
+                {
+                  /* It is possible that a server does not carry a
+                     key, thus we only save the error and continue
+                     with the next pattern.  FIXME: It is an open
+                     question how to return such an error condition to
+                     the caller.  */
+                  first_err = err;
+                  err = 0;
+                }
+              else
+                {
+                  err = copy_stream (infp, outfp);
+                  /* Reading from the keyserver should nver fail, thus
+                     return this error.  */
+                  es_fclose (infp);
+                  infp = NULL;
+                }
+            }
+        }
+    }
+
+  if (!any)
+    err = gpg_error (GPG_ERR_NO_KEYSERVER);
+  else if (!err && first_err)
+    err = first_err; /* fixme: Do we really want to do that?  */
+  return err;
+}
+
index 5790339..4a92ed1 100644 (file)
@@ -21,6 +21,7 @@
 #define DIRMNGR_KS_ACTION_H 1
 
 gpg_error_t ks_action_search (ctrl_t ctrl, strlist_t patterns, estream_t outfp);
+gpg_error_t ks_action_get (ctrl_t ctrl, strlist_t patterns, estream_t outfp);
 
 
 #endif /*DIRMNGR_KS_ACTION_H*/
index 356f643..662e9e4 100644 (file)
 #define MAX_REDIRECTS 2
 
 
+/* Send an HTTP request.  On success returns an estream object at
+   R_FP.  HOSTPORTSTR is only used for diagnostics. */
+static gpg_error_t
+send_request (ctrl_t ctrl, const char *request, const char *hostportstr,
+              estream_t *r_fp)
+{
+  gpg_error_t err;
+  http_t http = NULL;
+  int redirects_left = MAX_REDIRECTS;
+  estream_t fp = NULL;
+  char *request_buffer = NULL;
+
+  *r_fp = NULL;
+ once_more:
+  err = http_open (&http, HTTP_REQ_GET, request,
+                   /* fixme: AUTH */ NULL,
+                   0,
+                   /* fixme: proxy*/ NULL,
+                   NULL, NULL,
+                   /*FIXME curl->srvtag*/NULL);
+  if (!err)
+    {
+      fp = http_get_write_ptr (http);
+      /* Avoid caches to get the most recent copy of the key.  We set
+         both the Pragma and Cache-Control versions of the header, so
+         we're good with both HTTP 1.0 and 1.1.  */
+      es_fputs ("Pragma: no-cache\r\n"
+                "Cache-Control: no-cache\r\n", fp);
+      http_start_data (http);
+      if (es_ferror (fp))
+        err = gpg_error_from_syserror ();
+    }
+  if (err)
+    {
+      /* Fixme: After a redirection we show the old host name.  */
+      log_error (_("error connecting to `%s': %s\n"),
+                 hostportstr, gpg_strerror (err));
+      goto leave;
+    }
+
+  /* Wait for the response.  */
+  dirmngr_tick (ctrl);
+  err = http_wait_response (http);
+  if (err)
+    {
+      log_error (_("error reading HTTP response for `%s': %s\n"),
+                 hostportstr, gpg_strerror (err));
+      goto leave;
+    }
+
+  switch (http_get_status_code (http))
+    {
+    case 200:
+      err = 0;
+      break; /* Success.  */
+
+    case 301:
+    case 302:
+      {
+        const char *s = http_get_header (http, "Location");
+        
+        log_info (_("URL `%s' redirected to `%s' (%u)\n"),
+                  request, s?s:"[none]", http_get_status_code (http));
+        if (s && *s && redirects_left-- )
+          {
+            xfree (request_buffer);
+            request_buffer = xtrystrdup (s);
+            if (request_buffer)
+              {
+                request = request_buffer;
+                http_close (http, 0);
+                http = NULL;
+                goto once_more;
+              }
+            err = gpg_error_from_syserror ();
+          }
+        else
+          err = gpg_error (GPG_ERR_NO_DATA);
+        log_error (_("too many redirections\n"));
+      }
+      goto leave;
+
+    default:
+      log_error (_("error accessing `%s': http status %u\n"),
+                 request, http_get_status_code (http));
+      err = gpg_error (GPG_ERR_NO_DATA);
+      goto leave;
+    }
+
+  fp = http_get_read_ptr (http);
+  if (!fp)
+    {
+      err = gpg_error (GPG_ERR_BUG);
+      goto leave;
+    }
+
+  /* Return the read stream and close the HTTP context.  */
+  *r_fp = fp;
+  fp = NULL;
+  http_close (http, 1);
+  http = NULL;
+
+ leave:
+  es_fclose (fp);
+  http_close (http, 0);
+  xfree (request_buffer);
+  return err;
+}
+
+
+
 /* Search the keyserver identified by URI for keys matching PATTERN.
    On success R_FP has an open stream to read the data.  */
 gpg_error_t
@@ -48,10 +159,8 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
   char fprbuf[2+40+1];
   const char *scheme;
   char portstr[10];
-  http_t http = NULL;
   char *hostport = NULL;
   char *request = NULL;
-  int redirects_left = MAX_REDIRECTS;
   estream_t fp = NULL;
 
   *r_fp = NULL;
@@ -142,87 +251,11 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
   }
   
   /* Send the request.  */
- once_more:
-  err = http_open (&http, HTTP_REQ_GET, request,
-                   /* fixme: AUTH */ NULL,
-                   0,
-                   /* fixme: proxy*/ NULL,
-                   NULL, NULL,
-                   /*FIXME curl->srvtag*/NULL);
-  if (!err)
-    {
-      fp = http_get_write_ptr (http);
-      /* Avoid caches to get the most recent copy of the key.  We set
-         both the Pragma and Cache-Control versions of the header, so
-         we're good with both HTTP 1.0 and 1.1.  */
-      es_fputs ("Pragma: no-cache\r\n"
-                "Cache-Control: no-cache\r\n", fp);
-      http_start_data (http);
-      if (es_ferror (fp))
-        err = gpg_error_from_syserror ();
-    }
+  err = send_request (ctrl, request, hostport, &fp);
   if (err)
-    {
-      /* Fixme: After a redirection we show the old host name.  */
-      log_error (_("error connecting to `%s': %s\n"),
-                 hostport, gpg_strerror (err));
-      goto leave;
-    }
-
-  /* Wait for the response.  */
-  dirmngr_tick (ctrl);
-  err = http_wait_response (http);
-  if (err)
-    {
-      log_error (_("error reading HTTP response for `%s': %s\n"),
-                 hostport, gpg_strerror (err));
-      goto leave;
-    }
-
-  switch (http_get_status_code (http))
-    {
-    case 200:
-      break; /* Success.  */
-
-    case 301:
-    case 302:
-      {
-        const char *s = http_get_header (http, "Location");
-        
-        log_info (_("URL `%s' redirected to `%s' (%u)\n"),
-                  request, s?s:"[none]", http_get_status_code (http));
-        if (s && *s && redirects_left-- )
-          {
-            xfree (request);
-            request = xtrystrdup (s);
-            if (request)
-              {
-                http_close (http, 0);
-                http = NULL;
-                goto once_more;
-              }
-            err = gpg_error_from_syserror ();
-          }
-        else
-          err = gpg_error (GPG_ERR_NO_DATA);
-        log_error (_("too many redirections\n"));
-      }
-      goto leave;
-
-    default:
-      log_error (_("error accessing `%s': http status %u\n"),
-                 request, http_get_status_code (http));
-      err = gpg_error (GPG_ERR_NO_DATA);
-      goto leave;
-    }
+    goto leave;
 
   /* Start reading the response.  */
-  fp = http_get_read_ptr (http);
-  if (!fp)
-    {
-      err = gpg_error (GPG_ERR_BUG);
-      goto leave;
-    }
   {
     int c = es_getc (fp);
     if (c == -1)
@@ -241,15 +274,110 @@ ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
     es_ungetc (c, fp);
   }
 
+  /* Return the read stream.  */
+  *r_fp = fp;
+  fp = NULL;
+
+ leave:
+  es_fclose (fp);
+  xfree (request);
+  xfree (hostport);
+  return err;
+}
+
+
+/* Get the key described key the KEYSPEC string from the keyserver
+   identified by URI.  On success R_FP has an open stream to read the
+   data.  */
+gpg_error_t
+ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp)
+{
+  gpg_error_t err;
+  KEYDB_SEARCH_DESC desc;
+  char kidbuf[8+1];
+  const char *scheme;
+  char portstr[10];
+  char *hostport = NULL;
+  char *request = NULL;
+  estream_t fp = NULL;
+
+  *r_fp = NULL;
+
+  /* Remove search type indicator and adjust PATTERN accordingly.
+     Note that HKP keyservers like the 0x to be present when searching
+     by keyid.  We need to re-format the fingerprint and keyids so to
+     remove the gpg specific force-use-of-this-key flag ("!").  */
+  err = classify_user_id (keyspec, &desc);
+  if (err)
+    return err;
+  switch (desc.mode)
+    {
+    case KEYDB_SEARCH_MODE_SHORT_KID:
+    case KEYDB_SEARCH_MODE_LONG_KID:
+      snprintf (kidbuf, sizeof kidbuf, "%08lX", (ulong)desc.u.kid[1]);
+      break;
+    case KEYDB_SEARCH_MODE_FPR20:
+    case KEYDB_SEARCH_MODE_FPR:
+      /* This is a v4 fingerprint.  Take the last 8 hex digits from
+         the fingerprint which is the expected short keyid.  */
+      bin2hex (desc.u.fpr+16, 4, kidbuf);
+      break;
+
+    case KEYDB_SEARCH_MODE_FPR16:
+      log_error ("HKP keyserver do not support v3 fingerprints\n");
+    default:
+      return gpg_error (GPG_ERR_INV_USER_ID);
+    }
+  
+  /* Map scheme and port.  */
+  if (!strcmp (uri->scheme,"hkps") || !strcmp (uri->scheme,"https"))
+    {
+      scheme = "https";
+      strcpy (portstr, "443");
+    }
+  else /* HKP or HTTP.  */
+    {
+      scheme = "http";
+      strcpy (portstr, "11371");
+    }
+  if (uri->port)
+    snprintf (portstr, sizeof portstr, "%hu", uri->port);
+  else
+    {} /*fixme_do_srv_lookup ()*/
+
+  /* Build the request string.  */
+  {
+    hostport = strconcat (scheme, "://", 
+                          *uri->host? uri->host: "localhost",
+                          ":", portstr, NULL);
+    if (!hostport)
+      {
+        err = gpg_error_from_syserror ();
+        goto leave;
+      }
+
+    request = strconcat (hostport,
+                         "/pks/lookup?op=get&options=mr&search=0x",
+                         kidbuf,
+                         NULL);
+    if (!request)
+      {
+        err = gpg_error_from_syserror ();
+        goto leave;
+      }
+  }
+  
+  /* Send the request.  */
+  err = send_request (ctrl, request, hostport, &fp);
+  if (err)
+    goto leave;
+
   /* Return the read stream and close the HTTP context.  */
   *r_fp = fp;
   fp = NULL;
-  http_close (http, 1);
-  http = NULL;
 
  leave:
   es_fclose (fp);
-  http_close (http, 0);
   xfree (request);
   xfree (hostport);
   return err;
index f68782f..4b26662 100644 (file)
@@ -26,6 +26,8 @@
 /*-- ks-engine-hkp.c --*/
 gpg_error_t ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern,
                            estream_t *r_fp);
+gpg_error_t ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri,
+                        const char *keyspec, estream_t *r_fp);
 
 
 
index 40e8dab..5d61da8 100644 (file)
@@ -1475,6 +1475,66 @@ cmd_ks_search (assuan_context_t ctx, char *line)
 }
 
 
+\f
+static const char hlp_ks_get[] =
+  "KS_GET {<pattern>}\n"
+  "\n"
+  "Get the keys matching PATTERN from the configured OpenPGP keyservers\n"
+  "(see command KEYSERVER).  Each pattern should be a keyid or a fingerprint";
+static gpg_error_t
+cmd_ks_get (assuan_context_t ctx, char *line)
+{
+  ctrl_t ctrl = assuan_get_pointer (ctx);
+  gpg_error_t err;
+  strlist_t list, sl;
+  char *p;
+  estream_t outfp;
+
+  /* No options for now.  */
+  line = skip_options (line);
+
+  /* Break the line down into an strlist.  Each pattern is by
+     definition percent-plus escaped.  However we only support keyids
+     and fingerprints and thus the client has no need to apply the
+     escaping.  */
+  list = NULL;
+  for (p=line; *p; line = p)
+    {
+      while (*p && *p != ' ')
+        p++;
+      if (*p)
+        *p++ = 0;
+      if (*line)
+        {
+          sl = xtrymalloc (sizeof *sl + strlen (line));
+          if (!sl)
+            {
+              err = gpg_error_from_syserror ();
+              free_strlist (list);
+              goto leave;
+            }
+          sl->flags = 0;
+          strcpy_escaped_plus (sl->d, line);
+          sl->next = list;
+          list = sl;
+        }
+    }
+
+  /* Setup an output stream and perform the get.  */
+  outfp = es_fopencookie (ctx, "w", data_line_cookie_functions);
+  if (!outfp)
+    err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream");
+  else
+    {
+      err = ks_action_get (ctrl, list, outfp);
+      es_fclose (outfp);
+    }
+
+ leave:
+  return leave_cmd (ctx, err);
+}
+
+
 
 \f
 static const char hlp_getinfo[] = 
@@ -1611,6 +1671,7 @@ register_commands (assuan_context_t ctx)
     { "VALIDATE",   cmd_validate,   hlp_validate },
     { "KEYSERVER",  cmd_keyserver,  hlp_keyserver },
     { "KS_SEARCH",  cmd_ks_search,  hlp_ks_search },
+    { "KS_GET",     cmd_ks_get,     hlp_ks_get },
     { "GETINFO",    cmd_getinfo,    hlp_getinfo },
     { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr },
     { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr },
index 1be035d..27f60fe 100644 (file)
@@ -1,3 +1,11 @@
+2011-01-18  Werner Koch  <wk@g10code.com>
+
+       * import.c (import_keys_es_stream): New.
+
+2011-01-14  Werner Koch  <wk@g10code.com>
+
+       * keyserver.c (parse_keyrec): Use trim_trailing_ws.
+
 2011-01-07  Werner Koch  <wk@g10code.com>
 
        * call-dirmngr.c, call-dirmngr.h: New.
index a18eb64..1816a72 100644 (file)
 #include "options.h"
 #include "i18n.h"
 #include "asshelp.h"
+#include "keyserver.h"
 #include "call-dirmngr.h"
 
 
+/* Parameter structure used with the KS_SEARCH command.  */
+struct ks_search_parm_s
+{
+  gpg_error_t lasterr;  /* Last error code.  */
+  membuf_t saveddata;   /* Buffer to build complete lines.  */
+  char *helpbuf;        /* NULL or malloced buffer.  */
+  size_t helpbufsize;   /* Allocated size of HELPBUF.  */
+  gpg_error_t (*data_cb)(void*, char*);  /* Callback.  */
+  void *data_cb_value;  /* First argument for DATA_CB.  */
+};
+
+
+/* Parameter structure used with the KS_GET command.  */
+struct ks_get_parm_s
+{
+  estream_t memfp;
+};
+
+
 /* Data used to associate an session with dirmngr contexts.  We can't
    use a simple one to one mapping because we sometimes need two
    connection s to the dirmngr; for example while doing a listing and
@@ -53,7 +73,7 @@ struct dirmngr_local_s
   struct dirmngr_local_s *next;
 
   /* The active Assuan context. */
-  static assuan_context_t ctx;
+  assuan_context_t ctx;
 
   /* Flag set to true while an operation is running on CTX.  */
   int is_active;
@@ -106,12 +126,12 @@ create_context (ctrl_t ctrl, assuan_context_t *r_ctx)
       /* Set all configured keyservers.  We clear existing keyservers
          so that any keyserver configured in GPG overrides keyservers
          possibly configured in Dirmngr. */
-      if (ksi = opt.keyservers; !err && ksi; ksi = ksi->next)
+      for (ksi = opt.keyserver; !err && ksi; ksi = ksi->next)
         {
           char *line;
           
           line = xtryasprintf ("KEYSERVER%s %s",
-                               ksi == opt.keyservers? " --clear":"", ksi->uri);
+                               ksi == opt.keyserver? " --clear":"", ksi->uri);
           if (!line)
             err = gpg_error_from_syserror ();
           else
@@ -156,7 +176,8 @@ open_context (ctrl_t ctrl, assuan_context_t *r_ctx)
           /* Found an inactive local session - return that.  */
           assert (!dml->is_active);
           dml->is_active = 1;
-          return dml;
+          *r_ctx = dml->ctx;
+          return 0;
         }
       
       dml = xtrycalloc (1, sizeof *dml);
@@ -192,9 +213,9 @@ close_context (ctrl_t ctrl, assuan_context_t ctx)
     {
       if (dml->ctx == ctx)
         {
-          if (!ctx->is_active)
+          if (!dml->is_active)
             log_fatal ("closing inactive dirmngr context %p\n", ctx);
-          ctx->is_active = 0;
+          dml->is_active = 0;
           return;
         }
     }
@@ -203,54 +224,215 @@ close_context (ctrl_t ctrl, assuan_context_t ctx)
 
 
 \f
+/* Data callback for the KS_SEARCH command. */
+static gpg_error_t
+ks_search_data_cb (void *opaque, const void *data, size_t datalen)
+{
+  gpg_error_t err = 0;
+  struct ks_search_parm_s *parm = opaque;
+  const char *line, *s;
+  size_t rawlen, linelen;
+  char fixedbuf[256];
+
+  if (parm->lasterr)
+    return 0;
+
+  if (!data)
+    return 0;  /* Ignore END commands.  */
 
-int 
-gpg_dirmngr_ks_search (ctrl_t ctrl, strlist_t names,
-                       void (*cb)(void*, ksba_cert_t), void *cb_value)
+  put_membuf (&parm->saveddata, data, datalen);
+
+ again:
+  line = peek_membuf (&parm->saveddata, &rawlen);
+  if (!line)
+    {
+      parm->lasterr = gpg_error_from_syserror ();
+      return parm->lasterr; /* Tell the server about our problem.  */
+    }
+  if ((s = memchr (line, '\n', rawlen)))
+    {
+      linelen = s - line;  /* That is the length excluding the LF.  */
+      if (linelen + 1 < sizeof fixedbuf)
+        {
+          /* We can use the static buffer.  */
+          memcpy (fixedbuf, line, linelen);
+          fixedbuf[linelen] = 0;
+          if (linelen && fixedbuf[linelen-1] == '\r')
+            fixedbuf[linelen-1] = 0;
+          err = parm->data_cb (parm->data_cb_value, fixedbuf);
+        }
+      else 
+        {
+          if (linelen + 1 >= parm->helpbufsize)
+            {
+              xfree (parm->helpbuf);
+              parm->helpbufsize = linelen + 1 + 1024;
+              parm->helpbuf = xtrymalloc (parm->helpbufsize);
+              if (!parm->helpbuf)
+                {
+                  parm->lasterr = gpg_error_from_syserror ();
+                  return parm->lasterr;
+                }
+            }
+          memcpy (parm->helpbuf, line, linelen);
+          parm->helpbuf[linelen] = 0;
+          if (linelen && parm->helpbuf[linelen-1] == '\r')
+            parm->helpbuf[linelen-1] = 0;
+          err = parm->data_cb (parm->data_cb_value, parm->helpbuf);
+        }
+      if (err)
+        parm->lasterr = err;
+      else
+        {
+          clear_membuf (&parm->saveddata, linelen+1);
+          goto again;  /* There might be another complete line.  */
+        }
+    }
+
+  return err;
+}
+
+
+/* Run the KS_SEARCH command using the search string SEARCHSTR.  All
+   data lines are passed to the CB function.  That function is called
+   with CB_VALUE as its first argument and the decoded data line as
+   second argument.  The callback function may modify the data line
+   and it is guaranteed that this data line is a complete line with a
+   terminating 0 character but without the linefeed.  NULL is passed
+   to the callback to indicate EOF.  */
+gpg_error_t
+gpg_dirmngr_ks_search (ctrl_t ctrl, const char *searchstr,
+                       gpg_error_t (*cb)(void*, char *), void *cb_value)
 { 
   gpg_error_t err;
   assuan_context_t ctx;
-  char *pattern;
+  struct ks_search_parm_s parm;
   char line[ASSUAN_LINELENGTH];
 
   err = open_context (ctrl, &ctx);
   if (err)
     return err;
 
-  pattern = pattern_from_strlist (names);
-  if (!pattern)
+  {
+    char *escsearchstr = percent_plus_escape (searchstr);
+    if (!escsearchstr)
+      {
+        err = gpg_error_from_syserror ();
+        close_context (ctrl, ctx);
+        return err;
+      }
+    snprintf (line, sizeof line, "KS_SEARCH -- %s", escsearchstr);
+    xfree (escsearchstr);
+  }
+
+  memset (&parm, 0, sizeof parm);
+  init_membuf (&parm.saveddata, 1024);
+  parm.data_cb = cb;
+  parm.data_cb_value = cb_value;
+
+  err = assuan_transact (ctx, line, ks_search_data_cb, &parm,
+                        NULL, NULL, NULL, NULL);
+  if (!err)
+    err = cb (cb_value, NULL);  /* Send EOF.  */
+
+  xfree (get_membuf (&parm.saveddata, NULL));
+  xfree (parm.helpbuf);
+
+  close_context (ctrl, ctx);
+  return err;
+}
+
+
+\f
+/* Data callback for the KS_GET command. */
+static gpg_error_t
+ks_get_data_cb (void *opaque, const void *data, size_t datalen)
+{
+  gpg_error_t err = 0;
+  struct ks_get_parm_s *parm = opaque;
+  size_t nwritten;
+
+  if (!data)
+    return 0;  /* Ignore END commands.  */
+
+  if (es_write (parm->memfp, data, datalen, &nwritten))
+    err = gpg_error_from_syserror ();
+
+  return err;
+}
+
+
+/* Run the KS_GET command using the patterns in the array PATTERN.  On
+   success an estream object is returned to retrieve the keys.  On
+   error an error code is returned and NULL stored at R_FP.
+
+   The pattern may only use search specification which a keyserver can
+   use to retriev keys.  Because we know the format of the pattern we
+   don't need to escape the patterns before sending them to the
+   server.
+
+   If there are too many patterns the function returns an error.  That
+   could be fixed by issuing several search commands or by
+   implementing a different interface.  However with long keyids we
+   are able to ask for (1000-10-1)/(2+8+1) = 90 keys at once.  */
+gpg_error_t
+gpg_dirmngr_ks_get (ctrl_t ctrl, char **pattern, estream_t *r_fp)
+{ 
+  gpg_error_t err;
+  assuan_context_t ctx;
+  struct ks_get_parm_s parm;
+  char *line = NULL;
+  size_t linelen;
+  membuf_t mb;
+  int idx;
+
+  memset (&parm, 0, sizeof parm);
+
+  *r_fp = NULL;
+
+  err = open_context (ctrl, &ctx);
+  if (err)
+    return err;
+
+  /* Lump all patterns into one string.  */
+  init_membuf (&mb, 1024);
+  put_membuf_str (&mb, "KS_GET --");
+  for (idx=0; pattern[idx]; idx++)
     {
-      if (ctx == dirmngr_ctx)
-       release_dirmngr (ctrl);
-      else
-       release_dirmngr2 (ctrl);
+      put_membuf (&mb, " ", 1); /* Append Delimiter.  */
+      put_membuf_str (&mb, pattern[idx]);
+    }
+  put_membuf (&mb, "", 1); /* Append Nul.  */
+  line = get_membuf (&mb, &linelen);
+  if (!line)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
+  if (linelen + 2 >= ASSUAN_LINELENGTH)
+    {
+      err = gpg_error (GPG_ERR_TOO_MANY);
+      goto leave;
+    }
 
-      return out_of_core ();
+  parm.memfp = es_fopenmem (0, "rwb");
+  if (!parm.memfp)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
     }
-  snprintf (line, DIM(line)-1, "LOOKUP%s %s", 
-            cache_only? " --cache-only":"", pattern);
-  line[DIM(line)-1] = 0;
-  xfree (pattern);
-
-  parm.ctrl = ctrl;
-  parm.ctx = ctx;
-  parm.cb = cb;
-  parm.cb_value = cb_value;
-  parm.error = 0;
-  init_membuf (&parm.data, 4096);
-
-  rc = assuan_transact (ctx, line, lookup_cb, &parm,
-                        NULL, NULL, lookup_status_cb, &parm);
-  xfree (get_membuf (&parm.data, &len));
-
-  if (ctx == dirmngr_ctx)
-    release_dirmngr (ctrl);
-  else
-    release_dirmngr2 (ctrl);
+  err = assuan_transact (ctx, line, ks_get_data_cb, &parm,
+                         NULL, NULL, NULL, NULL);
+  if (err)
+    goto leave;
 
-  if (rc)
-      return rc;
+  es_rewind (parm.memfp);
+  *r_fp = parm.memfp;
+  parm.memfp = NULL;
 
+ leave:
+  es_fclose (parm.memfp);
+  xfree (line);
   close_context (ctrl, ctx);
-  return parm.error;
+  return err;
 }
index fa579ad..c848a29 100644 (file)
 
 void gpg_dirmngr_deinit_session_data (ctrl_t ctrl);
 
+gpg_error_t gpg_dirmngr_ks_search (ctrl_t ctrl, const char *searchstr,
+                                   gpg_error_t (*cb)(void*, char *),
+                                   void *cb_value);
+gpg_error_t gpg_dirmngr_ks_get (ctrl_t ctrl, char *pattern[], estream_t *r_fp);
 
 
 #endif /*GNUPG_G10_CALL_DIRMNGR_H*/
index 1866c1c..a0ec483 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -3752,12 +3752,12 @@ main (int argc, char **argv)
 
      case aSearchKeys:
        sl = NULL;
-       for( ; argc; argc--, argv++ )
-         append_to_strlist2( &sl, *argv, utf8_strings );
+       for (; argc; argc--, argv++)
+         append_to_strlist2 (&sl, *argv, utf8_strings);
        rc = keyserver_search (ctrl, sl);
-       if(rc)
-         log_error(_("keyserver search failed: %s\n"),g10_errstr(rc));
-       free_strlist(sl);
+       if (rc)
+         log_error (_("keyserver search failed: %s\n"), gpg_strerror (rc));
+       free_strlist (sl);
        break;
 
       case aRefreshKeys:
index 31160c3..88abafd 100644 (file)
@@ -243,6 +243,32 @@ import_keys_stream (ctrl_t ctrl, IOBUF inp, void *stats_handle,
                                fpr, fpr_len, options);
 }
 
+
+/* Variant of import_keys_stream reading from an estream_t.  */
+int
+import_keys_es_stream (ctrl_t ctrl, estream_t fp, void *stats_handle,
+                       unsigned char **fpr, size_t *fpr_len,
+                       unsigned int options)
+{
+  int rc;
+  iobuf_t inp;
+
+  inp = iobuf_esopen (fp, "r", 1);
+  if (!inp)
+    {
+      rc = gpg_error_from_syserror ();
+      log_error ("iobuf_esopen failed: %s\n", gpg_strerror (rc));
+      return rc;
+    }
+
+  rc = import_keys_internal (ctrl, inp, NULL, 0, stats_handle,
+                             fpr, fpr_len, options);
+
+  iobuf_close (inp);
+  return rc;
+}
+
+
 static int
 import (ctrl_t ctrl, IOBUF inp, const char* fname,struct stats_s *stats,
        unsigned char **fpr,size_t *fpr_len,unsigned int options )
index 60a117d..e560d4b 100644 (file)
@@ -1,6 +1,6 @@
 /* keyserver.c - generic keyserver code
  * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
- *               2009 Free Software Foundation, Inc.
+ *               2009, 2011 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -18,6 +18,9 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+/* !!! FIXME: Replace all printf by es_printf.  FIXME !!! */
+
+
 #include <config.h>
 #include <ctype.h>
 #include <stdio.h>
@@ -46,7 +49,7 @@
 #include "srv.h"
 #endif
 #include "membuf.h"
-
+#include "call-dirmngr.h"
 
 #ifdef HAVE_W32_SYSTEM
 /* It seems Vista doesn't grok X_OK and so fails access() tests.
@@ -66,6 +69,24 @@ struct keyrec
   unsigned int lines;
 };
 
+/* Parameters for the search line handler.  */
+struct search_line_handler_parm_s
+{
+  ctrl_t ctrl;     /* The session control structure.  */
+  char *searchstr_disp;  /* Native encoded search string or NULL.  */
+  KEYDB_SEARCH_DESC *desc; /* Array with search descriptions.  */
+  int count;      /* Number of keys we are currently prepared to
+                     handle.  This is the size of the DESC array.  If
+                     it is too small, it will grow safely.  */
+  int validcount; /* Enable the "Key x-y of z" messages. */
+  int nkeys;      /* Number of processed records.  */
+  int any_lines;  /* At least one line has been processed.  */
+  unsigned int numlines;  /* Counter for displayed lines.  */
+  int eof_seen;   /* EOF encountered.  */
+  int not_found;  /* Set if no keys have been found.  */
+};
+
+
 enum ks_action {KS_UNKNOWN=0,KS_GET,KS_GETNAME,KS_SEND,KS_SEARCH};
 
 static struct parse_options keyserver_opts[]=
@@ -94,6 +115,10 @@ static int keyserver_work (ctrl_t ctrl, enum ks_action action,strlist_t list,
                            KEYDB_SEARCH_DESC *desc,int count,
                            unsigned char **fpr,size_t *fpr_len,
                            struct keyserver_spec *keyserver);
+static gpg_error_t keyserver_get (ctrl_t ctrl,
+                                  KEYDB_SEARCH_DESC *desc, int ndesc,
+                                  struct keyserver_spec *keyserver);
+
 
 /* Reasonable guess */
 #define DEFAULT_MAX_CERT_SIZE 16384
@@ -556,6 +581,8 @@ print_keyrec(int number,struct keyrec *keyrec)
 static struct keyrec *
 parse_keyrec(char *keystring)
 {
+  /* FIXME: Remove the static and put the data into the parms we use
+     for the caller anyway.  */
   static struct keyrec *work=NULL;
   struct keyrec *ret=NULL;
   char *record;
@@ -584,12 +611,7 @@ parse_keyrec(char *keystring)
       work->uidbuf=iobuf_temp();
     }
 
-  /* Remove trailing whitespace */
-  for(i=strlen(keystring);i>0;i--)
-    if(ascii_isspace(keystring[i-1]))
-      keystring[i-1]='\0';
-    else
-      break;
+  trim_trailing_ws (keystring, strlen (keystring));
 
   if((record=strsep(&keystring,":"))==NULL)
     return ret;
@@ -665,7 +687,7 @@ parse_keyrec(char *keystring)
          case 'R':
            work->flags|=1;
            break;
-           
+
          case 'd':
          case 'D':
            work->flags|=2;
@@ -728,221 +750,245 @@ parse_keyrec(char *keystring)
   return ret;
 }
 
-/* TODO: do this as a list sent to keyserver_work rather than calling
-   it once for each key to get the correct counts after the import
-   (cosmetics, really) and to better take advantage of the keyservers
-   that can do multiple fetches in one go (LDAP). */
-static int
-show_prompt (ctrl_t ctrl,
-             KEYDB_SEARCH_DESC *desc,int numdesc,int count,const char *search)
+/* Show a prompt and allow the user to select keys for retrieval.  */
+static gpg_error_t
+show_prompt (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int numdesc,
+             int count, const char *search)
 {
-  char *answer;
+  gpg_error_t err;
+  char *answer = NULL;
 
   fflush (stdout);
 
-  if(count && opt.command_fd==-1)
+  if (count && opt.command_fd == -1)
     {
-      static int from=1;
-      tty_printf("Keys %d-%d of %d for \"%s\".  ",from,numdesc,count,search);
-      from=numdesc+1;
+      static int from = 1;
+      tty_printf ("Keys %d-%d of %d for \"%s\".  ",
+                  from, numdesc, count, search);
+      from = numdesc + 1;
     }
 
-  answer=cpr_get_no_help("keysearch.prompt",
-                        _("Enter number(s), N)ext, or Q)uit > "));
+ again:
+  err = 0;
+  xfree (answer);
+  answer = cpr_get_no_help ("keysearch.prompt",
+                            _("Enter number(s), N)ext, or Q)uit > "));
   /* control-d */
-  if(answer[0]=='\x04')
+  if (answer[0]=='\x04')
     {
-      printf("Q\n");
-      answer[0]='q';
+      tty_printf ("Q\n");
+      answer[0] = 'q';
     }
 
-  if(answer[0]=='q' || answer[0]=='Q')
+  if (answer[0]=='q' || answer[0]=='Q')
+    err = gpg_error (GPG_ERR_CANCELED);
+  else if (atoi (answer) >= 1 && atoi (answer) <= numdesc)
     {
-      xfree(answer);
-      return 1;
-    }
-  else if(atoi(answer)>=1 && atoi(answer)<=numdesc)
-    {
-      char *split=answer,*num;
-
-      while((num=strsep(&split," ,"))!=NULL)
-       if(atoi(num)>=1 && atoi(num)<=numdesc)
-         keyserver_work (ctrl, KS_GET,NULL,&desc[atoi(num)-1],1,
-                          NULL,NULL,opt.keyserver);
+      char *split = answer;
+      char *num;
+      int numarray[50];
+      int numidx = 0;
+      int idx;
+
+      while ((num = strsep (&split, " ,")))
+       if (atoi (num) >= 1 && atoi (num) <= numdesc)
+          {
+            if (numidx >= DIM (numarray))
+              {
+                tty_printf ("Too many keys selected\n");
+                goto again;
+              }
+            numarray[numidx++] = atoi (num);
+          }
+
+      if (!numidx)
+        goto again;
 
-      xfree(answer);
-      return 1;
+      {
+        KEYDB_SEARCH_DESC *selarray;
+
+        selarray = xtrymalloc (numidx * sizeof *selarray);
+        if (!selarray)
+          {
+            err = gpg_error_from_syserror ();
+            goto leave;
+          }
+        for (idx = 0; idx < numidx; idx++)
+          selarray[idx] = desc[numarray[idx]-1];
+        err = keyserver_get (ctrl, selarray, numidx, NULL);
+        xfree (selarray);
+      }
     }
 
-  return 0;
+ leave:
+  xfree (answer);
+  return err;
 }
 
-/* Count and searchstr are just for cosmetics.  If the count is too
-   small, it will grow safely.  If negative it disables the "Key x-y
-   of z" messages.  searchstr should be UTF-8 (rather than native). */
-static void
-keyserver_search_prompt (ctrl_t ctrl, IOBUF buffer,const char *searchstr)
-{
-  int i=0,validcount=0,started=0,header=0,count=1;
-  unsigned int maxlen,buflen,numlines=0;
-  KEYDB_SEARCH_DESC *desc;
-  byte *line=NULL;
-  char *localstr=NULL;
-
-  if(searchstr)
-    localstr=utf8_to_native(searchstr,strlen(searchstr),0);
 
-  desc=xmalloc(count*sizeof(KEYDB_SEARCH_DESC));
+/* This is a callback used by call-dirmngr.c to process the result of
+   KS_SEARCH command.  LINE is the actual data line received with all
+   escaping removed and guaranteed to be exactly one line with
+   stripped LF; an EOF is indicated by LINE passed as NULL.  LINE may
+   be modified after return.  */
+static gpg_error_t
+search_line_handler (void *opaque, char *line)
+{
+  struct search_line_handler_parm_s *parm = opaque;
+  gpg_error_t err = 0;
+  struct keyrec *keyrec;
 
-  for(;;)
+  if (parm->eof_seen && line)
     {
-      struct keyrec *keyrec;
-      int rl;
-
-      maxlen=1024;
-      rl=iobuf_read_line(buffer,&line,&buflen,&maxlen);
-
-      if(opt.with_colons)
-       {
-         if(!header && ascii_strncasecmp("SEARCH ",line,7)==0
-            && ascii_strncasecmp(" BEGIN",&line[strlen(line)-7],6)==0)
-           {
-             header=1;
-             continue;
-           }
-         else if(ascii_strncasecmp("SEARCH ",line,7)==0
-                 && ascii_strncasecmp(" END",&line[strlen(line)-5],4)==0)
-           continue;
-
-         printf("%s",line);
-       }
-
-      /* Look for an info: line.  The only current info: values
-        defined are the version and key count. */
-      if(!started && rl>0 && ascii_strncasecmp("info:",line,5)==0)
-       {
-         char *tok,*str=&line[5];
-
-         if((tok=strsep(&str,":"))!=NULL)
-           {
-             int version;
-
-             if(sscanf(tok,"%d",&version)!=1)
-               version=1;
-
-             if(version!=1)
-               {
-                 log_error(_("invalid keyserver protocol "
-                             "(us %d!=handler %d)\n"),1,version);
-                 break;
-               }
-           }
-
-         if((tok=strsep(&str,":"))!=NULL && sscanf(tok,"%d",&count)==1)
-           {
-             if(count==0)
-               goto notfound;
-             else if(count<0)
-               count=10;
-             else
-               validcount=1;
-
-             desc=xrealloc(desc,count*sizeof(KEYDB_SEARCH_DESC));
-           }
-
-         started=1;
-         continue;
-       }
-
-      if(rl==0)
-       {
-         keyrec=parse_keyrec(NULL);
-
-         if(keyrec==NULL)
-           {
-             if(i==0)
-               {
-                 count=0;
-                 break;
-               }
-
-             if(i!=count)
-               validcount=0;
-
-              if (opt.with_colons && opt.batch)
-                break;
-                
-             for(;;)
-               {
-                 if (show_prompt (ctrl, desc, i, validcount?count:0, localstr))
-                   break;
-                 validcount=0;
-               }
-
-             break;
-           }
-       }
-      else
-       keyrec=parse_keyrec(line);
-
-      if(i==count)
-       {
-         /* keyserver helper sent more keys than they claimed in the
-            info: line. */
-         count+=10;
-         desc=xrealloc(desc,count*sizeof(KEYDB_SEARCH_DESC));
-         validcount=0;
-       }
-
-      if(keyrec)
-       {
-         desc[i]=keyrec->desc;
+      log_debug ("ooops: unexpected data after EOF\n");
+      line = NULL;
+    }
 
-         if(!opt.with_colons)
-           {
-             /* screen_lines - 1 for the prompt. */
-             if(numlines+keyrec->lines>opt.screen_lines-1)
-               {
-                 if (show_prompt (ctrl, desc, i, validcount?count:0, localstr))
-                   break;
-                 else
-                   numlines=0;
-               }
+  /* Print the received line.  */
+  if (opt.with_colons && line)
+    {
+      log_debug ("%s\n",line);
+    }
 
-             print_keyrec(i+1,keyrec);
-           }
+  /* Look for an info: line.  The only current info: values defined
+     are the version and key count. */
+  if (line && !parm->any_lines && !ascii_strncasecmp ("info:", line, 5))
+    {
+      char *str = line + 5;
+      char *tok;
 
-         numlines+=keyrec->lines;
-         iobuf_close(keyrec->uidbuf);
-         xfree(keyrec);
+      if ((tok = strsep (&str, ":")))
+        {
+          int version;
+
+          if (sscanf (tok, "%d", &version) !=1 )
+            version = 1;
+
+          if (version !=1 )
+            {
+              log_error (_("invalid keyserver protocol "
+                           "(us %d!=handler %d)\n"), 1, version);
+              return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
+            }
+        }
+
+      if ((tok = strsep (&str, ":"))
+          && sscanf (tok, "%d", &parm->count) == 1)
+        {
+          if (!parm->count)
+            parm->not_found = 1;/* Server indicated that no items follow.  */
+          else if (parm->count < 0)
+            parm->count = 10;   /* Bad value - assume something reasonable.  */
+          else
+            parm->validcount = 1; /* COUNT seems to be okay.  */
+        }
+
+      parm->any_lines = 1;
+      return 0; /* Line processing finished.  */
+    }
 
-         started=1;
-         i++;
-       }
+ again:
+  if (line)
+    keyrec = parse_keyrec (line);
+  else
+    {
+      /* Received EOF - flush data */
+      parm->eof_seen = 1;
+      keyrec = parse_keyrec (NULL);
+      if (!keyrec)
+        {
+          if (!parm->nkeys)
+            parm->not_found = 1;  /* No keys at all.  */
+          else
+            {
+              if (parm->nkeys != parm->count)
+                parm->validcount = 0;
+
+              if (!(opt.with_colons && opt.batch))
+                {
+                  err = show_prompt (parm->ctrl, parm->desc, parm->nkeys,
+                                     parm->validcount? parm->count : 0,
+                                     parm->searchstr_disp);
+                  return err;
+                }
+            }
+        }
     }
 
- notfound:
-  /* Leave this commented out or now, and perhaps for a very long
-     time.  All HKPish servers return HTML error messages for
-     no-key-found. */
-  /* 
-     if(!started)
-     log_info(_("keyserver does not support searching\n"));
-     else
-  */
-  if(count==0)
+  /* Save the key in the key array.  */
+  if (keyrec)
     {
-      if(localstr)
-       log_info(_("key \"%s\" not found on keyserver\n"),localstr);
-      else
-       log_info(_("key not found on keyserver\n"));
+      /* Allocate or enlarge the key array if needed.  */
+      if (!parm->desc)
+        {
+          if (parm->count < 1)
+            {
+              parm->count = 10;
+              parm->validcount = 0;
+            }
+          parm->desc = xtrymalloc (parm->count * sizeof *parm->desc);
+          if (!parm->desc)
+            {
+              err = gpg_error_from_syserror ();
+              iobuf_close (keyrec->uidbuf);
+              xfree (keyrec);
+              return err;
+            }
+        }
+      else if (parm->nkeys == parm->count)
+        {
+          /* Keyserver sent more keys than claimed in the info: line. */
+          KEYDB_SEARCH_DESC *tmp;
+          int newcount = parm->count + 10;
+
+          tmp = xtryrealloc (parm->desc, newcount * sizeof *parm->desc);
+          if (!tmp)
+            {
+              err = gpg_error_from_syserror ();
+              iobuf_close (keyrec->uidbuf);
+              xfree (keyrec);
+              return err;
+            }
+          parm->count = newcount;
+          parm->desc = tmp;
+          parm->validcount = 0;
+        }
+
+      parm->desc[parm->nkeys] = keyrec->desc;
+
+      if (!opt.with_colons)
+        {
+          /* SCREEN_LINES - 1 for the prompt. */
+          if (parm->numlines + keyrec->lines > opt.screen_lines - 1)
+            {
+              err = show_prompt (parm->ctrl, parm->desc, parm->nkeys,
+                                 parm->validcount ? parm->count:0,
+                                 parm->searchstr_disp);
+              if (err)
+                return err;
+              parm->numlines = 0;
+            }
+
+          print_keyrec (parm->nkeys+1, keyrec);
+        }
+
+      parm->numlines += keyrec->lines;
+      iobuf_close (keyrec->uidbuf);
+      xfree (keyrec);
+
+      parm->any_lines = 1;
+      parm->nkeys++;
+
+      /* If we are here due to a flush after the EOF, run again for
+         the last prompt.  Fixme: Make this code better readable. */
+      if (parm->eof_seen)
+        goto again;
     }
 
-  xfree(localstr);
-  xfree(desc);
-  xfree(line);
+  return 0;
 }
 
+
 /* We sometimes want to use a different gpgkeys_xxx for a given
    protocol (for example, ldaps is handled by gpgkeys_ldap).  Map
    these here. */
@@ -978,7 +1024,7 @@ direct_uri_map(const char *scheme,unsigned int is_direct)
 #define KEYSERVER_ARGS_KEEP " -o \"%O\" \"%I\""
 #define KEYSERVER_ARGS_NOKEEP " -o \"%o\" \"%i\""
 
-static int 
+static int
 keyserver_spawn (ctrl_t ctrl,
                  enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
                  int count,int *prog,unsigned char **fpr,size_t *fpr_len,
@@ -1019,7 +1065,7 @@ keyserver_spawn (ctrl_t ctrl,
      the program of this process lives.  Fortunately Windows provides
      a way to retrieve this and our gnupg_libexecdir function has been
      modified to return just this.  Setting the exec-path is not
-     anymore required.  
+     anymore required.
        set_exec_path(libexecdir);
  */
 #else
@@ -1049,7 +1095,7 @@ keyserver_spawn (ctrl_t ctrl,
      fetcher that can speak that protocol (this is a problem for
      LDAP). */
 
-  strcat(command,GPGKEYS_PREFIX); 
+  strcat(command,GPGKEYS_PREFIX);
   strcat(command,scheme);
 
   /* This "_uri" thing is in case we need to call a direct handler
@@ -1079,7 +1125,7 @@ keyserver_spawn (ctrl_t ctrl,
        {
          command=xrealloc(command,strlen(command)+
                            strlen(KEYSERVER_ARGS_NOKEEP)+1);
-         strcat(command,KEYSERVER_ARGS_NOKEEP);  
+         strcat(command,KEYSERVER_ARGS_NOKEEP);
        }
 
       ret=exec_write(&spawn,NULL,command,NULL,0,0);
@@ -1497,7 +1543,7 @@ keyserver_spawn (ctrl_t ctrl,
             gpg complain about "no valid OpenPGP data found".  One
             way to do this could be to continue parsing this
             line-by-line and make a temp iobuf for each key. */
-          
+
           /* FIXME: Pass CTRL.  */
          import_keys_stream (NULL, spawn->fromchild,stats_handle,fpr,fpr_len,
                              opt.keyserver_options.import_options);
@@ -1513,7 +1559,7 @@ keyserver_spawn (ctrl_t ctrl,
        break;
 
       case KS_SEARCH:
-       keyserver_search_prompt (ctrl, spawn->fromchild,searchstr);
+       //keyserver_search_prompt (ctrl, spawn->fromchild,searchstr);
        break;
 
       default:
@@ -1532,7 +1578,9 @@ keyserver_spawn (ctrl_t ctrl,
 }
 
 
-static int 
+
+
+static int
 keyserver_work (ctrl_t ctrl,
                 enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc,
                 int count,unsigned char **fpr,size_t *fpr_len,
@@ -1596,7 +1644,11 @@ keyserver_work (ctrl_t ctrl,
   return 0;
 }
 
-int 
+
+
+
+
+int
 keyserver_export (ctrl_t ctrl, strlist_t users)
 {
   gpg_error_t err;
@@ -1629,7 +1681,7 @@ keyserver_export (ctrl_t ctrl, strlist_t users)
   return rc;
 }
 
-int 
+int
 keyserver_import (ctrl_t ctrl, strlist_t users)
 {
   gpg_error_t err;
@@ -1661,8 +1713,7 @@ keyserver_import (ctrl_t ctrl, strlist_t users)
     }
 
   if(count>0)
-    rc=keyserver_work (ctrl, KS_GET, NULL, desc, count,
-                       NULL, NULL, opt.keyserver);
+    rc=keyserver_get (ctrl, desc, count, NULL);
 
   xfree(desc);
 
@@ -1688,10 +1739,10 @@ keyserver_import_fprint (ctrl_t ctrl, const byte *fprint,size_t fprint_len,
 
   /* TODO: Warn here if the fingerprint we got doesn't match the one
      we asked for? */
-  return keyserver_work (ctrl, KS_GET, NULL, &desc, 1, NULL, NULL, keyserver);
+  return keyserver_get (ctrl, &desc, 1, keyserver);
 }
 
-int 
+int
 keyserver_import_keyid (ctrl_t ctrl,
                         u32 *keyid,struct keyserver_spec *keyserver)
 {
@@ -1703,11 +1754,11 @@ keyserver_import_keyid (ctrl_t ctrl,
   desc.u.kid[0]=keyid[0];
   desc.u.kid[1]=keyid[1];
 
-  return keyserver_work (ctrl, KS_GET,NULL,&desc,1,NULL,NULL,keyserver);
+  return keyserver_get (ctrl, &desc,1, keyserver);
 }
 
 /* code mostly stolen from do_export_stream */
-static int 
+static int
 keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
 {
   int rc=0,ndesc,num=100;
@@ -1730,13 +1781,13 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
     }
   else
     {
-      for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) 
+      for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++)
        ;
       desc = xmalloc ( ndesc * sizeof *desc);
-        
+
       for (ndesc=0, sl=users; sl; sl = sl->next)
        {
-          gpg_error_t err; 
+          gpg_error_t err;
          if (!(err = classify_user_id (sl->d, desc+ndesc)))
            ndesc++;
          else
@@ -1747,7 +1798,7 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
 
   while (!(rc = keydb_search (kdbhd, desc, ndesc)))
     {
-      if (!users) 
+      if (!users)
        desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
 
       /* read the keyblock */
@@ -1850,7 +1901,7 @@ keyidlist(strlist_t users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3)
 
   if(rc==-1)
     rc=0;
-  
+
  leave:
   if(rc)
     xfree(*klist);
@@ -1907,9 +1958,7 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users)
              /* We use the keyserver structure we parsed out before.
                 Note that a preferred keyserver without a scheme://
                 will be interpreted as hkp:// */
-
-             rc = keyserver_work (ctrl, KS_GET, NULL, &desc[i], 1,
-                                   NULL, NULL, keyserver);
+             rc = keyserver_get (ctrl, &desc[i], 1, keyserver);
              if(rc)
                log_info(_("WARNING: unable to refresh key %s"
                           " via %s: %s\n"),keystr_from_desc(&desc[i]),
@@ -1939,8 +1988,7 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users)
                     count,opt.keyserver->uri);
        }
 
-      rc=keyserver_work (ctrl, KS_GET, NULL, desc, numdesc,
-                         NULL, NULL, opt.keyserver);
+      rc=keyserver_get (ctrl, desc, numdesc, NULL);
     }
 
   xfree(desc);
@@ -1955,16 +2003,18 @@ keyserver_refresh (ctrl_t ctrl, strlist_t users)
   return rc;
 }
 
+
 /* Search for keys on the keyservers.  The patterns are given in the
    string list TOKENS.  */
 gpg_error_t
 keyserver_search (ctrl_t ctrl, strlist_t tokens)
 {
   gpg_error_t err;
-  int rc=0,ret=0;
   char *searchstr;
+  struct search_line_handler_parm_s parm;
+
+  memset (&parm, 0, sizeof parm);
 
-  /* FIXME:  WORK IN PROGRESS */
   if (!tokens)
     return 0;  /* Return success if no patterns are given.  */
 
@@ -1974,31 +2024,6 @@ keyserver_search (ctrl_t ctrl, strlist_t tokens)
       return gpg_error (GPG_ERR_NO_KEYSERVER);
     }
 
-      /* switch(ret) */
-      /*   { */
-      /*   case KEYSERVER_SCHEME_NOT_FOUND: */
-      /*     log_error(_("no handler for keyserver scheme `%s'\n"), */
-      /*           opt.keyserver->scheme); */
-      /*     break; */
-
-      /*   case KEYSERVER_NOT_SUPPORTED: */
-      /*     log_error(_("action `%s' not supported with keyserver " */
-      /*             "scheme `%s'\n"), "search", opt.keyserver->scheme); */
-      /*     break; */
-
-      /*   case KEYSERVER_TIMEOUT: */
-      /*     log_error(_("keyserver timed out\n")); */
-      /*     break; */
-
-      /*   case KEYSERVER_INTERNAL_ERROR: */
-      /*   default: */
-      /*     log_error(_("keyserver internal error\n")); */
-      /*     break; */
-      /*   } */
-
-      /* return gpg_error (GPG_ERR_KEYSERVER); */
-
-
   /* Write global options */
 
   /* for(temp=opt.keyserver_options.other;temp;temp=temp->next) */
@@ -2009,8 +2034,6 @@ keyserver_search (ctrl_t ctrl, strlist_t tokens)
   /* for(temp=keyserver->options;temp;temp=temp->next) */
   /*   fprintf(spawn->tochild,"OPTION %s\n",temp->d); */
 
-  /* Which keys do we want?  Remember that the gpgkeys_ program
-     is going to lump these together into a search string. */
   {
     membuf_t mb;
     strlist_t item;
@@ -2027,28 +2050,226 @@ keyserver_search (ctrl_t ctrl, strlist_t tokens)
     if (!searchstr)
       {
         err = gpg_error_from_syserror ();
+        goto leave;
       }
   }
-  log_info (_("searching for \"%s\" from %s\n"), searchstr, keyserver->uri);
+  /* FIXME: Enable the next line */
+  /* log_info (_("searching for \"%s\" from %s\n"), searchstr, keyserver->uri); */
+
+  parm.ctrl = ctrl;
+  if (searchstr)
+    parm.searchstr_disp = utf8_to_native (searchstr, strlen (searchstr), 0);
+
+  err = gpg_dirmngr_ks_search (ctrl, searchstr, search_line_handler, &parm);
+
+  if (parm.not_found)
+    {
+      if (parm.searchstr_disp)
+        log_info (_("key \"%s\" not found on keyserver\n"),
+                  parm.searchstr_disp);
+      else
+        log_info (_("key not found on keyserver\n"));
+    }
+
+  if (gpg_err_code (err) == GPG_ERR_NO_KEYSERVER)
+    log_error (_("no keyserver known (use option --keyserver)\n"));
+  else if (err)
+    log_error ("error searching keyserver: %s\n", gpg_strerror (err));
+
+  /* switch(ret) */
+  /*   { */
+  /*   case KEYSERVER_SCHEME_NOT_FOUND: */
+  /*     log_error(_("no handler for keyserver scheme `%s'\n"), */
+  /*               opt.keyserver->scheme); */
+  /*     break; */
+
+  /*   case KEYSERVER_NOT_SUPPORTED: */
+  /*     log_error(_("action `%s' not supported with keyserver " */
+  /*                 "scheme `%s'\n"), "search", opt.keyserver->scheme); */
+  /*     break; */
+
+  /*   case KEYSERVER_TIMEOUT: */
+  /*     log_error(_("keyserver timed out\n")); */
+  /*     break; */
+
+  /*   case KEYSERVER_INTERNAL_ERROR: */
+  /*   default: */
+  /*     log_error(_("keyserver internal error\n")); */
+  /*     break; */
+  /*   } */
+
+  /* return gpg_error (GPG_ERR_KEYSERVER); */
 
-  {
-    estream_t fp;
-    err = gpg_dirmngr_ks_search (ctrl, searchstr, &fp);
-    
-    keyserver_search_prompt (ctrl, fp,searchstr);
-  }
 
  leave:
-  xfree(line);
+  xfree (parm.desc);
+  xfree (parm.searchstr_disp);
   xfree(searchstr);
 
+  return err;
+}
 
-  *prog=exec_finish(spawn);
 
-  return ret;
+
+/* Called using:
+
+show_prompt:
+import:
+import_foo:
+refresh:
+    rc=keyserver_work (ctrl, KS_GET, NULL, desc, count,
+                       NULL, NULL, opt.keyserver);
+
+
+fetch:
+         rc = keyserver_work (ctrl, KS_GET, NULL, &desc, 1, NULL, NULL, spec);
+         if(rc)
+           log_info (_("WARNING: unable to fetch URI %s: %s\n"),
+                    sl->d,g10_errstr(rc));
+
+
+export:
+      rc = keyserver_work (ctrl, KS_SEND,sl,NULL,0,NULL,NULL,opt.keyserver);
+
+
+
+import_name:
+  rc = keyserver_work (ctrl, KS_GETNAME, list, NULL,
+                       0, fpr, fpr_len, keyserver);
+
+import_ldap:
+  rc = keyserver_work (ctrl, KS_GETNAME, list, NULL,
+                       0, fpr, fpr_len, keyserver);
+
+ */
+
+static gpg_error_t
+keyserver_get (ctrl_t ctrl, KEYDB_SEARCH_DESC *desc, int ndesc,
+               struct keyserver_spec *keyserver)
+
+{
+  gpg_error_t err = 0;
+  char **pattern;
+  int idx, npat;
+  estream_t datastream;
+
+  /* Create an array filled with a search pattern for each key.  The
+     array is delimited by a NULL entry.  */
+  pattern = xtrycalloc (ndesc+1, sizeof *pattern);
+  if (!pattern)
+    return gpg_error_from_syserror ();
+  for (npat=idx=0; idx < ndesc; idx++)
+    {
+      int quiet = 0;
+
+      if (desc[idx].mode == KEYDB_SEARCH_MODE_FPR20
+          || desc[idx].mode == KEYDB_SEARCH_MODE_FPR16)
+        {
+          pattern[npat] = xtrymalloc (2+2*20+1);
+          if (!pattern[npat])
+            err = gpg_error_from_syserror ();
+          else
+            {
+              strcpy (pattern[npat], "0x");
+              bin2hex (desc[idx].u.fpr,
+                       desc[idx].mode == KEYDB_SEARCH_MODE_FPR20? 20 : 16,
+                       pattern[npat]+2);
+              npat++;
+            }
+        }
+      else if(desc[idx].mode == KEYDB_SEARCH_MODE_LONG_KID)
+        {
+          pattern[npat] = xtryasprintf ("0x%08lX%08lX",
+                                        (ulong)desc[idx].u.kid[0],
+                                        (ulong)desc[idx].u.kid[1]);
+          if (!pattern[npat])
+            err = gpg_error_from_syserror ();
+          else
+            npat++;
+        }
+      else if(desc[idx].mode == KEYDB_SEARCH_MODE_SHORT_KID)
+        {
+          pattern[npat] = xtryasprintf ("0x%08lX", (ulong)desc[idx].u.kid[1]);
+          if (!pattern[npat])
+            err = gpg_error_from_syserror ();
+          else
+            npat++;
+        }
+      else if(desc[idx].mode == KEYDB_SEARCH_MODE_EXACT)
+        {
+          /* FIXME: We don't need this.  It is used as a dummy by
+             keyserver_fetch which passes an entire URL.  Better use a
+             separate function here. */
+          pattern[npat] = xtrystrdup ("0x0000000000000000");
+          if (!pattern[npat])
+            err = gpg_error_from_syserror ();
+          else
+            {
+              npat++;
+              quiet = 1;
+            }
+        }
+      else if (desc[idx].mode == KEYDB_SEARCH_MODE_NONE)
+        continue;
+      else
+        BUG();
+
+      if (err)
+        {
+          for (idx=0; idx < npat; idx++)
+            xfree (pattern[idx]);
+          xfree (pattern);
+          return err;
+        }
+
+      if (!quiet && keyserver)
+        {
+          if (keyserver->host)
+            log_info (_("requesting key %s from %s server %s\n"),
+                      keystr_from_desc (&desc[idx]),
+                      keyserver->scheme, keyserver->host);
+          else
+            log_info (_("requesting key %s from %s\n"),
+                      keystr_from_desc (&desc[idx]), keyserver->uri);
+        }
+    }
+
+
+  err = gpg_dirmngr_ks_get (ctrl, pattern, &datastream);
+  for (idx=0; idx < npat; idx++)
+    xfree (pattern[idx]);
+  xfree (pattern);
+  if (!err)
+    {
+      void *stats_handle;
+
+      stats_handle = import_new_stats_handle();
+
+      /* FIXME: Check whether this comment should be moved to dirmngr.
+
+         Slurp up all the key data.  In the future, it might be nice
+         to look for KEY foo OUTOFBAND and FAILED indicators.  It's
+         harmless to ignore them, but ignoring them does make gpg
+         complain about "no valid OpenPGP data found".  One way to do
+         this could be to continue parsing this line-by-line and make
+         a temp iobuf for each key. */
+
+      import_keys_es_stream (ctrl, datastream, stats_handle, NULL, NULL,
+                             opt.keyserver_options.import_options);
+
+      import_print_stats (stats_handle);
+      import_release_stats_handle (stats_handle);
+    }
+  es_fclose (datastream);
+
+
+  return err;
 }
 
 
+
+
+
 int
 keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
 {
@@ -2075,7 +2296,7 @@ keyserver_fetch (ctrl_t ctrl, strlist_t urilist)
        {
          int rc;
 
-         rc = keyserver_work (ctrl, KS_GET, NULL, &desc, 1, NULL, NULL, spec);
+         rc = keyserver_get (ctrl, &desc, 1, spec);
          if(rc)
            log_info (_("WARNING: unable to fetch URI %s: %s\n"),
                     sl->d,g10_errstr(rc));
@@ -2275,7 +2496,7 @@ keyserver_import_ldap (ctrl_t ctrl,
          snprintf(port,7,":%u",srvlist[i].port);
          strcat(keyserver->host,port);
        }
-       
+
       strcat(keyserver->host," ");
     }
 
@@ -2291,7 +2512,7 @@ keyserver_import_ldap (ctrl_t ctrl,
   strcat(keyserver->host,domain);
 
   append_to_strlist(&list,name);
-    
+
   rc = keyserver_work (ctrl, KS_GETNAME, list, NULL,
                        0, fpr, fpr_len, keyserver);
 
index b673cf5..2e76084 100644 (file)
@@ -272,6 +272,9 @@ void import_keys (ctrl_t ctrl, char **fnames, int nnames,
 int import_keys_stream (ctrl_t ctrl, iobuf_t inp, void *stats_hd, 
                         unsigned char **fpr,
                        size_t *fpr_len, unsigned int options);
+int import_keys_es_stream (ctrl_t ctrl, estream_t fp, void *stats_handle,
+                           unsigned char **fpr, size_t *fpr_len,
+                           unsigned int options);
 void *import_new_stats_handle (void);
 void import_release_stats_handle (void *p);
 void import_print_stats (void *hd);
index eec7d04..8545431 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gnupg-2.1.0\n"
 "Report-Msgid-Bugs-To: translations@gnupg.org\n"
-"POT-Creation-Date: 2010-11-23 19:37+0100\n"
+"POT-Creation-Date: 2011-01-14 21:03+0100\n"
 "PO-Revision-Date: 2010-11-23 19:38+0100\n"
 "Last-Translator: Werner Koch <wk@gnupg.org>\n"
 "Language-Team: German <de@li.org>\n"
@@ -114,23 +114,23 @@ msgid "ssh keys greater than %d bits are not supported\n"
 msgstr "SSH Schlüssel von mehr als %d Bits werden nicht unterstützt\n"
 
 #: agent/command-ssh.c:685 common/dotlock.c:326 g10/card-util.c:841
-#: g10/exec.c:481 g10/gpg.c:1128 g10/keygen.c:3202 g10/keyring.c:1213
+#: g10/exec.c:481 g10/gpg.c:1129 g10/keygen.c:3202 g10/keyring.c:1213
 #: g10/keyring.c:1521 g10/openfile.c:290 g10/openfile.c:383 g10/sign.c:870
-#: g10/sign.c:1181 g10/tdbio.c:548
+#: g10/sign.c:1181 g10/tdbio.c:562
 #, c-format
 msgid "can't create `%s': %s\n"
 msgstr "'%s' kann nicht erzeugt werden: %s\n"
 
 #: agent/command-ssh.c:697 common/helpfile.c:47 g10/card-util.c:795
 #: g10/dearmor.c:60 g10/dearmor.c:107 g10/decrypt.c:67 g10/decrypt.c:129
-#: g10/decrypt.c:146 g10/encrypt.c:198 g10/encrypt.c:547 g10/gpg.c:1129
+#: g10/decrypt.c:146 g10/encrypt.c:198 g10/encrypt.c:547 g10/gpg.c:1130
 #: g10/import.c:197 g10/keygen.c:2713 g10/keyring.c:1547 g10/openfile.c:197
 #: g10/openfile.c:211 g10/openfile.c:368 g10/plaintext.c:584 g10/sign.c:852
 #: g10/sign.c:1047 g10/sign.c:1165 g10/sign.c:1323 g10/tdbdump.c:142
-#: g10/tdbdump.c:150 g10/tdbio.c:552 g10/tdbio.c:616 g10/verify.c:98
+#: g10/tdbdump.c:150 g10/tdbio.c:566 g10/tdbio.c:647 g10/verify.c:98
 #: g10/verify.c:161 sm/gpgsm.c:2054 sm/gpgsm.c:2084 sm/gpgsm.c:2122
-#: sm/qualified.c:66 dirmngr/certcache.c:359 dirmngr/crlcache.c:2380
-#: dirmngr/dirmngr.c:1458
+#: sm/qualified.c:66 dirmngr/certcache.c:359 dirmngr/crlcache.c:2405
+#: dirmngr/dirmngr.c:1466
 #, c-format
 msgid "can't open `%s': %s\n"
 msgstr "'%s' kann nicht geöffnet werden: %s\n"
@@ -357,7 +357,7 @@ msgstr "Im Server Modus ausführen"
 msgid "run in daemon mode (background)"
 msgstr "Im Daemon Modus ausführen"
 
-#: agent/gpg-agent.c:126 g10/gpg.c:493 g10/gpgv.c:71 kbx/kbxutil.c:88
+#: agent/gpg-agent.c:126 g10/gpg.c:494 g10/gpgv.c:71 kbx/kbxutil.c:88
 #: scd/scdaemon.c:110 sm/gpgsm.c:281 dirmngr/dirmngr-client.c:68
 #: dirmngr/dirmngr.c:149 dirmngr/dirmngr_ldap.c:127
 #: tools/gpg-connect-agent.c:71 tools/gpgconf.c:79 tools/symcryptrun.c:163
@@ -446,9 +446,9 @@ msgstr "|DATEI|Schreibe die Umgebungsvariablen auf DATEI"
 #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug
 #. reporting address.  This is so that we can change the
 #. reporting address without breaking the translations.
-#: agent/gpg-agent.c:334 agent/preset-passphrase.c:93 agent/protect-tool.c:148
-#: g10/gpg.c:820 g10/gpgv.c:114 kbx/kbxutil.c:113 scd/scdaemon.c:247
-#: sm/gpgsm.c:529 dirmngr/dirmngr-client.c:147 dirmngr/dirmngr.c:298
+#: agent/gpg-agent.c:341 agent/preset-passphrase.c:93 agent/protect-tool.c:148
+#: g10/gpg.c:821 g10/gpgv.c:114 kbx/kbxutil.c:113 scd/scdaemon.c:247
+#: sm/gpgsm.c:529 dirmngr/dirmngr-client.c:147 dirmngr/dirmngr.c:302
 #: dirmngr/dirmngr_ldap.c:197 tools/gpg-connect-agent.c:188
 #: tools/gpgconf.c:101 tools/symcryptrun.c:203 tools/gpg-check-pattern.c:141
 msgid "Please report bugs to <@EMAIL@>.\n"
@@ -456,11 +456,11 @@ msgstr ""
 "Berichte über Programmfehler bitte in englisch an <@EMAIL@>.\n"
 "Sinn- oder Schreibfehler in den deutschen Texten bitte an <de@li.org>.\n"
 
-#: agent/gpg-agent.c:343
+#: agent/gpg-agent.c:350
 msgid "Usage: gpg-agent [options] (-h for help)"
 msgstr "Aufruf: gpg-agent [Optionen] (-h für Hilfe)"
 
-#: agent/gpg-agent.c:345
+#: agent/gpg-agent.c:352
 msgid ""
 "Syntax: gpg-agent [options] [command [args]]\n"
 "Secret key management for GnuPG\n"
@@ -468,147 +468,147 @@ msgstr ""
 "Syntax: gpg-agent [Optionen] [Befehl [Argumente]]\n"
 "Verwaltung von geheimen Schlüsseln für GnuPG\n"
 
-#: agent/gpg-agent.c:391 g10/gpg.c:1013 scd/scdaemon.c:320 sm/gpgsm.c:679
-#: dirmngr/dirmngr.c:367
+#: agent/gpg-agent.c:398 g10/gpg.c:1014 scd/scdaemon.c:320 sm/gpgsm.c:679
+#: dirmngr/dirmngr.c:371
 #, c-format
 msgid "invalid debug-level `%s' given\n"
 msgstr "ungültige Debugebene `%s' angegeben\n"
 
-#: agent/gpg-agent.c:616 agent/protect-tool.c:561 kbx/kbxutil.c:428
-#: scd/scdaemon.c:427 sm/gpgsm.c:919 sm/gpgsm.c:922 dirmngr/dirmngr.c:625
-#: dirmngr/dirmngr.c:628 tools/symcryptrun.c:1001
+#: agent/gpg-agent.c:623 agent/protect-tool.c:561 kbx/kbxutil.c:428
+#: scd/scdaemon.c:427 sm/gpgsm.c:919 sm/gpgsm.c:922 dirmngr/dirmngr.c:629
+#: dirmngr/dirmngr.c:632 tools/symcryptrun.c:1001
 #: tools/gpg-check-pattern.c:177
 #, c-format
 msgid "%s is too old (need %s, have %s)\n"
 msgstr "Die Bibliothek %s ist nicht aktuell (benötige %s, habe %s)\n"
 
-#: agent/gpg-agent.c:730 g10/gpg.c:2121 scd/scdaemon.c:513 sm/gpgsm.c:1019
-#: dirmngr/dirmngr.c:743
+#: agent/gpg-agent.c:737 g10/gpg.c:2122 scd/scdaemon.c:513 sm/gpgsm.c:1019
+#: dirmngr/dirmngr.c:751
 #, c-format
 msgid "NOTE: no default option file `%s'\n"
 msgstr "Hinweis: Keine voreingestellte Optionendatei '%s' vorhanden\n"
 
-#: agent/gpg-agent.c:741 agent/gpg-agent.c:1343 g10/gpg.c:2125
-#: scd/scdaemon.c:518 sm/gpgsm.c:1023 dirmngr/dirmngr.c:748
-#: dirmngr/dirmngr.c:1564 tools/symcryptrun.c:934
+#: agent/gpg-agent.c:748 agent/gpg-agent.c:1350 g10/gpg.c:2126
+#: scd/scdaemon.c:518 sm/gpgsm.c:1023 dirmngr/dirmngr.c:756
+#: dirmngr/dirmngr.c:1572 tools/symcryptrun.c:934
 #, c-format
 msgid "option file `%s': %s\n"
 msgstr "Optionendatei '%s': %s\n"
 
-#: agent/gpg-agent.c:749 g10/gpg.c:2132 scd/scdaemon.c:526 sm/gpgsm.c:1030
-#: dirmngr/dirmngr.c:756
+#: agent/gpg-agent.c:756 g10/gpg.c:2133 scd/scdaemon.c:526 sm/gpgsm.c:1030
+#: dirmngr/dirmngr.c:764
 #, c-format
 msgid "reading options from `%s'\n"
 msgstr "Optionen werden aus '%s' gelesen\n"
 
-#: agent/gpg-agent.c:1118 g10/plaintext.c:160 g10/plaintext.c:169
+#: agent/gpg-agent.c:1125 g10/plaintext.c:160 g10/plaintext.c:169
 #: g10/plaintext.c:175 g10/plaintext.c:198
 #, c-format
 msgid "error creating `%s': %s\n"
 msgstr "Fehler beim Erstellen von `%s': %s\n"
 
-#: agent/gpg-agent.c:1464 agent/gpg-agent.c:1591 agent/gpg-agent.c:1630
+#: agent/gpg-agent.c:1470 agent/gpg-agent.c:1597 agent/gpg-agent.c:1636
 #: g10/exec.c:196 g10/openfile.c:444 scd/scdaemon.c:1037
 #, c-format
 msgid "can't create directory `%s': %s\n"
 msgstr "Verzeichnis `%s' kann nicht erzeugt werden: %s\n"
 
-#: agent/gpg-agent.c:1478 scd/scdaemon.c:1051 dirmngr/dirmngr.c:956
+#: agent/gpg-agent.c:1484 scd/scdaemon.c:1051 dirmngr/dirmngr.c:964
 msgid "name of socket too long\n"
 msgstr "Der Name des Sockets ist zu lang\n"
 
-#: agent/gpg-agent.c:1501 scd/scdaemon.c:1074 dirmngr/dirmngr.c:963
+#: agent/gpg-agent.c:1507 scd/scdaemon.c:1074 dirmngr/dirmngr.c:971
 #, c-format
 msgid "can't create socket: %s\n"
 msgstr "Socket kann nicht erzeugt werden: %s\n"
 
-#: agent/gpg-agent.c:1510
+#: agent/gpg-agent.c:1516
 #, c-format
 msgid "socket name `%s' is too long\n"
 msgstr "Der Name des Sockets `%s' ist zu lang\n"
 
-#: agent/gpg-agent.c:1538
+#: agent/gpg-agent.c:1544
 msgid "a gpg-agent is already running - not starting a new one\n"
 msgstr "Ein gpg-agent läuft bereits - ein weiterer wird nicht gestartet\n"
 
-#: agent/gpg-agent.c:1549 scd/scdaemon.c:1093 dirmngr/dirmngr.c:987
+#: agent/gpg-agent.c:1555 scd/scdaemon.c:1093 dirmngr/dirmngr.c:995
 msgid "error getting nonce for the socket\n"
 msgstr "Fehler beim Ermitteln der \"Nonce\" dieses Sockets\n"
 
-#: agent/gpg-agent.c:1554 scd/scdaemon.c:1096 dirmngr/dirmngr.c:990
+#: agent/gpg-agent.c:1560 scd/scdaemon.c:1096 dirmngr/dirmngr.c:998
 #, c-format
 msgid "error binding socket to `%s': %s\n"
 msgstr "Der Socket kann nicht an `%s' gebunden werden: %s\n"
 
-#: agent/gpg-agent.c:1566 scd/scdaemon.c:1105 dirmngr/dirmngr.c:999
+#: agent/gpg-agent.c:1572 scd/scdaemon.c:1105 dirmngr/dirmngr.c:1007
 #, c-format
 msgid "listen() failed: %s\n"
 msgstr "Der listen()-Aufruf ist fehlgeschlagen: %s\n"
 
-#: agent/gpg-agent.c:1572 scd/scdaemon.c:1112 dirmngr/dirmngr.c:1005
+#: agent/gpg-agent.c:1578 scd/scdaemon.c:1112 dirmngr/dirmngr.c:1013
 #, c-format
 msgid "listening on socket `%s'\n"
 msgstr "Es wird auf Socket `%s' gehört\n"
 
-#: agent/gpg-agent.c:1594 agent/gpg-agent.c:1635 g10/openfile.c:447
+#: agent/gpg-agent.c:1600 agent/gpg-agent.c:1641 g10/openfile.c:447
 #, c-format
 msgid "directory `%s' created\n"
 msgstr "Verzeichnis `%s' erzeugt\n"
 
-#: agent/gpg-agent.c:1641
+#: agent/gpg-agent.c:1647
 #, c-format
 msgid "stat() failed for `%s': %s\n"
 msgstr "stat()-Aufruf für `%s' fehlgeschlagen: %s\n"
 
-#: agent/gpg-agent.c:1645
+#: agent/gpg-agent.c:1651
 #, c-format
 msgid "can't use `%s' as home directory\n"
 msgstr "Die Datei `%s' kann nicht als Home-Verzeichnis benutzt werden\n"
 
-#: agent/gpg-agent.c:1777 scd/scdaemon.c:1128 dirmngr/dirmngr.c:1681
+#: agent/gpg-agent.c:1785 scd/scdaemon.c:1128 dirmngr/dirmngr.c:1689
 #, c-format
 msgid "error reading nonce on fd %d: %s\n"
 msgstr "Fehler beim Lesen der \"Nonce\" von FD %d: %s\n"
 
-#: agent/gpg-agent.c:1799
+#: agent/gpg-agent.c:1810
 #, c-format
 msgid "handler 0x%lx for fd %d started\n"
 msgstr "Handhabungsroutine 0x%lx für fd %d gestartet\n"
 
-#: agent/gpg-agent.c:1804
+#: agent/gpg-agent.c:1815
 #, c-format
 msgid "handler 0x%lx for fd %d terminated\n"
 msgstr "Handhabungsroutine 0x%lx für den fd %d beendet\n"
 
-#: agent/gpg-agent.c:1824
+#: agent/gpg-agent.c:1835
 #, c-format
 msgid "ssh handler 0x%lx for fd %d started\n"
 msgstr "SSH-Handhabungsroutine 0x%lx für fd %d gestartet\n"
 
-#: agent/gpg-agent.c:1829
+#: agent/gpg-agent.c:1840
 #, c-format
 msgid "ssh handler 0x%lx for fd %d terminated\n"
 msgstr "SSH-Handhabungsroutine 0x%lx für fd %d beendet\n"
 
-#: agent/gpg-agent.c:1973 scd/scdaemon.c:1265
+#: agent/gpg-agent.c:1985 scd/scdaemon.c:1265
 #, c-format
 msgid "pth_select failed: %s - waiting 1s\n"
 msgstr "pth_select()-Aufruf fehlgeschlagen: %s - warte 1s\n"
 
-#: agent/gpg-agent.c:2096 scd/scdaemon.c:1332
+#: agent/gpg-agent.c:2108 scd/scdaemon.c:1332
 #, c-format
 msgid "%s %s stopped\n"
 msgstr "%s %s angehalten\n"
 
-#: agent/gpg-agent.c:2232
+#: agent/gpg-agent.c:2244
 msgid "no gpg-agent running in this session\n"
 msgstr "Der gpg-agent läuft nicht für diese Session\n"
 
-#: agent/gpg-agent.c:2243 common/simple-pwquery.c:352 common/asshelp.c:497
+#: agent/gpg-agent.c:2255 common/simple-pwquery.c:352 common/asshelp.c:497
 msgid "malformed GPG_AGENT_INFO environment variable\n"
 msgstr "fehlerhaft aufgebaute GPG_AGENT_INFO - Umgebungsvariable\n"
 
-#: agent/gpg-agent.c:2256 common/simple-pwquery.c:364 common/asshelp.c:509
+#: agent/gpg-agent.c:2268 common/simple-pwquery.c:364 common/asshelp.c:509
 #, c-format
 msgid "gpg-agent protocol version %d is not supported\n"
 msgstr "GPG-Agent-Protokoll-Version %d wird nicht unterstützt\n"
@@ -625,7 +625,7 @@ msgstr ""
 "Syntax: gpg-preset-passphrase [Optionen] KEYGRIP\n"
 "Kennwortpuffer-Pflege\n"
 
-#: agent/protect-tool.c:105 g10/gpg.c:376 kbx/kbxutil.c:71 sm/gpgsm.c:187
+#: agent/protect-tool.c:105 g10/gpg.c:377 kbx/kbxutil.c:71 sm/gpgsm.c:187
 #: dirmngr/dirmngr.c:132 tools/gpgconf.c:59
 msgid ""
 "@Commands:\n"
@@ -634,7 +634,7 @@ msgstr ""
 "@Befehle:\n"
 " "
 
-#: agent/protect-tool.c:114 g10/gpg.c:444 g10/gpgv.c:69 kbx/kbxutil.c:81
+#: agent/protect-tool.c:114 g10/gpg.c:445 g10/gpgv.c:69 kbx/kbxutil.c:81
 #: sm/gpgsm.c:227 dirmngr/dirmngr.c:147 tools/gpg-connect-agent.c:69
 #: tools/gpgconf.c:76 tools/symcryptrun.c:156
 msgid ""
@@ -696,7 +696,7 @@ msgstr "Vom Benutzer abgebrochen\n"
 msgid "error while asking for the passphrase: %s\n"
 msgstr "Fehler bei der Abfrage der Passphrase: %s\n"
 
-#: agent/trustlist.c:135 agent/trustlist.c:332 dirmngr/dirmngr.c:1366
+#: agent/trustlist.c:135 agent/trustlist.c:332 dirmngr/dirmngr.c:1374
 #, c-format
 msgid "error opening `%s': %s\n"
 msgstr "Fehler beim Öffnen von `%s': %s\n"
@@ -862,7 +862,7 @@ msgid "error creating a stream for a pipe: %s\n"
 msgstr "Fehler beim Erzeugen eines \"streams\" zu einer \"pipe\": %s\n"
 
 #: common/exechelp-posix.c:399 common/exechelp-posix.c:465
-#: common/exechelp-posix.c:579 dirmngr/dirmngr.c:1019
+#: common/exechelp-posix.c:579 dirmngr/dirmngr.c:1027
 #, c-format
 msgid "error forking process: %s\n"
 msgstr "Fehler beim \"Forken\" des Prozess: %s\n"
@@ -894,12 +894,12 @@ msgstr "Fehler bei Ausführung von `%s': beendet\n"
 msgid "error getting exit code of process %d: %s\n"
 msgstr "Fehler beim Holen des Exitwerte des Prozesses %d: %s\n"
 
-#: common/http.c:1550
+#: common/http.c:1568
 #, c-format
 msgid "error creating socket: %s\n"
 msgstr "Fehler beim Erstellen des Sockets: %s\n"
 
-#: common/http.c:1594
+#: common/http.c:1612
 msgid "host not found"
 msgstr "Host nicht gefunden"
 
@@ -999,45 +999,35 @@ msgstr ""
 msgid "out of core while allocating %lu bytes"
 msgstr "Kein Speicher mehr vorhanden, als %lu Byte zugewiesen werden sollten"
 
-#: common/asshelp.c:379
+#: common/asshelp.c:378
 #, c-format
 msgid "no running gpg-agent - starting `%s'\n"
 msgstr "Kein aktiver gpg-agent - `%s' wird gestartet\n"
 
-#: common/asshelp.c:435
-#, c-format
-msgid "waiting %d seconds for the agent to come up\n"
+#: common/asshelp.c:436
+#, fuzzy, c-format
+msgid "waiting for the agent to come up ... (%ds)\n"
 msgstr "Warte %d Sekunden bis der gpg-agent bereit ist\n"
 
-#: common/asshelp.c:445
-#, c-format
-msgid "connection to agent established (%ds)\n"
-msgstr "Verbindung zum gpg-agent aufgebaut (%ds)\n"
+#: common/asshelp.c:445 common/asshelp.c:534
+msgid "connection to agent established\n"
+msgstr "Verbindung zum gpg-agent aufgebaut\n"
 
 #: common/asshelp.c:520
 msgid "can't connect to the agent - trying fall back\n"
 msgstr "Verbindung zum gpg-agent nicht möglich - Ersatzmethode wird versucht\n"
 
-#: common/asshelp.c:534
-msgid "connection to agent established\n"
-msgstr "Verbindung zum gpg-agent aufgebaut\n"
-
 #: common/asshelp.c:596
 #, c-format
 msgid "no running Dirmngr - starting `%s'\n"
 msgstr "Kein aktiver Dirmngr - `%s' wird gestartet\n"
 
-#: common/asshelp.c:628
-#, c-format
-msgid "waiting %d seconds for the dirmngr to come up\n"
+#: common/asshelp.c:630
+#, fuzzy, c-format
+msgid "waiting for the dirmngr to come up ... (%ds)\n"
 msgstr "Warte %d Sekunden bis der Dirmngr bereit ist\n"
 
-#: common/asshelp.c:638
-#, c-format
-msgid "connection to the dirmngr established (%ds)\n"
-msgstr "Verbindung zum Dirmngr aufgebaut (%ds)\n"
-
-#: common/asshelp.c:667
+#: common/asshelp.c:639 common/asshelp.c:668
 msgid "connection to the dirmngr established\n"
 msgstr "Verbindung zum Dirmngr aufgebaut\n"
 
@@ -1285,7 +1275,7 @@ msgstr "Option \"%.50s\" ist mehrdeutig\n"
 msgid "command \"%.50s\" is ambiguous\n"
 msgstr "Befehl \"%.50s\" ist mehrdeutig\n"
 
-#: common/argparse.c:266 dirmngr/dirmngr.c:1037
+#: common/argparse.c:266 dirmngr/dirmngr.c:1045
 msgid "out of core\n"
 msgstr "Nicht genügend Speicher\n"
 
@@ -1294,7 +1284,7 @@ msgstr "Nicht genügend Speicher\n"
 msgid "invalid option \"%.50s\"\n"
 msgstr "Ungültige Option \"%.50s\"\n"
 
-#: common/logging.c:822
+#: common/logging.c:860
 #, c-format
 msgid "you found a bug ... (%s:%d)\n"
 msgstr "Sie haben einen Bug (Programmfehler) gefunden ... (%s:%d)\n"
@@ -1564,7 +1554,7 @@ msgstr "Fehler beim Zuteilen genügenden Speichers: %s\n"
 
 #: g10/card-util.c:814 g10/import.c:291 dirmngr/crlcache.c:649
 #: dirmngr/crlcache.c:654 dirmngr/crlcache.c:908 dirmngr/crlcache.c:914
-#: dirmngr/dirmngr.c:1404
+#: dirmngr/dirmngr.c:1412
 #, c-format
 msgid "error reading `%s': %s\n"
 msgstr "Fehler beim Lesen von `%s': %s\n"
@@ -1822,18 +1812,18 @@ msgstr "Ungültiger Befehl (versuchen Sie's mal mit \"help\")\n"
 msgid "--output doesn't work for this command\n"
 msgstr "--output funktioniert nicht bei diesem Befehl\n"
 
-#: g10/decrypt.c:240 g10/gpg.c:4049 g10/keyring.c:379 g10/keyring.c:690
+#: g10/decrypt.c:240 g10/gpg.c:4050 g10/keyring.c:379 g10/keyring.c:690
 #, c-format
 msgid "can't open `%s'\n"
 msgstr "'%s' kann nicht geöffnet werden\n"
 
-#: g10/delkey.c:73 g10/export.c:637 g10/keyedit.c:3355 g10/keyserver.c:1749
+#: g10/delkey.c:73 g10/export.c:637 g10/keyedit.c:3355 g10/keyserver.c:1751
 #: g10/revoke.c:227
 #, c-format
 msgid "key \"%s\" not found: %s\n"
 msgstr "Schlüssel \"%s\" nicht gefunden: %s\n"
 
-#: g10/delkey.c:81 g10/export.c:701 g10/getkey.c:2881 g10/keyserver.c:1763
+#: g10/delkey.c:81 g10/export.c:701 g10/getkey.c:2881 g10/keyserver.c:1765
 #: g10/revoke.c:233 g10/revoke.c:479
 #, c-format
 msgid "error reading keyblock: %s\n"
@@ -2115,171 +2105,171 @@ msgid "no secret subkey for public subkey %s - ignoring\n"
 msgstr ""
 "Kein privater Unterschlüssel zum öffentlichen Unterschlüssel %s - ignoriert\n"
 
-#: g10/gpg.c:378 sm/gpgsm.c:189
+#: g10/gpg.c:379 sm/gpgsm.c:189
 msgid "make a signature"
 msgstr "Eine Signatur erzeugen"
 
-#: g10/gpg.c:379 sm/gpgsm.c:190
+#: g10/gpg.c:380 sm/gpgsm.c:190
 msgid "make a clear text signature"
 msgstr "Eine Klartextsignatur erzeugen"
 
-#: g10/gpg.c:380 sm/gpgsm.c:191
+#: g10/gpg.c:381 sm/gpgsm.c:191
 msgid "make a detached signature"
 msgstr "Eine abgetrennte Signatur erzeugen"
 
-#: g10/gpg.c:381 sm/gpgsm.c:192
+#: g10/gpg.c:382 sm/gpgsm.c:192
 msgid "encrypt data"
 msgstr "Daten verschlüsseln"
 
-#: g10/gpg.c:383 sm/gpgsm.c:193
+#: g10/gpg.c:384 sm/gpgsm.c:193
 msgid "encryption only with symmetric cipher"
 msgstr "Daten symmetrisch verschlüsseln"
 
-#: g10/gpg.c:385 sm/gpgsm.c:194
+#: g10/gpg.c:386 sm/gpgsm.c:194
 msgid "decrypt data (default)"
 msgstr "Daten entschlüsseln (Voreinstellung)"
 
-#: g10/gpg.c:387 sm/gpgsm.c:195
+#: g10/gpg.c:388 sm/gpgsm.c:195
 msgid "verify a signature"
 msgstr "Signatur prüfen"
 
-#: g10/gpg.c:389 sm/gpgsm.c:196
+#: g10/gpg.c:390 sm/gpgsm.c:196
 msgid "list keys"
 msgstr "Liste der Schlüssel"
 
-#: g10/gpg.c:391
+#: g10/gpg.c:392
 msgid "list keys and signatures"
 msgstr "Liste der Schlüssel und ihrer Signaturen"
 
-#: g10/gpg.c:392
+#: g10/gpg.c:393
 msgid "list and check key signatures"
 msgstr "Signaturen der Schlüssel auflisten und prüfen"
 
-#: g10/gpg.c:393 sm/gpgsm.c:201
+#: g10/gpg.c:394 sm/gpgsm.c:201
 msgid "list keys and fingerprints"
 msgstr "Liste der Schlüssel und ihrer \"Fingerabdrücke\""
 
-#: g10/gpg.c:394 sm/gpgsm.c:199
+#: g10/gpg.c:395 sm/gpgsm.c:199
 msgid "list secret keys"
 msgstr "Liste der geheimen Schlüssel"
 
-#: g10/gpg.c:395 sm/gpgsm.c:202
+#: g10/gpg.c:396 sm/gpgsm.c:202
 msgid "generate a new key pair"
 msgstr "Ein neues Schlüsselpaar erzeugen"
 
-#: g10/gpg.c:396
+#: g10/gpg.c:397
 msgid "generate a revocation certificate"
 msgstr "Ein Schlüsselwiderruf-Zertifikat erzeugen"
 
-#: g10/gpg.c:398 sm/gpgsm.c:204
+#: g10/gpg.c:399 sm/gpgsm.c:204
 msgid "remove keys from the public keyring"
 msgstr "Schlüssel aus dem öff. Schlüsselbund entfernen"
 
-#: g10/gpg.c:400
+#: g10/gpg.c:401
 msgid "remove keys from the secret keyring"
 msgstr "Schlüssel aus dem geh. Schlüsselbund entfernen"
 
-#: g10/gpg.c:401
+#: g10/gpg.c:402
 msgid "sign a key"
 msgstr "Schlüssel signieren"
 
-#: g10/gpg.c:402
+#: g10/gpg.c:403
 msgid "sign a key locally"
 msgstr "Schlüssel nur für diesen Rechner signieren"
 
-#: g10/gpg.c:403
+#: g10/gpg.c:404
 msgid "sign or edit a key"
 msgstr "Signieren oder bearbeiten eines Schlüssels"
 
-#: g10/gpg.c:405 sm/gpgsm.c:216
+#: g10/gpg.c:406 sm/gpgsm.c:216
 msgid "change a passphrase"
 msgstr "Die Passphrase ändern"
 
-#: g10/gpg.c:407
+#: g10/gpg.c:408
 msgid "export keys"
 msgstr "Schlüssel exportieren"
 
-#: g10/gpg.c:408 sm/gpgsm.c:205
+#: g10/gpg.c:409 sm/gpgsm.c:205
 msgid "export keys to a key server"
 msgstr "Schlüssel zu einem Schlü.server exportieren"
 
-#: g10/gpg.c:409 sm/gpgsm.c:206
+#: g10/gpg.c:410 sm/gpgsm.c:206
 msgid "import keys from a key server"
 msgstr "Schlüssel von einem Schlü.server importieren"
 
-#: g10/gpg.c:411
+#: g10/gpg.c:412
 msgid "search for keys on a key server"
 msgstr "Schlüssel auf einem Schlü.server suchen"
 
-#: g10/gpg.c:413
+#: g10/gpg.c:414
 msgid "update all keys from a keyserver"
 msgstr "alle Schlüssel per Schlü.server aktualisieren"
 
-#: g10/gpg.c:418
+#: g10/gpg.c:419
 msgid "import/merge keys"
 msgstr "Schlüssel importieren/kombinieren"
 
-#: g10/gpg.c:421
+#: g10/gpg.c:422
 msgid "print the card status"
 msgstr "den Karten-Status ausgeben"
 
-#: g10/gpg.c:422
+#: g10/gpg.c:423
 msgid "change data on a card"
 msgstr "Daten auf einer Karte ändern"
 
-#: g10/gpg.c:423
+#: g10/gpg.c:424
 msgid "change a card's PIN"
 msgstr "PIN einer Karte ändern"
 
-#: g10/gpg.c:432
+#: g10/gpg.c:433
 msgid "update the trust database"
 msgstr "Ändern der \"Trust\"-Datenbank"
 
-#: g10/gpg.c:439
+#: g10/gpg.c:440
 msgid "print message digests"
 msgstr "Hashwerte für die Dateien ausgeben"
 
-#: g10/gpg.c:442 sm/gpgsm.c:211
+#: g10/gpg.c:443 sm/gpgsm.c:211
 msgid "run in server mode"
 msgstr "Im Server Modus ausführen"
 
-#: g10/gpg.c:446 sm/gpgsm.c:229
+#: g10/gpg.c:447 sm/gpgsm.c:229
 msgid "create ascii armored output"
 msgstr "Ausgabe mit ASCII-Hülle versehen"
 
-#: g10/gpg.c:449 sm/gpgsm.c:242
+#: g10/gpg.c:450 sm/gpgsm.c:242
 msgid "|USER-ID|encrypt for USER-ID"
 msgstr "|USER-ID|Verschlüsseln für USER-ID"
 
-#: g10/gpg.c:462 sm/gpgsm.c:278
+#: g10/gpg.c:463 sm/gpgsm.c:278
 msgid "|USER-ID|use USER-ID to sign or decrypt"
 msgstr "|USER-ID|Mit USER-ID signieren bzw. entschlüsseln"
 
-#: g10/gpg.c:467
+#: g10/gpg.c:468
 msgid "|N|set compress level to N (0 disables)"
 msgstr "|N|Kompressionsstufe auf N setzen (0=keine)"
 
-#: g10/gpg.c:473
+#: g10/gpg.c:474
 msgid "use canonical text mode"
 msgstr "Textmodus benutzen"
 
-#: g10/gpg.c:490 sm/gpgsm.c:280
+#: g10/gpg.c:491 sm/gpgsm.c:280
 msgid "|FILE|write output to FILE"
 msgstr "|DATEI|Ausgabe auf DATEI schreiben"
 
-#: g10/gpg.c:506 kbx/kbxutil.c:90 sm/gpgsm.c:292 tools/gpgconf.c:81
+#: g10/gpg.c:507 kbx/kbxutil.c:90 sm/gpgsm.c:292 tools/gpgconf.c:81
 msgid "do not make any changes"
 msgstr "Keine wirklichen Änderungen durchführen"
 
-#: g10/gpg.c:507
+#: g10/gpg.c:508
 msgid "prompt before overwriting"
 msgstr "vor Überschreiben nachfragen"
 
-#: g10/gpg.c:559
+#: g10/gpg.c:560
 msgid "use strict OpenPGP behavior"
 msgstr "OpenPGP-Verhalten strikt beachten"
 
-#: g10/gpg.c:589 sm/gpgsm.c:336
+#: g10/gpg.c:590 sm/gpgsm.c:336
 msgid ""
 "@\n"
 "(See the man page for a complete listing of all commands and options)\n"
@@ -2288,7 +2278,7 @@ msgstr ""
 "(Auf der \"man\"-Seite ist eine vollständige Liste aller Befehle und "
 "Optionen)\n"
 
-#: g10/gpg.c:592 sm/gpgsm.c:339
+#: g10/gpg.c:593 sm/gpgsm.c:339
 msgid ""
 "@\n"
 "Examples:\n"
@@ -2308,11 +2298,11 @@ msgstr ""
 " --list-keys [Namen]        Schlüssel anzeigen\n"
 " --fingerprint [Namen]      \"Fingerabdrücke\" anzeigen\n"
 
-#: g10/gpg.c:842
+#: g10/gpg.c:843
 msgid "Usage: gpg [options] [files] (-h for help)"
 msgstr "Aufruf: gpg [Optionen] [Dateien] (-h für Hilfe)"
 
-#: g10/gpg.c:845
+#: g10/gpg.c:846
 msgid ""
 "Syntax: gpg [options] [files]\n"
 "sign, check, encrypt or decrypt\n"
@@ -2322,7 +2312,7 @@ msgstr ""
 "Signieren, prüfen, verschlüsseln, entschlüsseln.\n"
 "Die voreingestellte Operation ist abhängig von den Eingabedaten\n"
 
-#: g10/gpg.c:856 sm/gpgsm.c:553
+#: g10/gpg.c:857 sm/gpgsm.c:553
 msgid ""
 "\n"
 "Supported algorithms:\n"
@@ -2330,73 +2320,73 @@ msgstr ""
 "\n"
 "Unterstützte Verfahren:\n"
 
-#: g10/gpg.c:859
+#: g10/gpg.c:860
 msgid "Pubkey: "
 msgstr "Öff. Schlüssel: "
 
-#: g10/gpg.c:866 g10/keyedit.c:2325
+#: g10/gpg.c:867 g10/keyedit.c:2325
 msgid "Cipher: "
 msgstr "Verschlü.: "
 
-#: g10/gpg.c:873
+#: g10/gpg.c:874
 msgid "Hash: "
 msgstr "Hash: "
 
-#: g10/gpg.c:880 g10/keyedit.c:2374
+#: g10/gpg.c:881 g10/keyedit.c:2374
 msgid "Compression: "
 msgstr "Komprimierung: "
 
-#: g10/gpg.c:950
+#: g10/gpg.c:951
 msgid "usage: gpg [options] "
 msgstr "Aufruf: gpg [Optionen] "
 
-#: g10/gpg.c:1164 sm/gpgsm.c:726
+#: g10/gpg.c:1165 sm/gpgsm.c:726
 msgid "conflicting commands\n"
 msgstr "Widersprüchliche Befehle\n"
 
-#: g10/gpg.c:1182
+#: g10/gpg.c:1183
 #, c-format
 msgid "no = sign found in group definition `%s'\n"
 msgstr "Kein '='-Zeichen in der Gruppendefinition gefunden `%s'\n"
 
-#: g10/gpg.c:1379
+#: g10/gpg.c:1380
 #, c-format
 msgid "WARNING: unsafe ownership on homedir `%s'\n"
 msgstr "WARNUNG: Unsicheres Besitzverhältnis des Home-Verzeichnis `%s'\n"
 
-#: g10/gpg.c:1382
+#: g10/gpg.c:1383
 #, c-format
 msgid "WARNING: unsafe ownership on configuration file `%s'\n"
 msgstr "WARNUNG: Unsicheres Besitzverhältnis der Konfigurationsdatei `%s'\n"
 
-#: g10/gpg.c:1385
+#: g10/gpg.c:1386
 #, c-format
 msgid "WARNING: unsafe ownership on extension `%s'\n"
 msgstr "WARNUNG: Unsicheres Besitzverhältnis auf die Erweiterung `%s'\n"
 
-#: g10/gpg.c:1391
+#: g10/gpg.c:1392
 #, c-format
 msgid "WARNING: unsafe permissions on homedir `%s'\n"
 msgstr "WARNUNG: Unsichere Zugriffsrechte des Home-Verzeichnis `%s'\n"
 
-#: g10/gpg.c:1394
+#: g10/gpg.c:1395
 #, c-format
 msgid "WARNING: unsafe permissions on configuration file `%s'\n"
 msgstr "WARNUNG: Unsichere Zugriffsrechte der Konfigurationsdatei `%s'\n"
 
-#: g10/gpg.c:1397
+#: g10/gpg.c:1398
 #, c-format
 msgid "WARNING: unsafe permissions on extension `%s'\n"
 msgstr "WARNUNG: Unsichere Zugriffsrechte auf die Erweiterung `%s'\n"
 
-#: g10/gpg.c:1403
+#: g10/gpg.c:1404
 #, c-format
 msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n"
 msgstr ""
 "WARNUNG: Unsicheres Besitzverhältnis des umgebenden Verzeichnisses für Home-"
 "Verzeichnis `%s'\n"
 
-#: g10/gpg.c:1406
+#: g10/gpg.c:1407
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory ownership on configuration file `%s'\n"
@@ -2404,20 +2394,20 @@ msgstr ""
 "WARNUNG: Unsicheres Besitzverhältnis des umgebenden Verzeichnisses der "
 "Konfigurationsdatei `%s'\n"
 
-#: g10/gpg.c:1409
+#: g10/gpg.c:1410
 #, c-format
 msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n"
 msgstr ""
 "WARNUNG: Unsicheres Besitzverhältnis des umgebenden Verzeichnisses `%s'\n"
 
-#: g10/gpg.c:1415
+#: g10/gpg.c:1416
 #, c-format
 msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n"
 msgstr ""
 "WARNUNG: Unsichere Zugriffsrechte des umgebenden Verzeichnisses des Home-"
 "Verzeichnisses `%s'\n"
 
-#: g10/gpg.c:1418
+#: g10/gpg.c:1419
 #, c-format
 msgid ""
 "WARNING: unsafe enclosing directory permissions on configuration file `%s'\n"
@@ -2425,481 +2415,481 @@ msgstr ""
 "WARNUNG: Unsichere Zugriffsrechte des umgebenden Verzeichnisses der "
 "Konfigurationsdatei `%s'\n"
 
-#: g10/gpg.c:1421
+#: g10/gpg.c:1422
 #, c-format
 msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n"
 msgstr ""
 "WARNUNG: Unsichere Zugriffsrechte des umgebenden Verzeichnisses auf "
 "Erweiterung `%s'\n"
 
-#: g10/gpg.c:1604
+#: g10/gpg.c:1605
 #, c-format
 msgid "unknown configuration item `%s'\n"
 msgstr "Unbekanntes Konfigurationselement `%s'\n"
 
-#: g10/gpg.c:1710
+#: g10/gpg.c:1711
 msgid "display photo IDs during key listings"
 msgstr "Anzeigen der Foto-ID in den Schlüssellisten"
 
-#: g10/gpg.c:1712
+#: g10/gpg.c:1713
 msgid "show policy URLs during signature listings"
 msgstr "Zeige Richtlinien-URL während des listens der Signaturen"
 
-#: g10/gpg.c:1714
+#: g10/gpg.c:1715
 msgid "show all notations during signature listings"
 msgstr "Alle Notationen mit den Signaturen anlisten"
 
-#: g10/gpg.c:1716
+#: g10/gpg.c:1717
 msgid "show IETF standard notations during signature listings"
 msgstr "Zeige IETF-Standard"
 
-#: g10/gpg.c:1720
+#: g10/gpg.c:1721
 msgid "show user-supplied notations during signature listings"
 msgstr "Zeige Benutzer-Notationen während des listens der Signaturen"
 
-#: g10/gpg.c:1722
+#: g10/gpg.c:1723
 msgid "show preferred keyserver URLs during signature listings"
 msgstr "Der bevorzugten Schlüsselserver mit den Signaturen anlisten"
 
-#: g10/gpg.c:1724
+#: g10/gpg.c:1725
 msgid "show user ID validity during key listings"
 msgstr "Zeige Gültigkeit der User-ID in den Schlüssellisten"
 
-#: g10/gpg.c:1726
+#: g10/gpg.c:1727
 msgid "show revoked and expired user IDs in key listings"
 msgstr "Zeige widerrufene und verfallene User-ID in den Schlüssellisten"
 
-#: g10/gpg.c:1728
+#: g10/gpg.c:1729
 msgid "show revoked and expired subkeys in key listings"
 msgstr "Zeige widerrufene und verfallene Unterschlüssel in den Schlüssellisten"
 
-#: g10/gpg.c:1730
+#: g10/gpg.c:1731
 msgid "show the keyring name in key listings"
 msgstr "Anzeigen des Schlüsselbundes, in dem ein Schlüssel drin ist"
 
-#: g10/gpg.c:1732
+#: g10/gpg.c:1733
 msgid "show expiration dates during signature listings"
 msgstr "Das Ablaufdatum mit den Signaturen anlisten"
 
-#: g10/gpg.c:1866
+#: g10/gpg.c:1867
 #, c-format
 msgid "NOTE: old default options file `%s' ignored\n"
 msgstr "Hinweis: Alte voreingestellte Optionendatei '%s' wurde ignoriert\n"
 
-#: g10/gpg.c:1957
+#: g10/gpg.c:1958
 #, c-format
 msgid "libgcrypt is too old (need %s, have %s)\n"
 msgstr ""
 "Die Bibliothek \"libgcrypt\" ist zu alt (benötigt wird %s, vorhanden ist %"
 "s)\n"
 
-#: g10/gpg.c:2359 g10/gpg.c:3065 g10/gpg.c:3077
+#: g10/gpg.c:2360 g10/gpg.c:3066 g10/gpg.c:3078
 #, c-format
 msgid "NOTE: %s is not for normal use!\n"
 msgstr "Hinweis: %s ist nicht für den üblichen Gebrauch gedacht!\n"
 
-#: g10/gpg.c:2548 g10/gpg.c:2560
+#: g10/gpg.c:2549 g10/gpg.c:2561
 #, c-format
 msgid "`%s' is not a valid signature expiration\n"
 msgstr "`%s' ist kein gültiges Signaturablaufdatum\n"
 
-#: g10/gpg.c:2642
+#: g10/gpg.c:2643
 #, c-format
 msgid "`%s' is not a valid character set\n"
 msgstr "`%s' ist kein gültiger Zeichensatz\n"
 
-#: g10/gpg.c:2665 g10/gpg.c:2860 g10/keyedit.c:3951
+#: g10/gpg.c:2666 g10/gpg.c:2861 g10/keyedit.c:3951
 msgid "could not parse keyserver URL\n"
 msgstr "Schlüsselserver-URL konnte nicht analysiert werden\n"
 
-#: g10/gpg.c:2677
+#: g10/gpg.c:2678
 #, c-format
 msgid "%s:%d: invalid keyserver options\n"
 msgstr "%s:%d: ungültige Schlüsselserver-Option\n"
 
-#: g10/gpg.c:2680
+#: g10/gpg.c:2681
 msgid "invalid keyserver options\n"
 msgstr "Ungültige Schlüsselserver-Option\n"
 
-#: g10/gpg.c:2687
+#: g10/gpg.c:2688
 #, c-format
 msgid "%s:%d: invalid import options\n"
 msgstr "%s:%d: ungültige Import-Option\n"
 
-#: g10/gpg.c:2690
+#: g10/gpg.c:2691
 msgid "invalid import options\n"
 msgstr "Ungültige Import-Option\n"
 
-#: g10/gpg.c:2697
+#: g10/gpg.c:2698
 #, c-format
 msgid "%s:%d: invalid export options\n"
 msgstr "%s:%d: ungültige Export-Option.\n"
 
-#: g10/gpg.c:2700
+#: g10/gpg.c:2701
 msgid "invalid export options\n"
 msgstr "Ungültige Export-Option\n"
 
-#: g10/gpg.c:2707
+#: g10/gpg.c:2708
 #, c-format
 msgid "%s:%d: invalid list options\n"
 msgstr "%s:%d: ungültige Listen-Option.\n"
 
-#: g10/gpg.c:2710
+#: g10/gpg.c:2711
 msgid "invalid list options\n"
 msgstr "Ungültige Listen-Option\n"
 
-#: g10/gpg.c:2718
+#: g10/gpg.c:2719
 msgid "display photo IDs during signature verification"
 msgstr "Foto-ID während der Signaturprüfung anzeigen"
 
-#: g10/gpg.c:2720
+#: g10/gpg.c:2721
 msgid "show policy URLs during signature verification"
 msgstr "Richtlinien-URLs während der Signaturprüfung anzeigen"
 
-#: g10/gpg.c:2722
+#: g10/gpg.c:2723
 msgid "show all notations during signature verification"
 msgstr "Alle Notationen während der Signaturprüfung anzeigen"
 
-#: g10/gpg.c:2724
+#: g10/gpg.c:2725
 msgid "show IETF standard notations during signature verification"
 msgstr "Standard-Notationen während der Signaturprüfung anzeigen"
 
-#: g10/gpg.c:2728
+#: g10/gpg.c:2729
 msgid "show user-supplied notations during signature verification"
 msgstr "Benutzer-Notationen während der Signaturprüfung anzeigen"
 
-#: g10/gpg.c:2730
+#: g10/gpg.c:2731
 msgid "show preferred keyserver URLs during signature verification"
 msgstr ""
 "Die URL für den bevorzugten Schlüsselserver während der Signaturprüfung "
 "anzeigen"
 
-#: g10/gpg.c:2732
+#: g10/gpg.c:2733
 msgid "show user ID validity during signature verification"
 msgstr "Die Gültigkeit der User-ID während der Signaturprüfung anzeigen"
 
-#: g10/gpg.c:2734
+#: g10/gpg.c:2735
 msgid "show revoked and expired user IDs in signature verification"
 msgstr "Zeige widerrufene und verfallene User-IDs während der Signaturprüfung"
 
-#: g10/gpg.c:2736
+#: g10/gpg.c:2737
 msgid "show only the primary user ID in signature verification"
 msgstr "Zeige nur die Haupt-User-ID während der Signaturprüfung"
 
-#: g10/gpg.c:2738
+#: g10/gpg.c:2739
 msgid "validate signatures with PKA data"
 msgstr "Prüfe Signaturgültigkeit mittels PKA-Daten"
 
-#: g10/gpg.c:2740
+#: g10/gpg.c:2741
 msgid "elevate the trust of signatures with valid PKA data"
 msgstr "Werte das Vertrauen zu Signaturen durch gültige PKA-Daten auf"
 
-#: g10/gpg.c:2747
+#: g10/gpg.c:2748
 #, c-format
 msgid "%s:%d: invalid verify options\n"
 msgstr "%s:%d: ungültige Überprüfungs-Option.\n"
 
-#: g10/gpg.c:2750
+#: g10/gpg.c:2751
 msgid "invalid verify options\n"
 msgstr "Ungültige Überprüfungs-Option\n"
 
-#: g10/gpg.c:2757
+#: g10/gpg.c:2758
 #, c-format
 msgid "unable to set exec-path to %s\n"
 msgstr "Der Ausführungspfad konnte nicht auf %s gesetzt werden.\n"
 
-#: g10/gpg.c:2943
+#: g10/gpg.c:2944
 #, c-format
 msgid "%s:%d: invalid auto-key-locate list\n"
 msgstr "%s:%d: ungültige \"auto-key-locate\"-Liste\n"
 
-#: g10/gpg.c:2946
+#: g10/gpg.c:2947
 msgid "invalid auto-key-locate list\n"
 msgstr "ungültige \"auto-key-locate\"-Liste\n"
 
-#: g10/gpg.c:3054 sm/gpgsm.c:1452
+#: g10/gpg.c:3055 sm/gpgsm.c:1452
 msgid "WARNING: program may create a core file!\n"
 msgstr "WARNUNG: Programm könnte eine core-dump-Datei schreiben!\n"
 
-#: g10/gpg.c:3058
+#: g10/gpg.c:3059
 #, c-format
 msgid "WARNING: %s overrides %s\n"
 msgstr "WARNUNG: %s ersetzt %s\n"
 
-#: g10/gpg.c:3067
+#: g10/gpg.c:3068
 #, c-format
 msgid "%s not allowed with %s!\n"
 msgstr "%s kann nicht zusammen mit %s verwendet werden!\n"
 
-#: g10/gpg.c:3070
+#: g10/gpg.c:3071
 #, c-format
 msgid "%s makes no sense with %s!\n"
 msgstr "%s zusammen mit %s ist nicht sinnvoll!\n"
 
-#: g10/gpg.c:3085 sm/gpgsm.c:1469 dirmngr/dirmngr.c:865
+#: g10/gpg.c:3086 sm/gpgsm.c:1469 dirmngr/dirmngr.c:873
 msgid "WARNING: running with faked system time: "
 msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: "
 
-#: g10/gpg.c:3096
+#: g10/gpg.c:3097
 #, c-format
 msgid "will not run with insecure memory due to %s\n"
 msgstr "Startet nicht mit unsicherem Speicher, wegen Option %s\n"
 
-#: g10/gpg.c:3110
+#: g10/gpg.c:3111
 msgid "you can only make detached or clear signatures while in --pgp2 mode\n"
 msgstr ""
 "Im --pgp2-Modus können Sie nur abgetrennte oder Klartextsignaturen machen\n"
 
-#: g10/gpg.c:3116
+#: g10/gpg.c:3117
 msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n"
 msgstr ""
 "Im --pgp2-Modus können Sie nicht gleichzeitig signieren und verschlüsseln\n"
 
-#: g10/gpg.c:3122
+#: g10/gpg.c:3123
 msgid "you must use files (and not a pipe) when working with --pgp2 enabled.\n"
 msgstr ""
 "Im --pgp2-Modus müssen Sie Dateien benutzen und können keine Pipes "
 "verwenden.\n"
 
-#: g10/gpg.c:3135
+#: g10/gpg.c:3136
 msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n"
 msgstr ""
 "Verschlüsseln einer Botschaft benötigt im --pgp2-Modus die IDEA-"
 "Verschlüsselung\n"
 
-#: g10/gpg.c:3202 g10/gpg.c:3226 sm/gpgsm.c:1524
+#: g10/gpg.c:3203 g10/gpg.c:3227 sm/gpgsm.c:1524
 msgid "selected cipher algorithm is invalid\n"
 msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\n"
 
-#: g10/gpg.c:3208 g10/gpg.c:3232 sm/gpgsm.c:1530 sm/gpgsm.c:1536
+#: g10/gpg.c:3209 g10/gpg.c:3233 sm/gpgsm.c:1530 sm/gpgsm.c:1536
 msgid "selected digest algorithm is invalid\n"
 msgstr "Das ausgewählte Hashverfahren ist ungültig\n"
 
-#: g10/gpg.c:3214
+#: g10/gpg.c:3215
 msgid "selected compression algorithm is invalid\n"
 msgstr "Das ausgewählte Komprimierungsverfahren ist ungültig\n"
 
-#: g10/gpg.c:3220
+#: g10/gpg.c:3221
 msgid "selected certification digest algorithm is invalid\n"
 msgstr "Das ausgewählte Hashverfahren ist ungültig\n"
 
-#: g10/gpg.c:3235
+#: g10/gpg.c:3236
 msgid "completes-needed must be greater than 0\n"
 msgstr "completes-needed müssen größer als 0 sein\n"
 
-#: g10/gpg.c:3237
+#: g10/gpg.c:3238
 msgid "marginals-needed must be greater than 1\n"
 msgstr "marginals-needed müssen größer als 1 sein\n"
 
-#: g10/gpg.c:3239
+#: g10/gpg.c:3240
 msgid "max-cert-depth must be in the range from 1 to 255\n"
 msgstr "max-cert-depth muß im Bereich 1 bis 255 liegen\n"
 
-#: g10/gpg.c:3241
+#: g10/gpg.c:3242
 msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n"
 msgstr "ungültiger \"default-cert-level\"; Wert muß 0, 1, 2 oder 3 sein\n"
 
-#: g10/gpg.c:3243
+#: g10/gpg.c:3244
 msgid "invalid min-cert-level; must be 1, 2, or 3\n"
 msgstr "ungültiger \"min-cert-level\"; Wert muß 0, 1, 2 oder 3 sein\n"
 
-#: g10/gpg.c:3246
+#: g10/gpg.c:3247
 msgid "NOTE: simple S2K mode (0) is strongly discouraged\n"
 msgstr "Hinweis: Vom \"simple S2K\"-Modus (0) ist strikt abzuraten\n"
 
-#: g10/gpg.c:3250
+#: g10/gpg.c:3251
 msgid "invalid S2K mode; must be 0, 1 or 3\n"
 msgstr "ungültiger \"simple S2K\"-Modus; Wert muß 0, 1 oder 3 sein\n"
 
-#: g10/gpg.c:3257
+#: g10/gpg.c:3258
 msgid "invalid default preferences\n"
 msgstr "ungültige Standard-Voreinstellungen\n"
 
-#: g10/gpg.c:3261
+#: g10/gpg.c:3262
 msgid "invalid personal cipher preferences\n"
 msgstr "ungültige private Verschlüsselungsvoreinstellungen\n"
 
-#: g10/gpg.c:3265
+#: g10/gpg.c:3266
 msgid "invalid personal digest preferences\n"
 msgstr "ungültige private Hashvoreinstellungen\n"
 
-#: g10/gpg.c:3269
+#: g10/gpg.c:3270
 msgid "invalid personal compress preferences\n"
 msgstr "ungültige private Komprimierungsvoreinstellungen\n"
 
-#: g10/gpg.c:3302
+#: g10/gpg.c:3303
 #, c-format
 msgid "%s does not yet work with %s\n"
 msgstr "%s arbeitet noch nicht mit %s zusammen\n"
 
-#: g10/gpg.c:3349
+#: g10/gpg.c:3350
 #, c-format
 msgid "you may not use cipher algorithm `%s' while in %s mode\n"
 msgstr ""
 "Die Benutzung des Verschlüsselungsverfahren %s ist im %s-Modus nicht "
 "erlaubt.\n"
 
-#: g10/gpg.c:3354
+#: g10/gpg.c:3355
 #, c-format
 msgid "you may not use digest algorithm `%s' while in %s mode\n"
 msgstr "Die Benutzung der Hashmethode %s ist im %s-Modus nicht erlaubt.\n"
 
-#: g10/gpg.c:3359
+#: g10/gpg.c:3360
 #, c-format
 msgid "you may not use compression algorithm `%s' while in %s mode\n"
 msgstr ""
 "Die Benutzung des Komprimierverfahren %s ist im %s-Modus nicht erlaubt.\n"
 
-#: g10/gpg.c:3438
+#: g10/gpg.c:3439
 #, c-format
 msgid "failed to initialize the TrustDB: %s\n"
 msgstr "Die Trust-DB kann nicht initialisiert werden: %s\n"
 
-#: g10/gpg.c:3449
+#: g10/gpg.c:3450
 msgid "WARNING: recipients (-r) given without using public key encryption\n"
 msgstr ""
 "WARNUNG: Empfänger (-r) angegeben ohne Verwendung von Public-Key-Verfahren\n"
 
-#: g10/gpg.c:3464
+#: g10/gpg.c:3465
 msgid "--store [filename]"
 msgstr "--store [Dateiname]"
 
-#: g10/gpg.c:3471
+#: g10/gpg.c:3472
 msgid "--symmetric [filename]"
 msgstr "--symmetric [Dateiname]"
 
-#: g10/gpg.c:3473
+#: g10/gpg.c:3474
 #, c-format
 msgid "symmetric encryption of `%s' failed: %s\n"
 msgstr "Symmetrische Entschlüsselung von `%s' fehlgeschlagen: %s\n"
 
-#: g10/gpg.c:3483
+#: g10/gpg.c:3484
 msgid "--encrypt [filename]"
 msgstr "--encrypt [Dateiname]"
 
-#: g10/gpg.c:3496
+#: g10/gpg.c:3497
 msgid "--symmetric --encrypt [filename]"
 msgstr "--symmetric --encrypt [Dateiname]"
 
-#: g10/gpg.c:3498
+#: g10/gpg.c:3499
 msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n"
 msgstr ""
 "--symmetric --encrypt kann nicht zusammen mit --s2k-mode 0 verwendet werden\n"
 
-#: g10/gpg.c:3501
+#: g10/gpg.c:3502
 #, c-format
 msgid "you cannot use --symmetric --encrypt while in %s mode\n"
 msgstr "Im %s-Modus kann --symmetric --encrypt nicht verwendet werden.\n"
 
-#: g10/gpg.c:3519
+#: g10/gpg.c:3520
 msgid "--sign [filename]"
 msgstr "--sign [Dateiname]"
 
-#: g10/gpg.c:3532
+#: g10/gpg.c:3533
 msgid "--sign --encrypt [filename]"
 msgstr "--sign --encrypt [Dateiname]"
 
-#: g10/gpg.c:3547
+#: g10/gpg.c:3548
 msgid "--symmetric --sign --encrypt [filename]"
 msgstr "--symmetric --sign --encrypt [Dateiname]"
 
-#: g10/gpg.c:3549
+#: g10/gpg.c:3550
 msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n"
 msgstr ""
 "--symmetric --sign --encrypt kann nicht zusammen mit --s2k-mode 0 verwendet "
 "werden\n"
 
-#: g10/gpg.c:3552
+#: g10/gpg.c:3553
 #, c-format
 msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n"
 msgstr ""
 "Im %s-Modus kann --symmetric --sign --encrypt nicht verwendet werden.\n"
 
-#: g10/gpg.c:3573
+#: g10/gpg.c:3574
 msgid "--sign --symmetric [filename]"
 msgstr "--sign --symmetric [Dateiname]"
 
-#: g10/gpg.c:3582
+#: g10/gpg.c:3583
 msgid "--clearsign [filename]"
 msgstr "--clearsign [Dateiname]"
 
-#: g10/gpg.c:3607
+#: g10/gpg.c:3608
 msgid "--decrypt [filename]"
 msgstr "--decrypt [Dateiname]"
 
-#: g10/gpg.c:3615
+#: g10/gpg.c:3616
 msgid "--sign-key user-id"
 msgstr "--sign-key User-ID"
 
-#: g10/gpg.c:3619
+#: g10/gpg.c:3620
 msgid "--lsign-key user-id"
 msgstr "--lsign-key User-ID"
 
-#: g10/gpg.c:3640
+#: g10/gpg.c:3641
 msgid "--edit-key user-id [commands]"
 msgstr "--edit-key User-ID [Befehle]"
 
-#: g10/gpg.c:3656
+#: g10/gpg.c:3657
 msgid "--passwd <user-id>"
 msgstr "--passwd User-ID"
 
-#: g10/gpg.c:3743
+#: g10/gpg.c:3744
 #, c-format
 msgid "keyserver send failed: %s\n"
 msgstr "Senden an Schlüsselserver fehlgeschlagen: %s\n"
 
-#: g10/gpg.c:3745
+#: g10/gpg.c:3746
 #, c-format
 msgid "keyserver receive failed: %s\n"
 msgstr "Empfangen vom Schlüsselserver fehlgeschlagen: %s\n"
 
-#: g10/gpg.c:3747
+#: g10/gpg.c:3748
 #, c-format
 msgid "key export failed: %s\n"
 msgstr "Schlüsselexport fehlgeschlagen: %s\n"
 
-#: g10/gpg.c:3758
+#: g10/gpg.c:3759
 #, c-format
 msgid "keyserver search failed: %s\n"
 msgstr "Suche auf dem Schlüsselserver fehlgeschlagen: %s\n"
 
-#: g10/gpg.c:3768
+#: g10/gpg.c:3769
 #, c-format
 msgid "keyserver refresh failed: %s\n"
 msgstr "Refresh vom Schlüsselserver fehlgeschlagen: %s\n"
 
-#: g10/gpg.c:3819
+#: g10/gpg.c:3820
 #, c-format
 msgid "dearmoring failed: %s\n"
 msgstr "Entfernen der ASCII-Hülle ist fehlgeschlagen: %s\n"
 
-#: g10/gpg.c:3827
+#: g10/gpg.c:3828
 #, c-format
 msgid "enarmoring failed: %s\n"
 msgstr "Anbringen der ASCII-Hülle ist fehlgeschlagen: %s\n"
 
-#: g10/gpg.c:3918
+#: g10/gpg.c:3919
 #, c-format
 msgid "invalid hash algorithm `%s'\n"
 msgstr "Ungültiges Hashverfahren '%s'\n"
 
-#: g10/gpg.c:4033
+#: g10/gpg.c:4034
 msgid "[filename]"
 msgstr "[Dateiname]"
 
-#: g10/gpg.c:4039
+#: g10/gpg.c:4040
 msgid "Go ahead and type your message ...\n"
 msgstr "Auf geht's - Botschaft eintippen ...\n"
 
-#: g10/gpg.c:4356
+#: g10/gpg.c:4357
 msgid "the given certification policy URL is invalid\n"
 msgstr "Die angegebene Zertifikat-Richtlinien-URL ist ungültig\n"
 
-#: g10/gpg.c:4358
+#: g10/gpg.c:4359
 msgid "the given signature policy URL is invalid\n"
 msgstr "Die angegebene Signatur-Richtlinien-URL ist ungültig\n"
 
-#: g10/gpg.c:4391
+#: g10/gpg.c:4392
 msgid "the given preferred keyserver URL is invalid\n"
 msgstr "Die angegebene URL des bevorzugten Schlüsselserver ist ungültig\n"
 
@@ -4058,7 +4048,7 @@ msgstr ""
 msgid "(sensitive)"
 msgstr "(empfindlich)"
 
-#: g10/keyedit.c:2775 g10/keyedit.c:2888 g10/keyserver.c:533
+#: g10/keyedit.c:2775 g10/keyedit.c:2888 g10/keyserver.c:552
 #, c-format
 msgid "created: %s"
 msgstr "erzeugt: %s"
@@ -4074,7 +4064,7 @@ msgid "expired: %s"
 msgstr "verfallen: %s"
 
 #: g10/keyedit.c:2782 g10/keyedit.c:2890 g10/keylist.c:822 g10/keylist.c:945
-#: g10/keyserver.c:539 g10/mainproc.c:1014
+#: g10/keyserver.c:558 g10/mainproc.c:1014
 #, c-format
 msgid "expires: %s"
 msgstr "verfällt: %s"
@@ -4110,13 +4100,13 @@ msgstr ""
 "Bitte beachten Sie, daß ohne einen Programmneustart die angezeigte\n"
 "Schlüsselgültigkeit nicht notwendigerweise korrekt ist.\n"
 
-#: g10/keyedit.c:2907 g10/keyedit.c:3219 g10/keyserver.c:543
+#: g10/keyedit.c:2907 g10/keyedit.c:3219 g10/keyserver.c:562
 #: g10/mainproc.c:1874 g10/trustdb.c:1202 g10/trustdb.c:1731
 #: dirmngr/ocsp.c:699
 msgid "revoked"
 msgstr "widerrufen"
 
-#: g10/keyedit.c:2909 g10/keyedit.c:3221 g10/keyserver.c:547
+#: g10/keyedit.c:2909 g10/keyedit.c:3221 g10/keyserver.c:566
 #: g10/mainproc.c:1876 g10/trustdb.c:549 g10/trustdb.c:1733
 msgid "expired"
 msgstr "verfallen"
@@ -4985,184 +4975,179 @@ msgstr "%lu Schlüssel gepuffert (%lu Beglaubigungen)\n"
 msgid "%s: keyring created\n"
 msgstr "%s: Schlüsselbund erstellt\n"
 
-#: g10/keyserver.c:75
+#: g10/keyserver.c:94
 msgid "include revoked keys in search results"
 msgstr "Widerrufene Schlüssel in den Suchergebnissen aufführen"
 
-#: g10/keyserver.c:76
+#: g10/keyserver.c:95
 msgid "include subkeys when searching by key ID"
 msgstr "Unterschlüssel in der Suche über Schlüssel-IDs aufführen"
 
-#: g10/keyserver.c:78
+#: g10/keyserver.c:97
 msgid "use temporary files to pass data to keyserver helpers"
 msgstr ""
 "verwende temporäre Dateien, um Daten an die Schlüsselserverhilfsprogramme zu "
 "geben"
 
-#: g10/keyserver.c:80
+#: g10/keyserver.c:99
 msgid "do not delete temporary files after using them"
 msgstr "Temporäre Dateien nach Nutzung nicht löschen"
 
-#: g10/keyserver.c:84
+#: g10/keyserver.c:103
 msgid "automatically retrieve keys when verifying signatures"
 msgstr "Schlüssel für die Signaturprüfung automatisch holen"
 
-#: g10/keyserver.c:86
+#: g10/keyserver.c:105
 msgid "honor the preferred keyserver URL set on the key"
 msgstr ""
 "Die im Schlüssel enthaltene bevorzugte URL für Schlüsselserver beachten"
 
-#: g10/keyserver.c:88
+#: g10/keyserver.c:107
 msgid "honor the PKA record set on a key when retrieving keys"
 msgstr "Die im Schlüssel enthaltenen PKA-Daten beim Schlüsselholen beachten"
 
-#: g10/keyserver.c:154
+#: g10/keyserver.c:173
 #, c-format
 msgid "WARNING: keyserver option `%s' is not used on this platform\n"
 msgstr ""
 "WARNUNG: Schlüsselserver-Option `%s' wird auf dieser Plattform nicht "
 "verwendet\n"
 
-#: g10/keyserver.c:545
+#: g10/keyserver.c:564
 msgid "disabled"
 msgstr "abgeschaltet"
 
-#: g10/keyserver.c:750
+#: g10/keyserver.c:764
 msgid "Enter number(s), N)ext, or Q)uit > "
 msgstr "Eingabe von Nummern, Nächste (N) oder Abbrechen (Q) > "
 
-#: g10/keyserver.c:834 g10/keyserver.c:1462
+#: g10/keyserver.c:834 g10/keyserver.c:1471
 #, c-format
 msgid "invalid keyserver protocol (us %d!=handler %d)\n"
 msgstr "Ungültiges Schlüsselserverprotokoll (wir %d!=Handhabungsroutine %d)\n"
 
-#: g10/keyserver.c:935
-#, c-format
-msgid "key \"%s\" not found on keyserver\n"
-msgstr "Schlüssel \"%s\" wurde auf dem Schlüsselserver nicht gefunden\n"
-
-#: g10/keyserver.c:937
-msgid "key not found on keyserver\n"
-msgstr "Schlüssel wurde auf dem Schlüsselserver nicht gefunden\n"
-
-#: g10/keyserver.c:1181
+#: g10/keyserver.c:1190
 #, c-format
 msgid "requesting key %s from %s server %s\n"
 msgstr "fordere Schlüssel %s von %s-Server %s an\n"
 
-#: g10/keyserver.c:1185
+#: g10/keyserver.c:1194
 #, c-format
 msgid "requesting key %s from %s\n"
 msgstr "fordere Schlüssel %s von %s an\n"
 
-#: g10/keyserver.c:1209
+#: g10/keyserver.c:1218
 #, c-format
 msgid "searching for names from %s server %s\n"
 msgstr "suche Namen auf %s-Server %s\n"
 
-#: g10/keyserver.c:1212
+#: g10/keyserver.c:1221
 #, c-format
 msgid "searching for names from %s\n"
 msgstr "suche Namen auf %s\n"
 
-#: g10/keyserver.c:1365
+#: g10/keyserver.c:1374
 #, c-format
 msgid "sending key %s to %s server %s\n"
 msgstr "sende Schlüssel %s auf den %s-Server %s\n"
 
-#: g10/keyserver.c:1369
+#: g10/keyserver.c:1378
 #, c-format
 msgid "sending key %s to %s\n"
 msgstr "sende Schlüssel %s auf %s\n"
 
-#: g10/keyserver.c:1412
+#: g10/keyserver.c:1421
 #, c-format
 msgid "searching for \"%s\" from %s server %s\n"
 msgstr "suche nach \"%s\" auf %s-Server %s\n"
 
-#: g10/keyserver.c:1415
+#: g10/keyserver.c:1424
 #, c-format
 msgid "searching for \"%s\" from %s\n"
 msgstr "suche nach \"%s\" auf %s\n"
 
-#: g10/keyserver.c:1422 g10/keyserver.c:1519
+#: g10/keyserver.c:1431 g10/keyserver.c:1528
 msgid "no keyserver action!\n"
 msgstr "Kein Schlüsselserver-Vorgang\n"
 
-#: g10/keyserver.c:1470
+#: g10/keyserver.c:1479
 #, c-format
 msgid "WARNING: keyserver handler from a different version of GnuPG (%s)\n"
 msgstr ""
 "WARNUNG: Die Schlüsselserver-Handhabungsroutine stammt von einer anderen "
 "GnuPG-Version (%s)\n"
 
-#: g10/keyserver.c:1479
+#: g10/keyserver.c:1488
 msgid "keyserver did not send VERSION\n"
 msgstr "Schlüsselserver sendete VERSION nicht\n"
 
-#: g10/keyserver.c:1543 g10/keyserver.c:2082
+#: g10/keyserver.c:1553 g10/keyserver.c:1983 g10/keyserver.c:2180
 msgid "no keyserver known (use option --keyserver)\n"
 msgstr "Kein Schlüsselserver bekannt (Option --keyserver verwenden)\n"
 
-#: g10/keyserver.c:1549
-msgid "external keyserver calls are not supported in this build\n"
-msgstr ""
-"Externe Schlüsselserveraufrufe werden in diesem \"Build\" nicht unterstützt\n"
-
-#: g10/keyserver.c:1562
+#: g10/keyserver.c:1565
 #, c-format
 msgid "no handler for keyserver scheme `%s'\n"
 msgstr "Keine Handhabungsroutine für Schlüsselserverschema `%s'\n"
 
-#: g10/keyserver.c:1567
+#: g10/keyserver.c:1570
 #, c-format
 msgid "action `%s' not supported with keyserver scheme `%s'\n"
 msgstr "Vorgang `%s' wird vom Schlüsselserverschema `%s' nicht unterstützt\n"
 
-#: g10/keyserver.c:1575
+#: g10/keyserver.c:1578
 #, c-format
 msgid "%s does not support handler version %d\n"
 msgstr "%s unterstützt Hilfsroutinenversion %d nicht\n"
 
-#: g10/keyserver.c:1582
+#: g10/keyserver.c:1585
 msgid "keyserver timed out\n"
 msgstr "Schlüsselserver-Zeitüberschreitung\n"
 
-#: g10/keyserver.c:1587
+#: g10/keyserver.c:1590
 msgid "keyserver internal error\n"
 msgstr "interner Fehler Schlüsselserver\n"
 
-#: g10/keyserver.c:1596
+#: g10/keyserver.c:1599
 #, c-format
 msgid "keyserver communications error: %s\n"
 msgstr "Schlüsselserver-Datenübertragunsfehler: %s\n"
 
-#: g10/keyserver.c:1622 g10/keyserver.c:1657
+#: g10/keyserver.c:1624 g10/keyserver.c:1659
 #, c-format
 msgid "\"%s\" not a key ID: skipping\n"
 msgstr "\"%s\" ist keine Schlüssel-ID: überspringe\n"
 
-#: g10/keyserver.c:1920
+#: g10/keyserver.c:1922
 #, c-format
 msgid "WARNING: unable to refresh key %s via %s: %s\n"
 msgstr "WARNUNG: Schlüssel %s kann per %s nicht aktualisiert werden: %s\n"
 
-#: g10/keyserver.c:1942
+#: g10/keyserver.c:1944
 #, c-format
 msgid "refreshing 1 key from %s\n"
 msgstr "ein Schlüssel wird per %s aktualisiert\n"
 
-#: g10/keyserver.c:1944
+#: g10/keyserver.c:1946
 #, c-format
 msgid "refreshing %d keys from %s\n"
 msgstr "%d Schlüssel werden per %s aktualisiert\n"
 
-#: g10/keyserver.c:2001
+#: g10/keyserver.c:2028
+#, c-format
+msgid "key \"%s\" not found on keyserver\n"
+msgstr "Schlüssel \"%s\" wurde auf dem Schlüsselserver nicht gefunden\n"
+
+#: g10/keyserver.c:2031
+msgid "key not found on keyserver\n"
+msgstr "Schlüssel wurde auf dem Schlüsselserver nicht gefunden\n"
+
+#: g10/keyserver.c:2099
 #, c-format
 msgid "WARNING: unable to fetch URI %s: %s\n"
 msgstr "WARNUNG: die URI %s kann nicht geholt werden: %s\n"
 
-#: g10/keyserver.c:2007
+#: g10/keyserver.c:2105
 #, c-format
 msgid "WARNING: unable to parse URI %s\n"
 msgstr "WARNUNG: die URI %s kann nicht analysiert werden\n"
@@ -6346,131 +6331,131 @@ msgstr "Lesefehler in `%s': %s\n"
 msgid "trustdb: sync failed: %s\n"
 msgstr "\"Trust-DB\": sync fehlgeschlagen: %s\n"
 
-#: g10/tdbio.c:128 g10/tdbio.c:1450
+#: g10/tdbio.c:135 g10/tdbio.c:1482
 #, c-format
 msgid "trustdb rec %lu: lseek failed: %s\n"
 msgstr "trustdb Satz %lu: lseek fehlgeschlagen: %s\n"
 
-#: g10/tdbio.c:135 g10/tdbio.c:1457
+#: g10/tdbio.c:142 g10/tdbio.c:1489
 #, c-format
 msgid "trustdb rec %lu: write failed (n=%d): %s\n"
 msgstr "trustdb Satz %lu: write fehlgeschlagen (n=%d): %s\n"
 
-#: g10/tdbio.c:245
+#: g10/tdbio.c:252
 msgid "trustdb transaction too large\n"
 msgstr "trustdb Transaktion zu groß\n"
 
-#: g10/tdbio.c:498
+#: g10/tdbio.c:512
 #, c-format
 msgid "can't access `%s': %s\n"
 msgstr "kann aus `%s' nicht zugreifen: %s\n"
 
-#: g10/tdbio.c:525
+#: g10/tdbio.c:539
 #, c-format
 msgid "%s: directory does not exist!\n"
 msgstr "%s: Verzeichnis existiert nicht!\n"
 
-#: g10/tdbio.c:535 g10/tdbio.c:558 g10/tdbio.c:599 sm/keydb.c:221
+#: g10/tdbio.c:549 g10/tdbio.c:572 g10/tdbio.c:613 sm/keydb.c:221
 #, c-format
 msgid "can't create lock for `%s'\n"
 msgstr "Datei `%s' konnte nicht gesperrt werden\n"
 
-#: g10/tdbio.c:537 g10/tdbio.c:602
+#: g10/tdbio.c:551 g10/tdbio.c:616
 #, c-format
 msgid "can't lock `%s'\n"
 msgstr "'%s' kann nicht gesperrt werden\n"
 
-#: g10/tdbio.c:563
+#: g10/tdbio.c:577
 #, c-format
 msgid "%s: failed to create version record: %s"
 msgstr "%s: Fehler beim Erzeugen des Versionsatzes: %s"
 
-#: g10/tdbio.c:567
+#: g10/tdbio.c:581
 #, c-format
 msgid "%s: invalid trustdb created\n"
 msgstr "%s: ungültige trust-db erzeugt\n"
 
-#: g10/tdbio.c:570
+#: g10/tdbio.c:584
 #, c-format
 msgid "%s: trustdb created\n"
 msgstr "%s: trust-db erzeugt\n"
 
-#: g10/tdbio.c:613
+#: g10/tdbio.c:644
 msgid "NOTE: trustdb not writable\n"
 msgstr "Notiz: Die \"trustdb\" ist nicht schreibbar\n"
 
-#: g10/tdbio.c:621
+#: g10/tdbio.c:653
 #, c-format
 msgid "%s: invalid trustdb\n"
 msgstr "%s: ungültige 'Trust'-Datenbank\n"
 
-#: g10/tdbio.c:653
+#: g10/tdbio.c:685
 #, c-format
 msgid "%s: failed to create hashtable: %s\n"
 msgstr "%s: hashtable kann nicht erzeugt werden: %s\n"
 
-#: g10/tdbio.c:661
+#: g10/tdbio.c:693
 #, c-format
 msgid "%s: error updating version record: %s\n"
 msgstr "%s: Fehler beim Ändern des Versionsatzes: %s\n"
 
-#: g10/tdbio.c:678 g10/tdbio.c:698 g10/tdbio.c:714 g10/tdbio.c:728
-#: g10/tdbio.c:758 g10/tdbio.c:1382 g10/tdbio.c:1409
+#: g10/tdbio.c:710 g10/tdbio.c:730 g10/tdbio.c:746 g10/tdbio.c:760
+#: g10/tdbio.c:790 g10/tdbio.c:1414 g10/tdbio.c:1441
 #, c-format
 msgid "%s: error reading version record: %s\n"
 msgstr "%s: Fehler beim Lesen des Versionsatzes: %s\n"
 
-#: g10/tdbio.c:737
+#: g10/tdbio.c:769
 #, c-format
 msgid "%s: error writing version record: %s\n"
 msgstr "%s: Fehler beim Schreiben des Versionsatzes: %s\n"
 
-#: g10/tdbio.c:1177
+#: g10/tdbio.c:1209
 #, c-format
 msgid "trustdb: lseek failed: %s\n"
 msgstr "trustdb: lseek fehlgeschlagen: %s\n"
 
-#: g10/tdbio.c:1186
+#: g10/tdbio.c:1218
 #, c-format
 msgid "trustdb: read failed (n=%d): %s\n"
 msgstr "trustdb: read failed (n=%d): %s\n"
 
-#: g10/tdbio.c:1207
+#: g10/tdbio.c:1239
 #, c-format
 msgid "%s: not a trustdb file\n"
 msgstr "%s: keine trustdb Datei\n"
 
-#: g10/tdbio.c:1225
+#: g10/tdbio.c:1257
 #, c-format
 msgid "%s: version record with recnum %lu\n"
 msgstr "%s: version record with recnum %lu\n"
 
-#: g10/tdbio.c:1230
+#: g10/tdbio.c:1262
 #, c-format
 msgid "%s: invalid file version %d\n"
 msgstr "%s: invalid file version %d\n"
 
-#: g10/tdbio.c:1415
+#: g10/tdbio.c:1447
 #, c-format
 msgid "%s: error reading free record: %s\n"
 msgstr "%s: Fehler beim Lesen eines freien Satzes: %s\n"
 
-#: g10/tdbio.c:1423
+#: g10/tdbio.c:1455
 #, c-format
 msgid "%s: error writing dir record: %s\n"
 msgstr "%s: Fehler beim Schreiben eines Verzeichnis-Satzes: %s\n"
 
-#: g10/tdbio.c:1433
+#: g10/tdbio.c:1465
 #, c-format
 msgid "%s: failed to zero a record: %s\n"
 msgstr "%s: konnte einen Satz nicht Nullen: %s\n"
 
-#: g10/tdbio.c:1463
+#: g10/tdbio.c:1495
 #, c-format
 msgid "%s: failed to append a record: %s\n"
 msgstr "%s: konnte Satz nicht anhängen: %s\n"
 
-#: g10/tdbio.c:1506
+#: g10/tdbio.c:1538
 msgid "Error: The trustdb is corrupted.\n"
 msgstr "Fehler: Die Vertrauensdatenbank ist fehlerhaft\n"
 
@@ -6984,7 +6969,7 @@ msgstr "Im Multiserver Modus ausführen"
 msgid "|LEVEL|set the debugging level to LEVEL"
 msgstr "|NAME|Die Debugstufe auf NAME setzen"
 
-#: scd/scdaemon.c:125 tools/gpgconf-comp.c:626
+#: scd/scdaemon.c:125 tools/gpgconf-comp.c:632
 msgid "|FILE|write a log to FILE"
 msgstr "|DATEI|Schreibe Logs auf DATEI"
 
@@ -7034,12 +7019,12 @@ msgstr ""
 "Bitte die Option `--daemon' nutzen, um das Programm im Hintergund "
 "auszuführen\n"
 
-#: scd/scdaemon.c:1137 dirmngr/dirmngr.c:1710
+#: scd/scdaemon.c:1137 dirmngr/dirmngr.c:1718
 #, c-format
 msgid "handler for fd %d started\n"
 msgstr "Handhabungsroutine für fd %d gestartet\n"
 
-#: scd/scdaemon.c:1149 dirmngr/dirmngr.c:1715
+#: scd/scdaemon.c:1149 dirmngr/dirmngr.c:1723
 #, c-format
 msgid "handler for fd %d terminated\n"
 msgstr "Handhabungsroutine für den fd %d beendet\n"
@@ -7692,7 +7677,7 @@ msgstr "|DATEI|DATEI als öffentlichen Schlüsselbund mitbenutzen"
 msgid "|USER-ID|use USER-ID as default secret key"
 msgstr "|USER-ID|USER-ID als voreingestellten Schlüssel benutzen"
 
-#: sm/gpgsm.c:311 tools/gpgconf-comp.c:758
+#: sm/gpgsm.c:311 tools/gpgconf-comp.c:770
 msgid "|SPEC|use this keyserver to lookup keys"
 msgstr "|SPEC|Schlüssel bei diesem Server nachschlagen"
 
@@ -8097,7 +8082,7 @@ msgstr "Die Zwischenspeicherdatei `%s' wird entfernt\n"
 msgid "not removing file `%s'\n"
 msgstr "Die Datei `%s' wird nicht gelöscht\n"
 
-#: dirmngr/crlcache.c:374 dirmngr/crlcache.c:1112
+#: dirmngr/crlcache.c:374 dirmngr/crlcache.c:1112 dirmngr/crlcache.c:2197
 #, c-format
 msgid "error closing cache file: %s\n"
 msgstr "Fehler beim Schließen der Zwischenspeicherdatei: %s\n"
@@ -8479,12 +8464,12 @@ msgstr "Fehler beim Lesen einer CRL Erweiterung: %s\n"
 msgid "creating cache file `%s'\n"
 msgstr "Zwischenspeicherdatei `%s' wird erzeugt\n"
 
-#: dirmngr/crlcache.c:2186
+#: dirmngr/crlcache.c:2211
 #, c-format
 msgid "problem renaming `%s' to `%s': %s\n"
 msgstr "Problem beim Umbenennen von `%s' nach `%s': %s\n"
 
-#: dirmngr/crlcache.c:2200
+#: dirmngr/crlcache.c:2225
 msgid ""
 "updating the DIR file failed - cache entry will get lost with the next "
 "program start\n"
@@ -8492,69 +8477,69 @@ msgstr ""
 "Update der Zwischenspeicherverzeichnisdatei fehlgeschlagen - "
 "Zwischenspeichereintrag wird mit dem nächste Programmstart verloren gehen\n"
 
-#: dirmngr/crlcache.c:2237
+#: dirmngr/crlcache.c:2262
 #, c-format
 msgid "Begin CRL dump (retrieved via %s)\n"
 msgstr "Anfang CRL Ausgabe (geholt via %s)\n"
 
-#: dirmngr/crlcache.c:2260
+#: dirmngr/crlcache.c:2285
 msgid ""
 " ERROR: The CRL will not be used because it was still too old after an "
 "update!\n"
 msgstr ""
 " FEHLER: Die CRL wird nicht benutzt, da sie trotz eines Updates zu alt war!\n"
 
-#: dirmngr/crlcache.c:2263
+#: dirmngr/crlcache.c:2288
 msgid ""
 " ERROR: The CRL will not be used due to an unknown critical extension!\n"
 msgstr ""
 " FEHLER: Die CRL wird nicht benutzt, da sie eine unbekannte kritische CRL "
 "Erweiterung trägt!\n"
 
-#: dirmngr/crlcache.c:2266
+#: dirmngr/crlcache.c:2291
 msgid " ERROR: The CRL will not be used\n"
 msgstr " FEHLER: Die CRL wird nicht benutzt\n"
 
-#: dirmngr/crlcache.c:2273
+#: dirmngr/crlcache.c:2298
 msgid " ERROR: This cached CRL may has been tampered with!\n"
 msgstr ""
 " FEHLER: Diese zwischengespeicherte CRL ist möglicherweise abgeändert "
 "worden!\n"
 
-#: dirmngr/crlcache.c:2291
+#: dirmngr/crlcache.c:2316
 msgid " WARNING: invalid cache record length\n"
 msgstr " WARNUNG: Ungültige Länge eines Zwischenspeicherdatensatzes\n"
 
-#: dirmngr/crlcache.c:2298
+#: dirmngr/crlcache.c:2323
 #, c-format
 msgid "problem reading cache record: %s\n"
 msgstr "Problem beim Lesen eines Zwischenspeicherdatensatzes: %s\n"
 
-#: dirmngr/crlcache.c:2309
+#: dirmngr/crlcache.c:2334
 #, c-format
 msgid "problem reading cache key: %s\n"
 msgstr "Problem beim Lesen eines Zwischenspeicherschlüssels: %s\n"
 
-#: dirmngr/crlcache.c:2340
+#: dirmngr/crlcache.c:2365
 #, c-format
 msgid "error reading cache entry from db: %s\n"
 msgstr "Fehler beim Lesen eine Zwischenspeichereintrags aus der DB: %s\n"
 
-#: dirmngr/crlcache.c:2343
+#: dirmngr/crlcache.c:2368
 msgid "End CRL dump\n"
 msgstr "Ende CRL Ausgabe\n"
 
-#: dirmngr/crlcache.c:2464
+#: dirmngr/crlcache.c:2489
 #, c-format
 msgid "crl_fetch via DP failed: %s\n"
 msgstr "crl_fetch über den DP fehlgeschlagen: %s\n"
 
-#: dirmngr/crlcache.c:2475
+#: dirmngr/crlcache.c:2500
 #, c-format
 msgid "crl_cache_insert via DP failed: %s\n"
 msgstr "crl_cache_insert über den DP fehlgeschlagen: %s\n"
 
-#: dirmngr/crlcache.c:2535
+#: dirmngr/crlcache.c:2560
 #, c-format
 msgid "crl_cache_insert via issuer failed: %s\n"
 msgstr "crl_cache_insert über den Issuer fehlgeschlagen: %s\n"
@@ -8721,7 +8706,7 @@ msgstr "Erhielt Status: `%s'\n"
 msgid "error writing base64 encoding: %s\n"
 msgstr "Fehler beim Schreiben der Base-64 Darstellung: %s\n"
 
-#: dirmngr/dirmngr-client.c:453 dirmngr/server.c:1529
+#: dirmngr/dirmngr-client.c:453 dirmngr/server.c:1672
 #, c-format
 msgid "failed to allocate assuan context: %s\n"
 msgstr "Fehler beim Bereitstellen eines Assuan Kontext: %s\n"
@@ -8790,8 +8775,8 @@ msgstr "Den Dirmngr herunterfahren"
 msgid "flush the cache"
 msgstr "Den Zwischenspeicher löschen"
 
-#: dirmngr/dirmngr.c:158 tools/gpgconf-comp.c:507 tools/gpgconf-comp.c:689
-#: tools/gpgconf-comp.c:772 tools/gpgconf-comp.c:854
+#: dirmngr/dirmngr.c:158 tools/gpgconf-comp.c:509 tools/gpgconf-comp.c:698
+#: tools/gpgconf-comp.c:784 tools/gpgconf-comp.c:870
 msgid "|FILE|write server mode logs to FILE"
 msgstr "|DATEI|Schreibe im Servermodus Logs auf DATEI"
 
@@ -8873,11 +8858,11 @@ msgstr ""
 "(Im \"info\"-Handbuch findet sich eine vollständige Liste aller Kommandos "
 "und Optionen)\n"
 
-#: dirmngr/dirmngr.c:301
+#: dirmngr/dirmngr.c:305
 msgid "Usage: dirmngr [options] (-h for help)"
 msgstr "Gebrauch: dirmnr [Optionen] [Kommando [Argumente]]"
 
-#: dirmngr/dirmngr.c:303
+#: dirmngr/dirmngr.c:307
 msgid ""
 "Syntax: dirmngr [options] [command [args]]\n"
 "LDAP and OCSP access for GnuPG\n"
@@ -8885,87 +8870,87 @@ msgstr ""
 "Syntax: dirmngr [Optionen] [Kommando [Argumente]]\n"
 "LDAP und OCSP Zugriff für GnuPG\n"
 
-#: dirmngr/dirmngr.c:368
+#: dirmngr/dirmngr.c:372
 #, c-format
 msgid "valid debug levels are: %s\n"
 msgstr "Gültige Debugebenen sind: %s\n"
 
-#: dirmngr/dirmngr.c:391
+#: dirmngr/dirmngr.c:395
 msgid "usage: dirmngr [options] "
 msgstr "Gebrauch: dirmngr [Optionen] "
 
-#: dirmngr/dirmngr.c:950
+#: dirmngr/dirmngr.c:958
 msgid "colons are not allowed in the socket name\n"
 msgstr "Doppelpunkte sind im Namen des Sockets nicht erlaubt\n"
 
-#: dirmngr/dirmngr.c:1156 dirmngr/server.c:1163
+#: dirmngr/dirmngr.c:1164 dirmngr/server.c:1179
 #, c-format
 msgid "fetching CRL from `%s' failed: %s\n"
 msgstr "Holen der CRL von `%s' fehlgeschlagen: %s\n"
 
-#: dirmngr/dirmngr.c:1162 dirmngr/server.c:1169
+#: dirmngr/dirmngr.c:1170 dirmngr/server.c:1185
 #, c-format
 msgid "processing CRL from `%s' failed: %s\n"
 msgstr "Verarbeitung der CRL von `%s' fehlgeschlagen: %s\n"
 
-#: dirmngr/dirmngr.c:1381
+#: dirmngr/dirmngr.c:1389
 #, c-format
 msgid "%s:%u: line too long - skipped\n"
 msgstr "%s:%u: Zeile ist zu lang - übergangen\n"
 
-#: dirmngr/dirmngr.c:1436 dirmngr/dirmngr.c:1520
+#: dirmngr/dirmngr.c:1444 dirmngr/dirmngr.c:1528
 #, c-format
 msgid "%s:%u: invalid fingerprint detected\n"
 msgstr "%s:%u: ungültiger Fingerabdruck erkannt\n"
 
-#: dirmngr/dirmngr.c:1472 dirmngr/dirmngr.c:1498
+#: dirmngr/dirmngr.c:1480 dirmngr/dirmngr.c:1506
 #, c-format
 msgid "%s:%u: read error: %s\n"
 msgstr "%s:%u: Lesefehler: %s\n"
 
-#: dirmngr/dirmngr.c:1527
+#: dirmngr/dirmngr.c:1535
 #, c-format
 msgid "%s:%u: garbage at end of line ignored\n"
 msgstr "%s:%u: Müll am Ende der Zeile wird ignoriert\n"
 
-#: dirmngr/dirmngr.c:1593
+#: dirmngr/dirmngr.c:1601
 msgid "SIGHUP received - re-reading configuration and flushing caches\n"
 msgstr ""
 "SIGHUP empfangen - lese die Konfiguration erneut und lösche die "
 "Zwischenspeicher\n"
 
-#: dirmngr/dirmngr.c:1620
+#: dirmngr/dirmngr.c:1628
 msgid "SIGUSR2 received - no action defined\n"
 msgstr "SIGUSR2 empfangen - keine Aktion definiert\n"
 
-#: dirmngr/dirmngr.c:1625 dirmngr/dirmngr.c:1662
+#: dirmngr/dirmngr.c:1633 dirmngr/dirmngr.c:1670
 msgid "SIGTERM received - shutting down ...\n"
 msgstr "SIGTERM empfangen - wird heruntergefahren ...\n"
 
-#: dirmngr/dirmngr.c:1627
+#: dirmngr/dirmngr.c:1635
 #, c-format
 msgid "SIGTERM received - still %d active connections\n"
 msgstr "SIGTERM empfangen - immer noch %d Verbindungen aktiv\n"
 
-#: dirmngr/dirmngr.c:1632 dirmngr/dirmngr.c:1665
+#: dirmngr/dirmngr.c:1640 dirmngr/dirmngr.c:1673
 msgid "shutdown forced\n"
 msgstr "Herunterfahren wurde erzwungen\n"
 
-#: dirmngr/dirmngr.c:1640
+#: dirmngr/dirmngr.c:1648
 msgid "SIGINT received - immediate shutdown\n"
 msgstr "SIGINT empfangen - wird sofort heruntergefahren\n"
 
-#: dirmngr/dirmngr.c:1647
+#: dirmngr/dirmngr.c:1655
 #, c-format
 msgid "signal %d received - no action defined\n"
 msgstr "Signal %d empfangen - keine Aktion definiert\n"
 
-#: dirmngr/dirmngr.c:1799
+#: dirmngr/dirmngr.c:1807
 #, c-format
 msgid "accept failed: %s - waiting 1s\n"
 msgstr "accept() fehlgeschlagen: %s - warte 1s\n"
 
-#: dirmngr/dirmngr.c:1829
+#: dirmngr/dirmngr.c:1837
 #, c-format
 msgid "error spawning connection handler: %s\n"
 msgstr "Fehler beim Starten des Verbindungshandler: %s\n"
@@ -9392,71 +9377,71 @@ msgstr "OCSP Responder gab einen nicht aktuellen Status zurück\n"
 msgid "OCSP responder returned an too old status\n"
 msgstr "OCSP Responder gab einen zu alten Status zurück\n"
 
-#: dirmngr/server.c:269 dirmngr/server.c:381 dirmngr/server.c:427
+#: dirmngr/server.c:285 dirmngr/server.c:397 dirmngr/server.c:443
 #, c-format
 msgid "assuan_inquire(%s) failed: %s\n"
 msgstr "assuan_inquire(%s) fehlgeschlagen: %s\n"
 
-#: dirmngr/server.c:524
+#: dirmngr/server.c:540
 msgid "ldapserver missing"
 msgstr "LDAP Server fehlt"
 
-#: dirmngr/server.c:594
+#: dirmngr/server.c:610
 msgid "serialno missing in cert ID"
 msgstr "Seriennummer fehlt in der Cert-ID"
 
-#: dirmngr/server.c:730 dirmngr/server.c:816 dirmngr/server.c:1248
-#: dirmngr/server.c:1299
+#: dirmngr/server.c:746 dirmngr/server.c:832 dirmngr/server.c:1264
+#: dirmngr/server.c:1315
 #, c-format
 msgid "assuan_inquire failed: %s\n"
 msgstr "assuan_inquire fehlgeschlagen: %s\n"
 
-#: dirmngr/server.c:859
+#: dirmngr/server.c:875
 #, c-format
 msgid "fetch_cert_by_url failed: %s\n"
 msgstr "fetch_cert_by_url() fehlgeschlagen: %s\n"
 
-#: dirmngr/server.c:871 dirmngr/server.c:902 dirmngr/server.c:1058
+#: dirmngr/server.c:887 dirmngr/server.c:918 dirmngr/server.c:1074
 #, c-format
 msgid "error sending data: %s\n"
 msgstr "Fehler beim Senden der Daten: %s\n"
 
-#: dirmngr/server.c:1006
+#: dirmngr/server.c:1022
 #, c-format
 msgid "start_cert_fetch failed: %s\n"
 msgstr "start_cert_fetch fehlgeschlagen: %s\n"
 
-#: dirmngr/server.c:1039
+#: dirmngr/server.c:1055
 #, c-format
 msgid "fetch_next_cert failed: %s\n"
 msgstr "fetch_next_cert fehlgeschlagen: %s\n"
 
-#: dirmngr/server.c:1066
+#: dirmngr/server.c:1082
 #, c-format
 msgid "max_replies %d exceeded\n"
 msgstr "max_replies %d überschritten\n"
 
-#: dirmngr/server.c:1518
+#: dirmngr/server.c:1661
 #, c-format
 msgid "can't allocate control structure: %s\n"
 msgstr "Fehler beim Erzeugen der Kontrollstruktur: %s\n"
 
-#: dirmngr/server.c:1550
+#: dirmngr/server.c:1693
 #, c-format
 msgid "failed to initialize the server: %s\n"
 msgstr "Fehler beim Initialisieren des Servers: %s\n"
 
-#: dirmngr/server.c:1558
+#: dirmngr/server.c:1701
 #, c-format
 msgid "failed to the register commands with Assuan: %s\n"
 msgstr "Fehler beim Registrieren der Kommandos gegen Assuan: %s\n"
 
-#: dirmngr/server.c:1598
+#: dirmngr/server.c:1741
 #, c-format
 msgid "Assuan accept problem: %s\n"
 msgstr "Assuan accept Problem: %s\n"
 
-#: dirmngr/server.c:1617
+#: dirmngr/server.c:1760
 #, c-format
 msgid "Assuan processing failed: %s\n"
 msgstr "Assuan Verarbeitung fehlgeschlagen: %s\n"
@@ -9592,141 +9577,141 @@ msgstr "Senden der Zeile schlug fehl: %s\n"
 msgid "error sending standard options: %s\n"
 msgstr "Fehler beim Senden der Standardoptionen: %s\n"
 
-#: tools/gpgconf-comp.c:479 tools/gpgconf-comp.c:583 tools/gpgconf-comp.c:650
-#: tools/gpgconf-comp.c:725 tools/gpgconf-comp.c:816
+#: tools/gpgconf-comp.c:481 tools/gpgconf-comp.c:589 tools/gpgconf-comp.c:659
+#: tools/gpgconf-comp.c:737 tools/gpgconf-comp.c:832
 msgid "Options controlling the diagnostic output"
 msgstr "Optionen zur Einstellung der Diagnoseausgaben"
 
-#: tools/gpgconf-comp.c:492 tools/gpgconf-comp.c:596 tools/gpgconf-comp.c:663
-#: tools/gpgconf-comp.c:738 tools/gpgconf-comp.c:839
+#: tools/gpgconf-comp.c:494 tools/gpgconf-comp.c:602 tools/gpgconf-comp.c:672
+#: tools/gpgconf-comp.c:750 tools/gpgconf-comp.c:855
 msgid "Options controlling the configuration"
 msgstr "Optionen zur Einstellung der Konfiguration"
 
-#: tools/gpgconf-comp.c:502 tools/gpgconf-comp.c:621 tools/gpgconf-comp.c:684
-#: tools/gpgconf-comp.c:767 tools/gpgconf-comp.c:846
+#: tools/gpgconf-comp.c:504 tools/gpgconf-comp.c:627 tools/gpgconf-comp.c:693
+#: tools/gpgconf-comp.c:779 tools/gpgconf-comp.c:862
 msgid "Options useful for debugging"
 msgstr "Nützliche Optionen zur Fehlersuche"
 
-#: tools/gpgconf-comp.c:515 tools/gpgconf-comp.c:631 tools/gpgconf-comp.c:780
+#: tools/gpgconf-comp.c:517 tools/gpgconf-comp.c:637 tools/gpgconf-comp.c:792
 msgid "Options controlling the security"
 msgstr "Optionen zur Einstellung der Sicherheit"
 
-#: tools/gpgconf-comp.c:522
+#: tools/gpgconf-comp.c:524
 msgid "|N|expire SSH keys after N seconds"
 msgstr "|N|lasse SSH Schlüssel im Cache nach N Sekunden verfallen"
 
-#: tools/gpgconf-comp.c:526
+#: tools/gpgconf-comp.c:528
 msgid "|N|set maximum PIN cache lifetime to N seconds"
 msgstr "|N|setze die maximale Lebensdauer von PINs im Cache auf N Sekunden"
 
-#: tools/gpgconf-comp.c:530
+#: tools/gpgconf-comp.c:532
 msgid "|N|set maximum SSH key lifetime to N seconds"
 msgstr "|N|setze die maximale Lebenszeit von SSH Schlüsseln auf N Sekunden"
 
-#: tools/gpgconf-comp.c:544
+#: tools/gpgconf-comp.c:546
 msgid "Options enforcing a passphrase policy"
 msgstr "Optionen für eine Passphrase-Policy"
 
-#: tools/gpgconf-comp.c:547
+#: tools/gpgconf-comp.c:549
 msgid "do not allow to bypass the passphrase policy"
 msgstr "Einhaltung der Passphrase-Policy erzwingen"
 
-#: tools/gpgconf-comp.c:551
+#: tools/gpgconf-comp.c:553
 msgid "|N|set minimal required length for new passphrases to N"
 msgstr "|N|setze die kleinste erlaubte Länge von Passphrasen auf N"
 
-#: tools/gpgconf-comp.c:555
+#: tools/gpgconf-comp.c:557
 msgid "|N|require at least N non-alpha characters for a new passphrase"
 msgstr "|N|Verlange mindestens N Nicht-Buchstaben für eine neue Passphrase"
 
-#: tools/gpgconf-comp.c:559
+#: tools/gpgconf-comp.c:561
 msgid "|FILE|check new passphrases against pattern in FILE"
 msgstr "|DATEI|Prüfe neue Passphrases gegen die Regelen in DATEI"
 
-#: tools/gpgconf-comp.c:563
+#: tools/gpgconf-comp.c:565
 msgid "|N|expire the passphrase after N days"
 msgstr "|N|Lasse die Passphrase nach N Tagen verfallen"
 
-#: tools/gpgconf-comp.c:567
+#: tools/gpgconf-comp.c:569
 msgid "do not allow the reuse of old passphrases"
 msgstr "Verbiete die Wiedernutzung alter Passphrases."
 
-#: tools/gpgconf-comp.c:665 tools/gpgconf-comp.c:740
+#: tools/gpgconf-comp.c:674 tools/gpgconf-comp.c:752
 msgid "|NAME|use NAME as default secret key"
 msgstr "|NAME|NAME als voreingestellten Schlüssel benutzen"
 
-#: tools/gpgconf-comp.c:668 tools/gpgconf-comp.c:743
+#: tools/gpgconf-comp.c:677 tools/gpgconf-comp.c:755
 msgid "|NAME|encrypt to user ID NAME as well"
 msgstr "|NAME|Auch an NAME verschlüsseln"
 
-#: tools/gpgconf-comp.c:671
+#: tools/gpgconf-comp.c:680
 msgid "|SPEC|set up email aliases"
 msgstr "|SPEC|Email Alias festlegen"
 
-#: tools/gpgconf-comp.c:697
+#: tools/gpgconf-comp.c:706
 msgid "Configuration for Keyservers"
 msgstr "Konfiguration der Schlüsselserver"
 
-#: tools/gpgconf-comp.c:699
+#: tools/gpgconf-comp.c:708
 msgid "|URL|use keyserver at URL"
 msgstr "Benutze Schlüsselserver unter der URL"
 
-#: tools/gpgconf-comp.c:702
+#: tools/gpgconf-comp.c:711
 msgid "allow PKA lookups (DNS requests)"
 msgstr "Erlaube PKA Zugriffe (DNS Anfragen)"
 
-#: tools/gpgconf-comp.c:705
+#: tools/gpgconf-comp.c:714
 msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address"
 msgstr ""
 "|MECHANISMEN|Benutze MECHANISMEN um Schlüssel über die Mailadresse "
 "aufzufinden."
 
-#: tools/gpgconf-comp.c:752
+#: tools/gpgconf-comp.c:764
 msgid "disable all access to the dirmngr"
 msgstr "Jeglichen Zugriff auf den Dirmngr verhindern"
 
-#: tools/gpgconf-comp.c:755
+#: tools/gpgconf-comp.c:767
 msgid "|NAME|use encoding NAME for PKCS#12 passphrases"
 msgstr "|NAME|Benutze die Kodierung NAME für PKCS#12 Passphrasen"
 
-#: tools/gpgconf-comp.c:785
+#: tools/gpgconf-comp.c:797
 msgid "do not check CRLs for root certificates"
 msgstr "CRL bei Wurzelzertifikaten nicht überprüfen"
 
-#: tools/gpgconf-comp.c:829
+#: tools/gpgconf-comp.c:845
 msgid "Options controlling the format of the output"
 msgstr "Optionen zum Einstellen der Ausgabeformate"
 
-#: tools/gpgconf-comp.c:865
+#: tools/gpgconf-comp.c:881
 msgid "Options controlling the interactivity and enforcement"
 msgstr "Optionen zur Einstellung der Interaktivität und Geltendmachung"
 
-#: tools/gpgconf-comp.c:875
+#: tools/gpgconf-comp.c:891
 msgid "Configuration for HTTP servers"
 msgstr "Konfiguration für HTTP Server"
 
-#: tools/gpgconf-comp.c:886
+#: tools/gpgconf-comp.c:902
 msgid "use system's HTTP proxy setting"
 msgstr "Benutze die HTTP Proxy Einstellung des Systems"
 
-#: tools/gpgconf-comp.c:891
+#: tools/gpgconf-comp.c:907
 msgid "Configuration of LDAP servers to use"
 msgstr "Konfiguration der zu nutzenden LDAP-Server"
 
-#: tools/gpgconf-comp.c:920
+#: tools/gpgconf-comp.c:936
 msgid "LDAP server list"
 msgstr "Liste der LDAP Server"
 
-#: tools/gpgconf-comp.c:928
+#: tools/gpgconf-comp.c:944
 msgid "Configuration for OCSP"
 msgstr "Konfiguration zu OCSP"
 
-#: tools/gpgconf-comp.c:3074
+#: tools/gpgconf-comp.c:3091
 #, c-format
 msgid "External verification of component %s failed"
 msgstr "Die externe Überprüfung der Komponente %s war nicht erfolgreich"
 
-#: tools/gpgconf-comp.c:3224
+#: tools/gpgconf-comp.c:3241
 msgid "Note that group specifications are ignored\n"
 msgstr "Beachten Sie, daß Gruppenspezifiaktionen ignoriert werden\n"
 
@@ -9986,6 +9971,17 @@ msgstr ""
 "Syntax: gpg-check-pattern [optionen] Musterdatei\n"
 "Die von stdin gelesene Passphrase gegen die Musterdatei prüfen\n"
 
+#~ msgid "connection to agent established (%ds)\n"
+#~ msgstr "Verbindung zum gpg-agent aufgebaut (%ds)\n"
+
+#~ msgid "connection to the dirmngr established (%ds)\n"
+#~ msgstr "Verbindung zum Dirmngr aufgebaut (%ds)\n"
+
+#~ msgid "external keyserver calls are not supported in this build\n"
+#~ msgstr ""
+#~ "Externe Schlüsselserveraufrufe werden in diesem \"Build\" nicht "
+#~ "unterstützt\n"
+
 #~ msgid "This key is not protected.\n"
 #~ msgstr "Dieser Schlüssel ist nicht geschützt.\n"