summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJinWang An <jinwang.an@samsung.com>2021-12-01 16:54:34 +0900
committerJinWang An <jinwang.an@samsung.com>2021-12-01 16:54:34 +0900
commit995a02825947cf6f11b67998d850c748d320c8cd (patch)
tree941ed2cd17bb2649ad441e9e49aaff3aeda987d3 /src
parent446ad01df66cb2f4dd51d97ff02be16d765847e1 (diff)
downloadgpgme-995a02825947cf6f11b67998d850c748d320c8cd.tar.gz
gpgme-995a02825947cf6f11b67998d850c748d320c8cd.tar.bz2
gpgme-995a02825947cf6f11b67998d850c748d320c8cd.zip
Imported Upstream version 1.5.0upstream/1.5.0
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am31
-rw-r--r--src/Makefile.in251
-rw-r--r--src/assuan-support.c3
-rw-r--r--src/conversion.c21
-rw-r--r--src/decrypt.c6
-rw-r--r--src/dirinfo.c107
-rw-r--r--src/engine-assuan.c3
-rw-r--r--src/engine-backend.h29
-rw-r--r--src/engine-g13.c19
-rw-r--r--src/engine-gpg.c49
-rw-r--r--src/engine-gpgconf.c11
-rw-r--r--src/engine-gpgsm.c24
-rw-r--r--src/engine-spawn.c475
-rw-r--r--src/engine-uiserver.c5
-rw-r--r--src/engine.c82
-rw-r--r--src/engine.h7
-rw-r--r--src/gpgconf.c33
-rw-r--r--src/gpgme-tool.c70
-rw-r--r--src/gpgme.c41
-rw-r--r--src/gpgme.def4
-rw-r--r--src/gpgme.h.in62
-rw-r--r--src/key.c2
-rw-r--r--src/keylist.c26
-rw-r--r--src/libgpgme.vers5
-rw-r--r--src/posix-io.c53
-rw-r--r--src/posix-util.c113
-rw-r--r--src/priv-io.h6
-rw-r--r--src/sign.c7
-rw-r--r--src/spawn.c106
-rw-r--r--src/status-table.c25
-rw-r--r--src/sys-util.h9
-rw-r--r--src/util.h19
-rw-r--r--src/verify.c14
-rw-r--r--src/version.c3
-rw-r--r--src/w32-glib-io.c3
-rw-r--r--src/w32-io.c3
-rw-r--r--src/w32-qt-io.cpp47
-rw-r--r--src/w32-util.c154
38 files changed, 1441 insertions, 487 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 1f95103..82f5327 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -66,30 +66,6 @@ if HAVE_W32CE_SYSTEM
system_components += w32-ce.h w32-ce.c
endif
-if HAVE_GPGSM
-gpgsm_components = engine-gpgsm.c
-else
-gpgsm_components =
-endif
-
-if HAVE_ASSUAN
-assuan_components = assuan-support.c engine-assuan.c
-else
-assuan_components =
-endif
-
-if HAVE_GPGCONF
-gpgconf_components = engine-gpgconf.c
-else
-gpgconf_components =
-endif
-
-if HAVE_G13
-g13_components = engine-g13.c
-else
-g13_components =
-endif
-
if HAVE_UISERVER
uiserver_components = engine-uiserver.c
else
@@ -113,11 +89,12 @@ main_sources = \
sign.c passphrase.c progress.c \
key.c keylist.c trust-item.c trustlist.c \
import.c export.c genkey.c delete.c edit.c getauditlog.c \
- opassuan.c passwd.c \
+ opassuan.c passwd.c spawn.c assuan-support.c \
engine.h engine-backend.h engine.c engine-gpg.c status-table.c \
- $(gpgsm_components) $(assuan_components) $(gpgconf_components) \
+ engine-gpgsm.c engine-assuan.c engine-gpgconf.c \
$(uiserver_components) \
- $(g13_components) vfs-mount.c vfs-create.c \
+ engine-g13.c vfs-mount.c vfs-create.c \
+ engine-spawn.c \
gpgconf.c \
sema.h priv-io.h $(system_components) sys-util.h dirinfo.c \
debug.c debug.h gpgme.c version.c error.c
diff --git a/src/Makefile.in b/src/Makefile.in
index 145e234..cd55a3f 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -135,25 +135,21 @@ am__libgpgme_glib_la_SOURCES_DIST = util.h conversion.c get-env.c \
encrypt-sign.c decrypt.c decrypt-verify.c verify.c sign.c \
passphrase.c progress.c key.c keylist.c trust-item.c \
trustlist.c import.c export.c genkey.c delete.c edit.c \
- getauditlog.c opassuan.c passwd.c engine.h engine-backend.h \
- engine.c engine-gpg.c status-table.c engine-gpgsm.c \
- assuan-support.c engine-assuan.c engine-gpgconf.c \
+ getauditlog.c opassuan.c passwd.c spawn.c assuan-support.c \
+ engine.h engine-backend.h engine.c engine-gpg.c status-table.c \
+ engine-gpgsm.c engine-assuan.c engine-gpgconf.c \
engine-uiserver.c engine-g13.c vfs-mount.c vfs-create.c \
- gpgconf.c sema.h priv-io.h ath.h posix-util.c posix-sema.c \
- posix-io.c w32-ce.h w32-ce.c w32-util.c w32-sema.c sys-util.h \
- dirinfo.c debug.c debug.h gpgme.c version.c error.c ath.c \
- w32-glib-io.c
-@HAVE_GPGSM_TRUE@am__objects_1 = engine-gpgsm.lo
-@HAVE_ASSUAN_TRUE@am__objects_2 = assuan-support.lo engine-assuan.lo
-@HAVE_GPGCONF_TRUE@am__objects_3 = engine-gpgconf.lo
-@HAVE_UISERVER_TRUE@am__objects_4 = engine-uiserver.lo
-@HAVE_G13_TRUE@am__objects_5 = engine-g13.lo
-@HAVE_W32CE_SYSTEM_TRUE@am__objects_6 = w32-ce.lo
-@HAVE_DOSISH_SYSTEM_FALSE@am__objects_7 = posix-util.lo posix-sema.lo \
-@HAVE_DOSISH_SYSTEM_FALSE@ posix-io.lo $(am__objects_6)
-@HAVE_DOSISH_SYSTEM_TRUE@am__objects_7 = w32-util.lo w32-sema.lo \
-@HAVE_DOSISH_SYSTEM_TRUE@ $(am__objects_6)
-am__objects_8 = conversion.lo get-env.lo parsetlv.lo data.lo \
+ engine-spawn.c gpgconf.c sema.h priv-io.h ath.h posix-util.c \
+ posix-sema.c posix-io.c w32-ce.h w32-ce.c w32-util.c \
+ w32-sema.c sys-util.h dirinfo.c debug.c debug.h gpgme.c \
+ version.c error.c ath.c w32-glib-io.c
+@HAVE_UISERVER_TRUE@am__objects_1 = engine-uiserver.lo
+@HAVE_W32CE_SYSTEM_TRUE@am__objects_2 = w32-ce.lo
+@HAVE_DOSISH_SYSTEM_FALSE@am__objects_3 = posix-util.lo posix-sema.lo \
+@HAVE_DOSISH_SYSTEM_FALSE@ posix-io.lo $(am__objects_2)
+@HAVE_DOSISH_SYSTEM_TRUE@am__objects_3 = w32-util.lo w32-sema.lo \
+@HAVE_DOSISH_SYSTEM_TRUE@ $(am__objects_2)
+am__objects_4 = conversion.lo get-env.lo parsetlv.lo data.lo \
data-fd.lo data-stream.lo data-mem.lo data-user.lo \
data-compat.lo data-identify.lo signers.lo sig-notation.lo \
wait.lo wait-global.lo wait-private.lo wait-user.lo \
@@ -161,17 +157,21 @@ am__objects_8 = conversion.lo get-env.lo parsetlv.lo data.lo \
decrypt-verify.lo verify.lo sign.lo passphrase.lo progress.lo \
key.lo keylist.lo trust-item.lo trustlist.lo import.lo \
export.lo genkey.lo delete.lo edit.lo getauditlog.lo \
- opassuan.lo passwd.lo engine.lo engine-gpg.lo status-table.lo \
- $(am__objects_1) $(am__objects_2) $(am__objects_3) \
- $(am__objects_4) $(am__objects_5) vfs-mount.lo vfs-create.lo \
- gpgconf.lo $(am__objects_7) dirinfo.lo debug.lo gpgme.lo \
- version.lo error.lo
-@BUILD_W32_GLIB_TRUE@am_libgpgme_glib_la_OBJECTS = $(am__objects_8) \
+ opassuan.lo passwd.lo spawn.lo assuan-support.lo engine.lo \
+ engine-gpg.lo status-table.lo engine-gpgsm.lo engine-assuan.lo \
+ engine-gpgconf.lo $(am__objects_1) engine-g13.lo vfs-mount.lo \
+ vfs-create.lo engine-spawn.lo gpgconf.lo $(am__objects_3) \
+ dirinfo.lo debug.lo gpgme.lo version.lo error.lo
+@BUILD_W32_GLIB_TRUE@am_libgpgme_glib_la_OBJECTS = $(am__objects_4) \
@BUILD_W32_GLIB_TRUE@ ath.lo w32-glib-io.lo
libgpgme_glib_la_OBJECTS = $(am_libgpgme_glib_la_OBJECTS)
-libgpgme_glib_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libgpgme_glib_la_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+libgpgme_glib_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libgpgme_glib_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
@BUILD_W32_GLIB_TRUE@am_libgpgme_glib_la_rpath = -rpath $(libdir)
am__libgpgme_pthread_la_SOURCES_DIST = util.h conversion.c get-env.c \
context.h ops.h parsetlv.c parsetlv.h data.h data.c data-fd.c \
@@ -181,21 +181,22 @@ am__libgpgme_pthread_la_SOURCES_DIST = util.h conversion.c get-env.c \
encrypt-sign.c decrypt.c decrypt-verify.c verify.c sign.c \
passphrase.c progress.c key.c keylist.c trust-item.c \
trustlist.c import.c export.c genkey.c delete.c edit.c \
- getauditlog.c opassuan.c passwd.c engine.h engine-backend.h \
- engine.c engine-gpg.c status-table.c engine-gpgsm.c \
- assuan-support.c engine-assuan.c engine-gpgconf.c \
+ getauditlog.c opassuan.c passwd.c spawn.c assuan-support.c \
+ engine.h engine-backend.h engine.c engine-gpg.c status-table.c \
+ engine-gpgsm.c engine-assuan.c engine-gpgconf.c \
engine-uiserver.c engine-g13.c vfs-mount.c vfs-create.c \
- gpgconf.c sema.h priv-io.h ath.h posix-util.c posix-sema.c \
- posix-io.c w32-ce.h w32-ce.c w32-util.c w32-sema.c sys-util.h \
- dirinfo.c debug.c debug.h gpgme.c version.c error.c \
- ath-pthread.c w32-io.c
-@HAVE_DOSISH_SYSTEM_TRUE@am__objects_9 = w32-io.lo
-am_libgpgme_pthread_la_OBJECTS = $(am__objects_8) ath-pthread.lo \
- $(am__objects_9)
+ engine-spawn.c gpgconf.c sema.h priv-io.h ath.h posix-util.c \
+ posix-sema.c posix-io.c w32-ce.h w32-ce.c w32-util.c \
+ w32-sema.c sys-util.h dirinfo.c debug.c debug.h gpgme.c \
+ version.c error.c ath-pthread.c w32-io.c
+@HAVE_DOSISH_SYSTEM_TRUE@am__objects_5 = w32-io.lo
+am_libgpgme_pthread_la_OBJECTS = $(am__objects_4) ath-pthread.lo \
+ $(am__objects_5)
libgpgme_pthread_la_OBJECTS = $(am_libgpgme_pthread_la_OBJECTS)
-libgpgme_pthread_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(libgpgme_pthread_la_LDFLAGS) $(LDFLAGS) -o $@
+libgpgme_pthread_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libgpgme_pthread_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
@HAVE_PTHREAD_TRUE@am_libgpgme_pthread_la_rpath = -rpath $(libdir)
am__libgpgme_qt_la_SOURCES_DIST = util.h conversion.c get-env.c \
context.h ops.h parsetlv.c parsetlv.h data.h data.c data-fd.c \
@@ -205,21 +206,22 @@ am__libgpgme_qt_la_SOURCES_DIST = util.h conversion.c get-env.c \
encrypt-sign.c decrypt.c decrypt-verify.c verify.c sign.c \
passphrase.c progress.c key.c keylist.c trust-item.c \
trustlist.c import.c export.c genkey.c delete.c edit.c \
- getauditlog.c opassuan.c passwd.c engine.h engine-backend.h \
- engine.c engine-gpg.c status-table.c engine-gpgsm.c \
- assuan-support.c engine-assuan.c engine-gpgconf.c \
+ getauditlog.c opassuan.c passwd.c spawn.c assuan-support.c \
+ engine.h engine-backend.h engine.c engine-gpg.c status-table.c \
+ engine-gpgsm.c engine-assuan.c engine-gpgconf.c \
engine-uiserver.c engine-g13.c vfs-mount.c vfs-create.c \
- gpgconf.c sema.h priv-io.h ath.h posix-util.c posix-sema.c \
- posix-io.c w32-ce.h w32-ce.c w32-util.c w32-sema.c sys-util.h \
- dirinfo.c debug.c debug.h gpgme.c version.c error.c ath.c \
- w32-qt-io.cpp kdpipeiodevice.h kdpipeiodevice.cpp \
- kdpipeiodevice.moc
-@BUILD_W32_QT_TRUE@am_libgpgme_qt_la_OBJECTS = $(am__objects_8) ath.lo \
+ engine-spawn.c gpgconf.c sema.h priv-io.h ath.h posix-util.c \
+ posix-sema.c posix-io.c w32-ce.h w32-ce.c w32-util.c \
+ w32-sema.c sys-util.h dirinfo.c debug.c debug.h gpgme.c \
+ version.c error.c ath.c w32-qt-io.cpp kdpipeiodevice.h \
+ kdpipeiodevice.cpp kdpipeiodevice.moc
+@BUILD_W32_QT_TRUE@am_libgpgme_qt_la_OBJECTS = $(am__objects_4) ath.lo \
@BUILD_W32_QT_TRUE@ w32-qt-io.lo kdpipeiodevice.lo
libgpgme_qt_la_OBJECTS = $(am_libgpgme_qt_la_OBJECTS)
-libgpgme_qt_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
- $(CXXFLAGS) $(libgpgme_qt_la_LDFLAGS) $(LDFLAGS) -o $@
+libgpgme_qt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+ $(AM_CXXFLAGS) $(CXXFLAGS) $(libgpgme_qt_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
@BUILD_W32_QT_TRUE@am_libgpgme_qt_la_rpath = -rpath $(libdir)
am__libgpgme_la_SOURCES_DIST = util.h conversion.c get-env.c context.h \
ops.h parsetlv.c parsetlv.h data.h data.c data-fd.c \
@@ -229,17 +231,17 @@ am__libgpgme_la_SOURCES_DIST = util.h conversion.c get-env.c context.h \
encrypt-sign.c decrypt.c decrypt-verify.c verify.c sign.c \
passphrase.c progress.c key.c keylist.c trust-item.c \
trustlist.c import.c export.c genkey.c delete.c edit.c \
- getauditlog.c opassuan.c passwd.c engine.h engine-backend.h \
- engine.c engine-gpg.c status-table.c engine-gpgsm.c \
- assuan-support.c engine-assuan.c engine-gpgconf.c \
+ getauditlog.c opassuan.c passwd.c spawn.c assuan-support.c \
+ engine.h engine-backend.h engine.c engine-gpg.c status-table.c \
+ engine-gpgsm.c engine-assuan.c engine-gpgconf.c \
engine-uiserver.c engine-g13.c vfs-mount.c vfs-create.c \
- gpgconf.c sema.h priv-io.h ath.h posix-util.c posix-sema.c \
- posix-io.c w32-ce.h w32-ce.c w32-util.c w32-sema.c sys-util.h \
- dirinfo.c debug.c debug.h gpgme.c version.c error.c ath.c \
- w32-io.c
-am_libgpgme_la_OBJECTS = $(am__objects_8) ath.lo $(am__objects_9)
+ engine-spawn.c gpgconf.c sema.h priv-io.h ath.h posix-util.c \
+ posix-sema.c posix-io.c w32-ce.h w32-ce.c w32-util.c \
+ w32-sema.c sys-util.h dirinfo.c debug.c debug.h gpgme.c \
+ version.c error.c ath.c w32-io.c
+am_libgpgme_la_OBJECTS = $(am__objects_4) ath.lo $(am__objects_5)
libgpgme_la_OBJECTS = $(am_libgpgme_la_OBJECTS)
-libgpgme_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+libgpgme_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libgpgme_la_LDFLAGS) $(LDFLAGS) -o $@
PROGRAMS = $(libexec_PROGRAMS) $(noinst_PROGRAMS)
@@ -256,22 +258,42 @@ am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
-LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_@AM_V@)
+am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
+am__v_CXX_0 = @echo " CXX " $@;
CXXLD = $(CXX)
-CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
- --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
- $(LDFLAGS) -o $@
+CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo " CXXLD " $@;
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(libgpgme_glib_la_SOURCES) $(libgpgme_pthread_la_SOURCES) \
$(libgpgme_qt_la_SOURCES) $(libgpgme_la_SOURCES) gpgme-tool.c \
gpgme-w32spawn.c
@@ -291,6 +313,7 @@ CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AS = @AS@
AUTOCONF = @AUTOCONF@
@@ -321,7 +344,6 @@ ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
-G13 = @G13@
GITLOG_TO_CHANGELOG = @GITLOG_TO_CHANGELOG@
GLIBC21 = @GLIBC21@
GLIB_CFLAGS = @GLIB_CFLAGS@
@@ -329,17 +351,13 @@ GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
GLIB_LIBS = @GLIB_LIBS@
GLIB_MKENUMS = @GLIB_MKENUMS@
GOBJECT_QUERY = @GOBJECT_QUERY@
-GPG = @GPG@
-GPGCONF = @GPGCONF@
GPGME_CONFIG_API_VERSION = @GPGME_CONFIG_API_VERSION@
GPGME_CONFIG_CFLAGS = @GPGME_CONFIG_CFLAGS@
GPGME_CONFIG_HOST = @GPGME_CONFIG_HOST@
GPGME_CONFIG_LIBS = @GPGME_CONFIG_LIBS@
-GPGSM = @GPGSM@
GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
-GPG_PATH = @GPG_PATH@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@@ -473,14 +491,6 @@ lib_LTLIBRARIES = libgpgme.la $(ltlib_gpgme_glib) $(ltlib_gpgme_qt) \
@HAVE_DOSISH_SYSTEM_TRUE@ $(am__append_1)
@HAVE_DOSISH_SYSTEM_FALSE@system_components_not_extra =
@HAVE_DOSISH_SYSTEM_TRUE@system_components_not_extra = w32-io.c
-@HAVE_GPGSM_FALSE@gpgsm_components =
-@HAVE_GPGSM_TRUE@gpgsm_components = engine-gpgsm.c
-@HAVE_ASSUAN_FALSE@assuan_components =
-@HAVE_ASSUAN_TRUE@assuan_components = assuan-support.c engine-assuan.c
-@HAVE_GPGCONF_FALSE@gpgconf_components =
-@HAVE_GPGCONF_TRUE@gpgconf_components = engine-gpgconf.c
-@HAVE_G13_FALSE@g13_components =
-@HAVE_G13_TRUE@g13_components = engine-g13.c
@HAVE_UISERVER_FALSE@uiserver_components =
@HAVE_UISERVER_TRUE@uiserver_components = engine-uiserver.c
@@ -501,11 +511,12 @@ main_sources = \
sign.c passphrase.c progress.c \
key.c keylist.c trust-item.c trustlist.c \
import.c export.c genkey.c delete.c edit.c getauditlog.c \
- opassuan.c passwd.c \
+ opassuan.c passwd.c spawn.c assuan-support.c \
engine.h engine-backend.h engine.c engine-gpg.c status-table.c \
- $(gpgsm_components) $(assuan_components) $(gpgconf_components) \
+ engine-gpgsm.c engine-assuan.c engine-gpgconf.c \
$(uiserver_components) \
- $(g13_components) vfs-mount.c vfs-create.c \
+ engine-g13.c vfs-mount.c vfs-create.c \
+ engine-spawn.c \
gpgconf.c \
sema.h priv-io.h $(system_components) sys-util.h dirinfo.c \
debug.c debug.h gpgme.c version.c error.c
@@ -652,13 +663,13 @@ clean-libLTLIBRARIES:
rm -f "$${dir}/so_locations"; \
done
libgpgme-glib.la: $(libgpgme_glib_la_OBJECTS) $(libgpgme_glib_la_DEPENDENCIES) $(EXTRA_libgpgme_glib_la_DEPENDENCIES)
- $(libgpgme_glib_la_LINK) $(am_libgpgme_glib_la_rpath) $(libgpgme_glib_la_OBJECTS) $(libgpgme_glib_la_LIBADD) $(LIBS)
+ $(AM_V_CCLD)$(libgpgme_glib_la_LINK) $(am_libgpgme_glib_la_rpath) $(libgpgme_glib_la_OBJECTS) $(libgpgme_glib_la_LIBADD) $(LIBS)
libgpgme-pthread.la: $(libgpgme_pthread_la_OBJECTS) $(libgpgme_pthread_la_DEPENDENCIES) $(EXTRA_libgpgme_pthread_la_DEPENDENCIES)
- $(libgpgme_pthread_la_LINK) $(am_libgpgme_pthread_la_rpath) $(libgpgme_pthread_la_OBJECTS) $(libgpgme_pthread_la_LIBADD) $(LIBS)
+ $(AM_V_CCLD)$(libgpgme_pthread_la_LINK) $(am_libgpgme_pthread_la_rpath) $(libgpgme_pthread_la_OBJECTS) $(libgpgme_pthread_la_LIBADD) $(LIBS)
libgpgme-qt.la: $(libgpgme_qt_la_OBJECTS) $(libgpgme_qt_la_DEPENDENCIES) $(EXTRA_libgpgme_qt_la_DEPENDENCIES)
- $(libgpgme_qt_la_LINK) $(am_libgpgme_qt_la_rpath) $(libgpgme_qt_la_OBJECTS) $(libgpgme_qt_la_LIBADD) $(LIBS)
+ $(AM_V_CXXLD)$(libgpgme_qt_la_LINK) $(am_libgpgme_qt_la_rpath) $(libgpgme_qt_la_OBJECTS) $(libgpgme_qt_la_LIBADD) $(LIBS)
libgpgme.la: $(libgpgme_la_OBJECTS) $(libgpgme_la_DEPENDENCIES) $(EXTRA_libgpgme_la_DEPENDENCIES)
- $(libgpgme_la_LINK) -rpath $(libdir) $(libgpgme_la_OBJECTS) $(libgpgme_la_LIBADD) $(LIBS)
+ $(AM_V_CCLD)$(libgpgme_la_LINK) -rpath $(libdir) $(libgpgme_la_OBJECTS) $(libgpgme_la_LIBADD) $(LIBS)
install-libexecPROGRAMS: $(libexec_PROGRAMS)
@$(NORMAL_INSTALL)
@list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
@@ -716,10 +727,10 @@ clean-noinstPROGRAMS:
rm -f $$list
gpgme-tool$(EXEEXT): $(gpgme_tool_OBJECTS) $(gpgme_tool_DEPENDENCIES) $(EXTRA_gpgme_tool_DEPENDENCIES)
@rm -f gpgme-tool$(EXEEXT)
- $(LINK) $(gpgme_tool_OBJECTS) $(gpgme_tool_LDADD) $(LIBS)
+ $(AM_V_CCLD)$(LINK) $(gpgme_tool_OBJECTS) $(gpgme_tool_LDADD) $(LIBS)
gpgme-w32spawn$(EXEEXT): $(gpgme_w32spawn_OBJECTS) $(gpgme_w32spawn_DEPENDENCIES) $(EXTRA_gpgme_w32spawn_DEPENDENCIES)
@rm -f gpgme-w32spawn$(EXEEXT)
- $(LINK) $(gpgme_w32spawn_OBJECTS) $(gpgme_w32spawn_LDADD) $(LIBS)
+ $(AM_V_CCLD)$(LINK) $(gpgme_w32spawn_OBJECTS) $(gpgme_w32spawn_LDADD) $(LIBS)
install-binSCRIPTS: $(bin_SCRIPTS)
@$(NORMAL_INSTALL)
@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
@@ -791,6 +802,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/engine-gpg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/engine-gpgconf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/engine-gpgsm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/engine-spawn.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/engine-uiserver.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/engine.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/error.Plo@am__quote@
@@ -818,6 +830,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sig-notation.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sign.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spawn.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status-table.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trust-item.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trustlist.Plo@am__quote@
@@ -837,46 +850,46 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wait.Plo@am__quote@
.c.o:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
-@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
-@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
.cpp.o:
-@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
-@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
-@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
diff --git a/src/assuan-support.c b/src/assuan-support.c
index d06518a..0a11d9f 100644
--- a/src/assuan-support.c
+++ b/src/assuan-support.c
@@ -168,7 +168,8 @@ my_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
fd_items[i].fd = -1;
fd_items[i].dup_to = -1;
- err = _gpgme_io_spawn (name, (char*const*)argv, IOSPAWN_FLAG_NOCLOSE,
+ err = _gpgme_io_spawn (name, (char*const*)argv,
+ (IOSPAWN_FLAG_NOCLOSE | IOSPAWN_FLAG_DETACHED),
fd_items, atfork, atforkvalue, r_pid);
if (! err)
{
diff --git a/src/conversion.c b/src/conversion.c
index b47d6de..d04a6be 100644
--- a/src/conversion.c
+++ b/src/conversion.c
@@ -412,3 +412,24 @@ _gpgme_parse_timestamp (const char *timestamp, char **endp)
else
return (time_t)strtoul (timestamp, endp, 10);
}
+
+
+/* The GPG backend uses OpenPGP algorithm numbers which we need to map
+ to our algorithm numbers. This function MUST not change ERRNO. */
+int
+_gpgme_map_pk_algo (int algo, gpgme_protocol_t protocol)
+{
+ if (protocol == GPGME_PROTOCOL_OPENPGP)
+ {
+ switch (algo)
+ {
+ case 1: case 2: case 3: case 16: case 17: break;
+ case 18: algo = GPGME_PK_ECDH; break;
+ case 19: algo = GPGME_PK_ECDSA; break;
+ case 20: break;
+ default: algo = 0; break; /* Unknown. */
+ }
+ }
+
+ return algo;
+}
diff --git a/src/decrypt.c b/src/decrypt.c
index 63787c7..4742060 100644
--- a/src/decrypt.c
+++ b/src/decrypt.c
@@ -119,7 +119,7 @@ gpgme_op_decrypt_result (gpgme_ctx_t ctx)
static gpgme_error_t
-parse_enc_to (char *args, gpgme_recipient_t *recp)
+parse_enc_to (char *args, gpgme_recipient_t *recp, gpgme_protocol_t protocol)
{
gpgme_recipient_t rec;
char *tail;
@@ -155,7 +155,7 @@ parse_enc_to (char *args, gpgme_recipient_t *recp)
if (*args)
{
gpg_err_set_errno (0);
- rec->pubkey_algo = strtol (args, &tail, 0);
+ rec->pubkey_algo = _gpgme_map_pk_algo (strtol (args, &tail, 0), protocol);
if (errno || args == tail || *tail != ' ')
{
/* The crypto backend does not behave. */
@@ -261,7 +261,7 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
break;
case GPGME_STATUS_ENC_TO:
- err = parse_enc_to (args, opd->last_recipient_p);
+ err = parse_enc_to (args, opd->last_recipient_p, ctx->protocol);
if (err)
return err;
diff --git a/src/dirinfo.c b/src/dirinfo.c
index 27c0dd7..8824c9a 100644
--- a/src/dirinfo.c
+++ b/src/dirinfo.c
@@ -38,24 +38,38 @@ enum
{
WANT_HOMEDIR,
WANT_AGENT_SOCKET,
+ WANT_GPGCONF_NAME,
WANT_GPG_NAME,
WANT_GPGSM_NAME,
WANT_G13_NAME,
- WANT_UISRV_SOCKET
+ WANT_UISRV_SOCKET,
+ WANT_GPG_ONE_MODE
};
/* Values retrieved via gpgconf and cached here. */
static struct {
int valid; /* Cached information is valid. */
+ int disable_gpgconf;
char *homedir;
char *agent_socket;
+ char *gpgconf_name;
char *gpg_name;
char *gpgsm_name;
char *g13_name;
char *uisrv_socket;
+ int gpg_one_mode; /* System is in gpg1 mode. */
} dirinfo;
+
+/* Helper function to be used only by gpgme_set_global_flag. */
+void
+_gpgme_dirinfo_disable_gpgconf (void)
+{
+ dirinfo.disable_gpgconf = 1;
+}
+
+
/* Parse the output of "gpgconf --list-dirs". This function expects
that DIRINFO_LOCK is held by the caller. If COMPONENTS is set, the
output of --list-components is expected. */
@@ -142,7 +156,8 @@ read_gpgconf_dirs (const char *pgmname, int components)
cfd[0].fd = rp[1];
- status = _gpgme_io_spawn (pgmname, argv, 0, cfd, NULL, NULL, NULL);
+ status = _gpgme_io_spawn (pgmname, argv, IOSPAWN_FLAG_DETACHED,
+ cfd, NULL, NULL, NULL);
if (status < 0)
{
_gpgme_io_close (rp[0]);
@@ -194,30 +209,34 @@ get_gpgconf_item (int what)
LOCK (dirinfo_lock);
if (!dirinfo.valid)
{
- const char *pgmname;
+ char *pgmname;
- pgmname = _gpgme_get_gpgconf_path ();
+ pgmname = dirinfo.disable_gpgconf? NULL : _gpgme_get_gpgconf_path ();
if (pgmname && access (pgmname, F_OK))
{
_gpgme_debug (DEBUG_INIT,
- "gpgme_dinfo: gpgconf='%s' [not installed]\n", pgmname);
+ "gpgme-dinfo: gpgconf='%s' [not installed]\n", pgmname);
+ free (pgmname);
pgmname = NULL; /* Not available. */
}
else
- _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: gpgconf='%s'\n",
+ _gpgme_debug (DEBUG_INIT, "gpgme-dinfo: gpgconf='%s'\n",
pgmname? pgmname : "[null]");
if (!pgmname)
{
/* Probably gpgconf is not installed. Assume we are using
GnuPG-1. */
+ dirinfo.gpg_one_mode = 1;
pgmname = _gpgme_get_gpg_path ();
if (pgmname)
- dirinfo.gpg_name = strdup (pgmname);
+ dirinfo.gpg_name = pgmname;
}
else
{
+ dirinfo.gpg_one_mode = 0;
read_gpgconf_dirs (pgmname, 0);
read_gpgconf_dirs (pgmname, 1);
+ dirinfo.gpgconf_name = pgmname;
}
/* Even if the reading of the directories failed (e.g. due to an
too old version gpgconf or no gpgconf at all), we need to
@@ -227,32 +246,34 @@ get_gpgconf_item (int what)
allocated. */
dirinfo.valid = 1;
if (dirinfo.gpg_name)
- _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: gpg='%s'\n",
+ _gpgme_debug (DEBUG_INIT, "gpgme-dinfo: gpg='%s'\n",
dirinfo.gpg_name);
if (dirinfo.g13_name)
- _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: g13='%s'\n",
+ _gpgme_debug (DEBUG_INIT, "gpgme-dinfo: g13='%s'\n",
dirinfo.g13_name);
if (dirinfo.gpgsm_name)
- _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: gpgsm='%s'\n",
+ _gpgme_debug (DEBUG_INIT, "gpgme-dinfo: gpgsm='%s'\n",
dirinfo.gpgsm_name);
if (dirinfo.homedir)
- _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: homedir='%s'\n",
+ _gpgme_debug (DEBUG_INIT, "gpgme-dinfo: homedir='%s'\n",
dirinfo.homedir);
if (dirinfo.agent_socket)
- _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: agent='%s'\n",
+ _gpgme_debug (DEBUG_INIT, "gpgme-dinfo: agent='%s'\n",
dirinfo.agent_socket);
if (dirinfo.uisrv_socket)
- _gpgme_debug (DEBUG_INIT, "gpgme_dinfo: uisrv='%s'\n",
+ _gpgme_debug (DEBUG_INIT, "gpgme-dinfo: uisrv='%s'\n",
dirinfo.uisrv_socket);
}
switch (what)
{
case WANT_HOMEDIR: result = dirinfo.homedir; break;
case WANT_AGENT_SOCKET: result = dirinfo.agent_socket; break;
+ case WANT_GPGCONF_NAME: result = dirinfo.gpgconf_name; break;
case WANT_GPG_NAME: result = dirinfo.gpg_name; break;
case WANT_GPGSM_NAME: result = dirinfo.gpgsm_name; break;
case WANT_G13_NAME: result = dirinfo.g13_name; break;
case WANT_UISRV_SOCKET: result = dirinfo.uisrv_socket; break;
+ case WANT_GPG_ONE_MODE: result = dirinfo.gpg_one_mode? "1":NULL; break;
}
UNLOCK (dirinfo_lock);
return result;
@@ -294,14 +315,11 @@ _gpgme_get_default_g13_name (void)
return get_gpgconf_item (WANT_G13_NAME);
}
-/* Return the default gpgconf file name. Returns NULL if not known.
- Because gpgconf is the binary used to retrieved all these default
- names, this function is merely a simple wrapper around the function
- used to locate this binary. */
+/* Return the default gpgconf file name. Returns NULL if not known. */
const char *
_gpgme_get_default_gpgconf_name (void)
{
- return _gpgme_get_gpgconf_path ();
+ return get_gpgconf_item (WANT_GPGCONF_NAME);
}
/* Return the default UI-server socket name. Returns NULL if not
@@ -311,3 +329,56 @@ _gpgme_get_default_uisrv_socket (void)
{
return get_gpgconf_item (WANT_UISRV_SOCKET);
}
+
+/* Return true if we are in GnuPG-1 mode - ie. no gpgconf and agent
+ being optional. */
+int
+_gpgme_in_gpg_one_mode (void)
+{
+ return !!get_gpgconf_item (WANT_GPG_ONE_MODE);
+}
+
+
+
+/* Helper function to return the basename of the passed filename. */
+const char *
+_gpgme_get_basename (const char *name)
+{
+ const char *s;
+
+ if (!name || !*name)
+ return name;
+ for (s = name + strlen (name) -1; s >= name; s--)
+ if (*s == '/'
+#ifdef HAVE_W32_SYSTEM
+ || *s == '\\' || *s == ':'
+#endif
+ )
+ return s+1;
+ return name;
+}
+
+
+/* Return default values for various directories and file names. */
+const char *
+gpgme_get_dirinfo (const char *what)
+{
+ if (!what)
+ return NULL;
+ else if (!strcmp (what, "homedir"))
+ return get_gpgconf_item (WANT_HOMEDIR);
+ else if (!strcmp (what, "agent-socket"))
+ return get_gpgconf_item (WANT_AGENT_SOCKET);
+ else if (!strcmp (what, "uiserver-socket"))
+ return get_gpgconf_item (WANT_UISRV_SOCKET);
+ else if (!strcmp (what, "gpgconf-name"))
+ return get_gpgconf_item (WANT_GPGCONF_NAME);
+ else if (!strcmp (what, "gpg-name"))
+ return get_gpgconf_item (WANT_GPG_NAME);
+ else if (!strcmp (what, "gpgsm-name"))
+ return get_gpgconf_item (WANT_GPGSM_NAME);
+ else if (!strcmp (what, "g13-name"))
+ return get_gpgconf_item (WANT_G13_NAME);
+ else
+ return NULL;
+}
diff --git a/src/engine-assuan.c b/src/engine-assuan.c
index 5ef3047..663b2ea 100644
--- a/src/engine-assuan.c
+++ b/src/engine-assuan.c
@@ -783,5 +783,6 @@ struct engine_ops _gpgme_engine_ops_assuan =
llass_cancel,
llass_cancel_op,
NULL, /* passwd */
- NULL /* set_pinentry_mode */
+ NULL, /* set_pinentry_mode */
+ NULL /* opspawn */
};
diff --git a/src/engine-backend.h b/src/engine-backend.h
index a4c0eb2..b3cc412 100644
--- a/src/engine-backend.h
+++ b/src/engine-backend.h
@@ -124,24 +124,37 @@ struct engine_ops
/* Set the pinentry mode. */
gpgme_error_t (*set_pinentry_mode) (void *engine, gpgme_pinentry_mode_t mode);
+
+ /* The spawn command. */
+ gpgme_error_t (*opspawn) (void * engine,
+ const char *file, const char *argv[],
+ gpgme_data_t datain,
+ gpgme_data_t dataout,
+ gpgme_data_t dataerr, unsigned int flags);
+
};
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
-#ifdef ENABLE_ASSUAN
extern struct engine_ops _gpgme_engine_ops_assuan; /* Low-level Assuan. */
-#endif
-#ifdef ENABLE_G13
extern struct engine_ops _gpgme_engine_ops_g13; /* Crypto VFS. */
-#endif
#ifdef ENABLE_UISERVER
extern struct engine_ops _gpgme_engine_ops_uiserver;
#endif
+extern struct engine_ops _gpgme_engine_ops_spawn; /* Spawn engine. */
+
+
+/* Prototypes for extra functions in engine-gpgconf.c */
+gpgme_error_t _gpgme_conf_arg_new (gpgme_conf_arg_t *arg_p,
+ gpgme_conf_type_t type, const 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);
+
+
#endif /* ENGINE_BACKEND_H */
diff --git a/src/engine-g13.c b/src/engine-g13.c
index b97e0b4..a9717ee 100644
--- a/src/engine-g13.c
+++ b/src/engine-g13.c
@@ -107,7 +107,7 @@ g13_get_version (const char *file_name)
static const char *
g13_get_req_version (void)
{
- return NEED_G13_VERSION;
+ return "2.1.0";
}
@@ -216,6 +216,7 @@ g13_new (void **engine, const char *file_name, const char *home_dir)
{
gpgme_error_t err = 0;
engine_g13_t g13;
+ const char *pgmname;
int argc;
const char *argv[5];
char *dft_display = NULL;
@@ -232,8 +233,9 @@ g13_new (void **engine, const char *file_name, const char *home_dir)
g13->status_cb.tag = 0;
g13->status_cb.data = g13;
+ pgmname = file_name ? file_name : _gpgme_get_default_g13_name ();
argc = 0;
- argv[argc++] = "g13";
+ argv[argc++] = _gpgme_get_basename (pgmname);
if (home_dir)
{
argv[argc++] = "--homedir";
@@ -250,13 +252,11 @@ g13_new (void **engine, const char *file_name, const char *home_dir)
assuan_ctx_set_system_hooks (g13->assuan_ctx, &_gpgme_assuan_system_hooks);
#if USE_DESCRIPTOR_PASSING
- err = assuan_pipe_connect
- (g13->assuan_ctx, file_name ? file_name : _gpgme_get_default_g13_name (),
- argv, NULL, NULL, NULL, ASSUAN_PIPE_CONNECT_FDPASSING);
+ err = assuan_pipe_connect (g13->assuan_ctx, pgmname, argv,
+ NULL, NULL, NULL, ASSUAN_PIPE_CONNECT_FDPASSING);
#else
- err = assuan_pipe_connect
- (g13->assuan_ctx, file_name ? file_name : _gpgme_get_default_g13_name (),
- argv, NULL, NULL, NULL, 0);
+ err = assuan_pipe_connect (g13->assuan_ctx, pgmname, argv,
+ NULL, NULL, NULL, 0);
#endif
if (err)
goto leave;
@@ -799,5 +799,6 @@ struct engine_ops _gpgme_engine_ops_g13 =
g13_cancel,
g13_cancel_op,
NULL, /* passwd */
- NULL /* set_pinentry_mode */
+ NULL, /* set_pinentry_mode */
+ NULL /* opspawn */
};
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 36f035a..ede098e 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -1,7 +1,7 @@
/* engine-gpg.c - Gpg Engine.
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2009, 2010, 2012 g10 Code GmbH
+ 2009, 2010, 2012, 2013 g10 Code GmbH
This file is part of GPGME.
@@ -303,7 +303,7 @@ gpg_get_version (const char *file_name)
static const char *
gpg_get_req_version (void)
{
- return NEED_GPG_VERSION;
+ return "1.4.0";
}
@@ -718,7 +718,7 @@ gpg_set_command_handler (void *engine, engine_command_handler_t fnc,
static gpgme_error_t
-build_argv (engine_gpg_t gpg)
+build_argv (engine_gpg_t gpg, const char *pgmname)
{
gpgme_error_t err;
struct arg_and_data_s *a;
@@ -729,15 +729,20 @@ build_argv (engine_gpg_t gpg)
int use_agent = 0;
char *p;
- /* We don't want to use the agent with a malformed environment
- variable. This is only a very basic test but sufficient to make
- our life in the regression tests easier. */
- err = _gpgme_getenv ("GPG_AGENT_INFO", &p);
- if (err)
- return err;
- use_agent = (p && strchr (p, ':'));
- if (p)
- free (p);
+ if (_gpgme_in_gpg_one_mode ())
+ {
+ /* In GnuPG-1 mode we don't want to use the agent with a
+ malformed environment variable. This is only a very basic
+ test but sufficient to make our life in the regression tests
+ easier. With GnuPG-2 the agent is anyway required and on
+ modern installations GPG_AGENT_INFO is optional. */
+ err = _gpgme_getenv ("GPG_AGENT_INFO", &p);
+ if (err)
+ return err;
+ use_agent = (p && strchr (p, ':'));
+ if (p)
+ free (p);
+ }
if (gpg->argv)
{
@@ -788,7 +793,7 @@ build_argv (engine_gpg_t gpg)
}
argc = datac = 0;
- argv[argc] = strdup ("gpg"); /* argv[0] */
+ argv[argc] = strdup (_gpgme_get_basename (pgmname)); /* argv[0] */
if (!argv[argc])
{
int saved_err = gpg_error_from_syserror ();
@@ -1296,6 +1301,7 @@ start (engine_gpg_t gpg)
int status;
struct spawn_fd_item_s *fd_list;
pid_t pid;
+ const char *pgmname;
if (!gpg)
return gpg_error (GPG_ERR_INV_VALUE);
@@ -1321,7 +1327,8 @@ start (engine_gpg_t gpg)
return rc;
}
- rc = build_argv (gpg);
+ pgmname = gpg->file_name ? gpg->file_name : _gpgme_get_default_gpg_name ();
+ rc = build_argv (gpg, pgmname);
if (rc)
return rc;
@@ -1355,9 +1362,8 @@ start (engine_gpg_t gpg)
fd_list[n].fd = -1;
fd_list[n].dup_to = -1;
- status = _gpgme_io_spawn (gpg->file_name ? gpg->file_name :
- _gpgme_get_default_gpg_name (), gpg->argv,
- IOSPAWN_FLAG_ALLOW_SET_FG,
+ status = _gpgme_io_spawn (pgmname, gpg->argv,
+ (IOSPAWN_FLAG_DETACHED |IOSPAWN_FLAG_ALLOW_SET_FG),
fd_list, NULL, NULL, &pid);
{
int saved_err = gpg_error_from_syserror ();
@@ -1656,6 +1662,9 @@ gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
if (!err && use_armor)
err = add_arg (gpg, "--armor");
+ if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
+ err = add_arg (gpg, "--compress-algo=none");
+
if (!symmetric)
{
/* If we know that all recipients are valid (full or ultimate trust)
@@ -1713,6 +1722,9 @@ gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
if (!err && use_armor)
err = add_arg (gpg, "--armor");
+ if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
+ err = add_arg (gpg, "--compress-algo=none");
+
if (!symmetric)
{
/* If we know that all recipients are valid (full or ultimate trust)
@@ -2443,5 +2455,6 @@ struct engine_ops _gpgme_engine_ops_gpg =
gpg_cancel,
NULL, /* cancel_op */
gpg_passwd,
- gpg_set_pinentry_mode
+ gpg_set_pinentry_mode,
+ NULL /* opspawn */
};
diff --git a/src/engine-gpgconf.c b/src/engine-gpgconf.c
index 1d457bb..a2407ac 100644
--- a/src/engine-gpgconf.c
+++ b/src/engine-gpgconf.c
@@ -68,7 +68,7 @@ gpgconf_get_version (const char *file_name)
static const char *
gpgconf_get_req_version (void)
{
- return NEED_GPGCONF_VERSION;
+ return "2.0.4";
}
@@ -228,7 +228,8 @@ gpgconf_read (void *engine, char *arg1, char *arg2,
cfd[0].fd = rp[1];
- status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL, NULL, NULL);
+ status = _gpgme_io_spawn (gpgconf->file_name, argv,
+ IOSPAWN_FLAG_DETACHED, cfd, NULL, NULL, NULL);
if (status < 0)
{
_gpgme_io_close (rp[0]);
@@ -697,7 +698,8 @@ gpgconf_write (void *engine, char *arg1, char *arg2, gpgme_data_t conf)
cfd[0].fd = rp[0];
- status = _gpgme_io_spawn (gpgconf->file_name, argv, 0, cfd, NULL, NULL, NULL);
+ status = _gpgme_io_spawn (gpgconf->file_name, argv,
+ IOSPAWN_FLAG_DETACHED, cfd, NULL, NULL, NULL);
if (status < 0)
{
_gpgme_io_close (rp[0]);
@@ -961,5 +963,6 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
NULL, /* cancel */
NULL, /* cancel_op */
NULL, /* passwd */
- NULL /* set_pinentry_mode */
+ NULL, /* set_pinentry_mode */
+ NULL /* opspawn */
};
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index a7888ca..710bf14 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -127,7 +127,7 @@ gpgsm_get_version (const char *file_name)
static const char *
gpgsm_get_req_version (void)
{
- return NEED_GPGSM_VERSION;
+ return "2.0.4";
}
@@ -239,6 +239,7 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
{
gpgme_error_t err = 0;
engine_gpgsm_t gpgsm;
+ const char *pgmname;
const char *argv[5];
int argc;
#if !USE_DESCRIPTOR_PASSING
@@ -321,8 +322,10 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
child_fds[3] = -1;
#endif
+ pgmname = file_name ? file_name : _gpgme_get_default_gpgsm_name ();
+
argc = 0;
- argv[argc++] = "gpgsm";
+ argv[argc++] = _gpgme_get_basename (pgmname);
if (home_dir)
{
argv[argc++] = "--homedir";
@@ -339,10 +342,8 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
assuan_ctx_set_system_hooks (gpgsm->assuan_ctx, &_gpgme_assuan_system_hooks);
#if USE_DESCRIPTOR_PASSING
- err = assuan_pipe_connect
- (gpgsm->assuan_ctx,
- file_name ? file_name : _gpgme_get_default_gpgsm_name (),
- argv, NULL, NULL, NULL, ASSUAN_PIPE_CONNECT_FDPASSING);
+ err = assuan_pipe_connect (gpgsm->assuan_ctx, pgmname, argv,
+ NULL, NULL, NULL, ASSUAN_PIPE_CONNECT_FDPASSING);
#else
{
assuan_fd_t achild_fds[4];
@@ -352,10 +353,8 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir)
for (i = 0; i < 4; i++)
achild_fds[i] = (assuan_fd_t) child_fds[i];
- err = assuan_pipe_connect
- (gpgsm->assuan_ctx,
- file_name ? file_name : _gpgme_get_default_gpgsm_name (),
- argv, achild_fds, NULL, NULL, 0);
+ err = assuan_pipe_connect (gpgsm->assuan_ctx, pgmname, argv,
+ achild_fds, NULL, NULL, 0);
/* For now... */
for (i = 0; i < 4; i++)
@@ -837,7 +836,7 @@ status_handler (void *opaque, int fd)
else
{
*aline = newline;
- gpgsm->colon.attic.linesize = *alinelen + linelen + 1;
+ gpgsm->colon.attic.linesize += linelen + 1;
}
}
if (!err)
@@ -1989,5 +1988,6 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
gpgsm_cancel,
NULL, /* cancel_op */
gpgsm_passwd,
- NULL /* set_pinentry_mode */
+ NULL, /* set_pinentry_mode */
+ NULL /* opspawn */
};
diff --git a/src/engine-spawn.c b/src/engine-spawn.c
new file mode 100644
index 0000000..8ffc628
--- /dev/null
+++ b/src/engine-spawn.c
@@ -0,0 +1,475 @@
+/* engine-spawn.c - Run an arbitrary program
+ Copyright (C) 2014 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#include "gpgme.h"
+#include "util.h"
+#include "ops.h"
+#include "wait.h"
+#include "context.h" /*temp hack until we have GpmeData methods to do I/O */
+#include "priv-io.h"
+#include "sema.h"
+#include "debug.h"
+
+#include "engine-backend.h"
+
+
+/* This type is used to build a list of data sources/sinks. */
+struct datalist_s
+{
+ struct datalist_s *next;
+ gpgme_data_t data; /* The data object. */
+ int inbound; /* True if this is used for reading from the peer. */
+ int dup_to; /* The fd used by the peer. */
+};
+
+
+struct fd_data_map_s
+{
+ gpgme_data_t data;
+ int inbound; /* True if this is used for reading from the peer. */
+ int dup_to; /* Dup the fd to that one. */
+ int fd; /* The fd to use. */
+ int peer_fd; /* The other side of the pipe. */
+ void *tag; /* Tag used by the I/O callback. */
+};
+
+
+struct engine_spawn
+{
+ struct datalist_s *arglist;
+ struct datalist_s **argtail;
+
+ struct fd_data_map_s *fd_data_map;
+
+ struct gpgme_io_cbs io_cbs;
+};
+typedef struct engine_spawn *engine_spawn_t;
+
+
+static void engspawn_io_event (void *engine,
+ gpgme_event_io_t type, void *type_data);
+static gpgme_error_t engspawn_cancel (void *engine);
+
+
+
+static void
+close_notify_handler (int fd, void *opaque)
+{
+ engine_spawn_t esp = opaque;
+ int i;
+
+ assert (fd != -1);
+
+ if (esp->fd_data_map)
+ {
+ for (i = 0; esp->fd_data_map[i].data; i++)
+ {
+ if (esp->fd_data_map[i].fd == fd)
+ {
+ if (esp->fd_data_map[i].tag)
+ (*esp->io_cbs.remove) (esp->fd_data_map[i].tag);
+ esp->fd_data_map[i].fd = -1;
+ break;
+ }
+ if (esp->fd_data_map[i].peer_fd == fd)
+ {
+ esp->fd_data_map[i].peer_fd = -1;
+ break;
+ }
+ }
+ }
+}
+
+
+static gpgme_error_t
+add_data (engine_spawn_t esp, gpgme_data_t data, int dup_to, int inbound)
+{
+ struct datalist_s *a;
+
+ assert (esp);
+ assert (data);
+
+ a = malloc (sizeof *a - 1);
+ if (!a)
+ return gpg_error_from_syserror ();
+ a->next = NULL;
+ a->data = data;
+ a->inbound = inbound;
+ a->dup_to = dup_to;
+ *esp->argtail = a;
+ esp->argtail = &a->next;
+ return 0;
+}
+
+
+static void
+free_fd_data_map (struct fd_data_map_s *fd_data_map)
+{
+ int i;
+
+ if (!fd_data_map)
+ return;
+
+ for (i = 0; fd_data_map[i].data; i++)
+ {
+ if (fd_data_map[i].fd != -1)
+ _gpgme_io_close (fd_data_map[i].fd);
+ if (fd_data_map[i].peer_fd != -1)
+ _gpgme_io_close (fd_data_map[i].peer_fd);
+ /* Don't release data because this is only a reference. */
+ }
+ free (fd_data_map);
+}
+
+
+static gpgme_error_t
+build_fd_data_map (engine_spawn_t esp)
+{
+ struct datalist_s *a;
+ size_t datac;
+ int fds[2];
+
+ for (datac = 0, a = esp->arglist; a; a = a->next)
+ if (a->data)
+ datac++;
+
+ free_fd_data_map (esp->fd_data_map);
+ esp->fd_data_map = calloc (datac + 1, sizeof *esp->fd_data_map);
+ if (!esp->fd_data_map)
+ return gpg_error_from_syserror ();
+
+ for (datac = 0, a = esp->arglist; a; a = a->next)
+ {
+ assert (a->data);
+
+ if (_gpgme_io_pipe (fds, a->inbound ? 1 : 0) == -1)
+ {
+ free (esp->fd_data_map);
+ esp->fd_data_map = NULL;
+ return gpg_error_from_syserror ();
+ }
+ if (_gpgme_io_set_close_notify (fds[0], close_notify_handler, esp)
+ || _gpgme_io_set_close_notify (fds[1], close_notify_handler, esp))
+ {
+ /* FIXME: Need error cleanup. */
+ return gpg_error (GPG_ERR_GENERAL);
+ }
+
+ esp->fd_data_map[datac].inbound = a->inbound;
+ if (a->inbound)
+ {
+ esp->fd_data_map[datac].fd = fds[0];
+ esp->fd_data_map[datac].peer_fd = fds[1];
+ }
+ else
+ {
+ esp->fd_data_map[datac].fd = fds[1];
+ esp->fd_data_map[datac].peer_fd = fds[0];
+ }
+ esp->fd_data_map[datac].data = a->data;
+ esp->fd_data_map[datac].dup_to = a->dup_to;
+ datac++;
+ }
+
+ return 0;
+}
+
+
+static gpgme_error_t
+add_io_cb (engine_spawn_t esp, int fd, int dir, gpgme_io_cb_t handler,
+ void *data, void **tag)
+{
+ gpgme_error_t err;
+
+ err = (*esp->io_cbs.add) (esp->io_cbs.add_priv, fd, dir, handler, data, tag);
+ if (err)
+ return err;
+ if (!dir) /* Fixme: Kludge around poll() problem. */
+ err = _gpgme_io_set_nonblocking (fd);
+ return err;
+}
+
+
+static gpgme_error_t
+engspawn_start (engine_spawn_t esp, const char *file, const char *argv[],
+ unsigned int flags)
+{
+ gpgme_error_t err;
+ int i, n;
+ int status;
+ struct spawn_fd_item_s *fd_list;
+ pid_t pid;
+ unsigned int spflags;
+ const char *save_argv0 = NULL;
+
+ if (!esp || !file || !argv || !argv[0])
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ spflags = 0;
+ if ((flags & GPGME_SPAWN_DETACHED))
+ spflags |= IOSPAWN_FLAG_DETACHED;
+ if ((flags & GPGME_SPAWN_ALLOW_SET_FG))
+ spflags |= IOSPAWN_FLAG_ALLOW_SET_FG;
+
+
+ err = build_fd_data_map (esp);
+ if (err)
+ return err;
+
+ n = 0;
+ for (i = 0; esp->fd_data_map[i].data; i++)
+ n++;
+ fd_list = calloc (n+1, sizeof *fd_list);
+ if (!fd_list)
+ return gpg_error_from_syserror ();
+
+ /* Build the fd list for the child. */
+ n = 0;
+ for (i = 0; esp->fd_data_map[i].data; i++)
+ {
+ fd_list[n].fd = esp->fd_data_map[i].peer_fd;
+ fd_list[n].dup_to = esp->fd_data_map[i].dup_to;
+ n++;
+ }
+ fd_list[n].fd = -1;
+ fd_list[n].dup_to = -1;
+
+ if (argv[0] && !*argv[0])
+ {
+ save_argv0 = argv[0];
+ argv[0] = _gpgme_get_basename (file);
+ }
+ status = _gpgme_io_spawn (file, (char * const *)argv, spflags,
+ fd_list, NULL, NULL, &pid);
+ if (save_argv0)
+ argv[0] = save_argv0;
+ free (fd_list);
+ if (status == -1)
+ return gpg_error_from_syserror ();
+
+ for (i = 0; esp->fd_data_map[i].data; i++)
+ {
+ err = add_io_cb (esp, esp->fd_data_map[i].fd,
+ esp->fd_data_map[i].inbound,
+ esp->fd_data_map[i].inbound
+ ? _gpgme_data_inbound_handler
+ : _gpgme_data_outbound_handler,
+ esp->fd_data_map[i].data, &esp->fd_data_map[i].tag);
+ if (err)
+ return err; /* FIXME: kill the child */
+ }
+
+ engspawn_io_event (esp, GPGME_EVENT_START, NULL);
+
+ return 0;
+}
+
+
+
+/*
+ Public functions
+ */
+
+static const char *
+engspawn_get_file_name (void)
+{
+ return "/nonexistent";
+}
+
+
+static char *
+engspawn_get_version (const char *file_name)
+{
+ (void)file_name;
+ return strdup ("1.0");
+}
+
+
+static const char *
+engspawn_get_req_version (void)
+{
+ return "1.0";
+}
+
+
+static gpgme_error_t
+engspawn_new (void **engine, const char *file_name, const char *home_dir)
+{
+ engine_spawn_t esp;
+
+ (void)file_name;
+ (void)home_dir;
+
+ esp = calloc (1, sizeof *esp);
+ if (!esp)
+ return gpg_error_from_syserror ();
+
+ esp->argtail = &esp->arglist;
+ *engine = esp;
+ return 0;
+}
+
+
+static void
+engspawn_release (void *engine)
+{
+ engine_spawn_t esp = engine;
+
+ if (!esp)
+ return;
+
+ engspawn_cancel (engine);
+
+ while (esp->arglist)
+ {
+ struct datalist_s *next = esp->arglist->next;
+
+ if (esp->arglist)
+ free (esp->arglist);
+ esp->arglist = next;
+ }
+
+ free (esp);
+}
+
+
+static void
+engspawn_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
+{
+ engine_spawn_t esp = engine;
+
+ esp->io_cbs = *io_cbs;
+}
+
+
+static void
+engspawn_io_event (void *engine, gpgme_event_io_t type, void *type_data)
+{
+ engine_spawn_t esp = engine;
+
+ TRACE3 (DEBUG_ENGINE, "gpgme:engspawn_io_event", esp,
+ "event %p, type %d, type_data %p",
+ esp->io_cbs.event, type, type_data);
+ if (esp->io_cbs.event)
+ (*esp->io_cbs.event) (esp->io_cbs.event_priv, type, type_data);
+}
+
+
+static gpgme_error_t
+engspawn_cancel (void *engine)
+{
+ engine_spawn_t esp = engine;
+
+ if (!esp)
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ if (esp->fd_data_map)
+ {
+ free_fd_data_map (esp->fd_data_map);
+ esp->fd_data_map = NULL;
+ }
+
+ return 0;
+}
+
+
+static gpgme_error_t
+engspawn_op_spawn (void *engine,
+ const char *file, const char *argv[],
+ gpgme_data_t datain,
+ gpgme_data_t dataout, gpgme_data_t dataerr,
+ unsigned int flags)
+{
+ engine_spawn_t esp = engine;
+ gpgme_error_t err = 0;
+
+ if (datain)
+ err = add_data (esp, datain, 0, 0);
+ if (!err && dataout)
+ err = add_data (esp, dataout, 1, 1);
+ if (!err && dataerr)
+ err = add_data (esp, dataerr, 2, 1);
+
+ if (!err)
+ err = engspawn_start (esp, file, argv, flags);
+
+ return err;
+}
+
+
+
+struct engine_ops _gpgme_engine_ops_spawn =
+ {
+ /* Static functions. */
+ engspawn_get_file_name,
+ NULL, /* get_home_dir */
+ engspawn_get_version,
+ engspawn_get_req_version,
+ engspawn_new,
+
+ /* Member functions. */
+ engspawn_release,
+ NULL, /* reset */
+ NULL, /* set_status_handler */
+ NULL, /* set_command_handler */
+ NULL, /* set_colon_line_handler */
+ NULL, /* set_locale */
+ NULL, /* set_protocol */
+ NULL, /* decrypt */
+ NULL, /* decrypt_verify */
+ 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 */
+ NULL, /* opassuan_transact */
+ NULL, /* conf_load */
+ NULL, /* conf_save */
+ engspawn_set_io_cbs,
+ engspawn_io_event, /* io_event */
+ engspawn_cancel, /* cancel */
+ NULL, /* cancel_op */
+ NULL, /* passwd */
+ NULL, /* set_pinentry_mode */
+ engspawn_op_spawn /* opspawn */
+ };
diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c
index 350b609..2738c36 100644
--- a/src/engine-uiserver.c
+++ b/src/engine-uiserver.c
@@ -698,7 +698,7 @@ status_handler (void *opaque, int fd)
else
{
*aline = newline;
- uiserver->colon.attic.linesize = *alinelen + linelen + 1;
+ uiserver->colon.attic.linesize += linelen + 1;
}
}
if (!err)
@@ -1340,5 +1340,6 @@ struct engine_ops _gpgme_engine_ops_uiserver =
uiserver_cancel,
NULL, /* cancel_op */
NULL, /* passwd */
- NULL /* set_pinentry_mode */
+ NULL, /* set_pinentry_mode */
+ NULL /* opspawn */
};
diff --git a/src/engine.c b/src/engine.c
index 09f379c..ff015c0 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -46,31 +46,16 @@ struct engine
static struct engine_ops *engine_ops[] =
{
&_gpgme_engine_ops_gpg, /* OpenPGP. */
-#ifdef ENABLE_GPGSM
&_gpgme_engine_ops_gpgsm, /* CMS. */
-#else
- NULL,
-#endif
-#ifdef ENABLE_GPGCONF
&_gpgme_engine_ops_gpgconf, /* gpg-conf. */
-#else
- NULL,
-#endif
-#ifdef ENABLE_ASSUAN
&_gpgme_engine_ops_assuan, /* Low-Level Assuan. */
-#else
- NULL,
-#endif
-#ifdef ENABLE_G13
&_gpgme_engine_ops_g13, /* Crypto VFS. */
-#else
- NULL,
-#endif
#ifdef ENABLE_UISERVER
- &_gpgme_engine_ops_uiserver /* UI-Server. */
+ &_gpgme_engine_ops_uiserver, /* UI-Server. */
#else
- NULL
+ NULL,
#endif
+ &_gpgme_engine_ops_spawn
};
@@ -198,6 +183,8 @@ _gpgme_engine_info_release (gpgme_engine_info_t info)
gpgme_error_t
gpgme_get_engine_info (gpgme_engine_info_t *info)
{
+ gpgme_error_t err;
+
LOCK (engine_info_lock);
if (!engine_info)
{
@@ -207,9 +194,11 @@ gpgme_get_engine_info (gpgme_engine_info_t *info)
GPGME_PROTOCOL_GPGCONF,
GPGME_PROTOCOL_ASSUAN,
GPGME_PROTOCOL_G13,
- GPGME_PROTOCOL_UISERVER };
+ GPGME_PROTOCOL_UISERVER,
+ GPGME_PROTOCOL_SPAWN };
unsigned int proto;
+ err = 0;
for (proto = 0; proto < DIM (proto_list); proto++)
{
const char *ofile_name = engine_get_file_name (proto_list[proto]);
@@ -221,13 +210,24 @@ gpgme_get_engine_info (gpgme_engine_info_t *info)
continue;
file_name = strdup (ofile_name);
- home_dir = ohome_dir? strdup (ohome_dir): NULL;
+ if (!file_name)
+ err = gpg_error_from_syserror ();
+
+ if (ohome_dir)
+ {
+ home_dir = strdup (ohome_dir);
+ if (!home_dir && !err)
+ err = gpg_error_from_syserror ();
+ }
+ else
+ home_dir = NULL;
*lastp = malloc (sizeof (*engine_info));
- if (!*lastp || !file_name)
- {
- int saved_err = gpg_error_from_syserror ();
+ if (!*lastp && !err)
+ err = gpg_error_from_syserror ();
+ if (err)
+ {
_gpgme_engine_info_release (engine_info);
engine_info = NULL;
@@ -237,7 +237,7 @@ gpgme_get_engine_info (gpgme_engine_info_t *info)
free (home_dir);
UNLOCK (engine_info_lock);
- return saved_err;
+ return err;
}
(*lastp)->protocol = proto_list[proto];
@@ -289,11 +289,13 @@ _gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
assert (info->file_name);
file_name = strdup (info->file_name);
+ if (!file_name)
+ err = gpg_error_from_syserror ();
if (info->home_dir)
{
home_dir = strdup (info->home_dir);
- if (!home_dir)
+ if (!home_dir && !err)
err = gpg_error_from_syserror ();
}
else
@@ -302,19 +304,19 @@ _gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
if (info->version)
{
version = strdup (info->version);
- if (!version)
+ if (!version && !err)
err = gpg_error_from_syserror ();
}
else
version = NULL;
*lastp = malloc (sizeof (*engine_info));
- if (!*lastp || !file_name || err)
- {
- int saved_err = gpg_error_from_syserror ();
+ if (!*lastp && !err)
+ err = gpg_error_from_syserror ();
+ if (err)
+ {
_gpgme_engine_info_release (new_info);
-
if (file_name)
free (file_name);
if (home_dir)
@@ -323,7 +325,7 @@ _gpgme_engine_info_copy (gpgme_engine_info_t *r_info)
free (version);
UNLOCK (engine_info_lock);
- return saved_err;
+ return err;
}
(*lastp)->protocol = info->protocol;
@@ -936,3 +938,21 @@ _gpgme_engine_set_pinentry_mode (engine_t engine, gpgme_pinentry_mode_t mode)
return (*engine->ops->set_pinentry_mode) (engine->engine, mode);
}
+
+
+gpgme_error_t
+_gpgme_engine_op_spawn (engine_t engine,
+ const char *file, const char *argv[],
+ gpgme_data_t datain,
+ gpgme_data_t dataout, gpgme_data_t dataerr,
+ unsigned int flags)
+{
+ if (!engine)
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ if (!engine->ops->opspawn)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
+ return (*engine->ops->opspawn) (engine->engine, file, argv,
+ datain, dataout, dataerr, flags);
+}
diff --git a/src/engine.h b/src/engine.h
index a0287ad..bbf009d 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -163,5 +163,12 @@ gpgme_error_t _gpgme_engine_op_passwd (engine_t engine, gpgme_key_t key,
gpgme_error_t _gpgme_engine_set_pinentry_mode (engine_t engine,
gpgme_pinentry_mode_t mode);
+gpgme_error_t _gpgme_engine_op_spawn (engine_t engine,
+ const char *file, const char *argv[],
+ gpgme_data_t datain,
+ gpgme_data_t dataout,
+ gpgme_data_t dataerr,
+ unsigned int flags);
+
#endif /* ENGINE_H */
diff --git a/src/gpgconf.c b/src/gpgconf.c
index 47ef47a..6591452 100644
--- a/src/gpgconf.c
+++ b/src/gpgconf.c
@@ -28,18 +28,7 @@
#include "engine.h"
#include "debug.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, const 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
+#include "engine-backend.h"
/* Allocate a new gpgme_conf_arg_t. */
@@ -47,11 +36,7 @@ gpgme_error_t
gpgme_conf_arg_new (gpgme_conf_arg_t *arg_p,
gpgme_conf_type_t type, const void *value)
{
-#ifdef ENABLE_GPGCONF
return _gpgme_conf_arg_new (arg_p, type, value);
-#else
- return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
-#endif
}
@@ -59,9 +44,7 @@ gpgme_conf_arg_new (gpgme_conf_arg_t *arg_p,
void
gpgme_conf_arg_release (gpgme_conf_arg_t arg, gpgme_conf_type_t type)
{
-#ifdef ENABLE_GPGCONF
_gpgme_conf_arg_release (arg, type);
-#endif
}
@@ -69,11 +52,7 @@ 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)
{
-#ifdef ENABLE_GPGCONF
return _gpgme_conf_opt_change (opt, reset, arg);
-#else
- return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
-#endif
}
@@ -82,9 +61,7 @@ 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)
{
-#ifdef ENABLE_GPGCONF
_gpgme_conf_release (conf);
-#endif
}
@@ -93,7 +70,6 @@ gpgme_conf_release (gpgme_conf_comp_t conf)
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;
@@ -109,9 +85,6 @@ gpgme_op_conf_load (gpgme_ctx_t ctx, gpgme_conf_comp_t *conf_p)
err = _gpgme_engine_op_conf_load (ctx->engine, conf_p);
ctx->protocol = proto;
return err;
-#else
- return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
-#endif
}
@@ -119,7 +92,6 @@ gpgme_op_conf_load (gpgme_ctx_t ctx, gpgme_conf_comp_t *conf_p)
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;
@@ -135,9 +107,6 @@ gpgme_op_conf_save (gpgme_ctx_t ctx, gpgme_conf_comp_t comp)
err = _gpgme_engine_op_conf_save (ctx->engine, comp);
ctx->protocol = proto;
return err;
-#else
- return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
-#endif
}
diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c
index 2bf7654..be8ed07 100644
--- a/src/gpgme-tool.c
+++ b/src/gpgme-tool.c
@@ -1742,6 +1742,8 @@ gt_protocol_from_name (const char *name)
return GPGME_PROTOCOL_G13;
if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_UISERVER)))
return GPGME_PROTOCOL_UISERVER;
+ if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_SPAWN)))
+ return GPGME_PROTOCOL_SPAWN;
if (! strcasecmp (name, gpgme_get_protocol_name (GPGME_PROTOCOL_DEFAULT)))
return GPGME_PROTOCOL_DEFAULT;
return GPGME_PROTOCOL_UNKNOWN;
@@ -2106,6 +2108,18 @@ gt_identify (gpgme_tool_t gt, gpgme_data_t data)
}
+gpg_error_t
+gt_spawn (gpgme_tool_t gt, const char *pgm,
+ gpgme_data_t inp, gpgme_data_t outp)
+{
+ gpg_error_t err;
+
+ err = gpgme_op_spawn (gt->ctx, pgm, NULL, inp, outp, outp, 0);
+
+ return err;
+}
+
+
#define GT_RESULT_ENCRYPT 0x1
#define GT_RESULT_DECRYPT 0x2
#define GT_RESULT_SIGN 0x4
@@ -2792,6 +2806,8 @@ _cmd_sign_encrypt (assuan_context_t ctx, char *line, int sign)
flags |= GPGME_ENCRYPT_PREPARE;
if (strstr (line, "--expect-sign"))
flags |= GPGME_ENCRYPT_EXPECT_SIGN;
+ if (strstr (line, "--no-compress"))
+ flags |= GPGME_ENCRYPT_NO_COMPRESS;
inp_fd = server->input_fd;
inp_fn = server->input_filename;
@@ -2828,7 +2844,7 @@ _cmd_sign_encrypt (assuan_context_t ctx, char *line, int sign)
static const char hlp_encrypt[] =
"ENCRYPT [--always-trust] [--no-encrypt-to]\n"
- " [--prepare] [--expect-sign]\n"
+ " [--no-compress] [--prepare] [--expect-sign]\n"
"\n"
"Encrypt the object set by the last INPUT command to\n"
"the keys specified by previous RECIPIENT commands. \n"
@@ -2843,7 +2859,7 @@ cmd_encrypt (assuan_context_t ctx, char *line)
static const char hlp_sign_encrypt[] =
"SIGN_ENCRYPT [--always-trust] [--no-encrypt-to]\n"
- " [--prepare] [--expect-sign]\n"
+ " [--no-compress] [--prepare] [--expect-sign]\n"
"\n"
"Sign the object set by the last INPUT command with the\n"
"keys specified by previous SIGNER commands and encrypt\n"
@@ -3487,6 +3503,55 @@ cmd_identify (assuan_context_t ctx, char *line)
}
+static const char hlp_spawn[] =
+ "SPAWN PGM [args]\n"
+ "\n"
+ "Run program PGM with stdin connected to the INPUT source;\n"
+ "stdout and stderr to the OUTPUT source.";
+static gpg_error_t
+cmd_spawn (assuan_context_t ctx, char *line)
+{
+ struct server *server = assuan_get_pointer (ctx);
+ gpg_error_t err;
+ assuan_fd_t inp_fd;
+ char *inp_fn;
+ assuan_fd_t out_fd;
+ char *out_fn;
+ gpgme_data_t inp_data = NULL;
+ gpgme_data_t out_data = NULL;
+
+ inp_fd = server->input_fd;
+ inp_fn = server->input_filename;
+ out_fd = server->output_fd;
+ out_fn = server->output_filename;
+ if (inp_fd != ASSUAN_INVALID_FD || inp_fn)
+ {
+ err = server_data_obj (inp_fd, inp_fn, 0, server->input_enc, &inp_data,
+ &server->input_stream);
+ if (err)
+ return err;
+ }
+ if (out_fd != ASSUAN_INVALID_FD || out_fn)
+ {
+ err = server_data_obj (out_fd, out_fn, 1, server->output_enc, &out_data,
+ &server->output_stream);
+ if (err)
+ {
+ gpgme_data_release (inp_data);
+ return err;
+ }
+ }
+
+ err = gt_spawn (server->gt, line, inp_data, out_data);
+
+ gpgme_data_release (inp_data);
+ gpgme_data_release (out_data);
+
+ server_reset_fds (server);
+
+ return err;
+}
+
/* Tell the assuan library about our commands. */
static gpg_error_t
@@ -3547,6 +3612,7 @@ register_commands (assuan_context_t ctx)
{ "HASH_ALGO_NAME", cmd_hash_algo_name },
{ "PASSWD", cmd_passwd, hlp_passwd },
{ "IDENTIFY", cmd_identify, hlp_identify },
+ { "SPAWN", cmd_spawn, hlp_spawn },
{ NULL }
};
int idx;
diff --git a/src/gpgme.c b/src/gpgme.c
index 51b68a5..628cdae 100644
--- a/src/gpgme.c
+++ b/src/gpgme.c
@@ -1,6 +1,7 @@
/* gpgme.c - GnuPG Made Easy.
Copyright (C) 2000 Werner Koch (dd9jn)
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2012 g10 Code GmbH
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2012,
+ 2014 g10 Code GmbH
This file is part of GPGME.
@@ -15,9 +16,8 @@
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. */
+ License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
#if HAVE_CONFIG_H
#include <config.h>
@@ -37,6 +37,7 @@
#include "wait.h"
#include "debug.h"
#include "priv-io.h"
+#include "sys-util.h"
/* The default locale. */
@@ -65,6 +66,15 @@ gpgme_set_global_flag (const char *name, const char *value)
return -1;
else if (!strcmp (name, "debug"))
return _gpgme_debug_set_debug_envvar (value);
+ else if (!strcmp (name, "disable-gpgconf"))
+ {
+ _gpgme_dirinfo_disable_gpgconf ();
+ return 0;
+ }
+ else if (!strcmp (name, "gpgconf-name"))
+ return _gpgme_set_default_gpgconf_name (value);
+ else if (!strcmp (name, "gpg-name"))
+ return _gpgme_set_default_gpg_name (value);
else
return -1;
}
@@ -76,6 +86,7 @@ gpgme_set_global_flag (const char *name, const char *value)
gpgme_error_t
gpgme_new (gpgme_ctx_t *r_ctx)
{
+ gpgme_error_t err;
gpgme_ctx_t ctx;
TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx);
@@ -91,11 +102,13 @@ gpgme_new (gpgme_ctx_t *r_ctx)
INIT_LOCK (ctx->lock);
- _gpgme_engine_info_copy (&ctx->engine_info);
- if (!ctx->engine_info)
+ err = _gpgme_engine_info_copy (&ctx->engine_info);
+ if (!err && !ctx->engine_info)
+ err = gpg_error (GPG_ERR_NO_ENGINE);
+ if (err)
{
free (ctx);
- return TRACE_ERR (gpg_error_from_syserror ());
+ return TRACE_ERR (err);
}
ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
@@ -220,6 +233,7 @@ gpgme_release (gpgme_ctx_t ctx)
return;
_gpgme_engine_release (ctx->engine);
+ ctx->engine = NULL;
_gpgme_fd_table_deinit (&ctx->fdt);
_gpgme_release_result (ctx);
_gpgme_signers_clear (ctx);
@@ -231,6 +245,7 @@ gpgme_release (gpgme_ctx_t ctx)
if (ctx->lc_messages)
free (ctx->lc_messages);
_gpgme_engine_info_release (ctx->engine_info);
+ ctx->engine_info = NULL;
DESTROY_LOCK (ctx->lock);
free (ctx);
}
@@ -308,7 +323,8 @@ gpgme_set_protocol (gpgme_ctx_t ctx, gpgme_protocol_t protocol)
&& protocol != GPGME_PROTOCOL_GPGCONF
&& protocol != GPGME_PROTOCOL_ASSUAN
&& protocol != GPGME_PROTOCOL_G13
- && protocol != GPGME_PROTOCOL_UISERVER)
+ && protocol != GPGME_PROTOCOL_UISERVER
+ && protocol != GPGME_PROTOCOL_SPAWN)
return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
if (!ctx)
@@ -392,6 +408,9 @@ gpgme_get_protocol_name (gpgme_protocol_t protocol)
case GPGME_PROTOCOL_UISERVER:
return "UIServer";
+ case GPGME_PROTOCOL_SPAWN:
+ return "Spawn";
+
case GPGME_PROTOCOL_DEFAULT:
return "default";
@@ -931,6 +950,9 @@ gpgme_pubkey_algo_name (gpgme_pubkey_algo_t algo)
case GPGME_PK_DSA:
return "DSA";
+ case GPGME_PK_ECC:
+ return "ECC";
+
case GPGME_PK_ELG:
return "ELG";
@@ -978,6 +1000,9 @@ gpgme_hash_algo_name (gpgme_hash_algo_t algo)
case GPGME_MD_SHA512:
return "SHA512";
+ case GPGME_MD_SHA224:
+ return "SHA224";
+
case GPGME_MD_MD4:
return "MD4";
diff --git a/src/gpgme.def b/src/gpgme.def
index 0478cb6..dc18948 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -213,5 +213,9 @@ EXPORTS
gpgme_data_identify @161
+ gpgme_get_dirinfo @162
+
+ gpgme_op_spawn_start @163
+ gpgme_op_spawn @164
; END
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 5c4de6b..d47f4ba 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -1,7 +1,7 @@
/* gpgme.h - Public interface to GnuPG Made Easy. -*- c -*-
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009
- 2010, 2011, 2012, 2013 g10 Code GmbH
+ 2010, 2011, 2012, 2013, 2014 g10 Code GmbH
This file is part of GPGME.
@@ -227,7 +227,7 @@ typedef enum
gpgme_data_type_t;
-/* Public key algorithms from libgcrypt. */
+/* Public key algorithms. */
typedef enum
{
GPGME_PK_RSA = 1,
@@ -235,6 +235,7 @@ typedef enum
GPGME_PK_RSA_S = 3,
GPGME_PK_ELG_E = 16,
GPGME_PK_DSA = 17,
+ GPGME_PK_ECC = 18,
GPGME_PK_ELG = 20,
GPGME_PK_ECDSA = 301,
GPGME_PK_ECDH = 302
@@ -242,7 +243,7 @@ typedef enum
gpgme_pubkey_algo_t;
-/* Hash algorithms from libgcrypt. */
+/* Hash algorithms (the values match those from libgcrypt). */
typedef enum
{
GPGME_MD_NONE = 0,
@@ -255,6 +256,7 @@ typedef enum
GPGME_MD_SHA256 = 8,
GPGME_MD_SHA384 = 9,
GPGME_MD_SHA512 = 10,
+ GPGME_MD_SHA224 = 11,
GPGME_MD_MD4 = 301,
GPGME_MD_CRC32 = 302,
GPGME_MD_CRC32_RFC1510 = 303,
@@ -354,6 +356,7 @@ typedef enum
GPGME_PROTOCOL_ASSUAN = 3, /* Low-level access to an Assuan server. */
GPGME_PROTOCOL_G13 = 4,
GPGME_PROTOCOL_UISERVER= 5,
+ GPGME_PROTOCOL_SPAWN = 6, /* Direct access to any program. */
GPGME_PROTOCOL_DEFAULT = 254,
GPGME_PROTOCOL_UNKNOWN = 255
}
@@ -452,7 +455,7 @@ typedef enum
GPGME_STATUS_BADARMOR = 7,
- GPGME_STATUS_RSA_OR_IDEA = 8,
+ GPGME_STATUS_RSA_OR_IDEA = 8, /* (legacy) */
GPGME_STATUS_KEYEXPIRED = 9,
GPGME_STATUS_KEYREVOKED = 10,
@@ -462,10 +465,10 @@ typedef enum
GPGME_STATUS_TRUST_FULLY = 14,
GPGME_STATUS_TRUST_ULTIMATE = 15,
- GPGME_STATUS_SHM_INFO = 16,
- GPGME_STATUS_SHM_GET = 17,
- GPGME_STATUS_SHM_GET_BOOL = 18,
- GPGME_STATUS_SHM_GET_HIDDEN = 19,
+ GPGME_STATUS_SHM_INFO = 16, /* (legacy) */
+ GPGME_STATUS_SHM_GET = 17, /* (legacy) */
+ GPGME_STATUS_SHM_GET_BOOL = 18, /* (legacy) */
+ GPGME_STATUS_SHM_GET_HIDDEN = 19, /* (legacy) */
GPGME_STATUS_NEED_PASSPHRASE = 20,
GPGME_STATUS_VALIDSIG = 21,
@@ -507,15 +510,15 @@ typedef enum
GPGME_STATUS_NOTATION_NAME = 55,
GPGME_STATUS_NOTATION_DATA = 56,
GPGME_STATUS_POLICY_URL = 57,
- GPGME_STATUS_BEGIN_STREAM = 58,
- GPGME_STATUS_END_STREAM = 59,
+ GPGME_STATUS_BEGIN_STREAM = 58, /* (legacy) */
+ GPGME_STATUS_END_STREAM = 59, /* (legacy) */
GPGME_STATUS_KEY_CREATED = 60,
GPGME_STATUS_USERID_HINT = 61,
GPGME_STATUS_UNEXPECTED = 62,
GPGME_STATUS_INV_RECP = 63,
GPGME_STATUS_NO_RECP = 64,
GPGME_STATUS_ALREADY_SIGNED = 65,
- GPGME_STATUS_SIGEXPIRED = 66,
+ GPGME_STATUS_SIGEXPIRED = 66, /* (legacy) */
GPGME_STATUS_EXPSIG = 67,
GPGME_STATUS_EXPKEYSIG = 68,
GPGME_STATUS_TRUNCATED = 69,
@@ -534,7 +537,13 @@ typedef enum
GPGME_STATUS_INV_SGNR = 82,
GPGME_STATUS_NO_SGNR = 83,
GPGME_STATUS_SUCCESS = 84,
- GPGME_STATUS_DECRYPTION_INFO = 85
+ GPGME_STATUS_DECRYPTION_INFO = 85,
+ GPGME_STATUS_PLAINTEXT_LENGTH = 86,
+ GPGME_STATUS_MOUNTPOINT = 87,
+ GPGME_STATUS_PINENTRY_LAUNCHED = 88,
+ GPGME_STATUS_ATTRIBUTE = 89,
+ GPGME_STATUS_BEGIN_SIGNING = 90,
+ GPGME_STATUS_KEY_NOT_CREATED = 91
}
gpgme_status_code_t;
@@ -626,6 +635,9 @@ struct _gpgme_subkey
/* The serial number of a smart card holding this key or NULL. */
char *card_number;
+
+ /* The name of the curve for ECC algorithms or NULL. */
+ char *curve;
};
typedef struct _gpgme_subkey *gpgme_subkey_t;
@@ -1282,7 +1294,8 @@ typedef enum
GPGME_ENCRYPT_ALWAYS_TRUST = 1,
GPGME_ENCRYPT_NO_ENCRYPT_TO = 2,
GPGME_ENCRYPT_PREPARE = 4,
- GPGME_ENCRYPT_EXPECT_SIGN = 8
+ GPGME_ENCRYPT_EXPECT_SIGN = 8,
+ GPGME_ENCRYPT_NO_COMPRESS = 16
}
gpgme_encrypt_flags_t;
@@ -1694,6 +1707,26 @@ gpgme_error_t gpgme_op_card_edit (gpgme_ctx_t ctx, gpgme_key_t key,
gpgme_edit_cb_t fnc, void *fnc_value,
gpgme_data_t out);
+
+/* Flags for the spawn operations. */
+#define GPGME_SPAWN_DETACHED 1
+#define GPGME_SPAWN_ALLOW_SET_FG 2
+
+
+/* Run the command FILE with the arguments in ARGV. Connect stdin to
+ DATAIN, stdout to DATAOUT, and STDERR to DATAERR. If one the data
+ streams is NULL, connect to /dev/null instead. */
+gpgme_error_t gpgme_op_spawn_start (gpgme_ctx_t ctx,
+ const char *file, const char *argv[],
+ gpgme_data_t datain,
+ gpgme_data_t dataout, gpgme_data_t dataerr,
+ unsigned int flags);
+gpgme_error_t gpgme_op_spawn (gpgme_ctx_t ctx,
+ const char *file, const char *argv[],
+ gpgme_data_t datain,
+ gpgme_data_t dataout, gpgme_data_t dataerr,
+ unsigned int flags);
+
/* Key management functions. */
struct _gpgme_op_keylist_result
@@ -2090,6 +2123,9 @@ const char *gpgme_check_version_internal (const char *req_version,
gpgme_check_version_internal (req_version, \
offsetof (struct _gpgme_signature, validity))
+/* Return the default values for various directories. */
+const char *gpgme_get_dirinfo (const char *what);
+
/* Get the information about the configured and installed engines. A
pointer to the first engine in the statically allocated linked list
is returned in *INFO. If an error occurs, it is returned. The
diff --git a/src/key.c b/src/key.c
index 59d4908..1a68966 100644
--- a/src/key.c
+++ b/src/key.c
@@ -331,6 +331,8 @@ gpgme_key_unref (gpgme_key_t key)
gpgme_subkey_t next = subkey->next;
if (subkey->fpr)
free (subkey->fpr);
+ if (subkey->curve)
+ free (subkey->curve);
if (subkey->card_number)
free (subkey->card_number);
free (subkey);
diff --git a/src/keylist.c b/src/keylist.c
index 465b472..582b241 100644
--- a/src/keylist.c
+++ b/src/keylist.c
@@ -422,7 +422,7 @@ keylist_colon_handler (void *priv, char *line)
RT_SSB, RT_SEC, RT_CRT, RT_CRS, RT_REV, RT_SPK
}
rectype = RT_NONE;
-#define NR_FIELDS 16
+#define NR_FIELDS 17
char *field[NR_FIELDS];
int fields = 0;
void *hook;
@@ -537,7 +537,7 @@ keylist_colon_handler (void *priv, char *line)
{
int i = atoi (field[3]);
if (i >= 1 && i < 128)
- subkey->pubkey_algo = i;
+ subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
}
/* Field 5 has the long keyid. Allow short key IDs for the
@@ -584,6 +584,15 @@ keylist_colon_handler (void *priv, char *line)
if (err)
return err;
}
+
+ /* Field 17 has the curve name for ECC. */
+ if (fields >= 17 && *field[16])
+ {
+ subkey->curve = strdup (field[16]);
+ if (!subkey->curve)
+ return gpg_error_from_syserror ();
+ }
+
break;
case RT_SUB:
@@ -614,7 +623,7 @@ keylist_colon_handler (void *priv, char *line)
{
int i = atoi (field[3]);
if (i >= 1 && i < 128)
- subkey->pubkey_algo = i;
+ subkey->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
}
/* Field 5 has the long keyid. */
@@ -646,6 +655,15 @@ keylist_colon_handler (void *priv, char *line)
if (err)
return err;
}
+
+ /* Field 17 has the curve name for ECC. */
+ if (fields >= 17 && *field[16])
+ {
+ subkey->curve = strdup (field[16]);
+ if (!subkey->curve)
+ return gpg_error_from_syserror ();
+ }
+
break;
case RT_UID:
@@ -728,7 +746,7 @@ keylist_colon_handler (void *priv, char *line)
{
int i = atoi (field[3]);
if (i >= 1 && i < 128)
- keysig->pubkey_algo = i;
+ keysig->pubkey_algo = _gpgme_map_pk_algo (i, ctx->protocol);
}
/* Field 5 has the long keyid. */
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index fe18e6a..39663c1 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -87,6 +87,11 @@ GPGME_1.1 {
gpgme_set_pinentry_mode;
gpgme_get_pinentry_mode;
+
+ gpgme_get_dirinfo;
+
+ gpgme_op_spawn_start;
+ gpgme_op_spawn;
};
diff --git a/src/posix-io.c b/src/posix-io.c
index c315539..ac823fc 100644
--- a/src/posix-io.c
+++ b/src/posix-io.c
@@ -377,8 +377,6 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
int status;
int signo;
- (void)flags;
-
TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_spawn", path,
"path=%s", path);
i = 0;
@@ -407,6 +405,7 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
/* Child. */
int seen_stdin = 0;
+ int seen_stdout = 0;
int seen_stderr = 0;
if (atfork)
@@ -435,6 +434,8 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
if (child_fd == 0)
seen_stdin = 1;
+ else if (child_fd == 1)
+ seen_stdout = 1;
else if (child_fd == 2)
seen_stderr = 1;
@@ -456,56 +457,38 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
close (fd_list[i].fd);
}
- if (! seen_stdin || ! seen_stderr)
+ if (! seen_stdin || ! seen_stdout || !seen_stderr)
{
fd = open ("/dev/null", O_RDWR);
if (fd == -1)
{
-#if 0
- /* FIXME: The debug file descriptor is not dup'ed
- anyway, so we can't see this. */
- TRACE_LOG1 ("can't open `/dev/null': %s\n",
- strerror (errno));
-#endif
+ /* The debug file descriptor is not dup'ed, so we
+ can't do a trace output. */
_exit (8);
}
- /* Make sure that the process has a connected stdin. */
+ /* Make sure that the process has connected stdin. */
if (! seen_stdin && fd != 0)
{
if (dup2 (fd, 0) == -1)
- {
-#if 0
- /* FIXME: The debug file descriptor is not dup'ed
- anyway, so we can't see this. */
- TRACE_LOG1 ("dup2(/dev/null, 0) failed: %s\n",
- strerror (errno));
-#endif
- _exit (8);
- }
+ _exit (8);
}
+ if (! seen_stdout && fd != 1)
+ {
+ if (dup2 (fd, 1) == -1)
+ _exit (8);
+ }
if (! seen_stderr && fd != 2)
- if (dup2 (fd, 2) == -1)
- {
-#if 0
- /* FIXME: The debug file descriptor is not dup'ed
- anyway, so we can't see this. */
- TRACE_LOG1 ("dup2(dev/null, 2) failed: %s\n",
- strerror (errno));
-#endif
- _exit (8);
- }
- if (fd != 0 && fd != 2)
+ {
+ if (dup2 (fd, 2) == -1)
+ _exit (8);
+ }
+ if (fd != 0 && fd != 1 && fd != 2)
close (fd);
}
execv (path, (char *const *) argv);
/* Hmm: in that case we could write a special status code to the
status-pipe. */
-#if 0
- /* FIXME: The debug file descriptor is not dup'ed anyway, so
- we can't see this. */
- TRACE_LOG1 ("exec of `%s' failed\n", path);
-#endif
_exit (8);
/* End child. */
}
diff --git a/src/posix-util.c b/src/posix-util.c
index fd44507..f7e0a17 100644
--- a/src/posix-util.c
+++ b/src/posix-util.c
@@ -29,48 +29,109 @@
#include "util.h"
#include "sys-util.h"
+#include "debug.h"
-const char *
-_gpgme_get_gpg_path (void)
+/* These variables store the malloced name of alternative default
+ binaries. The are set only once by gpgme_set_global_flag. */
+static char *default_gpg_name;
+static char *default_gpgconf_name;
+
+/* Set the default name for the gpg binary. This function may only be
+ called by gpgme_set_global_flag. Returns 0 on success. Leading
+ directories are removed from NAME. */
+int
+_gpgme_set_default_gpg_name (const char *name)
{
-#ifdef GPG_PATH
- return GPG_PATH;
-#else
- return NULL;
-#endif
+ const char *s;
+
+ s = strrchr (name, '/');
+ if (s)
+ name = s + 1;
+
+ if (!default_gpg_name)
+ default_gpg_name = strdup (name);
+ return !default_gpg_name;
}
-const char *
-_gpgme_get_gpgsm_path (void)
+/* Set the default name for the gpgconf binary. This function may
+ only be called by gpgme_set_global_flag. Returns 0 on success.
+ Leading directories are removed from NAME. */
+int
+_gpgme_set_default_gpgconf_name (const char *name)
{
-#ifdef GPGSM_PATH
- return GPGSM_PATH;
-#else
- return NULL;
-#endif
+ const char *s;
+
+ s = strrchr (name, '/');
+ if (s)
+ name = s + 1;
+
+ if (!default_gpgconf_name)
+ default_gpgconf_name = strdup (name);
+ return !default_gpgconf_name;
}
-const char *
-_gpgme_get_gpgconf_path (void)
+
+/* Find an executable program PGM along the envvar PATH. */
+static char *
+walk_path (const char *pgm)
{
-#ifdef GPGCONF_PATH
- return GPGCONF_PATH;
+ const char *orig_path, *path, *s;
+ char *fname, *p;
+
+#ifdef FIXED_SEARCH_PATH
+ orig_path = FIXED_SEARCH_PATH;
#else
- return NULL;
+ orig_path = getenv ("PATH");
+ if (!orig_path)
+ orig_path = "/bin:/usr/bin";
#endif
+
+ fname = malloc (strlen (orig_path) + 1 + strlen (pgm) + 1);
+ if (!fname)
+ return NULL;
+
+ path = orig_path;
+ for (;;)
+ {
+ for (s=path, p=fname; *s && *s != ':'; s++, p++)
+ *p = *s;
+ if (p != fname && p[-1] != '/')
+ *p++ = '/';
+ strcpy (p, pgm);
+ if (!access (fname, X_OK))
+ return fname;
+ if (!*s)
+ break;
+ path = s + 1;
+ }
+
+ _gpgme_debug (DEBUG_ENGINE, "gpgme-walk_path: '%s' not found in '%s'",
+ pgm, orig_path);
+
+ free (fname);
+ return NULL;
}
-const char *
-_gpgme_get_g13_path (void)
+
+/* Return the full file name of the GPG binary. This function is used
+ if gpgconf was not found and thus it can be assumed that gpg2 is
+ not installed. This function is only called by get_gpgconf_item
+ and may not be called concurrently. */
+char *
+_gpgme_get_gpg_path (void)
{
-#ifdef G13_PATH
- return G13_PATH;
-#else
- return NULL;
-#endif
+ return walk_path (default_gpg_name? default_gpg_name : "gpg");
}
+/* This function is only called by get_gpgconf_item and may not be
+ called concurrently. */
+char *
+_gpgme_get_gpgconf_path (void)
+{
+ return walk_path (default_gpgconf_name? default_gpgconf_name : "gpgconf");
+}
+
/* See w32-util.c */
int
_gpgme_get_conf_int (const char *key, int *value)
diff --git a/src/priv-io.h b/src/priv-io.h
index 4058b3b..583f06a 100644
--- a/src/priv-io.h
+++ b/src/priv-io.h
@@ -75,11 +75,13 @@ int _gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler,
void *value);
int _gpgme_io_set_nonblocking (int fd);
+/* Under Windows do not allocate a console. */
+#define IOSPAWN_FLAG_DETACHED 1
/* A flag to tell the spawn function to allow the child process to set
the foreground window. */
-#define IOSPAWN_FLAG_ALLOW_SET_FG 1
+#define IOSPAWN_FLAG_ALLOW_SET_FG 2
/* Don't close any child FDs. */
-#define IOSPAWN_FLAG_NOCLOSE 2
+#define IOSPAWN_FLAG_NOCLOSE 4
/* Spawn the executable PATH with ARGV as arguments. After forking
close all fds except for those in FD_LIST in the child, then
diff --git a/src/sign.c b/src/sign.c
index e910799..c55441d 100644
--- a/src/sign.c
+++ b/src/sign.c
@@ -142,7 +142,8 @@ gpgme_op_sign_result (gpgme_ctx_t ctx)
static gpgme_error_t
-parse_sig_created (char *args, gpgme_new_signature_t *sigp)
+parse_sig_created (char *args, gpgme_new_signature_t *sigp,
+ gpgme_protocol_t protocol)
{
gpgme_new_signature_t sig;
char *tail;
@@ -180,7 +181,7 @@ parse_sig_created (char *args, gpgme_new_signature_t *sigp)
}
gpg_err_set_errno (0);
- sig->pubkey_algo = strtol (args, &tail, 0);
+ sig->pubkey_algo = _gpgme_map_pk_algo (strtol (args, &tail, 0), protocol);
if (errno || args == tail || *tail != ' ')
{
/* The crypto backend does not behave. */
@@ -263,7 +264,7 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args)
{
case GPGME_STATUS_SIG_CREATED:
opd->sig_created_seen = 1;
- err = parse_sig_created (args, opd->last_sig_p);
+ err = parse_sig_created (args, opd->last_sig_p, ctx->protocol);
if (err)
return err;
diff --git a/src/spawn.c b/src/spawn.c
new file mode 100644
index 0000000..7b3b447
--- /dev/null
+++ b/src/spawn.c
@@ -0,0 +1,106 @@
+/* spawn.c - Run an arbitrary command with callbacks.
+ Copyright (C) 2014 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 "gpgme.h"
+#include "debug.h"
+#include "context.h"
+#include "util.h"
+#include "ops.h"
+
+
+static gpgme_error_t
+spawn_start (gpgme_ctx_t ctx, int synchronous,
+ const char *file, const char *argv[],
+ gpgme_data_t datain,
+ gpgme_data_t dataout, gpgme_data_t dataerr,
+ unsigned int flags)
+{
+ gpgme_error_t err;
+ const char *tmp_argv[2];
+
+ if (ctx->protocol != GPGME_PROTOCOL_SPAWN)
+ return gpg_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
+
+ err = _gpgme_op_reset (ctx, synchronous);
+ if (err)
+ return err;
+
+ if (!argv)
+ {
+ tmp_argv[0] = _gpgme_get_basename (file);
+ tmp_argv[1] = NULL;
+ argv = tmp_argv;
+ }
+
+ return _gpgme_engine_op_spawn (ctx->engine, file, argv,
+ datain, dataout, dataerr, flags);
+}
+
+
+/* Run the command FILE with the arguments in ARGV. Connect stdin to
+ DATAIN, stdout to DATAOUT, and STDERR to DATAERR. If one the data
+ streams is NULL, connect to /dev/null instead. */
+gpgme_error_t
+gpgme_op_spawn_start (gpgme_ctx_t ctx, const char *file, const char *argv[],
+ gpgme_data_t datain,
+ gpgme_data_t dataout, gpgme_data_t dataerr,
+ unsigned int flags)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG2 (DEBUG_CTX, "gpgme_op_spawn_start", ctx, "file=(%s) flaggs=%x",
+ file, flags);
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ err = spawn_start (ctx, 0, file, argv, datain, dataout, dataerr, flags);
+ return err;
+}
+
+
+/* Run the command FILE with the arguments in ARGV. Connect stdin to
+ DATAIN, stdout to DATAOUT, and STDERR to DATAERR. If one the data
+ streams is NULL, connect to /dev/null instead. Synchronous
+ variant. */
+gpgme_error_t
+gpgme_op_spawn (gpgme_ctx_t ctx, const char *file, const char *argv[],
+ gpgme_data_t datain,
+ gpgme_data_t dataout, gpgme_data_t dataerr,
+ unsigned int flags)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG2 (DEBUG_CTX, "gpgme_op_spawn", ctx, "file=(%s) flags=%x",
+ file, flags);
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ err = spawn_start (ctx, 1, file, argv, datain, dataout, dataerr, flags);
+
+ if (!err)
+ err = _gpgme_wait_one (ctx);
+ return TRACE_ERR (err);
+}
diff --git a/src/status-table.c b/src/status-table.c
index 8060bdb..b936997 100644
--- a/src/status-table.c
+++ b/src/status-table.c
@@ -39,17 +39,21 @@ struct status_table_s {
sorted at start up, too. */
static struct status_table_s status_table[] =
{
+ { "ABORT", GPGME_STATUS_ABORT },
{ "ALREADY_SIGNED", GPGME_STATUS_ALREADY_SIGNED },
+ { "ATTRIBUTE", GPGME_STATUS_ATTRIBUTE },
{ "BACKUP_KEY_CREATED", GPGME_STATUS_BACKUP_KEY_CREATED },
+ { "BAD_PASSPHRASE", GPGME_STATUS_BAD_PASSPHRASE },
{ "BADARMOR", GPGME_STATUS_BADARMOR },
{ "BADMDC", GPGME_STATUS_BADMDC },
{ "BADSIG", GPGME_STATUS_BADSIG },
- { "BAD_PASSPHRASE", GPGME_STATUS_BAD_PASSPHRASE },
{ "BEGIN_DECRYPTION", GPGME_STATUS_BEGIN_DECRYPTION },
{ "BEGIN_ENCRYPTION", GPGME_STATUS_BEGIN_ENCRYPTION },
+ { "BEGIN_SIGNING", GPGME_STATUS_BEGIN_SIGNING },
{ "BEGIN_STREAM", GPGME_STATUS_BEGIN_STREAM },
{ "CARDCTRL", GPGME_STATUS_CARDCTRL },
{ "DECRYPTION_FAILED", GPGME_STATUS_DECRYPTION_FAILED },
+ { "DECRYPTION_INFO", GPGME_STATUS_DECRYPTION_INFO },
{ "DECRYPTION_OKAY", GPGME_STATUS_DECRYPTION_OKAY },
{ "DELETE_PROBLEM", GPGME_STATUS_DELETE_PROBLEM },
{ "ENC_TO", GPGME_STATUS_ENC_TO },
@@ -68,35 +72,39 @@ static struct status_table_s status_table[] =
{ "GET_BOOL", GPGME_STATUS_GET_BOOL },
{ "GET_HIDDEN", GPGME_STATUS_GET_HIDDEN },
{ "GET_LINE", GPGME_STATUS_GET_LINE },
+ { "GOOD_PASSPHRASE", GPGME_STATUS_GOOD_PASSPHRASE },
{ "GOODMDC", GPGME_STATUS_GOODMDC },
{ "GOODSIG", GPGME_STATUS_GOODSIG },
- { "GOOD_PASSPHRASE", GPGME_STATUS_GOOD_PASSPHRASE },
{ "GOT_IT", GPGME_STATUS_GOT_IT },
- { "IMPORTED", GPGME_STATUS_IMPORTED },
{ "IMPORT_OK", GPGME_STATUS_IMPORT_OK },
{ "IMPORT_PROBLEM", GPGME_STATUS_IMPORT_PROBLEM },
{ "IMPORT_RES", GPGME_STATUS_IMPORT_RES },
+ { "IMPORTED", GPGME_STATUS_IMPORTED },
{ "INV_RECP", GPGME_STATUS_INV_RECP },
{ "INV_SGNR", GPGME_STATUS_INV_SGNR },
+ { "KEY_CREATED", GPGME_STATUS_KEY_CREATED },
+ { "KEY_NOT_CREATED", GPGME_STATUS_KEY_NOT_CREATED },
{ "KEYEXPIRED", GPGME_STATUS_KEYEXPIRED },
{ "KEYREVOKED", GPGME_STATUS_KEYREVOKED },
- { "KEY_CREATED", GPGME_STATUS_KEY_CREATED },
{ "LEAVE", GPGME_STATUS_LEAVE },
{ "MISSING_PASSPHRASE", GPGME_STATUS_MISSING_PASSPHRASE },
+ { "MOUNTPOINT", GPGME_STATUS_MOUNTPOINT },
{ "NEED_PASSPHRASE", GPGME_STATUS_NEED_PASSPHRASE },
{ "NEED_PASSPHRASE_PIN", GPGME_STATUS_NEED_PASSPHRASE_PIN },
{ "NEED_PASSPHRASE_SYM", GPGME_STATUS_NEED_PASSPHRASE_SYM },
{ "NEWSIG", GPGME_STATUS_NEWSIG },
- { "NODATA", GPGME_STATUS_NODATA },
- { "NOTATION_DATA", GPGME_STATUS_NOTATION_DATA },
- { "NOTATION_NAME", GPGME_STATUS_NOTATION_NAME },
{ "NO_PUBKEY", GPGME_STATUS_NO_PUBKEY },
{ "NO_RECP", GPGME_STATUS_NO_RECP },
{ "NO_SECKEY", GPGME_STATUS_NO_SECKEY },
{ "NO_SGNR", GPGME_STATUS_NO_SGNR },
+ { "NODATA", GPGME_STATUS_NODATA },
+ { "NOTATION_DATA", GPGME_STATUS_NOTATION_DATA },
+ { "NOTATION_NAME", GPGME_STATUS_NOTATION_NAME },
+ { "PINENTRY_LAUNCHED", GPGME_STATUS_PINENTRY_LAUNCHED},
{ "PKA_TRUST_BAD", GPGME_STATUS_PKA_TRUST_BAD },
{ "PKA_TRUST_GOOD", GPGME_STATUS_PKA_TRUST_GOOD },
{ "PLAINTEXT", GPGME_STATUS_PLAINTEXT },
+ { "PLAINTEXT_LENGTH", GPGME_STATUS_PLAINTEXT_LENGTH },
{ "POLICY_URL", GPGME_STATUS_POLICY_URL },
{ "PROGRESS", GPGME_STATUS_PROGRESS },
{ "REVKEYSIG", GPGME_STATUS_REVKEYSIG },
@@ -108,10 +116,10 @@ static struct status_table_s status_table[] =
{ "SHM_GET_BOOL", GPGME_STATUS_SHM_GET_BOOL },
{ "SHM_GET_HIDDEN", GPGME_STATUS_SHM_GET_HIDDEN },
{ "SHM_INFO", GPGME_STATUS_SHM_INFO },
- { "SIGEXPIRED", GPGME_STATUS_SIGEXPIRED },
{ "SIG_CREATED", GPGME_STATUS_SIG_CREATED },
{ "SIG_ID", GPGME_STATUS_SIG_ID },
{ "SIG_SUBPACKET", GPGME_STATUS_SIG_SUBPACKET },
+ { "SIGEXPIRED", GPGME_STATUS_SIGEXPIRED },
{ "SUCCESS", GPGME_STATUS_SUCCESS },
{ "TRUNCATED", GPGME_STATUS_TRUNCATED },
{ "TRUST_FULLY", GPGME_STATUS_TRUST_FULLY },
@@ -122,7 +130,6 @@ static struct status_table_s status_table[] =
{ "UNEXPECTED", GPGME_STATUS_UNEXPECTED },
{ "USERID_HINT", GPGME_STATUS_USERID_HINT },
{ "VALIDSIG", GPGME_STATUS_VALIDSIG },
- { "ABORT", GPGME_STATUS_ABORT },
{NULL, 0}
};
diff --git a/src/sys-util.h b/src/sys-util.h
index f6506d3..7180fca 100644
--- a/src/sys-util.h
+++ b/src/sys-util.h
@@ -21,9 +21,10 @@
#define SYS_UTIL_H
/*-- {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);
-const char *_gpgme_get_g13_path (void);
+int _gpgme_set_default_gpg_name (const char *name);
+int _gpgme_set_default_gpgconf_name (const char *name);
+
+char *_gpgme_get_gpg_path (void);
+char *_gpgme_get_gpgconf_path (void);
#endif /* SYS_UTIL_H */
diff --git a/src/util.h b/src/util.h
index c432980..365f1d8 100644
--- a/src/util.h
+++ b/src/util.h
@@ -51,6 +51,8 @@ int _gpgme_get_conf_int (const char *key, int *value);
void _gpgme_allow_set_foreground_window (pid_t pid);
/*-- dirinfo.c --*/
+void _gpgme_dirinfo_disable_gpgconf (void);
+
const char *_gpgme_get_default_homedir (void);
const char *_gpgme_get_default_agent_socket (void);
const char *_gpgme_get_default_gpg_name (void);
@@ -58,6 +60,9 @@ const char *_gpgme_get_default_gpgsm_name (void);
const char *_gpgme_get_default_g13_name (void);
const char *_gpgme_get_default_gpgconf_name (void);
const char *_gpgme_get_default_uisrv_socket (void);
+int _gpgme_in_gpg_one_mode (void);
+
+const char *_gpgme_get_basename (const char *name);
@@ -130,6 +135,8 @@ time_t _gpgme_parse_timestamp (const char *timestamp, char **endp);
gpgme_error_t _gpgme_map_gnupg_error (char *err);
+int _gpgme_map_pk_algo (int algo, gpgme_protocol_t protocol);
+
/* Retrieve the environment variable NAME and return a copy of it in a
malloc()'ed buffer in *VALUE. If the environment variable is not
@@ -151,25 +158,13 @@ const char *_gpgme_get_w32spawn_path (void);
char *_gpgme_w32ce_get_debug_envvar (void);
#endif /*HAVE_W32CE_SYSTEM*/
-/*-- Error codes not yet available in current gpg-error.h. --*/
-#ifndef GPG_ERR_UNFINISHED
-#define GPG_ERR_UNFINISHED 199
-#endif
-#ifndef GPG_ERR_NOT_OPERATIONAL
-#define GPG_ERR_NOT_OPERATIONAL 176
-#endif
-#ifndef GPG_ERR_MISSING_ISSUER_CERT
-#define GPG_ERR_MISSING_ISSUER_CERT 185
-#endif
-#ifdef ENABLE_ASSUAN
#include <assuan.h>
/* System hooks for assuan integration. */
extern struct assuan_system_hooks _gpgme_assuan_system_hooks;
extern struct assuan_malloc_hooks _gpgme_assuan_malloc_hooks;
int _gpgme_assuan_log_cb (assuan_context_t ctx, void *hook,
unsigned int cat, const char *msg);
-#endif
#endif /* UTIL_H */
diff --git a/src/verify.c b/src/verify.c
index c32241a..37b2bd4 100644
--- a/src/verify.c
+++ b/src/verify.c
@@ -264,7 +264,8 @@ prepare_new_sig (op_data_t opd)
}
static gpgme_error_t
-parse_new_sig (op_data_t opd, gpgme_status_code_t code, char *args)
+parse_new_sig (op_data_t opd, gpgme_status_code_t code, char *args,
+ gpgme_protocol_t protocol)
{
gpgme_signature_t sig;
char *end = strchr (args, ' ');
@@ -318,7 +319,7 @@ parse_new_sig (op_data_t opd, gpgme_status_code_t code, char *args)
if (!end)
goto parse_err_sig_fail;
gpg_err_set_errno (0);
- sig->pubkey_algo = strtol (end, &tail, 0);
+ sig->pubkey_algo = _gpgme_map_pk_algo (strtol (end, &tail, 0), protocol);
if (errno || end == tail || *tail != ' ')
goto parse_err_sig_fail;
end = tail;
@@ -393,7 +394,7 @@ parse_new_sig (op_data_t opd, gpgme_status_code_t code, char *args)
static gpgme_error_t
-parse_valid_sig (gpgme_signature_t sig, char *args)
+parse_valid_sig (gpgme_signature_t sig, char *args, gpgme_protocol_t protocol)
{
char *end = strchr (args, ' ');
if (end)
@@ -443,7 +444,8 @@ parse_valid_sig (gpgme_signature_t sig, char *args)
{
/* Parse the pubkey algo. */
gpg_err_set_errno (0);
- sig->pubkey_algo = strtol (end, &tail, 0);
+ sig->pubkey_algo = _gpgme_map_pk_algo (strtol (end, &tail, 0),
+ protocol);
if (errno || end == tail || *tail != ' ')
return trace_gpg_error (GPG_ERR_INV_ENGINE);
end = tail;
@@ -703,11 +705,11 @@ _gpgme_verify_status_handler (void *priv, gpgme_status_code_t code, char *args)
if (sig && !opd->did_prepare_new_sig)
calc_sig_summary (sig);
opd->only_newsig_seen = 0;
- return parse_new_sig (opd, code, args);
+ return parse_new_sig (opd, code, args, ctx->protocol);
case GPGME_STATUS_VALIDSIG:
opd->only_newsig_seen = 0;
- return sig ? parse_valid_sig (sig, args)
+ return sig ? parse_valid_sig (sig, args, ctx->protocol)
: trace_gpg_error (GPG_ERR_INV_ENGINE);
case GPGME_STATUS_NODATA:
diff --git a/src/version.c b/src/version.c
index 18825f8..15e5aee 100644
--- a/src/version.c
+++ b/src/version.c
@@ -321,7 +321,8 @@ _gpgme_get_program_version (const char *const file_name)
cfd[0].fd = rp[1];
- status = _gpgme_io_spawn (file_name, argv, 0, cfd, NULL, NULL, NULL);
+ status = _gpgme_io_spawn (file_name, argv,
+ IOSPAWN_FLAG_DETACHED, cfd, NULL, NULL, NULL);
if (status < 0)
{
_gpgme_io_close (rp[0]);
diff --git a/src/w32-glib-io.c b/src/w32-glib-io.c
index cb1bb3c..a5af4e6 100644
--- a/src/w32-glib-io.c
+++ b/src/w32-glib-io.c
@@ -662,7 +662,8 @@ _gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
si.hStdError = INVALID_HANDLE_VALUE;
cr_flags |= CREATE_SUSPENDED;
- cr_flags |= DETACHED_PROCESS;
+ if ((flags & IOSPAWN_FLAG_DETACHED))
+ cr_flags |= DETACHED_PROCESS;
if (!CreateProcessA (_gpgme_get_w32spawn_path (),
arg_string,
&sec_attr, /* process security attributes */
diff --git a/src/w32-io.c b/src/w32-io.c
index f9e4313..42961e3 100644
--- a/src/w32-io.c
+++ b/src/w32-io.c
@@ -1600,7 +1600,8 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
si.hStdError = INVALID_HANDLE_VALUE;
cr_flags |= CREATE_SUSPENDED;
- cr_flags |= DETACHED_PROCESS;
+ if ((flags & IOSPAWN_FLAG_DETACHED))
+ cr_flags |= DETACHED_PROCESS;
cr_flags |= GetPriorityClass (GetCurrentProcess ());
if (!CreateProcessA (_gpgme_get_w32spawn_path (),
arg_string,
diff --git a/src/w32-qt-io.cpp b/src/w32-qt-io.cpp
index 358ff75..44655ec 100644
--- a/src/w32-qt-io.cpp
+++ b/src/w32-qt-io.cpp
@@ -3,17 +3,17 @@
Copyright (C) 2001, 2002, 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
@@ -107,7 +107,7 @@ find_channel (int fd, int create)
DeviceEntry* entry = new DeviceEntry;
entry->iodev = new KDPipeIODevice
(fd, QIODevice::ReadWrite|QIODevice::Unbuffered);
- iodevice_table[fd] = entry;
+ iodevice_table[fd] = entry;
}
return iodevice_table[fd] ? iodevice_table[fd]->iodev : 0;
}
@@ -156,7 +156,7 @@ _gpgme_io_read (int fd, void *buffer, size_t count)
errno = EAGAIN;
return TRACE_SYSRES( -1 );
}
-
+
nread = chan->read ((char *) buffer, count);
if (nread < 0)
{
@@ -289,8 +289,8 @@ _gpgme_io_close (int fd)
notify_table[fd].value = NULL;
}
- /* Then do the close. */
-
+ /* Then do the close. */
+
DeviceEntry* const entry = iodevice_table[fd];
if ( entry ) {
if ( entry->unref() == 0 ) {
@@ -303,7 +303,7 @@ _gpgme_io_close (int fd)
_close( fd );
}
-
+
return 0;
}
@@ -334,7 +334,7 @@ _gpgme_io_set_nonblocking (int fd)
{
DeviceEntry* const entry = iodevice_table[fd];
assert( entry );
- entry->blocking = false;
+ entry->blocking = false;
TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_set_nonblocking", fd);
return TRACE_SYSRES (0);
}
@@ -347,7 +347,7 @@ build_commandline (char **argv)
int n = 0;
char *buf;
char *p;
-
+
/* We have to quote some things because under Windows the program
parses the commandline and does some unquoting. We enclose the
whole argument in double-quotes, and escape literal double-quotes
@@ -428,7 +428,7 @@ _gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
TRACE_LOG2 ("argv[%2i] = %s", i, argv[i]);
i++;
}
-
+
/* We do not inherit any handles by default, and just insert those
handles we want the child to have afterwards. But some handle
values occur on the command line, and we need to move
@@ -450,7 +450,7 @@ _gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
memset (&sec_attr, 0, sizeof sec_attr);
sec_attr.nLength = sizeof sec_attr;
sec_attr.bInheritHandle = FALSE;
-
+
arg_string = build_commandline (args);
free (args);
if (!arg_string)
@@ -459,7 +459,7 @@ _gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
DeleteFile (tmp_name);
return TRACE_SYSRES (-1);
}
-
+
memset (&si, 0, sizeof si);
si.cb = sizeof (si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
@@ -469,7 +469,8 @@ _gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
si.hStdError = INVALID_HANDLE_VALUE;
cr_flags |= CREATE_SUSPENDED;
- cr_flags |= DETACHED_PROCESS;
+ if ((flags & IOSPAWN_FLAG_DETACHED))
+ cr_flags |= DETACHED_PROCESS;
if (!CreateProcessA (_gpgme_get_w32spawn_path (),
arg_string,
&sec_attr, /* process security attributes */
@@ -523,7 +524,7 @@ _gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
/* Return the child name of this handle. */
fd_list[i].peer_name = (int) hd;
}
-
+
/* Write the handle translation information to the temporary
file. */
{
@@ -545,7 +546,7 @@ _gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
{
/* Strip the newline. */
len = strlen (line) - 1;
-
+
/* Format is: Local name, stdin/stdout/stderr, peer name, argv idx. */
snprintf (&line[len], BUFFER_MAX - len, "0x%x %d 0x%x %d \n",
fd_list[i].fd, fd_list[i].dup_to,
@@ -567,18 +568,18 @@ _gpgme_io_spawn (const char *path, char * const argv[], unsigned int flags,
close (tmp_fd);
/* The temporary file is deleted by the gpgme-w32spawn process
(hopefully). */
-
+
TRACE_LOG4 ("CreateProcess ready: hProcess=%p, hThread=%p, "
"dwProcessID=%d, dwThreadId=%d",
- pi.hProcess, pi.hThread,
+ pi.hProcess, pi.hThread,
(int) pi.dwProcessId, (int) pi.dwThreadId);
if (r_pid)
*r_pid = (pid_t)pi.dwProcessId;
-
+
if (ResumeThread (pi.hThread) < 0)
TRACE_LOG1 ("ResumeThread failed: ec=%d", (int) GetLastError ());
-
+
if (!CloseHandle (pi.hThread))
TRACE_LOG1 ("CloseHandle of thread failed: ec=%d",
(int) GetLastError ());
@@ -635,7 +636,7 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
else
fds[i].signaled = chan->waitForReadyRead( 1000 ) ? 1 : 0;
TRACE_ADD1 (dbg_help, "w0x%x ", fds[i].fd);
- if ( fds[i].signaled )
+ if ( fds[i].signaled )
count++;
}
else if (fds[i].for_write)
@@ -644,11 +645,11 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
assert (chan);
fds[i].signaled = nonblock ? ( chan->writeWouldBlock() ? 0 : 1 ) : 1;
TRACE_ADD1 (dbg_help, "w0x%x ", fds[i].fd);
- if ( fds[i].signaled )
+ if ( fds[i].signaled )
count++;
}
}
- TRACE_END (dbg_help, "]");
+ TRACE_END (dbg_help, "]");
return TRACE_SYSRES (count);
}
diff --git a/src/w32-util.c b/src/w32-util.c
index 2dc7655..daf3bd2 100644
--- a/src/w32-util.c
+++ b/src/w32-util.c
@@ -81,6 +81,11 @@ DEFINE_STATIC_LOCK (get_path_lock);
file name of the DLL or executable which contains the gpgme code. */
static HMODULE my_hmodule;
+/* These variables store the malloced name of alternative default
+ binaries. The are set only once by gpgme_set_global_flag. */
+static char *default_gpg_name;
+static char *default_gpgconf_name;
+
#ifdef HAVE_ALLOW_SET_FOREGROUND_WINDOW
@@ -151,6 +156,32 @@ wchar_to_utf8 (const wchar_t *string)
}
+/* Replace all forward slashes by backslashes. */
+static void
+replace_slashes (char *string)
+{
+ for (; *string; string++)
+ if (*string == '/')
+ *string = '\\';
+}
+
+
+/* Get the base name of NAME. Returns a pointer into NAME right after
+ the last slash or backslash or to NAME if no slash or backslash
+ exists. */
+static const char *
+get_basename (const char *name)
+{
+ const char *mark, *s;
+
+ for (mark=NULL, s=name; *s; s++)
+ if (*s == '/' || *s == '\\')
+ mark = s;
+
+ return mark? mark+1 : name;
+}
+
+
void
_gpgme_allow_set_foreground_window (pid_t pid)
{
@@ -373,8 +404,8 @@ find_program_in_inst_dir (const char *inst_dir, const char *name)
char *dir;
/* If an installation directory has been passed, this overrides a
- location given bu the registry. The idea here is that we prefer
- a a program installed alongside with gpgme. We don't want the
+ location given by the registry. The idea here is that we prefer
+ a program installed alongside with gpgme. We don't want the
registry to override this to have a better isolation of an gpgme
aware applications for other effects. Note that the "Install
Directory" registry item has been used for ages in Gpg4win and
@@ -424,72 +455,91 @@ find_program_at_standard_place (const char *name)
}
-const char *
-_gpgme_get_gpg_path (void)
+/* Set the default name for the gpg binary. This function may only be
+ called by gpgme_set_global_flag. Returns 0 on success. */
+int
+_gpgme_set_default_gpg_name (const char *name)
{
- static char *gpg_program;
- const char *inst_dir;
-
- inst_dir = _gpgme_get_inst_dir ();
- LOCK (get_path_lock);
- if (!gpg_program)
- gpg_program = find_program_in_inst_dir (inst_dir, "gpg.exe");
- if (!gpg_program)
- gpg_program = find_program_at_standard_place ("GNU\\GnuPG\\gpg.exe");
- UNLOCK (get_path_lock);
- return gpg_program;
+ if (!default_gpg_name)
+ {
+ default_gpg_name = malloc (strlen (name) + 5);
+ if (default_gpg_name)
+ {
+ strcpy (stpcpy (default_gpg_name, name), ".exe");
+ replace_slashes (default_gpg_name);
+ }
+ }
+ return !default_gpg_name;
}
-
-const char *
-_gpgme_get_gpgsm_path (void)
+/* Set the default name for the gpgconf binary. This function may only be
+ called by gpgme_set_global_flag. Returns 0 on success. */
+int
+_gpgme_set_default_gpgconf_name (const char *name)
{
- static char *gpgsm_program;
- const char *inst_dir;
-
- inst_dir = _gpgme_get_inst_dir ();
- LOCK (get_path_lock);
- if (!gpgsm_program)
- gpgsm_program = find_program_in_inst_dir (inst_dir, "gpgsm.exe");
- if (!gpgsm_program)
- gpgsm_program = find_program_at_standard_place ("GNU\\GnuPG\\gpgsm.exe");
- UNLOCK (get_path_lock);
- return gpgsm_program;
+ if (!default_gpgconf_name)
+ {
+ default_gpgconf_name = malloc (strlen (name) + 5);
+ if (default_gpgconf_name)
+ {
+ strcpy (stpcpy (default_gpgconf_name, name), ".exe");
+ replace_slashes (default_gpgconf_name);
+ }
+ }
+ return !default_gpgconf_name;
}
-const char *
-_gpgme_get_gpgconf_path (void)
+/* Return the full file name of the GPG binary. This function is used
+ if gpgconf was not found and thus it can be assumed that gpg2 is
+ not installed. This function is only called by get_gpgconf_item
+ and may not be called concurrently. */
+char *
+_gpgme_get_gpg_path (void)
{
- static char *gpgconf_program;
- const char *inst_dir;
+ char *gpg;
+ const char *inst_dir, *name;
inst_dir = _gpgme_get_inst_dir ();
- LOCK (get_path_lock);
- if (!gpgconf_program)
- gpgconf_program = find_program_in_inst_dir (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;
+ gpg = find_program_in_inst_dir
+ (inst_dir,
+ default_gpg_name? get_basename (default_gpg_name) : "gpg.exe");
+ if (!gpg)
+ {
+ name = (default_gpg_name? default_gpg_name
+ /* */ : "GNU\\GnuPG\\gpg.exe");
+ gpg = find_program_at_standard_place (name);
+ if (!gpg)
+ _gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpg_path: '%s' not found",
+ name);
+ }
+
+ return gpg;
}
-const char *
-_gpgme_get_g13_path (void)
+/* This function is only called by get_gpgconf_item and may not be
+ called concurrently. */
+char *
+_gpgme_get_gpgconf_path (void)
{
- static char *g13_program;
- const char *inst_dir;
+ char *gpgconf;
+ const char *inst_dir, *name;
inst_dir = _gpgme_get_inst_dir ();
- LOCK (get_path_lock);
- if (!g13_program)
- g13_program = find_program_in_inst_dir (inst_dir, "g13.exe");
- if (!g13_program)
- g13_program = find_program_at_standard_place ("GNU\\GnuPG\\g13.exe");
- UNLOCK (get_path_lock);
- return g13_program;
+ gpgconf = find_program_in_inst_dir
+ (inst_dir,
+ default_gpgconf_name? get_basename (default_gpgconf_name) : "gpgconf.exe");
+ if (!gpgconf)
+ {
+ name = (default_gpgconf_name? default_gpgconf_name
+ /* */ : "GNU\\GnuPG\\gpgconf.exe");
+ gpgconf = find_program_at_standard_place (name);
+ if (!gpgconf)
+ _gpgme_debug (DEBUG_ENGINE, "_gpgme_get_gpgconf_path: '%s' not found",
+ name);
+ }
+ return gpgconf;
}