diff options
author | JinWang An <jinwang.an@samsung.com> | 2021-12-01 16:54:38 +0900 |
---|---|---|
committer | JinWang An <jinwang.an@samsung.com> | 2021-12-01 16:54:38 +0900 |
commit | 5793c283c7ddc13e62a1eef6ecd38d7e996d6e3f (patch) | |
tree | 984b58b62afb259d96ca5e0af2c737300ca62722 /src | |
parent | a4cc2ca8c024d3187c4ff465a176c7585b533411 (diff) | |
download | gpgme-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.c | 4 | ||||
-rw-r--r-- | src/cJSON.c | 48 | ||||
-rw-r--r-- | src/data-compat.c | 2 | ||||
-rw-r--r-- | src/data-fd.c | 2 | ||||
-rw-r--r-- | src/data-mem.c | 2 | ||||
-rw-r--r-- | src/data.c | 4 | ||||
-rw-r--r-- | src/debug.c | 245 | ||||
-rw-r--r-- | src/debug.h | 40 | ||||
-rw-r--r-- | src/dirinfo.c | 22 | ||||
-rw-r--r-- | src/engine-assuan.c | 2 | ||||
-rw-r--r-- | src/engine-g13.c | 2 | ||||
-rw-r--r-- | src/engine-gpg.c | 2 | ||||
-rw-r--r-- | src/engine-gpgsm.c | 46 | ||||
-rw-r--r-- | src/engine-uiserver.c | 2 | ||||
-rw-r--r-- | src/engine.c | 1 | ||||
-rw-r--r-- | src/posix-io.c | 144 | ||||
-rw-r--r-- | src/posix-util.c | 9 | ||||
-rw-r--r-- | src/sys-util.h | 13 | ||||
-rw-r--r-- | src/version.c | 6 | ||||
-rw-r--r-- | src/w32-glib-io.c | 21 | ||||
-rw-r--r-- | src/w32-io.c | 53 | ||||
-rw-r--r-- | src/w32-util.c | 143 | ||||
-rw-r--r-- | src/wait.c | 15 |
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); @@ -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 @@ -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)", |