Merged changes from upstream libassuan to allow building a W32 DLL.

This commit is contained in:
Werner Koch 2005-08-09 13:19:24 +00:00
parent 7bdaf53a4a
commit b71096a832
24 changed files with 1312 additions and 470 deletions

View File

@ -1,3 +1,7 @@
2005-08-08 Werner Koch <wk@g10code.com>
* configure.ac (stpcpy): Changed from replace to test.
2005-03-24 Marcus Brinkmann <marcus@g10code.de>
* configure.ac (AH_BOTTOM): Removed.

View File

@ -1,3 +1,50 @@
2005-08-09 Werner Koch <wk@g10code.com>
* README.1st: Adjusted to cope with changes done in upstream Assuan.
Merged changes for W32 support from libassuan.
* assuan.h [_ASSUAN_EXT_SYM_PREFIX]: New.
* assuan-io.c [_ASSUAN_NO_PTH]: New.
* assuan-pipe-connect.c (fix_signals) [_ASSUAN_NO_FIXED_SIGNALS]: New.
(assuan_pipe_connect2) [_ASSUAN_USE_DOUBLE_FORK]: Use double fork.
(fix_signals) [_ASSUAN_USE_DOUBLE_FORK]: Do not wait..
* assuan-logging.c, assuan-io.c: Include config.h
Replaced all usages of _WIN32 by the new HAVE_W32_SYSTEM because
there is nothing winning in this API.
* assuan-pipe-connect.c (assuan_pipe_connect2) [_WIN32]: Return
error Not Imlemented.
* assuan-logging.c (_assuan_w32_strerror): New.
* assuan-defs.h (w32_strerror): new.
* assuan-pipe-connect.c (assuan_pipe_connect2, fix_signals):
Factored signal code out to new function.
(build_w32_commandline, create_inheritable_pipe): New. Taken
from gnupg 1.9.
(assuan_pipe_connect2) [W32]: Implemented for W32.
* assuan-pipe-server.c (assuan_init_pipe_server) [W32]: Map file
descriptors using _get_osfhandle.
* assuan-socket-connect.c (assuan_socket_connect) [W32]: Allow for
a drive letter in the path.
* assuan-client.c (assuan_transact): Handle empty and comment
commands correctly.
* assuan-util.c (_assuan_calloc): Avoid integer overflow.
* assuan-util.c (assuan_set_flag, assuan_get_flag): New.
* assuan-defs.h (struct assuan_context_s): New field flags.
* assuan.h (assuan_flag_t): New with one flag value
ASSUAN_NO_WAITPID for now.
* assuan-pipe-connect.c (do_finish): Take care of the no_waitpid
flag.
* mkerrors: Include config.h into assuan-errors.c. This is
required so that assuan.h knows about the W32 macro.
2005-08-09 Timo Schulz <twoaday@g10code.com> (ported from libassuan by wk)
* assuan-io.c (_assuan_simple_read, _assuan_simple_write): W32
support.
* assuan-socket.c (_assuan_close): New.
(_assuan_sock_new): New.
(_assuan_sock_bind): New.
2005-03-22 Werner Koch <wk@g10code.com>
* assuan-defs.h (struct assuan_io): Renamed elements READ and

View File

@ -13,16 +13,15 @@ updating this directory, are:
with ATH replacements.
* assuan.h
** Define _ASSUAN_IN_GPGME to enable GPGME specific code.
** Put all exported Assuan functions in the _gpgme namespace.
** Also wrap all system functions that are wrapped by GNU Pth to
_gpgme wrappers.
* assuan-io.c
** Don't try to support GNU Pth here.
* assuan-pipe-connect.c
** Do not install SIGPIPE signal handler here.
** Preserve the block between "Begin/End GPGME specific modifications".
In particular make sure that
#define _ASSUAN_EXT_SYM_PREFIX _gpgme_
#define _ASSUAN_NO_PTH
#define _ASSUAN_NO_FIXED_SIGNALS
#define _ASSUAN_USE_DOUBLE_FORK
are defined. This puts all exported Assuan functions in the _gpgme
namespace. It also wraps all system functions that are wrapped by
GNU Pth to _gpgme wrappers.
Copyright 2004 g10 Code GmbH

View File

@ -1,5 +1,5 @@
/* assuan-buffer.c - read and send data
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -25,6 +25,9 @@
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#ifdef HAVE_W32_SYSTEM
#include <process.h>
#endif
#include "assuan-defs.h"
static int
@ -49,12 +52,12 @@ writen (ASSUAN_CONTEXT ctx, const char *buffer, size_t length)
/* Read an entire line. */
static int
readline (ASSUAN_CONTEXT ctx, char *buf, size_t buflen,
int *r_nread, int *eof)
int *r_nread, int *r_eof)
{
size_t nleft = buflen;
char *p;
*eof = 0;
*r_eof = 0;
*r_nread = 0;
while (nleft > 0)
{
@ -68,7 +71,7 @@ readline (ASSUAN_CONTEXT ctx, char *buf, size_t buflen,
}
else if (!n)
{
*eof = 1;
*r_eof = 1;
break; /* allow incomplete lines */
}
p = buf;
@ -125,16 +128,18 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
if (rc)
{
if (ctx->log_fp)
fprintf (ctx->log_fp, "%s[%p] <- [Error: %s]\n",
assuan_get_assuan_log_prefix (), ctx, strerror (errno));
fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Error: %s]\n",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx, strerror (errno));
return ASSUAN_Read_Error;
}
if (!nread)
{
assert (ctx->inbound.eof);
if (ctx->log_fp)
fprintf (ctx->log_fp, "%s[%p] <- [EOF]\n",
assuan_get_assuan_log_prefix (), ctx);
fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [EOF]\n",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx);
return -1;
}
@ -165,8 +170,9 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
ctx->inbound.linelen = endp - line;
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%s[%p] <- ",
assuan_get_assuan_log_prefix (), ctx);
fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- ",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
@ -180,8 +186,9 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
else
{
if (ctx->log_fp)
fprintf (ctx->log_fp, "%s[%p] <- [Invalid line]\n",
assuan_get_assuan_log_prefix (), ctx);
fprintf (ctx->log_fp, "%s[%u.%p] DBG: <- [Invalid line]\n",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx);
*line = 0;
ctx->inbound.linelen = 0;
return ctx->inbound.eof ? ASSUAN_Line_Not_Terminated
@ -199,10 +206,10 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
Returns 0 on success or an assuan error code.
See also: assuan_pending_line().
*/
AssuanError
assuan_error_t
assuan_read_line (ASSUAN_CONTEXT ctx, char **line, size_t *linelen)
{
AssuanError err;
assuan_error_t err;
if (!ctx)
return ASSUAN_Invalid_Value;
@ -223,10 +230,65 @@ assuan_pending_line (ASSUAN_CONTEXT ctx)
}
AssuanError
assuan_error_t
_assuan_write_line (assuan_context_t ctx, const char *prefix,
const char *line, size_t len)
{
int rc = 0;
size_t prefixlen = prefix? strlen (prefix):0;
/* Make sure that the line is short enough. */
if (len + prefixlen + 2 > ASSUAN_LINELENGTH)
{
if (ctx->log_fp)
fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> "
"[supplied line too long -truncated]\n",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx);
if (prefixlen > 5)
prefixlen = 5;
if (len > ASSUAN_LINELENGTH - prefixlen - 2)
len = ASSUAN_LINELENGTH - prefixlen - 2 - 1;
}
/* Fixme: we should do some kind of line buffering. */
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
_assuan_log_print_buffer (ctx->log_fp, line, len);
putc ('\n', ctx->log_fp);
}
if (prefixlen)
{
rc = writen (ctx, prefix, prefixlen);
if (rc)
rc = ASSUAN_Write_Error;
}
if (!rc)
{
rc = writen (ctx, line, len);
if (rc)
rc = ASSUAN_Write_Error;
if (!rc)
{
rc = writen (ctx, "\n", 1);
if (rc)
rc = ASSUAN_Write_Error;
}
}
return rc;
}
assuan_error_t
assuan_write_line (ASSUAN_CONTEXT ctx, const char *line)
{
int rc;
size_t len;
const char *s;
@ -238,44 +300,24 @@ assuan_write_line (ASSUAN_CONTEXT ctx, const char *line)
s = strchr (line, '\n');
len = s? (s-line) : strlen (line);
if (len > LINELENGTH - 2)
return ASSUAN_Line_Too_Long;
if (ctx->log_fp && s)
fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> "
"[supplied line contained a LF -truncated]\n",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx);
/* fixme: we should do some kind of line buffering. */
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%s[%p] -> ",
assuan_get_assuan_log_prefix (), ctx);
if (s)
fputs ("[supplied line contained a LF]", ctx->log_fp);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
_assuan_log_print_buffer (ctx->log_fp, line, len);
putc ('\n', ctx->log_fp);
}
rc = writen (ctx, line, len);
if (rc)
rc = ASSUAN_Write_Error;
if (!rc)
{
rc = writen (ctx, "\n", 1);
if (rc)
rc = ASSUAN_Write_Error;
}
return rc;
return _assuan_write_line (ctx, NULL, line, len);
}
/* Write out the data in buffer as datalines with line wrapping and
percent escaping. This fucntion is used for GNU's custom streams */
percent escaping. This function is used for GNU's custom streams */
int
_assuan_cookie_write_data (void *cookie, const char *buffer, size_t size)
_assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size)
{
ASSUAN_CONTEXT ctx = cookie;
size_t size = orig_size;
char *line;
size_t linelen;
@ -317,8 +359,9 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size)
{
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%s[%p] -> ",
assuan_get_assuan_log_prefix (), ctx);
fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
@ -341,12 +384,12 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size)
}
ctx->outbound.data.linelen = linelen;
return 0;
return (int)orig_size;
}
/* Write out any buffered data
This fucntion is used for GNU's custom streams */
This function is used for GNU's custom streams */
int
_assuan_cookie_write_flush (void *cookie)
{
@ -364,8 +407,9 @@ _assuan_cookie_write_flush (void *cookie)
{
if (ctx->log_fp)
{
fprintf (ctx->log_fp, "%s[%p] -> ",
assuan_get_assuan_log_prefix (), ctx);
fprintf (ctx->log_fp, "%s[%u.%p] DBG: -> ",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
@ -404,7 +448,7 @@ _assuan_cookie_write_flush (void *cookie)
* Return value: 0 on success or an error code
**/
AssuanError
assuan_error_t
assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length)
{
if (!ctx)
@ -430,7 +474,7 @@ assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length)
return 0;
}
AssuanError
assuan_error_t
assuan_sendfd (ASSUAN_CONTEXT ctx, int fd)
{
if (! ctx->io->sendfd)
@ -440,7 +484,7 @@ assuan_sendfd (ASSUAN_CONTEXT ctx, int fd)
return ctx->io->sendfd (ctx, fd);
}
AssuanError
assuan_error_t
assuan_receivefd (ASSUAN_CONTEXT ctx, int *fd)
{
if (! ctx->io->receivefd)

View File

@ -32,12 +32,12 @@
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
AssuanError
assuan_error_t
_assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
{
char *line;
int linelen;
AssuanError rc;
assuan_error_t rc;
*okay = 0;
*off = 0;
@ -126,14 +126,14 @@ _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
* the one one returned by the server in error lines or from the
* callback functions.
**/
AssuanError
assuan_error_t
assuan_transact (ASSUAN_CONTEXT ctx,
const char *command,
AssuanError (*data_cb)(void *, const void *, size_t),
assuan_error_t (*data_cb)(void *, const void *, size_t),
void *data_cb_arg,
AssuanError (*inquire_cb)(void*, const char *),
assuan_error_t (*inquire_cb)(void*, const char *),
void *inquire_cb_arg,
AssuanError (*status_cb)(void*, const char *),
assuan_error_t (*status_cb)(void*, const char *),
void *status_cb_arg)
{
int rc, okay, off;
@ -144,6 +144,9 @@ assuan_transact (ASSUAN_CONTEXT ctx,
if (rc)
return rc;
if (*command == '#' || !*command)
return 0; /* Don't expect a response for a comment line. */
again:
rc = _assuan_read_from_server (ctx, &okay, &off);
if (rc)

View File

@ -29,21 +29,19 @@
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#ifndef HAVE_W32_SYSTEM
#include <sys/wait.h>
#endif
#include "assuan-defs.h"
/* Disconnect and release the context CTX. */
void
assuan_disconnect (ASSUAN_CONTEXT ctx)
assuan_disconnect (assuan_context_t ctx)
{
if (ctx)
{
#if 0
/* This may not work if the pipe is full and the other end is
blocked. */
assuan_write_line (ctx, "BYE");
#endif
ctx->finish_handler (ctx);
ctx->deinit_handler (ctx);
ctx->deinit_handler = NULL;
@ -51,8 +49,10 @@ assuan_disconnect (ASSUAN_CONTEXT ctx)
}
}
/* Return the PID of the peer or -1 if not known. */
pid_t
assuan_get_pid (ASSUAN_CONTEXT ctx)
assuan_get_pid (assuan_context_t ctx)
{
return ctx ? ctx->pid : -1;
return (ctx && ctx->pid)? ctx->pid : -1;
}

View File

@ -1,5 +1,5 @@
/* assuan-defs.c - Internal definitions to Assuan
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
* Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -22,12 +22,44 @@
#define ASSUAN_DEFS_H
#include <sys/types.h>
#ifndef HAVE_W32_SYSTEM
#include <sys/socket.h>
#include <sys/un.h>
#else
#include <windows.h>
#endif
#include <unistd.h>
#include "assuan.h"
#ifndef HAVE_W32_SYSTEM
#define DIRSEP_C '/'
#else
#define DIRSEP_C '\\'
#endif
#ifdef HAVE_W32_SYSTEM
#define AF_LOCAL AF_UNIX
/* We need to prefix the structure with a sockaddr_in header so we can
use it later for sendto and recvfrom. */
struct sockaddr_un
{
short sun_family;
unsigned short sun_port;
struct in_addr sun_addr;
char sun_path[108-2-4]; /* Path name. */
};
/* Not needed anymore because the current mingw32 defines this in
sys/types.h */
/* typedef int ssize_t; */
/* Missing W32 functions */
int putc_unlocked (int c, FILE *stream);
void * memrchr (const void *block, int c, size_t size);
char * stpcpy (char *dest, const char *src);
#endif
#define LINELENGTH ASSUAN_LINELENGTH
struct cmdtbl_s
@ -43,24 +75,31 @@ struct assuan_io
/* Routine to write to output_fd. */
ssize_t (*writefnc) (ASSUAN_CONTEXT, const void *, size_t);
/* Send a file descriptor. */
AssuanError (*sendfd) (ASSUAN_CONTEXT, int);
assuan_error_t (*sendfd) (ASSUAN_CONTEXT, int);
/* Receive a file descriptor. */
AssuanError (*receivefd) (ASSUAN_CONTEXT, int *);
assuan_error_t (*receivefd) (ASSUAN_CONTEXT, int *);
};
struct assuan_context_s
{
AssuanError err_no;
assuan_error_t err_no;
const char *err_str;
int os_errno; /* last system error number used with certain error codes*/
int os_errno; /* Last system error number used with certain
error codes. */
/* Context specific flags (cf. assuan_flag_t). */
struct
{
unsigned int no_waitpid:1; /* See ASSUAN_NO_WAITPID. */
} flags;
int confidential;
int is_server; /* set if this is context belongs to a server */
int is_server; /* Set if this is context belongs to a server */
int in_inquire;
char *hello_line;
char *okay_line; /* see assan_set_okay_line() */
char *okay_line; /* See assuan_set_okay_line() */
void *user_pointer; /* for assuan_[gs]et_pointer () */
void *user_pointer; /* For assuan_get_pointer and assuan-set_pointer (). */
FILE *log_fp;
@ -90,13 +129,10 @@ struct assuan_context_s
int pipe_mode; /* We are in pipe mode, i.e. we can handle just one
connection and must terminate then */
pid_t pid; /* In pipe mode, the pid of the child server process.
In socket mode, the pid of the server */
pid_t pid; /* The the pid of the peer. */
int listen_fd; /* The fd we are listening on (used by socket servers) */
int connected_fd; /* helper */
pid_t client_pid; /* for a socket server the PID of the client or -1
if not available */
/* Used for Unix domain sockets. */
struct sockaddr_un myaddr;
@ -145,7 +181,7 @@ void _assuan_release_context (ASSUAN_CONTEXT ctx);
/* Make a connection to the Unix domain socket NAME and return a new
Assuan context in CTX. SERVER_PID is currently not used but may
become handy in the future. */
AssuanError _assuan_domain_init (ASSUAN_CONTEXT *r_ctx,
assuan_error_t _assuan_domain_init (ASSUAN_CONTEXT *r_ctx,
int rendezvousfd,
pid_t peer);
@ -156,9 +192,11 @@ int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
int _assuan_read_line (ASSUAN_CONTEXT ctx);
int _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size);
int _assuan_cookie_write_flush (void *cookie);
assuan_error_t _assuan_write_line (assuan_context_t ctx, const char *prefix,
const char *line, size_t len);
/*-- assuan-client.c --*/
AssuanError _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off);
assuan_error_t _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off);
/*-- assuan-util.c --*/
@ -177,17 +215,40 @@ void _assuan_free (void *p);
void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length);
void _assuan_log_sanitized_string (const char *string);
#ifdef HAVE_W32_SYSTEM
const char *_assuan_w32_strerror (int ec);
#define w32_strerror(e) _assuan_w32_strerror ((e))
#endif /*HAVE_W32_SYSTEM*/
/*-- assuan-logging.c --*/
void _assuan_set_default_log_stream (FILE *fp);
void _assuan_log_printf (const char *format, ...)
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
__attribute__ ((format (printf,1,2)))
#endif
;
/*-- assuan-io.c --*/
ssize_t _assuan_simple_read (ASSUAN_CONTEXT ctx, void *buffer, size_t size);
ssize_t _assuan_simple_write (ASSUAN_CONTEXT ctx, const void *buffer,
size_t size);
/*-- assuan-socket.c --*/
int _assuan_close (int fd);
int _assuan_sock_new (int domain, int type, int proto);
int _assuan_sock_bind (int sockfd, struct sockaddr *addr, int addrlen);
int _assuan_sock_connect (int sockfd, struct sockaddr *addr, int addrlen);
#ifdef HAVE_FOPENCOOKIE
/* We have to implement funopen in terms of glibc's fopencookie. */
FILE *funopen(const void *cookie, cookie_read_function_t *readfn,
cookie_write_function_t *writefn,
cookie_seek_function_t *seekfn,
cookie_close_function_t *closefn);
FILE *_assuan_funopen(void *cookie,
cookie_read_function_t *readfn,
cookie_write_function_t *writefn,
cookie_seek_function_t *seekfn,
cookie_close_function_t *closefn);
#define funopen(a,r,w,s,c) _assuan_funopen ((a), (r), (w), (s), (c))
#endif /*HAVE_FOPENCOOKIE*/
#endif /*ASSUAN_DEFS_H*/

View File

@ -27,8 +27,12 @@
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#ifndef HAVE_W32_SYSTEM
#include <sys/socket.h>
#include <sys/un.h>
#else
#include <windows.h>
#endif
#if HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
@ -39,17 +43,23 @@
#include "assuan-defs.h"
#define LOG(format, args...) \
fprintf (assuan_get_assuan_log_stream (), \
assuan_get_assuan_log_prefix (), \
"%s" format , ## args)
#ifndef PF_LOCAL
# ifdef PF_UNIX
# define PF_LOCAL PF_UNIX
# else
# define PF_LOCAL AF_UNIX
# endif
# ifndef AF_LOCAL
# define AF_LOCAL AF_UNIX
# endif
#endif
static void
do_deinit (ASSUAN_CONTEXT ctx)
do_deinit (assuan_context_t ctx)
{
if (ctx->inbound.fd != -1)
close (ctx->inbound.fd);
_assuan_close (ctx->inbound.fd);
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
@ -65,7 +75,7 @@ do_deinit (ASSUAN_CONTEXT ctx)
assert (ctx->pendingfdscount > 0);
for (i = 0; i < ctx->pendingfdscount; i ++)
close (ctx->pendingfds[i]);
_assuan_close (ctx->pendingfds[i]);
free (ctx->pendingfds);
}
@ -76,10 +86,11 @@ do_deinit (ASSUAN_CONTEXT ctx)
/* Read from the socket server. */
static ssize_t
domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
domain_reader (assuan_context_t ctx, void *buf, size_t buflen)
{
int len = ctx->domainbuffersize;
#ifndef HAVE_W32_SYSTEM
start:
if (len == 0)
/* No data is buffered. */
@ -166,15 +177,15 @@ domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
/* XXX: Arg. Not from whom we expected! What do we want to
do? Should we just ignore it? We shall do the latter
for the moment. */
LOG ("Not setup to receive messages from: `%s'.",
((struct sockaddr_un *) msg.msg_name)->sun_path);
_assuan_log_printf ("not setup to receive messages from `%s'\n",
((struct sockaddr_un *) msg.msg_name)->sun_path);
goto start;
}
len = recvmsg (ctx->inbound.fd, &msg, 0);
if (len < 0)
{
LOG ("domain_reader: %s\n", strerror (errno));
_assuan_log_printf ("domain_reader: %s\n", strerror (errno));
return -1;
}
@ -190,7 +201,7 @@ domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
sizeof (int) * (ctx->pendingfdscount + 1));
if (! tmp)
{
LOG ("domain_reader: %s\n", strerror (errno));
_assuan_log_printf ("domain_reader: %s\n", strerror (errno));
return -1;
}
@ -198,13 +209,16 @@ domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
ctx->pendingfds[ctx->pendingfdscount++]
= *(int *) CMSG_DATA (&cmsg.hdr);
LOG ("Received file descriptor %d from peer.\n",
_assuan_log_printf ("received file descriptor %d from peer\n",
ctx->pendingfds[ctx->pendingfdscount - 1]);
}
if (len == 0)
goto start;
}
#else
len = recvfrom (ctx->inbound.fd, buf, buflen, 0, NULL, NULL);
#endif
/* Return some data to the user. */
@ -223,8 +237,9 @@ domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
/* Write to the domain server. */
static ssize_t
domain_writer (ASSUAN_CONTEXT ctx, const void *buf, size_t buflen)
domain_writer (assuan_context_t ctx, const void *buf, size_t buflen)
{
#ifndef HAVE_W32_SYSTEM
struct msghdr msg;
struct iovec iovec;
ssize_t len;
@ -244,14 +259,21 @@ domain_writer (ASSUAN_CONTEXT ctx, const void *buf, size_t buflen)
len = sendmsg (ctx->outbound.fd, &msg, 0);
if (len < 0)
LOG ("domain_writer: %s\n", strerror (errno));
_assuan_log_printf ("domain_writer: %s\n", strerror (errno));
#else
int len;
len = sendto (ctx->outbound.fd, buf, buflen, 0,
(struct sockaddr *)&ctx->serveraddr,
sizeof (struct sockaddr_in));
#endif
return len;
}
static AssuanError
domain_sendfd (ASSUAN_CONTEXT ctx, int fd)
static assuan_error_t
domain_sendfd (assuan_context_t ctx, int fd)
{
#ifndef HAVE_W32_SYSTEM
struct msghdr msg;
struct
{
@ -282,19 +304,23 @@ domain_sendfd (ASSUAN_CONTEXT ctx, int fd)
len = sendmsg (ctx->outbound.fd, &msg, 0);
if (len < 0)
{
LOG ("domain_sendfd: %s\n", strerror (errno));
_assuan_log_printf ("domain_sendfd: %s\n", strerror (errno));
return ASSUAN_General_Error;
}
else
return 0;
#else
return 0;
#endif
}
static AssuanError
domain_receivefd (ASSUAN_CONTEXT ctx, int *fd)
static assuan_error_t
domain_receivefd (assuan_context_t ctx, int *fd)
{
#ifndef HAVE_W32_SYSTEM
if (ctx->pendingfds == 0)
{
LOG ("No pending file descriptors!\n");
_assuan_log_printf ("no pending file descriptors!\n");
return ASSUAN_General_Error;
}
@ -312,7 +338,7 @@ domain_receivefd (ASSUAN_CONTEXT ctx, int *fd)
ctx->pendingfds = realloc (ctx->pendingfds,
ctx->pendingfdscount * sizeof (int));
}
#endif
return 0;
}
@ -321,14 +347,14 @@ domain_receivefd (ASSUAN_CONTEXT ctx, int *fd)
/* Make a connection to the Unix domain socket NAME and return a new
Assuan context in CTX. SERVER_PID is currently not used but may
become handy in the future. */
AssuanError
_assuan_domain_init (ASSUAN_CONTEXT *r_ctx, int rendezvousfd, pid_t peer)
assuan_error_t
_assuan_domain_init (assuan_context_t *r_ctx, int rendezvousfd, pid_t peer)
{
static struct assuan_io io = { domain_reader, domain_writer,
domain_sendfd, domain_receivefd };
AssuanError err;
ASSUAN_CONTEXT ctx;
assuan_error_t err;
assuan_context_t ctx;
int fd;
size_t len;
int tries;
@ -349,17 +375,17 @@ _assuan_domain_init (ASSUAN_CONTEXT *r_ctx, int rendezvousfd, pid_t peer)
/* Setup the socket. */
fd = socket (PF_LOCAL, SOCK_DGRAM, 0);
fd = _assuan_sock_new (PF_LOCAL, SOCK_DGRAM, 0);
if (fd == -1)
{
LOG ("can't create socket: %s\n", strerror (errno));
_assuan_log_printf ("can't create socket: %s\n", strerror (errno));
_assuan_release_context (ctx);
return ASSUAN_General_Error;
}
ctx->inbound.fd = fd;
ctx->outbound.fd = fd;
/* And the io buffers. */
ctx->io = &io;
@ -380,13 +406,14 @@ _assuan_domain_init (ASSUAN_CONTEXT *r_ctx, int rendezvousfd, pid_t peer)
/* XXX: L_tmpnam must be shorter than sizeof (sun_path)! */
assert (L_tmpnam < sizeof (ctx->myaddr.sun_path));
/* XXX: W32 tmpnam is broken */
p = tmpnam (buf);
if (! p)
{
LOG ("cannot determine an appropriate temporary file "
"name. DOS in progress?\n");
_assuan_log_printf ("cannot determine an appropriate temporary file "
"name. DoS in progress?\n");
_assuan_release_context (ctx);
close (fd);
_assuan_close (fd);
return ASSUAN_General_Error;
}
@ -396,17 +423,17 @@ _assuan_domain_init (ASSUAN_CONTEXT *r_ctx, int rendezvousfd, pid_t peer)
memcpy (ctx->myaddr.sun_path, buf, len);
len += offsetof (struct sockaddr_un, sun_path);
err = bind (fd, (struct sockaddr *) &ctx->myaddr, len);
err = _assuan_sock_bind (fd, (struct sockaddr *) &ctx->myaddr, len);
if (! err)
break;
}
if (err)
{
LOG ("can't bind to `%s': %s\n", ctx->myaddr.sun_path,
strerror (errno));
_assuan_log_printf ("can't bind to `%s': %s\n", ctx->myaddr.sun_path,
strerror (errno));
_assuan_release_context (ctx);
close (fd);
_assuan_close (fd);
return ASSUAN_Connect_Failed;
}
@ -418,7 +445,7 @@ _assuan_domain_init (ASSUAN_CONTEXT *r_ctx, int rendezvousfd, pid_t peer)
fp = fdopen (rendezvousfd, "w+");
if (! fp)
{
LOG ("can't open rendezvous port: %s\n", strerror (errno));
_assuan_log_printf ("can't open rendezvous port: %s\n", strerror (errno));
return ASSUAN_Connect_Failed;
}
@ -447,10 +474,10 @@ _assuan_domain_init (ASSUAN_CONTEXT *r_ctx, int rendezvousfd, pid_t peer)
return 0;
}
AssuanError
assuan_domain_connect (ASSUAN_CONTEXT * r_ctx, int rendezvousfd, pid_t peer)
assuan_error_t
assuan_domain_connect (assuan_context_t * r_ctx, int rendezvousfd, pid_t peer)
{
AssuanError aerr;
assuan_error_t aerr;
int okay, off;
aerr = _assuan_domain_init (r_ctx, rendezvousfd, peer);
@ -460,10 +487,11 @@ assuan_domain_connect (ASSUAN_CONTEXT * r_ctx, int rendezvousfd, pid_t peer)
/* Initial handshake. */
aerr = _assuan_read_from_server (*r_ctx, &okay, &off);
if (aerr)
LOG ("can't connect to server: %s\n", assuan_strerror (aerr));
_assuan_log_printf ("can't connect to server: %s\n",
assuan_strerror (aerr));
else if (okay != 1)
{
LOG ("can't connect to server: `");
_assuan_log_printf ("can't connect to server: `");
_assuan_log_sanitized_string ((*r_ctx)->inbound.line);
fprintf (assuan_get_assuan_log_stream (), "'\n");
aerr = ASSUAN_Connect_Failed;

View File

@ -27,12 +27,12 @@
#include "assuan-defs.h"
/* Initialize a server. */
AssuanError
assuan_error_t
assuan_init_domain_server (ASSUAN_CONTEXT *r_ctx,
int rendezvousfd,
pid_t peer)
{
AssuanError err;
assuan_error_t err;
err = _assuan_domain_init (r_ctx, rendezvousfd, peer);
if (err)

View File

@ -135,7 +135,7 @@ std_handler_end (ASSUAN_CONTEXT ctx, char *line)
return set_error (ctx, Not_Implemented, NULL);
}
AssuanError
assuan_error_t
assuan_command_parse_fd (ASSUAN_CONTEXT ctx, char *line, int *rfd)
{
char *endp;
@ -391,7 +391,7 @@ my_strcasecmp (const char *a, const char *b)
}
/* Parse the line, break out the command, find it in the command
table, remove leading and white spaces from the arguments, all the
table, remove leading and white spaces from the arguments, call the
handler with the argument line and return the error */
static int
dispatch_command (ASSUAN_CONTEXT ctx, char *line, int linelen)
@ -484,7 +484,7 @@ process_request (ASSUAN_CONTEXT ctx)
}
else
{
char errline[256];
char errline[300];
if (rc < 100)
sprintf (errline, "ERR %d server fault (%.50s)",
@ -493,8 +493,40 @@ process_request (ASSUAN_CONTEXT ctx)
{
const char *text = ctx->err_no == rc? ctx->err_str:NULL;
sprintf (errline, "ERR %d %.50s%s%.100s",
rc, assuan_strerror (rc), text? " - ":"", text?text:"");
#if defined(__GNUC__) && defined(__ELF__)
/* If we have weak symbol support we try to use the error
strings from libgpg-error without creating a dependency.
They are used for debugging purposes only, so there is no
problem if they are not available. We need to make sure
that we are using elf because only this guarantees that
weak symbol support is available in case GNU ld is not
used. */
unsigned int source, code;
int gpg_strerror_r (unsigned int err, char *buf, size_t buflen)
__attribute__ ((weak));
const char *gpg_strsource (unsigned int err)
__attribute__ ((weak));
source = ((rc >> 24) & 0xff);
code = (rc & 0x00ffffff);
if (source && gpg_strsource && gpg_strerror_r)
{
/* Assume this is an libgpg-error. */
char ebuf[50];
gpg_strerror_r (rc, ebuf, sizeof ebuf );
sprintf (errline, "ERR %d %.50s <%.30s>%s%.100s",
rc,
ebuf,
gpg_strsource (rc),
text? " - ":"", text?text:"");
}
else
#endif /* __GNUC__ && __ELF__ */
sprintf (errline, "ERR %d %.50s%s%.100s",
rc, assuan_strerror (rc), text? " - ":"", text?text:"");
}
rc = assuan_write_line (ctx, errline);
}
@ -512,7 +544,7 @@ process_request (ASSUAN_CONTEXT ctx)
* assuan_process:
* @ctx: assuan context
*
* This fucntion is used to handle the assuan protocol after a
* This function is used to handle the assuan protocol after a
* connection has been established using assuan_accept(). This is the
* main protocol handler.
*
@ -625,7 +657,7 @@ assuan_get_data_fp (ASSUAN_CONTEXT ctx)
/* Set the text used for the next OK reponse. This string is
automatically reset to NULL after the next command. */
AssuanError
assuan_error_t
assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line)
{
if (!ctx)
@ -652,15 +684,16 @@ assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line)
void
assuan_error_t
assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text)
{
char buffer[256];
char *helpbuf;
size_t n;
assuan_error_t ae;
if ( !ctx || !keyword)
return;
return ASSUAN_Invalid_Value;
if (!text)
text = "";
@ -674,7 +707,7 @@ assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text)
strcat (buffer, " ");
strcat (buffer, text);
}
assuan_write_line (ctx, buffer);
ae = assuan_write_line (ctx, buffer);
}
else if ( (helpbuf = xtrymalloc (n)) )
{
@ -685,7 +718,10 @@ assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text)
strcat (helpbuf, " ");
strcat (helpbuf, text);
}
assuan_write_line (ctx, helpbuf);
ae = assuan_write_line (ctx, helpbuf);
xfree (helpbuf);
}
else
ae = 0;
return ae;
}

View File

@ -134,11 +134,11 @@ free_membuf (struct membuf *mb)
*
* Return value: 0 on success or an ASSUAN error code
**/
AssuanError
assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
char **r_buffer, size_t *r_length, size_t maxlen)
assuan_error_t
assuan_inquire (assuan_context_t ctx, const char *keyword,
unsigned char **r_buffer, size_t *r_length, size_t maxlen)
{
AssuanError rc;
assuan_error_t rc;
struct membuf mb;
char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */
unsigned char *line, *p;

View File

@ -1,5 +1,5 @@
/* assuan-io.c - Wraps the read and write functions.
* Copyright (C) 2002 Free Software Foundation, Inc.
* Copyright (C) 2002, 2004 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -18,41 +18,53 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "assuan-defs.h"
#include <sys/types.h>
#include <unistd.h>
#ifdef HAVE_W32_SYSTEM
#include <windows.h>
#endif
#ifdef _ASSUAN_IN_GPGME
ssize_t
_assuan_simple_read (ASSUAN_CONTEXT ctx, void *buffer, size_t size)
{
return read (ctx->inbound.fd, buffer, size);
}
ssize_t
_assuan_simple_write (ASSUAN_CONTEXT ctx, const void *buffer, size_t size)
{
return write (ctx->outbound.fd, buffer, size);
}
#else
#ifndef _ASSUAN_NO_PTH
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);
#ifndef HAVE_W32_SYSTEM
#pragma weak pth_read
#pragma weak pth_write
ssize_t
_assuan_simple_read (ASSUAN_CONTEXT ctx, void *buffer, size_t size)
{
return (pth_read ? pth_read : read) (ctx->inbound.fd, buffer, size);
}
ssize_t
_assuan_simple_write (ASSUAN_CONTEXT ctx, const void *buffer, size_t size)
{
return (pth_write ? pth_write : write) (ctx->outbound.fd, buffer, size);
}
#endif
#endif /*!_ASSUAN_NO_PTH*/
ssize_t
_assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size)
{
#ifdef _ASSUAN_NO_PTH
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
_assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size)
{
#ifdef _ASSUAN_NO_PTH
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
}

View File

@ -1,5 +1,5 @@
/* assuan-listen.c - Wait for a connection (server)
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
* Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -26,8 +26,8 @@
#include "assuan-defs.h"
AssuanError
assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line)
assuan_error_t
assuan_set_hello_line (assuan_context_t ctx, const char *line)
{
if (!ctx)
return ASSUAN_Invalid_Value;
@ -41,8 +41,13 @@ assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line)
char *buf = xtrymalloc (3+strlen(line)+1);
if (!buf)
return ASSUAN_Out_Of_Core;
strcpy (buf, "OK ");
strcpy (buf+3, line);
if (strchr (line, '\n'))
strcpy (buf, line);
else
{
strcpy (buf, "OK ");
strcpy (buf+3, line);
}
xfree (ctx->hello_line);
ctx->hello_line = buf;
}
@ -61,10 +66,11 @@ assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line)
* Return value: 0 on success or an error if the connection could for
* some reason not be established.
**/
AssuanError
assuan_accept (ASSUAN_CONTEXT ctx)
assuan_error_t
assuan_accept (assuan_context_t ctx)
{
int rc;
const char *p, *pend;
if (!ctx)
return ASSUAN_Invalid_Value;
@ -77,9 +83,26 @@ assuan_accept (ASSUAN_CONTEXT ctx)
if (rc)
return rc;
/* send the hello */
rc = assuan_write_line (ctx, ctx->hello_line? ctx->hello_line
: "OK Your orders please");
/* Send the hello. */
p = ctx->hello_line;
if (p && (pend = strchr (p, '\n')))
{ /* This is a multi line hello. Send all but the last line as
comments. */
do
{
rc = _assuan_write_line (ctx, "# ", p, pend - p);
if (rc)
return rc;
p = pend + 1;
pend = strchr (p, '\n');
}
while (pend);
rc = _assuan_write_line (ctx, "OK ", p, strlen (p));
}
else if (p)
rc = assuan_write_line (ctx, p);
else
rc = assuan_write_line (ctx, "OK Pleased to meet you");
if (rc)
return rc;
@ -92,14 +115,14 @@ assuan_accept (ASSUAN_CONTEXT ctx)
int
assuan_get_input_fd (ASSUAN_CONTEXT ctx)
assuan_get_input_fd (assuan_context_t ctx)
{
return ctx? ctx->input_fd : -1;
}
int
assuan_get_output_fd (ASSUAN_CONTEXT ctx)
assuan_get_output_fd (assuan_context_t ctx)
{
return ctx? ctx->output_fd : -1;
}
@ -107,25 +130,25 @@ assuan_get_output_fd (ASSUAN_CONTEXT ctx)
/* Close the fd descriptor set by the command INPUT FD=n. We handle
this fd inside assuan so that we can do some initial checks */
AssuanError
assuan_close_input_fd (ASSUAN_CONTEXT ctx)
assuan_error_t
assuan_close_input_fd (assuan_context_t ctx)
{
if (!ctx || ctx->input_fd == -1)
return ASSUAN_Invalid_Value;
close (ctx->input_fd);
_assuan_close (ctx->input_fd);
ctx->input_fd = -1;
return 0;
}
/* Close the fd descriptor set by the command OUTPUT FD=n. We handle
this fd inside assuan so that we can do some initial checks */
AssuanError
assuan_close_output_fd (ASSUAN_CONTEXT ctx)
assuan_error_t
assuan_close_output_fd (assuan_context_t ctx)
{
if (!ctx || ctx->output_fd == -1)
return ASSUAN_Invalid_Value;
close (ctx->output_fd);
_assuan_close (ctx->output_fd);
ctx->output_fd = -1;
return 0;
}

View File

@ -1,5 +1,5 @@
/* assuan-logging.c - Default logging function.
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -18,11 +18,28 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include "assuan-defs.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#ifdef HAVE_W32_SYSTEM
#include <windows.h>
#endif /*HAVE_W32_SYSTEM*/
#include "assuan-defs.h"
static char prefix_buffer[80];
static FILE *_assuan_log;
void
_assuan_set_default_log_stream (FILE *fp)
{
if (!_assuan_log)
_assuan_log = fp;
}
void
assuan_set_assuan_log_stream (FILE *fp)
{
@ -35,8 +52,61 @@ assuan_get_assuan_log_stream (void)
return _assuan_log ? _assuan_log : stderr;
}
/* Set the prefix to be used for logging to TEXT or
resets it to the default if TEXT is NULL. */
void
assuan_set_assuan_log_prefix (const char *text)
{
if (text)
{
strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1);
prefix_buffer[sizeof (prefix_buffer)-1] = 0;
}
else
*prefix_buffer = 0;
}
const char *
assuan_get_assuan_log_prefix (void)
{
return "";
return prefix_buffer;
}
void
_assuan_log_printf (const char *format, ...)
{
va_list arg_ptr;
FILE *fp;
const char *prf;
fp = assuan_get_assuan_log_stream ();
prf = assuan_get_assuan_log_prefix ();
if (*prf)
{
fputs (prf, fp);
fputs (": ", fp);
}
va_start (arg_ptr, format);
vfprintf (fp, format, arg_ptr );
va_end (arg_ptr);
}
#ifdef HAVE_W32_SYSTEM
const char *
_assuan_w32_strerror (int ec)
{
static char strerr[256];
if (ec == -1)
ec = (int)GetLastError ();
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
strerr, sizeof (strerr)-1, NULL);
return strerr;
}
#endif /*HAVE_W32_SYSTEM*/

View File

@ -30,7 +30,11 @@
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#ifndef HAVE_W32_SYSTEM
#include <sys/wait.h>
#else
#include <windows.h>
#endif
#include "assuan-defs.h"
@ -40,11 +44,47 @@
#define MAX_OPEN_FDS 20
#endif
#define LOG(format, args...) \
fprintf (assuan_get_assuan_log_stream (), \
assuan_get_assuan_log_prefix (), \
"%s" format , ## args)
#ifdef HAVE_W32_SYSTEM
/* We assume that a HANDLE can be represented by an int which should
be true for all i386 systems (HANDLE is defined as void *) and
these are the only systems for which Windows is available. Further
we assume that -1 denotes an invalid handle. */
#define fd_to_handle(a) ((HANDLE)(a))
#define handle_to_fd(a) ((int)(a))
#define pid_to_handle(a) ((HANDLE)(a))
#define handle_to_pid(a) ((int)(a))
#endif /*HAVE_W32_SYSTEM*/
/* This should be called to make sure that SIGPIPE gets ignored. */
static void
fix_signals (void)
{
#ifndef _ASSUAN_NO_FIXED_SIGNALS
#ifndef HAVE_DOSISH_SYSTEM /* No SIGPIPE for these systems. */
static int fixed_signals;
if (!fixed_signals)
{
struct sigaction act;
sigaction (SIGPIPE, NULL, &act);
if (act.sa_handler == SIG_DFL)
{
act.sa_handler = SIG_IGN;
sigemptyset (&act.sa_mask);
act.sa_flags = 0;
sigaction (SIGPIPE, &act, NULL);
}
fixed_signals = 1;
/* FIXME: This is not MT safe */
}
#endif /*HAVE_DOSISH_SYSTEM*/
#endif /*!_ASSUAN_NO_FIXED_SIGNALS*/
}
#ifndef HAVE_W32_SYSTEM
static int
writen (int fd, const char *buffer, size_t length)
{
@ -63,75 +103,328 @@ writen (int fd, const char *buffer, size_t length)
}
return 0; /* okay */
}
#endif
static int
do_finish (ASSUAN_CONTEXT ctx)
do_finish (assuan_context_t ctx)
{
if (ctx->inbound.fd != -1)
{
close (ctx->inbound.fd);
_assuan_close (ctx->inbound.fd);
ctx->inbound.fd = -1;
}
if (ctx->outbound.fd != -1)
{
close (ctx->outbound.fd);
_assuan_close (ctx->outbound.fd);
ctx->outbound.fd = -1;
}
if (ctx->pid != -1)
if (ctx->pid != -1 && ctx->pid)
{
#if 0
/* This is already done by the double fork. */
waitpid (ctx->pid, NULL, 0); /* FIXME Check return value. */
#ifndef HAVE_W32_SYSTEM
#ifndef _ASSUAN_USE_DOUBLE_FORK
if (!ctx->flags.no_waitpid)
waitpid (ctx->pid, NULL, 0);
ctx->pid = -1;
#endif
#endif /*!HAVE_W32_SYSTEM*/
}
return 0;
}
static void
do_deinit (ASSUAN_CONTEXT ctx)
do_deinit (assuan_context_t ctx)
{
do_finish (ctx);
}
#ifdef HAVE_W32_SYSTEM
/* Build a command line for use with W32's CreateProcess. On success
CMDLINE gets the address of a newly allocated string. */
static int
build_w32_commandline (char * const *argv, char **cmdline)
{
int i, n;
const char *s;
char *buf, *p;
*cmdline = NULL;
n = 0;
for (i=0; (s=argv[i]); i++)
{
n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */
for (; *s; s++)
if (*s == '\"')
n++; /* Need to double inner quotes. */
}
n++;
buf = p = xtrymalloc (n);
if (!buf)
return -1;
for (i=0; argv[i]; i++)
{
if (i)
p = stpcpy (p, " ");
if (!*argv[i]) /* Empty string. */
p = stpcpy (p, "\"\"");
else if (strpbrk (argv[i], " \t\n\v\f\""))
{
p = stpcpy (p, "\"");
for (s=argv[i]; *s; s++)
{
*p++ = *s;
if (*s == '\"')
*p++ = *s;
}
*p++ = '\"';
*p = 0;
}
else
p = stpcpy (p, argv[i]);
}
*cmdline= buf;
return 0;
}
#endif /*HAVE_W32_SYSTEM*/
#ifdef HAVE_W32_SYSTEM
/* Create pipe where one end end is inheritable. */
static int
create_inheritable_pipe (int filedes[2], int for_write)
{
HANDLE r, w, h;
SECURITY_ATTRIBUTES sec_attr;
memset (&sec_attr, 0, sizeof sec_attr );
sec_attr.nLength = sizeof sec_attr;
sec_attr.bInheritHandle = FALSE;
if (!CreatePipe (&r, &w, &sec_attr, 0))
{
_assuan_log_printf ("CreatePipe failed: %s\n", w32_strerror (-1));
return -1;
}
if (!DuplicateHandle (GetCurrentProcess(), for_write? r : w,
GetCurrentProcess(), &h, 0,
TRUE, DUPLICATE_SAME_ACCESS ))
{
_assuan_log_printf ("DuplicateHandle failed: %s\n", w32_strerror (-1));
CloseHandle (r);
CloseHandle (w);
return -1;
}
if (for_write)
{
CloseHandle (r);
r = h;
}
else
{
CloseHandle (w);
w = h;
}
filedes[0] = handle_to_fd (r);
filedes[1] = handle_to_fd (w);
return 0;
}
#endif /*HAVE_W32_SYSTEM*/
/* Connect to a server over a pipe, creating the assuan context and
returning it in CTX. The server filename is NAME, the argument
vector in ARGV. FD_CHILD_LIST is a -1 terminated list of file
descriptors not to close in the child. */
AssuanError
assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
int *fd_child_list)
descriptors not to close in the child. ATFORK is called in the
child right after the fork; ATFORKVALUE is passed as the first
argument and 0 is passed as the second argument. The ATFORK
function should only act if the second value is 0. */
assuan_error_t
assuan_pipe_connect2 (assuan_context_t *ctx,
const char *name, char *const argv[],
int *fd_child_list,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue)
{
#ifndef _ASSUAN_IN_GPGME
static int fixed_signals = 0;
#endif
AssuanError err;
#ifdef HAVE_W32_SYSTEM
assuan_error_t err;
int rp[2];
int wp[2];
char mypidstr[50];
char *cmdline;
SECURITY_ATTRIBUTES sec_attr;
PROCESS_INFORMATION pi =
{
NULL, /* Returns process handle. */
0, /* Returns primary thread handle. */
0, /* Returns pid. */
0 /* Returns tid. */
};
STARTUPINFO si;
int fd, *fdp;
HANDLE nullfd = INVALID_HANDLE_VALUE;
if (!ctx || !name || !argv || !argv[0])
return ASSUAN_Invalid_Value;
#ifndef _ASSUAN_IN_GPGME
if (!fixed_signals)
{
struct sigaction act;
sigaction (SIGPIPE, NULL, &act);
if (act.sa_handler == SIG_DFL)
{
act.sa_handler = SIG_IGN;
sigemptyset (&act.sa_mask);
act.sa_flags = 0;
sigaction (SIGPIPE, &act, NULL);
}
fixed_signals = 1;
/* FIXME: This is not MT safe */
fix_signals ();
sprintf (mypidstr, "%lu", (unsigned long)getpid ());
/* Build the command line. */
if (build_w32_commandline (argv, &cmdline))
return ASSUAN_Out_Of_Core;
/* Create thew two pipes. */
if (create_inheritable_pipe (rp, 0))
{
xfree (cmdline);
return ASSUAN_General_Error;
}
#endif
if (create_inheritable_pipe (wp, 1))
{
CloseHandle (fd_to_handle (rp[0]));
CloseHandle (fd_to_handle (rp[1]));
xfree (cmdline);
return ASSUAN_General_Error;
}
err = _assuan_new_context (ctx);
if (err)
{
CloseHandle (fd_to_handle (rp[0]));
CloseHandle (fd_to_handle (rp[1]));
CloseHandle (fd_to_handle (wp[0]));
CloseHandle (fd_to_handle (wp[1]));
xfree (cmdline);
return ASSUAN_General_Error;
}
(*ctx)->pipe_mode = 1;
(*ctx)->inbound.fd = rp[0]; /* Our inbound is read end of read pipe. */
(*ctx)->outbound.fd = wp[1]; /* Our outbound is write end of write pipe. */
(*ctx)->deinit_handler = do_deinit;
(*ctx)->finish_handler = do_finish;
/* fixme: Actually we should set the "_assuan_pipe_connect_pid" env
variable. However this requires us to write a full environment
handler, because the strings are expected in sorted order. The
suggestion given in the MS Reference Library, to save the old
value, changeit, create proces and restore it, is not thread
safe. */
/* Start the process. */
memset (&sec_attr, 0, sizeof sec_attr );
sec_attr.nLength = sizeof sec_attr;
sec_attr.bInheritHandle = FALSE;
memset (&si, 0, sizeof si);
si.cb = sizeof (si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = fd_to_handle (wp[0]);
si.hStdOutput = fd_to_handle (rp[1]);
/* Dup stderr to /dev/null unless it is in the list of FDs to be
passed to the child. */
fd = fileno (stderr);
fdp = fd_child_list;
if (fdp)
{
for (; *fdp != -1 && *fdp != fd; fdp++)
;
}
if (!fdp || *fdp == -1)
{
nullfd = CreateFile ("nul", GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (nullfd == INVALID_HANDLE_VALUE)
{
_assuan_log_printf ("can't open `nul': %s\n", w32_strerror (-1));
CloseHandle (fd_to_handle (rp[0]));
CloseHandle (fd_to_handle (rp[1]));
CloseHandle (fd_to_handle (wp[0]));
CloseHandle (fd_to_handle (wp[1]));
xfree (cmdline);
_assuan_release_context (*ctx);
return -1;
}
si.hStdError = nullfd;
}
else
si.hStdError = fd_to_handle (_get_osfhandle (fd));
/* Note: We inherit all handles flagged as inheritable. This seems
to be a security flaw but there seems to be no way of selecting
handles to inherit. */
/* _assuan_log_printf ("CreateProcess, path=`%s' cmdline=`%s'\n", */
/* name, cmdline); */
if (!CreateProcess (name, /* Program to start. */
cmdline, /* Command line arguments. */
&sec_attr, /* Process security attributes. */
&sec_attr, /* Thread security attributes. */
TRUE, /* Inherit handles. */
(CREATE_DEFAULT_ERROR_MODE
| GetPriorityClass (GetCurrentProcess ())
| CREATE_SUSPENDED), /* Creation flags. */
NULL, /* Environment. */
NULL, /* Use current drive/directory. */
&si, /* Startup information. */
&pi /* Returns process information. */
))
{
_assuan_log_printf ("CreateProcess failed: %s\n", w32_strerror (-1));
CloseHandle (fd_to_handle (rp[0]));
CloseHandle (fd_to_handle (rp[1]));
CloseHandle (fd_to_handle (wp[0]));
CloseHandle (fd_to_handle (wp[1]));
if (nullfd != INVALID_HANDLE_VALUE)
CloseHandle (nullfd);
xfree (cmdline);
_assuan_release_context (*ctx);
return ASSUAN_General_Error;
}
xfree (cmdline);
cmdline = NULL;
if (nullfd != INVALID_HANDLE_VALUE)
{
CloseHandle (nullfd);
nullfd = INVALID_HANDLE_VALUE;
}
CloseHandle (fd_to_handle (rp[1]));
CloseHandle (fd_to_handle (wp[0]));
/* _assuan_log_printf ("CreateProcess ready: hProcess=%p hThread=%p" */
/* " dwProcessID=%d dwThreadId=%d\n", */
/* pi.hProcess, pi.hThread, */
/* (int) pi.dwProcessId, (int) pi.dwThreadId); */
ResumeThread (pi.hThread);
CloseHandle (pi.hThread);
(*ctx)->pid = 0; /* We don't use the PID. */
CloseHandle (pi.hProcess); /* We don't need to wait for the process. */
#else /*!HAVE_W32_SYSTEM*/
assuan_error_t err;
int rp[2];
int wp[2];
char mypidstr[50];
if (!ctx || !name || !argv || !argv[0])
return ASSUAN_Invalid_Value;
fix_signals ();
sprintf (mypidstr, "%lu", (unsigned long)getpid ());
if (pipe (rp) < 0)
return ASSUAN_General_Error;
@ -158,8 +451,8 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
(*ctx)->deinit_handler = do_deinit;
(*ctx)->finish_handler = do_finish;
/* FIXME: Use _gpgme_io_spawn. The PID stored here is actually
soon useless. */
/* FIXME: For GPGME we should better use _gpgme_io_spawn. The PID
stored here is actually soon useless. */
(*ctx)->pid = fork ();
if ((*ctx)->pid < 0)
{
@ -173,111 +466,131 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
if ((*ctx)->pid == 0)
{
/* Intermediate child to prevent zombie processes. */
pid_t pid;
#ifdef _ASSUAN_USE_DOUBLE_FORK
if ((pid = fork ()) == 0)
#endif
{
/* Child. */
int i, n;
char errbuf[512];
int *fdp;
if (atfork)
atfork (atforkvalue, 0);
int i, n;
char errbuf[512];
int *fdp;
/* Dup handles to stdin/stdout. */
if (rp[1] != STDOUT_FILENO)
{
if (dup2 (rp[1], STDOUT_FILENO) == -1)
{
_assuan_log_printf ("dup2 failed in child: %s\n",
strerror (errno));
_exit (4);
}
}
if (wp[0] != STDIN_FILENO)
{
if (dup2 (wp[0], STDIN_FILENO) == -1)
{
_assuan_log_printf ("dup2 failed in child: %s\n",
strerror (errno));
_exit (4);
}
}
/* Dup handles to stdin/stdout. */
if (rp[1] != STDOUT_FILENO)
{
if (dup2 (rp[1], STDOUT_FILENO) == -1)
{
LOG ("dup2 failed in child: %s\n", strerror (errno));
_exit (4);
}
}
if (wp[0] != STDIN_FILENO)
{
if (dup2 (wp[0], STDIN_FILENO) == -1)
{
LOG ("dup2 failed in child: %s\n", strerror (errno));
_exit (4);
}
}
/* Dup stderr to /dev/null unless it is in the list of FDs to be
passed to the child. */
fdp = fd_child_list;
if (fdp)
{
for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++)
;
}
if (!fdp || *fdp == -1)
{
int fd = open ("/dev/null", O_WRONLY);
if (fd == -1)
{
LOG ("can't open `/dev/null': %s\n", strerror (errno));
_exit (4);
}
if (dup2 (fd, STDERR_FILENO) == -1)
{
LOG ("dup2(dev/null, 2) failed: %s\n", strerror (errno));
_exit (4);
}
}
/* Dup stderr to /dev/null unless it is in the list of FDs to be
passed to the child. */
fdp = fd_child_list;
if (fdp)
{
for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++)
;
}
if (!fdp || *fdp == -1)
{
int fd = open ("/dev/null", O_WRONLY);
if (fd == -1)
{
_assuan_log_printf ("can't open `/dev/null': %s\n",
strerror (errno));
_exit (4);
}
if (dup2 (fd, STDERR_FILENO) == -1)
{
_assuan_log_printf ("dup2(dev/null, 2) failed: %s\n",
strerror (errno));
_exit (4);
}
}
/* Close all files which will not be duped and are not in the
fd_child_list. */
n = sysconf (_SC_OPEN_MAX);
if (n < 0)
n = MAX_OPEN_FDS;
for (i=0; i < n; i++)
{
if ( i == STDIN_FILENO || i == STDOUT_FILENO || i == STDERR_FILENO)
continue;
fdp = fd_child_list;
if (fdp)
{
while (*fdp != -1 && *fdp != i)
fdp++;
}
if (!(fdp && *fdp != -1))
close(i);
}
/* Close all files which will not be duped and are not in the
fd_child_list. */
n = sysconf (_SC_OPEN_MAX);
if (n < 0)
n = MAX_OPEN_FDS;
for (i=0; i < n; i++)
{
if ( i == STDIN_FILENO || i == STDOUT_FILENO
|| i == STDERR_FILENO)
continue;
fdp = fd_child_list;
if (fdp)
{
while (*fdp != -1 && *fdp != i)
fdp++;
}
errno = 0;
if (!(fdp && *fdp != -1))
close(i);
}
errno = 0;
execv (name, argv);
/* oops - use the pipe to tell the parent about it */
snprintf (errbuf, sizeof(errbuf)-1, "ERR %d can't exec `%s': %.50s\n",
ASSUAN_Problem_Starting_Server, name, strerror (errno));
errbuf[sizeof(errbuf)-1] = 0;
writen (1, errbuf, strlen (errbuf));
_exit (4);
} /* End child. */
/* We store our parents pid in the environment so that the
execed assuan server is able to read the actual pid of the
client. The server can't use getppid becuase it might have
been double forked before the assuan server has been
initialized. */
setenv ("_assuan_pipe_connect_pid", mypidstr, 1);
execv (name, argv);
/* oops - use the pipe to tell the parent about it */
snprintf (errbuf, sizeof(errbuf)-1,
"ERR %d can't exec `%s': %.50s\n",
ASSUAN_Problem_Starting_Server, name, strerror (errno));
errbuf[sizeof(errbuf)-1] = 0;
writen (1, errbuf, strlen (errbuf));
_exit (4);
}
#ifdef _ASSUAN_USE_DOUBLE_FORK
if (pid == -1)
_exit (1);
else
_exit (0);
#endif
}
#ifdef _ASSUAN_USE_DOUBLE_FORK
waitpid ((*ctx)->pid, NULL, 0);
(*ctx)->pid = -1;
#endif
close (rp[1]);
close (wp[0]);
#endif /*!HAVE_W32_SYSTEM*/
/* initial handshake */
{
int okay, off;
err = _assuan_read_from_server (*ctx, &okay, &off);
if (err)
LOG ("can't connect server: %s\n", assuan_strerror (err));
_assuan_log_printf ("can't connect server: %s\n",
assuan_strerror (err));
else if (okay != 1)
{
LOG ("can't connect server: `%s'\n", (*ctx)->inbound.line);
_assuan_log_printf ("can't connect server: `%s'\n",
(*ctx)->inbound.line);
err = ASSUAN_Connect_Failed;
}
}
@ -292,15 +605,13 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
}
/* Connect to a server over a pipe, creating the assuan context and
returning it in CTX. The server filename is NAME, the argument
vector in ARGV. FD_CHILD_LIST is a -1 terminated list of file
descriptors not to close in the child. */
assuan_error_t
assuan_pipe_connect (assuan_context_t *ctx, const char *name, char *const argv[],
int *fd_child_list)
{
return assuan_pipe_connect2 (ctx, name, argv, fd_child_list, NULL, NULL);
}

View File

@ -22,9 +22,14 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#ifdef HAVE_W32_SYSTEM
#include <windows.h>
#include <fcntl.h>
#endif
#include "assuan-defs.h"
static void
deinit_pipe_server (ASSUAN_CONTEXT ctx)
{
@ -69,7 +74,6 @@ _assuan_new_context (ASSUAN_CONTEXT *r_ctx)
ctx->io = &io;
ctx->listen_fd = -1;
ctx->client_pid = (pid_t)-1;
/* Use the pipe server handler as a default. */
ctx->deinit_handler = deinit_pipe_server;
ctx->accept_handler = accept_connection;
@ -84,7 +88,6 @@ _assuan_new_context (ASSUAN_CONTEXT *r_ctx)
}
int
assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
{
@ -94,11 +97,30 @@ assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
if (!rc)
{
ASSUAN_CONTEXT ctx = *r_ctx;
const char *s;
unsigned long ul;
ctx->is_server = 1;
ctx->inbound.fd = filedes[0];
#ifdef HAVE_W32_SYSTEM
/* MS Windows has so many different types of handle that one
needs to tranlsate them at many place forth and back. Also
make sure that the fiel descriptos are in binary mode. */
setmode (filedes[0], O_BINARY);
setmode (filedes[1], O_BINARY);
ctx->inbound.fd = _get_osfhandle (filedes[0]);
ctx->outbound.fd = _get_osfhandle (filedes[1]);
#else
ctx->inbound.fd = filedes[0];
ctx->outbound.fd = filedes[1];
#endif
ctx->pipe_mode = 1;
s = getenv ("_assuan_pipe_connect_pid");
if (s && (ul=strtoul (s, NULL, 10)) && ul)
ctx->pid = (pid_t)ul;
else
ctx->pid = (pid_t)-1;
}
return rc;
}

View File

@ -1,5 +1,5 @@
/* assuan-socket-connect.c - Assuan socket based client
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -22,25 +22,43 @@
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#ifndef HAVE_W32_SYSTEM
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#else
#include <windows.h>
#endif
#include "assuan-defs.h"
#define LOG(format, args...) \
fprintf (assuan_get_assuan_log_stream (), \
assuan_get_assuan_log_prefix (), \
"%s" format , ## args)
/* Hacks for Slowaris. */
#ifndef PF_LOCAL
# ifdef PF_UNIX
# define PF_LOCAL PF_UNIX
# else
# define PF_LOCAL AF_UNIX
# endif
#endif
#ifndef AF_LOCAL
# define AF_LOCAL AF_UNIX
#endif
#ifndef SUN_LEN
# define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
+ strlen ((ptr)->sun_path))
#endif
static int
do_finish (ASSUAN_CONTEXT ctx)
{
if (ctx->inbound.fd != -1)
{
close (ctx->inbound.fd);
_assuan_close (ctx->inbound.fd);
}
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
@ -55,56 +73,64 @@ do_deinit (ASSUAN_CONTEXT ctx)
/* Make a connection to the Unix domain socket NAME and return a new
Assuan context in CTX. SERVER_PID is currently not used but may
become handy in the future. */
AssuanError
assuan_error_t
assuan_socket_connect (ASSUAN_CONTEXT *r_ctx,
const char *name, pid_t server_pid)
{
static struct assuan_io io = { _assuan_simple_read,
_assuan_simple_write };
AssuanError err;
assuan_error_t err;
ASSUAN_CONTEXT ctx;
int fd;
struct sockaddr_un srvr_addr;
size_t len;
const char *s;
if (!r_ctx || !name)
return ASSUAN_Invalid_Value;
*r_ctx = NULL;
/* we require that the name starts with a slash, so that we can
alter reuse this function for other socket types */
if (*name != '/')
/* We require that the name starts with a slash, so that we can
alter reuse this function for other socket types. To make things
easier we allow an optional dirver prefix. */
s = name;
if (*s && s[1] == ':')
s += 2;
if (*s != DIRSEP_C && *s != '/')
return ASSUAN_Invalid_Value;
if (strlen (name)+1 >= sizeof srvr_addr.sun_path)
return ASSUAN_Invalid_Value;
err = _assuan_new_context (&ctx);
if (err)
return err;
ctx->pid = server_pid; /* save it in case we need it later */
ctx->deinit_handler = do_deinit;
ctx->finish_handler = do_finish;
fd = socket (PF_LOCAL, SOCK_STREAM, 0);
fd = _assuan_sock_new (PF_LOCAL, SOCK_STREAM, 0);
if (fd == -1)
{
LOG ("can't create socket: %s\n", strerror (errno));
_assuan_log_printf ("can't create socket: %s\n", strerror (errno));
_assuan_release_context (ctx);
return ASSUAN_General_Error;
}
memset (&srvr_addr, 0, sizeof srvr_addr);
srvr_addr.sun_family = AF_LOCAL;
len = strlen (srvr_addr.sun_path) + 1;
memcpy (srvr_addr.sun_path, name, len);
len += (offsetof (struct sockaddr_un, sun_path));
strncpy (srvr_addr.sun_path, name, sizeof (srvr_addr.sun_path) - 1);
srvr_addr.sun_path[sizeof (srvr_addr.sun_path) - 1] = 0;
len = SUN_LEN (&srvr_addr);
if (connect (fd, (struct sockaddr *) &srvr_addr, len) == -1)
if (_assuan_sock_connect (fd, (struct sockaddr *) &srvr_addr, len) == -1)
{
LOG ("can't connect to `%s': %s\n", name, strerror (errno));
_assuan_log_printf ("can't connect to `%s': %s\n",
name, strerror (errno));
_assuan_release_context (ctx);
close (fd);
_assuan_close (fd);
return ASSUAN_Connect_Failed;
}
@ -118,10 +144,11 @@ assuan_socket_connect (ASSUAN_CONTEXT *r_ctx,
err = _assuan_read_from_server (ctx, &okay, &off);
if (err)
LOG ("can't connect to server: %s\n", assuan_strerror (err));
_assuan_log_printf ("can't connect to server: %s\n",
assuan_strerror (err));
else if (okay != 1)
{
LOG ("can't connect to server: `");
/*LOG ("can't connect to server: `");*/
_assuan_log_sanitized_string (ctx->inbound.line);
fprintf (assuan_get_assuan_log_stream (), "'\n");
err = ASSUAN_Connect_Failed;

View File

@ -22,26 +22,32 @@
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#ifndef HAVE_W32_SYSTEM
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#else
#include <windows.h>
#endif
#include "assuan-defs.h"
static int
accept_connection_bottom (ASSUAN_CONTEXT ctx)
accept_connection_bottom (assuan_context_t ctx)
{
int fd = ctx->connected_fd;
ctx->client_pid = (pid_t)-1;
#ifdef HAVE_SO_PEERCRED
{
/* This overrides any already set PID if the function returns a
valid one. */
struct ucred cr;
int cl = sizeof cr;
if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) )
ctx->client_pid = cr.pid;
if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl)
&& cr.pid != (pid_t)-1 && cr.pid )
ctx->pid = cr.pid;
}
#endif
@ -62,13 +68,12 @@ accept_connection_bottom (ASSUAN_CONTEXT ctx)
static int
accept_connection (ASSUAN_CONTEXT ctx)
accept_connection (assuan_context_t ctx)
{
int fd;
struct sockaddr_un clnt_addr;
size_t len = sizeof clnt_addr;
ctx->client_pid = (pid_t)-1;
fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
if (fd == -1)
{
@ -81,11 +86,11 @@ accept_connection (ASSUAN_CONTEXT ctx)
}
static int
finish_connection (ASSUAN_CONTEXT ctx)
finish_connection (assuan_context_t ctx)
{
if (ctx->inbound.fd != -1)
{
close (ctx->inbound.fd);
_assuan_close (ctx->inbound.fd);
}
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
@ -94,7 +99,7 @@ finish_connection (ASSUAN_CONTEXT ctx)
static void
deinit_socket_server (ASSUAN_CONTEXT ctx)
deinit_socket_server (assuan_context_t ctx)
{
finish_connection (ctx);
}
@ -105,9 +110,9 @@ static struct assuan_io io = { _assuan_simple_read,
/* Initialize a server for the socket LISTEN_FD which has already be
put into listen mode */
int
assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd)
assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd)
{
ASSUAN_CONTEXT ctx;
assuan_context_t ctx;
int rc;
*r_ctx = NULL;
@ -139,9 +144,9 @@ assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd)
/* Initialize a server using the already accepted socket FD. */
int
assuan_init_connected_socket_server (ASSUAN_CONTEXT *r_ctx, int fd)
assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd)
{
ASSUAN_CONTEXT ctx;
assuan_context_t ctx;
int rc;
*r_ctx = NULL;

View File

@ -1,5 +1,5 @@
/* assuan-util.c - Utility functions for Assuan
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
* Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -23,6 +23,7 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "assuan-defs.h"
@ -55,9 +56,19 @@ _assuan_realloc (void *a, size_t n)
void *
_assuan_calloc (size_t n, size_t m)
{
void *p = _assuan_malloc (n*m);
void *p;
size_t nbytes;
nbytes = n * m;
if (m && nbytes / m != n)
{
errno = ENOMEM;
return NULL;
}
p = _assuan_malloc (nbytes);
if (p)
memset (p, 0, n* m);
memset (p, 0, nbytes);
return p;
}
@ -73,7 +84,7 @@ _assuan_free (void *p)
can take out a descriptive text. Inside the assuan code, use the
macro set_error instead of this function. */
int
assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text)
assuan_set_error (assuan_context_t ctx, int err, const char *text)
{
ctx->err_no = err;
ctx->err_str = text;
@ -81,33 +92,34 @@ assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text)
}
void
assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer)
assuan_set_pointer (assuan_context_t ctx, void *pointer)
{
if (ctx)
ctx->user_pointer = pointer;
}
void *
assuan_get_pointer (ASSUAN_CONTEXT ctx)
assuan_get_pointer (assuan_context_t ctx)
{
return ctx? ctx->user_pointer : NULL;
}
void
assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp)
assuan_set_log_stream (assuan_context_t ctx, FILE *fp)
{
if (ctx)
{
if (ctx->log_fp)
fflush (ctx->log_fp);
ctx->log_fp = fp;
_assuan_set_default_log_stream (fp);
}
}
void
assuan_begin_confidential (ASSUAN_CONTEXT ctx)
assuan_begin_confidential (assuan_context_t ctx)
{
if (ctx)
{
@ -116,7 +128,7 @@ assuan_begin_confidential (ASSUAN_CONTEXT ctx)
}
void
assuan_end_confidential (ASSUAN_CONTEXT ctx)
assuan_end_confidential (assuan_context_t ctx)
{
if (ctx)
{
@ -124,6 +136,36 @@ assuan_end_confidential (ASSUAN_CONTEXT ctx)
}
}
/* 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;
see the description of the type assuan_flag_t for details. */
void
assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value)
{
if (!ctx)
return;
switch (flag)
{
case ASSUAN_NO_WAITPID: ctx->flags.no_waitpid = value; break;
}
}
/* Return the VALUE of FLAG in context CTX. */
int
assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag)
{
if (!ctx)
return 0;
switch (flag)
{
case ASSUAN_NO_WAITPID: return ctx->flags.no_waitpid;
}
return 0;
}
/* Dump a possibly binary string (used for debugging). Distinguish
ascii text from binary and print it accordingly. */
void
@ -133,7 +175,7 @@ _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
int n;
for (n=length,s=buffer; n; n--, s++)
if (!isascii (*s) || iscntrl (*s) || !isprint (*s))
if ((!isascii (*s) || iscntrl (*s) || !isprint (*s)) && !(*s >= 0x80))
break;
s = buffer;
@ -197,7 +239,7 @@ _assuan_log_sanitized_string (const char *string)
break;
default:
if (isascii (*s) && isprint (*s))
if ((isascii (*s) && isprint (*s)) || (*s >= 0x80))
putc_unlocked (*s, fp);
else
{
@ -217,3 +259,4 @@ _assuan_log_sanitized_string (const char *string)
funlockfile (fp);
#endif
}

View File

@ -1,5 +1,5 @@
/* assuan.c - Definitions for the Assuan protocol
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
/* assuan.c - Definitions for the Assuan IPC library
* Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -25,22 +25,46 @@
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#define _ASSUAN_IN_GPGME
#ifdef _ASSUAN_IN_GPGME
/* To use this file with libraries the following macros are often
useful:
#define _ASSUAN_EXT_SYM_PREFIX _foo_
This prefixes all external symbols with "_foo_".
#define _ASSUAN_NO_PTH
This avoids inclusion of special GNU Pth hacks.
#define _ASSUAN_NO_FIXED_SIGNALS
This disables changing of certain signal handler; i.e. SIGPIPE.
#define _ASSUAN_USE_DOUBLE_FORK
Use a double fork approach when connecting to a server through a pipe.
*/
/**** Begin GPGME specific modifications. ******/
#define _ASSUAN_EXT_SYM_PREFIX _gpgme_
#define _ASSUAN_NO_PTH
#define _ASSUAN_NO_FIXED_SIGNALS
#define _ASSUAN_USE_DOUBLE_FORK
#ifdef _ASSUAN_IN_GPGME_BUILD_ASSUAN
int _gpgme_io_read (int fd, void *buffer, size_t count);
int _gpgme_io_write (int fd, const void *buffer, size_t count);
ssize_t _gpgme_ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout);
ssize_t _gpgme_ath_waitpid (pid_t pid, int *status, int options);
#ifdef HAVE_W32_SYSTEM
int _gpgme_ath_accept (int s, void *addr, int *length_ptr);
#else /*!HAVE_W32_SYSTEM*/
ssize_t _gpgme_ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
struct timeval *timeout);
int _gpgme_ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr);
int _gpgme_ath_connect (int s, struct sockaddr *addr, socklen_t length);
int _gpgme_ath_sendmsg (int s, const struct msghdr *msg, int flags);
int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags);
#endif /*!HAVE_W32_SYSTEM*/
#define read _gpgme_io_read
#define write _gpgme_io_write
@ -50,8 +74,9 @@ int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags);
#define connect _gpgme_ath_connect
#define sendmsg _gpgme_ath_sendmsg
#define recvmsg _gpgme_ath_recvmsg
#endif
#endif
#endif /*_ASSUAN_IN_GPGME_BUILD_ASSUAN*/
/**** End GPGME specific modifications. ******/
#ifdef _ASSUAN_EXT_SYM_PREFIX
#define _ASSUAN_PREFIX1(x,y) x ## y
@ -116,6 +141,8 @@ int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags);
_ASSUAN_PREFIX(assuan_get_assuan_log_stream)
#define assuan_get_assuan_log_prefix \
_ASSUAN_PREFIX(assuan_get_assuan_log_prefix)
#define assuan_set_flag _ASSUAN_PREFIX(assuan_set_flag)
#define assuan_get_flag _ASSUAN_PREFIX(assuan_get_flag)
/* And now the internal functions, argh... */
#define _assuan_read_line _ASSUAN_PREFIX(_assuan_read_line)
@ -138,14 +165,27 @@ int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags);
#define _assuan_log_print_buffer _ASSUAN_PREFIX(_assuan_log_print_buffer)
#define _assuan_log_sanitized_string \
_ASSUAN_PREFIX(_assuan_log_sanitized_string)
#define _assuan_log_printf _ASSUAN_PREFIX(_assuan_log_printf)
#define _assuan_set_default_log_stream \
_ASSUAN_PREFIX(_assuan_set_default_log_stream)
#define _assuan_w32_strerror _ASSUAN_PREFIX(_assuan_w32_strerror)
#define _assuan_write_line _ASSUAN_PREFIX(_assuan_write_line)
#define _assuan_close _ASSUAN_PREFIX(_assuan_close)
#define _assuan_sock_new _ASSUAN_PREFIX(_assuan_sock_new)
#define _assuan_sock_bind _ASSUAN_PREFIX(_assuan_sock_bind)
#define _assuan_sock_connect _ASSUAN_PREFIX(_assuan_sock_connect)
#endif /*_ASSUAN_EXT_SYM_PREFIX*/
#endif
#ifdef __cplusplus
extern "C"
{
#if 0
}
#endif
#endif
typedef enum
{
@ -166,7 +206,7 @@ typedef enum
ASSUAN_Connect_Failed = 14,
ASSUAN_Accept_Failed = 15,
/* error codes above 99 are meant as status codes */
/* Error codes above 99 are meant as status codes */
ASSUAN_Not_Implemented = 100,
ASSUAN_Server_Fault = 101,
ASSUAN_Invalid_Command = 102,
@ -194,9 +234,10 @@ typedef enum
ASSUAN_Unexpected_Status = 124,
ASSUAN_Unexpected_Data = 125,
ASSUAN_Invalid_Status = 126,
ASSUAN_Locale_Problem = 127,
ASSUAN_Not_Confirmed = 128,
/* Warning: Don't use the rror codes, below they are deprecated. */
ASSUAN_Bad_Certificate = 201,
ASSUAN_Bad_Certificate_Chain = 202,
ASSUAN_Missing_Certificate = 203,
@ -216,11 +257,20 @@ typedef enum
ASSUAN_Invalid_Card = 402,
ASSUAN_No_PKCS15_App = 403,
ASSUAN_Card_Not_Present = 404,
ASSUAN_Invalid_Id = 405
ASSUAN_Invalid_Id = 405,
} AssuanError;
/* Error codes in the range 1000 to 9999 may be used by applications
at their own discretion. */
ASSUAN_USER_ERROR_FIRST = 1000,
ASSUAN_USER_ERROR_LAST = 9999
} assuan_error_t;
typedef assuan_error_t AssuanError; /* Deprecated. */
/* This is a list of pre-registered ASSUAN commands */
/* NOTE, these command IDs are now deprectated and solely exists for
compatibility reasons. */
typedef enum
{
ASSUAN_CMD_NOP = 0,
@ -237,72 +287,90 @@ typedef enum
ASSUAN_CMD_USER = 256 /* Other commands should be used with this offset*/
} AssuanCommand;
/* Definitions of flags for assuan_set_flag(). */
typedef enum
{
/* When using a pipe server, by default Assuan will wait for the
forked process to die in assuan_disconnect. In certain cases
this is not desirable. By setting this flag, the waitpid will
be skipped and the caller is responsible to cleanup a forked
process. */
ASSUAN_NO_WAITPID = 1
}
assuan_flag_t;
#define ASSUAN_LINELENGTH 1002 /* 1000 + [CR,]LF */
struct assuan_context_s;
typedef struct assuan_context_s *assuan_context_t;
typedef struct assuan_context_s *ASSUAN_CONTEXT;
/*-- assuan-handler.c --*/
int assuan_register_command (ASSUAN_CONTEXT ctx,
int assuan_register_command (assuan_context_t ctx,
const char *cmd_string,
int (*handler)(ASSUAN_CONTEXT, char *));
int assuan_register_bye_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT));
int assuan_register_reset_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT));
int assuan_register_cancel_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT));
int assuan_register_input_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT, const char *));
int assuan_register_output_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT, const char *));
int (*handler)(assuan_context_t, char *));
int assuan_register_bye_notify (assuan_context_t ctx,
void (*fnc)(assuan_context_t));
int assuan_register_reset_notify (assuan_context_t ctx,
void (*fnc)(assuan_context_t));
int assuan_register_cancel_notify (assuan_context_t ctx,
void (*fnc)(assuan_context_t));
int assuan_register_input_notify (assuan_context_t ctx,
void (*fnc)(assuan_context_t, const char *));
int assuan_register_output_notify (assuan_context_t ctx,
void (*fnc)(assuan_context_t, const char *));
int assuan_register_option_handler (ASSUAN_CONTEXT ctx,
int (*fnc)(ASSUAN_CONTEXT,
int assuan_register_option_handler (assuan_context_t ctx,
int (*fnc)(assuan_context_t,
const char*, const char*));
int assuan_process (ASSUAN_CONTEXT ctx);
int assuan_process_next (ASSUAN_CONTEXT ctx);
int assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what,
int assuan_process (assuan_context_t ctx);
int assuan_process_next (assuan_context_t ctx);
int assuan_get_active_fds (assuan_context_t ctx, int what,
int *fdarray, int fdarraysize);
FILE *assuan_get_data_fp (ASSUAN_CONTEXT ctx);
AssuanError assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line);
void assuan_write_status (ASSUAN_CONTEXT ctx,
const char *keyword, const char *text);
FILE *assuan_get_data_fp (assuan_context_t ctx);
assuan_error_t assuan_set_okay_line (assuan_context_t ctx, const char *line);
assuan_error_t assuan_write_status (assuan_context_t ctx,
const char *keyword, const char *text);
/* Negotiate a file descriptor. If LINE contains "FD=N", returns N
assuming a local file descriptor. If LINE contains "FD" reads a
file descriptor via CTX and stores it in *RDF (the CTX must be
capable of passing file descriptors). */
AssuanError assuan_command_parse_fd (ASSUAN_CONTEXT ctx, char *line,
assuan_error_t assuan_command_parse_fd (assuan_context_t ctx, char *line,
int *rfd);
/*-- assuan-listen.c --*/
AssuanError assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line);
AssuanError assuan_accept (ASSUAN_CONTEXT ctx);
int assuan_get_input_fd (ASSUAN_CONTEXT ctx);
int assuan_get_output_fd (ASSUAN_CONTEXT ctx);
AssuanError assuan_close_input_fd (ASSUAN_CONTEXT ctx);
AssuanError assuan_close_output_fd (ASSUAN_CONTEXT ctx);
assuan_error_t assuan_set_hello_line (assuan_context_t ctx, const char *line);
assuan_error_t assuan_accept (assuan_context_t ctx);
int assuan_get_input_fd (assuan_context_t ctx);
int assuan_get_output_fd (assuan_context_t ctx);
assuan_error_t assuan_close_input_fd (assuan_context_t ctx);
assuan_error_t assuan_close_output_fd (assuan_context_t ctx);
/*-- assuan-pipe-server.c --*/
int assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2]);
void assuan_deinit_server (ASSUAN_CONTEXT ctx);
int assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2]);
void assuan_deinit_server (assuan_context_t ctx);
/*-- assuan-socket-server.c --*/
int assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd);
int assuan_init_connected_socket_server (ASSUAN_CONTEXT *r_ctx, int fd);
int assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd);
int assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd);
/*-- assuan-pipe-connect.c --*/
AssuanError assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name,
assuan_error_t assuan_pipe_connect (assuan_context_t *ctx, const char *name,
char *const argv[], int *fd_child_list);
assuan_error_t assuan_pipe_connect2 (assuan_context_t *ctx, const char *name,
char *const argv[], int *fd_child_list,
void (*atfork) (void*, int),
void *atforkvalue);
/*-- assuan-socket-connect.c --*/
AssuanError assuan_socket_connect (ASSUAN_CONTEXT *ctx, const char *name,
pid_t server_pid);
assuan_error_t assuan_socket_connect (assuan_context_t *ctx, const char *name,
pid_t server_pid);
/*-- assuan-domain-connect.c --*/
@ -310,7 +378,7 @@ AssuanError assuan_socket_connect (ASSUAN_CONTEXT *ctx, const char *name,
bidirectional file descriptor (normally returned via socketpair)
which the client can use to rendezvous with the server. SERVER s
the server's pid. */
AssuanError assuan_domain_connect (ASSUAN_CONTEXT *r_ctx,
assuan_error_t assuan_domain_connect (assuan_context_t *r_ctx,
int rendezvousfd,
pid_t server);
@ -319,74 +387,93 @@ AssuanError assuan_domain_connect (ASSUAN_CONTEXT *r_ctx,
/* RENDEZVOUSFD is a bidirectional file descriptor (normally returned
via socketpair) that the domain server can use to rendezvous with
the client. CLIENT is the client's pid. */
AssuanError assuan_init_domain_server (ASSUAN_CONTEXT *r_ctx,
assuan_error_t assuan_init_domain_server (assuan_context_t *r_ctx,
int rendezvousfd,
pid_t client);
/*-- assuan-connect.c --*/
void assuan_disconnect (ASSUAN_CONTEXT ctx);
pid_t assuan_get_pid (ASSUAN_CONTEXT ctx);
void assuan_disconnect (assuan_context_t ctx);
pid_t assuan_get_pid (assuan_context_t ctx);
/*-- assuan-client.c --*/
AssuanError
assuan_transact (ASSUAN_CONTEXT ctx,
assuan_error_t
assuan_transact (assuan_context_t ctx,
const char *command,
AssuanError (*data_cb)(void *, const void *, size_t),
assuan_error_t (*data_cb)(void *, const void *, size_t),
void *data_cb_arg,
AssuanError (*inquire_cb)(void*, const char *),
assuan_error_t (*inquire_cb)(void*, const char *),
void *inquire_cb_arg,
AssuanError (*status_cb)(void*, const char *),
assuan_error_t (*status_cb)(void*, const char *),
void *status_cb_arg);
/*-- assuan-inquire.c --*/
AssuanError assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
char **r_buffer, size_t *r_length, size_t maxlen);
assuan_error_t assuan_inquire (assuan_context_t ctx, const char *keyword,
unsigned char **r_buffer, size_t *r_length,
size_t maxlen);
/*-- assuan-buffer.c --*/
AssuanError assuan_read_line (ASSUAN_CONTEXT ctx,
assuan_error_t assuan_read_line (assuan_context_t ctx,
char **line, size_t *linelen);
int assuan_pending_line (ASSUAN_CONTEXT ctx);
AssuanError assuan_write_line (ASSUAN_CONTEXT ctx, const char *line );
AssuanError assuan_send_data (ASSUAN_CONTEXT ctx,
int assuan_pending_line (assuan_context_t ctx);
assuan_error_t assuan_write_line (assuan_context_t ctx, const char *line );
assuan_error_t assuan_send_data (assuan_context_t ctx,
const void *buffer, size_t length);
/* The file descriptor must be pending before assuan_receivefd is
call. This means that assuan_sendfd should be called *before* the
trigger is sent (normally via assuan_send_data ("I sent you a
descriptor")). */
AssuanError assuan_sendfd (ASSUAN_CONTEXT ctx, int fd);
AssuanError assuan_receivefd (ASSUAN_CONTEXT ctx, int *fd);
assuan_error_t assuan_sendfd (assuan_context_t ctx, int fd);
assuan_error_t assuan_receivefd (assuan_context_t ctx, int *fd);
/*-- assuan-util.c --*/
void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
void *(*new_realloc_func)(void *p, size_t n),
void (*new_free_func)(void*) );
void assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp);
int assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text);
void assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer);
void *assuan_get_pointer (ASSUAN_CONTEXT ctx);
void assuan_set_log_stream (assuan_context_t ctx, FILE *fp);
int assuan_set_error (assuan_context_t ctx, int err, const char *text);
void assuan_set_pointer (assuan_context_t ctx, void *pointer);
void *assuan_get_pointer (assuan_context_t ctx);
void assuan_begin_confidential (assuan_context_t ctx);
void assuan_end_confidential (assuan_context_t ctx);
/* 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;
see the description of the type assuan_flag_t for details. */
void assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value);
/* Return the VALUE of FLAG in context CTX. */
int assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag);
void assuan_begin_confidential (ASSUAN_CONTEXT ctx);
void assuan_end_confidential (ASSUAN_CONTEXT ctx);
/*-- assuan-errors.c (built) --*/
const char *assuan_strerror (AssuanError err);
const char *assuan_strerror (assuan_error_t err);
/*-- assuan-logging.c --*/
/* Set the stream to which assuan should log. By default, this is
stderr. */
/* Set the stream to which assuan should log message not associated
with a context. By default, this is stderr. The default value
will be changed when the first log stream is associated with a
context. Note, that this function is not thread-safe and should
in general be used right at startup. */
extern void assuan_set_assuan_log_stream (FILE *fp);
/* Return the stream which is currently being using for logging. */
/* Return the stream which is currently being using for global logging. */
extern FILE *assuan_get_assuan_log_stream (void);
/* User defined call back. Return a prefix to be used at the start of
a line emitted by assuan on the log stream. The default
implementation returns the empty string, i.e. "" */
extern const char *assuan_get_assuan_log_prefix (void);
/* Set the prefix to be used at the start of a line emitted by assuan
on the log stream. The default is the empty string. Note, that
this function is not thread-safe and should in general be used
right at startup. */
void assuan_set_assuan_log_prefix (const char *text);
/* Return a prefix to be used at the start of a line emitted by assuan
on the log stream. The default implementation returns the empty
string, i.e. "" */
const char *assuan_get_assuan_log_prefix (void);
#ifdef __cplusplus
}

View File

@ -23,6 +23,10 @@ cat <<EOF
/* Generated automatically by mkerrors */
/* Do not edit! */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include "assuan.h"

View File

@ -169,7 +169,7 @@ fi
# Checks for library functions.
AC_FUNC_FSEEKO
AC_REPLACE_FUNCS(stpcpy)
AC_CHECK_FUNCS(stpcpy)
AC_REPLACE_FUNCS(vasprintf)
if test "$ac_cv_func_vasprintf" != yes; then

View File

@ -1,3 +1,10 @@
2005-08-08 Werner Koch <wk@g10code.com>
* util.h (stpcpy): Renamed to ..
(_gpgme_stpcpy): .. this and made inline. This avoids duplicate
definitions when linking statically.
* stpcpy.c: Removed.
2005-07-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.h (gpgme_status_code_t): Add GPGME_STATUS_PLAINTEXT.

View File

@ -1,6 +1,6 @@
/* util.h
Copyright (C) 2000 Werner Koch (dd9jn)
Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH
Copyright (C) 2001, 2002, 2003, 2004, 2005 g10 Code GmbH
This file is part of GPGME.
@ -35,9 +35,18 @@ const char *_gpgme_get_gpgsm_path (void);
/*-- replacement functions in <funcname>.c --*/
#ifdef HAVE_CONFIG_H
#ifndef HAVE_STPCPY
char *stpcpy (char *a, const char *b);
#endif
static _GPGME_INLINE char *
_gpgme_stpcpy (char *a, const char *b)
{
while (*b)
*a++ = *b++;
*a = 0;
return a;
}
#define stpcpy(a,b) _gpgme_stpcpy ((a), (b))
#endif /*!HAVE_STPCPY*/
#if !HAVE_VASPRINTF
#include <stdarg.h>