summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJinWang An <jinwang.an@samsung.com>2023-01-30 13:26:32 +0900
committerJinWang An <jinwang.an@samsung.com>2023-01-30 13:26:32 +0900
commit7068c0ead0c25a9a1fd3ce0b486636d74350e7ca (patch)
tree732edf51b955fd198e4bb7ef46a0782fb3ea1d12 /src
parentd19c360948ede5ffe5974de8abc9da44be617ca1 (diff)
downloadgpgme-7068c0ead0c25a9a1fd3ce0b486636d74350e7ca.tar.gz
gpgme-7068c0ead0c25a9a1fd3ce0b486636d74350e7ca.tar.bz2
gpgme-7068c0ead0c25a9a1fd3ce0b486636d74350e7ca.zip
Imported Upstream version 1.17.0upstream/1.17.0
Diffstat (limited to 'src')
-rw-r--r--src/ath.c15
-rw-r--r--src/ath.h13
-rw-r--r--src/context.h6
-rw-r--r--src/data.c6
-rw-r--r--src/debug.h34
-rw-r--r--src/dirinfo.c66
-rw-r--r--src/engine-backend.h5
-rw-r--r--src/engine-gpg.c59
-rw-r--r--src/engine-gpgconf.c6
-rw-r--r--src/engine-gpgsm.c22
-rw-r--r--src/engine.c6
-rw-r--r--src/engine.h5
-rw-r--r--src/export.c88
-rw-r--r--src/gpgme-tool.c5
-rw-r--r--src/gpgme.c24
-rw-r--r--src/gpgme.def3
-rw-r--r--src/gpgme.h.in7
-rw-r--r--src/gpgme.pc.in6
-rw-r--r--src/import.c148
-rw-r--r--src/libgpgme.vers3
-rw-r--r--src/posix-io.c127
-rw-r--r--src/w32-util.c21
22 files changed, 586 insertions, 89 deletions
diff --git a/src/ath.c b/src/ath.c
index 6cc84aa..996143d 100644
--- a/src/ath.c
+++ b/src/ath.c
@@ -26,11 +26,15 @@
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
+#ifdef HAVE_POLL_H
+# include <poll.h>
#else
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
+# ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+# else
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# endif
# endif
#endif
#ifdef HAVE_SYS_TYPES_H
@@ -89,6 +93,7 @@ ath_write (int fd, const void *buf, size_t nbytes)
}
+#if !defined(HAVE_POLL_H)
gpgme_ssize_t
ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout)
@@ -99,7 +104,7 @@ ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
return select (nfd, rset, wset, eset, timeout);
#endif
}
-
+#endif
gpgme_ssize_t
ath_waitpid (pid_t pid, int *status, int options)
diff --git a/src/ath.h b/src/ath.h
index d4c1c6f..8243864 100644
--- a/src/ath.h
+++ b/src/ath.h
@@ -32,12 +32,15 @@
# include <io.h>
#else /*!HAVE_W32_SYSTEM*/
-
-# ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
+# ifdef HAVE_POLL_H
+# include <poll.h>
# else
-# ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
+# ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+# else
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# endif
# endif
# endif
# ifdef HAVE_SYS_TYPES_H
diff --git a/src/context.h b/src/context.h
index 2792a16..e976ba3 100644
--- a/src/context.h
+++ b/src/context.h
@@ -177,6 +177,12 @@ struct gpgme_context
/* The optional expiration date of a certification. */
char *cert_expire;
+ /* The optional key origin. */
+ char *key_origin;
+
+ /* The optional import filter. */
+ char *import_filter;
+
/* The operation data hooked into the context. */
ctx_op_data_t op_data;
diff --git a/src/data.c b/src/data.c
index 62b7231..e2de9f6 100644
--- a/src/data.c
+++ b/src/data.c
@@ -391,7 +391,7 @@ gpgme_data_read (gpgme_data_t dh, void *buffer, size_t size)
while (res < 0 && errno == EINTR);
}
- return TRACE_SYSRES ((int)res);
+ return TRACE_SYSRES_SSIZE_T (res);
}
@@ -419,7 +419,7 @@ gpgme_data_write (gpgme_data_t dh, const void *buffer, size_t size)
res = (*dh->cbs->write) (dh, buffer, size);
while (res < 0 && errno == EINTR);
- return TRACE_SYSRES ((int)res);
+ return TRACE_SYSRES_SSIZE_T (res);
}
@@ -452,7 +452,7 @@ gpgme_data_seek (gpgme_data_t dh, gpgme_off_t offset, int whence)
if (offset >= 0)
dh->outbound_pending = 0;
- return TRACE_SYSRES ((int)offset);
+ return TRACE_SYSRES_OFF_T (offset);
}
diff --git a/src/debug.h b/src/debug.h
index fa0bfc6..7b823ee 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -141,7 +141,7 @@ _trace_err (gpg_error_t err, int lvl, const char *func, int line)
return err;
}
-/* Trace a system call result and return it. */
+/* Trace a system call result of type int and return it. */
#define TRACE_SYSRES(res) \
_trace_sysres ((res), _gpgme_trace_level, _gpgme_trace_func, __LINE__)
static inline int
@@ -157,6 +157,38 @@ _trace_sysres (int res, int lvl, const char *func, int line)
return res;
}
+/* Trace a system call result of type gpgme_off_t and return it. */
+#define TRACE_SYSRES_OFF_T(res) \
+ _trace_sysres_off_t ((res), _gpgme_trace_level, _gpgme_trace_func, __LINE__)
+static inline gpgme_off_t
+_trace_sysres_off_t (gpgme_off_t res, int lvl, const char *func, int line)
+{
+ if (res >= 0)
+ _gpgme_debug (NULL, lvl, 3, func, NULL, NULL, "result=%ld", res);
+ else
+ _gpgme_debug (NULL, lvl, -1, NULL, NULL, NULL,
+ "%s:%d: error: %s (%d)\n",
+ func, line, strerror (errno), errno);
+ _gpgme_debug_frame_end ();
+ return res;
+}
+
+/* Trace a system call result of type gpgme_ssize_t and return it. */
+#define TRACE_SYSRES_SSIZE_T(res) \
+ _trace_sysres_ssize_t ((res), _gpgme_trace_level, _gpgme_trace_func, __LINE__)
+static inline gpgme_ssize_t
+_trace_sysres_ssize_t (gpgme_ssize_t res, int lvl, const char *func, int line)
+{
+ if (res >= 0)
+ _gpgme_debug (NULL, lvl, 3, func, NULL, NULL, "result=%zd", res);
+ else
+ _gpgme_debug (NULL, lvl, -1, NULL, NULL, NULL,
+ "%s:%d: error: %s (%d)\n",
+ func, line, strerror (errno), errno);
+ _gpgme_debug_frame_end ();
+ return res;
+}
+
/* Trace a system call error and return it. */
#define TRACE_SYSERR(rc) \
_trace_syserr ((rc), _gpgme_trace_level, _gpgme_trace_func, __LINE__)
diff --git a/src/dirinfo.c b/src/dirinfo.c
index c4f0e4a..8ea15d8 100644
--- a/src/dirinfo.c
+++ b/src/dirinfo.c
@@ -44,6 +44,7 @@ enum
WANT_LIBDIR,
WANT_DATADIR,
WANT_LOCALEDIR,
+ WANT_SOCKETDIR,
WANT_AGENT_SOCKET,
WANT_AGENT_SSH_SOCKET,
WANT_DIRMNGR_SOCKET,
@@ -52,6 +53,11 @@ enum
WANT_GPG_NAME,
WANT_GPGSM_NAME,
WANT_G13_NAME,
+ WANT_KEYBOXD_NAME,
+ WANT_AGENT_NAME,
+ WANT_SCDAEMON_NAME,
+ WANT_DIRMNGR_NAME,
+ WANT_PINENTRY_NAME,
WANT_GPG_WKS_CLIENT_NAME,
WANT_GPG_ONE_MODE
};
@@ -67,6 +73,7 @@ static struct {
char *libdir;
char *datadir;
char *localedir;
+ char *socketdir;
char *agent_socket;
char *agent_ssh_socket;
char *dirmngr_socket;
@@ -75,6 +82,11 @@ static struct {
char *gpg_name;
char *gpgsm_name;
char *g13_name;
+ char *keyboxd_name;
+ char *agent_name;
+ char *scdaemon_name;
+ char *dirmngr_name;
+ char *pinentry_name;
char *gpg_wks_client_name;
int gpg_one_mode; /* System is in gpg1 mode. */
} dirinfo;
@@ -135,6 +147,16 @@ parse_output (char *line, int components)
dirinfo.gpgsm_name = strdup (value);
else if (!strcmp (line, "g13") && !dirinfo.g13_name)
dirinfo.g13_name = strdup (value);
+ else if (!strcmp (line, "keyboxd") && !dirinfo.keyboxd_name)
+ dirinfo.keyboxd_name = strdup (value);
+ else if (!strcmp (line, "gpg-agent") && !dirinfo.agent_name)
+ dirinfo.agent_name = strdup (value);
+ else if (!strcmp (line, "scdaemon") && !dirinfo.scdaemon_name)
+ dirinfo.scdaemon_name = strdup (value);
+ else if (!strcmp (line, "dirmngr") && !dirinfo.dirmngr_name)
+ dirinfo.dirmngr_name = strdup (value);
+ else if (!strcmp (line, "pinentry") && !dirinfo.pinentry_name)
+ dirinfo.pinentry_name = strdup (value);
}
else
{
@@ -152,6 +174,8 @@ parse_output (char *line, int components)
dirinfo.datadir = strdup (value);
else if (!strcmp (line, "localedir") && !dirinfo.localedir)
dirinfo.localedir = strdup (value);
+ else if (!strcmp (line, "socketdir") && !dirinfo.socketdir)
+ dirinfo.socketdir = strdup (value);
else if (!strcmp (line, "agent-socket") && !dirinfo.agent_socket)
{
const char name[] = "S.uiserver";
@@ -306,10 +330,34 @@ get_gpgconf_item (int what)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: gpgsm='%s'\n",
dirinfo.gpgsm_name);
+ if (dirinfo.keyboxd_name)
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
+ "gpgme-dinfo: keyboxd='%s'\n",
+ dirinfo.keyboxd_name);
+ if (dirinfo.agent_name)
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
+ "gpgme-dinfo: gpg-agent='%s'\n",
+ dirinfo.agent_name);
+ if (dirinfo.scdaemon_name)
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
+ "gpgme-dinfo: scdaemon='%s'\n",
+ dirinfo.scdaemon_name);
+ if (dirinfo.dirmngr_name)
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
+ "gpgme-dinfo: dirmngr='%s'\n",
+ dirinfo.dirmngr_name);
+ if (dirinfo.pinentry_name)
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
+ "gpgme-dinfo: pinentry='%s'\n",
+ dirinfo.pinentry_name);
if (dirinfo.homedir)
_gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: homedir='%s'\n",
dirinfo.homedir);
+ if (dirinfo.socketdir)
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
+ "gpgme-dinfo: sockdir='%s'\n",
+ dirinfo.socketdir);
if (dirinfo.agent_socket)
_gpgme_debug (NULL,DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: agent='%s'\n",
@@ -336,6 +384,7 @@ get_gpgconf_item (int what)
case WANT_LIBDIR: result = dirinfo.libdir; break;
case WANT_DATADIR: result = dirinfo.datadir; break;
case WANT_LOCALEDIR: result = dirinfo.localedir; break;
+ case WANT_SOCKETDIR: result = dirinfo.socketdir; break;
case WANT_AGENT_SOCKET: result = dirinfo.agent_socket; break;
case WANT_AGENT_SSH_SOCKET: result = dirinfo.agent_ssh_socket; break;
case WANT_DIRMNGR_SOCKET: result = dirinfo.dirmngr_socket; break;
@@ -343,6 +392,11 @@ get_gpgconf_item (int what)
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_KEYBOXD_NAME: result = dirinfo.keyboxd_name; break;
+ case WANT_AGENT_NAME: result = dirinfo.agent_name; break;
+ case WANT_SCDAEMON_NAME: result = dirinfo.scdaemon_name; break;
+ case WANT_DIRMNGR_NAME: result = dirinfo.dirmngr_name; break;
+ case WANT_PINENTRY_NAME: result = dirinfo.pinentry_name; break;
case WANT_UISRV_SOCKET: result = dirinfo.uisrv_socket; break;
case WANT_GPG_ONE_MODE: result = dirinfo.gpg_one_mode? "1":NULL; break;
case WANT_GPG_WKS_CLIENT_NAME:
@@ -458,6 +512,16 @@ gpgme_get_dirinfo (const char *what)
return get_gpgconf_item (WANT_GPGSM_NAME);
else if (!strcmp (what, "g13-name"))
return get_gpgconf_item (WANT_G13_NAME);
+ else if (!strcmp (what, "keyboxd-name"))
+ return get_gpgconf_item (WANT_KEYBOXD_NAME);
+ else if (!strcmp (what, "agent-name"))
+ return get_gpgconf_item (WANT_AGENT_NAME);
+ else if (!strcmp (what, "scdaemon-name"))
+ return get_gpgconf_item (WANT_SCDAEMON_NAME);
+ else if (!strcmp (what, "dirmngr-name"))
+ return get_gpgconf_item (WANT_DIRMNGR_NAME);
+ else if (!strcmp (what, "pinentry-name"))
+ return get_gpgconf_item (WANT_PINENTRY_NAME);
else if (!strcmp (what, "gpg-wks-client-name"))
return get_gpgconf_item (WANT_GPG_WKS_CLIENT_NAME);
else if (!strcmp (what, "agent-ssh-socket"))
@@ -476,6 +540,8 @@ gpgme_get_dirinfo (const char *what)
return get_gpgconf_item (WANT_DATADIR);
else if (!strcmp (what, "localedir"))
return get_gpgconf_item (WANT_LOCALEDIR);
+ else if (!strcmp (what, "socketdir"))
+ return get_gpgconf_item (WANT_SOCKETDIR);
else
return NULL;
}
diff --git a/src/engine-backend.h b/src/engine-backend.h
index 8f90b6c..9b755a3 100644
--- a/src/engine-backend.h
+++ b/src/engine-backend.h
@@ -95,7 +95,10 @@ struct engine_ops
unsigned int extraflags,
gpgme_data_t pubkey, gpgme_data_t seckey);
gpgme_error_t (*import) (void *engine, gpgme_data_t keydata,
- gpgme_key_t *keyarray);
+ gpgme_key_t *keyarray,
+ const char *keyids[],
+ const char *import_filter,
+ const char *key_origin);
gpgme_error_t (*keylist) (void *engine, const char *pattern,
int secret_only, gpgme_keylist_mode_t mode,
int engine_flags);
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index b51ea17..88a248d 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -59,7 +59,7 @@ struct arg_and_data_s
int print_fd; /* Print the fd number and not the special form of it. */
int *arg_locp; /* Write back the argv idx of this argument when
building command line to this location. */
- char arg[1]; /* Used if data above is not used. */
+ char arg[FLEXIBLE_ARRAY_MEMBER]; /* Used if data above is not used. */
};
@@ -233,7 +233,7 @@ _add_arg (engine_gpg_t gpg, const char *prefix, const char *arg, size_t arglen,
assert (gpg);
assert (arg);
- a = malloc (sizeof *a + prefixlen + arglen);
+ a = malloc (offsetof (struct arg_and_data_s, arg) + prefixlen + arglen + 1);
if (!a)
return gpg_error_from_syserror ();
@@ -307,7 +307,7 @@ add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound)
assert (gpg);
assert (data);
- a = malloc (sizeof *a - 1);
+ a = malloc (offsetof (struct arg_and_data_s, arg));
if (!a)
return gpg_error_from_syserror ();
a->next = NULL;
@@ -2354,7 +2354,8 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|GPGME_EXPORT_MODE_MINIMAL
|GPGME_EXPORT_MODE_SSH
- |GPGME_EXPORT_MODE_SECRET)))
+ |GPGME_EXPORT_MODE_SECRET
+ |GPGME_EXPORT_MODE_SECRET_SUBKEY)))
return gpg_error (GPG_ERR_NOT_SUPPORTED);
if ((mode & GPGME_EXPORT_MODE_MINIMAL))
@@ -2379,7 +2380,9 @@ export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
}
else
{
- if ((mode & GPGME_EXPORT_MODE_SECRET))
+ if ((mode & GPGME_EXPORT_MODE_SECRET_SUBKEY))
+ err = add_arg (gpg, "--export-secret-subkeys");
+ else if ((mode & GPGME_EXPORT_MODE_SECRET))
err = add_arg (gpg, "--export-secret-keys");
else
err = add_arg (gpg, "--export");
@@ -2766,21 +2769,43 @@ string_from_data (gpgme_data_t data, int delim,
static gpgme_error_t
-gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
+gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray,
+ const char *keyids[], const char *import_filter,
+ const char *key_origin)
{
engine_gpg_t gpg = engine;
gpgme_error_t err;
int idx;
gpgme_data_encoding_t dataenc;
- if (keydata && keyarray)
+ if ((keydata && keyarray) || (keydata && keyids) || (keyarray && keyids))
return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */
dataenc = gpgme_data_get_encoding (keydata);
- if (keyarray)
+ if (keyids)
{
err = add_arg (gpg, "--recv-keys");
+ if (!err && import_filter && have_gpg_version (gpg, "2.1.14"))
+ {
+ err = add_arg (gpg, "--import-filter");
+ if (!err)
+ err = add_arg (gpg, import_filter);
+ }
+ if (!err)
+ err = add_arg (gpg, "--");
+ while (!err && *keyids && **keyids)
+ err = add_arg (gpg, *(keyids++));
+ }
+ else if (keyarray)
+ {
+ err = add_arg (gpg, "--recv-keys");
+ if (!err && import_filter && have_gpg_version (gpg, "2.1.14"))
+ {
+ err = add_arg (gpg, "--import-filter");
+ if (!err)
+ err = add_arg (gpg, import_filter);
+ }
if (!err)
err = add_arg (gpg, "--");
for (idx=0; !err && keyarray[idx]; idx++)
@@ -2812,6 +2837,12 @@ gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
should use an option to gpg to modify such commands (ala
--multifile). */
err = add_arg (gpg, "--fetch-keys");
+ if (!err && import_filter && have_gpg_version (gpg, "2.1.14"))
+ {
+ err = add_arg (gpg, "--import-filter");
+ if (!err)
+ err = add_arg (gpg, import_filter);
+ }
if (!err)
err = add_arg (gpg, "--");
helpptr = NULL;
@@ -2830,6 +2861,18 @@ gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
else
{
err = add_arg (gpg, "--import");
+ if (!err && import_filter && have_gpg_version (gpg, "2.1.14"))
+ {
+ err = add_arg (gpg, "--import-filter");
+ if (!err)
+ err = add_arg (gpg, import_filter);
+ }
+ if (!err && key_origin && have_gpg_version (gpg, "2.1.22"))
+ {
+ err = add_arg (gpg, "--key-origin");
+ if (!err)
+ err = add_arg (gpg, key_origin);
+ }
if (!err)
err = add_arg (gpg, "--");
if (!err)
diff --git a/src/engine-gpgconf.c b/src/engine-gpgconf.c
index 28f9115..caf4d78 100644
--- a/src/engine-gpgconf.c
+++ b/src/engine-gpgconf.c
@@ -445,8 +445,10 @@ gpgconf_parse_option (gpgme_conf_opt_t opt,
case GPGME_CONF_PUB_KEY:
case GPGME_CONF_SEC_KEY:
case GPGME_CONF_ALIAS_LIST:
- /* Skip quote character. */
- line++;
+ /* Skip quote character. It is required by specs but
+ * technically not always needed. */
+ if (*line == '\"' && line[1])
+ line++;
err = _gpgme_decode_percent_string (line, &arg->value.string,
0, 0);
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index d5f0d7a..9ab0555 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -1512,6 +1512,12 @@ gpgsm_export (void *engine, const char *pattern, gpgme_export_mode_t mode,
if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE);
+ if ((mode & ~(GPGME_EXPORT_MODE_SECRET
+ |GPGME_EXPORT_MODE_MINIMAL
+ |GPGME_EXPORT_MODE_RAW
+ |GPGME_EXPORT_MODE_PKCS12)))
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
if (!pattern)
pattern = "";
@@ -1559,6 +1565,12 @@ gpgsm_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE);
+ if ((mode & ~(GPGME_EXPORT_MODE_SECRET
+ |GPGME_EXPORT_MODE_MINIMAL
+ |GPGME_EXPORT_MODE_RAW
+ |GPGME_EXPORT_MODE_PKCS12)))
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
if (pattern && *pattern)
{
const char **pat = pattern;
@@ -1696,16 +1708,24 @@ gpgsm_genkey (void *engine,
static gpgme_error_t
-gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
+gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray,
+ const char *keyids[], const char *import_filter,
+ const char *key_origin)
{
engine_gpgsm_t gpgsm = engine;
gpgme_error_t err;
gpgme_data_encoding_t dataenc;
int idx;
+ (void)import_filter;
+ (void)key_origin;
+
if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE);
+ if (keyids)
+ return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+
if (keydata && keyarray)
return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */
diff --git a/src/engine.c b/src/engine.c
index 96b8d3a..db594cb 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -850,7 +850,8 @@ _gpgme_engine_op_tofu_policy (engine_t engine,
gpgme_error_t
_gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata,
- gpgme_key_t *keyarray)
+ gpgme_key_t *keyarray, const char *keyids[],
+ const char *import_filter, const char *key_origin)
{
if (!engine)
return gpg_error (GPG_ERR_INV_VALUE);
@@ -858,7 +859,8 @@ _gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata,
if (!engine->ops->import)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
- return (*engine->ops->import) (engine->engine, keydata, keyarray);
+ return (*engine->ops->import) (engine->engine, keydata, keyarray, keyids,
+ import_filter, key_origin);
}
diff --git a/src/engine.h b/src/engine.h
index d7ff542..8b45e13 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -141,7 +141,10 @@ gpgme_error_t _gpgme_engine_op_tofu_policy (engine_t engine,
gpgme_tofu_policy_t policy);
gpgme_error_t _gpgme_engine_op_import (engine_t engine,
gpgme_data_t keydata,
- gpgme_key_t *keyarray);
+ gpgme_key_t *keyarray,
+ const char *keyids[],
+ const char *import_filter,
+ const char *key_origin);
gpgme_error_t _gpgme_engine_op_keylist (engine_t engine,
const char *pattern,
int secret_only,
diff --git a/src/export.c b/src/export.c
index 4cee0ef..155085f 100644
--- a/src/export.c
+++ b/src/export.c
@@ -105,7 +105,8 @@ export_status_handler (void *priv, gpgme_status_code_t code, char *args)
return err;
else if (opd->err)
; /* We only want to report the first error. */
- else if (!strcmp (loc, "keyserver_send"))
+ else if (!strcmp (loc, "keyserver_send")
+ || !strcmp (loc, "export_keys.secret"))
opd->err = err;
break;
@@ -117,21 +118,29 @@ export_status_handler (void *priv, gpgme_status_code_t code, char *args)
static gpgme_error_t
-export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,
- gpgme_export_mode_t mode, gpgme_data_t keydata)
+check_mode (gpgme_export_mode_t mode, gpgme_protocol_t protocol,
+ gpgme_data_t keydata)
{
- gpgme_error_t err;
- void *hook;
- op_data_t opd;
-
if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
|GPGME_EXPORT_MODE_MINIMAL
|GPGME_EXPORT_MODE_SECRET
|GPGME_EXPORT_MODE_SSH
|GPGME_EXPORT_MODE_RAW
- |GPGME_EXPORT_MODE_PKCS12)))
+ |GPGME_EXPORT_MODE_PKCS12
+ |GPGME_EXPORT_MODE_SECRET_SUBKEY)))
return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */
+ if ((mode & GPGME_EXPORT_MODE_SSH))
+ {
+ if ((mode & (GPGME_EXPORT_MODE_EXTERN
+ |GPGME_EXPORT_MODE_MINIMAL
+ |GPGME_EXPORT_MODE_SECRET
+ |GPGME_EXPORT_MODE_RAW
+ |GPGME_EXPORT_MODE_PKCS12
+ |GPGME_EXPORT_MODE_SECRET_SUBKEY)))
+ return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
+ }
+
if ((mode & GPGME_EXPORT_MODE_SECRET))
{
if ((mode & GPGME_EXPORT_MODE_EXTERN))
@@ -140,11 +149,17 @@ export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,
&& (mode & GPGME_EXPORT_MODE_PKCS12))
return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
- if (ctx->protocol != GPGME_PROTOCOL_CMS
+ if (protocol != GPGME_PROTOCOL_CMS
&& (mode & (GPGME_EXPORT_MODE_RAW|GPGME_EXPORT_MODE_PKCS12)))
return gpg_error (GPG_ERR_INV_FLAG); /* Only supported for X.509. */
}
+ if ((mode & GPGME_EXPORT_MODE_SECRET_SUBKEY))
+ {
+ if ((mode & GPGME_EXPORT_MODE_EXTERN))
+ return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
+ }
+
if ((mode & GPGME_EXPORT_MODE_EXTERN))
{
if (keydata)
@@ -156,6 +171,22 @@ export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,
return gpg_error (GPG_ERR_INV_VALUE);
}
+ return 0;
+}
+
+
+static gpgme_error_t
+export_start (gpgme_ctx_t ctx, int synchronous, const char *pattern,
+ gpgme_export_mode_t mode, gpgme_data_t keydata)
+{
+ gpgme_error_t err;
+ void *hook;
+ op_data_t opd;
+
+ err = check_mode (mode, ctx->protocol, keydata);
+ if (err)
+ return err;
+
err = _gpgme_op_reset (ctx, synchronous);
if (err)
return err;
@@ -227,37 +258,9 @@ export_ext_start (gpgme_ctx_t ctx, int synchronous, const char *pattern[],
void *hook;
op_data_t opd;
- if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
- |GPGME_EXPORT_MODE_MINIMAL
- |GPGME_EXPORT_MODE_SECRET
- |GPGME_EXPORT_MODE_SSH
- |GPGME_EXPORT_MODE_RAW
- |GPGME_EXPORT_MODE_PKCS12)))
- return gpg_error (GPG_ERR_INV_VALUE); /* Invalid flags in MODE. */
-
- if ((mode & GPGME_EXPORT_MODE_SECRET))
- {
- if ((mode & GPGME_EXPORT_MODE_EXTERN))
- return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
- if ((mode & GPGME_EXPORT_MODE_RAW)
- && (mode & GPGME_EXPORT_MODE_PKCS12))
- return gpg_error (GPG_ERR_INV_FLAG); /* Combination not allowed. */
-
- if (ctx->protocol != GPGME_PROTOCOL_CMS
- && (mode & (GPGME_EXPORT_MODE_RAW|GPGME_EXPORT_MODE_PKCS12)))
- return gpg_error (GPG_ERR_INV_FLAG); /* Only supported for X.509. */
- }
-
- if ((mode & GPGME_EXPORT_MODE_EXTERN))
- {
- if (keydata)
- return gpg_error (GPG_ERR_INV_VALUE);
- }
- else
- {
- if (!keydata)
- return gpg_error (GPG_ERR_INV_VALUE);
- }
+ err = check_mode (mode, ctx->protocol, keydata);
+ if (err)
+ return err;
err = _gpgme_op_reset (ctx, synchronous);
if (err)
@@ -375,6 +378,11 @@ export_keys_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t keys[],
if (!keys)
return gpg_error (GPG_ERR_INV_VALUE);
+ if ((mode & GPGME_EXPORT_MODE_SECRET_SUBKEY))
+ {
+ return gpg_error (GPG_ERR_INV_FLAG);
+ }
+
/* Create a list of pattern from the keys. */
for (idx=nkeys=0; keys[idx]; idx++)
if (keys[idx]->protocol == ctx->protocol)
diff --git a/src/gpgme-tool.c b/src/gpgme-tool.c
index 0dbc4a9..e45ea12 100644
--- a/src/gpgme-tool.c
+++ b/src/gpgme-tool.c
@@ -2658,7 +2658,8 @@ cmd_import (assuan_context_t ctx, char *line)
static const char hlp_export[] =
- "EXPORT [--extern] [--minimal] [--secret [--pkcs12] [--raw]] [<pattern>]\n"
+ "EXPORT [--extern] [--minimal]\n"
+ " [--secret [--pkcs12] [--raw]|--secret-subkey] [<pattern>]\n"
"\n"
"Export the keys described by PATTERN. Write the\n"
"the output to the object set by the last OUTPUT command.";
@@ -2688,6 +2689,8 @@ cmd_export (assuan_context_t ctx, char *line)
mode |= GPGME_EXPORT_MODE_MINIMAL;
if (has_option (line, "--secret"))
mode |= GPGME_EXPORT_MODE_SECRET;
+ if (has_option (line, "--secret-subkey"))
+ mode |= GPGME_EXPORT_MODE_SECRET_SUBKEY;
if (has_option (line, "--raw"))
mode |= GPGME_EXPORT_MODE_RAW;
if (has_option (line, "--pkcs12"))
diff --git a/src/gpgme.c b/src/gpgme.c
index 255d116..6a5232e 100644
--- a/src/gpgme.c
+++ b/src/gpgme.c
@@ -254,6 +254,8 @@ gpgme_release (gpgme_ctx_t ctx)
free (ctx->auto_key_locate);
free (ctx->trust_model);
free (ctx->cert_expire);
+ free (ctx->key_origin);
+ free (ctx->import_filter);
_gpgme_engine_info_release (ctx->engine_info);
ctx->engine_info = NULL;
DESTROY_LOCK (ctx->lock);
@@ -586,6 +588,20 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
if (!ctx->cert_expire)
err = gpg_error_from_syserror ();
}
+ else if (!strcmp (name, "key-origin"))
+ {
+ free (ctx->key_origin);
+ ctx->key_origin = strdup (value);
+ if (!ctx->key_origin)
+ err = gpg_error_from_syserror ();
+ }
+ else if (!strcmp (name, "import-filter"))
+ {
+ free (ctx->import_filter);
+ ctx->import_filter = strdup (value);
+ if (!ctx->import_filter)
+ err = gpg_error_from_syserror ();
+ }
else
err = gpg_error (GPG_ERR_UNKNOWN_NAME);
@@ -659,6 +675,14 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
{
return ctx->cert_expire? ctx->cert_expire : "";
}
+ else if (!strcmp (name, "key-origin"))
+ {
+ return ctx->key_origin? ctx->key_origin : "";
+ }
+ else if (!strcmp (name, "import-filter"))
+ {
+ return ctx->import_filter? ctx->import_filter : "";
+ }
else
return NULL;
}
diff --git a/src/gpgme.def b/src/gpgme.def
index 6644cae..d8ccd4c 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -280,5 +280,8 @@ EXPORTS
gpgme_op_revsig @207
gpgme_op_revsig_start @208
+ gpgme_op_receive_keys @209
+ gpgme_op_receive_keys_start @210
+
; END
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 5c74afd..0f7c361 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -407,6 +407,7 @@ gpgme_pinentry_mode_t;
#define GPGME_EXPORT_MODE_RAW 32
#define GPGME_EXPORT_MODE_PKCS12 64
#define GPGME_EXPORT_MODE_SSH 256
+#define GPGME_EXPORT_MODE_SECRET_SUBKEY 512
typedef unsigned int gpgme_export_mode_t;
@@ -1737,6 +1738,12 @@ gpgme_error_t gpgme_op_import (gpgme_ctx_t ctx, gpgme_data_t keydata);
gpgme_error_t gpgme_op_import_keys_start (gpgme_ctx_t ctx, gpgme_key_t keys[]);
gpgme_error_t gpgme_op_import_keys (gpgme_ctx_t ctx, gpgme_key_t keys[]);
+/* Import the keys given by the array KEYIDS from a keyserver into the
+ * keyring. */
+gpgme_error_t gpgme_op_receive_keys_start (gpgme_ctx_t ctx,
+ const char *keyids[]);
+gpgme_error_t gpgme_op_receive_keys (gpgme_ctx_t ctx, const char *keyids[]);
+
/* Export the keys found by PATTERN into KEYDATA. */
gpgme_error_t gpgme_op_export_start (gpgme_ctx_t ctx, const char *pattern,
diff --git a/src/gpgme.pc.in b/src/gpgme.pc.in
index be288b8..80d59de 100644
--- a/src/gpgme.pc.in
+++ b/src/gpgme.pc.in
@@ -7,8 +7,8 @@ api_version=@GPGME_CONFIG_API_VERSION@
Name: gpgme
Description: GnuPG Made Easy to access GnuPG
-Requires: gpg-error, libassuan
+Requires.private: gpg-error, libassuan
Version: @PACKAGE_VERSION@
-Cflags: @GPGME_CONFIG_CFLAGS@
-Libs: @GPGME_CONFIG_LIBS@
+Cflags: -I${includedir} @GPGME_CONFIG_CFLAGS@
+Libs: -L${libdir} @GPGME_CONFIG_LIBS@
URL: https://www.gnupg.org/software/gpgme/index.html
diff --git a/src/import.c b/src/import.c
index 2834aec..85c459b 100644
--- a/src/import.c
+++ b/src/import.c
@@ -103,7 +103,7 @@ gpgme_op_import_result (gpgme_ctx_t ctx)
while (impstat)
{
TRACE_LOG ("import[%i] for %s = 0x%x (%s)",
- i, impstat->fpr, impstat->status,
+ i, impstat->fpr ? impstat->fpr : "null", impstat->status,
gpgme_strerror (impstat->result));
impstat = impstat->next;
i++;
@@ -223,6 +223,49 @@ parse_import_res (char *args, gpgme_import_result_t result)
}
+/* Parses an error on a status line and adds a corresponding import status.
+ Currently, only supports "import.parsep12 11". */
+static gpgme_error_t
+parse_error (char *args, gpgme_import_status_t *import_status)
+{
+ gpgme_import_status_t import;
+ char *tail;
+ long int nr;
+
+ tail = strchr (args, ' ');
+ if (!tail)
+ return 0;
+
+ *tail = '\0';
+ if (strcmp( args, "import.parsep12" ))
+ return 0;
+
+ args = tail + 1;
+
+ gpg_err_set_errno (0);
+ nr = strtol (args, &tail, 0);
+ if (errno || args == tail || !(*tail == ' ' || !*tail))
+ {
+ /* The crypto backend does not behave. */
+ return trace_gpg_error (GPG_ERR_INV_ENGINE);
+ }
+ if (nr != GPG_ERR_BAD_PASSPHRASE)
+ return 0;
+
+ import = malloc (sizeof (*import));
+ if (!import)
+ return gpg_error_from_syserror ();
+ import->next = NULL;
+
+ import->result = gpg_error (GPG_ERR_BAD_PASSPHRASE);
+ import->status = 0;
+ import->fpr = 0;
+
+ *import_status = import;
+ return 0;
+}
+
+
static gpgme_error_t
import_status_handler (void *priv, gpgme_status_code_t code, char *args)
{
@@ -252,6 +295,15 @@ import_status_handler (void *priv, gpgme_status_code_t code, char *args)
err = parse_import_res (args, &opd->result);
break;
+ case GPGME_STATUS_ERROR:
+ err = parse_error (args, opd->lastp);
+ if (err)
+ return err;
+
+ if (*opd->lastp)
+ opd->lastp = &(*opd->lastp)->next;
+ break;
+
default:
break;
}
@@ -282,7 +334,8 @@ _gpgme_op_import_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t keydata)
_gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx);
- return _gpgme_engine_op_import (ctx->engine, keydata, NULL);
+ return _gpgme_engine_op_import (ctx->engine, keydata, NULL, NULL,
+ ctx->import_filter, ctx->key_origin);
}
@@ -365,7 +418,8 @@ _gpgme_op_import_keys_start (gpgme_ctx_t ctx, int synchronous,
_gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx);
- return _gpgme_engine_op_import (ctx->engine, NULL, keys);
+ return _gpgme_engine_op_import (ctx->engine, NULL, keys, NULL,
+ ctx->import_filter, ctx->key_origin);
}
@@ -438,6 +492,94 @@ gpgme_op_import_keys (gpgme_ctx_t ctx, gpgme_key_t *keys)
}
+static gpgme_error_t
+_gpgme_op_receive_keys_start (gpgme_ctx_t ctx, int synchronous, const char *keyids[])
+{
+ gpgme_error_t err;
+ void *hook;
+ op_data_t opd;
+
+ err = _gpgme_op_reset (ctx, synchronous);
+ if (err)
+ return err;
+
+ err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook,
+ sizeof (*opd), release_op_data);
+ opd = hook;
+ if (err)
+ return err;
+ opd->lastp = &opd->result.imports;
+
+ if (!keyids || !*keyids)
+ return gpg_error (GPG_ERR_NO_DATA);
+
+ _gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx);
+
+ return _gpgme_engine_op_import (ctx->engine, NULL, NULL, keyids,
+ ctx->import_filter, ctx->key_origin);
+}
+
+
+/* Asynchronous version of gpgme_op_receive_keys. */
+gpgme_error_t
+gpgme_op_receive_keys_start (gpgme_ctx_t ctx, const char *keyids[])
+{
+ gpgme_error_t err;
+
+ TRACE_BEG (DEBUG_CTX, "gpgme_op_receive_keys_start", ctx, "");
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ if (_gpgme_debug_trace () && keyids)
+ {
+ int i = 0;
+
+ while (keyids[i] && *keyids[i])
+ {
+ TRACE_LOG ("keyids[%i] = %s", i, keyids[i]);
+ i++;
+ }
+ }
+
+ err = _gpgme_op_receive_keys_start (ctx, 1, keyids);
+ return TRACE_ERR (err);
+}
+
+
+/* Retrieve the keys from the array KEYIDS from a keyserver and import
+ them into the keyring.
+
+ KEYIDS is a NULL terminated array of . The result
+ is the usual import result structure. */
+gpgme_error_t
+gpgme_op_receive_keys (gpgme_ctx_t ctx, const char *keyids[])
+{
+ gpgme_error_t err;
+
+ TRACE_BEG (DEBUG_CTX, "gpgme_op_receive_keys", ctx, "");
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ if (_gpgme_debug_trace () && keyids)
+ {
+ int i = 0;
+
+ while (keyids[i] && *keyids[i])
+ {
+ TRACE_LOG ("keyids[%i] = %s", i, keyids[i]);
+ i++;
+ }
+ }
+
+ err = _gpgme_op_receive_keys_start (ctx, 1, keyids);
+ if (!err)
+ err = _gpgme_wait_one (ctx);
+ return TRACE_ERR (err);
+}
+
+
/* Deprecated interface. */
gpgme_error_t
gpgme_op_import_ext (gpgme_ctx_t ctx, gpgme_data_t keydata, int *nr)
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index 8e86e4e..86d2a5d 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -279,6 +279,9 @@ GPGME_1.0 {
gpgme_op_revsig;
gpgme_op_revsig_start;
+ gpgme_op_receive_keys;
+ gpgme_op_receive_keys_start;
+
local:
*;
diff --git a/src/posix-io.c b/src/posix-io.c
index e712ef2..5c6cf1d 100644
--- a/src/posix-io.c
+++ b/src/posix-io.c
@@ -570,7 +570,7 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
if (fd_list[i].fd > fd)
fd = fd_list[i].fd;
fd++;
-#if defined(__sun) || defined(__FreeBSD__)
+#if defined(__sun) || defined(__FreeBSD__) || defined(__GLIBC__)
closefrom (fd);
max_fds = fd;
#else /*!__sun */
@@ -691,8 +691,119 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
/* Select on the list of fds. Returns: -1 = error, 0 = timeout or
nothing to select, > 0 = number of signaled fds. */
-int
-_gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
+#ifdef HAVE_POLL_H
+static int
+_gpgme_io_select_poll (struct io_select_fd_s *fds, size_t nfds, int nonblock)
+{
+ struct pollfd *poll_fds = NULL;
+ nfds_t poll_nfds;
+ /* Use a 1s timeout. */
+ int timeout = 1000;
+ unsigned int i;
+ int any;
+ int count;
+ void *dbg_help = NULL;
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_select", NULL,
+ "nfds=%zu, nonblock=%u", nfds, nonblock);
+
+
+ if (nonblock)
+ timeout = 0;
+
+ poll_fds = malloc (sizeof (*poll_fds)*nfds);
+ if (!poll_fds)
+ return -1;
+
+ poll_nfds = 0;
+
+ TRACE_SEQ (dbg_help, "poll on [ ");
+
+ any = 0;
+ for (i = 0; i < nfds; i++)
+ {
+ if (fds[i].fd == -1)
+ continue;
+ if (fds[i].for_read || fds[i].for_write)
+ {
+ poll_fds[poll_nfds].fd = fds[i].fd;
+ poll_fds[poll_nfds].events = 0;
+ poll_fds[poll_nfds].revents = 0;
+ if (fds[i].for_read)
+ {
+ poll_fds[poll_nfds].events |= POLLIN;
+ TRACE_ADD1 (dbg_help, "r=%d ", fds[i].fd);
+ }
+ if (fds[i].for_write)
+ {
+ poll_fds[poll_nfds].events |= POLLOUT;
+ TRACE_ADD1 (dbg_help, "w=%d ", fds[i].fd);
+ }
+ poll_nfds++;
+ any = 1;
+ }
+ fds[i].signaled = 0;
+ }
+ TRACE_END (dbg_help, "]");
+ if (!any)
+ {
+ free (poll_fds);
+ return TRACE_SYSRES (0);
+ }
+
+ do
+ count = poll (poll_fds, poll_nfds, timeout);
+ while (count < 0 && (errno == EINTR || errno == EAGAIN));
+ if (count < 0)
+ {
+ int save_errno = errno;
+ free (poll_fds);
+ errno = save_errno;
+ return TRACE_SYSRES (-1);
+ }
+
+ TRACE_SEQ (dbg_help, "poll OK [ ");
+ if (TRACE_ENABLED (dbg_help))
+ {
+ poll_nfds = 0;
+ for (i = 0; i < nfds; i++)
+ {
+ if (fds[i].fd == -1)
+ continue;
+ if ((poll_fds[poll_nfds].revents & (POLLIN|POLLHUP)))
+ TRACE_ADD1 (dbg_help, "r=%d ", i);
+ if ((poll_fds[poll_nfds].revents & POLLOUT))
+ TRACE_ADD1 (dbg_help, "w=%d ", i);
+ poll_nfds++;
+ }
+ TRACE_END (dbg_help, "]");
+ }
+
+ poll_nfds = 0;
+ for (i = 0; i < nfds; i++)
+ {
+ if (fds[i].fd == -1)
+ continue;
+ if (fds[i].for_read || fds[i].for_write)
+ {
+ short events_to_be_checked = 0;
+
+ if (fds[i].for_read)
+ events_to_be_checked |= (POLLIN|POLLHUP);
+ if (fds[i].for_write)
+ events_to_be_checked |= POLLOUT;
+ if ((poll_fds[poll_nfds].revents & events_to_be_checked))
+ fds[i].signaled = 1;
+
+ poll_nfds++;
+ }
+ }
+
+ free (poll_fds);
+ return TRACE_SYSRES (count);
+}
+#else
+static int
+_gpgme_io_select_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
{
fd_set readfds;
fd_set writefds;
@@ -802,7 +913,17 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
}
return TRACE_SYSRES (count);
}
+#endif
+int
+_gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
+{
+#ifdef HAVE_POLL_H
+ return _gpgme_io_select_poll (fds, nfds, nonblock);
+#else
+ return _gpgme_io_select_select (fds, nfds, nonblock);
+#endif
+}
int
_gpgme_io_recvmsg (int fd, struct msghdr *msg, int flags)
diff --git a/src/w32-util.c b/src/w32-util.c
index 2631ae7..e4757a2 100644
--- a/src/w32-util.c
+++ b/src/w32-util.c
@@ -841,16 +841,17 @@ _gpgme_access (const char *path, int mode)
/* Like CreateProcessA but mapping the arguments to wchar API */
-int _gpgme_create_process_utf8 (const char *application_name_utf8,
- char *command_line_utf8,
- LPSECURITY_ATTRIBUTES lpProcessAttributes,
- LPSECURITY_ATTRIBUTES lpThreadAttributes,
- BOOL bInheritHandles,
- DWORD dwCreationFlags,
- void *lpEnvironment,
- char *working_directory_utf8,
- LPSTARTUPINFOA si,
- LPPROCESS_INFORMATION lpProcessInformation)
+int
+_gpgme_create_process_utf8 (const char *application_name_utf8,
+ char *command_line_utf8,
+ LPSECURITY_ATTRIBUTES lpProcessAttributes,
+ LPSECURITY_ATTRIBUTES lpThreadAttributes,
+ BOOL bInheritHandles,
+ DWORD dwCreationFlags,
+ void *lpEnvironment,
+ char *working_directory_utf8,
+ LPSTARTUPINFOA si,
+ LPPROCESS_INFORMATION lpProcessInformation)
{
BOOL ret;
wchar_t *application_name = utf8_to_wchar0 (application_name_utf8);