From f3ca57dfd7af19f9b2fd01616a81dc889707a4d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ingo=20Kl=C3=B6cker?= Date: Wed, 4 May 2022 14:23:42 +0200 Subject: [PATCH] core: Handle import status lines during keylist operation * src/import.c (import_status_handler): Rename to ... (_gpgme_import_status_handler): this. Make non-static. (_gpgme_op_import_init_result): New. (_gpgme_op_import_start, _gpgme_op_import_keys_start, _gpgme_op_receive_keys_start): Call _gpgme_op_import_init_result. * src/keylist.c (keylist_status_handler): Call _gpgme_import_status_handler to handle import status lines. (gpgme_op_keylist_start, gpgme_op_keylist_ext_start): Call _gpgme_op_import_init_result. * src/ops.h (_gpgme_op_import_init_result, _gpgme_import_status_handler): New prototypes. -- If a keylist operation with keylist mode GPGME_KEYLIST_MODE_LOCATE is run, then gpg emits import status lines. Handling those status lines allows users to retrieve the result of a --locate-(external)-keys command. GnuPG-bug-id: 5951 --- src/import.c | 52 ++++++++++++++++++++++++++++----------------------- src/keylist.c | 14 ++++++++++++++ src/ops.h | 12 ++++++++++++ 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/src/import.c b/src/import.c index 85c459b1..cd9f960f 100644 --- a/src/import.c +++ b/src/import.c @@ -266,8 +266,8 @@ parse_error (char *args, gpgme_import_status_t *import_status) } -static gpgme_error_t -import_status_handler (void *priv, gpgme_status_code_t code, char *args) +gpgme_error_t +_gpgme_import_status_handler (void *priv, gpgme_status_code_t code, char *args) { gpgme_ctx_t ctx = (gpgme_ctx_t) priv; gpgme_error_t err; @@ -311,28 +311,42 @@ import_status_handler (void *priv, gpgme_status_code_t code, char *args) } -static gpgme_error_t -_gpgme_op_import_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t keydata) +gpgme_error_t +_gpgme_op_import_init_result (gpgme_ctx_t ctx) { gpgme_error_t err; void *hook; op_data_t opd; - err = _gpgme_op_reset (ctx, synchronous); - if (err) - return err; - err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook, sizeof (*opd), release_op_data); opd = hook; if (err) return err; + opd->lastp = &opd->result.imports; + return 0; +} + + +static gpgme_error_t +_gpgme_op_import_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t keydata) +{ + gpgme_error_t err; + + err = _gpgme_op_reset (ctx, synchronous); + if (err) + return err; + + err = _gpgme_op_import_init_result (ctx); + if (err) + return err; if (!keydata) return gpg_error (GPG_ERR_NO_DATA); - _gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx); + _gpgme_engine_set_status_handler (ctx->engine, _gpgme_import_status_handler, + ctx); return _gpgme_engine_op_import (ctx->engine, keydata, NULL, NULL, ctx->import_filter, ctx->key_origin); @@ -380,20 +394,15 @@ _gpgme_op_import_keys_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t *keys) { gpgme_error_t err; - void *hook; - op_data_t opd; int idx, firstidx, nkeys; err = _gpgme_op_reset (ctx, synchronous); if (err) return err; - err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook, - sizeof (*opd), release_op_data); - opd = hook; + err = _gpgme_op_import_init_result (ctx); if (err) return err; - opd->lastp = &opd->result.imports; if (!keys) return gpg_error (GPG_ERR_NO_DATA); @@ -416,7 +425,8 @@ _gpgme_op_import_keys_start (gpgme_ctx_t ctx, int synchronous, if (!nkeys) return gpg_error (GPG_ERR_NO_DATA); - _gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx); + _gpgme_engine_set_status_handler (ctx->engine, _gpgme_import_status_handler, + ctx); return _gpgme_engine_op_import (ctx->engine, NULL, keys, NULL, ctx->import_filter, ctx->key_origin); @@ -496,24 +506,20 @@ static gpgme_error_t _gpgme_op_receive_keys_start (gpgme_ctx_t ctx, int synchronous, const char *keyids[]) { gpgme_error_t err; - void *hook; - op_data_t opd; err = _gpgme_op_reset (ctx, synchronous); if (err) return err; - err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook, - sizeof (*opd), release_op_data); - opd = hook; + err = _gpgme_op_import_init_result (ctx); if (err) return err; - opd->lastp = &opd->result.imports; if (!keyids || !*keyids) return gpg_error (GPG_ERR_NO_DATA); - _gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx); + _gpgme_engine_set_status_handler (ctx->engine, _gpgme_import_status_handler, + ctx); return _gpgme_engine_op_import (ctx->engine, NULL, NULL, keyids, ctx->import_filter, ctx->key_origin); diff --git a/src/keylist.c b/src/keylist.c index 883d6257..05267e6c 100644 --- a/src/keylist.c +++ b/src/keylist.c @@ -146,6 +146,12 @@ keylist_status_handler (void *priv, gpgme_status_code_t code, char *args) err = 0; break; + case GPGME_STATUS_IMPORT_OK: + case GPGME_STATUS_IMPORT_PROBLEM: + case GPGME_STATUS_IMPORT_RES: + err = _gpgme_import_status_handler (priv, code, args); + break; + default: break; } @@ -1125,6 +1131,10 @@ gpgme_op_keylist_start (gpgme_ctx_t ctx, const char *pattern, int secret_only) if (err) return TRACE_ERR (err); + err = _gpgme_op_import_init_result (ctx); + if (err) + return TRACE_ERR (err); + _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx); err = _gpgme_engine_set_colon_line_handler (ctx->engine, @@ -1169,6 +1179,10 @@ gpgme_op_keylist_ext_start (gpgme_ctx_t ctx, const char *pattern[], if (err) return TRACE_ERR (err); + err = _gpgme_op_import_init_result (ctx); + if (err) + return TRACE_ERR (err); + _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx); err = _gpgme_engine_set_colon_line_handler (ctx->engine, keylist_colon_handler, ctx); diff --git a/src/ops.h b/src/ops.h index 3b9728dd..cde63a4e 100644 --- a/src/ops.h +++ b/src/ops.h @@ -192,4 +192,16 @@ gpgme_error_t _gpgme_parse_notation (gpgme_sig_notation_t *notationp, int type, int pkflags, int len, char *data); + +/* From import.c. */ + +/* Create an initial op data object for import. Needs to be called + once before calling _gpgme_import_status_handler. */ +gpgme_error_t _gpgme_op_import_init_result (gpgme_ctx_t ctx); + +/* Process a status line for import operations. */ +gpgme_error_t _gpgme_import_status_handler (void *priv, + gpgme_status_code_t code, + char *args); + #endif /* OPS_H */