* server.c (cmd_listkeys, cmd_listsecretkeys): Divert to NEWPG-0-3-2
authorWerner Koch <wk@gnupg.org>
Wed, 6 Mar 2002 16:13:47 +0000 (16:13 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 6 Mar 2002 16:13:47 +0000 (16:13 +0000)
(do_listkeys): new.  Add pattern parsing.
* keylist.c (gpgsm_list_keys): Handle selection pattern.

sm/ChangeLog
sm/keylist.c
sm/server.c

index 756cb45..5b97cf1 100644 (file)
@@ -1,5 +1,10 @@
 2002-03-06  Werner Koch  <wk@gnupg.org>
 
+       * server.c (cmd_listkeys, cmd_listsecretkeys): Divert to
+       (do_listkeys): new.  Add pattern parsing.
+
+       * keylist.c (gpgsm_list_keys): Handle selection pattern.
+
        * gpgsm.c: New command --learn-card
        * call-agent.c (learn_cb,gpgsm_agent_learn): New.
 
index 0c84168..6c57897 100644 (file)
@@ -227,28 +227,68 @@ void
 gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
 {
   KEYDB_HANDLE hd;
+  KEYDB_SEARCH_DESC *desc = NULL;
+  STRLIST sl;
+  int ndesc;
   KsbaCert cert = NULL;
   int rc=0;
   const char *lastresname, *resname;
   int have_secret;
 
-#warning there is no key selection yet
-  /* We must take care of quoting here */
   hd = keydb_new (0);
   if (!hd)
-    rc = GNUPG_General_Error;
+    {
+      log_error ("keydb_new failed\n");
+      goto leave;
+    }
+
+  if (!names)
+    ndesc = 1;
   else
-    rc = keydb_search_first (hd);
-  if (rc)
     {
-      if (rc != -1)
-        log_error ("keydb_search_first failed: %s\n", gnupg_strerror (rc) );
+      for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
+        ;
+    }
+
+  desc = xtrycalloc (ndesc, sizeof *desc);
+  if (!ndesc)
+    {
+      log_error ("out of core\n");
       goto leave;
     }
 
+  if (!names)
+    desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
+  else 
+    {
+      for (ndesc=0, sl=names; sl; sl = sl->next) 
+        {
+          rc = keydb_classify_name (sl->d, desc+ndesc);
+          if (rc)
+            {
+              log_error ("key `%s' not found: %s\n",
+                         sl->d, gnupg_strerror (rc));
+              rc = 0;
+            }
+          else
+            ndesc++;
+        }
+      
+    }
+
+  /* it would be nice to see which of the given users did actually
+     match one in the keyring.  To implement this we need to have a
+     found flag for each entry in desc and to set this we must check
+     all those entries after a match to mark all matched one -
+     currently we stop at the first match.  To do this we need an
+     extra flag to enable this feature so */
+
   lastresname = NULL;
-  do
+  while (!(rc = keydb_search (hd, desc, ndesc)))
     {
+      if (!names) 
+        desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
+
       rc = keydb_get_cert (hd, &cert);
       if (rc) 
         {
@@ -296,12 +336,14 @@ gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
       ksba_cert_release (cert); 
       cert = NULL;
     }
-  while (!(rc = keydb_search_next (hd)));
   if (rc && rc != -1)
-    log_error ("keydb_search_next failed: %s\n", gnupg_strerror (rc));
+    log_error ("keydb_search failed: %s\n", gnupg_strerror (rc));
   
  leave:
   ksba_cert_release (cert);
+  xfree (desc);
   keydb_release (hd);
 }
 
+
+
index 065fc5a..856eb56 100644 (file)
@@ -42,6 +42,32 @@ struct server_local_s {
   CERTLIST recplist;
 };
 
+
+
+/* note, that it is sufficient to allocate the target string D as
+   long as the source string S, i.e.: strlen(s)+1; */
+static void
+strcpy_escaped_plus (char *d, const unsigned char *s)
+{
+  while (*s)
+    {
+      if (*s == '%' && s[1] && s[2])
+        { 
+          s++;
+          *d++ = xtoi_2 ( s);
+          s += 2;
+        }
+      else if (*s == '+')
+        *d++ = ' ', s++;
+      else
+        *d++ = *s++;
+    }
+  *d = 0; 
+}
+
+
+
+
 /* Check whether the option NAME appears in LINE */
 static int
 has_option (const char *line, const char *name)
@@ -370,35 +396,56 @@ cmd_message (ASSUAN_CONTEXT ctx, char *line)
 }
 
 
-/* Note that the line contains a space separated list of pappern where
-   each pappern is percent escaped and spaces may be replaced by
-   '+'. */
 static int 
-cmd_listkeys (ASSUAN_CONTEXT ctx, char *line)
+do_listkeys (ASSUAN_CONTEXT ctx, char *line, int mode)
 {
   CTRL ctrl = assuan_get_pointer (ctx);
   FILE *fp = assuan_get_data_fp (ctx);
+  char *p;
+  STRLIST list, sl;
 
   if (!fp)
     return set_error (General_Error, "no data stream");
-  ctrl->with_colons = 1;
-  gpgsm_list_keys (assuan_get_pointer (ctx), NULL, fp, 3);
+  
+  /* break the line down into an STRLIST */
+  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)
+            {
+              free_strlist (list);
+              return ASSUAN_Out_Of_Core;
+            }
+          sl->flags = 0;
+          strcpy_escaped_plus (sl->d, line);
+          sl->next = list;
+          list = sl;
+        }
+    }
 
+  ctrl->with_colons = 1;
+  gpgsm_list_keys (assuan_get_pointer (ctx), list, fp, 3);
+  free_strlist (list);
   return 0;
 }
 
 static int 
-cmd_listsecretkeys (ASSUAN_CONTEXT ctx, char *line)
+cmd_listkeys (ASSUAN_CONTEXT ctx, char *line)
 {
-  CTRL ctrl = assuan_get_pointer (ctx);
-  FILE *fp = assuan_get_data_fp (ctx);
-
-  ctrl->with_colons = 1;
-  if (!fp)
-    return set_error (General_Error, "no data stream");
-  gpgsm_list_keys (assuan_get_pointer (ctx), NULL, fp, 2);
+  return do_listkeys (ctx, line, 3);
+}
 
-  return 0;
+static int 
+cmd_listsecretkeys (ASSUAN_CONTEXT ctx, char *line)
+{
+  return do_listkeys (ctx, line, 2);
 }
 
 \f