gpgconf: Add access to --list-dirs for non-default engine.

* src/engine-assuan.c (_gpgme_engine_ops_assuan): Add conf_dir.
* src/engine-g13.c (_gpgme_engine_ops_g13): Likewise.
* src/engine-gpg.c (_gpgme_engine_ops_gpg): Likewise.
* src/engine-gpgsm.c (_gpgme_engine_ops_gpgsm): Likewise.
* src/engine-spawn.c (_gpgme_engine_ops_spawn): Likewise.
* src/engine-uiserver.c (_gpgme_engine_ops_uiserver): Likewise.
* src/engine-backend.h (struct engine_ops): Likewise.
* src/engine-gpgconf.c (gpgconf_config_dir_cb, gpgconf_conf_dir):
New functions.
(struct engine_ops): Add gpgconf_conf_dir.
* src/engine.c (_gpgme_engine_op_conf_dir): New function.
* src/engine.h (_gpgme_engine_op_conf_dir): New prototype.
* src/gpgconf.c (gpgme_op_conf_dir): New function.
* src/gpgme.def (gpgme_op_conf_save): New symbol.
* src/gpgme.h.in (gpgme_op_conf_dir): New prototype.
* src/libgpgme.vers (gpgme_op_conf_dir): New symbol.
* tests/gpg/t-gpgconf.c (main): Test gpgme_op_conf_dir.

Signed-off-by: Marcus Brinkmann <mb@g10code.com>
GnuPG-bug-id: 3018
This commit is contained in:
Marcus Brinkmann 2017-08-15 19:40:12 +02:00
parent a0cc6e01a8
commit 9f24e6c901
15 changed files with 111 additions and 0 deletions

View File

@ -796,6 +796,7 @@ struct engine_ops _gpgme_engine_ops_assuan =
llass_transact, /* opassuan_transact */
NULL, /* conf_load */
NULL, /* conf_save */
NULL, /* conf_dir */
NULL, /* query_swdb */
llass_set_io_cbs,
llass_io_event,

View File

@ -128,6 +128,7 @@ struct engine_ops
gpgme_error_t (*conf_load) (void *engine, gpgme_conf_comp_t *conf_p);
gpgme_error_t (*conf_save) (void *engine, gpgme_conf_comp_t conf);
gpgme_error_t (*conf_dir) (void *engine, const char *what, char **result);
gpgme_error_t (*query_swdb) (void *engine,
const char *name, const char *iversion,

View File

@ -811,6 +811,7 @@ struct engine_ops _gpgme_engine_ops_g13 =
g13_transact,
NULL, /* conf_load */
NULL, /* conf_save */
NULL, /* conf_dir */
NULL, /* query_swdb */
g13_set_io_cbs,
g13_io_event,

View File

@ -3093,6 +3093,7 @@ struct engine_ops _gpgme_engine_ops_gpg =
NULL, /* opassuan_transact */
NULL, /* conf_load */
NULL, /* conf_save */
NULL, /* conf_dir */
NULL, /* query_swdb */
gpg_set_io_cbs,
gpg_io_event,

View File

@ -986,6 +986,48 @@ gpgconf_conf_save (void *engine, gpgme_conf_comp_t comp)
}
static gpgme_error_t
gpgconf_config_dir_cb (void *hook, char *line)
{
/* This is an input- and output-parameter. */
char **str_p = (char **) hook;
char *what = *str_p;
int len = strlen(what);
if (!strncmp(line, what, len) && line[len] == ':')
{
char *result = strdup(&line[len + 1]);
if (!result)
return gpg_error_from_syserror ();
*str_p = result;
return gpg_error(GPG_ERR_USER_1);
}
return 0;
}
static gpgme_error_t
gpgconf_conf_dir (void *engine, const char *what, char **result)
{
gpgme_error_t err;
char *res = what;
*result = NULL;
err = gpgconf_read (engine, "--list-dirs", NULL,
gpgconf_config_dir_cb, &res);
if (gpg_err_code (err) == GPG_ERR_USER_1)
{
/* This signals to use that a result was found. */
*result = res;
return 0;
}
if (!err)
err = gpg_error(GPG_ERR_NOT_FOUND);
return 0;
}
/* Parse a line received from gpgconf --query-swdb. This function may
* modify LINE. The result is stored at RESUL. */
static gpg_error_t
@ -1254,6 +1296,7 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
NULL, /* opassuan_transact */
gpgconf_conf_load,
gpgconf_conf_save,
gpgconf_conf_dir,
gpgconf_query_swdb,
gpgconf_set_io_cbs,
NULL, /* io_event */

View File

@ -2119,6 +2119,7 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
NULL, /* opassuan_transact */
NULL, /* conf_load */
NULL, /* conf_save */
NULL, /* conf_dir */
NULL, /* query_swdb */
gpgsm_set_io_cbs,
gpgsm_io_event,

View File

@ -469,6 +469,7 @@ struct engine_ops _gpgme_engine_ops_spawn =
NULL, /* opassuan_transact */
NULL, /* conf_load */
NULL, /* conf_save */
NULL, /* conf_dir */
NULL, /* query_swdb */
engspawn_set_io_cbs,
engspawn_io_event, /* io_event */

View File

@ -1386,6 +1386,7 @@ struct engine_ops _gpgme_engine_ops_uiserver =
NULL, /* opassuan_transact */
NULL, /* conf_load */
NULL, /* conf_save */
NULL, /* conf_dir */
NULL, /* query_swdb */
uiserver_set_io_cbs,
uiserver_io_event,

View File

@ -983,6 +983,19 @@ _gpgme_engine_op_conf_save (engine_t engine, gpgme_conf_comp_t conf)
}
gpgme_error_t
_gpgme_engine_op_conf_dir (engine_t engine, const char *what, char **result)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
if (!engine->ops->conf_dir)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->conf_dir) (engine->engine, what, result);
}
gpgme_error_t
_gpgme_engine_op_query_swdb (engine_t engine,
const char *name, const char *iversion,

View File

@ -176,6 +176,9 @@ gpgme_error_t _gpgme_engine_op_conf_load (engine_t engine,
gpgme_conf_comp_t *conf_p);
gpgme_error_t _gpgme_engine_op_conf_save (engine_t engine,
gpgme_conf_comp_t conf);
gpgme_error_t _gpgme_engine_op_conf_dir (engine_t engine,
const char *what,
char **result);
gpgme_error_t _gpgme_engine_op_query_swdb (engine_t engine,
const char *name,

View File

@ -108,3 +108,24 @@ gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp)
ctx->protocol = proto;
return err;
}
gpgme_error_t
gpgme_op_conf_dir (gpgme_ctx_t ctx, const char *what, char **result)
{
gpgme_error_t err;
gpgme_protocol_t proto;
if (!ctx)
return gpg_error (GPG_ERR_INV_VALUE);
proto = ctx->protocol;
ctx->protocol = GPGME_PROTOCOL_GPGCONF;
err = _gpgme_op_reset (ctx, 1);
if (err)
return err;
err = _gpgme_engine_op_conf_dir (ctx->engine, what, result);
ctx->protocol = proto;
return err;
}

View File

@ -265,5 +265,7 @@ EXPORTS
gpgme_op_delete_ext @197
gpgme_op_delete_ext_start @198
gpgme_op_conf_save @199
; END

View File

@ -2240,6 +2240,10 @@ gpgme_error_t gpgme_op_conf_load (gpgme_ctx_t ctx, gpgme_conf_comp_t *conf_p);
follow chained components! */
gpgme_error_t gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp);
/* Retrieve the configured directory. */
gpgme_error_t gpgme_op_conf_dir(gpgme_ctx_t ctx, const char *what,
char **result);
/* Information about software versions.
* This structure shall be considered read-only and an application

View File

@ -46,6 +46,7 @@ GPGME_1.1 {
gpgme_conf_opt_change;
gpgme_op_conf_load;
gpgme_op_conf_save;
gpgme_op_conf_dir;
gpgme_cancel_async;

View File

@ -263,6 +263,23 @@ main (void)
err = gpgme_new (&ctx);
fail_if_err (err);
/* Let's check getting the agent-socket directory for different homedirs. */
char *result1 = NULL;
err = gpgme_ctx_set_engine_info (ctx, GPGME_PROTOCOL_GPGCONF, NULL, "/tmp/foo");
fail_if_err (err);
err = gpgme_op_conf_dir (ctx, "agent-socket", &result1);
fail_if_err (err);
char *result2 = NULL;
err = gpgme_ctx_set_engine_info (ctx, GPGME_PROTOCOL_GPGCONF, NULL, NULL);
fail_if_err (err);
err = gpgme_op_conf_dir (ctx, "agent-socket", &result2);
fail_if_err (err);
/* They have to be different. */
test (strcmp(result1, result2));
err = gpgme_op_conf_load (ctx, &conf);
fail_if_err (err);