[git] GPGME - branch, master, updated. gpgme-1.6.0-119-g88f2c1c

by Werner Koch cvs at cvs.gnupg.org
Thu May 19 17:06:41 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  88f2c1c0d16eee6bb36a901623ea65ac69499f03 (commit)
       via  5aa8e588e166abeef2e3d677ab6830f2d7af1b5d (commit)
      from  0d4e95621e05d50cd454049a424bb9ee098a5db6 (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 88f2c1c0d16eee6bb36a901623ea65ac69499f03
Author: Werner Koch <wk at gnupg.org>
Date:   Thu May 19 17:01:07 2016 +0200

    api: Add new function gpgme_set_ctx_flag.
    
    * src/gpgme.h.in (gpgme_set_ctx_flag): New prototype.
    * src/gpgme.c (gpgme_set_ctx_flag): New.
    * src/gpgme.def, src/libgpgme.vers: Add new function.
    * src/context.h (struct gpgme_context): Add FULL_STATUS.
    * src/decrypt.c (_gpgme_decrypt_status_handler): Do not call the
      status callback if FULL_STATUS is set.
    * src/genkey.c (genkey_status_handler): Ditto.
    * src/passphrase.c (_gpgme_passphrase_status_handler): Ditto.
    * src/sign.c (_gpgme_sign_status_handler): Ditto.
    
    * src/engine-backend.h (struct engine_ops): Add SET_STATUS_CB and add
    adjust all definitions of that variable.
    * src/engine.c (_gpgme_engine_set_status_cb): New.
    * src/op-support.c (_gpgme_op_reset): Call this function.
    
    * src/engine-gpg.c (struct engine_gpg): Add fields MON_CB and
    MON_CB_VALUE.
    (gpg_set_status_cb): New.
    (_gpgme_engine_ops_gpg): Register that function.
    (read_status): Call the monitor callback.
    
    * src/engine-gpgsm.c (struct engine_gpgsm): Add fields MON_CB and
    MON_CB_VALUE.
    (_gpgme_engine_ops_gpgsm): Register that function.
    (gpgsm_assuan_simple_command): Change first arg to be an engine
    context and adjust call callers.  Call the monitor callback.
    
    * src/engine-uiserver.c (struct engine_uiserver): Add fields MON_CB
    and MON_CB_VALUE.
    (_gpgme_engine_ops_uiserver): Register that function.
    (uiserver_assuan_simple_command): Change first arg to be an engine
    context and adjust call callers.  Call the monitor callback.
    
    * tests/run-verify.c (status_cb): New.
    (print_result): Print algo names.
    (main): Add option --status.
    --
    
    This new feature is mainly intended for bug tracking.  Having access
    to the raw status lines might also be useful for applications, though.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/NEWS b/NEWS
index cfff559..119866e 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_]
  * Interface changes relative to the 1.6.0 release:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  gpgme_pubkey_algo_string       NEW.
+ gpgme_set_ctx_flag             NEW.
  GPGME_PK_EDDSA                 NEW.
 
 
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index db94617..4d7a874 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -2736,6 +2736,27 @@ or @var{ctx} is not a valid pointer, @code{NULL} is returned in both
 variables.
 @end deftypefun
 
+ at deftypefun {gpgme_error_t} gpgme_set_ctx_flag  @
+            (@w{gpgme_ctx_t @var{ctx}}, @
+            @w{const char *@var{name}}, @
+            @w{const char *@var{value}})
+
+Some minor properties of the context can be controlled with flags set
+by this function.  The properties are identified by the following
+values for @var{name}:
+
+ at table @code
+ at item "full-status"
+Using a @var{value} of "1" the status callback set by
+gpgme_set_status_cb returns all status lines with the exception of
+PROGRESS lines.  With the default of "0" the status callback is only
+called in certain situations.
+
+ at end table
+
+This function returns @code{0} on success.
+ at end deftypefun
+
 
 @node Locale
 @subsection Locale
diff --git a/src/context.h b/src/context.h
index 757d9b4..078f0cb 100644
--- a/src/context.h
+++ b/src/context.h
@@ -101,6 +101,10 @@ struct gpgme_context
   /* True if offline mode should be used.  */
   unsigned int offline : 1;
 
+  /* True if a status callback shall be called for nearly all status
+   * lines.  */
+  unsigned int full_status : 1;
+
   /* Flags for keylist mode.  */
   gpgme_keylist_mode_t keylist_mode;
 
diff --git a/src/decrypt.c b/src/decrypt.c
index 4db68a1..51e4292 100644
--- a/src/decrypt.c
+++ b/src/decrypt.c
@@ -303,7 +303,7 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
       break;
 
     case GPGME_STATUS_INQUIRE_MAXLEN:
-      if (ctx->status_cb)
+      if (ctx->status_cb && !ctx->full_status)
         {
           err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args);
           if (err)
diff --git a/src/engine-assuan.c b/src/engine-assuan.c
index 9902467..a396006 100644
--- a/src/engine-assuan.c
+++ b/src/engine-assuan.c
@@ -752,6 +752,7 @@ struct engine_ops _gpgme_engine_ops_assuan =
     /* Member functions.  */
     llass_release,
     NULL,		/* reset */
+    NULL,               /* set_status_cb */
     NULL,               /* set_status_handler */
     NULL,		/* set_command_handler */
     NULL,               /* set_colon_line_handler */
diff --git a/src/engine-backend.h b/src/engine-backend.h
index 4f4519c..ea7db14 100644
--- a/src/engine-backend.h
+++ b/src/engine-backend.h
@@ -49,6 +49,7 @@ struct engine_ops
   /* Member functions.  */
   void (*release) (void *engine);
   gpgme_error_t (*reset) (void *engine);
+  void (*set_status_cb) (void *engine, gpgme_status_cb_t cb, void *cb_value);
   void (*set_status_handler) (void *engine, engine_status_handler_t fnc,
 			      void *fnc_value);
   gpgme_error_t (*set_command_handler) (void *engine,
diff --git a/src/engine-g13.c b/src/engine-g13.c
index 4a7b75c..8f24f4c 100644
--- a/src/engine-g13.c
+++ b/src/engine-g13.c
@@ -768,6 +768,7 @@ struct engine_ops _gpgme_engine_ops_g13 =
 #else
     NULL,			/* reset */
 #endif
+    NULL,               /* set_status_cb */
     NULL,               /* set_status_handler */
     NULL,		/* set_command_handler */
     NULL,               /* set_colon_line_handler */
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 9efced2..e507c68 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -95,6 +95,8 @@ struct engine_gpg
     int eof;
     engine_status_handler_t fnc;
     void *fnc_value;
+    gpgme_status_cb_t mon_cb;
+    void *mon_cb_value;
     void *tag;
   } status;
 
@@ -609,6 +611,17 @@ gpg_set_locale (void *engine, int category, const char *value)
   return 0;
 }
 
+/* This sets a status callback for monitoring status lines before they
+ * are passed to a caller set handler.  */
+static void
+gpg_set_status_cb (void *engine, gpgme_status_cb_t cb, void *cb_value)
+{
+  engine_gpg_t gpg = engine;
+
+  gpg->status.mon_cb = cb;
+  gpg->status.mon_cb_value = cb_value;
+}
+
 
 /* Note, that the status_handler is allowed to modifiy the args
    value.  */
@@ -1019,6 +1032,7 @@ read_status (engine_gpg_t gpg)
   size_t bufsize = gpg->status.bufsize;
   char *buffer = gpg->status.buffer;
   size_t readpos = gpg->status.readpos;
+  gpgme_error_t err;
 
   assert (buffer);
   if (bufsize - readpos < 256)
@@ -1037,15 +1051,15 @@ read_status (engine_gpg_t gpg)
 
   if (!nread)
     {
+      err = 0;
       gpg->status.eof = 1;
+      if (gpg->status.mon_cb)
+        err = gpg->status.mon_cb (gpg->status.mon_cb_value,
+                                  GPGME_STATUS_EOF, "");
       if (gpg->status.fnc)
-	{
-	  gpgme_error_t err;
-	  err = gpg->status.fnc (gpg->status.fnc_value, GPGME_STATUS_EOF, "");
-	  if (err)
-	    return err;
-	}
-      return 0;
+        err = gpg->status.fnc (gpg->status.fnc_value, GPGME_STATUS_EOF, "");
+
+      return err;
     }
 
   while (nread > 0)
@@ -1071,6 +1085,15 @@ read_status (engine_gpg_t gpg)
 		    *rest++ = 0;
 
 		  r = _gpgme_parse_status (buffer + 9);
+                  if (gpg->status.mon_cb && r != GPGME_STATUS_PROGRESS)
+                    {
+                      /* Note that we call the monitor even if we do
+                       * not know the status code (r < 0).  */
+                      err = gpg->status.mon_cb (gpg->status.mon_cb_value,
+                                                buffer + 9, rest);
+                      if (err)
+                        return err;
+                    }
 		  if (r >= 0)
 		    {
 		      if (gpg->cmd.used
@@ -1099,7 +1122,6 @@ read_status (engine_gpg_t gpg)
                         }
 		      else if (gpg->status.fnc)
 			{
-			  gpgme_error_t err;
 			  err = gpg->status.fnc (gpg->status.fnc_value,
 						 r, rest);
 			  if (err)
@@ -2470,6 +2492,7 @@ struct engine_ops _gpgme_engine_ops_gpg =
     /* Member functions.  */
     gpg_release,
     NULL,				/* reset */
+    gpg_set_status_cb,
     gpg_set_status_handler,
     gpg_set_command_handler,
     gpg_set_colon_line_handler,
diff --git a/src/engine-gpgconf.c b/src/engine-gpgconf.c
index a2407ac..bcc9522 100644
--- a/src/engine-gpgconf.c
+++ b/src/engine-gpgconf.c
@@ -934,6 +934,7 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
     /* Member functions.  */
     gpgconf_release,
     NULL,		/* reset */
+    NULL,               /* set_status_cb */
     NULL,		/* set_status_handler */
     NULL,		/* set_command_handler */
     NULL,		/* set_colon_line_handler */
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index 476e9ef..3aa9f0b 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -88,6 +88,8 @@ struct engine_gpgsm
   {
     engine_status_handler_t fnc;
     void *fnc_value;
+    gpgme_status_cb_t mon_cb;
+    void *mon_cb_value;
   } status;
 
   struct
@@ -558,10 +560,11 @@ gpgsm_set_locale (void *engine, int category, const char *value)
 
 
 static gpgme_error_t
-gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd,
+gpgsm_assuan_simple_command (engine_gpgsm_t gpgsm, char *cmd,
 			     engine_status_handler_t status_fnc,
 			     void *status_fnc_value)
 {
+  assuan_context_t ctx = gpgsm->assuan_ctx;
   gpg_error_t err, cb_err;
   char *line;
   size_t linelen;
@@ -610,8 +613,15 @@ gpgsm_assuan_simple_command (assuan_context_t ctx, char *cmd,
                 *(rest++) = 0;
 
               r = _gpgme_parse_status (line + 2);
+              if (gpgsm->status.mon_cb && r != GPGME_STATUS_PROGRESS)
+                {
+                  /* Note that we call the monitor even if we do
+                   * not know the status code (r < 0).  */
+                  cb_err = gpgsm->status.mon_cb (gpgsm->status.mon_cb_value,
+                                                 line + 2, rest);
+                }
 
-              if (r >= 0 && status_fnc)
+              if (r >= 0 && status_fnc && !cb_err)
                 cb_err = status_fnc (status_fnc_value, r, rest);
             }
 	}
@@ -726,7 +736,7 @@ gpgsm_set_fd (engine_gpgsm_t gpgsm, fd_type_t fd_type, const char *opt)
               which, iocb_data->server_fd_str);
 #endif
 
-  err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL);
+  err = gpgsm_assuan_simple_command (gpgsm, line, NULL, NULL);
 
 #if USE_DESCRIPTOR_PASSING
  leave_set_fd:
@@ -1075,8 +1085,7 @@ gpgsm_reset (void *engine)
      need to reset the list of signers.  Note that RESET does not
      reset OPTION commands. */
   return (gpgsm->assuan_ctx
-          ? gpgsm_assuan_simple_command (gpgsm->assuan_ctx, "RESET",
-                                         NULL, NULL)
+          ? gpgsm_assuan_simple_command (gpgsm, "RESET", NULL, NULL)
           : 0);
 }
 #endif
@@ -1180,7 +1189,6 @@ static gpgme_error_t
 set_recipients (engine_gpgsm_t gpgsm, gpgme_key_t recp[])
 {
   gpgme_error_t err = 0;
-  assuan_context_t ctx = gpgsm->assuan_ctx;
   char *line;
   int linelen;
   int invalid_recipients = 0;
@@ -1218,7 +1226,7 @@ set_recipients (engine_gpgsm_t gpgsm, gpgme_key_t recp[])
 	}
       strcpy (&line[10], fpr);
 
-      err = gpgsm_assuan_simple_command (ctx, line, gpgsm->status.fnc,
+      err = gpgsm_assuan_simple_command (gpgsm, line, gpgsm->status.fnc,
 					 gpgsm->status.fnc_value);
       /* FIXME: This requires more work.  */
       if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY)
@@ -1249,7 +1257,7 @@ gpgsm_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
 
   if (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO)
     {
-      err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
+      err = gpgsm_assuan_simple_command (gpgsm,
 					 "OPTION no-encrypt-to", NULL, NULL);
       if (err)
 	return err;
@@ -1472,8 +1480,7 @@ gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
       /* Fist check whether the engine already features the
          --re-import option.  */
       err = gpgsm_assuan_simple_command
-        (gpgsm->assuan_ctx,
-         "GETINFO cmd_has_option IMPORT re-import", NULL, NULL);
+        (gpgsm, "GETINFO cmd_has_option IMPORT re-import", NULL, NULL);
       if (err)
 	return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
@@ -1575,13 +1582,12 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
      available and thus there is no need for gpgsm to ask the agent
      whether a secret key exists for the public key.  */
   if (secret_only || (mode & GPGME_KEYLIST_MODE_WITH_SECRET))
-    gpgsm_assuan_simple_command (gpgsm->assuan_ctx, "GETINFO agent-check",
-                                 NULL, NULL);
+    gpgsm_assuan_simple_command (gpgsm, "GETINFO agent-check", NULL, NULL);
 
   /* Always send list-mode option because RESET does not reset it.  */
   if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
     return gpg_error_from_syserror ();
-  err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL);
+  err = gpgsm_assuan_simple_command (gpgsm, line, NULL, NULL);
   free (line);
   if (err)
     return err;
@@ -1591,24 +1597,24 @@ gpgsm_keylist (void *engine, const char *pattern, int secret_only,
 
   /* Use the validation mode if requested.  We don't check for an error
      yet because this is a pretty fresh gpgsm features. */
-  gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
+  gpgsm_assuan_simple_command (gpgsm,
                                (mode & GPGME_KEYLIST_MODE_VALIDATE)?
                                "OPTION with-validation=1":
                                "OPTION with-validation=0" ,
                                NULL, NULL);
   /* Include the ephemeral keys if requested.  We don't check for an error
      yet because this is a pretty fresh gpgsm features. */
-  gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
+  gpgsm_assuan_simple_command (gpgsm,
                                (mode & GPGME_KEYLIST_MODE_EPHEMERAL)?
                                "OPTION with-ephemeral-keys=1":
                                "OPTION with-ephemeral-keys=0" ,
                                NULL, NULL);
-  gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
+  gpgsm_assuan_simple_command (gpgsm,
                                (mode & GPGME_KEYLIST_MODE_WITH_SECRET)?
                                "OPTION with-secret=1":
                                "OPTION with-secret=0" ,
                                NULL, NULL);
-  gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
+  gpgsm_assuan_simple_command (gpgsm,
                                (engine_flags & GPGME_ENGINE_FLAG_OFFLINE)?
                                "OPTION offline=1":
                                "OPTION offline=0" ,
@@ -1665,7 +1671,7 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
   /* Always send list-mode option because RESET does not reset it.  */
   if (asprintf (&line, "OPTION list-mode=%d", (list_mode & 3)) < 0)
     return gpg_error_from_syserror ();
-  err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, line, NULL, NULL);
+  err = gpgsm_assuan_simple_command (gpgsm, line, NULL, NULL);
   free (line);
   if (err)
     return err;
@@ -1673,17 +1679,17 @@ gpgsm_keylist_ext (void *engine, const char *pattern[], int secret_only,
   /* Always send key validation because RESET does not reset it.  */
   /* Use the validation mode if required.  We don't check for an error
      yet because this is a pretty fresh gpgsm features. */
-  gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
+  gpgsm_assuan_simple_command (gpgsm,
                                (mode & GPGME_KEYLIST_MODE_VALIDATE)?
                                "OPTION with-validation=1":
                                "OPTION with-validation=0" ,
                                NULL, NULL);
-  gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
+  gpgsm_assuan_simple_command (gpgsm,
                                (mode & GPGME_KEYLIST_MODE_WITH_SECRET)?
                                "OPTION with-secret=1":
                                "OPTION with-secret=0" ,
                                NULL, NULL);
-  gpgsm_assuan_simple_command (gpgsm->assuan_ctx,
+  gpgsm_assuan_simple_command (gpgsm,
                                (engine_flags & GPGME_ENGINE_FLAG_OFFLINE)?
                                "OPTION offline=1":
                                "OPTION offline=0" ,
@@ -1797,8 +1803,7 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
 
       if (asprintf (&assuan_cmd, "OPTION include-certs %i", include_certs) < 0)
 	return gpg_error_from_syserror ();
-      err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, assuan_cmd,
-                                         NULL, NULL);
+      err = gpgsm_assuan_simple_command (gpgsm, assuan_cmd, NULL, NULL);
       free (assuan_cmd);
       if (err)
 	return err;
@@ -1812,7 +1817,7 @@ gpgsm_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
           char buf[100];
 
           strcpy (stpcpy (buf, "SIGNER "), s);
-          err = gpgsm_assuan_simple_command (gpgsm->assuan_ctx, buf,
+          err = gpgsm_assuan_simple_command (gpgsm, buf,
                                              gpgsm->status.fnc,
                                              gpgsm->status.fnc_value);
 	}
@@ -1913,6 +1918,17 @@ gpgsm_getauditlog (void *engine, gpgme_data_t output, unsigned int flags)
 }
 
 
+/* This sets a status callback for monitoring status lines before they
+ * are passed to a caller set handler.  */
+static void
+gpgsm_set_status_cb (void *engine, gpgme_status_cb_t cb, void *cb_value)
+{
+  engine_gpgsm_t gpgsm = engine;
+
+  gpgsm->status.mon_cb = cb;
+  gpgsm->status.mon_cb_value = cb_value;
+}
+
 
 static void
 gpgsm_set_status_handler (void *engine, engine_status_handler_t fnc,
@@ -2001,6 +2017,7 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
 #else
     NULL,			/* reset */
 #endif
+    gpgsm_set_status_cb,
     gpgsm_set_status_handler,
     NULL,		/* set_command_handler */
     gpgsm_set_colon_line_handler,
diff --git a/src/engine-spawn.c b/src/engine-spawn.c
index eb4e038..3674efb 100644
--- a/src/engine-spawn.c
+++ b/src/engine-spawn.c
@@ -440,6 +440,7 @@ struct engine_ops _gpgme_engine_ops_spawn =
     /* Member functions.  */
     engspawn_release,
     NULL,		/* reset */
+    NULL,               /* set_status_cb */
     NULL,		/* set_status_handler */
     NULL,		/* set_command_handler */
     NULL,		/* set_colon_line_handler */
diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c
index e4fd47c..d05ade6 100644
--- a/src/engine-uiserver.c
+++ b/src/engine-uiserver.c
@@ -90,6 +90,8 @@ struct engine_uiserver
   {
     engine_status_handler_t fnc;
     void *fnc_value;
+    gpgme_status_cb_t mon_cb;
+    void *mon_cb_value;
   } status;
 
   struct
@@ -451,10 +453,11 @@ uiserver_set_protocol (void *engine, gpgme_protocol_t protocol)
 
 
 static gpgme_error_t
-uiserver_assuan_simple_command (assuan_context_t ctx, char *cmd,
-			     engine_status_handler_t status_fnc,
-			     void *status_fnc_value)
+uiserver_assuan_simple_command (engine_uiserver_t uiserver, char *cmd,
+                                engine_status_handler_t status_fnc,
+                                void *status_fnc_value)
 {
+  assuan_context_t ctx = uiserver->assuan_ctx;
   gpg_error_t err;
   char *line;
   size_t linelen;
@@ -493,8 +496,17 @@ uiserver_assuan_simple_command (assuan_context_t ctx, char *cmd,
 	    *(rest++) = 0;
 
 	  r = _gpgme_parse_status (line + 2);
+          if (uiserver->status.mon_cb && r != GPGME_STATUS_PROGRESS)
+            {
+              /* Note that we call the monitor even if we do
+               * not know the status code (r < 0).  */
+              err = uiserver->status.mon_cb (uiserver->status.mon_cb_value,
+                                             line + 2, rest);
+            }
 
-	  if (r >= 0 && status_fnc)
+          if (err)
+            ;
+	  else if (r >= 0 && status_fnc)
 	    err = status_fnc (status_fnc_value, r, rest);
 	  else
 	    err = gpg_error (GPG_ERR_GENERAL);
@@ -576,7 +588,7 @@ uiserver_set_fd (engine_uiserver_t uiserver, fd_type_t fd_type, const char *opt)
   else
     snprintf (line, COMMANDLINELEN, "%s FD", which);
 
-  err = uiserver_assuan_simple_command (uiserver->assuan_ctx, line, NULL, NULL);
+  err = uiserver_assuan_simple_command (uiserver, line, NULL, NULL);
 
  leave_set_fd:
   if (err)
@@ -915,7 +927,7 @@ uiserver_reset (void *engine)
 
   /* We must send a reset because we need to reset the list of
      signers.  Note that RESET does not reset OPTION commands. */
-  return uiserver_assuan_simple_command (uiserver->assuan_ctx, "RESET", NULL, NULL);
+  return uiserver_assuan_simple_command (uiserver, "RESET", NULL, NULL);
 }
 
 
@@ -984,7 +996,6 @@ static gpgme_error_t
 set_recipients (engine_uiserver_t uiserver, gpgme_key_t recp[])
 {
   gpgme_error_t err = 0;
-  assuan_context_t ctx = uiserver->assuan_ctx;
   char *line;
   int linelen;
   int invalid_recipients = 0;
@@ -1023,7 +1034,8 @@ set_recipients (engine_uiserver_t uiserver, gpgme_key_t recp[])
       /* FIXME: need to do proper escaping  */
       strcpy (&line[10], uid);
 
-      err = uiserver_assuan_simple_command (ctx, line, uiserver->status.fnc,
+      err = uiserver_assuan_simple_command (uiserver, line,
+                                            uiserver->status.fnc,
                                             uiserver->status.fnc_value);
       /* FIXME: This might requires more work.  */
       if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY)
@@ -1160,7 +1172,7 @@ uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
           char buf[100];
 
           strcpy (stpcpy (buf, "SENDER --info "), s);
-          err = uiserver_assuan_simple_command (uiserver->assuan_ctx, buf,
+          err = uiserver_assuan_simple_command (uiserver, buf,
                                                 uiserver->status.fnc,
                                                 uiserver->status.fnc_value);
         }
@@ -1252,6 +1264,18 @@ uiserver_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
 }
 
 
+/* This sets a status callback for monitoring status lines before they
+ * are passed to a caller set handler.  */
+static void
+uiserver_set_status_cb (void *engine, gpgme_status_cb_t cb, void *cb_value)
+{
+  engine_uiserver_t uiserver = engine;
+
+  uiserver->status.mon_cb = cb;
+  uiserver->status.mon_cb_value = cb_value;
+}
+
+
 static void
 uiserver_set_status_handler (void *engine, engine_status_handler_t fnc,
 			  void *fnc_value)
@@ -1309,6 +1333,7 @@ struct engine_ops _gpgme_engine_ops_uiserver =
     /* Member functions.  */
     uiserver_release,
     uiserver_reset,
+    uiserver_set_status_cb,
     uiserver_set_status_handler,
     NULL,		/* set_command_handler */
     uiserver_set_colon_line_handler,
diff --git a/src/engine.c b/src/engine.c
index 8e84da9..c9449db 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -503,6 +503,21 @@ _gpgme_engine_release (engine_t engine)
 }
 
 
+/* Set a status callback which is used to monitor the status values
+ * before they are passed to a handler set with
+ * _gpgme_engine_set_status_handler.  */
+void
+_gpgme_engine_set_status_cb (engine_t engine,
+                             gpgme_status_cb_t cb, void *cb_value)
+{
+  if (!engine)
+    return;
+
+  if (engine->ops->set_status_cb)
+    (*engine->ops->set_status_cb) (engine->engine, cb, cb_value);
+}
+
+
 void
 _gpgme_engine_set_status_handler (engine_t engine,
 				  engine_status_handler_t fnc, void *fnc_value)
diff --git a/src/engine.h b/src/engine.h
index 56fcc42..238a21c 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -62,6 +62,8 @@ gpgme_error_t _gpgme_engine_set_locale (engine_t engine, int category,
 gpgme_error_t _gpgme_engine_set_protocol (engine_t engine,
 					  gpgme_protocol_t protocol);
 void _gpgme_engine_release (engine_t engine);
+void _gpgme_engine_set_status_cb (engine_t engine,
+                                  gpgme_status_cb_t cb, void *cb_value);
 void _gpgme_engine_set_status_handler (engine_t engine,
 				       engine_status_handler_t fnc,
 				       void *fnc_value);
diff --git a/src/genkey.c b/src/genkey.c
index 3afd3b4..34cc5af 100644
--- a/src/genkey.c
+++ b/src/genkey.c
@@ -134,7 +134,7 @@ genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)
       break;
 
     case GPGME_STATUS_INQUIRE_MAXLEN:
-      if (ctx->status_cb)
+      if (ctx->status_cb && !ctx->full_status)
         {
           err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args);
           if (err)
diff --git a/src/gpgme.c b/src/gpgme.c
index 0b42ea1..3289be9 100644
--- a/src/gpgme.c
+++ b/src/gpgme.c
@@ -82,6 +82,30 @@ gpgme_set_global_flag (const char *name, const char *value)
 }
 
 
+/* Set the flag NAME for CTX to VALUE.  The supported flags are:
+ *
+ * - full-status :: With a value of "1" the status callback set by
+ *                  gpgme_set_status_cb returns all status lines
+ *                  except for PROGRESS lines.  With the default of
+ *                  "0" the status callback is only called in certain
+ *                  situations.
+ */
+gpgme_error_t
+gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
+{
+  if (!ctx || !name || !value)
+    return gpg_error (GPG_ERR_INV_VALUE);
+  else if (!strcmp (name, "full-status"))
+    {
+      ctx->full_status = *value? !!atoi (value) : 0;
+    }
+  else
+    return gpg_error (GPG_ERR_UNKNOWN_NAME);
+
+  return 0;
+}
+
+
 

 /* Create a new context as an environment for GPGME crypto
    operations.  */
diff --git a/src/gpgme.def b/src/gpgme.def
index 3b56aaa..dfdb6c6 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -225,5 +225,6 @@ EXPORTS
     gpgme_get_status_cb                   @168
 
     gpgme_pubkey_algo_string              @169
+    gpgme_set_ctx_flag                    @170
 ; END
 
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 7a58ded..5f7896d 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -911,6 +911,10 @@ gpgme_error_t gpgme_new (gpgme_ctx_t *ctx);
 /* Release the context CTX.  */
 void gpgme_release (gpgme_ctx_t ctx);
 
+/* Set the flag NAME for CTX to VALUE.  */
+gpgme_error_t gpgme_set_ctx_flag (gpgme_ctx_t ctx,
+                                  const char *name, const char *value);
+
 /* Set the protocol to be used by CTX to PROTO.  */
 gpgme_error_t gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t proto);
 
@@ -993,7 +997,7 @@ void gpgme_get_progress_cb (gpgme_ctx_t ctx, gpgme_progress_cb_t *cb,
 			    void **hook_value);
 
 /* Set the status callback function in CTX to CB.  HOOK_VALUE is
-   passed as first argument to thes status callback function.  */
+   passed as first argument to the status callback function.  */
 void gpgme_set_status_cb (gpgme_ctx_t c, gpgme_status_cb_t cb,
                           void *hook_value);
 
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index c677190..873cb19 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -100,6 +100,7 @@ GPGME_1.1 {
     gpgme_get_status_cb;
 
     gpgme_pubkey_algo_string;
+    gpgme_set_ctx_flag;
 };
 
 
diff --git a/src/op-support.c b/src/op-support.c
index 4e388a4..a74405e 100644
--- a/src/op-support.c
+++ b/src/op-support.c
@@ -148,6 +148,12 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
             err = 0;
         }
 
+      if (!err && ctx->status_cb && ctx->full_status)
+        {
+          _gpgme_engine_set_status_cb (ctx->engine,
+                                       ctx->status_cb, ctx->status_cb_value);
+        }
+
       if (err)
         {
           _gpgme_engine_release (ctx->engine);
diff --git a/src/passphrase.c b/src/passphrase.c
index c88e57d..74d235c 100644
--- a/src/passphrase.c
+++ b/src/passphrase.c
@@ -118,9 +118,8 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code,
 
     case GPGME_STATUS_ERROR:
       /* We abuse this status handler to forward ERROR status codes to
-         the caller.  This should better be done in a generic handler,
-         but for now this is sufficient.  */
-      if (ctx->status_cb)
+         the caller.  */
+      if (ctx->status_cb && !ctx->full_status)
         {
           err = ctx->status_cb (ctx->status_cb_value, "ERROR", args);
           if (err)
@@ -130,9 +129,8 @@ _gpgme_passphrase_status_handler (void *priv, gpgme_status_code_t code,
 
     case GPGME_STATUS_FAILURE:
       /* We abuse this status handler to forward FAILURE status codes
-         to the caller.  This should better be done in a generic
-         handler, but for now this is sufficient.  */
-      if (ctx->status_cb)
+         to the caller.  */
+      if (ctx->status_cb && !ctx->full_status)
         {
           err = ctx->status_cb (ctx->status_cb_value, "FAILURE", args);
           if (err)
@@ -173,6 +171,7 @@ _gpgme_passphrase_command_handler (void *priv, gpgme_status_code_t code,
       if (processed)
 	*processed = 1;
 
+      /* Fake a status line to to convey the MAXLEN info.  */
       if (ctx->status_cb && opd->maxlen)
         err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN",
                               opd->maxlen);
diff --git a/src/sign.c b/src/sign.c
index d8650a9..bfd9ad1 100644
--- a/src/sign.c
+++ b/src/sign.c
@@ -369,7 +369,7 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
       break;
 
     case GPGME_STATUS_INQUIRE_MAXLEN:
-      if (ctx->status_cb)
+      if (ctx->status_cb && !ctx->full_status)
         err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args);
       break;
 
diff --git a/tests/run-verify.c b/tests/run-verify.c
index b49ea2a..b7be320 100644
--- a/tests/run-verify.c
+++ b/tests/run-verify.c
@@ -36,6 +36,15 @@
 
 static int verbose;
 
+static gpg_error_t
+status_cb (void *opaque, const char *keyword, const char *value)
+{
+  (void)opaque;
+  fprintf (stderr, "status_cb: %s %s\n", keyword, value);
+  return 0;
+}
+
+
 static void
 print_summary (gpgme_sigsum_t summary)
 {
@@ -102,8 +111,10 @@ print_result (gpgme_verify_result_t result)
       printf ("  validity ..: ");
       print_validity (sig->validity); putchar ('\n');
       printf ("  val.reason : %s\n", gpgme_strerror (sig->status));
-      printf ("  pubkey algo: %d\n", sig->pubkey_algo);
-      printf ("  digest algo: %d\n", sig->hash_algo);
+      printf ("  pubkey algo: %d (%s)\n", sig->pubkey_algo,
+              nonnull(gpgme_pubkey_algo_name (sig->pubkey_algo)));
+      printf ("  digest algo: %d (%s)\n", sig->hash_algo,
+              nonnull(gpgme_hash_algo_name (sig->hash_algo)));
       printf ("  pka address: %s\n", nonnull (sig->pka_address));
       printf ("  pka trust .: %s\n",
               sig->pka_trust == 0? "n/a" :
@@ -126,6 +137,7 @@ show_usage (int ex)
   fputs ("usage: " PGM " [options] [DETACHEDSIGFILE] FILE\n\n"
          "Options:\n"
          "  --verbose        run in verbose mode\n"
+         "  --status         print status lines from the backend\n"
          "  --openpgp        use the OpenPGP protocol (default)\n"
          "  --cms            use the CMS protocol\n"
          , stderr);
@@ -145,6 +157,7 @@ main (int argc, char **argv)
   FILE *fp_msg = NULL;
   gpgme_data_t msg = NULL;
   gpgme_verify_result_t result;
+  int print_status = 0;
 
   if (argc)
     { argc--; argv++; }
@@ -164,6 +177,11 @@ main (int argc, char **argv)
           verbose = 1;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--status"))
+        {
+          print_status = 1;
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--openpgp"))
         {
           protocol = GPGME_PROTOCOL_OpenPGP;
@@ -207,6 +225,11 @@ main (int argc, char **argv)
   err = gpgme_new (&ctx);
   fail_if_err (err);
   gpgme_set_protocol (ctx, protocol);
+  if (print_status)
+    {
+      gpgme_set_status_cb (ctx, status_cb, NULL);
+      gpgme_set_ctx_flag (ctx, "full-status", "1");
+    }
 
   err = gpgme_data_new_from_stream (&sig, fp_sig);
   if (err)
@@ -232,7 +255,7 @@ main (int argc, char **argv)
     print_result (result);
   if (err)
     {
-      fprintf (stderr, PGM ": signing failed: %s\n", gpgme_strerror (err));
+      fprintf (stderr, PGM ": verify failed: %s\n", gpgme_strerror (err));
       exit (1);
     }
 

commit 5aa8e588e166abeef2e3d677ab6830f2d7af1b5d
Author: Werner Koch <wk at gnupg.org>
Date:   Thu May 19 14:26:22 2016 +0200

    api: Remove arbitrary restriction from gpgme_op_verify.
    
    * src/verify.c (verify_start): Do not return GPG_ERR_INV_VALUES when
    when SIGNED_TEXT is not given.
    --
    
    The original idea behind this restriction probably was that it is
    useless to verify a non-detached signatures without also returning the
    signed text.  However, it is sometimes useful to just check the
    signature, for example to see who signed it.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/src/verify.c b/src/verify.c
index 75914e2..4781d99 100644
--- a/src/verify.c
+++ b/src/verify.c
@@ -861,8 +861,6 @@ verify_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t sig,
 
   if (!sig)
     return gpg_error (GPG_ERR_NO_DATA);
-  if (!signed_text && !plaintext)
-    return gpg_error (GPG_ERR_INV_VALUE);
 
   return _gpgme_engine_op_verify (ctx->engine, sig, signed_text, plaintext);
 }

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

Summary of changes:
 NEWS                  |  1 +
 doc/gpgme.texi        | 21 +++++++++++++++++
 src/context.h         |  4 ++++
 src/decrypt.c         |  2 +-
 src/engine-assuan.c   |  1 +
 src/engine-backend.h  |  1 +
 src/engine-g13.c      |  1 +
 src/engine-gpg.c      | 39 ++++++++++++++++++++++++-------
 src/engine-gpgconf.c  |  1 +
 src/engine-gpgsm.c    | 65 ++++++++++++++++++++++++++++++++-------------------
 src/engine-spawn.c    |  1 +
 src/engine-uiserver.c | 43 +++++++++++++++++++++++++++-------
 src/engine.c          | 15 ++++++++++++
 src/engine.h          |  2 ++
 src/genkey.c          |  2 +-
 src/gpgme.c           | 24 +++++++++++++++++++
 src/gpgme.def         |  1 +
 src/gpgme.h.in        |  6 ++++-
 src/libgpgme.vers     |  1 +
 src/op-support.c      |  6 +++++
 src/passphrase.c      | 11 ++++-----
 src/sign.c            |  2 +-
 src/verify.c          |  2 --
 tests/run-verify.c    | 29 ++++++++++++++++++++---
 24 files changed, 225 insertions(+), 56 deletions(-)


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




More information about the Gnupg-commits mailing list