Merged changes from upstream libassuan to allow building a W32 DLL.
This commit is contained in:
parent
7bdaf53a4a
commit
b71096a832
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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*/
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
249
assuan/assuan.h
249
assuan/assuan.h
@ -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
|
||||
}
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
15
gpgme/util.h
15
gpgme/util.h
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user