diff options
| author | Werner Koch <[email protected]> | 2016-05-19 15:01:07 +0000 | 
|---|---|---|
| committer | Werner Koch <[email protected]> | 2016-05-19 15:04:54 +0000 | 
| commit | 88f2c1c0d16eee6bb36a901623ea65ac69499f03 (patch) | |
| tree | 4ac0d8ab84bee699987f61e277e8c4d80e857850 /src | |
| parent | api: Remove arbitrary restriction from gpgme_op_verify. (diff) | |
| download | gpgme-88f2c1c0d16eee6bb36a901623ea65ac69499f03.tar.gz gpgme-88f2c1c0d16eee6bb36a901623ea65ac69499f03.zip | |
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 <[email protected]>
Diffstat (limited to '')
| -rw-r--r-- | src/context.h | 4 | ||||
| -rw-r--r-- | src/decrypt.c | 2 | ||||
| -rw-r--r-- | src/engine-assuan.c | 1 | ||||
| -rw-r--r-- | src/engine-backend.h | 1 | ||||
| -rw-r--r-- | src/engine-g13.c | 1 | ||||
| -rw-r--r-- | src/engine-gpg.c | 39 | ||||
| -rw-r--r-- | src/engine-gpgconf.c | 1 | ||||
| -rw-r--r-- | src/engine-gpgsm.c | 65 | ||||
| -rw-r--r-- | src/engine-spawn.c | 1 | ||||
| -rw-r--r-- | src/engine-uiserver.c | 43 | ||||
| -rw-r--r-- | src/engine.c | 15 | ||||
| -rw-r--r-- | src/engine.h | 2 | ||||
| -rw-r--r-- | src/genkey.c | 2 | ||||
| -rw-r--r-- | src/gpgme.c | 24 | ||||
| -rw-r--r-- | src/gpgme.def | 1 | ||||
| -rw-r--r-- | src/gpgme.h.in | 6 | ||||
| -rw-r--r-- | src/libgpgme.vers | 1 | ||||
| -rw-r--r-- | src/op-support.c | 6 | ||||
| -rw-r--r-- | src/passphrase.c | 11 | ||||
| -rw-r--r-- | src/sign.c | 2 | 
20 files changed, 177 insertions, 51 deletions
| diff --git a/src/context.h b/src/context.h index 757d9b42..078f0cbd 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 4db68a10..51e42920 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 99024675..a3960067 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 4f4519c0..ea7db144 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 4a7b75c5..8f24f4c2 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 9efced25..e507c683 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 a2407ac7..bcc95225 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 476e9ef3..3aa9f0bf 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 eb4e0385..3674efb2 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 e4fd47c3..d05ade61 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 8e84da95..c9449db1 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 56fcc420..238a21c0 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 3afd3b41..34cc5af4 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 0b42ea19..3289be9d 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 3b56aaad..dfdb6c66 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 7a58dedd..5f7896de 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 c677190f..873cb190 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 4e388a41..a74405ef 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 c88e57d2..74d235cb 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); @@ -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; | 
