[git] GPGME - branch, master, updated. gpgme-1.6.0-365-ged1f270

by Werner Koch cvs at cvs.gnupg.org
Thu Sep 15 11:42:39 CEST 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG Made Easy".

The branch, master has been updated
       via  ed1f2700a73060e2615697491ea9e49ded4293e6 (commit)
       via  d2b72d3cc19fe2a7d548dac38d55e069e0c9a904 (commit)
      from  7c37719d79345a665ec2f4570e3f257033b58c62 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ed1f2700a73060e2615697491ea9e49ded4293e6
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Sep 15 10:45:04 2016 +0200

    core: New function gpgme_op_interact, deprecate gpgme_op_edit.
    
    * src/gpgme.h.in (gpgme_interact_cb_t): New.
    (GPGME_INTERACT_CARD): New.
    (gpgme_op_interact_start, gpgme_op_interact): New.
    * src/libgpgme.vers, src/gpgme.def: Add new functions.
    * src/edit.c (op_data_t): Rename fnc to fnc_old and change users.  Add
    fnc.
    (edit_status_handler): Call old or new callback.
    (command_handler): Ditto.
    (interact_start): New.
    (gpgme_op_interact_start, gpgme_op_interact_start): New.
    * src/status-table.c (_gpgme_status_to_string): New.
    
    * tests/gpg/t-edit.c (edit_fnc): Rename to interact_fnc and change
    type of STATUS.  Use gpgme_io_writen.
    (main): s/gpgme_op_edit/gpgme_op_interact/.
    --
    
    This change will eventually allow us to remove all those status codes
    from gpgme.h.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/NEWS b/NEWS
index 6499f5e..5332432 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,9 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_]
 
  * New global flag "require-gnupg" to set a minimal gnupg version.
 
+ * New function gpgme_op_interact to replace the deprecated functions
+   gpgme_op_edit and gpgme_op_card_edit.
+
  * Interface changes relative to the 1.6.0 release:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  gpgme_pubkey_algo_string       NEW.
@@ -27,6 +30,15 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_]
  gpgme_op_keysign               NEW.
  gpgme_op_tofu_policy_start     NEW.
  gpgme_op_tofu_policy           NEW.
+ gpgme_op_interact_start        NEW.
+ gpgme_op_interact              NEW.
+ gpgme_interact_cb_t            NEW.
+ gpgme_op_edit_start            DEPRECATED.
+ gpgme_op_edit                  DEPRECATED.
+ gpgme_op_card_edit_start       DEPRECATED.
+ gpgme_op_card_edit             DEPRECATED.
+ gpgme_edit_cb_t                DEPRECATED.
+ gpgme_status_code_t            DEPRECATED.
  gpgme_genkey_result_t          EXTENDED: New fields pubkey and seckey.
  gpgme_signature_t              EXTENDED: New field key.
  gpgme_key_t                    EXTENDED: New field fpr.
@@ -56,6 +68,7 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_]
  GPGME_CREATE_FORCE             NEW.
  GPGME_KEYSIGN_LOCAL            NEW.
  GPGME_KEYSIGN_LFSEP            NEW.
+ GPGME_INTERACT_CARD            NEW.
 
 
 Noteworthy changes in version 1.6.0 (2015-08-26) [C25/A14/R0]
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index a4a0814..5971e48 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -15,7 +15,7 @@
 
 @copying
 Copyright @copyright{} 2002, 2003, 2004, 2005, 2006, 2007,
-2008, 2010, 2012, 2013, 2014 g10 Code GmbH.
+2008, 2010, 2012, 2013, 2014, 2016 g10 Code GmbH.
 
 @quotation
 Permission is granted to copy, distribute and/or modify this document
@@ -71,7 +71,7 @@ This is Edition @value{EDITION}, last updated @value{UPDATED}, of
 @center for version @value{VERSION}
 @page
 @vskip 0pt plus 1filll
-Published by g10 Code GmbH@* Hüttenstr. 61@* 40699 Erkrath, Germany
+Published by g10 Code GmbH@* Hüttenstr. 61@* 40699 Erkrath, Germany
 
 @insertcopying
 @end titlepage
@@ -4301,7 +4301,79 @@ could not be started.
 @subsection Advanced Key Editing
 @cindex key, edit
 
- at deftp {Data type} {gpgme_error_t (*gpgme_edit_cb_t) (@w{void *@var{handle}}, @w{gpgme_status_code_t @var{status}}, @w{const char *@var{args}}, @w{int @var{fd}})}
+ at deftp {Data type} {gpgme_error_t (*gpgme_interact_cb_t) @
+   (@w{void *@var{handle}}, @
+    @w{const char *@var{status}}, @
+    @w{const char *@var{args}}, @
+    @w{int @var{fd}})}
+ at tindex gpgme_interact_cb_t
+The @code{gpgme_interact_cb_t} type is the type of functions which
+ at acronym{GPGME} calls if it a key interact operation is on-going.  The
+status keyword @var{status} and the argument line @var{args} are passed
+through by @acronym{GPGME} from the crypto engine.  The file
+descriptor @var{fd} is -1 for normal status messages.  If @var{status}
+indicates a command rather than a status message, the response to the
+command should be written to @var{fd}.  The @var{handle} is provided
+by the user at start of operation.
+
+The function should return @code{GPG_ERR_FALSE} if it did not handle
+the status code, @code{0} for success, or any other error value.
+ at end deftp
+
+ at deftypefun gpgme_error_t gpgme_op_interact (@w{gpgme_ctx_t @var{ctx}}, @
+   @w{gpgme_key_t @var{key}}, @
+   @w{unsigned int @var{flags}}, @
+   @w{gpgme_interact_cb_t @var{fnc}}, @
+   @w{void *@var{handle}}, @
+   @w{gpgme_data_t @var{out}})
+The function @code{gpgme_op_interact} processes the key @var{KEY}
+interactively, using the interact callback function @var{FNC} with the
+handle @var{HANDLE}.  The callback is invoked for every status and
+command request from the crypto engine.  The output of the crypto
+engine is written to the data object @var{out}.
+
+Note that the protocol between the callback function and the crypto
+engine is specific to the crypto engine and no further support in
+implementing this protocol correctly is provided by @acronym{GPGME}.
+
+ at var{flags} modifies the behaviour of the function; the only defined
+bit value is:
+
+ at table @code
+ at item GPGME_INTERACT_CARD
+This is used for smartcard based keys and uses gpg’s
+ at code{--card-edit} command.
+
+ at end table
+
+The function returns @code{0} if the edit operation completes
+successfully, @code{GPG_ERR_INV_VALUE} if @var{ctx} or @var{key} is
+not a valid pointer, and any error returned by the crypto engine or
+the edit callback handler.
+ at end deftypefun
+
+
+ at deftypefun gpgme_error_t gpgme_op_interact_start (@w{gpgme_ctx_t @var{ctx}}, @
+   @w{gpgme_key_t @var{key}}, @
+   @w{unsigned int @var{flags}}, @
+   @w{gpgme_interact_cb_t @var{fnc}}, @
+   @w{void *@var{handle}}, @
+   @w{gpgme_data_t @var{out}})
+The function @code{gpgme_op_interact_start} initiates a
+ at code{gpgme_op_interact} operation.  It can be completed by calling
+ at code{gpgme_wait} on the context.  @xref{Waiting For Completion}.
+
+The function returns @code{0} if the operation was started
+successfully, and @code{GPG_ERR_INV_VALUE} if @var{ctx} or @var{key}
+is not a valid pointer.
+ at end deftypefun
+
+
+ at deftp {Data type} {gpgme_error_t (*gpgme_edit_cb_t) @
+   (@w{void *@var{handle}}, @
+    @w{gpgme_status_code_t @var{status}}, @
+    @w{const char *@var{args}}, @
+    @w{int @var{fd}})}
 @tindex gpgme_edit_cb_t
 The @code{gpgme_edit_cb_t} type is the type of functions which
 @acronym{GPGME} calls if it a key edit operation is on-going.  The
@@ -4317,6 +4389,9 @@ the status code, @code{0} for success, or any other error value.
 @end deftp
 
 @deftypefun gpgme_error_t gpgme_op_edit (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{key}}, @w{gpgme_edit_cb_t @var{fnc}}, @w{void *@var{handle}}, @w{gpgme_data_t @var{out}})
+Note: This function is deprecated, please use
+ at code{gpgme_op_interact} instead.
+
 The function @code{gpgme_op_edit} processes the key @var{KEY}
 interactively, using the edit callback function @var{FNC} with the
 handle @var{HANDLE}.  The callback is invoked for every status and
@@ -4334,6 +4409,9 @@ by the crypto engine or the edit callback handler.
 @end deftypefun
 
 @deftypefun gpgme_error_t gpgme_op_edit_start (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{key}}, @w{gpgme_edit_cb_t @var{fnc}}, @w{void *@var{handle}}, @w{gpgme_data_t @var{out}})
+Note: This function is deprecated, please use
+ at code{gpgme_op_interact_start} instead.
+
 The function @code{gpgme_op_edit_start} initiates a
 @code{gpgme_op_edit} operation.  It can be completed by calling
 @code{gpgme_wait} on the context.  @xref{Waiting For Completion}.
@@ -4345,11 +4423,17 @@ operation was started successfully, and @code{GPG_ERR_INV_VALUE} if
 
 
 @deftypefun gpgme_error_t gpgme_op_card_edit (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{key}}, @w{gpgme_edit_cb_t @var{fnc}}, @w{void *@var{handle}}, @w{gpgme_data_t @var{out}})
+Note: This function is deprecated, please use @code{gpgme_op_interact}
+with the flag @code{GPGME_INTERACT_CARD} instead.
+
 The function @code{gpgme_op_card_edit} is analogous to
 @code{gpgme_op_edit}, but should be used to process the smart card corresponding to the key @var{key}.
 @end deftypefun
 
 @deftypefun gpgme_error_t gpgme_op_card_edit_start (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{key}}, @w{gpgme_edit_cb_t @var{fnc}}, @w{void *@var{handle}}, @w{gpgme_data_t @var{out}})
+Note: This function is deprecated, please use @code{gpgme_op_interact_start}
+with the flag @code{GPGME_INTERACT_CARD} instead.
+
 The function @code{gpgme_op_card_edit_start} initiates a
 @code{gpgme_op_card_edit} operation.  It can be completed by calling
 @code{gpgme_wait} on the context.  @xref{Waiting For Completion}.
diff --git a/src/edit.c b/src/edit.c
index 1be60c4..887af73 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -27,12 +27,15 @@
 #include "debug.h"
 #include "context.h"
 #include "ops.h"
+#include "util.h"
+
 
 

 typedef struct
 {
   /* The user callback function and its hook value.  */
-  gpgme_edit_cb_t fnc;
+  gpgme_interact_cb_t fnc;
+  gpgme_edit_cb_t fnc_old;
   void *fnc_value;
 } *op_data_t;
 
@@ -58,7 +61,11 @@ edit_status_handler (void *priv, gpgme_status_code_t status, char *args)
   if (err)
     return err;
 
-  return (*opd->fnc) (opd->fnc_value, status, args, -1);
+  if (opd->fnc_old)
+    return (*opd->fnc_old) (opd->fnc_value, status, args, -1);
+
+  return (*opd->fnc) (opd->fnc_value, _gpgme_status_to_string (status),
+                      args, -1);
 }
 
 
@@ -90,7 +97,12 @@ command_handler (void *priv, gpgme_status_code_t status, const char *args,
       if (err)
 	return err;
 
-      err = (*opd->fnc) (opd->fnc_value, status, args, fd);
+      if (opd->fnc_old)
+        err = (*opd->fnc_old) (opd->fnc_value, status, args, fd);
+      else
+        err = (*opd->fnc) (opd->fnc_value, _gpgme_status_to_string (status),
+                           args, fd);
+
       if (gpg_err_code (err) == GPG_ERR_FALSE)
         err = 0;
       else
@@ -103,6 +115,87 @@ command_handler (void *priv, gpgme_status_code_t status, const char *args,
 
 
 static gpgme_error_t
+interact_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t key,
+                unsigned int flags,
+                gpgme_interact_cb_t fnc, void *fnc_value, gpgme_data_t out)
+{
+  gpgme_error_t err;
+  void *hook;
+  op_data_t opd;
+
+  err = _gpgme_op_reset (ctx, synchronous);
+  if (err)
+    return err;
+
+  if (!fnc || !out)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  err = _gpgme_op_data_lookup (ctx, OPDATA_EDIT, &hook, sizeof (*opd), NULL);
+  opd = hook;
+  if (err)
+    return err;
+
+  opd->fnc = fnc;
+  opd->fnc_old = NULL;
+  opd->fnc_value = fnc_value;
+
+  err = _gpgme_engine_set_command_handler (ctx->engine, command_handler,
+					   ctx, out);
+  if (err)
+    return err;
+
+  _gpgme_engine_set_status_handler (ctx->engine, edit_status_handler, ctx);
+
+  return _gpgme_engine_op_edit (ctx->engine,
+                                (flags & GPGME_INTERACT_CARD)? 1: 0,
+                                key, out, ctx);
+}
+
+
+gpgme_error_t
+gpgme_op_interact_start (gpgme_ctx_t ctx, gpgme_key_t key, unsigned int flags,
+                         gpgme_interact_cb_t fnc, void *fnc_value,
+                         gpgme_data_t out)
+{
+  gpgme_error_t err;
+
+  TRACE_BEG5 (DEBUG_CTX, "gpgme_op_interact_start", ctx,
+	      "key=%p flags=0x%x fnc=%p fnc_value=%p, out=%p",
+	      key, flags,fnc, fnc_value, out);
+
+  if (!ctx)
+    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+  err = interact_start (ctx, 0, key, flags, fnc, fnc_value, out);
+  return err;
+}
+
+
+gpgme_error_t
+gpgme_op_interact (gpgme_ctx_t ctx, gpgme_key_t key, unsigned int flags,
+                   gpgme_interact_cb_t fnc, void *fnc_value,
+                   gpgme_data_t out)
+{
+  gpgme_error_t err;
+
+  TRACE_BEG5 (DEBUG_CTX, "gpgme_op_interact", ctx,
+	      "key=%p flags=0x%x fnc=%p fnc_value=%p, out=%p",
+	      key, flags,fnc, fnc_value, out);
+
+  if (!ctx)
+    return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+  err = interact_start (ctx, 1, key, flags, fnc, fnc_value, out);
+  if (!err)
+    err = _gpgme_wait_one (ctx);
+  return err;
+}
+
+
+
+

+/* The deprectated interface.  */
+static gpgme_error_t
 edit_start (gpgme_ctx_t ctx, int synchronous, int type, gpgme_key_t key,
 	    gpgme_edit_cb_t fnc, void *fnc_value, gpgme_data_t out)
 {
@@ -122,7 +215,8 @@ edit_start (gpgme_ctx_t ctx, int synchronous, int type, gpgme_key_t key,
   if (err)
     return err;
 
-  opd->fnc = fnc;
+  opd->fnc = NULL;
+  opd->fnc_old = fnc;
   opd->fnc_value = fnc_value;
 
   err = _gpgme_engine_set_command_handler (ctx->engine, command_handler,
diff --git a/src/gpgme.def b/src/gpgme.def
index 7882af6..9815a83 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -241,6 +241,8 @@ EXPORTS
     gpgme_op_keysign                      @181
     gpgme_op_tofu_policy_start            @182
     gpgme_op_tofu_policy                  @183
+    gpgme_op_interact_start               @184
+    gpgme_op_interact                     @185
 
 ; END
 
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 5ed0890..9c87b7b 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -444,7 +444,9 @@ typedef unsigned int gpgme_export_mode_t;
 #define GPGME_AUDITLOG_HTML      1
 #define GPGME_AUDITLOG_WITH_HELP 128
 
-/* The possible stati for the edit operation.  */
+
+/* The possible stati for gpgme_op_edit.  The use of that function and
+ * these status codes are deprecated in favor of gpgme_op_interact. */
 typedef enum
   {
     GPGME_STATUS_EOF = 0,
@@ -967,8 +969,13 @@ typedef void (*gpgme_progress_cb_t) (void *opaque, const char *what,
 typedef gpgme_error_t (*gpgme_status_cb_t) (void *opaque, const char *keyword,
                                             const char *args);
 
-
 /* Interact with the user about an edit operation.  */
+typedef gpgme_error_t (*gpgme_interact_cb_t) (void *opaque,
+                                              const char *keyword,
+                                              const char *args, int fd);
+
+/* The callback type used by the deprecated functions gpgme_op_card
+ * and gpgme_of_card_edit.  */
 typedef gpgme_error_t (*gpgme_edit_cb_t) (void *opaque,
 					  gpgme_status_code_t status,
 					  const char *args, int fd);
@@ -1217,7 +1224,7 @@ void gpgme_set_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs);
 void gpgme_get_io_cbs (gpgme_ctx_t ctx, gpgme_io_cbs_t io_cbs);
 
 /* Wrappers around the internal I/O functions for use with
-   gpgme_passphrase_cb_t and gpgme_edit_cb_t.  */
+   gpgme_passphrase_cb_t and gpgme_interact_cb_t.  */
 @API__SSIZE_T@ gpgme_io_read (int fd, void *buffer, size_t count);
 @API__SSIZE_T@ gpgme_io_write (int fd, const void *buffer, size_t count);
 int     gpgme_io_writen (int fd, const void *buffer, size_t count);
@@ -1949,23 +1956,36 @@ gpgme_error_t gpgme_op_keysign       (gpgme_ctx_t ctx,
  * Key edit interface
  */
 
-/* Edit the key KEY.  Send status and command requests to FNC and
+/* Flags to select the mode of the interact.  */
+#define GPGME_INTERACT_CARD   (1 << 0)  /* Use --card-edit mode. */
+
+
+/* Edit the KEY.  Send status and command requests to FNC and
    output of edit commands to OUT.  */
+gpgme_error_t gpgme_op_interact_start (gpgme_ctx_t ctx,
+                                       gpgme_key_t key,
+                                       unsigned int flags,
+                                       gpgme_interact_cb_t fnc,
+                                       void *fnc_value,
+                                       gpgme_data_t out);
+gpgme_error_t gpgme_op_interact (gpgme_ctx_t ctx, gpgme_key_t key,
+                                 unsigned int flags,
+                                 gpgme_interact_cb_t fnc,
+                                 void *fnc_value,
+                                 gpgme_data_t out);
+
 gpgme_error_t gpgme_op_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
 				   gpgme_edit_cb_t fnc, void *fnc_value,
-				   gpgme_data_t out);
+				   gpgme_data_t out) _GPGME_DEPRECATED;
 gpgme_error_t gpgme_op_edit (gpgme_ctx_t ctx, gpgme_key_t key,
 			     gpgme_edit_cb_t fnc, void *fnc_value,
-			     gpgme_data_t out);
-
-/* Edit the card for the key KEY.  Send status and command requests to
-   FNC and output of edit commands to OUT.  */
+			     gpgme_data_t out) _GPGME_DEPRECATED;
 gpgme_error_t gpgme_op_card_edit_start (gpgme_ctx_t ctx, gpgme_key_t key,
 					gpgme_edit_cb_t fnc, void *fnc_value,
-					gpgme_data_t out);
+					gpgme_data_t out) _GPGME_DEPRECATED;
 gpgme_error_t gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
 				  gpgme_edit_cb_t fnc, void *fnc_value,
-				  gpgme_data_t out);
+				  gpgme_data_t out) _GPGME_DEPRECATED;
 
 
 /* Set the Tofu policy of KEY to POLCIY.  */
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index d635b6b..aec9090 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -115,6 +115,8 @@ GPGME_1.1 {
     gpgme_op_keysign;
     gpgme_op_tofu_policy_start;
     gpgme_op_tofu_policy;
+    gpgme_op_interact_start;
+    gpgme_op_interact;
 };
 
 
diff --git a/src/status-table.c b/src/status-table.c
index 1318c8e..f44a08f 100644
--- a/src/status-table.c
+++ b/src/status-table.c
@@ -169,3 +169,15 @@ _gpgme_parse_status (const char *name)
 	       sizeof t, status_cmp);
   return r ? r->code : -1;
 }
+
+
+const char *
+_gpgme_status_to_string (gpgme_status_code_t code)
+{
+  int i;
+
+  for (i=0; i < DIM(status_table); i++)
+    if (status_table[i].code == code)
+      return status_table[i].name;
+  return "status_code_lost";
+}
diff --git a/src/util.h b/src/util.h
index a59700f..88e7750 100644
--- a/src/util.h
+++ b/src/util.h
@@ -185,6 +185,7 @@ gpgme_error_t _gpgme_getenv (const char *name, char **value);
 /* Convert a status string to a status code.  */
 void _gpgme_status_init (void);
 gpgme_status_code_t _gpgme_parse_status (const char *name);
+const char *_gpgme_status_to_string (gpgme_status_code_t code);
 
 

 #ifdef HAVE_W32_SYSTEM
diff --git a/tests/gpg/t-edit.c b/tests/gpg/t-edit.c
index 8b5f7cb..7b444fa 100644
--- a/tests/gpg/t-edit.c
+++ b/tests/gpg/t-edit.c
@@ -55,7 +55,7 @@ flush_data (gpgme_data_t dh)
 
 
 gpgme_error_t
-edit_fnc (void *opaque, gpgme_status_code_t status, const char *args, int fd)
+interact_fnc (void *opaque, const char *status, const char *args, int fd)
 {
   const char *result = NULL;
   gpgme_data_t out = (gpgme_data_t) opaque;
@@ -63,7 +63,7 @@ edit_fnc (void *opaque, gpgme_status_code_t status, const char *args, int fd)
   fputs ("[-- Response --]\n", stdout);
   flush_data (out);
 
-  fprintf (stdout, "[-- Code: %i, %s --]\n", status, args);
+  fprintf (stdout, "[-- Code: %s, %s --]\n", status, args);
 
   if (fd >= 0)
     {
@@ -103,8 +103,8 @@ edit_fnc (void *opaque, gpgme_status_code_t status, const char *args, int fd)
 
   if (result)
     {
-      gpgme_io_write (fd, result, strlen (result));
-      gpgme_io_write (fd, "\n", 1);
+      gpgme_io_writen (fd, result, strlen (result));
+      gpgme_io_writen (fd, "\n", 1);
     }
   return 0;
 }
@@ -141,7 +141,7 @@ main (int argc, char **argv)
   err = gpgme_op_keylist_end (ctx);
   fail_if_err (err);
 
-  err = gpgme_op_edit (ctx, key, edit_fnc, out, out);
+  err = gpgme_op_interact (ctx, key, 0, interact_fnc, out, out);
   fail_if_err (err);
 
   fputs ("[-- Last response --]\n", stdout);

commit d2b72d3cc19fe2a7d548dac38d55e069e0c9a904
Author: Werner Koch <wk at gnupg.org>
Date:   Thu Sep 15 09:24:29 2016 +0200

    core: Minor change of the gpgme_op_edit semantics.
    
    * src/edit.c (command_handler): Handle special error code.
    * src/engine-gpg.c (read_status): Ditto.
    * src/engine-gpgsm.c (status_handler): Ditto.
    * src/engine-uiserver.c (status_handler): Ditto.
    * src/util.h (GPG_ERR_FALSE): Define for older libgpg-error versions.
    --
    
    An edit callback may now simply return GPG_ERR_FALSE to indicate that
    it did not handled the status code.  GPGME will the do the appropriate
    action, which is to send an empty line.
    
    Note that it is highly unlikely that GPG_ERR_FALSE has ever been used
    by an application as return value from an edit interactor.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index ef39d81..a4a0814 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -4312,7 +4312,8 @@ indicates a command rather than a status message, the response to the
 command should be written to @var{fd}.  The @var{handle} is provided
 by the user at start of operation.
 
-The function should return @code{GPG_ERR_NO_ERROR} or an error value.
+The function should return @code{GPG_ERR_FALSE} if it did not handle
+the status code, @code{0} for success, or any other error value.
 @end deftp
 
 @deftypefun gpgme_error_t gpgme_op_edit (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{key}}, @w{gpgme_edit_cb_t @var{fnc}}, @w{void *@var{handle}}, @w{gpgme_data_t @var{out}})
diff --git a/src/edit.c b/src/edit.c
index 72fa458..1be60c4 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -77,6 +77,8 @@ command_handler (void *priv, gpgme_status_code_t status, const char *args,
       if (err)
 	return err;
     }
+  else
+    err = 0;
 
   if (!processed)
     {
@@ -88,16 +90,15 @@ command_handler (void *priv, gpgme_status_code_t status, const char *args,
       if (err)
 	return err;
 
-      /* FIXME: We expect the user to handle _all_ status codes.
-	 Later, we may fix the callback interface to allow the user
-	 indicate if it processed the status code or not.  */
-      *processed_r = 1;
-
-      return (*opd->fnc) (opd->fnc_value, status, args, fd);
+      err = (*opd->fnc) (opd->fnc_value, status, args, fd);
+      if (gpg_err_code (err) == GPG_ERR_FALSE)
+        err = 0;
+      else
+        processed = 1;
     }
 
   *processed_r = processed;
-  return 0;
+  return err;
 }
 
 
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 9a0dab0..d2741cb 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -1102,6 +1102,8 @@ read_status (engine_gpg_t gpg)
           char emptystring[1] = {0};
           err = gpg->status.fnc (gpg->status.fnc_value,
                                  GPGME_STATUS_EOF, emptystring);
+          if (gpg_err_code (err) == GPG_ERR_FALSE)
+            err = 0; /* Drop special error code.  */
         }
 
       return err;
@@ -1169,6 +1171,8 @@ read_status (engine_gpg_t gpg)
 			{
 			  err = gpg->status.fnc (gpg->status.fnc_value,
 						 r, rest);
+                          if (gpg_err_code (err) == GPG_ERR_FALSE)
+                            err = 0; /* Drop special error code.  */
 			  if (err)
 			    return err;
                         }
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index 5fcfbf1..49cf061 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -827,6 +827,8 @@ status_handler (void *opaque, int fd)
               char emptystring[1] = {0};
               err = gpgsm->status.fnc (gpgsm->status.fnc_value,
                                        GPGME_STATUS_EOF, emptystring);
+              if (gpg_err_code (err) == GPG_ERR_FALSE)
+                err = 0; /* Drop special error code.  */
             }
 
 	  if (!err && gpgsm->colon.fnc && gpgsm->colon.any)
@@ -978,7 +980,11 @@ status_handler (void *opaque, int fd)
 	  if (r >= 0)
 	    {
 	      if (gpgsm->status.fnc)
-		err = gpgsm->status.fnc (gpgsm->status.fnc_value, r, rest);
+                {
+                  err = gpgsm->status.fnc (gpgsm->status.fnc_value, r, rest);
+                  if (gpg_err_code (err) == GPG_ERR_FALSE)
+                    err = 0; /* Drop special error code.  */
+                }
 	    }
 	  else
 	    fprintf (stderr, "[UNKNOWN STATUS]%s %s", line + 2, rest);
diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c
index 318d32e..d855c74 100644
--- a/src/engine-uiserver.c
+++ b/src/engine-uiserver.c
@@ -676,6 +676,8 @@ status_handler (void *opaque, int fd)
               char emptystring[1] = {0};
               err = uiserver->status.fnc (uiserver->status.fnc_value,
                                           GPGME_STATUS_EOF, emptystring);
+              if (gpg_err_code (err) == GPG_ERR_FALSE)
+                err = 0; /* Drop special error code.  */
             }
 
 	  if (!err && uiserver->colon.fnc && uiserver->colon.any)
@@ -827,7 +829,12 @@ status_handler (void *opaque, int fd)
 	  if (r >= 0)
 	    {
 	      if (uiserver->status.fnc)
-		err = uiserver->status.fnc (uiserver->status.fnc_value, r, rest);
+                {
+                  err = uiserver->status.fnc (uiserver->status.fnc_value,
+                                              r, rest);
+                  if (gpg_err_code (err) == GPG_ERR_FALSE)
+                    err = 0; /* Drop special error code.  */
+                }
 	    }
 	  else
 	    fprintf (stderr, "[UNKNOWN STATUS]%s %s", line + 2, rest);
diff --git a/src/util.h b/src/util.h
index a3425f0..a59700f 100644
--- a/src/util.h
+++ b/src/util.h
@@ -45,6 +45,11 @@
 

 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
 
+#if GPG_ERROR_VERSION_NUMBER < 0x011500 /* 1.21 */
+# define GPG_ERR_FALSE 256
+#endif
+
+
 

 /*-- {posix,w32}-util.c --*/
 int _gpgme_get_conf_int (const char *key, int *value);

-----------------------------------------------------------------------

Summary of changes:
 NEWS                  |  13 ++++++
 doc/gpgme.texi        |  93 +++++++++++++++++++++++++++++++++++++++--
 src/edit.c            | 113 ++++++++++++++++++++++++++++++++++++++++++++++----
 src/engine-gpg.c      |   4 ++
 src/engine-gpgsm.c    |   8 +++-
 src/engine-uiserver.c |   9 +++-
 src/gpgme.def         |   2 +
 src/gpgme.h.in        |  42 ++++++++++++++-----
 src/libgpgme.vers     |   2 +
 src/status-table.c    |  12 ++++++
 src/util.h            |   6 +++
 tests/gpg/t-edit.c    |  10 ++---
 12 files changed, 283 insertions(+), 31 deletions(-)


hooks/post-receive
-- 
GnuPG Made Easy
http://git.gnupg.org




More information about the Gnupg-commits mailing list