doc/
authorMarcus Brinkmann <mb@g10code.com>
Wed, 27 Feb 2002 00:59:31 +0000 (00:59 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Wed, 27 Feb 2002 00:59:31 +0000 (00:59 +0000)
2002-02-27  Marcus Brinkmann  <marcus@g10code.de>

* gpgme.texi (Listing Keys): Document gpgme_op_keylist_ext_start.

gpgme/
2002-02-27  Marcus Brinkmann  <marcus@g10code.de>

* rungpg.h (_gpgme_gpg_op_keylist_ext): New prototype.
* rungpg.c (_gpgme_gpg_op_keylist_ext): New function.
* engine-gpgsm.h (_gpgme_gpgsm_op_keylist_ext): New prototype.
* engine-gpgsm.c (_gpgme_gpgsm_op_keylist_ext): New function.
* engine.h (_gpgme_engine_op_keylist_ext): New prototype.
* engine.c (_gpgme_engine_op_keylist_ext): New function.
* keylist.c (gpgme_op_keylist_ext_start): New function.

12 files changed:
NEWS
TODO
doc/ChangeLog
doc/gpgme.texi
gpgme/ChangeLog
gpgme/engine-gpgsm.c
gpgme/engine-gpgsm.h
gpgme/engine.c
gpgme/engine.h
gpgme/keylist.c
gpgme/rungpg.c
gpgme/rungpg.h

diff --git a/NEWS b/NEWS
index 8d7a2bacfca7343e14b174daff15cf5ac6d10915..682f262d3ce243e8a7ce093db1bc768796d8e25f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,11 @@
 
+ * gpgme_op_encrypt does now fail with GPGME_Invalid_Recipients if
+   some recipients have been invalid, whereas earlier versions
+   succeeded in this case.  The plaintext is still encrypted for all valid
+   recipients, so the application might take this error as a hint that
+   the ciphertext is not usable for all requested recipients.
+   Information about invalid recipients is available with gpgme_get_op_info.
+
  * New interfaces gpgme_set_include_certs and gpgme_get_include_certs
    to set and get the number of certifications to include in S/MIME
    signed messages.
@@ -6,12 +13,7 @@
  * New interfaces gpgme_op_encrypt_sign and gpgme_op_encrypt_sign_start
    to encrypt and sign a message in a combined operation.
 
- * gpgme_op_encrypt does now fail with GPGME_Invalid_Recipients if
-   some recipients have been invalid, whereas earlier versions
-   succeeded in this case.  The plaintext is still encrypted for all valid
-   recipients, so the application might take this error as a hint that
-   the ciphertext is not usable for all requested recipients.
-   Information about invalid recipients is available with gpgme_get_op_info.
+ * New interface gpgme_op_keylist_ext_start to search for multiple patterns.
 
  * Interface changes relative to the 0.3.3 release:
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -20,6 +22,7 @@ gpgme_set_include_certs               NEW
 gpgme_get_include_certs                NEW
 gpgme_op_encrypt_sign          NEW
 gpgme_op_encrypt_sign_start    NEW
+gpgme_op_keylist_ext_start     NEW
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Noteworthy changes in version 0.3.3 (2002-02-12)
diff --git a/TODO b/TODO
index 2cf08bc5cd4bd4ea731d81e193b86667f8bc9ca8..8970c3995d95b769906763216710ab76d6b0c59e 100644 (file)
--- a/TODO
+++ b/TODO
@@ -44,10 +44,10 @@ Hey Emacs, this is -*- outline -*- mode!
    get GPGME_No_Passphrase." Bug reported by Stephane Corthesy.
 
 * Tests
-  Write a fake gpg-agent so that we can supply known passphrases to
-  gpgsm and setup the configuration files to use the agent.  Without
-  this we are testing a currently running gpg-agent which is not a
-  clever idea.
+** Write a fake gpg-agent so that we can supply known passphrases to
+   gpgsm and setup the configuration files to use the agent.  Without
+   this we are testing a currently running gpg-agent which is not a
+   clever idea.
 ** t-data
 *** Test gpgme_data_release_and_get_mem.
 *** Test gpgme_data_rewind for invalid types.
@@ -55,8 +55,6 @@ Hey Emacs, this is -*- outline -*- mode!
 
 * Build suite
 ** Make sure everything is cleaned correctly (esp. test area).
-** There is a spurious 4/10 tests failed in some conditions.
-   Rebuilding from scratch works around that.
 
 * Architecture support
 ** Implement posix-sema.c
index 8ae8ae2b451b64f292270a75d9d7ffafea83f302..56be628059bb01f1729c57b2f3659d780d453e9f 100644 (file)
@@ -1,3 +1,7 @@
+2002-02-27  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpgme.texi (Listing Keys): Document gpgme_op_keylist_ext_start.
+
 2002-02-27  Marcus Brinkmann  <marcus@g10code.de>
 
        * gpgme.texi (Encrypting a Plaintext): Document
index 5c2a084d473a69604ad67764d605ae2a48cbf801..a012abb8190e00a0d678318d586c96060004fef9 100644 (file)
@@ -1261,6 +1261,31 @@ valid pointer, and passes through any errors that are reported by the
 crypto engine support routines.
 @end deftypefun
 
+@deftypefun GpgmeError gpgme_op_keylist_ext_start (@w{GpgmeCtx @var{ctx}}, @w{const char *@var{pattern}[]}, @w{int @var{secret_only}}, @w{int @var{reserved}})
+The function @code{gpgme_op_keylist_ext_start} initiates an extended
+key listing operation inside the context @var{ctx}.  It sets
+everything up so that subsequent invocations of
+@code{gpgme_op_keylist_next} return the keys in the list.
+
+If @var{pattern} or @var{*pattern} is @code{NULL}, all available keys
+are returned.  Otherwise, @var{pattern} is a @code{NULL} terminated
+array of strings that are used to limit the list to all keys matching
+at least one of the patterns verbatim.
+
+If @var{secret_only} is not @code{0}, the list is restricted to secret
+keys only.
+
+The value of @var{reserved} must be @code{0}.
+
+The context will be busy until either all keys are received (and
+@code{gpgme_op_keylist_next} returns @code{GPGME_EOF}), or
+@code{gpgme_op_keylist_end} is called to finish the operation.
+
+The function returns @code{GPGME_Invalid_Value} if @var{ctx} is not a
+valid pointer, and passes through any errors that are reported by the
+crypto engine support routines.
+@end deftypefun
+
 @deftypefun GpgmeError gpgme_op_keylist_next (@w{GpgmeCtx @var{ctx}}, @w{GpgmeKey *@var{r_key}})
 The function @code{gpgme_op_keylist_next} returns the next key in the
 list created by a previous @code{gpgme_op_keylist_start} operation in
index 55358f70e96230d0886fb5fae7511262a105c582..58f09c62c9e3e31da7cf808facdf7e038ffa0d05 100644 (file)
@@ -1,3 +1,13 @@
+2002-02-27  Marcus Brinkmann  <marcus@g10code.de>
+
+       * rungpg.h (_gpgme_gpg_op_keylist_ext): New prototype.
+       * rungpg.c (_gpgme_gpg_op_keylist_ext): New function.
+       * engine-gpgsm.h (_gpgme_gpgsm_op_keylist_ext): New prototype.
+       * engine-gpgsm.c (_gpgme_gpgsm_op_keylist_ext): New function.
+       * engine.h (_gpgme_engine_op_keylist_ext): New prototype.
+       * engine.c (_gpgme_engine_op_keylist_ext): New function.
+       * keylist.c (gpgme_op_keylist_ext_start): New function.
+
 2002-02-27  Marcus Brinkmann  <marcus@g10code.de>
 
        * gpgme.h: Add new error code GPGME_Invalid_Recipient.
index a88d63847bf6bb848c4b835a48add72f451a7d25..32ee3a07630b300c00f78cd84897ae28c77592b2 100644 (file)
@@ -601,6 +601,97 @@ _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern,
 }
 
 
+GpgmeError
+_gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm, const char *pattern[],
+                            int secret_only, int reserved, int keylist_mode)
+{
+  char *line;
+  /* Length is "LISTSECRETKEYS " + p + '\0'.  */
+  int length = 15 + 1;
+  char *linep;
+
+  if (reserved)
+    return mk_error (Invalid_Value);
+
+  if (pattern && *pattern)
+    {
+      const char **pat = pattern;
+
+      while (*pat)
+       {
+         const char *patlet = *pat;
+
+         while (*patlet)
+           {
+             length++;
+             if (*patlet == '%' || *patlet == ' ' || *patlet == '+')
+               length += 2;
+             patlet++;
+           }
+         pat++;
+         /* This will allocate one byte more than necessary.  */
+         length++;
+       }
+    }
+  line = xtrymalloc (length);
+  if (!line)
+    return mk_error (Out_Of_Core);
+  if (secret_only)
+    {
+      strcpy (line, "LISTSECRETKEYS ");
+      linep = &line[15];
+    }
+  else
+    {
+      strcpy (line, "LISTKEYS ");
+      linep = &line[9];
+    }
+
+  if (pattern && *pattern)
+    {
+      while (*pattern)
+       {
+         const char *patlet = *pattern;
+
+         while (*patlet)
+           {
+             switch (*patlet)
+               {
+               case '%':
+                 *(linep++) = '%';
+                 *(linep++) = '2';
+                 *(linep++) = '5';
+                 break;
+               case ' ':
+                 *(linep++) = '%';
+                 *(linep++) = '2';
+                 *(linep++) = '0';
+                 break;
+               case '+':
+                 *(linep++) = '%';
+                 *(linep++) = '2';
+                 *(linep++) = 'B';
+                 break;
+               default:
+                 *(linep++) = *patlet;
+                 break;
+               }
+             patlet++;
+           }
+         pattern++;
+       }
+    }
+  *linep = '\0';
+
+  _gpgme_io_close (gpgsm->input_fd);
+  _gpgme_io_close (gpgsm->output_fd);
+  _gpgme_io_close (gpgsm->message_fd);
+
+  gpgsm->command = line;
+  return 0;
+}
+
+
 GpgmeError
 _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out,
                      GpgmeSigMode mode, int use_armor,
index b629ed6fc725b83b69bc3b1eb3cad837597fa178..ecd80b40bd9886ba12d8f1d1db149b969c6e5a5f 100644 (file)
@@ -50,6 +50,10 @@ GpgmeError _gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data,
 GpgmeError _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata);
 GpgmeError _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern,
                                    int secret_only, int keylist_mode);
+GpgmeError _gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm,
+                                       const char *pattern[],
+                                       int secret_only, int reserved,
+                                       int keylist_mode);
 GpgmeError _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in,
                                 GpgmeData out,
                                 GpgmeSigMode mode, int use_armor,
index 8841b20bdcb24c51759c9b2b34f5d1330630ed66..c1dd630ec8c304dc34e92f3ee2cf63604de6eb6c 100644 (file)
@@ -438,9 +438,10 @@ _gpgme_engine_op_import (EngineObject engine, GpgmeData keydata)
   return 0;
 }
 
+
 GpgmeError
-_gpgme_engine_op_keylist (EngineObject engine, const char *pattern, int secret_only,
-                         int keylist_mode)
+_gpgme_engine_op_keylist (EngineObject engine, const char *pattern,
+                         int secret_only, int keylist_mode)
 {
   if (!engine)
     return mk_error (Invalid_Value);
@@ -459,6 +460,29 @@ _gpgme_engine_op_keylist (EngineObject engine, const char *pattern, int secret_o
   return 0;
 }
 
+
+GpgmeError
+_gpgme_engine_op_keylist_ext (EngineObject engine, const char *pattern[],
+                             int secret_only, int reserved, int keylist_mode)
+{
+  if (!engine)
+    return mk_error (Invalid_Value);
+
+  switch (engine->protocol)
+    {
+    case GPGME_PROTOCOL_OpenPGP:
+      return _gpgme_gpg_op_keylist_ext (engine->engine.gpg, pattern,
+                                       secret_only, reserved, keylist_mode);
+    case GPGME_PROTOCOL_CMS:
+      return _gpgme_gpgsm_op_keylist_ext (engine->engine.gpgsm, pattern,
+                                         secret_only, reserved, keylist_mode);
+    default:
+      break;
+    }
+  return 0;
+}
+
+
 GpgmeError
 _gpgme_engine_op_sign (EngineObject engine, GpgmeData in, GpgmeData out,
                       GpgmeSigMode mode, int use_armor,
index d8881a109594dfbbbed064dae76289a0f990f810..f684021709c06c2f15c51773cf0f84372271d456 100644 (file)
@@ -60,6 +60,11 @@ GpgmeError _gpgme_engine_op_import (EngineObject engine, GpgmeData keydata);
 GpgmeError _gpgme_engine_op_keylist (EngineObject engine, const char *pattern,
                                     int secret_only,
                                     int keylist_mode);
+GpgmeError _gpgme_engine_op_keylist_ext (EngineObject engine,
+                                        const char *pattern[],
+                                        int secret_only,
+                                        int reserved,
+                                        int keylist_mode);
 GpgmeError _gpgme_engine_op_sign (EngineObject engine, GpgmeData in,
                                  GpgmeData out, GpgmeSigMode mode,
                                  int use_armor, int use_textmode,
index 91bdbc358129f4b897bfd9796c4e168de20bc7ac..55d427d2a90dd89a7c0689250138cd38280b4a52 100644 (file)
@@ -505,6 +505,73 @@ gpgme_op_keylist_start (GpgmeCtx ctx, const char *pattern, int secret_only)
 }
 
 
+/**
+ * gpgme_op_keylist_ext_start:
+ * @c: context 
+ * @pattern: a NULL terminated array of search patterns
+ * @secret_only: List only keys where the secret part is available
+ * @reserved: Should be 0.
+ * 
+ * Note that this function also cancels a pending key listing
+ * operaton. To actually retrieve the key, use
+ * gpgme_op_keylist_next().
+ * 
+ * Return value:  0 on success or an errorcode. 
+ **/
+GpgmeError
+gpgme_op_keylist_ext_start (GpgmeCtx ctx, const char *pattern[],
+                           int secret_only, int reserved)
+{
+  GpgmeError err = 0;
+
+  if (!ctx)
+    return mk_error (Invalid_Value);
+  ctx->pending = 1;
+
+  _gpgme_release_result (ctx);
+
+  if (ctx->engine)
+    {
+      _gpgme_engine_release (ctx->engine); 
+      ctx->engine = NULL;
+    }
+  gpgme_key_release (ctx->tmp_key);
+  ctx->tmp_key = NULL;
+  /* Fixme: Release key_queue.  */
+    
+  err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
+                          : GPGME_PROTOCOL_OpenPGP, &ctx->engine);
+  if (err)
+    goto leave;
+
+  _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
+  err = _gpgme_engine_set_colon_line_handler (ctx->engine,
+                                             keylist_colon_handler, ctx);
+  if (err)
+    goto leave;
+
+  /* We don't want to use the verbose mode as this will also print 
+     the key signatures which is in most cases not needed and furthermore we 
+     just ignore those lines - This should speed up things */
+  _gpgme_engine_set_verbosity (ctx->engine, 0);
+
+  err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
+                                     reserved, ctx->keylist_mode);
+
+  if (!err)    /* And kick off the process.  */
+    err = _gpgme_engine_start (ctx->engine, ctx);
+
+ leave:
+  if (err)
+    {
+      ctx->pending = 0; 
+      _gpgme_engine_release (ctx->engine);
+      ctx->engine = NULL;
+    }
+  return err;
+}
+
+
 /**
  * gpgme_op_keylist_next:
  * @c: Context
index 8738fc38612234cecb49c2c65bf749c9c47fe22f..dc69acba755005e8b3ecec7ad3f29a24241db881 100644 (file)
@@ -1441,6 +1441,7 @@ _gpgme_gpg_op_import (GpgObject gpg, GpgmeData keydata)
   return err;
 }
 
+
 GpgmeError
 _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, int secret_only,
                       int keylist_mode)
@@ -1465,6 +1466,38 @@ _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, int secret_only,
   return err;
 }
 
+
+GpgmeError
+_gpgme_gpg_op_keylist_ext (GpgObject gpg, const char *pattern[],
+                          int secret_only, int reserved, int keylist_mode)
+{
+  GpgmeError err;
+
+  if (reserved)
+    return mk_error (Invalid_Value);
+
+  err = _gpgme_gpg_add_arg (gpg, "--with-colons");
+  if (!err)
+    err = _gpgme_gpg_add_arg (gpg, "--fixed-list-mode");
+  if (!err)
+    err = _gpgme_gpg_add_arg (gpg, "--with-fingerprint");
+  if (!err)
+    err = _gpgme_gpg_add_arg (gpg, secret_only ? "--list-secret-keys"
+                             : "--list-keys");
+  
+  /* Tell the gpg object about the data */
+  if (!err)
+    err = _gpgme_gpg_add_arg (gpg, "--");
+  if (!err && pattern && *pattern)
+    {
+      while (*pattern)
+       err = _gpgme_gpg_add_arg (gpg, *(pattern++));
+    }
+
+  return err;
+}
+
+
 GpgmeError
 _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out,
                    GpgmeSigMode mode, int use_armor,
index ed65cf15fd88e3f77d077b0ae519ee9f10fc68dc..58afd8a8017ef1f71a1c70cef6b3cbbdd5c8a78b 100644 (file)
@@ -137,6 +137,9 @@ GpgmeError _gpgme_gpg_op_genkey (GpgObject gpg, GpgmeData help_data,
 GpgmeError _gpgme_gpg_op_import (GpgObject gpg, GpgmeData keydata);
 GpgmeError _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern,
                                  int secret_only, int keylist_mode);
+GpgmeError _gpgme_gpg_op_keylist_ext (GpgObject gpg, const char *pattern[],
+                                     int secret_only, int reserved,
+                                     int keylist_mode);
 GpgmeError _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out,
                               GpgmeSigMode mode, int use_armor,
                               int use_textmode, GpgmeCtx ctx /* FIXME */);