summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJinWang An <jinwang.an@samsung.com>2021-12-01 16:54:38 +0900
committerJinWang An <jinwang.an@samsung.com>2021-12-01 16:54:38 +0900
commit5793c283c7ddc13e62a1eef6ecd38d7e996d6e3f (patch)
tree984b58b62afb259d96ca5e0af2c737300ca62722 /src
parenta4cc2ca8c024d3187c4ff465a176c7585b533411 (diff)
downloadgpgme-5793c283c7ddc13e62a1eef6ecd38d7e996d6e3f.tar.gz
gpgme-5793c283c7ddc13e62a1eef6ecd38d7e996d6e3f.tar.bz2
gpgme-5793c283c7ddc13e62a1eef6ecd38d7e996d6e3f.zip
Imported Upstream version 1.13.1upstream/1.13.1
Diffstat (limited to 'src')
-rw-r--r--src/assuan-support.c4
-rw-r--r--src/cJSON.c48
-rw-r--r--src/data-compat.c2
-rw-r--r--src/data-fd.c2
-rw-r--r--src/data-mem.c2
-rw-r--r--src/data.c4
-rw-r--r--src/debug.c245
-rw-r--r--src/debug.h40
-rw-r--r--src/dirinfo.c22
-rw-r--r--src/engine-assuan.c2
-rw-r--r--src/engine-g13.c2
-rw-r--r--src/engine-gpg.c2
-rw-r--r--src/engine-gpgsm.c46
-rw-r--r--src/engine-uiserver.c2
-rw-r--r--src/engine.c1
-rw-r--r--src/posix-io.c144
-rw-r--r--src/posix-util.c9
-rw-r--r--src/sys-util.h13
-rw-r--r--src/version.c6
-rw-r--r--src/w32-glib-io.c21
-rw-r--r--src/w32-io.c53
-rw-r--r--src/w32-util.c143
-rw-r--r--src/wait.c15
23 files changed, 545 insertions, 283 deletions
diff --git a/src/assuan-support.c b/src/assuan-support.c
index 925aeba..0ddf29b 100644
--- a/src/assuan-support.c
+++ b/src/assuan-support.c
@@ -54,7 +54,7 @@ _gpgme_assuan_log_cb (assuan_context_t ctx, void *hook,
if (msg == NULL)
return 1;
- _gpgme_debug (DEBUG_ASSUAN, -1, NULL, NULL, NULL, "%s", msg);
+ _gpgme_debug (NULL, DEBUG_ASSUAN, -1, NULL, NULL, NULL, "%s", msg);
return 0;
}
@@ -234,7 +234,7 @@ my_spawn (assuan_context_t ctx, pid_t *r_pid, const char *name,
break;
}
logger_fd = strtol (argv[loc], &tail, 10);
- if (tail == argv[loc] || logger_fd <= 0)
+ if (tail == argv[loc] || logger_fd < 0)
{
err = GPG_ERR_INV_ARG;
break;
diff --git a/src/cJSON.c b/src/cJSON.c
index 101d556..f233848 100644
--- a/src/cJSON.c
+++ b/src/cJSON.c
@@ -40,6 +40,7 @@
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
+#include <stdint.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
@@ -146,8 +147,13 @@ cJSON_Delete (cJSON * c)
static const char *
parse_number (cJSON * item, const char *num)
{
- double n = 0, sign = 1, scale = 0;
- int subscale = 0, signsubscale = 1;
+ int subscale = 0;
+ int signsubscale = 1;
+ double n = 0;
+ double sign = 1;
+ double scale = 0;
+ double dblmin = INT32_MIN;
+ double dblmax = INT32_MAX;
if (*num == '-')
sign = -1, num++; /* Has sign? */
@@ -169,17 +175,37 @@ parse_number (cJSON * item, const char *num)
num++;
if (*num == '+')
num++;
- else if (*num == '-')
- signsubscale = -1, num++; /* With sign? */
+ else if (*num == '-') /* With sign? */
+ signsubscale = -1, num++;
while (*num >= '0' && *num <= '9')
- subscale = (subscale * 10) + (*num++ - '0'); /* Number? */
+ {
+ if ((10 * (double)subscale) > dblmax)
+ break;
+ subscale = (subscale * 10) + (*num++ - '0');
+ }
}
/* number = +/- number.fraction * 10^+/- exponent */
n = sign * n * pow (10.0, (scale + subscale * signsubscale));
- item->valuedouble = n;
- item->valueint = (int) n;
+ /* For NAN set both parts to 0. For out of range values let the
+ * integer part be 0. */
+ if (isnan (n) || isinf (n))
+ {
+ item->valuedouble = 0;
+ item->valueint = 0;
+ }
+ else if (n > dblmax || n < dblmin)
+ {
+ item->valuedouble = n;
+ item->valueint = 0;
+ }
+ else
+ {
+ item->valuedouble = n;
+ item->valueint = (int)n;
+ }
+
item->type = cJSON_Number;
return num;
}
@@ -190,6 +216,8 @@ print_number (cJSON * item)
{
char *str;
double d = item->valuedouble;
+ int i;
+
if (fabs (((double) item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX
&& d >= INT_MIN)
{
@@ -203,7 +231,11 @@ print_number (cJSON * item)
str = xtrymalloc (64); /* This is a nice tradeoff. */
if (str)
{
- if (fabs (floor (d) - d) <= DBL_EPSILON && fabs (d) < 1.0e60)
+ if (isnan (d))
+ strcpy (str, "nan");
+ else if ((i = isinf (d)))
+ strcpy (str, i > 0? "inf" : ":-inf");
+ else if (fabs (floor (d) - d) <= DBL_EPSILON && fabs (d) < 1.0e60)
sprintf (str, "%.0f", d);
else if (fabs (d) < 1.0e-6 || fabs (d) > 1.0e9)
sprintf (str, "%e", d);
diff --git a/src/data-compat.c b/src/data-compat.c
index 64ed2d2..4960bf4 100644
--- a/src/data-compat.c
+++ b/src/data-compat.c
@@ -160,7 +160,7 @@ gpgme_error_to_errno (gpgme_error_t err)
break;
}
}
- TRACE (DEBUG_DATA, "gpgme:gpgme_error_to_errno", 0,
+ TRACE (DEBUG_DATA, "gpgme:gpgme_error_to_errno", NULL,
"mapping %s <%s> to: %s", gpgme_strerror (err),
gpgme_strsource (err), strerror (res));
gpg_err_set_errno (res);
diff --git a/src/data-fd.c b/src/data-fd.c
index 5c68130..4bc8f61 100644
--- a/src/data-fd.c
+++ b/src/data-fd.c
@@ -75,7 +75,7 @@ gpgme_error_t
gpgme_data_new_from_fd (gpgme_data_t *r_dh, int fd)
{
gpgme_error_t err;
- TRACE_BEG (DEBUG_DATA, "gpgme_data_new_from_fd", r_dh, "fd=0x%x", fd);
+ TRACE_BEG (DEBUG_DATA, "gpgme_data_new_from_fd", r_dh, "fd=%d", fd);
err = _gpgme_data_new (r_dh, &fd_cbs);
if (err)
diff --git a/src/data-mem.c b/src/data-mem.c
index f51d2fd..539b453 100644
--- a/src/data-mem.c
+++ b/src/data-mem.c
@@ -296,7 +296,7 @@ gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len)
void
gpgme_free (void *buffer)
{
- TRACE (DEBUG_DATA, "gpgme_free", buffer, "");
+ TRACE (DEBUG_DATA, "gpgme_free", NULL, "p=%p", buffer);
if (buffer)
free (buffer);
diff --git a/src/data.c b/src/data.c
index 44ef2d3..7059590 100644
--- a/src/data.c
+++ b/src/data.c
@@ -574,7 +574,7 @@ _gpgme_data_inbound_handler (void *opaque, int fd)
char *bufp = buffer;
gpgme_ssize_t buflen;
TRACE_BEG (DEBUG_CTX, "_gpgme_data_inbound_handler", dh,
- "fd=0x%x", fd);
+ "fd=%d", fd);
buflen = _gpgme_io_read (fd, buffer, BUFFER_SIZE);
if (buflen < 0)
@@ -605,7 +605,7 @@ _gpgme_data_outbound_handler (void *opaque, int fd)
gpgme_data_t dh = (gpgme_data_t) data->handler_value;
gpgme_ssize_t nwritten;
TRACE_BEG (DEBUG_CTX, "_gpgme_data_outbound_handler", dh,
- "fd=0x%x", fd);
+ "fd=%d", fd);
if (!dh->pending_len)
{
diff --git a/src/debug.c b/src/debug.c
index 81c2a90..d5d11bd 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -1,6 +1,6 @@
/* debug.c - helpful output in desperate situations
* Copyright (C) 2000 Werner Koch (dd9jn)
- * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009 g10 Code GmbH
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007, 2009, 2019 g10 Code GmbH
*
* This file is part of GPGME.
*
@@ -50,10 +50,6 @@
#include "debug.h"
-/* Lock to serialize initialization of the debug output subsystem and
- output of actual debug messages. */
-DEFINE_STATIC_LOCK (debug_lock);
-
/* The amount of detail requested by the user, per environment
variable GPGME_DEBUG. */
static int debug_level;
@@ -135,7 +131,6 @@ debug_init (void)
{
static int initialized;
- LOCK (debug_lock);
if (!initialized)
{
gpgme_error_t err;
@@ -152,10 +147,7 @@ debug_init (void)
{
err = _gpgme_getenv ("GPGME_DEBUG", &e);
if (err)
- {
- UNLOCK (debug_lock);
- return;
- }
+ return;
}
initialized = 1;
@@ -201,16 +193,15 @@ debug_init (void)
free (e);
}
}
- UNLOCK (debug_lock);
if (debug_level > 0)
{
- _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme_debug: level=%d\n", debug_level);
#ifdef HAVE_W32_SYSTEM
{
const char *name = _gpgme_get_inst_dir ();
- _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme_debug: gpgme='%s'\n", name? name: "?");
}
#endif
@@ -219,9 +210,9 @@ debug_init (void)
-/* This should be called as soon as the locks are initialized. It is
- required so that the assuan logging gets conncted to the gpgme log
- stream as early as possible. */
+/* This should be called as soon as possible. It is required so that
+ * the assuan logging gets connected to the gpgme log stream as early
+ * as possible. */
void
_gpgme_debug_subsystem_init (void)
{
@@ -240,6 +231,10 @@ _gpgme_debug_subsystem_init (void)
* 2 = debug a function (used by macro TRACE_LOG)
* 3 = leave a function (used by macro TRACE_SUC)
*
+ * If LINE is not NULL the output will be stored in that variabale but
+ * without a LF. _gpgme_debug_add can be used to add more and
+ * _gpgme_debug_end to finally output it.
+ *
* Returns: 0
*
* Note that we always return 0 because the old TRACE macro evaluated
@@ -249,96 +244,96 @@ _gpgme_debug_subsystem_init (void)
* value from the TRACE macros are actually used somewhere.
*/
int
-_gpgme_debug (int level, int mode, const char *func, const char *tagname,
+_gpgme_debug (void **line, int level, int mode,
+ const char *func, const char *tagname,
const char *tagvalue, const char *format, ...)
{
va_list arg_ptr;
int saved_errno;
int need_lf;
+ int indent;
+ char *prefix, *stdinfo, *userinfo;
+ const char *modestr;
+ int no_userinfo = 0;
if (debug_level < level)
return 0;
+#ifdef FRAME_NR
+ indent = frame_nr > 0? (2 * (frame_nr - 1)):0;
+#else
+ indent = 0;
+#endif
+
saved_errno = errno;
va_start (arg_ptr, format);
- LOCK (debug_lock);
{
struct tm *tp;
time_t atime = time (NULL);
tp = localtime (&atime);
- fprintf (errfp, "GPGME %04d-%02d-%02d %02d:%02d:%02d <0x%04llx> ",
- 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
- tp->tm_hour, tp->tm_min, tp->tm_sec,
- (unsigned long long) ath_self ());
+ prefix = gpgrt_bsprintf ("GPGME %04d%02d%02dT%02d%02d%02d %04llX %*s",
+ 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+ tp->tm_hour, tp->tm_min, tp->tm_sec,
+ (unsigned long long) ath_self (),
+ indent < 40? indent : 40, "");
}
-#ifdef FRAME_NR
- {
- int indent;
-
- indent = frame_nr > 0? (2 * (frame_nr - 1)):0;
- fprintf (errfp, "%*s", indent < 40? indent : 40, "");
- }
-#endif
- need_lf = 0;
switch (mode)
{
- case -1: /* Do nothing. */
- break;
- case 0:
- fprintf (errfp, "%s: call: %s=%p ", func, tagname, tagvalue);
- break;
- case 1:
- fprintf (errfp, "%s: enter: %s=%p ", func, tagname, tagvalue);
- break;
- case 2:
- fprintf (errfp, "%s: check: %s=%p ", func, tagname, tagvalue);
- break;
- case 3:
- if (tagname)
- fprintf (errfp, "%s: leave: %s=%p ", func, tagname, tagvalue);
- else
- fprintf (errfp, "%s: leave: ", func);
- break;
- default:
- fprintf (errfp, "%s: ?(mode=%d): %s=%p ", func, mode, tagname, tagvalue);
- break;
+ case -1: modestr = NULL; break; /* Do nothing. */
+ case 0: modestr = "call"; break;
+ case 1: modestr = "enter"; break;
+ case 2: modestr = "check"; break;
+ case 3: modestr = "leave"; break;
+ default: modestr = "mode?"; break;
}
- need_lf = (mode != -1 && (!format || !*format));
-
- vfprintf (errfp, format, arg_ptr);
- va_end (arg_ptr);
- if (need_lf || (format && *format && format[strlen (format) - 1] != '\n'))
- putc ('\n', errfp);
- UNLOCK (debug_lock);
- fflush (errfp);
-
- gpg_err_set_errno (saved_errno);
- return 0;
-}
+ if (!modestr)
+ stdinfo = NULL;
+ else if (tagname && strcmp (tagname, XSTRINGIFY (NULL)))
+ stdinfo = gpgrt_bsprintf ("%s: %s: %s=%p ", func,modestr,tagname,tagvalue);
+ else
+ stdinfo = gpgrt_bsprintf ("%s: %s: ", func, modestr);
-/* Start a new debug line in *LINE, logged at level LEVEL or higher,
- and starting with the formatted string FORMAT. */
-void
-_gpgme_debug_begin (void **line, int level, const char *format, ...)
-{
- va_list arg_ptr;
- int res;
+ if (format && *format)
+ userinfo = gpgrt_vbsprintf (format, arg_ptr);
+ else
+ {
+ userinfo = NULL;
+ no_userinfo = 1;
+ }
+ va_end (arg_ptr);
- if (debug_level < level)
+ if (mode != -1 && (!format || !*format))
+ need_lf = 1;
+ else if (userinfo && *userinfo && userinfo[strlen (userinfo) - 1] != '\n')
+ need_lf = 1;
+ else
+ need_lf = 0;
+
+ if (line)
+ *line = gpgrt_bsprintf ("%s%s%s",
+ prefix? prefix : "GPGME out-of-core ",
+ !modestr? "" : stdinfo? stdinfo :
+ (!format || !*format)? "" :"out-of-core ",
+ userinfo? userinfo : "out-of-core");
+ else
{
- /* Disable logging of this line. */
- *line = NULL;
- return;
+ fprintf (errfp, "%s%s%s%s",
+ prefix? prefix : "GPGME out-of-core ",
+ !modestr? "" : stdinfo? stdinfo :
+ (!format || !*format)? "" :"out-of-core ",
+ userinfo? userinfo : no_userinfo? "" : "out-of-core",
+ need_lf? "\n":"");
+ fflush (errfp);
}
- va_start (arg_ptr, format);
- res = gpgrt_vasprintf ((char **) line, format, arg_ptr);
- va_end (arg_ptr);
- if (res < 0)
- *line = NULL;
+ gpgrt_free (userinfo);
+ gpgrt_free (stdinfo);
+ gpgrt_free (prefix);
+ gpg_err_set_errno (saved_errno);
+ return 0;
}
@@ -377,12 +372,16 @@ _gpgme_debug_add (void **line, const char *format, ...)
void
_gpgme_debug_end (void **line)
{
+ const char *string;
+
if (!*line)
return;
+ string = *line;
- /* The smallest possible level is 1, so force logging here by
- using that. */
- _gpgme_debug (1, -1, NULL, NULL, NULL, "%s", (char*)*line);
+ fprintf (errfp, "%s%s",
+ string,
+ (*string && string[strlen (string)-1] != '\n')? "\n":"");
+ fflush (errfp);
gpgrt_free (*line);
*line = NULL;
}
@@ -404,33 +403,65 @@ _gpgme_debug_buffer (int lvl, const char *const fmt,
if (!buffer)
return;
- while (idx < len)
+ if (lvl > 9)
{
- char str[51];
- char *strp = str;
- char *strp2 = &str[34];
+ while (idx < len)
+ {
+ char str[51];
+ char *strp = str;
+ char *strp2 = &str[34];
- for (j = 0; j < 16; j++)
- {
- unsigned char val;
- if (idx < len)
- {
- val = buffer[idx++];
- *(strp++) = TOHEX (val >> 4);
- *(strp++) = TOHEX (val % 16);
- *(strp2++) = isprint (val) ? val : '.';
- }
- else
- {
- *(strp++) = ' ';
- *(strp++) = ' ';
- }
- if (j == 7)
- *(strp++) = ' ';
- }
- *(strp++) = ' ';
- *(strp2) = '\0';
+ for (j = 0; j < 16; j++)
+ {
+ unsigned char val;
+ if (idx < len)
+ {
+ val = buffer[idx++];
+ *(strp++) = TOHEX (val >> 4);
+ *(strp++) = TOHEX (val % 16);
+ *(strp2++) = isprint (val)? val : '.';
+ }
+ else
+ {
+ *(strp++) = ' ';
+ *(strp++) = ' ';
+ }
+ if (j == 7)
+ *(strp++) = ' ';
+ }
+ *(strp++) = ' ';
+ *(strp2) = '\0';
- _gpgme_debug (lvl, -1, NULL, NULL, NULL, fmt, func, str);
+ _gpgme_debug (NULL, lvl, -1, NULL, NULL, NULL, fmt, func, str);
+ }
+ }
+ else
+ {
+ while (idx < len)
+ {
+ char str[48+4+1];
+ char *strp = str;
+
+ for (j = 0; j < 48; j++)
+ {
+ unsigned char val;
+ if (idx < len)
+ {
+ val = buffer[idx++];
+ if (val == '\n')
+ {
+ *strp++ = '<';
+ *strp++ = 'L';
+ *strp++ = 'F';
+ *strp++ = '>';
+ break;
+ }
+ *strp++ = (val > 31 && val < 127)? val : '.';
+ }
+ }
+ *strp = 0;
+
+ _gpgme_debug (NULL, lvl, -1, NULL, NULL, NULL, fmt, func, str);
+ }
}
}
diff --git a/src/debug.h b/src/debug.h
index 7ef8cf2..fa0bfc6 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -25,6 +25,7 @@
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
+#include <errno.h>
#include "gpgme.h" /* Required for gpgme_error stuff. */
@@ -68,15 +69,11 @@ int _gpgme_debug_set_debug_envvar (const char *value);
void _gpgme_debug_subsystem_init (void);
/* Log the formatted string FORMAT at debug level LEVEL or higher. */
-int _gpgme_debug (int level, int mode,
+int _gpgme_debug (void **line, int level, int mode,
const char *func, const char *tagname, const char *tagvalue,
- const char *format, ...) GPGRT_ATTR_PRINTF(6,7);
+ const char *format, ...) GPGRT_ATTR_PRINTF(7,8);
-/* Start a new debug line in *LINE, logged at level LEVEL or higher,
- and starting with the formatted string FORMAT. */
-void _gpgme_debug_begin (void **helper, int level, const char *format, ...);
-
/* Add the formatted string FORMAT to the debug line *LINE. */
void _gpgme_debug_add (void **helper, const char *format, ...);
@@ -94,7 +91,7 @@ int _gpgme_debug_frame_end (void);
static inline gpgme_error_t
_gpgme_trace_gpgme_error (gpgme_error_t err, const char *file, int line)
{
- _gpgme_debug (DEBUG_ENGINE, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_ENGINE, -1, NULL, NULL, NULL,
"%s:%d: returning error: %s\n",
_gpgme_debug_srcname (file), line, gpgme_strerror (err));
return err;
@@ -116,13 +113,13 @@ _gpgme_trace_gpgme_error (gpgme_error_t err, const char *file, int line)
/* Note: We can't protect this with a do-while block. */
#define TRACE_BEG(lvl, name, tag, ...) \
_TRACE (lvl, name, tag); \
- _gpgme_debug (_gpgme_trace_level, 1, \
+ _gpgme_debug (NULL, _gpgme_trace_level, 1, \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
__VA_ARGS__)
#define TRACE(lvl, name, tag, ...) do { \
_gpgme_debug_frame_begin (); \
- _gpgme_debug (lvl, 0, name, STRINGIFY (tag), (void *)(uintptr_t)tag, \
+ _gpgme_debug (NULL, lvl, 0, name, STRINGIFY (tag), (void *)(uintptr_t)tag, \
__VA_ARGS__); \
_gpgme_debug_frame_end (); \
} while (0)
@@ -135,9 +132,9 @@ static inline gpg_error_t
_trace_err (gpg_error_t err, int lvl, const char *func, int line)
{
if (!err)
- _gpgme_debug (lvl, 3, func, NULL, NULL, "");
+ _gpgme_debug (NULL, lvl, 3, func, NULL, NULL, "");
else
- _gpgme_debug (lvl, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, lvl, -1, NULL, NULL, NULL,
"%s:%d: error: %s <%s>\n",
func, line, gpgme_strerror (err), gpgme_strsource (err));
_gpgme_debug_frame_end ();
@@ -151,11 +148,11 @@ static inline int
_trace_sysres (int res, int lvl, const char *func, int line)
{
if (res >= 0)
- _gpgme_debug (lvl, 3, func, NULL, NULL, "result=%d", res);
+ _gpgme_debug (NULL, lvl, 3, func, NULL, NULL, "result=%d", res);
else
- _gpgme_debug (lvl, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, lvl, -1, NULL, NULL, NULL,
"%s:%d: error: %s (%d)\n",
- func, line, strerror (res), res);
+ func, line, strerror (errno), errno);
_gpgme_debug_frame_end ();
return res;
}
@@ -167,9 +164,9 @@ static inline int
_trace_syserr (int rc, int lvl, const char *func, int line)
{
if (!rc)
- _gpgme_debug (lvl, 3, func, NULL, NULL, "result=0");
+ _gpgme_debug (NULL, lvl, 3, func, NULL, NULL, "result=0");
else
- _gpgme_debug (lvl, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, lvl, -1, NULL, NULL, NULL,
"%s:%d: error: %s (%d)\n",
func, line, strerror (rc), rc);
_gpgme_debug_frame_end ();
@@ -177,13 +174,13 @@ _trace_syserr (int rc, int lvl, const char *func, int line)
}
#define TRACE_SUC(...) do { \
- _gpgme_debug (_gpgme_trace_level, 3, _gpgme_trace_func, NULL, NULL, \
+ _gpgme_debug (NULL, _gpgme_trace_level, 3, _gpgme_trace_func, NULL, NULL, \
__VA_ARGS__); \
_gpgme_debug_frame_end (); \
} while (0)
#define TRACE_LOG(...) do { \
- _gpgme_debug (_gpgme_trace_level, 2, \
+ _gpgme_debug (NULL, _gpgme_trace_level, 2, \
_gpgme_trace_func, _gpgme_trace_tagname, _gpgme_trace_tag, \
__VA_ARGS__); \
} while (0)
@@ -198,10 +195,9 @@ _trace_syserr (int rc, int lvl, const char *func, int line)
_gpgme_trace_func, buf, len); \
} while (0)
-#define TRACE_SEQ(hlp,fmt) do { \
- _gpgme_debug_begin (&(hlp), _gpgme_trace_level, \
- "%s: check: %s=%p, " fmt, _gpgme_trace_func, \
- _gpgme_trace_tagname, _gpgme_trace_tag); \
+#define TRACE_SEQ(hlp,...) do { \
+ _gpgme_debug (&(hlp), _gpgme_trace_level, 2, _gpgme_trace_func, \
+ _gpgme_trace_tagname, _gpgme_trace_tag, __VA_ARGS__); \
} while (0)
#define TRACE_ADD0(hlp,fmt) \
diff --git a/src/dirinfo.c b/src/dirinfo.c
index d481199..c4f0e4a 100644
--- a/src/dirinfo.c
+++ b/src/dirinfo.c
@@ -260,15 +260,15 @@ get_gpgconf_item (int what)
char *pgmname;
pgmname = dirinfo.disable_gpgconf? NULL : _gpgme_get_gpgconf_path ();
- if (pgmname && access (pgmname, F_OK))
+ if (pgmname && _gpgme_access (pgmname, F_OK))
{
- _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: gpgconf='%s' [not installed]\n", pgmname);
free (pgmname);
pgmname = NULL; /* Not available. */
}
else
- _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: gpgconf='%s'\n",
pgmname? pgmname : "[null]");
if (!pgmname)
@@ -295,35 +295,35 @@ get_gpgconf_item (int what)
allocated. */
dirinfo.valid = 1;
if (dirinfo.gpg_name)
- _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: gpg='%s'\n",
dirinfo.gpg_name);
if (dirinfo.g13_name)
- _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: g13='%s'\n",
dirinfo.g13_name);
if (dirinfo.gpgsm_name)
- _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: gpgsm='%s'\n",
dirinfo.gpgsm_name);
if (dirinfo.homedir)
- _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: homedir='%s'\n",
dirinfo.homedir);
if (dirinfo.agent_socket)
- _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL,DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: agent='%s'\n",
dirinfo.agent_socket);
if (dirinfo.agent_ssh_socket)
- _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: ssh='%s'\n",
dirinfo.agent_ssh_socket);
if (dirinfo.dirmngr_socket)
- _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: dirmngr='%s'\n",
dirinfo.dirmngr_socket);
if (dirinfo.uisrv_socket)
- _gpgme_debug (DEBUG_INIT, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_INIT, -1, NULL, NULL, NULL,
"gpgme-dinfo: uisrv='%s'\n",
dirinfo.uisrv_socket);
}
diff --git a/src/engine-assuan.c b/src/engine-assuan.c
index 79e826e..497397d 100644
--- a/src/engine-assuan.c
+++ b/src/engine-assuan.c
@@ -658,7 +658,7 @@ add_io_cb (engine_llass_t llass, iocb_data_t *iocbd, gpgme_io_cb_t handler)
gpgme_error_t err;
TRACE_BEG (DEBUG_ENGINE, "engine-assuan:add_io_cb", llass,
- "fd %d, dir %d", iocbd->fd, iocbd->dir);
+ "fd=%d, dir %d", iocbd->fd, iocbd->dir);
err = (*llass->io_cbs.add) (llass->io_cbs.add_priv,
iocbd->fd, iocbd->dir,
handler, iocbd->data, &iocbd->tag);
diff --git a/src/engine-g13.c b/src/engine-g13.c
index edb8d54..19dd8f4 100644
--- a/src/engine-g13.c
+++ b/src/engine-g13.c
@@ -639,7 +639,7 @@ add_io_cb (engine_g13_t g13, iocb_data_t *iocbd, gpgme_io_cb_t handler)
gpgme_error_t err;
TRACE_BEG (DEBUG_ENGINE, "engine-g13:add_io_cb", g13,
- "fd %d, dir %d", iocbd->fd, iocbd->dir);
+ "fd=%d, dir %d", iocbd->fd, iocbd->dir);
err = (*g13->io_cbs.add) (g13->io_cbs.add_priv,
iocbd->fd, iocbd->dir,
handler, iocbd->data, &iocbd->tag);
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 31d219a..dc2d945 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -2075,6 +2075,8 @@ append_args_from_recipients_string (engine_gpg_t gpg,
file = 0;
flags = orig_flags;
}
+ else if (!ignore && n > 2 && !memcmp (string, "--", 2))
+ err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
else if (n) /* Not empty - use it. */
{
err = add_arg (gpg, file? (hidden? "-F":"-f") : (hidden? "-R":"-r"));
diff --git a/src/engine-gpgsm.c b/src/engine-gpgsm.c
index 396f19c..ae5d8ef 100644
--- a/src/engine-gpgsm.c
+++ b/src/engine-gpgsm.c
@@ -549,8 +549,6 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
|| _gpgme_io_set_close_notify (gpgsm->output_cb.fd,
close_notify_handler, gpgsm)
|| _gpgme_io_set_close_notify (gpgsm->message_cb.fd,
- close_notify_handler, gpgsm)
- || _gpgme_io_set_close_notify (gpgsm->diag_cb.fd,
close_notify_handler, gpgsm)))
{
err = gpg_error (GPG_ERR_GENERAL);
@@ -1129,7 +1127,7 @@ add_io_cb (engine_gpgsm_t gpgsm, iocb_data_t *iocbd, gpgme_io_cb_t handler)
gpgme_error_t err;
TRACE_BEG (DEBUG_ENGINE, "engine-gpgsm:add_io_cb", gpgsm,
- "fd %d, dir %d", iocbd->fd, iocbd->dir);
+ "fd=%d, dir %d", iocbd->fd, iocbd->dir);
err = (*gpgsm->io_cbs.add) (gpgsm->io_cbs.add_priv,
iocbd->fd, iocbd->dir,
handler, iocbd->data, &iocbd->tag);
@@ -1409,11 +1407,12 @@ set_recipients_from_string (engine_gpgsm_t gpgsm, const char *string)
{
gpg_error_t err = 0;
char *line = NULL;
- int no_pubkey = 0;
+ int ignore = 0;
+ int any = 0;
const char *s;
int n;
- for (;;)
+ do
{
while (*string == ' ' || *string == '\t')
string++;
@@ -1428,25 +1427,32 @@ set_recipients_from_string (engine_gpgsm_t gpgsm, const char *string)
while (n && (string[n-1] == ' ' || string[n-1] == '\t'))
n--;
- gpgrt_free (line);
- if (gpgrt_asprintf (&line, "RECIPIENT %.*s", n, string) < 0)
+ if (!ignore && n == 2 && !memcmp (string, "--", 2))
+ ignore = 1;
+ else if (!ignore && n > 2 && !memcmp (string, "--", 2))
+ err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
+ else if (n) /* Not empty - use it. */
{
- err = gpg_error_from_syserror ();
- break;
+ gpgrt_free (line);
+ if (gpgrt_asprintf (&line, "RECIPIENT %.*s", n, string) < 0)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ err = gpgsm_assuan_simple_command (gpgsm, line, gpgsm->status.fnc,
+ gpgsm->status.fnc_value);
+ if (!err)
+ any = 1;
+ }
}
- string += n + !!s;
-
- err = gpgsm_assuan_simple_command (gpgsm, line, gpgsm->status.fnc,
- gpgsm->status.fnc_value);
- /* Fixme: Improve error reporting. */
- if (gpg_err_code (err) == GPG_ERR_NO_PUBKEY)
- no_pubkey++;
- else if (err)
- break;
+ string += n + !!s;
}
+ while (!err);
+
+ if (!err && !any)
+ err = gpg_error (GPG_ERR_MISSING_KEY);
gpgrt_free (line);
- return err? err : no_pubkey? gpg_error (GPG_ERR_NO_PUBKEY) : 0;
+ return err;
}
@@ -1460,7 +1466,7 @@ gpgsm_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE);
- if (!recp)
+ if (!recp && !recpstring) /* Symmetric only */
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
if ((flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
diff --git a/src/engine-uiserver.c b/src/engine-uiserver.c
index 62c4e5b..cb8e155 100644
--- a/src/engine-uiserver.c
+++ b/src/engine-uiserver.c
@@ -879,7 +879,7 @@ add_io_cb (engine_uiserver_t uiserver, iocb_data_t *iocbd, gpgme_io_cb_t handler
gpgme_error_t err;
TRACE_BEG (DEBUG_ENGINE, "engine-uiserver:add_io_cb", uiserver,
- "fd %d, dir %d", iocbd->fd, iocbd->dir);
+ "fd=%d, dir %d", iocbd->fd, iocbd->dir);
err = (*uiserver->io_cbs.add) (uiserver->io_cbs.add_priv,
iocbd->fd, iocbd->dir,
handler, iocbd->data, &iocbd->tag);
diff --git a/src/engine.c b/src/engine.c
index b3df01a..05979c1 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -461,6 +461,7 @@ _gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_protocol_t proto,
{
free (new_file_name);
free (new_home_dir);
+ return gpg_error_from_syserror ();
}
}
diff --git a/src/posix-io.c b/src/posix-io.c
index be08431..e712ef2 100644
--- a/src/posix-io.c
+++ b/src/posix-io.c
@@ -62,6 +62,70 @@
#include "debug.h"
+#ifdef USE_LINUX_GETDENTS
+/* This is not declared in public headers; getdents64(2) says that we must
+ * define it ourselves. */
+struct linux_dirent64
+{
+ ino64_t d_ino;
+ off64_t d_off;
+ unsigned short d_reclen;
+ unsigned char d_type;
+ char d_name[];
+};
+
+# define DIR_BUF_SIZE 1024
+#endif /*USE_LINUX_GETDENTS*/
+
+
+/* Return true if FD is valid file descriptor. */
+#if 0
+int
+_gpgme_is_fd_valid (int fd)
+{
+ int dir_fd;
+ char dir_buf[DIR_BUF_SIZE];
+ struct linux_dirent64 *dir_entry;
+ int r, pos, x;
+ const char *s;
+ int result = 0;
+
+ dir_fd = open ("/proc/self/fd", O_RDONLY | O_DIRECTORY);
+ if (dir_fd != -1)
+ {
+ for (;;)
+ {
+ r = syscall(SYS_getdents64, dir_fd, dir_buf, DIR_BUF_SIZE);
+ if (r == -1)
+ break; /* Ooops */
+ if (r == 0)
+ break;
+
+ for (pos = 0; pos < r; pos += dir_entry->d_reclen)
+ {
+ dir_entry = (struct linux_dirent64 *) (dir_buf + pos);
+ s = dir_entry->d_name;
+ if (*s < '0' || *s > '9')
+ continue;
+ /* atoi is not guaranteed to be async-signal-safe. */
+ for (x = 0; *s >= '0' && *s <= '9'; s++)
+ x = x * 10 + (*s - '0');
+ if (*s)
+ continue; /* Does not look like a file descriptor. */
+ if (x == fd)
+ {
+ result = 1;
+ goto leave;
+ }
+ }
+ }
+ leave:
+ close (dir_fd);
+ }
+ return result;
+}
+#endif /*0*/
+
void
_gpgme_io_subsystem_init (void)
@@ -109,8 +173,8 @@ int
_gpgme_io_read (int fd, void *buffer, size_t count)
{
int nread;
- TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_read", fd,
- "buffer=%p, count=%zu", buffer, count);
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_read", NULL,
+ "fd=%d buffer=%p count=%zu", fd, buffer, count);
do
{
@@ -127,8 +191,8 @@ int
_gpgme_io_write (int fd, const void *buffer, size_t count)
{
int nwritten;
- TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_write", fd,
- "buffer=%p, count=%zu", buffer, count);
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_write", NULL,
+ "fd=%d buffer=%p count=%zu", fd, buffer, count);
TRACE_LOGBUFX (buffer, count);
do
@@ -146,7 +210,7 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
{
int saved_errno;
int err;
- TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_pipe", filedes,
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_pipe", NULL,
"inherit_idx=%i (GPGME uses it for %s)",
inherit_idx, inherit_idx ? "reading" : "writing");
@@ -166,7 +230,7 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
if (err)
return TRACE_SYSRES (err);
- TRACE_SUC ("read=0x%x, write=0x%x", filedes[0], filedes[1]);
+ TRACE_SUC ("read fd=%d write fd=%d", filedes[0], filedes[1]);
return 0;
}
@@ -179,7 +243,7 @@ _gpgme_io_close (int fd)
void *handler_value;
int idx;
- TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", fd, "");
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_close", NULL, "fd=%d", fd);
if (fd == -1)
{
@@ -221,8 +285,8 @@ _gpgme_io_set_close_notify (int fd, _gpgme_close_notify_handler_t handler,
int res = 0;
int idx;
- TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_set_close_notify", fd,
- "close_handler=%p/%p", handler, value);
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_set_close_notify", NULL,
+ "fd=%d close_handler=%p/%p", fd, handler, value);
assert (fd != -1);
@@ -272,7 +336,7 @@ _gpgme_io_set_nonblocking (int fd)
{
int flags;
int res;
- TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_set_nonblocking", fd, "");
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_set_nonblocking", NULL, "fd=%d", fd);
flags = fcntl (fd, F_GETFL, 0);
if (flags == -1)
@@ -283,22 +347,6 @@ _gpgme_io_set_nonblocking (int fd)
}
-#ifdef USE_LINUX_GETDENTS
-/* This is not declared in public headers; getdents64(2) says that we must
- * define it ourselves. */
-struct linux_dirent64
-{
- ino64_t d_ino;
- off64_t d_off;
- unsigned short d_reclen;
- unsigned char d_type;
- char d_name[];
-};
-
-# define DIR_BUF_SIZE 1024
-#endif /*USE_LINUX_GETDENTS*/
-
-
static long int
get_max_fds (void)
{
@@ -428,7 +476,7 @@ get_max_fds (void)
}
#endif
- TRACE (DEBUG_SYSIO, "gpgme:max_fds", 0, "max fds=%ld (%s)", fds, source);
+ TRACE (DEBUG_SYSIO, "gpgme:max_fds", NULL, "max fds=%ld (%s)", fds, source);
return fds;
}
@@ -474,7 +522,7 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
int status;
int signo;
- TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_spawn", path,
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_spawn", NULL,
"path=%s", path);
i = 0;
while (argv[i])
@@ -483,10 +531,12 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
i++;
}
for (i = 0; fd_list[i].fd != -1; i++)
- if (fd_list[i].dup_to == -1)
- TRACE_LOG ("fd[%i] = 0x%x", i, fd_list[i].fd);
- else
- TRACE_LOG ("fd[%i] = 0x%x -> 0x%x", i, fd_list[i].fd, fd_list[i].dup_to);
+ {
+ if (fd_list[i].dup_to == -1)
+ TRACE_LOG ("fd[%i] = 0x%x", i, fd_list[i].fd);
+ else
+ TRACE_LOG ("fd[%i] = 0x%x -> 0x%x", i,fd_list[i].fd,fd_list[i].dup_to);
+ }
pid = fork ();
if (pid == -1)
@@ -654,7 +704,7 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
/* Use a 1s timeout. */
struct timeval timeout = { 1, 0 };
void *dbg_help = NULL;
- TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_select", fds,
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_select", NULL,
"nfds=%zu, nonblock=%u", nfds, nonblock);
FD_ZERO (&readfds);
@@ -682,8 +732,8 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
FD_SET (fds[i].fd, &readfds);
if (fds[i].fd > max_fd)
max_fd = fds[i].fd;
- TRACE_ADD1 (dbg_help, "r0x%x ", fds[i].fd);
- any = 1;
+ TRACE_ADD1 (dbg_help, "r=%d ", fds[i].fd);
+ any = 1;
}
else if (fds[i].for_write)
{
@@ -697,7 +747,7 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
FD_SET (fds[i].fd, &writefds);
if (fds[i].fd > max_fd)
max_fd = fds[i].fd;
- TRACE_ADD1 (dbg_help, "w0x%x ", fds[i].fd);
+ TRACE_ADD1 (dbg_help, "w=%d ", fds[i].fd);
any = 1;
}
fds[i].signaled = 0;
@@ -721,9 +771,9 @@ _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds, int nonblock)
for (i = 0; i <= max_fd; i++)
{
if (FD_ISSET (i, &readfds))
- TRACE_ADD1 (dbg_help, "r0x%x ", i);
+ TRACE_ADD1 (dbg_help, "r=%d ", i);
if (FD_ISSET (i, &writefds))
- TRACE_ADD1 (dbg_help, "w0x%x ", i);
+ TRACE_ADD1 (dbg_help, "w=%d ", i);
}
TRACE_END (dbg_help, "]");
}
@@ -760,8 +810,8 @@ _gpgme_io_recvmsg (int fd, struct msghdr *msg, int flags)
int nread;
int saved_errno;
struct iovec *iov;
- TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_recvmsg", fd,
- "msg=%p, flags=%i", msg, flags);
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_recvmsg", NULL,
+ "fd=%d msg=%p flags=%i", fd, msg, flags);
nread = 0;
iov = msg->msg_iov;
@@ -802,8 +852,8 @@ _gpgme_io_sendmsg (int fd, const struct msghdr *msg, int flags)
{
int nwritten;
struct iovec *iov;
- TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_sendmsg", fd,
- "msg=%p, flags=%i", msg, flags);
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_sendmsg", NULL,
+ "fd=%d msg=%p flags=%i", fd, msg, flags);
nwritten = 0;
iov = msg->msg_iov;
@@ -841,7 +891,7 @@ _gpgme_io_dup (int fd)
new_fd = dup (fd);
while (new_fd == -1 && errno == EINTR);
- TRACE (DEBUG_SYSIO, "_gpgme_io_dup", fd, "new fd==%i", new_fd);
+ TRACE (DEBUG_SYSIO, "_gpgme_io_dup", NULL, "fd=%d -> fd=%d", fd, new_fd);
return new_fd;
}
@@ -852,8 +902,8 @@ _gpgme_io_socket (int domain, int type, int proto)
{
int res;
- TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_socket", domain,
- "type=%i, proto=%i", type, proto);
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_socket", NULL,
+ "domain=%d type=%i proto=%i", domain, type, proto);
res = socket (domain, type, proto);
@@ -866,8 +916,8 @@ _gpgme_io_connect (int fd, struct sockaddr *addr, int addrlen)
{
int res;
- TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_connect", fd,
- "addr=%p, addrlen=%i", addr, addrlen);
+ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_connect", NULL,
+ "fd=%d addr=%p addrlen=%i", fd, addr, addrlen);
do
res = ath_connect (fd, addr, addrlen);
diff --git a/src/posix-util.c b/src/posix-util.c
index 881856c..5c4f339 100644
--- a/src/posix-util.c
+++ b/src/posix-util.c
@@ -114,7 +114,7 @@ walk_path (const char *pgm)
path = s + 1;
}
- _gpgme_debug (DEBUG_ENGINE, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_ENGINE, -1, NULL, NULL, NULL,
"gpgme-walk_path: '%s' not found in '%s'",
pgm, orig_path);
@@ -157,3 +157,10 @@ _gpgme_allow_set_foreground_window (pid_t pid)
(void)pid;
/* Not needed. */
}
+
+/* See w32-util.c */
+int
+_gpgme_access (const char *path, int mode)
+{
+ return access (path, mode);
+}
diff --git a/src/sys-util.h b/src/sys-util.h
index 6cb2224..e537613 100644
--- a/src/sys-util.h
+++ b/src/sys-util.h
@@ -28,9 +28,22 @@ int _gpgme_set_override_inst_dir (const char *dir);
char *_gpgme_get_gpg_path (void);
char *_gpgme_get_gpgconf_path (void);
+int _gpgme_access (const char *path_utf8, int mode);
+
#ifdef HAVE_W32_SYSTEM
const char *_gpgme_get_inst_dir (void);
void _gpgme_w32_cancel_synchronous_io (HANDLE thread);
+/* See CreateProcessA returns true on success */
+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 lpStartupInfo,
+ LPPROCESS_INFORMATION lpProcessInformation);
#endif
#endif /* SYS_UTIL_H */
diff --git a/src/version.c b/src/version.c
index 3bf12e9..5beb63a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -202,7 +202,7 @@ gpgme_check_version (const char *req_version)
before using the trace facility. If we won't the trace would
automagically initialize the debug system with out the locks
being initialized and missing the assuan log level setting. */
- TRACE (DEBUG_INIT, "gpgme_check_version", 0,
+ TRACE (DEBUG_INIT, "gpgme_check_version", NULL,
"req_version=%s, VERSION=%s",
req_version? req_version:"(null)", VERSION);
@@ -229,13 +229,13 @@ gpgme_check_version_internal (const char *req_version,
return result;
/* Catch-22, see above. */
- TRACE (DEBUG_INIT, "gpgme_check_version_internal", 0,
+ TRACE (DEBUG_INIT, "gpgme_check_version_internal", NULL,
"req_version=%s, offset_sig_validity=%zu",
req_version ? req_version : "(null)", offset_sig_validity);
if (offset_sig_validity != offsetof (struct _gpgme_signature, validity))
{
- TRACE (DEBUG_INIT, "gpgme_check_version_internal", 0,
+ TRACE (DEBUG_INIT, "gpgme_check_version_internal", NULL,
"offset_sig_validity mismatch: expected %i",
(int)offsetof (struct _gpgme_signature, validity));
_gpgme_selftest = GPG_ERR_SELFTEST_FAILED;
diff --git a/src/w32-glib-io.c b/src/w32-glib-io.c
index 8c8722c..09ffffa 100644
--- a/src/w32-glib-io.c
+++ b/src/w32-glib-io.c
@@ -324,7 +324,7 @@ _gpgme_io_write (int fd, const void *buffer, size_t count)
chan = find_channel (fd);
if (!chan)
{
- TRACE_LOG ("fd %d: no channel registered");
+ TRACE_LOG ("fd=%d: no channel registered");
errno = EINVAL;
return -1;
}
@@ -421,12 +421,13 @@ _gpgme_io_pipe (int filedes[2], int inherit_idx)
return TRACE_SYSRES (-1);
}
- return TRACE_SUC ("read=0x%x/%p, write=0x%x/%p, channel=%p",
- filedes[0],
- (HANDLE) _get_osfhandle (giochannel_table[filedes[0]].fd),
- filedes[1],
- (HANDLE) _get_osfhandle (giochannel_table[filedes[1]].fd),
- giochannel_table[1 - inherit_idx].chan);
+ TRACE_SUC ("read=0x%x/%p, write=0x%x/%p, channel=%p",
+ filedes[0],
+ (HANDLE) _get_osfhandle (giochannel_table[filedes[0]].fd),
+ filedes[1],
+ (HANDLE) _get_osfhandle (giochannel_table[filedes[1]].fd),
+ giochannel_table[1 - inherit_idx].chan);
+ return 0;
}
@@ -1066,7 +1067,7 @@ _gpgme_io_connect (int fd, struct sockaddr *addr, int addrlen)
return TRACE_SYSRES (-1);
}
- TRACE_LOG ("connect sockfd=0x%x", sockfd);
+ TRACE_LOG ("connect socket fd=%d", sockfd);
res = connect (sockfd, addr, addrlen);
/* FIXME: Error ignored here. */
@@ -1081,5 +1082,7 @@ _gpgme_io_connect (int fd, struct sockaddr *addr, int addrlen)
return TRACE_SYSRES (-1);
}
- return TRACE_SUC ("");
+ TRACE_SUC ("");
+
+ return 0;
}
diff --git a/src/w32-io.c b/src/w32-io.c
index 919ca6f..c5c21f5 100644
--- a/src/w32-io.c
+++ b/src/w32-io.c
@@ -1389,6 +1389,7 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
int tmp_fd;
char *tmp_name;
const char *spawnhelper;
+ static int spawn_warning_shown = 0;
TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_spawn", path,
"path=%s", path);
@@ -1456,36 +1457,40 @@ _gpgme_io_spawn (const char *path, char *const argv[], unsigned int flags,
up their installation this should also be properly communicated
as otherwise calls to gnupg will result in unsupported protocol
errors that do not explain a lot. */
- char *msg;
- gpgrt_asprintf (&msg, "gpgme-w32spawn.exe was not found in the "
- "detected installation directory of GpgME"
- "\n\t\"%s\"\n\n"
- "Crypto operations will not work.\n\n"
- "If you see this it indicates a problem "
- "with your installation.\n"
- "Please report the problem to your "
- "distributor of GpgME.\n\n"
- "Developer's Note: The install dir can be "
- "manually set with: gpgme_set_global_flag",
- _gpgme_get_inst_dir ());
- MessageBoxA (NULL, msg, "GpgME not installed correctly", MB_OK);
- gpgrt_free (msg);
+ if (!spawn_warning_shown)
+ {
+ char *msg;
+ gpgrt_asprintf (&msg, "gpgme-w32spawn.exe was not found in the "
+ "detected installation directory of GpgME"
+ "\n\t\"%s\"\n\n"
+ "Crypto operations will not work.\n\n"
+ "If you see this it indicates a problem "
+ "with your installation.\n"
+ "Please report the problem to your "
+ "distributor of GpgME.\n\n"
+ "Developer's Note: The install dir can be "
+ "manually set with: gpgme_set_global_flag",
+ _gpgme_get_inst_dir ());
+ MessageBoxA (NULL, msg, "GpgME not installed correctly", MB_OK);
+ gpgrt_free (msg);
+ spawn_warning_shown = 1;
+ }
gpg_err_set_errno (EIO);
close (tmp_fd);
DeleteFileA (tmp_name);
free (tmp_name);
return TRACE_SYSRES (-1);
}
- if (!CreateProcessA (spawnhelper,
- arg_string,
- &sec_attr, /* process security attributes */
- &sec_attr, /* thread security attributes */
- FALSE, /* inherit handles */
- cr_flags, /* creation flags */
- NULL, /* environment */
- NULL, /* use current drive/directory */
- &si, /* startup information */
- &pi)) /* returns process information */
+ if (!_gpgme_create_process_utf8 (spawnhelper,
+ arg_string,
+ &sec_attr, /* process security attributes */
+ &sec_attr, /* thread security attributes */
+ FALSE, /* inherit handles */
+ cr_flags, /* creation flags */
+ NULL, /* environment */
+ NULL, /* use current drive/directory */
+ &si, /* startup information */
+ &pi)) /* returns process information */
{
int lasterr = (int)GetLastError ();
TRACE_LOG ("CreateProcess failed: ec=%d", lasterr);
diff --git a/src/w32-util.c b/src/w32-util.c
index 9802d9c..8207676 100644
--- a/src/w32-util.c
+++ b/src/w32-util.c
@@ -168,6 +168,48 @@ wchar_to_utf8 (const wchar_t *string)
}
+/* Return a malloced wide char string from an UTF-8 encoded input
+ string STRING. Caller must free this value. On failure returns
+ NULL; caller may use GetLastError to get the actual error number.
+ Calling this function with STRING set to NULL is not defined. */
+static wchar_t *
+utf8_to_wchar (const char *string)
+{
+ int n;
+ wchar_t *result;
+
+
+ n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
+ if (n < 0)
+ return NULL;
+
+ result = (wchar_t *) malloc ((n+1) * sizeof *result);
+ if (!result)
+ return NULL;
+
+ n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
+ if (n < 0)
+ {
+ free (result);
+ return NULL;
+ }
+ return result;
+}
+
+
+/* Same as utf8_to_wchar but calling it with NULL returns
+ NULL. So a return value of NULL only indicates failure
+ if STRING is not set to NULL. */
+static wchar_t *
+utf8_to_wchar0 (const char *string)
+{
+ if (!string)
+ return NULL;
+
+ return utf8_to_wchar (string);
+}
+
+
/* Replace all forward slashes by backslashes. */
static void
replace_slashes (char *string)
@@ -220,19 +262,19 @@ _gpgme_allow_set_foreground_window (pid_t pid)
if (!pid || pid == (pid_t)(-1))
{
- TRACE (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", 0,
+ TRACE (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", NULL,
"no action for pid %d", (int)pid);
}
else if (func)
{
int rc = func (pid);
- TRACE (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", 0,
+ TRACE (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", NULL,
"called for pid %d; result=%d", (int)pid, rc);
}
else
{
- TRACE (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", 0,
+ TRACE (DEBUG_ENGINE, "gpgme:AllowSetForegroundWindow", NULL,
"function not available");
}
#endif /* HAVE_ALLOW_SET_FOREGROUND_WINDOW */
@@ -268,13 +310,13 @@ _gpgme_w32_cancel_synchronous_io (HANDLE thread)
{
if (!func (thread) && GetLastError() != ERROR_NOT_FOUND)
{
- TRACE (DEBUG_ENGINE, "gpgme:CancelSynchronousIo", 0,
+ TRACE (DEBUG_ENGINE, "gpgme:CancelSynchronousIo", NULL,
"called for thread %p: ec=%d", thread, GetLastError ());
}
}
else
{
- TRACE (DEBUG_ENGINE, "gpgme:CancelSynchronousIo", 0,
+ TRACE (DEBUG_ENGINE, "gpgme:CancelSynchronousIo", NULL,
"function not available");
}
}
@@ -395,7 +437,7 @@ find_program_in_dir (const char *dir, const char *name)
if (!result)
return NULL;
- if (access (result, F_OK))
+ if (_gpgme_access (result, F_OK))
{
free (result);
return NULL;
@@ -408,7 +450,7 @@ find_program_in_dir (const char *dir, const char *name)
static char *
find_program_at_standard_place (const char *name)
{
- char path[MAX_PATH];
+ wchar_t path[MAX_PATH];
char *result = NULL;
/* See https://wiki.tcl-lang.org/page/Getting+Windows+%22special+folders%22+with+Ffidl for details on compatibility.
@@ -416,20 +458,24 @@ find_program_at_standard_place (const char *name)
We First try the generic place and then fallback to the x86
(i.e. 32 bit) place. This will prefer a 64 bit of the program
over a 32 bit version on 64 bit Windows if installed. */
- if (SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILES, 0))
+ if (SHGetSpecialFolderPathW (NULL, path, CSIDL_PROGRAM_FILES, 0))
{
- result = _gpgme_strconcat (path, "\\", name, NULL);
- if (result && access (result, F_OK))
+ char *utf8_path = wchar_to_utf8 (path);
+ result = _gpgme_strconcat (utf8_path, "\\", name, NULL);
+ free (utf8_path);
+ if (result && _gpgme_access (result, F_OK))
{
free (result);
result = NULL;
}
}
if (!result
- && SHGetSpecialFolderPathA (NULL, path, CSIDL_PROGRAM_FILESX86, 0))
+ && SHGetSpecialFolderPathW (NULL, path, CSIDL_PROGRAM_FILESX86, 0))
{
- result = _gpgme_strconcat (path, "\\", name, NULL);
- if (result && access (result, F_OK))
+ char *utf8_path = wchar_to_utf8 (path);
+ result = _gpgme_strconcat (utf8_path, "\\", name, NULL);
+ free (utf8_path);
+ if (result && _gpgme_access (result, F_OK))
{
free (result);
result = NULL;
@@ -532,7 +578,7 @@ _gpgme_get_gpg_path (void)
/* 4. Print a debug message if not found. */
if (!gpg)
- _gpgme_debug (DEBUG_ENGINE, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_ENGINE, -1, NULL, NULL, NULL,
"_gpgme_get_gpg_path: '%s' not found", name);
return gpg;
@@ -608,7 +654,7 @@ _gpgme_get_gpgconf_path (void)
/* 5. Print a debug message if not found. */
if (!gpgconf)
- _gpgme_debug (DEBUG_ENGINE, -1, NULL, NULL, NULL,
+ _gpgme_debug (NULL, DEBUG_ENGINE, -1, NULL, NULL, NULL,
"_gpgme_get_gpgconf_path: '%s' not found",name);
return gpgconf;
@@ -781,6 +827,73 @@ _gpgme_mkstemp (int *fd, char **name)
}
+/* Like access but using windows _waccess */
+int
+_gpgme_access (const char *path, int mode)
+{
+ wchar_t *u16 = utf8_to_wchar0 (path);
+ int r = _waccess (u16, mode);
+
+ free(u16);
+ return r;
+}
+
+
+/* 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)
+{
+ BOOL ret;
+ wchar_t *application_name = utf8_to_wchar0 (application_name_utf8);
+ wchar_t *command_line = utf8_to_wchar0 (command_line_utf8);
+ wchar_t *working_directory = utf8_to_wchar0 (working_directory_utf8);
+
+ STARTUPINFOW siw;
+ memset (&siw, 0, sizeof siw);
+ if (si)
+ {
+ siw.cb = sizeof (siw);
+ siw.dwFlags = si->dwFlags;
+ siw.wShowWindow = si->wShowWindow;
+ siw.hStdInput = si->hStdInput;
+ siw.hStdOutput = si->hStdOutput;
+ siw.hStdError = si->hStdError;
+ siw.dwX = si->dwX;
+ siw.dwY = si->dwY;
+ siw.dwXSize = si->dwXSize;
+ siw.dwYSize = si->dwYSize;
+ siw.dwXCountChars = si->dwXCountChars;
+ siw.dwYCountChars = si->dwYCountChars;
+ siw.dwFillAttribute = si->dwFillAttribute;
+ siw.lpDesktop = utf8_to_wchar0 (si->lpDesktop);
+ siw.lpTitle = utf8_to_wchar0 (si->lpTitle);
+ }
+
+ ret = CreateProcessW (application_name,
+ command_line,
+ lpProcessAttributes,
+ lpThreadAttributes,
+ bInheritHandles,
+ dwCreationFlags,
+ lpEnvironment,
+ working_directory,
+ si ? &siw : NULL,
+ lpProcessInformation);
+ free (siw.lpTitle);
+ free (siw.lpDesktop);
+ free (application_name);
+ free (command_line);
+ free (working_directory);
+ return ret;
+}
/* Entry point called by the DLL loader. */
#ifdef DLL_EXPORT
diff --git a/src/wait.c b/src/wait.c
index 1da9e93..c76f98f 100644
--- a/src/wait.c
+++ b/src/wait.c
@@ -137,7 +137,7 @@ _gpgme_add_io_cb (void *data, int fd, int dir, gpgme_io_cb_t fnc,
}
TRACE (DEBUG_CTX, "_gpgme_add_io_cb", ctx,
- "fd %d, dir=%d -> tag=%p", fd, dir, tag);
+ "fd=%d, dir=%d -> tag=%p", fd, dir, tag);
*r_tag = tag;
return 0;
@@ -179,7 +179,8 @@ _gpgme_remove_io_cb (void *data)
own event loops could compensate for that, but the external event
loops cannot. FIXME: We may still want to optimize this a bit when
we are called from our own event loops. So if CHECKED is 1, the
- check is skipped. */
+ check is skipped. FIXME: Give an example on how the status of other
+ fds can be influenced. */
gpgme_error_t
_gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked,
gpgme_error_t *op_err)
@@ -203,11 +204,13 @@ _gpgme_run_io_cb (struct io_select_fd_s *an_fds, int checked,
nr = _gpgme_io_select (&fds, 1, 1);
assert (nr <= 1);
if (nr < 0)
- return errno;
+ return gpg_error_from_syserror ();
else if (nr == 0)
- /* The status changed in the meantime, there is nothing left
- to do. */
- return 0;
+ {
+ /* The status changed in the meantime, there is nothing left
+ * to do. */
+ return 0;
+ }
}
TRACE (DEBUG_CTX, "_gpgme_run_io_cb", item, "handler (%p, %d)",