2008-01-04 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: Support gpgconf. gpgme/ 2008-01-04 Marcus Brinkmann <marcus@g10code.de> * Makefile.am (gpgconf_components): New variable. (main_sources): Add gpgconf.c. * gpgme.h (gpgme_protocol_t): New protocol GPGME_PROTOCOL_GPGCONF. (gpgme_conf_level_t, gpgme_conf_type_t, gpgme_conf_arg_t) (gpgme_conf_opt_t, gpgme_conf_comp_t, gpgme_conf_arg_new) (gpgme_conf_arg_release, gpgme_conf_opt_change) (gpgme_conf_release, gpgme_op_conf_load, gpgme_op_conf_save): New types. * gpgconf.c, engine-gpgconf.c: New files. * engine.h: (_gpgme_engine_op_conf_load, (_gpgme_engine_op_conf_save): New prototypes. * op-support.c (_gpgme_op_reset): Ignore not implemented locale function. * posix-util.c (_gpgme_get_gpgconf_path): New function. * w32-util.c (_gpgme_get_gpgconf_path): New function. * engine-gpgsm.c: (_gpgme_engine_ops_gpgsm): Add stubs for conf_load and conf_save. * rungpg.c: (_gpgme_engine_ops_gpg): Add stubs for conf_load and conf_save. * gpgme.def: Add new gpgconf related interfaces. * libgpgme.vers: Likewise. * util.h (_gpgme_get_gpgconf_path): New prototype. * gpgme.h (gpgme_protocol_t): Add GPGME_PROTOCOL_GPGCONF. * engine-backend.h (_gpgme_engine_ops_gpgconf): New prototype. (struct engine_ops): Add members for conf_load and conf_save. * engine.c (engine_ops): Add _gpgme_engine_ops_gpgconf. (_gpgme_engine_op_conf_load, (_gpgme_engine_op_conf_save): New functions. (gpgme_get_engine_info): Allow protocol GPGME_PROTOCOL_GPGCONF. tests/ 2008-01-04 Marcus Brinkmann <marcus@g10code.de> * Makefile.am (TESTS_ENVIRONMENT): Use absolute path for GNUPGHOME. * gpg/Makefile.am (TESTS_ENVIRONMENT): Use absolute path for GNUPGHOME. * gpgsm/Makefile.am (TESTS_ENVIRONMENT): Use absolute path for GNUPGHOME. * gpg/Makefile.am (TESTS): Add t-gpgconf. t-gpgconf.c: New file.
This commit is contained in:
parent
6286b436bd
commit
19025d7918
@ -1,3 +1,7 @@
|
||||
2008-01-04 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* configure.ac: Support gpgconf.
|
||||
|
||||
2007-09-27 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-pipe-connect.c (pipe_connect_gpgme): Do not close process
|
||||
|
122
configure.ac
122
configure.ac
@ -114,6 +114,7 @@ AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
|
||||
|
||||
GPG_DEFAULT=no
|
||||
GPGSM_DEFAULT=no
|
||||
GPGCONF_DEFAULT=no
|
||||
component_system=None
|
||||
have_dosish_system=no
|
||||
have_w32_system=no
|
||||
@ -126,6 +127,7 @@ case "${host}" in
|
||||
have_w32_system=yes
|
||||
GPG_DEFAULT='c:\\gnupg\\gpg.exe'
|
||||
GPGSM_DEFAULT='c:\\gnupg\\gpgsm.exe'
|
||||
GPGCONF_DEFAULT='c:\\gnupg\\gpgconf.exe'
|
||||
#component_system='COM+'
|
||||
|
||||
AM_PATH_GLIB_2_0
|
||||
@ -158,6 +160,7 @@ case "${host}" in
|
||||
# XXX: Probably use exec-prefix here?
|
||||
# GPG_DEFAULT='/usr/bin/gpg'
|
||||
# GPGSM_DEFAULT='/usr/bin/gpgsm'
|
||||
# GPGCONF_DEFAULT='/usr/bin/gpgconf'
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -261,8 +264,10 @@ AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GPGME,
|
||||
# Checks for system services
|
||||
NEED_GPG_VERSION_DEFAULT=1.3.0
|
||||
NEED_GPGSM_VERSION_DEFAULT=1.9.6
|
||||
NEED_GPGCONF_VERSION_DEFAULT=2.0.4
|
||||
NEED_GPG_VERSION="$NEED_GPG_VERSION_DEFAULT"
|
||||
NEED_GPGSM_VERSION="$NEED_GPGSM_VERSION_DEFAULT"
|
||||
NEED_GPGCONF_VERSION="$NEED_GPGCONF_VERSION_DEFAULT"
|
||||
AC_ARG_WITH(gpg-version,
|
||||
AC_HELP_STRING([--with-gpg-version=VER], [require GnuPG version VER]),
|
||||
NEED_GPG_VERSION=$withval)
|
||||
@ -281,11 +286,22 @@ fi
|
||||
if test "$NEED_GPGSM_VERSION" = "no"; then
|
||||
NEED_GPGSM_VERSION=0.0.0
|
||||
fi
|
||||
AC_ARG_WITH(gpgconf-version,
|
||||
AC_HELP_STRING([--with-gpgconf-version=VER], [require GPGCONF version VER]),
|
||||
NEED_GPGCONF_VERSION=$withval)
|
||||
if test "$NEED_GPGCONF_VERSION" = "yes"; then
|
||||
NEED_GPGCONF_VERSION="$NEED_GPGCONF_VERSION_DEFAULT"
|
||||
fi
|
||||
if test "$NEED_GPGCONF_VERSION" = "no"; then
|
||||
NEED_GPGCONF_VERSION=0.0.0
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(NEED_GPG_VERSION, "$NEED_GPG_VERSION",
|
||||
[Min. needed GnuPG version.])
|
||||
AC_DEFINE_UNQUOTED(NEED_GPGSM_VERSION, "$NEED_GPGSM_VERSION",
|
||||
[Min. needed GPGSM version.])
|
||||
AC_DEFINE_UNQUOTED(NEED_GPGCONF_VERSION, "$NEED_GPGCONF_VERSION",
|
||||
[Min. needed GPGCONF version.])
|
||||
|
||||
|
||||
NO_OVERRIDE=no
|
||||
@ -477,6 +493,109 @@ AC_ARG_ENABLE(gpgsm-test,
|
||||
AM_CONDITIONAL(RUN_GPGSM_TESTS, test "$run_gpgsm_test" = "yes")
|
||||
|
||||
|
||||
NO_OVERRIDE=no
|
||||
AC_ARG_WITH(gpgconf,
|
||||
AC_HELP_STRING([--with-gpgconf=PATH],
|
||||
[use gpgconf binary at PATH]),
|
||||
GPGCONF=$withval, NO_OVERRIDE=yes)
|
||||
if test "$NO_OVERRIDE" = "yes" || test "$GPGCONF" = "yes"; then
|
||||
GPGCONF=
|
||||
NO_OVERRIDE=yes
|
||||
if test "$cross_compiling" != "yes"; then
|
||||
AC_PATH_PROG(GPGCONF, gpgconf)
|
||||
fi
|
||||
if test -z "$GPGCONF"; then
|
||||
GPGCONF="$GPGCONF_DEFAULT"
|
||||
fi
|
||||
fi
|
||||
if test "$GPGCONF" = no; then
|
||||
if test "$NO_OVERRIDE" = "yes"; then
|
||||
if test "$cross_compiling" != "yes"; then
|
||||
AC_MSG_WARN([
|
||||
***
|
||||
*** Could not find gpgconf, install gpgconf or use --with-gpgconf=PATH to enable it
|
||||
***])
|
||||
else
|
||||
AC_MSG_ERROR([
|
||||
***
|
||||
*** Can not determine path to gpgconf when cross-compiling, use --with-gpgconf=PATH
|
||||
***])
|
||||
fi
|
||||
fi
|
||||
else
|
||||
AC_DEFINE_UNQUOTED(GPGCONF_PATH, "$GPGCONF", [Path to the GPGCONF binary.])
|
||||
AC_DEFINE(ENABLE_GPGCONF,1,[Whether GPGCONF support is enabled])
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_GPGCONF, test "$GPGCONF" != "no")
|
||||
|
||||
dnl Check for GPGCONF version requirement.
|
||||
GPGCONF_VERSION=unknown
|
||||
ok=maybe
|
||||
if test -z "$GPGCONF" -o "x$GPGCONF" = "xno"; then
|
||||
ok=no
|
||||
else
|
||||
if test "$cross_compiling" = "yes"; then
|
||||
AC_MSG_WARN([GPGCONF version can not be checked when cross compiling])
|
||||
ok=no
|
||||
else
|
||||
if test ! -x "$GPGCONF"; then
|
||||
AC_MSG_WARN([GPGCONF not executable, version check disabled])
|
||||
ok=no
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "$ok" = "maybe"; then
|
||||
AC_MSG_CHECKING(for GPGCONF >= $NEED_GPGCONF_VERSION)
|
||||
req_major=`echo $NEED_GPGCONF_VERSION | \
|
||||
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
|
||||
req_minor=`echo $NEED_GPGCONF_VERSION | \
|
||||
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
|
||||
req_micro=`echo $NEED_GPGCONF_VERSION | \
|
||||
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
|
||||
GPGCONF_VERSION=`$GPGCONF --version | sed -n '1 s/[[^0-9]]*\(.*\)/\1/p'`
|
||||
major=`echo $GPGCONF_VERSION | \
|
||||
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
|
||||
minor=`echo $GPGCONF_VERSION | \
|
||||
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
|
||||
micro=`echo $GPGCONF_VERSION | \
|
||||
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
|
||||
|
||||
if test "$major" -gt "$req_major"; then
|
||||
ok=yes
|
||||
else
|
||||
if test "$major" -eq "$req_major"; then
|
||||
if test "$minor" -gt "$req_minor"; then
|
||||
ok=yes
|
||||
else
|
||||
if test "$minor" -eq "$req_minor"; then
|
||||
if test "$micro" -ge "$req_micro"; then
|
||||
ok=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test "$ok" = "yes"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_WARN([GPGCONF must be at least version $NEED_GPGCONF_VERSION])
|
||||
fi
|
||||
fi
|
||||
run_gpgconf_test="$ok"
|
||||
AC_ARG_ENABLE(gpgconf-test,
|
||||
AC_HELP_STRING([--disable-gpgconf-test], [disable GPGCONF run test]),
|
||||
run_gpgconf_test=$enableval)
|
||||
AM_CONDITIONAL(RUN_GPGCONF_TESTS, test "$run_gpgconf_test" = "yes")
|
||||
|
||||
# Only build if supported.
|
||||
AM_CONDITIONAL(BUILD_GPGCONF, test "$GPGCONF" != "no")
|
||||
if test "$GPGCONF" != "no"; then
|
||||
AC_DEFINE(HAVE_GPGCONF, 1,
|
||||
[Defined if we are building with gpgconf support.])
|
||||
fi
|
||||
|
||||
|
||||
# FIXME: Only build if supported.
|
||||
AM_CONDITIONAL(BUILD_ASSUAN, test "$GPGSM" != "no")
|
||||
if test "$GPGSM" != "no"; then
|
||||
@ -640,6 +759,9 @@ echo "
|
||||
GpgSM path: $GPGSM
|
||||
GpgSM version: $GPGSM_VERSION, min. $NEED_GPGSM_VERSION
|
||||
|
||||
GpgConf path: $GPGCONF
|
||||
GpgConf version: $GPGCONF_VERSION, min. $NEED_GPGCONF_VERSION
|
||||
|
||||
GPGME Pthread: $have_pthread
|
||||
GPGME Pth: $have_pth
|
||||
"
|
||||
|
@ -1,3 +1,35 @@
|
||||
2008-01-04 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* Makefile.am (gpgconf_components): New variable.
|
||||
(main_sources): Add gpgconf.c.
|
||||
* gpgme.h (gpgme_protocol_t): New protocol GPGME_PROTOCOL_GPGCONF.
|
||||
(gpgme_conf_level_t, gpgme_conf_type_t, gpgme_conf_arg_t)
|
||||
(gpgme_conf_opt_t, gpgme_conf_comp_t, gpgme_conf_arg_new)
|
||||
(gpgme_conf_arg_release, gpgme_conf_opt_change)
|
||||
(gpgme_conf_release, gpgme_op_conf_load, gpgme_op_conf_save): New
|
||||
types.
|
||||
* gpgconf.c, engine-gpgconf.c: New files.
|
||||
* engine.h: (_gpgme_engine_op_conf_load,
|
||||
(_gpgme_engine_op_conf_save): New prototypes.
|
||||
* op-support.c (_gpgme_op_reset): Ignore not implemented locale
|
||||
function.
|
||||
* posix-util.c (_gpgme_get_gpgconf_path): New function.
|
||||
* w32-util.c (_gpgme_get_gpgconf_path): New function.
|
||||
* engine-gpgsm.c:
|
||||
(_gpgme_engine_ops_gpgsm): Add stubs for conf_load and conf_save.
|
||||
* rungpg.c:
|
||||
(_gpgme_engine_ops_gpg): Add stubs for conf_load and conf_save.
|
||||
* gpgme.def: Add new gpgconf related interfaces.
|
||||
* libgpgme.vers: Likewise.
|
||||
* util.h (_gpgme_get_gpgconf_path): New prototype.
|
||||
* gpgme.h (gpgme_protocol_t): Add GPGME_PROTOCOL_GPGCONF.
|
||||
* engine-backend.h (_gpgme_engine_ops_gpgconf): New prototype.
|
||||
(struct engine_ops): Add members for conf_load and conf_save.
|
||||
* engine.c (engine_ops): Add _gpgme_engine_ops_gpgconf.
|
||||
(_gpgme_engine_op_conf_load,
|
||||
(_gpgme_engine_op_conf_save): New functions.
|
||||
(gpgme_get_engine_info): Allow protocol GPGME_PROTOCOL_GPGCONF.
|
||||
|
||||
2007-11-28 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* w32-util.c (_gpgme_get_gpg_path, _gpgme_get_gpgsm_path): Search
|
||||
|
@ -83,6 +83,12 @@ else
|
||||
gpgsm_components =
|
||||
endif
|
||||
|
||||
if HAVE_GPGCONF
|
||||
gpgconf_components = engine-gpgconf.c
|
||||
else
|
||||
gpgconf_components =
|
||||
endif
|
||||
|
||||
# These are the source files common to all library versions. We used
|
||||
# to build a non-installed library for that, but that does not work
|
||||
# correctly on all platforms (in particular, one can not specify the
|
||||
@ -100,7 +106,8 @@ main_sources = \
|
||||
key.c keylist.c trust-item.c trustlist.c \
|
||||
import.c export.c genkey.c delete.c edit.c getauditlog.c \
|
||||
engine.h engine-backend.h engine.c rungpg.c status-table.h \
|
||||
$(gpgsm_components) sema.h priv-io.h $(system_components) \
|
||||
$(gpgsm_components) $(gpgconf_components) gpgconf.c \
|
||||
sema.h priv-io.h $(system_components) \
|
||||
debug.c debug.h gpgme.c version.c error.c
|
||||
|
||||
libgpgme_la_SOURCES = $(main_sources) \
|
||||
|
@ -97,6 +97,9 @@ struct engine_ops
|
||||
gpgme_error_t (*getauditlog) (void *engine, gpgme_data_t output,
|
||||
unsigned int flags);
|
||||
|
||||
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);
|
||||
|
||||
void (*set_io_cbs) (void *engine, gpgme_io_cbs_t io_cbs);
|
||||
void (*io_event) (void *engine, gpgme_event_io_t type, void *type_data);
|
||||
|
||||
@ -108,5 +111,8 @@ extern struct engine_ops _gpgme_engine_ops_gpg; /* OpenPGP. */
|
||||
#ifdef ENABLE_GPGSM
|
||||
extern struct engine_ops _gpgme_engine_ops_gpgsm; /* CMS. */
|
||||
#endif
|
||||
#ifdef ENABLE_GPGCONF
|
||||
extern struct engine_ops _gpgme_engine_ops_gpgconf; /* gpg-conf. */
|
||||
#endif
|
||||
|
||||
#endif /* ENGINE_BACKEND_H */
|
||||
|
877
gpgme/engine-gpgconf.c
Normal file
877
gpgme/engine-gpgconf.c
Normal file
@ -0,0 +1,877 @@
|
||||
// Check protocol.
|
||||
// IMPLEMENT NO_ARG_DESC!!!!
|
||||
|
||||
/* engine-gpgconf.c - gpg-conf engine.
|
||||
Copyright (C) 2000 Werner Koch (dd9jn)
|
||||
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 g10 Code GmbH
|
||||
|
||||
This file is part of GPGME.
|
||||
|
||||
GPGME is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
GPGME is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <locale.h>
|
||||
#include <fcntl.h> /* FIXME */
|
||||
#include <errno.h>
|
||||
|
||||
#include "gpgme.h"
|
||||
#include "util.h"
|
||||
#include "ops.h"
|
||||
#include "wait.h"
|
||||
#include "priv-io.h"
|
||||
#include "sema.h"
|
||||
|
||||
#include "assuan.h"
|
||||
#include "debug.h"
|
||||
|
||||
#include "engine-backend.h"
|
||||
|
||||
|
||||
struct engine_gpgconf
|
||||
{
|
||||
char *file_name;
|
||||
char *home_dir;
|
||||
};
|
||||
|
||||
typedef struct engine_gpgconf *engine_gpgconf_t;
|
||||
|
||||
|
||||
static char *
|
||||
gpgconf_get_version (const char *file_name)
|
||||
{
|
||||
return _gpgme_get_program_version (file_name ? file_name
|
||||
: _gpgme_get_gpgconf_path ());
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
gpgconf_get_req_version (void)
|
||||
{
|
||||
return NEED_GPGCONF_VERSION;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gpgconf_release (void *engine)
|
||||
{
|
||||
engine_gpgconf_t gpgconf = engine;
|
||||
|
||||
if (!gpgconf)
|
||||
return;
|
||||
|
||||
if (gpgconf->file_name)
|
||||
free (gpgconf->file_name);
|
||||
if (gpgconf->home_dir)
|
||||
free (gpgconf->home_dir);
|
||||
|
||||
free (gpgconf);
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
gpgconf_new (void **engine, const char *file_name, const char *home_dir)
|
||||
{
|
||||
gpgme_error_t err = 0;
|
||||
engine_gpgconf_t gpgconf;
|
||||
|
||||
gpgconf = calloc (1, sizeof *gpgconf);
|
||||
if (!gpgconf)
|
||||
return gpg_error_from_errno (errno);
|
||||
|
||||
gpgconf->file_name = strdup (file_name ? file_name
|
||||
: _gpgme_get_gpgconf_path ());
|
||||
if (!gpgconf->file_name)
|
||||
err = gpg_error_from_syserror ();
|
||||
|
||||
if (!err && home_dir)
|
||||
{
|
||||
gpgconf->home_dir = strdup (home_dir);
|
||||
if (!gpgconf->home_dir)
|
||||
err = gpg_error_from_syserror ();
|
||||
}
|
||||
|
||||
if (err)
|
||||
gpgconf_release (gpgconf);
|
||||
else
|
||||
*engine = gpgconf;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
release_arg (gpgme_conf_arg_t arg, gpgme_conf_type_t alt_type)
|
||||
{
|
||||
while (arg)
|
||||
{
|
||||
gpgme_conf_arg_t next = arg->next;
|
||||
|
||||
if (alt_type == GPGME_CONF_STRING)
|
||||
free (arg->value.string);
|
||||
free (arg);
|
||||
arg = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
release_opt (gpgme_conf_opt_t opt)
|
||||
{
|
||||
if (opt->name)
|
||||
free (opt->name);
|
||||
if (opt->description)
|
||||
free (opt->description);
|
||||
if (opt->argname)
|
||||
free (opt->argname);
|
||||
|
||||
release_arg (opt->default_value, opt->alt_type);
|
||||
if (opt->default_description)
|
||||
free (opt->default_description);
|
||||
|
||||
release_arg (opt->no_arg_value, opt->alt_type);
|
||||
release_arg (opt->value, opt->alt_type);
|
||||
release_arg (opt->new_value, opt->alt_type);
|
||||
|
||||
free (opt);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
release_comp (gpgme_conf_comp_t comp)
|
||||
{
|
||||
gpgme_conf_opt_t opt;
|
||||
|
||||
if (comp->name)
|
||||
free (comp->name);
|
||||
if (comp->description)
|
||||
free (comp->description);
|
||||
if (comp->program_name)
|
||||
free (comp->program_name);
|
||||
|
||||
opt = comp->options;
|
||||
while (opt)
|
||||
{
|
||||
gpgme_conf_opt_t next = opt->next;
|
||||
release_opt (opt);
|
||||
opt = next;
|
||||
}
|
||||
|
||||
free (comp);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gpgconf_config_release (gpgme_conf_comp_t conf)
|
||||
{
|
||||
while (conf)
|
||||
{
|
||||
gpgme_conf_comp_t next = conf->next;
|
||||
release_comp (conf);
|
||||
conf = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
gpgconf_read (void *engine, char *arg1, char *arg2,
|
||||
gpgme_error_t (*cb) (void *hook, char *line),
|
||||
void *hook)
|
||||
{
|
||||
struct engine_gpgconf *gpgconf = engine;
|
||||
gpgme_error_t err = 0;
|
||||
#define LINELENGTH 1024
|
||||
char line[LINELENGTH] = "";
|
||||
int linelen = 0;
|
||||
char *argv[] = { NULL /* file_name */, arg1, arg2, 0 };
|
||||
int rp[2];
|
||||
struct spawn_fd_item_s pfd[] = { {0, -1}, {-1, -1} };
|
||||
struct spawn_fd_item_s cfd[] = { {-1, 1 /* STDOUT_FILENO */}, {-1, -1} };
|
||||
int status;
|
||||
int nread;
|
||||
char *mark = NULL;
|
||||
|
||||
/* FIXME: Deal with engine->home_dir. */
|
||||
|
||||
/* _gpgme_engine_new guarantees that this is not NULL. */
|
||||
argv[0] = gpgconf->file_name;
|
||||
|
||||
if (_gpgme_io_pipe (rp, 1) < 0)
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
pfd[0].fd = rp[1];
|
||||
cfd[0].fd = rp[1];
|
||||
|
||||
status = _gpgme_io_spawn (gpgconf->file_name, argv, cfd, pfd);
|
||||
if (status < 0)
|
||||
{
|
||||
_gpgme_io_close (rp[0]);
|
||||
_gpgme_io_close (rp[1]);
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
nread = _gpgme_io_read (rp[0], &line[linelen], LINELENGTH - linelen - 1);
|
||||
if (nread > 0)
|
||||
{
|
||||
line[linelen + nread] = '\0';
|
||||
linelen += nread;
|
||||
|
||||
while ((mark = strchr (line, '\n')))
|
||||
{
|
||||
char *eol = mark;
|
||||
|
||||
if (eol > &line[0] && *eol == '\r')
|
||||
eol--;
|
||||
*eol = '\0';
|
||||
|
||||
/* Got a full line. */
|
||||
err = (*cb) (hook, line);
|
||||
if (err)
|
||||
break;
|
||||
|
||||
linelen -= mark - line;
|
||||
memmove (line, eol + 1, linelen);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (nread > 0 && linelen < LINELENGTH - 1);
|
||||
|
||||
if (!err && nread < 0)
|
||||
err = gpg_error_from_syserror ();
|
||||
if (!err && nread > 0)
|
||||
err = gpg_error (GPG_ERR_LINE_TOO_LONG);
|
||||
|
||||
_gpgme_io_close (rp[0]);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
gpgconf_config_load_cb (void *hook, char *line)
|
||||
{
|
||||
gpgme_conf_comp_t *comp_p = hook;
|
||||
gpgme_conf_comp_t comp = *comp_p;
|
||||
#define NR_FIELDS 16
|
||||
char *field[NR_FIELDS];
|
||||
int fields = 0;
|
||||
|
||||
while (line && fields < NR_FIELDS)
|
||||
{
|
||||
field[fields++] = line;
|
||||
line = strchr (line, ':');
|
||||
if (line)
|
||||
*(line++) = '\0';
|
||||
}
|
||||
|
||||
/* We require at least the first 3 fields. */
|
||||
if (fields < 2)
|
||||
return gpg_error (GPG_ERR_INV_ENGINE);
|
||||
|
||||
/* Find the pointer to the new component in the list. */
|
||||
while (comp && comp->next)
|
||||
comp = comp->next;
|
||||
if (comp)
|
||||
comp_p = &comp->next;
|
||||
|
||||
comp = calloc (1, sizeof (*comp));
|
||||
if (!comp)
|
||||
return gpg_error_from_syserror ();
|
||||
/* Prepare return value. */
|
||||
comp->_last_opt_p = &comp->options;
|
||||
*comp_p = comp;
|
||||
|
||||
comp->name = strdup (field[0]);
|
||||
if (!comp->name)
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
comp->description = strdup (field[1]);
|
||||
if (!comp->description)
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
if (fields >= 3)
|
||||
{
|
||||
comp->description = strdup (field[2]);
|
||||
if (!comp->description)
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
gpgconf_parse_option (gpgme_conf_opt_t opt,
|
||||
gpgme_conf_arg_t *arg_p, char *line)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
char *mark;
|
||||
|
||||
if (!line[0])
|
||||
return 0;
|
||||
|
||||
mark = strchr (line, ',');
|
||||
if (mark)
|
||||
*mark = '\0';
|
||||
|
||||
while (line)
|
||||
{
|
||||
gpgme_conf_arg_t arg = calloc (1, sizeof (*arg));
|
||||
if (!arg)
|
||||
return gpg_error_from_syserror ();
|
||||
*arg_p = arg;
|
||||
arg_p = &arg->next;
|
||||
|
||||
if (*line == '\0')
|
||||
arg->no_arg = 1;
|
||||
else
|
||||
{
|
||||
switch (opt->alt_type)
|
||||
{
|
||||
/* arg->value.count is an alias for arg->value.uint32. */
|
||||
case GPGME_CONF_NONE:
|
||||
case GPGME_CONF_UINT32:
|
||||
arg->value.uint32 = strtoul (line, NULL, 0);
|
||||
break;
|
||||
|
||||
case GPGME_CONF_INT32:
|
||||
arg->value.uint32 = strtol (line, NULL, 0);
|
||||
break;
|
||||
|
||||
case GPGME_CONF_STRING:
|
||||
case GPGME_CONF_PATHNAME:
|
||||
case GPGME_CONF_LDAP_SERVER:
|
||||
/* Skip quote character. */
|
||||
line++;
|
||||
|
||||
err = _gpgme_decode_percent_string (line, &arg->value.string,
|
||||
0, 0);
|
||||
if (err)
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find beginning of next value. */
|
||||
if (mark++ && *mark)
|
||||
line = mark;
|
||||
else
|
||||
line = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
gpgconf_config_load_cb2 (void *hook, char *line)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
gpgme_conf_comp_t comp = hook;
|
||||
gpgme_conf_opt_t *opt_p = comp->_last_opt_p;
|
||||
gpgme_conf_opt_t opt;
|
||||
#define NR_FIELDS 16
|
||||
char *field[NR_FIELDS];
|
||||
int fields = 0;
|
||||
|
||||
while (line && fields < NR_FIELDS)
|
||||
{
|
||||
field[fields++] = line;
|
||||
line = strchr (line, ':');
|
||||
if (line)
|
||||
*(line++) = '\0';
|
||||
}
|
||||
|
||||
/* We require at least the first 10 fields. */
|
||||
if (fields < 10)
|
||||
return gpg_error (GPG_ERR_INV_ENGINE);
|
||||
|
||||
opt = calloc (1, sizeof (*opt));
|
||||
if (!opt)
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
comp->_last_opt_p = &opt->next;
|
||||
*opt_p = opt;
|
||||
|
||||
if (field[0][0])
|
||||
{
|
||||
opt->name = strdup (field[0]);
|
||||
if (!opt->name)
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
|
||||
opt->flags = strtoul (field[1], NULL, 0);
|
||||
|
||||
opt->level = strtoul (field[2], NULL, 0);
|
||||
|
||||
if (field[3][0])
|
||||
{
|
||||
opt->description = strdup (field[3]);
|
||||
if (!opt->description)
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
|
||||
opt->type = strtoul (field[4], NULL, 0);
|
||||
|
||||
opt->alt_type = strtoul (field[5], NULL, 0);
|
||||
|
||||
if (field[6][0])
|
||||
{
|
||||
opt->argname = strdup (field[6]);
|
||||
if (!opt->argname)
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
|
||||
if (opt->flags & GPGME_CONF_DEFAULT)
|
||||
{
|
||||
err = gpgconf_parse_option (opt, &opt->default_value, field[7]);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
else if ((opt->flags & GPGME_CONF_DEFAULT_DESC) && field[7][0])
|
||||
{
|
||||
opt->default_description = strdup (field[7]);
|
||||
if (!opt->default_description)
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
|
||||
err = gpgconf_parse_option (opt, &opt->no_arg_value, field[8]);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = gpgconf_parse_option (opt, &opt->value, field[9]);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
gpgconf_conf_load (void *engine, gpgme_conf_comp_t *comp_p)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
gpgme_conf_comp_t comp = NULL;
|
||||
gpgme_conf_comp_t cur_comp;
|
||||
|
||||
*comp_p = NULL;
|
||||
|
||||
err = gpgconf_read (engine, "--list-components", NULL,
|
||||
gpgconf_config_load_cb, &comp);
|
||||
if (err)
|
||||
{
|
||||
gpgconf_release (comp);
|
||||
return err;
|
||||
}
|
||||
|
||||
cur_comp = comp;
|
||||
while (!err && cur_comp)
|
||||
{
|
||||
err = gpgconf_read (engine, "--list-options", cur_comp->name,
|
||||
gpgconf_config_load_cb2, cur_comp);
|
||||
cur_comp = cur_comp->next;
|
||||
}
|
||||
|
||||
if (err)
|
||||
{
|
||||
gpgconf_release (comp);
|
||||
return err;
|
||||
}
|
||||
|
||||
*comp_p = comp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gpgme_error_t
|
||||
_gpgme_conf_arg_new (gpgme_conf_arg_t *arg_p,
|
||||
gpgme_conf_type_t type, void *value)
|
||||
{
|
||||
gpgme_conf_arg_t arg;
|
||||
|
||||
arg = calloc (1, sizeof (*arg));
|
||||
if (!arg)
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
if (!value)
|
||||
arg->no_arg = 1;
|
||||
else
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GPGME_CONF_NONE:
|
||||
case GPGME_CONF_UINT32:
|
||||
arg->value.uint32 = *((unsigned int *) value);
|
||||
break;
|
||||
|
||||
case GPGME_CONF_INT32:
|
||||
arg->value.int32 = *((int *) value);
|
||||
break;
|
||||
|
||||
case GPGME_CONF_STRING:
|
||||
case GPGME_CONF_PATHNAME:
|
||||
case GPGME_CONF_LDAP_SERVER:
|
||||
arg->value.string = strdup (value);
|
||||
if (!arg->value.string)
|
||||
{
|
||||
free (arg);
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
free (arg);
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
*arg_p = arg;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gpgme_conf_arg_release (gpgme_conf_arg_t arg, gpgme_conf_type_t type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GPGME_CONF_NONE:
|
||||
case GPGME_CONF_UINT32:
|
||||
case GPGME_CONF_INT32:
|
||||
case GPGME_CONF_STRING:
|
||||
default:
|
||||
break;
|
||||
|
||||
case GPGME_CONF_PATHNAME:
|
||||
case GPGME_CONF_LDAP_SERVER:
|
||||
type = GPGME_CONF_STRING;
|
||||
break;
|
||||
}
|
||||
|
||||
release_arg (arg, type);
|
||||
}
|
||||
|
||||
|
||||
gpgme_error_t
|
||||
_gpgme_conf_opt_change (gpgme_conf_opt_t opt, int reset, gpgme_conf_arg_t arg)
|
||||
{
|
||||
if (opt->new_value)
|
||||
release_arg (opt->new_value, opt->alt_type);
|
||||
|
||||
if (reset)
|
||||
{
|
||||
opt->new_value = NULL;
|
||||
opt->change_value = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
opt->new_value = arg;
|
||||
opt->change_value = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: Major problem: We don't get errors from gpgconf. */
|
||||
|
||||
static gpgme_error_t
|
||||
gpgconf_write (void *engine, char *arg1, char *arg2, gpgme_data_t conf)
|
||||
{
|
||||
struct engine_gpgconf *gpgconf = engine;
|
||||
gpgme_error_t err = 0;
|
||||
#define BUFLEN 1024
|
||||
char buf[BUFLEN];
|
||||
int buflen = 0;
|
||||
char *argv[] = { NULL /* file_name */, arg1, arg2, 0 };
|
||||
int rp[2];
|
||||
struct spawn_fd_item_s pfd[] = { {1, -1}, {-1, -1} };
|
||||
struct spawn_fd_item_s cfd[] = { {-1, 0 /* STDIN_FILENO */}, {-1, -1} };
|
||||
int status;
|
||||
int nwrite;
|
||||
|
||||
/* FIXME: Deal with engine->home_dir. */
|
||||
|
||||
/* _gpgme_engine_new guarantees that this is not NULL. */
|
||||
argv[0] = gpgconf->file_name;
|
||||
argv[0] = "/home/marcus/g10/install/bin/gpgconf";
|
||||
|
||||
if (_gpgme_io_pipe (rp, 0) < 0)
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
pfd[0].fd = rp[0];
|
||||
cfd[0].fd = rp[0];
|
||||
|
||||
status = _gpgme_io_spawn (gpgconf->file_name, argv, cfd, pfd);
|
||||
if (status < 0)
|
||||
{
|
||||
_gpgme_io_close (rp[0]);
|
||||
_gpgme_io_close (rp[1]);
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (buflen == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
buflen = gpgme_data_read (conf, buf, BUFLEN);
|
||||
}
|
||||
while (buflen < 0 && errno == EAGAIN);
|
||||
|
||||
if (buflen < 0)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
_gpgme_io_close (rp[1]);
|
||||
return err;
|
||||
}
|
||||
else if (buflen == 0)
|
||||
{
|
||||
/* All is written. */
|
||||
_gpgme_io_close (rp[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
nwrite = _gpgme_io_write (rp[1], buf, buflen);
|
||||
}
|
||||
while (nwrite < 0 && errno == EAGAIN);
|
||||
|
||||
if (nwrite > 0)
|
||||
{
|
||||
buflen -= nwrite;
|
||||
if (buflen > 0)
|
||||
memmove (&buf[0], &buf[nwrite], buflen);
|
||||
}
|
||||
else if (nwrite < 0)
|
||||
{
|
||||
_gpgme_io_close (rp[1]);
|
||||
return gpg_error_from_syserror ();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
arg_to_data (gpgme_data_t conf, gpgme_conf_opt_t option, gpgme_conf_arg_t arg)
|
||||
{
|
||||
gpgme_error_t err = 0;
|
||||
int amt = 0;
|
||||
char buf[16];
|
||||
|
||||
while (amt >= 0 && arg)
|
||||
{
|
||||
switch (option->alt_type)
|
||||
{
|
||||
case GPGME_CONF_NONE:
|
||||
case GPGME_CONF_UINT32:
|
||||
default:
|
||||
snprintf (buf, sizeof (buf), "%u", arg->value.uint32);
|
||||
buf[sizeof (buf) - 1] = '\0';
|
||||
amt = gpgme_data_write (conf, buf, strlen (buf));
|
||||
break;
|
||||
|
||||
case GPGME_CONF_INT32:
|
||||
snprintf (buf, sizeof (buf), "%i", arg->value.uint32);
|
||||
buf[sizeof (buf) - 1] = '\0';
|
||||
amt = gpgme_data_write (conf, buf, strlen (buf));
|
||||
break;
|
||||
|
||||
case GPGME_CONF_STRING:
|
||||
case GPGME_CONF_PATHNAME:
|
||||
case GPGME_CONF_LDAP_SERVER:
|
||||
/* One quote character, and three times to allow
|
||||
for percent escaping. */
|
||||
{
|
||||
char *ptr = arg->value.string;
|
||||
amt = gpgme_data_write (conf, "\"", 1);
|
||||
if (amt < 0)
|
||||
break;
|
||||
|
||||
while (!err && *ptr)
|
||||
{
|
||||
switch (*ptr)
|
||||
{
|
||||
case '%':
|
||||
amt = gpgme_data_write (conf, "%25", 3);
|
||||
break;
|
||||
|
||||
case ':':
|
||||
amt = gpgme_data_write (conf, "%3a", 3);
|
||||
break;
|
||||
|
||||
case ',':
|
||||
amt = gpgme_data_write (conf, "%2c", 3);
|
||||
break;
|
||||
|
||||
default:
|
||||
amt = gpgme_data_write (conf, ptr, 1);
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (amt < 0)
|
||||
break;
|
||||
|
||||
arg = arg->next;
|
||||
/* Comma separator. */
|
||||
if (arg)
|
||||
amt = gpgme_data_write (conf, ",", 1);
|
||||
}
|
||||
|
||||
if (amt < 0)
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static gpgme_error_t
|
||||
gpgconf_conf_save (void *engine, gpgme_conf_comp_t comp)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
int amt = 0;
|
||||
/* We use a data object to store the new configuration. */
|
||||
gpgme_data_t conf;
|
||||
gpgme_conf_opt_t option;
|
||||
int something_changed = 0;
|
||||
|
||||
err = gpgme_data_new (&conf);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
option = comp->options;
|
||||
while (!err && amt >= 0 && option)
|
||||
{
|
||||
if (option->change_value)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
char buf[16];
|
||||
|
||||
something_changed = 1;
|
||||
|
||||
amt = gpgme_data_write (conf, option->name, strlen (option->name));
|
||||
if (amt >= 0)
|
||||
amt = gpgme_data_write (conf, ":", 1);
|
||||
if (amt < 0)
|
||||
break;
|
||||
|
||||
if (!option->new_value)
|
||||
flags |= GPGME_CONF_DEFAULT;
|
||||
snprintf (buf, sizeof (buf), "%u", flags);
|
||||
buf[sizeof (buf) - 1] = '\0';
|
||||
|
||||
amt = gpgme_data_write (conf, buf, strlen (buf));
|
||||
if (amt >= 0)
|
||||
amt = gpgme_data_write (conf, ":", 1);
|
||||
if (amt < 0)
|
||||
break;
|
||||
|
||||
if (option->new_value)
|
||||
{
|
||||
err = arg_to_data (conf, option, option->new_value);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
amt = gpgme_data_write (conf, "\n", 1);
|
||||
}
|
||||
option = option->next;
|
||||
}
|
||||
if (!err && amt < 0)
|
||||
err = gpg_error_from_syserror ();
|
||||
if (err || !something_changed)
|
||||
goto bail;
|
||||
|
||||
err = gpgme_data_seek (conf, 0, SEEK_SET);
|
||||
if (err)
|
||||
goto bail;
|
||||
|
||||
err = gpgconf_write (engine, "--change-options", comp->name, conf);
|
||||
bail:
|
||||
gpgme_data_release (conf);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gpgconf_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
|
||||
|
||||
/* Currently, we do not use the engine interface for the various
|
||||
operations. */
|
||||
void
|
||||
_gpgme_conf_release (gpgme_conf_comp_t conf)
|
||||
{
|
||||
gpgconf_config_release (conf);
|
||||
}
|
||||
|
||||
|
||||
struct engine_ops _gpgme_engine_ops_gpgconf =
|
||||
{
|
||||
/* Static functions. */
|
||||
_gpgme_get_gpgconf_path,
|
||||
gpgconf_get_version,
|
||||
gpgconf_get_req_version,
|
||||
gpgconf_new,
|
||||
|
||||
/* Member functions. */
|
||||
gpgconf_release,
|
||||
NULL, /* reset */
|
||||
NULL, /* set_status_handler */
|
||||
NULL, /* set_command_handler */
|
||||
NULL, /* set_colon_line_handler */
|
||||
NULL, /* set_locale */
|
||||
NULL, /* decrypt */
|
||||
NULL, /* delete */
|
||||
NULL, /* edit */
|
||||
NULL, /* encrypt */
|
||||
NULL, /* encrypt_sign */
|
||||
NULL, /* export */
|
||||
NULL, /* export_ext */
|
||||
NULL, /* genkey */
|
||||
NULL, /* import */
|
||||
NULL, /* keylist */
|
||||
NULL, /* keylist_ext */
|
||||
NULL, /* sign */
|
||||
NULL, /* trustlist */
|
||||
NULL, /* verify */
|
||||
NULL, /* getauditlog */
|
||||
gpgconf_conf_load,
|
||||
gpgconf_conf_save,
|
||||
gpgconf_set_io_cbs,
|
||||
NULL, /* io_event */
|
||||
NULL /* cancel */
|
||||
};
|
@ -1885,6 +1885,8 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
|
||||
NULL, /* trustlist */
|
||||
gpgsm_verify,
|
||||
gpgsm_getauditlog,
|
||||
NULL, /* conf_load */
|
||||
NULL, /* conf_save */
|
||||
gpgsm_set_io_cbs,
|
||||
gpgsm_io_event,
|
||||
gpgsm_cancel
|
||||
|
@ -47,7 +47,12 @@ static struct engine_ops *engine_ops[] =
|
||||
{
|
||||
&_gpgme_engine_ops_gpg, /* OpenPGP. */
|
||||
#ifdef ENABLE_GPGSM
|
||||
&_gpgme_engine_ops_gpgsm /* CMS. */
|
||||
&_gpgme_engine_ops_gpgsm, /* CMS. */
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#ifdef ENABLE_GPGCONF
|
||||
&_gpgme_engine_ops_gpgconf /* gpg-conf. */
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
@ -169,7 +174,8 @@ gpgme_get_engine_info (gpgme_engine_info_t *info)
|
||||
{
|
||||
gpgme_engine_info_t *lastp = &engine_info;
|
||||
gpgme_protocol_t proto_list[] = { GPGME_PROTOCOL_OpenPGP,
|
||||
GPGME_PROTOCOL_CMS };
|
||||
GPGME_PROTOCOL_CMS,
|
||||
GPGME_PROTOCOL_GPGCONF };
|
||||
unsigned int proto;
|
||||
|
||||
for (proto = 0; proto < DIM (proto_list); proto++)
|
||||
@ -724,6 +730,32 @@ _gpgme_engine_op_getauditlog (engine_t engine, gpgme_data_t output,
|
||||
}
|
||||
|
||||
|
||||
gpgme_error_t
|
||||
_gpgme_engine_op_conf_load (engine_t engine, gpgme_conf_comp_t *conf_p)
|
||||
{
|
||||
if (!engine)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
if (!engine->ops->conf_load)
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
|
||||
return (*engine->ops->conf_load) (engine->engine, conf_p);
|
||||
}
|
||||
|
||||
|
||||
gpgme_error_t
|
||||
_gpgme_engine_op_conf_save (engine_t engine, gpgme_conf_comp_t conf)
|
||||
{
|
||||
if (!engine)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
if (!engine->ops->conf_save)
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
|
||||
return (*engine->ops->conf_save) (engine->engine, conf);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gpgme_engine_set_io_cbs (engine_t engine, gpgme_io_cbs_t io_cbs)
|
||||
{
|
||||
|
@ -127,6 +127,11 @@ gpgme_error_t _gpgme_engine_op_getauditlog (engine_t engine,
|
||||
gpgme_data_t output,
|
||||
unsigned int flags);
|
||||
|
||||
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);
|
||||
|
||||
void _gpgme_engine_set_io_cbs (engine_t engine,
|
||||
gpgme_io_cbs_t io_cbs);
|
||||
void _gpgme_engine_io_event (engine_t engine,
|
||||
|
134
gpgme/gpgconf.c
Normal file
134
gpgme/gpgconf.c
Normal file
@ -0,0 +1,134 @@
|
||||
/* gpgconf.c - GnuPG Made Easy.
|
||||
Copyright (C) 2007 g10 Code GmbH
|
||||
|
||||
This file is part of GPGME.
|
||||
|
||||
GPGME is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
GPGME is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "gpgme.h"
|
||||
|
||||
#include "ops.h"
|
||||
#include "engine.h"
|
||||
|
||||
#ifdef ENABLE_GPGCONF
|
||||
/* engine-gpgconf.c. */
|
||||
gpgme_error_t _gpgme_conf_arg_new (gpgme_conf_arg_t *arg_p,
|
||||
gpgme_conf_type_t type, void *value);
|
||||
void _gpgme_conf_arg_release (gpgme_conf_arg_t arg, gpgme_conf_type_t type);
|
||||
gpgme_error_t _gpgme_conf_opt_change (gpgme_conf_opt_t opt, int reset,
|
||||
gpgme_conf_arg_t arg);
|
||||
void _gpgme_conf_release (gpgme_conf_comp_t conf);
|
||||
gpgme_error_t _gpgme_conf_load (void *engine, gpgme_conf_comp_t *conf_p);
|
||||
gpgme_error_t gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* Allocate a new gpgme_conf_arg_t. */
|
||||
gpgme_error_t
|
||||
gpgme_conf_arg_new (gpgme_conf_arg_t *arg_p,
|
||||
gpgme_conf_type_t type, void *value)
|
||||
{
|
||||
#ifdef ENABLE_GPGCONF
|
||||
return _gpgme_conf_arg_new (arg_p, type, value);
|
||||
#else
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* This also releases all chained argument structures! */
|
||||
void
|
||||
gpgme_conf_arg_release (gpgme_conf_arg_t arg, gpgme_conf_type_t type)
|
||||
{
|
||||
#ifdef ENABLE_GPGCONF
|
||||
return _gpgme_conf_arg_release (arg, type);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Register a change for the value of OPT to ARG. */
|
||||
gpgme_error_t
|
||||
gpgme_conf_opt_change (gpgme_conf_opt_t opt, int reset, gpgme_conf_arg_t arg)
|
||||
{
|
||||
#ifdef ENABLE_GPGCONF
|
||||
return _gpgme_conf_opt_change (opt, reset, arg);
|
||||
#else
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Public function to release a gpgme_conf_comp list. */
|
||||
void
|
||||
gpgme_conf_release (gpgme_conf_comp_t conf)
|
||||
{
|
||||
#ifdef ENABLE_GPGCONF
|
||||
_gpgme_conf_release (conf);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Public function to release load a configuration list. No
|
||||
asynchronous interface for now. */
|
||||
gpgme_error_t
|
||||
gpgme_op_conf_load (gpgme_ctx_t ctx, gpgme_conf_comp_t *conf_p)
|
||||
{
|
||||
#ifdef ENABLE_GPGCONF
|
||||
gpgme_error_t err;
|
||||
gpgme_protocol_t proto = ctx->protocol;
|
||||
|
||||
ctx->protocol = GPGME_PROTOCOL_GPGCONF;
|
||||
err = _gpgme_op_reset (ctx, 1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = _gpgme_engine_op_conf_load (ctx->engine, conf_p);
|
||||
ctx->protocol = proto;
|
||||
return err;
|
||||
#else
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* This function does not follow chained components! */
|
||||
gpgme_error_t
|
||||
gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp)
|
||||
{
|
||||
#ifdef ENABLE_GPGCONF
|
||||
gpgme_error_t err;
|
||||
gpgme_protocol_t proto = ctx->protocol;
|
||||
|
||||
ctx->protocol = GPGME_PROTOCOL_GPGCONF;
|
||||
err = _gpgme_op_reset (ctx, 1);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = _gpgme_engine_op_conf_save (ctx->engine, comp);
|
||||
ctx->protocol = proto;
|
||||
return err;
|
||||
#else
|
||||
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -159,5 +159,12 @@ EXPORTS
|
||||
gpgme_op_getauditlog_start @123
|
||||
gpgme_op_getauditlog @124
|
||||
|
||||
gpgme_conf_release @125
|
||||
gpgme_conf_arg_new @126
|
||||
gpgme_conf_arg_release @127
|
||||
gpgme_conf_opt_change @128
|
||||
gpgme_op_conf_load @129
|
||||
gpgme_op_conf_save @130
|
||||
|
||||
; END
|
||||
|
||||
|
160
gpgme/gpgme.h
160
gpgme/gpgme.h
@ -72,7 +72,7 @@ extern "C" {
|
||||
AM_PATH_GPGME macro) check that this header matches the installed
|
||||
library. Warning: Do not edit the next line. configure will do
|
||||
that for you! */
|
||||
#define GPGME_VERSION "1.1.6-svn1258"
|
||||
#define GPGME_VERSION "1.1.6-svn1282"
|
||||
|
||||
|
||||
|
||||
@ -300,6 +300,7 @@ typedef enum
|
||||
{
|
||||
GPGME_PROTOCOL_OpenPGP = 0, /* The default mode. */
|
||||
GPGME_PROTOCOL_CMS = 1,
|
||||
GPGME_PROTOCOL_GPGCONF = 2, /* Special code for gpgconf. */
|
||||
GPGME_PROTOCOL_UNKNOWN = 255
|
||||
}
|
||||
gpgme_protocol_t;
|
||||
@ -1652,6 +1653,163 @@ gpgme_error_t gpgme_op_getauditlog_start (gpgme_ctx_t ctx, gpgme_data_t output,
|
||||
gpgme_error_t gpgme_op_getauditlog (gpgme_ctx_t ctx, gpgme_data_t output,
|
||||
unsigned int flags);
|
||||
|
||||
|
||||
/* Interface to gpg-conf. */
|
||||
|
||||
/* The expert level at which a configuration option or group of
|
||||
options should be displayed. See the gpg-conf documentation for
|
||||
more details. */
|
||||
typedef enum
|
||||
{
|
||||
GPGME_CONF_BASIC = 0,
|
||||
GPGME_CONF_ADVANCED = 1,
|
||||
GPGME_CONF_EXPERT = 2,
|
||||
GPGME_CONF_INVISIBLE = 3,
|
||||
GPGME_CONF_INTERNAL = 4
|
||||
}
|
||||
gpgme_conf_level_t;
|
||||
|
||||
|
||||
/* The data type of a configuration option argument. See the gpg-conf
|
||||
documentation for more details. */
|
||||
typedef enum
|
||||
{
|
||||
/* Basic types. */
|
||||
GPGME_CONF_NONE = 0,
|
||||
GPGME_CONF_STRING = 1,
|
||||
GPGME_CONF_INT32 = 2,
|
||||
GPGME_CONF_UINT32 = 3,
|
||||
|
||||
/* Complex types. */
|
||||
GPGME_CONF_PATHNAME = 32,
|
||||
GPGME_CONF_LDAP_SERVER = 33
|
||||
}
|
||||
gpgme_conf_type_t;
|
||||
|
||||
|
||||
/* This represents a single argument for a configuration option.
|
||||
Which of the members of value is used depends on the ALT_TYPE. */
|
||||
typedef struct gpgme_conf_arg
|
||||
{
|
||||
struct gpgme_conf_arg *next;
|
||||
/* True if the option appears without an (optional) argument. */
|
||||
unsigned int no_arg;
|
||||
union
|
||||
{
|
||||
unsigned int count;
|
||||
unsigned int uint32;
|
||||
int int32;
|
||||
char *string;
|
||||
} value;
|
||||
} *gpgme_conf_arg_t;
|
||||
|
||||
|
||||
/* The flags of a configuration option. See the gpg-conf
|
||||
documentation for details. */
|
||||
#define GPGME_CONF_GROUP (1 << 0)
|
||||
#define GPGME_CONF_OPTIONAL (1 << 1)
|
||||
#define GPGME_CONF_LIST (1 << 2)
|
||||
#define GPGME_CONF_RUNTIME (1 << 3)
|
||||
#define GPGME_CONF_DEFAULT (1 << 4)
|
||||
#define GPGME_CONF_DEFAULT_DESC (1 << 5)
|
||||
#define GPGME_CONF_NO_ARG_DESC (1 << 6)
|
||||
#define GPGME_CONF_NO_CHANGE (1 << 7)
|
||||
|
||||
|
||||
/* The representation of a single configuration option. See the
|
||||
gpg-conf documentation for details. */
|
||||
typedef struct gpgme_conf_opt
|
||||
{
|
||||
struct gpgme_conf_opt *next;
|
||||
|
||||
/* The option name. */
|
||||
char *name;
|
||||
|
||||
/* The flags for this option. */
|
||||
unsigned int flags;
|
||||
|
||||
/* The level of this option. */
|
||||
gpgme_conf_level_t level;
|
||||
|
||||
/* The localized description of this option. */
|
||||
char *description;
|
||||
|
||||
/* The type and alternate type of this option. */
|
||||
gpgme_conf_type_t type;
|
||||
gpgme_conf_type_t alt_type;
|
||||
|
||||
/* The localized (short) name of the argument, if any. */
|
||||
char *argname;
|
||||
|
||||
/* The default value. */
|
||||
gpgme_conf_arg_t default_value;
|
||||
char *default_description;
|
||||
|
||||
/* The default value if the option is not set. */
|
||||
gpgme_conf_arg_t no_arg_value;
|
||||
char *no_arg_description;
|
||||
|
||||
/* The current value if the option is set. */
|
||||
gpgme_conf_arg_t value;
|
||||
|
||||
/* The new value, if any. NULL means reset to default. */
|
||||
int change_value;
|
||||
gpgme_conf_arg_t new_value;
|
||||
|
||||
/* Free for application use. */
|
||||
void *user_data;
|
||||
} *gpgme_conf_opt_t;
|
||||
|
||||
|
||||
/* The representation of a component that can be configured. See the
|
||||
gpg-conf documentation for details. */
|
||||
typedef struct gpgme_conf_comp
|
||||
{
|
||||
struct gpgme_conf_comp *next;
|
||||
|
||||
/* Internal to GPGME, do not use! */
|
||||
gpgme_conf_opt_t *_last_opt_p;
|
||||
|
||||
/* The component name. */
|
||||
char *name;
|
||||
|
||||
/* A human-readable description for the component. */
|
||||
char *description;
|
||||
|
||||
/* The program name (an absolute path to the program). */
|
||||
char *program_name;
|
||||
|
||||
/* A linked list of options for this component. */
|
||||
struct gpgme_conf_opt *options;
|
||||
} *gpgme_conf_comp_t;
|
||||
|
||||
|
||||
/* Allocate a new gpgme_conf_arg_t. If VALUE is NULL, a "no arg
|
||||
default" is prepared. If type is a string type, VALUE should point
|
||||
to the string. Else, it should point to an unsigned or signed
|
||||
integer respectively. */
|
||||
gpgme_error_t gpgme_conf_arg_new (gpgme_conf_arg_t *arg_p,
|
||||
gpgme_conf_type_t type, void *value);
|
||||
|
||||
/* This also releases all chained argument structures! */
|
||||
void gpgme_conf_arg_release (gpgme_conf_arg_t arg, gpgme_conf_type_t type);
|
||||
|
||||
/* Register a change for the value of OPT to ARG. If RESET is 1 (do
|
||||
not use any values but 0 or 1), ARG is ignored and the option is
|
||||
not changed (reverting a previous change). Otherwise, if ARG is
|
||||
NULL, the option is cleared or reset to its default. */
|
||||
gpgme_error_t gpgme_conf_opt_change (gpgme_conf_opt_t opt, int reset,
|
||||
gpgme_conf_arg_t arg);
|
||||
|
||||
/* Release a set of configurations. */
|
||||
void gpgme_conf_release (gpgme_conf_comp_t conf);
|
||||
|
||||
/* Retrieve the current configurations. */
|
||||
gpgme_error_t gpgme_op_conf_load (gpgme_ctx_t ctx, gpgme_conf_comp_t *conf_p);
|
||||
|
||||
/* Save the configuration of component comp. This function does not
|
||||
follow chained components! */
|
||||
gpgme_error_t gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp);
|
||||
|
||||
|
||||
/* Various functions. */
|
||||
|
@ -39,6 +39,13 @@ GPGME_1.1 {
|
||||
|
||||
gpgme_op_getauditlog_start;
|
||||
gpgme_op_getauditlog;
|
||||
|
||||
gpgme_conf_release;
|
||||
gpgme_conf_arg_new;
|
||||
gpgme_conf_arg_release;
|
||||
gpgme_conf_opt_change;
|
||||
gpgme_op_conf_load;
|
||||
gpgme_op_conf_save;
|
||||
};
|
||||
|
||||
|
||||
|
@ -115,6 +115,8 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
|
||||
err = _gpgme_engine_set_locale (ctx->engine,
|
||||
LC_MESSAGES, ctx->lc_messages);
|
||||
#endif
|
||||
if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
|
||||
err = 0;
|
||||
if (err)
|
||||
{
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
|
@ -49,6 +49,16 @@ _gpgme_get_gpgsm_path (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
_gpgme_get_gpgconf_path (void)
|
||||
{
|
||||
#ifdef GPGCONF_PATH
|
||||
return GPGCONF_PATH;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* See w32-util.c */
|
||||
int
|
||||
_gpgme_get_conf_int (const char *key, int *value)
|
||||
|
@ -2120,7 +2120,9 @@ struct engine_ops _gpgme_engine_ops_gpg =
|
||||
gpg_sign,
|
||||
gpg_trustlist,
|
||||
gpg_verify,
|
||||
NULL,
|
||||
NULL, /* getauditlog */
|
||||
NULL, /* conf_load */
|
||||
NULL, /* conf_save */
|
||||
gpg_set_io_cbs,
|
||||
gpg_io_event,
|
||||
gpg_cancel
|
||||
|
@ -31,6 +31,7 @@
|
||||
/*-- {posix,w32}-util.c --*/
|
||||
const char *_gpgme_get_gpg_path (void);
|
||||
const char *_gpgme_get_gpgsm_path (void);
|
||||
const char *_gpgme_get_gpgconf_path (void);
|
||||
int _gpgme_get_conf_int (const char *key, int *value);
|
||||
|
||||
|
||||
|
@ -274,6 +274,7 @@ find_program_in_inst_dir (const char *name)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
find_program_at_standard_place (const char *name)
|
||||
{
|
||||
@ -313,6 +314,7 @@ _gpgme_get_gpg_path (void)
|
||||
return gpg_program;
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
_gpgme_get_gpgsm_path (void)
|
||||
{
|
||||
@ -330,6 +332,24 @@ _gpgme_get_gpgsm_path (void)
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
_gpgme_get_gpgconf_path (void)
|
||||
{
|
||||
static char *gpgconf_program;
|
||||
|
||||
LOCK (get_path_lock);
|
||||
if (!gpgconf_program)
|
||||
gpgconf_program = find_program_in_registry ("gpgconfProgram");
|
||||
if (!gpgconf_program)
|
||||
gpgconf_program = find_program_in_inst_dir ("gpgconf.exe");
|
||||
if (!gpgconf_program)
|
||||
gpgconf_program
|
||||
= find_program_at_standard_place ("GNU\\GnuPG\\gpgconf.exe");
|
||||
UNLOCK (get_path_lock);
|
||||
return gpgconf_program;
|
||||
}
|
||||
|
||||
|
||||
/* Return an integer value from gpgme specific configuration
|
||||
entries. VALUE receives that value; function returns true if a value
|
||||
has been configured and false if not. */
|
||||
|
@ -1,3 +1,14 @@
|
||||
2008-01-04 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* Makefile.am (TESTS_ENVIRONMENT): Use absolute path for
|
||||
GNUPGHOME.
|
||||
* gpg/Makefile.am (TESTS_ENVIRONMENT): Use absolute path for
|
||||
GNUPGHOME.
|
||||
* gpgsm/Makefile.am (TESTS_ENVIRONMENT): Use absolute path for
|
||||
GNUPGHOME.
|
||||
* gpg/Makefile.am (TESTS): Add t-gpgconf.
|
||||
t-gpgconf.c: New file.
|
||||
|
||||
2007-11-23 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* gpgsm/t-verify.c (show_auditlog): Check for GPG_ERR_ASS_UNKNOWN_CMD.
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
TESTS_ENVIRONMENT = GNUPGHOME=.
|
||||
TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir)
|
||||
|
||||
TESTS = t-version t-data t-engine-info
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
GPG = @GPG@
|
||||
|
||||
TESTS_ENVIRONMENT = GNUPGHOME=. GPG_AGENT_INFO=
|
||||
TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) GPG_AGENT_INFO=
|
||||
|
||||
# The keylist tests must come after the import and the edit test.
|
||||
noinst_HEADERS = t-support.h
|
||||
@ -35,9 +35,9 @@ endif
|
||||
TESTS = t-encrypt t-encrypt-sym t-encrypt-sign t-sign t-signers \
|
||||
t-decrypt t-verify t-decrypt-verify t-sig-notation t-export \
|
||||
t-import t-trustlist t-edit t-keylist t-keylist-sig t-wait \
|
||||
t-encrypt-large t-file-name $(tests_unix)
|
||||
t-encrypt-large t-file-name t-gpgconf $(tests_unix)
|
||||
|
||||
CLEANFILES = secring.gpg pubring.gpg trustdb.gpg
|
||||
CLEANFILES = secring.gpg pubring.gpg trustdb.gpg dirmngr.conf
|
||||
DISTCLEANFILES = pubring.gpg~ random_seed gpg.conf
|
||||
|
||||
EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc cipher-2.asc \
|
||||
|
305
tests/gpg/t-gpgconf.c
Normal file
305
tests/gpg/t-gpgconf.c
Normal file
@ -0,0 +1,305 @@
|
||||
/* t-gpgconf.c - Regression test.
|
||||
Copyright (C) 2001, 2004, 2007 g10 Code GmbH
|
||||
|
||||
This file is part of GPGME.
|
||||
|
||||
GPGME is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as
|
||||
published by the Free Software Foundation; either version 2.1 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
GPGME is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <gpgme.h>
|
||||
|
||||
|
||||
#define fail_if_err(err) \
|
||||
do \
|
||||
{ \
|
||||
if (err) \
|
||||
{ \
|
||||
fprintf (stderr, "%s:%d: %s: %s\n", \
|
||||
__FILE__, __LINE__, gpgme_strsource (err), \
|
||||
gpgme_strerror (err)); \
|
||||
exit (1); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
|
||||
void
|
||||
init_gpgme (gpgme_protocol_t proto)
|
||||
{
|
||||
gpgme_error_t err;
|
||||
|
||||
gpgme_check_version (NULL);
|
||||
setlocale (LC_ALL, "");
|
||||
gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
|
||||
#endif
|
||||
|
||||
err = gpgme_engine_check_version (proto);
|
||||
fail_if_err (err);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
spaces (char *str, int extra)
|
||||
{
|
||||
static char buf[80];
|
||||
int len = str ? strlen (str) : 0;
|
||||
int n;
|
||||
|
||||
#define TABSTOP 30
|
||||
n = TABSTOP - len - extra;
|
||||
|
||||
memset (buf, ' ', sizeof (buf));
|
||||
if (n < 1 || n > (sizeof (buf) - 1))
|
||||
{
|
||||
buf[0] = '\n';
|
||||
n = TABSTOP + 1;
|
||||
}
|
||||
|
||||
buf[n] = '\0';
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dump_arg (int type, gpgme_conf_arg_t arg)
|
||||
{
|
||||
if (!arg)
|
||||
{
|
||||
printf ("(none)");
|
||||
return;
|
||||
}
|
||||
|
||||
while (arg)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case GPGME_CONF_STRING:
|
||||
case GPGME_CONF_PATHNAME:
|
||||
case GPGME_CONF_LDAP_SERVER:
|
||||
printf ("%s", arg->value.string);
|
||||
break;
|
||||
|
||||
case GPGME_CONF_UINT32:
|
||||
printf ("%u", arg->value.uint32);
|
||||
break;
|
||||
|
||||
case GPGME_CONF_INT32:
|
||||
printf ("%i", arg->value.int32);
|
||||
break;
|
||||
|
||||
case GPGME_CONF_NONE:
|
||||
printf ("%i (times)", arg->value.count);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("(unknown type)");
|
||||
}
|
||||
|
||||
arg = arg->next;
|
||||
if (arg)
|
||||
printf (" ");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dump_opt (gpgme_conf_opt_t opt)
|
||||
{
|
||||
char level;
|
||||
char runtime = (opt->flags & GPGME_CONF_RUNTIME) ? 'r' : ' ';
|
||||
|
||||
switch (opt->level)
|
||||
{
|
||||
case GPGME_CONF_BASIC:
|
||||
level = 'b';
|
||||
break;
|
||||
case GPGME_CONF_ADVANCED:
|
||||
level = 'a';
|
||||
break;
|
||||
case GPGME_CONF_EXPERT:
|
||||
level = 'e';
|
||||
break;
|
||||
case GPGME_CONF_INVISIBLE:
|
||||
level = 'i';
|
||||
break;
|
||||
case GPGME_CONF_INTERNAL:
|
||||
level = '#';
|
||||
break;
|
||||
default:
|
||||
level = '?';
|
||||
}
|
||||
|
||||
if (opt->flags & GPGME_CONF_GROUP)
|
||||
{
|
||||
printf ("\n");
|
||||
printf ("%c%c [%s]%s%s\n", level, runtime, opt->name, spaces (opt->name, 5),
|
||||
opt->description
|
||||
? opt->description : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (opt->argname)
|
||||
{
|
||||
char *more = (opt->flags & GPGME_CONF_LIST) ? "..." : "";
|
||||
|
||||
if (opt->flags & GPGME_CONF_OPTIONAL)
|
||||
{
|
||||
printf ("%c%c --%s [%s%s] %s", level, runtime, opt->name, opt->argname, more,
|
||||
spaces (opt->name, 9 + strlen (opt->argname) + strlen (more)));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("%c%c --%s %s%s %s", level, runtime, opt->name, opt->argname, more,
|
||||
spaces (opt->name, 7 + strlen (opt->argname) + strlen (more)));
|
||||
}
|
||||
}
|
||||
else
|
||||
printf ("%c%c --%s%s", level, runtime, opt->name, spaces (opt->name, 5));
|
||||
|
||||
if (opt->description)
|
||||
printf ("%s", opt->description);
|
||||
printf ("\n");
|
||||
|
||||
if (opt->flags & GPGME_CONF_DEFAULT)
|
||||
{
|
||||
printf ("%s%s = ", spaces (NULL, 0), opt->argname ? opt->argname : "(default)");
|
||||
dump_arg (opt->type, opt->default_value);
|
||||
printf ("\n");
|
||||
}
|
||||
else if (opt->flags & GPGME_CONF_DEFAULT_DESC)
|
||||
printf ("%s%s = %s\n", spaces (NULL, 0), opt->argname ? opt->argname : "(default)",
|
||||
opt->default_description);
|
||||
|
||||
if (opt->no_arg_value)
|
||||
{
|
||||
printf ("%sNo Arg Def = ", spaces (NULL, 0));
|
||||
dump_arg (opt->type, opt->no_arg_value);
|
||||
printf ("\n");
|
||||
}
|
||||
if (opt->value)
|
||||
{
|
||||
printf ("%sCurrent = ", spaces (NULL, 0));
|
||||
dump_arg (opt->type, opt->value);
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
arg = comp->options;
|
||||
while (opt)
|
||||
{
|
||||
dump_opt (opt);
|
||||
opt = opt->next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dump_comp (gpgme_conf_comp_t comp)
|
||||
{
|
||||
gpgme_conf_opt_t opt;
|
||||
|
||||
printf ("COMPONENT\n");
|
||||
printf ("=========\n");
|
||||
printf (" Name: %s\n", comp->name);
|
||||
if (comp->description)
|
||||
printf (" Desc: %s\n", comp->description);
|
||||
if (comp->program_name)
|
||||
printf (" Path: %s\n", comp->program_name);
|
||||
printf ("\n");
|
||||
|
||||
opt = comp->options;
|
||||
while (opt)
|
||||
{
|
||||
dump_opt (opt);
|
||||
opt = opt->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
gpgme_ctx_t ctx;
|
||||
gpgme_error_t err;
|
||||
gpgme_conf_comp_t conf;
|
||||
gpgme_conf_comp_t comp;
|
||||
int first;
|
||||
init_gpgme (GPGME_PROTOCOL_GPGCONF);
|
||||
|
||||
err = gpgme_new (&ctx);
|
||||
fail_if_err (err);
|
||||
|
||||
err = gpgme_op_conf_load (ctx, &conf);
|
||||
fail_if_err (err);
|
||||
|
||||
comp = conf;
|
||||
first = 1;
|
||||
while (comp)
|
||||
{
|
||||
if (!first)
|
||||
printf ("\n");
|
||||
else
|
||||
first = 0;
|
||||
dump_comp (comp);
|
||||
comp = comp->next;
|
||||
}
|
||||
|
||||
#if 1
|
||||
/* Now change something. */
|
||||
{
|
||||
unsigned int count = 1;
|
||||
gpgme_conf_arg_t arg;
|
||||
gpgme_conf_opt_t opt;
|
||||
|
||||
err = gpgme_conf_arg_new (&arg, GPGME_CONF_NONE, &count);
|
||||
fail_if_err (err);
|
||||
|
||||
comp = conf;
|
||||
while (comp && strcmp (comp->name, "dirmngr"))
|
||||
comp = comp->next;
|
||||
opt = comp->options;
|
||||
while (opt && strcmp (opt->name, "verbose"))
|
||||
opt = opt->next;
|
||||
|
||||
err = gpgme_conf_opt_change (opt, 0, arg);
|
||||
fail_if_err (err);
|
||||
|
||||
err = gpgme_op_conf_save (ctx, comp);
|
||||
fail_if_err (err);
|
||||
}
|
||||
#endif
|
||||
|
||||
gpgme_conf_release (conf);
|
||||
|
||||
return 0;
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
|
||||
GPGSM = @GPGSM@
|
||||
|
||||
TESTS_ENVIRONMENT = GNUPGHOME=. GPG_AGENT_INFO=
|
||||
TESTS_ENVIRONMENT = GNUPGHOME=$(abs_builddir) GPG_AGENT_INFO=
|
||||
|
||||
noinst_HEADERS = t-support.h
|
||||
TESTS = t-import t-keylist t-encrypt t-verify t-decrypt t-sign t-export
|
||||
|
Loading…
Reference in New Issue
Block a user