Update to rev 231 of libassuan.

This commit is contained in:
Marcus Brinkmann 2006-11-29 16:25:46 +00:00
parent a9e91c8b4a
commit aa1c0a545d
13 changed files with 253 additions and 161 deletions

View File

@ -1,3 +1,70 @@
2006-11-22 Werner Koch <wk@g10code.com>
* assuan-handler.c (fun1_cookie_write, fun2_cookie_write): New.
(assuan_get_data_fp) [HAVE_FUNOPEN]: Use it.
2006-11-21 Werner Koch <wk@g10code.com>
* Makefile.am (libassuan_pth_a_CFLAGS): New.
* assuan-pipe-server.c (_assuan_release_context): Free CMDTBL.
2006-11-14 Werner Koch <wk@g10code.com>
* libassuan.m4 (AM_CHECK_LIBASSUAN): New.
* assuan-handler.c (assuan_register_post_cmd_notify)
(assuan_register_post_cmd_notify): New.
* assuan-util.c (assuan_set_io_monitor): New.
* assuan-buffer.c (_assuan_read_line): Use it.
(_assuan_write_line): Ditto.
(_assuan_cookie_write_data): Ditto.
(_assuan_cookie_write_flush): Ditto.
2006-10-18 Werner Koch <wk@g10code.com>
* libassuan.m4: Pass "pthread" to the common macro. Reported by
Rex Dieter.
2006-10-16 Werner Koch <wk@g10code.com>
* mkerrors: Map ASSUAN_Not_Confirmed.
2006-10-10 Werner Koch <wk@g10code.com>
* libassuan.m4 (AM_PATH_LIBASSUAN_PTH)
(AM_PATH_LIBASSUAN_PTHREAD): Fixed.
* assuan-buffer.c (assuan_sendfd): Implement a runtime detection
of implemented descripotr passing.
* assuan-uds.c: Take care of USE_DESCRIPTOR_PASSING.
* assuan-defs.h: Add missing semicolon.
2006-10-09 Werner Koch <wk@g10code.com>
* assuan-handler.c (process_request): Use weak pragma for the sake
of old gcc's. Reported by Alain Guibert.
* assuan-io.c: Removed Pth support.
* assuan-io-pth.c: New. Based on assuan-io.c
2006-10-06 Werner Koch <wk@g10code.com>
* libassuan-config.in: New options --api-version and --thread.
2006-10-04 Werner Koch <wk@g10code.com>
* assuan-client.c (assuan_transact): Need to map old assuan status
codes so that for example CANCELED is correctly mapped.
2006-09-28 Marcus Brinkmann <marcus@g10code.de>
* assuan-client.c (assuan_transact): Do not convert error on
status line, it is already a gpg-error. Do convert
ASSUAN_Server_Fault.
2006-09-19 Marcus Brinkmann <marcus@g10code.de> 2006-09-19 Marcus Brinkmann <marcus@g10code.de>
* assuan.h (assuan_init_socket_server_ext) * assuan.h (assuan_init_socket_server_ext)

View File

@ -1,5 +1,5 @@
/* assuan-buffer.c - read and send data /* assuan-buffer.c - read and send data
* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. * Copyright (C) 2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
* *
* This file is part of Assuan. * This file is part of Assuan.
* *
@ -159,7 +159,9 @@ _assuan_read_line (assuan_context_t ctx)
if (endp) if (endp)
{ {
unsigned monitor_result;
int n = endp - line + 1; int n = endp - line + 1;
if (n < nread) if (n < nread)
/* LINE contains more than one line. We copy it to the attic /* LINE contains more than one line. We copy it to the attic
now as handlers are allowed to modify the passed now as handlers are allowed to modify the passed
@ -176,7 +178,16 @@ _assuan_read_line (assuan_context_t ctx)
*endp = 0; *endp = 0;
ctx->inbound.linelen = endp - line; ctx->inbound.linelen = endp - line;
if (ctx->log_fp)
monitor_result = (ctx->io_monitor
? ctx->io_monitor (ctx, 0,
ctx->inbound.line,
ctx->inbound.linelen)
: 0);
if ( (monitor_result & 2) )
ctx->inbound.linelen = 0;
if (ctx->log_fp && !(monitor_result & 1))
{ {
fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- ", fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- ",
assuan_get_assuan_log_prefix (), assuan_get_assuan_log_prefix (),
@ -245,6 +256,7 @@ _assuan_write_line (assuan_context_t ctx, const char *prefix,
{ {
assuan_error_t rc = 0; assuan_error_t rc = 0;
size_t prefixlen = prefix? strlen (prefix):0; size_t prefixlen = prefix? strlen (prefix):0;
unsigned int monitor_result;
/* Make sure that the line is short enough. */ /* Make sure that the line is short enough. */
if (len + prefixlen + 2 > ASSUAN_LINELENGTH) if (len + prefixlen + 2 > ASSUAN_LINELENGTH)
@ -260,8 +272,12 @@ _assuan_write_line (assuan_context_t ctx, const char *prefix,
len = ASSUAN_LINELENGTH - prefixlen - 2 - 1; len = ASSUAN_LINELENGTH - prefixlen - 2 - 1;
} }
monitor_result = (ctx->io_monitor
? ctx->io_monitor (ctx, 1, line, len)
: 0);
/* Fixme: we should do some kind of line buffering. */ /* Fixme: we should do some kind of line buffering. */
if (ctx->log_fp) if (ctx->log_fp && !(monitor_result & 1))
{ {
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ", fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
assuan_get_assuan_log_prefix (), assuan_get_assuan_log_prefix (),
@ -277,13 +293,13 @@ _assuan_write_line (assuan_context_t ctx, const char *prefix,
putc ('\n', ctx->log_fp); putc ('\n', ctx->log_fp);
} }
if (prefixlen) if (prefixlen && !(monitor_result & 2))
{ {
rc = writen (ctx, prefix, prefixlen); rc = writen (ctx, prefix, prefixlen);
if (rc) if (rc)
rc = _assuan_error (ASSUAN_Write_Error); rc = _assuan_error (ASSUAN_Write_Error);
} }
if (!rc) if (!rc && !(monitor_result & 2))
{ {
rc = writen (ctx, line, len); rc = writen (ctx, line, len);
if (rc) if (rc)
@ -325,7 +341,7 @@ assuan_write_line (assuan_context_t ctx, const char *line)
/* Write out the data in buffer as datalines with line wrapping and /* Write out the data in buffer as datalines with line wrapping and
percent escaping. This function is used for GNU's custom streams */ percent escaping. This function is used for GNU's custom streams. */
int int
_assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size) _assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size)
{ {
@ -342,7 +358,9 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size)
line += linelen; line += linelen;
while (size) while (size)
{ {
/* insert data line header */ unsigned int monitor_result;
/* Insert data line header. */
if (!linelen) if (!linelen)
{ {
*line++ = 'D'; *line++ = 'D';
@ -350,7 +368,7 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size)
linelen += 2; linelen += 2;
} }
/* copy data, keep some space for the CRLF and to escape one character */ /* Copy data, keep space for the CRLF and to escape one character. */
while (size && linelen < LINELENGTH-2-2) while (size && linelen < LINELENGTH-2-2)
{ {
if (*buffer == '%' || *buffer == '\r' || *buffer == '\n') if (*buffer == '%' || *buffer == '\r' || *buffer == '\n')
@ -368,9 +386,15 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size)
size--; size--;
} }
monitor_result = (ctx->io_monitor
? ctx->io_monitor (ctx, 1,
ctx->outbound.data.line, linelen)
: 0);
if (linelen >= LINELENGTH-2-2) if (linelen >= LINELENGTH-2-2)
{ {
if (ctx->log_fp) if (ctx->log_fp && !(monitor_result & 1))
{ {
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ", fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
assuan_get_assuan_log_prefix (), assuan_get_assuan_log_prefix (),
@ -386,7 +410,8 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size)
} }
*line++ = '\n'; *line++ = '\n';
linelen++; linelen++;
if (writen (ctx, ctx->outbound.data.line, linelen)) if ( !(monitor_result & 2)
&& writen (ctx, ctx->outbound.data.line, linelen))
{ {
ctx->outbound.data.error = _assuan_error (ASSUAN_Write_Error); ctx->outbound.data.error = _assuan_error (ASSUAN_Write_Error);
return 0; return 0;
@ -409,6 +434,7 @@ _assuan_cookie_write_flush (void *cookie)
assuan_context_t ctx = cookie; assuan_context_t ctx = cookie;
char *line; char *line;
size_t linelen; size_t linelen;
unsigned int monitor_result;
if (ctx->outbound.data.error) if (ctx->outbound.data.error)
return 0; return 0;
@ -416,9 +442,15 @@ _assuan_cookie_write_flush (void *cookie)
line = ctx->outbound.data.line; line = ctx->outbound.data.line;
linelen = ctx->outbound.data.linelen; linelen = ctx->outbound.data.linelen;
line += linelen; line += linelen;
monitor_result = (ctx->io_monitor
? ctx->io_monitor (ctx, 1,
ctx->outbound.data.line, linelen)
: 0);
if (linelen) if (linelen)
{ {
if (ctx->log_fp) if (ctx->log_fp && !(monitor_result & 1))
{ {
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ", fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
assuan_get_assuan_log_prefix (), assuan_get_assuan_log_prefix (),
@ -432,7 +464,8 @@ _assuan_cookie_write_flush (void *cookie)
} }
*line++ = '\n'; *line++ = '\n';
linelen++; linelen++;
if (writen (ctx, ctx->outbound.data.line, linelen)) if ( !(monitor_result & 2)
&& writen (ctx, ctx->outbound.data.line, linelen))
{ {
ctx->outbound.data.error = _assuan_error (ASSUAN_Write_Error); ctx->outbound.data.error = _assuan_error (ASSUAN_Write_Error);
return 0; return 0;
@ -490,6 +523,15 @@ assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length)
assuan_error_t assuan_error_t
assuan_sendfd (assuan_context_t ctx, int fd) assuan_sendfd (assuan_context_t ctx, int fd)
{ {
/* It is explicitly allowed to use (NULL, -1) as a runtime test to
check whether descriptor passing is available. */
if (!ctx && fd == -1)
#ifdef USE_DESCRIPTOR_PASSING
return 0;
#else
return _assuan_error (ASSUAN_Not_Implemented);
#endif
if (! ctx->io->sendfd) if (! ctx->io->sendfd)
return set_error (ctx, Not_Implemented, return set_error (ctx, Not_Implemented,
"server does not support sending and receiving " "server does not support sending and receiving "

View File

@ -161,9 +161,11 @@ assuan_transact (assuan_context_t ctx,
if (!okay) if (!okay)
{ {
rc = _assuan_error (atoi (line)); rc = atoi (line);
if (rc < 100) if (rc > 0 && rc < 100)
rc = ASSUAN_Server_Fault; rc = _assuan_error (ASSUAN_Server_Fault);
else if (rc > 0 && rc <= 128)
rc = _assuan_error (rc);
} }
else if (okay == 2) else if (okay == 2)
{ {

View File

@ -179,6 +179,20 @@ struct assuan_context_s
void (*input_notify_fnc)(assuan_context_t, const char *); void (*input_notify_fnc)(assuan_context_t, const char *);
void (*output_notify_fnc)(assuan_context_t, const char *); void (*output_notify_fnc)(assuan_context_t, const char *);
/* This function is called right after a command has been processed.
It may be used to command related cleanup. */
void (*post_cmd_notify_fnc)(assuan_context_t, int);
/* If set, this is called right before logging an I/O line. With
DIRECTION set to 1 it is called for an output oeration; 0 means
an input operation. If bit 0 is set in the return value, the
logging of the will be suppressed. With bit 1 set, the entire
line will be ignored. */
unsigned int (*io_monitor)(assuan_context_t ctx,
int direction,
const char *line,
size_t linelen);
int input_fd; /* set by INPUT command */ int input_fd; /* set by INPUT command */
int output_fd; /* set by OUTPUT command */ int output_fd; /* set by OUTPUT command */
@ -299,7 +313,7 @@ char *stpcpy (char *dest, const char *src);
int setenv (const char *name, const char *value, int replace); int setenv (const char *name, const char *value, int replace);
#endif #endif
#ifndef HAVE_PUTC_UNLOCKED #ifndef HAVE_PUTC_UNLOCKED
int putc_unlocked (int c, FILE *stream) int putc_unlocked (int c, FILE *stream);
#endif #endif
#define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIM(v) (sizeof(v)/sizeof((v)[0]))

View File

@ -291,6 +291,16 @@ assuan_register_command (assuan_context_t ctx,
return 0; return 0;
} }
int
assuan_register_post_cmd_notify (assuan_context_t ctx,
void (*fnc)(assuan_context_t, int))
{
if (!ctx)
return _assuan_error (ASSUAN_Invalid_Value);
ctx->post_cmd_notify_fnc = fnc;
return 0;
}
int int
assuan_register_bye_notify (assuan_context_t ctx, assuan_register_bye_notify (assuan_context_t ctx,
void (*fnc)(assuan_context_t)) void (*fnc)(assuan_context_t))
@ -506,14 +516,20 @@ process_request (assuan_context_t ctx)
problem if they are not available. We need to make sure problem if they are not available. We need to make sure
that we are using ELF because only this guarantees that that we are using ELF because only this guarantees that
weak symbol support is available in case GNU ld is not weak symbol support is available in case GNU ld is not
used. */ used. It seems that old gcc versions don't implement the
weak attribute properly but it works with the weak
pragma. */
unsigned int source, code; unsigned int source, code;
int gpg_strerror_r (unsigned int err, char *buf, size_t buflen) int gpg_strerror_r (unsigned int err, char *buf, size_t buflen)
__attribute__ ((weak)); __attribute__ ((weak));
const char *gpg_strsource (unsigned int err) const char *gpg_strsource (unsigned int err)
__attribute__ ((weak)); __attribute__ ((weak));
#if !defined(HAVE_W32_SYSTEM) && __GNUC__ < 3
#pragma weak gpg_strerror_r
#pragma weak gpg_strsource
#endif
source = ((rc >> 24) & 0xff); source = ((rc >> 24) & 0xff);
code = (rc & 0x00ffffff); code = (rc & 0x00ffffff);
@ -537,6 +553,9 @@ process_request (assuan_context_t ctx)
rc = assuan_write_line (ctx, errline); rc = assuan_write_line (ctx, errline);
} }
if (ctx->post_cmd_notify_fnc)
ctx->post_cmd_notify_fnc (ctx, rc);
ctx->confidential = 0; ctx->confidential = 0;
if (ctx->okay_line) if (ctx->okay_line)
{ {
@ -633,6 +652,23 @@ assuan_get_active_fds (assuan_context_t ctx, int what,
return n; return n;
} }
/* Two simple wrappers to make the expected function types match. */
#ifdef HAVE_FUNOPEN
static int
fun1_cookie_write (void *cookie, const char *buffer, int orig_size)
{
return _assuan_cookie_write_data (cookie, buffer, orig_size);
}
#endif /*HAVE_FUNOPEN*/
#ifdef HAVE_FOPENCOOKIE
static ssize_t
fun2_cookie_write (void *cookie, const char *buffer, size_t orig_size)
{
return _assuan_cookie_write_data (cookie, buffer, orig_size);
}
#endif /*HAVE_FOPENCOOKIE*/
/* Return a FP to be used for data output. The FILE pointer is valid /* Return a FP to be used for data output. The FILE pointer is valid
until the end of a handler. So a close is not needed. Assuan does until the end of a handler. So a close is not needed. Assuan does
all the buffering needed to insert the status line as well as the all the buffering needed to insert the status line as well as the
@ -648,10 +684,14 @@ assuan_get_data_fp (assuan_context_t ctx)
if (ctx->outbound.data.fp) if (ctx->outbound.data.fp)
return ctx->outbound.data.fp; return ctx->outbound.data.fp;
#ifdef HAVE_FUNOPEN
ctx->outbound.data.fp = funopen (ctx, 0, ctx->outbound.data.fp = funopen (ctx, 0, fun1_cookie_write,
_assuan_cookie_write_data,
0, _assuan_cookie_write_flush); 0, _assuan_cookie_write_flush);
#else
ctx->outbound.data.fp = funopen (ctx, 0, fun2_cookie_write,
0, _assuan_cookie_write_flush);
#endif
ctx->outbound.data.error = 0; ctx->outbound.data.error = 0;
return ctx->outbound.data.fp; return ctx->outbound.data.fp;
#else #else

View File

@ -23,12 +23,9 @@
#include <config.h> #include <config.h>
#endif #endif
#include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/wait.h>
#if HAVE_SYS_UIO_H
# include <sys/uio.h>
#endif
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#ifdef HAVE_W32_SYSTEM #ifdef HAVE_W32_SYSTEM
@ -39,65 +36,12 @@
#include "assuan-defs.h" #include "assuan-defs.h"
/* We can't include pth.h and we are not sure whether other headers
already included it. This we define macros with the same
values. */
#define MY_PTH_FDMODE_ERROR (-1)
#define MY_PTH_FDMODE_POLL 0
#define MY_PTH_FDMODE_BLOCK 1
#define MY_PTH_FDMODE_NONBLOCK 2
#ifndef _ASSUAN_NO_PTH
extern pid_t pth_waitpid (pid_t pid, int *status, int options);
extern ssize_t pth_read (int fd, void *buffer, size_t size);
extern ssize_t pth_write (int fd, const void *buffer, size_t size);
extern int pth_fdmode (int, int);
extern int pth_select(int, fd_set*, fd_set*, fd_set*, struct timeval*);
#ifndef HAVE_W32_SYSTEM
#pragma weak pth_waitpid
#pragma weak pth_read
#pragma weak pth_write
#pragma weak pth_fdmode
#pragma weak pth_select
#endif
#endif /*!_ASSUAN_NO_PTH*/
#ifndef _ASSUAN_NO_PTH
/* Wrapper around pth_fdmode. */
static int
my_pth_fdmode (int fd, int mode)
{
if (pth_fdmode)
return pth_fdmode (fd, mode);
else
return MY_PTH_FDMODE_NONBLOCK; /* This is okay, given the way we use it. */
}
#endif /*_ASSUAN_NO_PTH*/
#ifndef _ASSUAN_NO_PTH
/* Wrapper around pth_select. */
static int
my_pth_select (int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds,
struct timeval *timeout)
{
if (pth_select)
return pth_select (nfd, rfds, wfds, efds, timeout);
else
return 1; /* Fake one fd ready; this is okay, given the way we use it. */
}
#endif /*_ASSUAN_NO_PTH*/
#ifndef HAVE_W32_SYSTEM #ifndef HAVE_W32_SYSTEM
pid_t pid_t
_assuan_waitpid (pid_t pid, int *status, int options) _assuan_waitpid (pid_t pid, int *status, int options)
{ {
#ifdef _ASSUAN_NO_PTH
return waitpid (pid, status, options); return waitpid (pid, status, options);
#else
return (pth_waitpid ? pth_waitpid : waitpid) (pid, status, options);
#endif
} }
#endif #endif
@ -105,72 +49,26 @@ _assuan_waitpid (pid_t pid, int *status, int options)
ssize_t ssize_t
_assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size) _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size)
{ {
#ifdef _ASSUAN_NO_PTH
return read (ctx->inbound.fd, buffer, size); return read (ctx->inbound.fd, buffer, size);
#else
# ifndef HAVE_W32_SYSTEM
return (pth_read ? pth_read : read) (ctx->inbound.fd, buffer, size);
# else
return pth_read ? pth_read (ctx->inbound.fd, buffer, size)
: recv (ctx->inbound.fd, buffer, size, 0);
# endif
#endif
} }
ssize_t ssize_t
_assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size) _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size)
{ {
#ifdef _ASSUAN_NO_PTH
return write (ctx->outbound.fd, buffer, size); return write (ctx->outbound.fd, buffer, size);
#else
# ifndef HAVE_W32_SYSTEM
return (pth_write ? pth_write : write) (ctx->outbound.fd, buffer, size);
# else
return pth_write ? pth_write (ctx->outbound.fd, buffer, size)
: send (ctx->outbound.fd, buffer, size, 0);
# endif
#endif
} }
ssize_t ssize_t
_assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg) _assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg)
{ {
#if defined(HAVE_W32_SYSTEM) #ifdef HAVE_W32_SYSTEM
return _assuan_error (ASSUAN_Not_Implemented); return _assuan_error (ASSUAN_Not_Implemented);
#elif defined(_ASSUAN_NO_PTH) #else
int ret; int ret;
while ( (ret = sendmsg (ctx->outbound.fd, msg, 0)) == -1 && errno == EINTR) while ( (ret = sendmsg (ctx->outbound.fd, msg, 0)) == -1 && errno == EINTR)
; ;
return ret; return ret;
#else
/* Pth does not provide a sendmsg function. Thus we implement it here. */
int ret;
int fd = ctx->outbound.fd;
int fdmode;
fdmode = my_pth_fdmode (fd, MY_PTH_FDMODE_POLL);
if (fdmode == MY_PTH_FDMODE_ERROR)
{
errno = EBADF;
return -1;
}
if (fdmode == MY_PTH_FDMODE_BLOCK)
{
fd_set fds;
FD_ZERO (&fds);
FD_SET (fd, &fds);
while ( (ret = my_pth_select (fd+1, NULL, &fds, NULL, NULL)) < 0
&& errno == EINTR)
;
if (ret < 0)
return -1;
}
while ((ret = sendmsg (fd, msg, 0)) == -1 && errno == EINTR)
;
return ret;
#endif #endif
} }
@ -178,40 +76,12 @@ _assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg)
ssize_t ssize_t
_assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg) _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg)
{ {
#if defined(HAVE_W32_SYSTEM) #ifdef HAVE_W32_SYSTEM
return _assuan_error (ASSUAN_Not_Implemented); return _assuan_error (ASSUAN_Not_Implemented);
#elif defined(_ASSUAN_NO_PTH) #else
int ret; int ret;
while ( (ret = recvmsg (ctx->inbound.fd, msg, 0)) == -1 && errno == EINTR) while ( (ret = recvmsg (ctx->inbound.fd, msg, 0)) == -1 && errno == EINTR)
; ;
return ret; return ret;
#else
/* Pth does not provide a recvmsg function. Thus we implement it here. */
int ret;
int fd = ctx->inbound.fd;
int fdmode;
fdmode = my_pth_fdmode (fd, MY_PTH_FDMODE_POLL);
if (fdmode == MY_PTH_FDMODE_ERROR)
{
errno = EBADF;
return -1;
}
if (fdmode == MY_PTH_FDMODE_BLOCK)
{
fd_set fds;
FD_ZERO (&fds);
FD_SET (fd, &fds);
while ( (ret = my_pth_select (fd+1, &fds, NULL, NULL, NULL)) < 0
&& errno == EINTR)
;
if (ret < 0)
return -1;
}
while ((ret = recvmsg (fd, msg, 0)) == -1 && errno == EINTR)
;
return ret;
#endif #endif
} }

View File

@ -168,6 +168,7 @@ _assuan_release_context (assuan_context_t ctx)
{ {
xfree (ctx->hello_line); xfree (ctx->hello_line);
xfree (ctx->okay_line); xfree (ctx->okay_line);
xfree (ctx->cmdtbl);
xfree (ctx); xfree (ctx);
} }
} }

View File

@ -44,6 +44,26 @@
#include "assuan-defs.h" #include "assuan-defs.h"
#ifdef USE_DESCRIPTOR_PASSING
/* Provide replacement for missing CMSG maccros. We assume that
size_t matches the alignment requirement. */
#define MY_ALIGN(n) ((((n))+ sizeof(size_t)-1) & (size_t)~(sizeof(size_t)-1))
#ifndef CMSG_SPACE
#define CMSG_SPACE(n) (MY_ALIGN(sizeof(struct cmsghdr)) + MY_ALIGN((n)))
#endif
#ifndef CMSG_LEN
#define CMSG_LEN(n) (MY_ALIGN(sizeof(struct cmsghdr)) + (n))
#endif
#ifndef CMSG_FIRSTHDR
#define CMSG_FIRSTHDR(mhdr) \
((size_t)(mhdr)->msg_controllen >= sizeof (struct cmsghdr) \
? (struct cmsghdr*) (mhdr)->msg_control : (struct cmsghdr*)NULL)
#endif
#ifndef CMSG_DATA
#define CMSG_DATA(cmsg) ((unsigned char*)((struct cmsghdr*)(cmsg)+1))
#endif
#endif /*USE_DESCRIPTOR_PASSING*/
/* Read from a unix domain socket using sendmsg. /* Read from a unix domain socket using sendmsg.
@ -55,7 +75,6 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
int len = ctx->uds.buffersize; int len = ctx->uds.buffersize;
#ifndef HAVE_W32_SYSTEM #ifndef HAVE_W32_SYSTEM
if (!ctx->uds.bufferallocated) if (!ctx->uds.bufferallocated)
{ {
ctx->uds.buffer = xtrymalloc (2048); ctx->uds.buffer = xtrymalloc (2048);
@ -68,11 +87,13 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
{ {
struct msghdr msg; struct msghdr msg;
struct iovec iovec; struct iovec iovec;
#ifdef USE_DESCRIPTOR_PASSING
union { union {
struct cmsghdr cm; struct cmsghdr cm;
char control[CMSG_SPACE(sizeof (int))]; char control[CMSG_SPACE(sizeof (int))];
} control_u; } control_u;
struct cmsghdr *cmptr; struct cmsghdr *cmptr;
#endif /*USE_DESCRIPTOR_PASSING*/
memset (&msg, 0, sizeof (msg)); memset (&msg, 0, sizeof (msg));
@ -82,8 +103,10 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
msg.msg_iovlen = 1; msg.msg_iovlen = 1;
iovec.iov_base = ctx->uds.buffer; iovec.iov_base = ctx->uds.buffer;
iovec.iov_len = ctx->uds.bufferallocated; iovec.iov_len = ctx->uds.bufferallocated;
#ifdef USE_DESCRIPTOR_PASSING
msg.msg_control = control_u.control; msg.msg_control = control_u.control;
msg.msg_controllen = sizeof (control_u.control); msg.msg_controllen = sizeof (control_u.control);
#endif
len = _assuan_simple_recvmsg (ctx, &msg); len = _assuan_simple_recvmsg (ctx, &msg);
if (len < 0) if (len < 0)
@ -92,6 +115,7 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
ctx->uds.buffersize = len; ctx->uds.buffersize = len;
ctx->uds.bufferoffset = 0; ctx->uds.bufferoffset = 0;
#ifdef USE_DESCRIPTOR_PASSING
cmptr = CMSG_FIRSTHDR (&msg); cmptr = CMSG_FIRSTHDR (&msg);
if (cmptr && cmptr->cmsg_len == CMSG_LEN (sizeof(int))) if (cmptr && cmptr->cmsg_len == CMSG_LEN (sizeof(int)))
{ {
@ -112,9 +136,13 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
ctx->uds.pendingfds[ctx->uds.pendingfdscount++] = fd; ctx->uds.pendingfds[ctx->uds.pendingfdscount++] = fd;
} }
} }
#endif /*USE_DESCRIPTOR_PASSING*/
} }
#else /*HAVE_W32_SYSTEM*/ #else /*HAVE_W32_SYSTEM*/
len = recvfrom (ctx->inbound.fd, buf, buflen, 0, NULL, NULL); len = recvfrom (ctx->inbound.fd, buf, buflen, 0, NULL, NULL);
#endif /*HAVE_W32_SYSTEM*/ #endif /*HAVE_W32_SYSTEM*/
/* Return some data to the user. */ /* Return some data to the user. */
@ -149,8 +177,6 @@ uds_writer (assuan_context_t ctx, const void *buf, size_t buflen)
msg.msg_iov = &iovec; msg.msg_iov = &iovec;
iovec.iov_base = (void*)buf; iovec.iov_base = (void*)buf;
iovec.iov_len = buflen; iovec.iov_len = buflen;
msg.msg_control = 0;
msg.msg_controllen = 0;
len = _assuan_simple_sendmsg (ctx, &msg); len = _assuan_simple_sendmsg (ctx, &msg);
#else /*HAVE_W32_SYSTEM*/ #else /*HAVE_W32_SYSTEM*/
@ -167,7 +193,7 @@ uds_writer (assuan_context_t ctx, const void *buf, size_t buflen)
static assuan_error_t static assuan_error_t
uds_sendfd (assuan_context_t ctx, int fd) uds_sendfd (assuan_context_t ctx, int fd)
{ {
#ifndef HAVE_W32_SYSTEM #ifdef USE_DESCRIPTOR_PASSING
struct msghdr msg; struct msghdr msg;
struct iovec iovec; struct iovec iovec;
union { union {
@ -217,7 +243,7 @@ uds_sendfd (assuan_context_t ctx, int fd)
static assuan_error_t static assuan_error_t
uds_receivefd (assuan_context_t ctx, int *fd) uds_receivefd (assuan_context_t ctx, int *fd)
{ {
#ifndef HAVE_W32_SYSTEM #ifdef USE_DESCRIPTOR_PASSING
int i; int i;
if (!ctx->uds.pendingfdscount) if (!ctx->uds.pendingfdscount)

View File

@ -125,6 +125,21 @@ assuan_end_confidential (assuan_context_t ctx)
} }
void
assuan_set_io_monitor (assuan_context_t ctx,
unsigned int (*monitor)(assuan_context_t ctx,
int direction,
const char *line,
size_t linelen))
{
if (ctx)
{
ctx->io_monitor = monitor;
}
}
/* For context CTX, set the flag FLAG to VALUE. Values for flags /* For context CTX, set the flag FLAG to VALUE. Values for flags
are usually 1 or 0 but certain flags might allow for other values; are usually 1 or 0 but certain flags might allow for other values;

View File

@ -95,6 +95,8 @@ int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags);
#define _ASSUAN_PREFIX(x) _ASSUAN_PREFIX2(_ASSUAN_EXT_SYM_PREFIX,x) #define _ASSUAN_PREFIX(x) _ASSUAN_PREFIX2(_ASSUAN_EXT_SYM_PREFIX,x)
#define assuan_ _ASSUAN_PREFIX(assuan_) #define assuan_ _ASSUAN_PREFIX(assuan_)
#define assuan_register_command _ASSUAN_PREFIX(assuan_register_command) #define assuan_register_command _ASSUAN_PREFIX(assuan_register_command)
#define assuan_register_post_cmd_notify \
_ASSUAN_PREFIX(assuan_register_post_cmd_notify)
#define assuan_register_bye_notify _ASSUAN_PREFIX(assuan_register_bye_notify) #define assuan_register_bye_notify _ASSUAN_PREFIX(assuan_register_bye_notify)
#define assuan_register_reset_notify \ #define assuan_register_reset_notify \
_ASSUAN_PREFIX(assuan_register_reset_notify) _ASSUAN_PREFIX(assuan_register_reset_notify)
@ -146,6 +148,7 @@ int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags);
#define assuan_set_error _ASSUAN_PREFIX(assuan_set_error) #define assuan_set_error _ASSUAN_PREFIX(assuan_set_error)
#define assuan_set_pointer _ASSUAN_PREFIX(assuan_set_pointer) #define assuan_set_pointer _ASSUAN_PREFIX(assuan_set_pointer)
#define assuan_get_pointer _ASSUAN_PREFIX(assuan_get_pointer) #define assuan_get_pointer _ASSUAN_PREFIX(assuan_get_pointer)
#define assuan_set_io_monitor _ASSUAN_PREFIX(assuan_set_io_monitor)
#define assuan_begin_confidential _ASSUAN_PREFIX(assuan_begin_confidential) #define assuan_begin_confidential _ASSUAN_PREFIX(assuan_begin_confidential)
#define assuan_end_confidential _ASSUAN_PREFIX(assuan_end_confidential) #define assuan_end_confidential _ASSUAN_PREFIX(assuan_end_confidential)
#define assuan_strerror _ASSUAN_PREFIX(assuan_strerror) #define assuan_strerror _ASSUAN_PREFIX(assuan_strerror)
@ -282,9 +285,11 @@ extern "C"
#define ASSUAN_Unexpected_Data 125 #define ASSUAN_Unexpected_Data 125
#define ASSUAN_Invalid_Status 126 #define ASSUAN_Invalid_Status 126
#define ASSUAN_Locale_Problem 127 #define ASSUAN_Locale_Problem 127
#endif
#define ASSUAN_Not_Confirmed 128 #define ASSUAN_Not_Confirmed 128
/* Warning: Don't use the Error codes, below they are deprecated. */ /* Warning: Don't use the Error codes, below they are deprecated. */
#ifndef _ASSUAN_IN_LIBASSUAN
#define ASSUAN_Bad_Certificate 201 #define ASSUAN_Bad_Certificate 201
#define ASSUAN_Bad_Certificate_Chain 202 #define ASSUAN_Bad_Certificate_Chain 202
#define ASSUAN_Missing_Certificate 203 #define ASSUAN_Missing_Certificate 203
@ -367,6 +372,8 @@ typedef struct assuan_context_s *ASSUAN_CONTEXT _ASSUAN_DEPRECATED;
int assuan_register_command (assuan_context_t ctx, int assuan_register_command (assuan_context_t ctx,
const char *cmd_string, const char *cmd_string,
int (*handler)(assuan_context_t, char *)); int (*handler)(assuan_context_t, char *));
int assuan_register_post_cmd_notify (assuan_context_t ctx,
void (*fnc)(assuan_context_t, int));
int assuan_register_bye_notify (assuan_context_t ctx, int assuan_register_bye_notify (assuan_context_t ctx,
void (*fnc)(assuan_context_t)); void (*fnc)(assuan_context_t));
int assuan_register_reset_notify (assuan_context_t ctx, int assuan_register_reset_notify (assuan_context_t ctx,
@ -497,6 +504,12 @@ void *assuan_get_pointer (assuan_context_t ctx);
void assuan_begin_confidential (assuan_context_t ctx); void assuan_begin_confidential (assuan_context_t ctx);
void assuan_end_confidential (assuan_context_t ctx); void assuan_end_confidential (assuan_context_t ctx);
void assuan_set_io_monitor (assuan_context_t ctx,
unsigned int (*monitor)(assuan_context_t ctx,
int direction,
const char *line,
size_t linelen));
/* For context CTX, set the flag FLAG to VALUE. Values for flags /* For context CTX, set the flag FLAG to VALUE. Values for flags
are usually 1 or 0 but certain flags might allow for other values; are usually 1 or 0 but certain flags might allow for other values;
see the description of the type assuan_flag_t for details. */ see the description of the type assuan_flag_t for details. */

View File

@ -84,6 +84,7 @@ _assuan_error (int oldcode)
case ASSUAN_Unknown_Command: n = 275; break; case ASSUAN_Unknown_Command: n = 275; break;
case ASSUAN_Canceled: n = 277; break; case ASSUAN_Canceled: n = 277; break;
case ASSUAN_No_Secret_Key: n = 17; break; case ASSUAN_No_Secret_Key: n = 17; break;
case ASSUAN_Not_Confirmed: n = 114; break;
case ASSUAN_Read_Error: case ASSUAN_Read_Error:
switch (errno) switch (errno)
@ -200,6 +201,7 @@ cat <<EOF
case 274: n = ASSUAN_Unexpected_Command ; break; case 274: n = ASSUAN_Unexpected_Command ; break;
case 275: n = ASSUAN_Unknown_Command ; break; case 275: n = ASSUAN_Unknown_Command ; break;
case 277: n = ASSUAN_Canceled ; break; case 277: n = ASSUAN_Canceled ; break;
case 114: n = ASSUAN_Not_Confirmed ; break;
case ((1<<15)|86): n = ASSUAN_Out_Of_Core ; break; case ((1<<15)|86): n = ASSUAN_Out_Of_Core ; break;
default: n = 0; break; default: n = 0; break;
} }