gpgconf: Add access to --list-dirs for non-default engine.
authorMarcus Brinkmann <marcus.brinkmann@ruhr-uni-bochum.de>
Tue, 15 Aug 2017 17:40:12 +0000 (19:40 +0200)
committerMarcus Brinkmann <marcus.brinkmann@ruhr-uni-bochum.de>
Tue, 15 Aug 2017 17:52:29 +0000 (19:52 +0200)
* 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

15 files changed:
src/engine-assuan.c
src/engine-backend.h
src/engine-g13.c
src/engine-gpg.c
src/engine-gpgconf.c
src/engine-gpgsm.c
src/engine-spawn.c
src/engine-uiserver.c
src/engine.c
src/engine.h
src/gpgconf.c
src/gpgme.def
src/gpgme.h.in
src/libgpgme.vers
tests/gpg/t-gpgconf.c

index 68bdaa6..bb2290a 100644 (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,
index 90328ec..f41aaeb 100644 (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,
index 02951e8..f8f3178 100644 (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,
index c749c97..bc60d82 100644 (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,
index af5f110..2b0f448 100644 (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 */
index a0fcb1f..f23b0bf 100644 (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,
index 9d587cc..7044781 100644 (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 */
index 20a8abf..3db705d 100644 (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,
index 89a8552..2c7e625 100644 (file)
@@ -984,6 +984,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,
                              gpgme_query_swdb_result_t result)
index d25c1fa..b71b7e2 100644 (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,
index b1b84a6..ce6ace4 100644 (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;
+}
index a891812..dd8e532 100644 (file)
@@ -265,5 +265,7 @@ EXPORTS
     gpgme_op_delete_ext                   @197
     gpgme_op_delete_ext_start             @198
 
+    gpgme_op_conf_save                   @199
+
 ; END
 
index 29cda2c..8afc276 100644 (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
index 9a74b76..a95befb 100644 (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;
 
index 67bb886..8c81de6 100644 (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);