2003-08-18 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: If building Assuan, check for funopen and fopencookie, and make isascii, putc_unlocked and memrchr replacement functions. assuan/ Update to the latest assuan version. gpgme/ 2003-08-18 Marcus Brinkmann <marcus@g10code.de> * funopen.c, putc_unlocked.c, isascii.c, memrchr.c: New files. * fopencookie.c: File removed.
This commit is contained in:
parent
c1ae70b177
commit
c93237c3a4
@ -1,3 +1,9 @@
|
|||||||
|
2003-08-18 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* configure.ac: If building Assuan, check for funopen and
|
||||||
|
fopencookie, and make isascii, putc_unlocked and memrchr
|
||||||
|
replacement functions.
|
||||||
|
|
||||||
2003-07-31 Marcus Brinkmann <marcus@g10code.de>
|
2003-07-31 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* configure.ac (AC_INIT): Bump version to 0.4.3.
|
* configure.ac (AC_INIT): Bump version to 0.4.3.
|
||||||
|
211
assuan/ChangeLog
211
assuan/ChangeLog
@ -1,3 +1,209 @@
|
|||||||
|
2003-08-13 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* assuan-inquire.c (assuan_inquire): Increase length of cmdbuf to
|
||||||
|
the Assuan limit.
|
||||||
|
|
||||||
|
2003-06-24 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* mkerrors: Kludge to print libgpg-error values in an easier
|
||||||
|
readable way.
|
||||||
|
|
||||||
|
2003-04-29 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
|
* libassuan.m4: New. Based on libgrypt.m4.
|
||||||
|
* Makefile.am (m4data_DATA): New.
|
||||||
|
|
||||||
|
* assuan.h (AssuanCommand): Removed.
|
||||||
|
|
||||||
|
* assuan-handler.c: Remove the cmd_id element,
|
||||||
|
(assuan_register_command): Likewise. Note that semantics changed.
|
||||||
|
(_assuan_register_std_commands): Adjusted.
|
||||||
|
|
||||||
|
2003-02-22 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* Makefile.am (bin_SCRIPTS): Renamed from bin_PROGRAMS.
|
||||||
|
|
||||||
|
2003-02-18 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* Makefile.am (libassuan_a_LIBADD): New variable.
|
||||||
|
* funopen.c: Move from ../common.
|
||||||
|
* isascii.c: Likewise.
|
||||||
|
* memrchr.c: Likewise.
|
||||||
|
* putc_unlocked.c: Likewise.
|
||||||
|
|
||||||
|
2003-02-18 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* assuan-handler.c (_IO_cookie_io_functions_t): Remove.
|
||||||
|
(cookie_io_functions_t): Remove.
|
||||||
|
(fopencookie): Remove prototype.
|
||||||
|
(assuan_get_data_fp): Use funopen, not fopencookie.
|
||||||
|
|
||||||
|
2003-02-18 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* libassuan-config.in: New file.
|
||||||
|
* Makefile.am (bin_PROGRAMS): New variable.
|
||||||
|
|
||||||
|
2003-02-17 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* .cvsignore: New file.
|
||||||
|
|
||||||
|
2003-02-17 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* Makefile.am (lib_LIBRARIES): Use this instead of . . .
|
||||||
|
(noinst_LIBRARIES): . . . this.
|
||||||
|
(include_HEADERS): New variable.
|
||||||
|
(libassuan_a_SOURCES): Remove assuan.h, add assuan-logging.c.
|
||||||
|
|
||||||
|
* assuan.h (assuan_set_assuan_log_stream): New prototype.
|
||||||
|
(assuan_get_assuan_log_stream): Likewise.
|
||||||
|
(assuan_get_assuan_log_prefix): Likewise.
|
||||||
|
* assuan-logging.c: New file.
|
||||||
|
|
||||||
|
* assuan-buffer.c [HAVE_JNLIB_LOGGIN]: Do not include
|
||||||
|
"../jnlib/logging.h".
|
||||||
|
(my_log_prefix): Remove function.
|
||||||
|
(_assuan_read_line): Use assuan_get_assuan_log_prefix in lieu of
|
||||||
|
my_log_prefix.
|
||||||
|
(assuan_write_line): Likewise.
|
||||||
|
(_assuan_cookie_write_data): Likewise.
|
||||||
|
(_assuan_cookie_write_flush): Likewise.
|
||||||
|
* assuan-domain-connect.c (LOGERROR, LOGERROR1, LOGERROR2,
|
||||||
|
LOGERRORX): Remove.
|
||||||
|
(LOG): New macro.
|
||||||
|
(domain_reader): Use it.
|
||||||
|
(domain_writer): Likewise.
|
||||||
|
(domain_sendfd): Likewise.
|
||||||
|
(domain_receivefd): Likewise.
|
||||||
|
(_assuan_domain_init): Likewise.
|
||||||
|
(assuan_domain_connect): Likewise.
|
||||||
|
* assuan-pipe-connect.c [HAVE_JNLIB_LOGGIN]: Do not include
|
||||||
|
"../jnlib/logging.h".
|
||||||
|
(LOGERROR, LOGERROR1, LOGERROR2, LOGERRORX): Remove.
|
||||||
|
(LOG): New macro.
|
||||||
|
(assuan_pipe_connect): Use it.
|
||||||
|
* assuan-socket-connect.c [HAVE_JNLIB_LOGGIN]: Do not include
|
||||||
|
"../jnlib/logging.h".
|
||||||
|
(LOGERROR, LOGERROR1, LOGERROR2, LOGERRORX): Remove.
|
||||||
|
(LOG): New macro.
|
||||||
|
(assuan_socket_connect): Use it.
|
||||||
|
(socket_reader): Remove dead code.
|
||||||
|
(socket_writer): Likewise.
|
||||||
|
* assuan-util.c [HAVE_JNLIB_LOGGIN]: Do not include
|
||||||
|
"../jnlib/logging.h".
|
||||||
|
(_assuan_log_sanitized_string): Use assuan_get_assuan_log_stream,
|
||||||
|
not jnlib.
|
||||||
|
|
||||||
|
2002-11-24 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* assuan.h (assuan_command_parse_fd): New prototype.
|
||||||
|
* assuan-handler.c (assuan_command_parse_fd): Rename from
|
||||||
|
parse_cmd_input_output. Export.
|
||||||
|
(std_handler_input): Update to use assuan_command_parse_fd.
|
||||||
|
(std_handler_output): Likewise.
|
||||||
|
|
||||||
|
2002-11-24 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* assuan.h (assuan_sendfd): New prototype.
|
||||||
|
(assuan_receivefd): New prototype.
|
||||||
|
* assuan-buffer.c (assuan_sendfd): New function.
|
||||||
|
(assuan_receivefd): New function.
|
||||||
|
* assuan-handler.c (parse_cmd_input_output): Recognize incoming
|
||||||
|
file descriptors and act appropriately.
|
||||||
|
* assuan-defs.h (struct assuan_io): Add fields sendfd and
|
||||||
|
receivefd.
|
||||||
|
(struct assuan_context_s): Add fields pendingfds and
|
||||||
|
pendingfdscount.
|
||||||
|
* assuan-pipe-server.c (_assuan_new_context): Update IO to reflect
|
||||||
|
new features.
|
||||||
|
* assuan-domain-connect.c (do_deinit): Cleanup any unreceived file
|
||||||
|
descriptors.
|
||||||
|
(domain_reader): Receive file descriptors.
|
||||||
|
(domain_sendfd): New function.
|
||||||
|
(domain_receivefd): New function.
|
||||||
|
(_assuan_domain_init): Update initialization code to reflect new
|
||||||
|
features.
|
||||||
|
|
||||||
|
2002-11-24 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* assuan-domain-connect.c (do_finish): Remove.
|
||||||
|
(_assuan_domain_init): Use default handlers where possible.
|
||||||
|
Add an assert and update comments.
|
||||||
|
* assuan-domain-server.c (accept_connection): Remove.
|
||||||
|
(assuan_init_domain_server): Use default handlers where possible.
|
||||||
|
Put the server in pipe mode: it can only be used by a single
|
||||||
|
client.
|
||||||
|
|
||||||
|
2002-11-24 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* assuan.h: Add prototype for assuan_domain_connect and
|
||||||
|
assuan_init_domain_server.
|
||||||
|
* assuan-defs.h: Include <unistd.h>.
|
||||||
|
Add prototype for _assuan_domain_init.
|
||||||
|
* assuan-domain-connect.c: New file.
|
||||||
|
* assuan-domain-server.c: New file.
|
||||||
|
* Makefile.am (libassuan_a_SOURCES): Add assuan-domain-connect.c
|
||||||
|
and assuan-domain-server.c
|
||||||
|
|
||||||
|
2002-11-23 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* Makefile.am (libassuan_a_SOURCES): Add assuan-io.c.
|
||||||
|
* assuan-io.c: Restore.
|
||||||
|
(_assuan_simple_read): Rename from _assuan_read.
|
||||||
|
(_assuan_simple_write): Rename from _assuan_write.
|
||||||
|
* assuan-defs.h (_assuan_simple_read): New prototype.
|
||||||
|
(_assuan_simple_write): Likewise.
|
||||||
|
* assuan-pipe-server.c (pipe_reader): Remove.
|
||||||
|
(pipe_writer): Remove.
|
||||||
|
(_assuan_new_context): Initialize IO is with _assuan_simple_read
|
||||||
|
and _assuan_simple_write.
|
||||||
|
* assuan-socket-connect.c (socket_reader): Remove.
|
||||||
|
(socket_writer): Remove.
|
||||||
|
(assuan_socket_connect): Initialize IO is with _assuan_simple_read
|
||||||
|
and _assuan_simple_write.
|
||||||
|
* assuan-socket-server.c (io): New local variable.
|
||||||
|
(assuan_init_socket_server): Initialize CTX->io.
|
||||||
|
(assuan_init_connected_socket_server): Likewise.
|
||||||
|
|
||||||
|
2002-11-23 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* assuan-buffer.c (readline): Use memrchr.
|
||||||
|
(_assuan_read_line): Rewritten to use the string functions.
|
||||||
|
|
||||||
|
2002-11-20 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* assuan-socket-connect.c (assuan_socket_connect): Pass PF_LOCAL
|
||||||
|
to socket(), not AF_UNIX: it expects a PF_* macro and the former
|
||||||
|
is more portable.
|
||||||
|
(assuan_socket_connect): Use AF_LOCAL, not AF_UNIX which is more
|
||||||
|
POSIXy.
|
||||||
|
|
||||||
|
2002-11-20 Neal H. Walfield <neal@g10code.de>
|
||||||
|
|
||||||
|
* assuan-defs.h (struct assuan_io): New structure.
|
||||||
|
(struct assuan_context_s): New field, io.
|
||||||
|
(_assuan_read): Depreciated.
|
||||||
|
(_assuan_write): Likewise.
|
||||||
|
* assuan-pipe-server.c: Include <unistd.h>.
|
||||||
|
(pipe_reader): New function.
|
||||||
|
(pipe_writer): Likewise.
|
||||||
|
(_assuan_new_context.IO): New local static. Set to pipe_reader
|
||||||
|
and pipe_writer. Use it to initialize new context.
|
||||||
|
* assuan-socket-connect.c (socket_reader): New function.
|
||||||
|
(socket_writer): New function.
|
||||||
|
(assuan_socket_connect.IO): New local static. Set to socket_reader
|
||||||
|
and socket_writer. Use it to initialize new context.
|
||||||
|
* assuan-buffer.c (writen): Take an ASSUAN_CONTEXT rather than a
|
||||||
|
file descriptor. Do not use _assuan_write but the write method
|
||||||
|
in the supplied context.
|
||||||
|
(readline): Likewise for _assuan_read.
|
||||||
|
(assuan_write_line): When calling writen, pass CTX; not the file
|
||||||
|
descriptor directly.
|
||||||
|
(_assuan_cookie_write_data): Likewise.
|
||||||
|
(_assuan_cookie_write_flush): Likewise.
|
||||||
|
(_assuan_read_line): Likewise for readline.
|
||||||
|
* Makefile.am (libassuan_a_SOURCES): Remove assuan-io.c.
|
||||||
|
* assuan-io.c: Removed.
|
||||||
|
|
||||||
2002-11-10 Werner Koch <wk@gnupg.org>
|
2002-11-10 Werner Koch <wk@gnupg.org>
|
||||||
|
|
||||||
* assuan-pipe-connect.c (assuan_pipe_connect): Changed the order
|
* assuan-pipe-connect.c (assuan_pipe_connect): Changed the order
|
||||||
@ -267,11 +473,6 @@
|
|||||||
* assuan-defs.h: Add space in the context for this.
|
* assuan-defs.h: Add space in the context for this.
|
||||||
|
|
||||||
|
|
||||||
***********************************************************
|
|
||||||
* Please note that Assuan is maintained as part of GnuPG. *
|
|
||||||
* You may find it source-copied in other packages. *
|
|
||||||
***********************************************************
|
|
||||||
|
|
||||||
Copyright 2001, 2002 Free Software Foundation, Inc.
|
Copyright 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is free software; as a special exception the author gives
|
This file is free software; as a special exception the author gives
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Assuan Makefile
|
# Assuan Makefile
|
||||||
# Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||||
#
|
#
|
||||||
# This file is part of Assuan.
|
# This file is part of Assuan.
|
||||||
#
|
#
|
||||||
@ -43,8 +43,10 @@ libassuan_la_SOURCES = \
|
|||||||
assuan-socket-server.c \
|
assuan-socket-server.c \
|
||||||
assuan-pipe-connect.c \
|
assuan-pipe-connect.c \
|
||||||
assuan-socket-connect.c \
|
assuan-socket-connect.c \
|
||||||
assuan-io.c
|
assuan-io.c \
|
||||||
|
assuan-domain-connect.c \
|
||||||
|
assuan-domain-server.c \
|
||||||
|
assuan-logging.c
|
||||||
|
|
||||||
assuan-errors.c : assuan.h
|
assuan-errors.c : assuan.h
|
||||||
$(srcdir)/mkerrors < $(srcdir)/assuan.h > assuan-errors.c
|
$(srcdir)/mkerrors < $(srcdir)/assuan.h > assuan-errors.c
|
||||||
|
@ -1 +1,3 @@
|
|||||||
Please don't modify it here but in the copy which comes with GnuPG.
|
This is a modified copy of the libassuan library. Don't modify it,
|
||||||
|
but instead modify the original Assuan library and merge the changes
|
||||||
|
back into this copy.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* assuan-buffer.c - read and send data
|
/* assuan-buffer.c - read and send data
|
||||||
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of Assuan.
|
* This file is part of Assuan.
|
||||||
*
|
*
|
||||||
@ -27,28 +27,12 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "assuan-defs.h"
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
#ifdef HAVE_JNLIB_LOGGING
|
|
||||||
#include "../jnlib/logging.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
my_log_prefix (void)
|
|
||||||
{
|
|
||||||
#ifdef HAVE_JNLIB_LOGGING
|
|
||||||
return log_get_prefix (NULL);
|
|
||||||
#else
|
|
||||||
return "";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
writen ( int fd, const char *buffer, size_t length )
|
writen (ASSUAN_CONTEXT ctx, const char *buffer, size_t length)
|
||||||
{
|
{
|
||||||
while (length)
|
while (length)
|
||||||
{
|
{
|
||||||
ssize_t nwritten = _assuan_write (fd, buffer, length);
|
ssize_t nwritten = ctx->io->write (ctx, buffer, length);
|
||||||
|
|
||||||
if (nwritten < 0)
|
if (nwritten < 0)
|
||||||
{
|
{
|
||||||
@ -62,9 +46,10 @@ writen ( int fd, const char *buffer, size_t length )
|
|||||||
return 0; /* okay */
|
return 0; /* okay */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read an entire line */
|
/* Read an entire line. */
|
||||||
static int
|
static int
|
||||||
readline (int fd, char *buf, size_t buflen, int *r_nread, int *eof)
|
readline (ASSUAN_CONTEXT ctx, char *buf, size_t buflen,
|
||||||
|
int *r_nread, int *eof)
|
||||||
{
|
{
|
||||||
size_t nleft = buflen;
|
size_t nleft = buflen;
|
||||||
char *p;
|
char *p;
|
||||||
@ -73,7 +58,7 @@ readline (int fd, char *buf, size_t buflen, int *r_nread, int *eof)
|
|||||||
*r_nread = 0;
|
*r_nread = 0;
|
||||||
while (nleft > 0)
|
while (nleft > 0)
|
||||||
{
|
{
|
||||||
ssize_t n = _assuan_read (fd, buf, nleft);
|
ssize_t n = ctx->io->read (ctx, buf, nleft);
|
||||||
|
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
{
|
{
|
||||||
@ -91,9 +76,8 @@ readline (int fd, char *buf, size_t buflen, int *r_nread, int *eof)
|
|||||||
buf += n;
|
buf += n;
|
||||||
*r_nread += n;
|
*r_nread += n;
|
||||||
|
|
||||||
for (; n && *p != '\n'; n--, p++)
|
p = memrchr (p, '\n', n);
|
||||||
;
|
if (p)
|
||||||
if (n)
|
|
||||||
break; /* at least one full line available - that's enough for now */
|
break; /* at least one full line available - that's enough for now */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,8 +89,9 @@ int
|
|||||||
_assuan_read_line (ASSUAN_CONTEXT ctx)
|
_assuan_read_line (ASSUAN_CONTEXT ctx)
|
||||||
{
|
{
|
||||||
char *line = ctx->inbound.line;
|
char *line = ctx->inbound.line;
|
||||||
int n, nread, atticlen;
|
int nread, atticlen;
|
||||||
int rc;
|
int rc;
|
||||||
|
char *endp = 0;
|
||||||
|
|
||||||
if (ctx->inbound.eof)
|
if (ctx->inbound.eof)
|
||||||
return -1;
|
return -1;
|
||||||
@ -116,69 +101,72 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
|
|||||||
{
|
{
|
||||||
memcpy (line, ctx->inbound.attic.line, atticlen);
|
memcpy (line, ctx->inbound.attic.line, atticlen);
|
||||||
ctx->inbound.attic.linelen = 0;
|
ctx->inbound.attic.linelen = 0;
|
||||||
for (n=0; n < atticlen && line[n] != '\n'; n++)
|
|
||||||
;
|
endp = memchr (line, '\n', atticlen);
|
||||||
if (n < atticlen)
|
if (endp)
|
||||||
|
/* Found another line in the attic. */
|
||||||
{
|
{
|
||||||
rc = 0; /* found another line in the attic */
|
rc = 0;
|
||||||
nread = atticlen;
|
nread = atticlen;
|
||||||
atticlen = 0;
|
atticlen = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ /* read the rest */
|
/* There is pending data but not a full line. */
|
||||||
|
{
|
||||||
assert (atticlen < LINELENGTH);
|
assert (atticlen < LINELENGTH);
|
||||||
rc = readline (ctx->inbound.fd, line + atticlen,
|
rc = readline (ctx, line + atticlen,
|
||||||
LINELENGTH - atticlen, &nread, &ctx->inbound.eof);
|
LINELENGTH - atticlen, &nread, &ctx->inbound.eof);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
rc = readline (ctx->inbound.fd, line, LINELENGTH,
|
/* No pending data. */
|
||||||
|
rc = readline (ctx, line, LINELENGTH,
|
||||||
&nread, &ctx->inbound.eof);
|
&nread, &ctx->inbound.eof);
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
if (ctx->log_fp)
|
if (ctx->log_fp)
|
||||||
fprintf (ctx->log_fp, "%s[%p] <- [Error: %s]\n",
|
fprintf (ctx->log_fp, "%s[%p] <- [Error: %s]\n",
|
||||||
my_log_prefix (), ctx, strerror (errno));
|
assuan_get_assuan_log_prefix (), ctx, strerror (errno));
|
||||||
return ASSUAN_Read_Error;
|
return ASSUAN_Read_Error;
|
||||||
}
|
}
|
||||||
if (!nread)
|
if (!nread)
|
||||||
{
|
{
|
||||||
assert (ctx->inbound.eof);
|
assert (ctx->inbound.eof);
|
||||||
if (ctx->log_fp)
|
if (ctx->log_fp)
|
||||||
fprintf (ctx->log_fp, "%s[%p] <- [EOF]\n", my_log_prefix (),ctx);
|
fprintf (ctx->log_fp, "%s[%p] <- [EOF]\n",
|
||||||
|
assuan_get_assuan_log_prefix (), ctx);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->inbound.attic.pending = 0;
|
ctx->inbound.attic.pending = 0;
|
||||||
nread += atticlen;
|
nread += atticlen;
|
||||||
for (n=0; n < nread; n++)
|
|
||||||
{
|
|
||||||
if (line[n] == '\n')
|
|
||||||
{
|
|
||||||
if (n+1 < nread)
|
|
||||||
{
|
|
||||||
char *s, *d;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
n++;
|
if (! endp)
|
||||||
/* we have to copy the rest because the handlers are
|
endp = memchr (line, '\n', nread);
|
||||||
allowed to modify the passed buffer */
|
|
||||||
for (d=ctx->inbound.attic.line, s=line+n, i=nread-n; i; i--)
|
if (endp)
|
||||||
{
|
{
|
||||||
if (*s=='\n')
|
int n = endp - line + 1;
|
||||||
ctx->inbound.attic.pending = 1;
|
if (n < nread)
|
||||||
*d++ = *s++;
|
/* LINE contains more than one line. We copy it to the attic
|
||||||
|
now as handlers are allowed to modify the passed
|
||||||
|
buffer. */
|
||||||
|
{
|
||||||
|
int len = nread - n;
|
||||||
|
memcpy (ctx->inbound.attic.line, endp + 1, len);
|
||||||
|
ctx->inbound.attic.pending = memrchr (endp + 1, '\n', len) ? 1 : 0;
|
||||||
|
ctx->inbound.attic.linelen = len;
|
||||||
}
|
}
|
||||||
ctx->inbound.attic.linelen = nread-n;
|
|
||||||
n--;
|
if (endp != line && endp[-1] == '\r')
|
||||||
}
|
endp --;
|
||||||
if (n && line[n-1] == '\r')
|
*endp = 0;
|
||||||
n--;
|
|
||||||
line[n] = 0;
|
ctx->inbound.linelen = endp - line;
|
||||||
ctx->inbound.linelen = n;
|
|
||||||
if (ctx->log_fp)
|
if (ctx->log_fp)
|
||||||
{
|
{
|
||||||
fprintf (ctx->log_fp, "%s[%p] <- ", my_log_prefix (), ctx);
|
fprintf (ctx->log_fp, "%s[%p] <- ",
|
||||||
|
assuan_get_assuan_log_prefix (), ctx);
|
||||||
if (ctx->confidential)
|
if (ctx->confidential)
|
||||||
fputs ("[Confidential data not shown]", ctx->log_fp);
|
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||||
else
|
else
|
||||||
@ -189,13 +177,16 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
if (ctx->log_fp)
|
if (ctx->log_fp)
|
||||||
fprintf (ctx->log_fp, "%s[%p] <- [Invalid line]\n", my_log_prefix (), ctx);
|
fprintf (ctx->log_fp, "%s[%p] <- [Invalid line]\n",
|
||||||
|
assuan_get_assuan_log_prefix (), ctx);
|
||||||
*line = 0;
|
*line = 0;
|
||||||
ctx->inbound.linelen = 0;
|
ctx->inbound.linelen = 0;
|
||||||
return ctx->inbound.eof? ASSUAN_Line_Not_Terminated : ASSUAN_Line_Too_Long;
|
return ctx->inbound.eof ? ASSUAN_Line_Not_Terminated
|
||||||
|
: ASSUAN_Line_Too_Long;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -233,7 +224,7 @@ assuan_pending_line (ASSUAN_CONTEXT ctx)
|
|||||||
|
|
||||||
|
|
||||||
AssuanError
|
AssuanError
|
||||||
assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
|
assuan_write_line (ASSUAN_CONTEXT ctx, const char *line)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -250,7 +241,8 @@ assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
|
|||||||
/* fixme: we should do some kind of line buffering. */
|
/* fixme: we should do some kind of line buffering. */
|
||||||
if (ctx->log_fp)
|
if (ctx->log_fp)
|
||||||
{
|
{
|
||||||
fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
|
fprintf (ctx->log_fp, "%s[%p] -> ",
|
||||||
|
assuan_get_assuan_log_prefix (), ctx);
|
||||||
if (s)
|
if (s)
|
||||||
fputs ("[supplied line contained a LF]", ctx->log_fp);
|
fputs ("[supplied line contained a LF]", ctx->log_fp);
|
||||||
if (ctx->confidential)
|
if (ctx->confidential)
|
||||||
@ -260,12 +252,12 @@ assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
|
|||||||
putc ('\n', ctx->log_fp);
|
putc ('\n', ctx->log_fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = writen (ctx->outbound.fd, line, len);
|
rc = writen (ctx, line, len);
|
||||||
if (rc)
|
if (rc)
|
||||||
rc = ASSUAN_Write_Error;
|
rc = ASSUAN_Write_Error;
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
rc = writen (ctx->outbound.fd, "\n", 1);
|
rc = writen (ctx, "\n", 1);
|
||||||
if (rc)
|
if (rc)
|
||||||
rc = ASSUAN_Write_Error;
|
rc = ASSUAN_Write_Error;
|
||||||
}
|
}
|
||||||
@ -322,7 +314,9 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size)
|
|||||||
{
|
{
|
||||||
if (ctx->log_fp)
|
if (ctx->log_fp)
|
||||||
{
|
{
|
||||||
fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
|
fprintf (ctx->log_fp, "%s[%p] -> ",
|
||||||
|
assuan_get_assuan_log_prefix (), ctx);
|
||||||
|
|
||||||
if (ctx->confidential)
|
if (ctx->confidential)
|
||||||
fputs ("[Confidential data not shown]", ctx->log_fp);
|
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||||
else
|
else
|
||||||
@ -333,7 +327,7 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size)
|
|||||||
}
|
}
|
||||||
*line++ = '\n';
|
*line++ = '\n';
|
||||||
linelen++;
|
linelen++;
|
||||||
if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
|
if (writen (ctx, ctx->outbound.data.line, linelen))
|
||||||
{
|
{
|
||||||
ctx->outbound.data.error = ASSUAN_Write_Error;
|
ctx->outbound.data.error = ASSUAN_Write_Error;
|
||||||
return 0;
|
return 0;
|
||||||
@ -367,18 +361,18 @@ _assuan_cookie_write_flush (void *cookie)
|
|||||||
{
|
{
|
||||||
if (ctx->log_fp)
|
if (ctx->log_fp)
|
||||||
{
|
{
|
||||||
fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
|
fprintf (ctx->log_fp, "%s[%p] -> ",
|
||||||
|
assuan_get_assuan_log_prefix (), ctx);
|
||||||
if (ctx->confidential)
|
if (ctx->confidential)
|
||||||
fputs ("[Confidential data not shown]", ctx->log_fp);
|
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||||
else
|
else
|
||||||
_assuan_log_print_buffer (ctx->log_fp,
|
_assuan_log_print_buffer (ctx->log_fp,
|
||||||
ctx->outbound.data.line,
|
ctx->outbound.data.line, linelen);
|
||||||
linelen);
|
|
||||||
putc ('\n', ctx->log_fp);
|
putc ('\n', ctx->log_fp);
|
||||||
}
|
}
|
||||||
*line++ = '\n';
|
*line++ = '\n';
|
||||||
linelen++;
|
linelen++;
|
||||||
if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
|
if (writen (ctx, ctx->outbound.data.line, linelen))
|
||||||
{
|
{
|
||||||
ctx->outbound.data.error = ASSUAN_Write_Error;
|
ctx->outbound.data.error = ASSUAN_Write_Error;
|
||||||
return 0;
|
return 0;
|
||||||
@ -432,3 +426,23 @@ assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AssuanError
|
||||||
|
assuan_sendfd (ASSUAN_CONTEXT ctx, int fd)
|
||||||
|
{
|
||||||
|
if (! ctx->io->sendfd)
|
||||||
|
return set_error (ctx, Not_Implemented,
|
||||||
|
"server does not support sending and receiving "
|
||||||
|
"of file descriptors");
|
||||||
|
return ctx->io->sendfd (ctx, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssuanError
|
||||||
|
assuan_receivefd (ASSUAN_CONTEXT ctx, int *fd)
|
||||||
|
{
|
||||||
|
if (! ctx->io->receivefd)
|
||||||
|
return set_error (ctx, Not_Implemented,
|
||||||
|
"server does not support sending and receiving "
|
||||||
|
"of file descriptors");
|
||||||
|
return ctx->io->receivefd (ctx, fd);
|
||||||
|
}
|
||||||
|
@ -22,17 +22,34 @@
|
|||||||
#define ASSUAN_DEFS_H
|
#define ASSUAN_DEFS_H
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "assuan.h"
|
#include "assuan.h"
|
||||||
|
|
||||||
#define LINELENGTH ASSUAN_LINELENGTH
|
#define LINELENGTH ASSUAN_LINELENGTH
|
||||||
|
|
||||||
struct cmdtbl_s {
|
struct cmdtbl_s
|
||||||
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
int cmd_id;
|
|
||||||
int (*handler)(ASSUAN_CONTEXT, char *line);
|
int (*handler)(ASSUAN_CONTEXT, char *line);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct assuan_context_s {
|
struct assuan_io
|
||||||
|
{
|
||||||
|
/* Routine to read from input_fd. */
|
||||||
|
ssize_t (*read) (ASSUAN_CONTEXT, void *, size_t);
|
||||||
|
/* Routine to write to output_fd. */
|
||||||
|
ssize_t (*write) (ASSUAN_CONTEXT, const void *, size_t);
|
||||||
|
/* Send a file descriptor. */
|
||||||
|
AssuanError (*sendfd) (ASSUAN_CONTEXT, int);
|
||||||
|
/* Receive a file descriptor. */
|
||||||
|
AssuanError (*receivefd) (ASSUAN_CONTEXT, int *);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct assuan_context_s
|
||||||
|
{
|
||||||
AssuanError err_no;
|
AssuanError err_no;
|
||||||
const char *err_str;
|
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*/
|
||||||
@ -81,6 +98,23 @@ struct assuan_context_s {
|
|||||||
pid_t client_pid; /* for a socket server the PID of the client or -1
|
pid_t client_pid; /* for a socket server the PID of the client or -1
|
||||||
if not available */
|
if not available */
|
||||||
|
|
||||||
|
/* Used for Unix domain sockets. */
|
||||||
|
struct sockaddr_un myaddr;
|
||||||
|
struct sockaddr_un serveraddr;
|
||||||
|
/* When reading from datagram sockets, we must read an entire
|
||||||
|
message at a time. This means that we have to do our own
|
||||||
|
buffering to be able to get the semantics of read. */
|
||||||
|
void *domainbuffer;
|
||||||
|
/* Offset of start of buffer. */
|
||||||
|
int domainbufferoffset;
|
||||||
|
/* Bytes buffered. */
|
||||||
|
int domainbuffersize;
|
||||||
|
/* Memory allocated. */
|
||||||
|
int domainbufferallocated;
|
||||||
|
|
||||||
|
int *pendingfds;
|
||||||
|
int pendingfdscount;
|
||||||
|
|
||||||
void (*deinit_handler)(ASSUAN_CONTEXT);
|
void (*deinit_handler)(ASSUAN_CONTEXT);
|
||||||
int (*accept_handler)(ASSUAN_CONTEXT);
|
int (*accept_handler)(ASSUAN_CONTEXT);
|
||||||
int (*finish_handler)(ASSUAN_CONTEXT);
|
int (*finish_handler)(ASSUAN_CONTEXT);
|
||||||
@ -99,14 +133,21 @@ struct assuan_context_s {
|
|||||||
int input_fd; /* set by INPUT command */
|
int input_fd; /* set by INPUT command */
|
||||||
int output_fd; /* set by OUTPUT command */
|
int output_fd; /* set by OUTPUT command */
|
||||||
|
|
||||||
|
/* io routines. */
|
||||||
|
struct assuan_io *io;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-- assuan-pipe-server.c --*/
|
/*-- assuan-pipe-server.c --*/
|
||||||
int _assuan_new_context (ASSUAN_CONTEXT *r_ctx);
|
int _assuan_new_context (ASSUAN_CONTEXT *r_ctx);
|
||||||
void _assuan_release_context (ASSUAN_CONTEXT ctx);
|
void _assuan_release_context (ASSUAN_CONTEXT ctx);
|
||||||
|
|
||||||
|
/*-- assuan-domain-connect.c --*/
|
||||||
|
/* 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-handler.c --*/
|
/*-- assuan-handler.c --*/
|
||||||
int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
|
int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
|
||||||
@ -137,11 +178,17 @@ void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length);
|
|||||||
void _assuan_log_sanitized_string (const char *string);
|
void _assuan_log_sanitized_string (const char *string);
|
||||||
|
|
||||||
/*-- assuan-io.c --*/
|
/*-- 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);
|
||||||
|
|
||||||
/* Wraps the standard read and write functions to do the Right
|
#ifdef HAVE_FOPENCOOKIE
|
||||||
Thing depending on our linkage. */
|
/* We have to implement funopen in terms of glibc's fopencookie. */
|
||||||
ssize_t _assuan_read (int fd, void *buffer, size_t size);
|
FILE *funopen(const void *cookie, cookie_read_function_t *readfn,
|
||||||
ssize_t _assuan_write (int fd, const void *buffer, size_t size);
|
cookie_write_function_t *writefn,
|
||||||
|
cookie_seek_function_t *seekfn,
|
||||||
|
cookie_close_function_t *closefn);
|
||||||
|
#endif /*HAVE_FOPENCOOKIE*/
|
||||||
|
|
||||||
#endif /*ASSUAN_DEFS_H*/
|
#endif /*ASSUAN_DEFS_H*/
|
||||||
|
|
||||||
|
473
assuan/assuan-domain-connect.c
Normal file
473
assuan/assuan-domain-connect.c
Normal file
@ -0,0 +1,473 @@
|
|||||||
|
/* assuan-domain-connect.c - Assuan unix domain socket based client
|
||||||
|
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of Assuan.
|
||||||
|
*
|
||||||
|
* Assuan is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Assuan is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <alloca.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
|
#define LOG(format, args...) \
|
||||||
|
fprintf (assuan_get_assuan_log_stream (), \
|
||||||
|
assuan_get_assuan_log_prefix (), \
|
||||||
|
"%s" format , ## args)
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
do_deinit (ASSUAN_CONTEXT ctx)
|
||||||
|
{
|
||||||
|
if (ctx->inbound.fd != -1)
|
||||||
|
close (ctx->inbound.fd);
|
||||||
|
ctx->inbound.fd = -1;
|
||||||
|
ctx->outbound.fd = -1;
|
||||||
|
|
||||||
|
if (ctx->domainbuffer)
|
||||||
|
{
|
||||||
|
assert (ctx->domainbufferallocated);
|
||||||
|
free (ctx->domainbuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx->pendingfds)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
assert (ctx->pendingfdscount > 0);
|
||||||
|
for (i = 0; i < ctx->pendingfdscount; i ++)
|
||||||
|
close (ctx->pendingfds[i]);
|
||||||
|
|
||||||
|
free (ctx->pendingfds);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlink (ctx->myaddr.sun_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Read from the socket server. */
|
||||||
|
static ssize_t
|
||||||
|
domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
int len = ctx->domainbuffersize;
|
||||||
|
|
||||||
|
start:
|
||||||
|
if (len == 0)
|
||||||
|
/* No data is buffered. */
|
||||||
|
{
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec iovec;
|
||||||
|
struct sockaddr_un sender;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct cmsghdr hdr;
|
||||||
|
int fd;
|
||||||
|
}
|
||||||
|
cmsg;
|
||||||
|
|
||||||
|
memset (&msg, 0, sizeof (msg));
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
msg.msg_name = &sender;
|
||||||
|
msg.msg_namelen = sizeof (struct sockaddr_un);
|
||||||
|
msg.msg_iov = &iovec;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
iovec.iov_base = ctx->domainbuffer;
|
||||||
|
iovec.iov_len = ctx->domainbufferallocated;
|
||||||
|
msg.msg_control = &cmsg;
|
||||||
|
msg.msg_controllen = sizeof cmsg;
|
||||||
|
|
||||||
|
/* Peek first: if the buffer we have is too small then it
|
||||||
|
will be truncated. */
|
||||||
|
len = recvmsg (ctx->inbound.fd, &msg, MSG_PEEK);
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
|
printf ("domain_reader: %m\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp (ctx->serveraddr.sun_path,
|
||||||
|
((struct sockaddr_un *) msg.msg_name)->sun_path) != 0)
|
||||||
|
{
|
||||||
|
/* XXX: Arg. Not from whom we expected! What do we
|
||||||
|
want to do? Should we just ignore it? Either way,
|
||||||
|
we still need to consume the message. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg.msg_flags & MSG_TRUNC)
|
||||||
|
/* Enlarge the buffer and try again. */
|
||||||
|
{
|
||||||
|
int size = ctx->domainbufferallocated;
|
||||||
|
void *tmp;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
size = 4 * 1024;
|
||||||
|
else
|
||||||
|
size *= 2;
|
||||||
|
|
||||||
|
tmp = malloc (size);
|
||||||
|
if (! tmp)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
free (ctx->domainbuffer);
|
||||||
|
ctx->domainbuffer = tmp;
|
||||||
|
ctx->domainbufferallocated = size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* We have enough space! */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we have to actually consume it (remember, we only
|
||||||
|
peeked). */
|
||||||
|
msg.msg_name = &sender;
|
||||||
|
msg.msg_namelen = sizeof (struct sockaddr_un);
|
||||||
|
msg.msg_iov = &iovec;
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
iovec.iov_base = ctx->domainbuffer;
|
||||||
|
iovec.iov_len = ctx->domainbufferallocated;
|
||||||
|
msg.msg_control = &cmsg;
|
||||||
|
msg.msg_controllen = sizeof cmsg;
|
||||||
|
|
||||||
|
if (strcmp (ctx->serveraddr.sun_path,
|
||||||
|
((struct sockaddr_un *) msg.msg_name)->sun_path) != 0)
|
||||||
|
{
|
||||||
|
/* 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);
|
||||||
|
goto start;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = recvmsg (ctx->inbound.fd, &msg, 0);
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
|
LOG ("domain_reader: %s\n", strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->domainbuffersize = len;
|
||||||
|
ctx->domainbufferoffset = 0;
|
||||||
|
|
||||||
|
if (sizeof (cmsg) == msg.msg_controllen)
|
||||||
|
/* We received a file descriptor. */
|
||||||
|
{
|
||||||
|
void *tmp;
|
||||||
|
|
||||||
|
tmp = realloc (ctx->pendingfds,
|
||||||
|
sizeof (int) * (ctx->pendingfdscount + 1));
|
||||||
|
if (! tmp)
|
||||||
|
{
|
||||||
|
LOG ("domain_reader: %s\n", strerror (errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->pendingfds = tmp;
|
||||||
|
ctx->pendingfds[ctx->pendingfdscount++]
|
||||||
|
= *(int *) CMSG_DATA (&cmsg.hdr);
|
||||||
|
|
||||||
|
LOG ("Received file descriptor %d from peer.\n",
|
||||||
|
ctx->pendingfds[ctx->pendingfdscount - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 0)
|
||||||
|
goto start;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return some data to the user. */
|
||||||
|
|
||||||
|
if (len > buflen)
|
||||||
|
/* We have more than the user requested. */
|
||||||
|
len = buflen;
|
||||||
|
|
||||||
|
memcpy (buf, ctx->domainbuffer + ctx->domainbufferoffset, len);
|
||||||
|
ctx->domainbuffersize -= len;
|
||||||
|
assert (ctx->domainbuffersize >= 0);
|
||||||
|
ctx->domainbufferoffset += len;
|
||||||
|
assert (ctx->domainbufferoffset <= ctx->domainbufferallocated);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write to the domain server. */
|
||||||
|
static ssize_t
|
||||||
|
domain_writer (ASSUAN_CONTEXT ctx, const void *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec iovec;
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
|
memset (&msg, 0, sizeof (msg));
|
||||||
|
|
||||||
|
msg.msg_name = &ctx->serveraddr;
|
||||||
|
msg.msg_namelen = offsetof (struct sockaddr_un, sun_path)
|
||||||
|
+ strlen (ctx->serveraddr.sun_path) + 1;
|
||||||
|
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
msg.msg_iov = &iovec;
|
||||||
|
iovec.iov_base = (void *) buf;
|
||||||
|
iovec.iov_len = buflen;
|
||||||
|
msg.msg_control = 0;
|
||||||
|
msg.msg_controllen = 0;
|
||||||
|
|
||||||
|
len = sendmsg (ctx->outbound.fd, &msg, 0);
|
||||||
|
if (len < 0)
|
||||||
|
LOG ("domain_writer: %s\n", strerror (errno));
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static AssuanError
|
||||||
|
domain_sendfd (ASSUAN_CONTEXT ctx, int fd)
|
||||||
|
{
|
||||||
|
struct msghdr msg;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct cmsghdr hdr;
|
||||||
|
int fd;
|
||||||
|
}
|
||||||
|
cmsg;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
memset (&msg, 0, sizeof (msg));
|
||||||
|
|
||||||
|
msg.msg_name = &ctx->serveraddr;
|
||||||
|
msg.msg_namelen = offsetof (struct sockaddr_un, sun_path)
|
||||||
|
+ strlen (ctx->serveraddr.sun_path) + 1;
|
||||||
|
|
||||||
|
msg.msg_iovlen = 0;
|
||||||
|
msg.msg_iov = 0;
|
||||||
|
|
||||||
|
cmsg.hdr.cmsg_level = SOL_SOCKET;
|
||||||
|
cmsg.hdr.cmsg_type = SCM_RIGHTS;
|
||||||
|
cmsg.hdr.cmsg_len = sizeof (cmsg);
|
||||||
|
|
||||||
|
msg.msg_control = &cmsg;
|
||||||
|
msg.msg_controllen = sizeof (cmsg);
|
||||||
|
|
||||||
|
*(int *) CMSG_DATA (&cmsg.hdr) = fd;
|
||||||
|
|
||||||
|
len = sendmsg (ctx->outbound.fd, &msg, 0);
|
||||||
|
if (len < 0)
|
||||||
|
{
|
||||||
|
LOG ("domain_sendfd: %s\n", strerror (errno));
|
||||||
|
return ASSUAN_General_Error;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static AssuanError
|
||||||
|
domain_receivefd (ASSUAN_CONTEXT ctx, int *fd)
|
||||||
|
{
|
||||||
|
if (ctx->pendingfds == 0)
|
||||||
|
{
|
||||||
|
LOG ("No pending file descriptors!\n");
|
||||||
|
return ASSUAN_General_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
*fd = ctx->pendingfds[0];
|
||||||
|
if (-- ctx->pendingfdscount == 0)
|
||||||
|
{
|
||||||
|
free (ctx->pendingfds);
|
||||||
|
ctx->pendingfds = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* Fix the array. */
|
||||||
|
{
|
||||||
|
memmove (ctx->pendingfds, ctx->pendingfds + 1,
|
||||||
|
ctx->pendingfdscount * sizeof (int));
|
||||||
|
ctx->pendingfds = realloc (ctx->pendingfds,
|
||||||
|
ctx->pendingfdscount * sizeof (int));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
{
|
||||||
|
static struct assuan_io io = { domain_reader, domain_writer,
|
||||||
|
domain_sendfd, domain_receivefd };
|
||||||
|
|
||||||
|
AssuanError err;
|
||||||
|
ASSUAN_CONTEXT ctx;
|
||||||
|
int fd;
|
||||||
|
size_t len;
|
||||||
|
int tries;
|
||||||
|
|
||||||
|
if (!r_ctx)
|
||||||
|
return ASSUAN_Invalid_Value;
|
||||||
|
*r_ctx = NULL;
|
||||||
|
|
||||||
|
err = _assuan_new_context (&ctx);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/* Save it in case we need it later. */
|
||||||
|
ctx->pid = peer;
|
||||||
|
|
||||||
|
/* Override the default (NOP) handlers. */
|
||||||
|
ctx->deinit_handler = do_deinit;
|
||||||
|
|
||||||
|
/* Setup the socket. */
|
||||||
|
|
||||||
|
fd = socket (PF_LOCAL, SOCK_DGRAM, 0);
|
||||||
|
if (fd == -1)
|
||||||
|
{
|
||||||
|
LOG ("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;
|
||||||
|
ctx->domainbuffer = 0;
|
||||||
|
ctx->domainbufferoffset = 0;
|
||||||
|
ctx->domainbuffersize = 0;
|
||||||
|
ctx->domainbufferallocated = 0;
|
||||||
|
ctx->pendingfds = 0;
|
||||||
|
ctx->pendingfdscount = 0;
|
||||||
|
|
||||||
|
/* Get usable name and bind to it. */
|
||||||
|
|
||||||
|
for (tries = 0; tries < TMP_MAX; tries ++)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
char buf[L_tmpnam];
|
||||||
|
|
||||||
|
/* XXX: L_tmpnam must be shorter than sizeof (sun_path)! */
|
||||||
|
assert (L_tmpnam < sizeof (ctx->myaddr.sun_path));
|
||||||
|
|
||||||
|
p = tmpnam (buf);
|
||||||
|
if (! p)
|
||||||
|
{
|
||||||
|
LOG ("cannot determine an appropriate temporary file "
|
||||||
|
"name. DOS in progress?\n");
|
||||||
|
_assuan_release_context (ctx);
|
||||||
|
close (fd);
|
||||||
|
return ASSUAN_General_Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (&ctx->myaddr, 0, sizeof ctx->myaddr);
|
||||||
|
ctx->myaddr.sun_family = AF_LOCAL;
|
||||||
|
len = strlen (buf) + 1;
|
||||||
|
memcpy (ctx->myaddr.sun_path, buf, len);
|
||||||
|
len += offsetof (struct sockaddr_un, sun_path);
|
||||||
|
|
||||||
|
err = 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_release_context (ctx);
|
||||||
|
close (fd);
|
||||||
|
return ASSUAN_Connect_Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Rendezvous with our peer. */
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
fp = fdopen (rendezvousfd, "w+");
|
||||||
|
if (! fp)
|
||||||
|
{
|
||||||
|
LOG ("can't open rendezvous port: %s\n", strerror (errno));
|
||||||
|
return ASSUAN_Connect_Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send our address. */
|
||||||
|
fprintf (fp, "%s\n", ctx->myaddr.sun_path);
|
||||||
|
fflush (fp);
|
||||||
|
|
||||||
|
/* And receive our peer's. */
|
||||||
|
memset (&ctx->serveraddr, 0, sizeof ctx->serveraddr);
|
||||||
|
for (p = ctx->serveraddr.sun_path;
|
||||||
|
p < (ctx->serveraddr.sun_path
|
||||||
|
+ sizeof ctx->serveraddr.sun_path - 1);
|
||||||
|
p ++)
|
||||||
|
{
|
||||||
|
*p = fgetc (fp);
|
||||||
|
if (*p == '\n')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*p = '\0';
|
||||||
|
fclose (fp);
|
||||||
|
|
||||||
|
ctx->serveraddr.sun_family = AF_LOCAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*r_ctx = ctx;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssuanError
|
||||||
|
assuan_domain_connect (ASSUAN_CONTEXT * r_ctx, int rendezvousfd, pid_t peer)
|
||||||
|
{
|
||||||
|
AssuanError aerr;
|
||||||
|
int okay, off;
|
||||||
|
|
||||||
|
aerr = _assuan_domain_init (r_ctx, rendezvousfd, peer);
|
||||||
|
if (aerr)
|
||||||
|
return aerr;
|
||||||
|
|
||||||
|
/* Initial handshake. */
|
||||||
|
aerr = _assuan_read_from_server (*r_ctx, &okay, &off);
|
||||||
|
if (aerr)
|
||||||
|
LOG ("can't connect to server: %s\n", assuan_strerror (aerr));
|
||||||
|
else if (okay != 1)
|
||||||
|
{
|
||||||
|
LOG ("can't connect to server: `");
|
||||||
|
_assuan_log_sanitized_string ((*r_ctx)->inbound.line);
|
||||||
|
fprintf (assuan_get_assuan_log_stream (), "'\n");
|
||||||
|
aerr = ASSUAN_Connect_Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aerr)
|
||||||
|
assuan_disconnect (*r_ctx);
|
||||||
|
|
||||||
|
return aerr;
|
||||||
|
}
|
46
assuan/assuan-domain-server.c
Normal file
46
assuan/assuan-domain-server.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* assuan-socket-server.c - Assuan socket based server
|
||||||
|
* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of Assuan.
|
||||||
|
*
|
||||||
|
* Assuan is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Assuan is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
|
/* Initialize a server. */
|
||||||
|
AssuanError
|
||||||
|
assuan_init_domain_server (ASSUAN_CONTEXT *r_ctx,
|
||||||
|
int rendezvousfd,
|
||||||
|
pid_t peer)
|
||||||
|
{
|
||||||
|
AssuanError err;
|
||||||
|
|
||||||
|
err = _assuan_domain_init (r_ctx, rendezvousfd, peer);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
(*r_ctx)->is_server = 1;
|
||||||
|
/* A domain server can only be used once. */
|
||||||
|
(*r_ctx)->pipe_mode = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/* assuan-handler.c - dispatch commands
|
/* assuan-handler.c - dispatch commands
|
||||||
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of Assuan.
|
* This file is part of Assuan.
|
||||||
*
|
*
|
||||||
@ -25,27 +25,12 @@
|
|||||||
|
|
||||||
#include "assuan-defs.h"
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define spacep(p) (*(p) == ' ' || *(p) == '\t')
|
#define spacep(p) (*(p) == ' ' || *(p) == '\t')
|
||||||
#define digitp(a) ((a) >= '0' && (a) <= '9')
|
#define digitp(a) ((a) >= '0' && (a) <= '9')
|
||||||
|
|
||||||
|
static int my_strcasecmp (const char *a, const char *b);
|
||||||
#if !HAVE_FOPENCOOKIE
|
|
||||||
/* Provide structure for our dummy replacement function. Usually this
|
|
||||||
is defined in ../common/util.h but assuan should be self
|
|
||||||
contained. */
|
|
||||||
/* Fixme: Remove fopencoookie :-(( */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
ssize_t (*read)(void*,char*,size_t);
|
|
||||||
ssize_t (*write)(void*,const char*,size_t);
|
|
||||||
int (*seek)(void*,off_t*,int);
|
|
||||||
int (*close)(void*);
|
|
||||||
} _IO_cookie_io_functions_t;
|
|
||||||
typedef _IO_cookie_io_functions_t cookie_io_functions_t;
|
|
||||||
FILE *fopencookie (void *cookie, const char *opentype,
|
|
||||||
cookie_io_functions_t funclist);
|
|
||||||
#endif /*!HAVE_FOPENCOOKIE*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -149,14 +134,17 @@ std_handler_end (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
return set_error (ctx, Not_Implemented, NULL);
|
return set_error (ctx, Not_Implemented, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
AssuanError
|
||||||
parse_cmd_input_output (ASSUAN_CONTEXT ctx, char *line, int *rfd)
|
assuan_command_parse_fd (ASSUAN_CONTEXT ctx, char *line, int *rfd)
|
||||||
{
|
{
|
||||||
char *endp;
|
char *endp;
|
||||||
|
|
||||||
if (strncmp (line, "FD=", 3))
|
if (strncmp (line, "FD", 2) != 0 || (line[2] != '=' && line[2] != '\0'))
|
||||||
return set_error (ctx, Syntax_Error, "FD=<n> expected");
|
return set_error (ctx, Syntax_Error, "FD[=<n>] expected");
|
||||||
line += 3;
|
line += 2;
|
||||||
|
if (*line == '=')
|
||||||
|
{
|
||||||
|
line ++;
|
||||||
if (!digitp (*line))
|
if (!digitp (*line))
|
||||||
return set_error (ctx, Syntax_Error, "number required");
|
return set_error (ctx, Syntax_Error, "number required");
|
||||||
*rfd = strtoul (line, &endp, 10);
|
*rfd = strtoul (line, &endp, 10);
|
||||||
@ -168,6 +156,10 @@ parse_cmd_input_output (ASSUAN_CONTEXT ctx, char *line, int *rfd)
|
|||||||
if (*rfd == ctx->outbound.fd)
|
if (*rfd == ctx->outbound.fd)
|
||||||
return set_error (ctx, Parameter_Conflict, "fd same as outbound fd");
|
return set_error (ctx, Parameter_Conflict, "fd same as outbound fd");
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* Our peer has sent the file descriptor. */
|
||||||
|
return assuan_receivefd (ctx, rfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Format is INPUT FD=<n> */
|
/* Format is INPUT FD=<n> */
|
||||||
@ -176,7 +168,7 @@ std_handler_input (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
{
|
{
|
||||||
int rc, fd;
|
int rc, fd;
|
||||||
|
|
||||||
rc = parse_cmd_input_output (ctx, line, &fd);
|
rc = assuan_command_parse_fd (ctx, line, &fd);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
ctx->input_fd = fd;
|
ctx->input_fd = fd;
|
||||||
@ -191,7 +183,7 @@ std_handler_output (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
{
|
{
|
||||||
int rc, fd;
|
int rc, fd;
|
||||||
|
|
||||||
rc = parse_cmd_input_output (ctx, line, &fd);
|
rc = assuan_command_parse_fd (ctx, line, &fd);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
ctx->output_fd = fd;
|
ctx->output_fd = fd;
|
||||||
@ -205,25 +197,24 @@ std_handler_output (ASSUAN_CONTEXT ctx, char *line)
|
|||||||
|
|
||||||
|
|
||||||
/* This is a table with the standard commands and handler for them.
|
/* This is a table with the standard commands and handler for them.
|
||||||
The table is used to initialize a new context and assuciate strings
|
The table is used to initialize a new context and associate strings
|
||||||
and handlers with cmd_ids */
|
with default handlers */
|
||||||
static struct {
|
static struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
int cmd_id;
|
|
||||||
int (*handler)(ASSUAN_CONTEXT, char *line);
|
int (*handler)(ASSUAN_CONTEXT, char *line);
|
||||||
int always; /* always initialize this command */
|
int always; /* always initialize this command */
|
||||||
} std_cmd_table[] = {
|
} std_cmd_table[] = {
|
||||||
{ "NOP", ASSUAN_CMD_NOP, std_handler_nop, 1 },
|
{ "NOP", std_handler_nop, 1 },
|
||||||
{ "CANCEL", ASSUAN_CMD_CANCEL, std_handler_cancel, 1 },
|
{ "CANCEL", std_handler_cancel, 1 },
|
||||||
{ "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 },
|
{ "OPTION", std_handler_option, 1 },
|
||||||
{ "BYE", ASSUAN_CMD_BYE, std_handler_bye, 1 },
|
{ "BYE", std_handler_bye, 1 },
|
||||||
{ "AUTH", ASSUAN_CMD_AUTH, std_handler_auth, 1 },
|
{ "AUTH", std_handler_auth, 1 },
|
||||||
{ "RESET", ASSUAN_CMD_RESET, std_handler_reset, 1 },
|
{ "RESET", std_handler_reset, 1 },
|
||||||
{ "END", ASSUAN_CMD_END, std_handler_end, 1 },
|
{ "END", std_handler_end, 1 },
|
||||||
|
|
||||||
{ "INPUT", ASSUAN_CMD_INPUT, std_handler_input },
|
{ "INPUT", std_handler_input },
|
||||||
{ "OUTPUT", ASSUAN_CMD_OUTPUT, std_handler_output },
|
{ "OUTPUT", std_handler_output },
|
||||||
{ "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 },
|
{ "OPTION", std_handler_option, 1 },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -231,53 +222,45 @@ static struct {
|
|||||||
/**
|
/**
|
||||||
* assuan_register_command:
|
* assuan_register_command:
|
||||||
* @ctx: the server context
|
* @ctx: the server context
|
||||||
* @cmd_id: An ID value for the command
|
|
||||||
* @cmd_name: A string with the command name
|
* @cmd_name: A string with the command name
|
||||||
* @handler: The handler function to be called
|
* @handler: The handler function to be called or NULL to use a default
|
||||||
|
* handler.
|
||||||
*
|
*
|
||||||
* Register a handler to be used for a given command.
|
* Register a handler to be used for a given command. Note that
|
||||||
|
* several default handlers are already regsitered with a new context.
|
||||||
|
* This function however allows to override them.
|
||||||
*
|
*
|
||||||
* The @cmd_name must be %NULL or an empty string for all @cmd_ids
|
* Return value: 0 on success or an error code
|
||||||
* below %ASSUAN_CMD_USER because predefined values are used.
|
|
||||||
*
|
|
||||||
* Return value:
|
|
||||||
**/
|
**/
|
||||||
int
|
int
|
||||||
assuan_register_command (ASSUAN_CONTEXT ctx,
|
assuan_register_command (ASSUAN_CONTEXT ctx,
|
||||||
int cmd_id, const char *cmd_name,
|
const char *cmd_name,
|
||||||
int (*handler)(ASSUAN_CONTEXT, char *))
|
int (*handler)(ASSUAN_CONTEXT, char *))
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
if (cmd_name && !*cmd_name)
|
if (cmd_name && !*cmd_name)
|
||||||
cmd_name = NULL;
|
cmd_name = NULL;
|
||||||
|
|
||||||
if (cmd_id < ASSUAN_CMD_USER)
|
|
||||||
{
|
|
||||||
if (cmd_name)
|
|
||||||
return ASSUAN_Invalid_Value; /* must be NULL for these values*/
|
|
||||||
|
|
||||||
for (i=0; std_cmd_table[i].name; i++)
|
|
||||||
{
|
|
||||||
if (std_cmd_table[i].cmd_id == cmd_id)
|
|
||||||
{
|
|
||||||
cmd_name = std_cmd_table[i].name;
|
|
||||||
if (!handler)
|
|
||||||
handler = std_cmd_table[i].handler;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!std_cmd_table[i].name)
|
|
||||||
return ASSUAN_Invalid_Value; /* not a pre-registered one */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!handler)
|
|
||||||
handler = dummy_handler;
|
|
||||||
|
|
||||||
if (!cmd_name)
|
if (!cmd_name)
|
||||||
return ASSUAN_Invalid_Value;
|
return ASSUAN_Invalid_Value;
|
||||||
|
|
||||||
/* fprintf (stderr, "DBG-assuan: registering %d as `%s'\n", cmd_id, cmd_name); */
|
if (!handler)
|
||||||
|
{ /* find a default handler. */
|
||||||
|
for (i=0; (s=std_cmd_table[i].name) && strcmp (cmd_name, s); i++)
|
||||||
|
;
|
||||||
|
if (!s)
|
||||||
|
{ /* Try again but case insensitive. */
|
||||||
|
for (i=0; (s=std_cmd_table[i].name)
|
||||||
|
&& my_strcasecmp (cmd_name, s); i++)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
if (s)
|
||||||
|
handler = std_cmd_table[i].handler;
|
||||||
|
if (!handler)
|
||||||
|
handler = dummy_handler; /* Last resort is the dummy handler. */
|
||||||
|
}
|
||||||
|
|
||||||
if (!ctx->cmdtbl)
|
if (!ctx->cmdtbl)
|
||||||
{
|
{
|
||||||
@ -299,7 +282,6 @@ assuan_register_command (ASSUAN_CONTEXT ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctx->cmdtbl[ctx->cmdtbl_used].name = cmd_name;
|
ctx->cmdtbl[ctx->cmdtbl_used].name = cmd_name;
|
||||||
ctx->cmdtbl[ctx->cmdtbl_used].cmd_id = cmd_id;
|
|
||||||
ctx->cmdtbl[ctx->cmdtbl_used].handler = handler;
|
ctx->cmdtbl[ctx->cmdtbl_used].handler = handler;
|
||||||
ctx->cmdtbl_used++;
|
ctx->cmdtbl_used++;
|
||||||
return 0;
|
return 0;
|
||||||
@ -374,8 +356,7 @@ _assuan_register_std_commands (ASSUAN_CONTEXT ctx)
|
|||||||
{
|
{
|
||||||
if (std_cmd_table[i].always)
|
if (std_cmd_table[i].always)
|
||||||
{
|
{
|
||||||
rc = assuan_register_command (ctx, std_cmd_table[i].cmd_id,
|
rc = assuan_register_command (ctx, std_cmd_table[i].name, NULL);
|
||||||
NULL, NULL);
|
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -624,17 +605,13 @@ assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what,
|
|||||||
FILE *
|
FILE *
|
||||||
assuan_get_data_fp (ASSUAN_CONTEXT ctx)
|
assuan_get_data_fp (ASSUAN_CONTEXT ctx)
|
||||||
{
|
{
|
||||||
cookie_io_functions_t cookie_fnc;
|
|
||||||
|
|
||||||
if (ctx->outbound.data.fp)
|
if (ctx->outbound.data.fp)
|
||||||
return ctx->outbound.data.fp;
|
return ctx->outbound.data.fp;
|
||||||
|
|
||||||
cookie_fnc.read = NULL;
|
|
||||||
cookie_fnc.write = _assuan_cookie_write_data;
|
|
||||||
cookie_fnc.seek = NULL;
|
|
||||||
cookie_fnc.close = _assuan_cookie_write_flush;
|
|
||||||
|
|
||||||
ctx->outbound.data.fp = fopencookie (ctx, "wb", cookie_fnc);
|
ctx->outbound.data.fp = funopen (ctx, 0,
|
||||||
|
_assuan_cookie_write_data,
|
||||||
|
0, _assuan_cookie_write_flush);
|
||||||
ctx->outbound.data.error = 0;
|
ctx->outbound.data.error = 0;
|
||||||
return ctx->outbound.data.fp;
|
return ctx->outbound.data.fp;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* assuan-inquire.c - handle inquire stuff
|
/* assuan-inquire.c - handle inquire stuff
|
||||||
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of Assuan.
|
* This file is part of Assuan.
|
||||||
*
|
*
|
||||||
@ -31,7 +31,8 @@
|
|||||||
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
|
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
|
||||||
|
|
||||||
|
|
||||||
struct membuf {
|
struct membuf
|
||||||
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
size_t size;
|
size_t size;
|
||||||
char *buf;
|
char *buf;
|
||||||
@ -139,7 +140,7 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
|
|||||||
{
|
{
|
||||||
AssuanError rc;
|
AssuanError rc;
|
||||||
struct membuf mb;
|
struct membuf mb;
|
||||||
char cmdbuf[100];
|
char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */
|
||||||
unsigned char *line, *p;
|
unsigned char *line, *p;
|
||||||
int linelen;
|
int linelen;
|
||||||
int nodataexpected;
|
int nodataexpected;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* assuan-buffer.c - Wraps the read and write functions.
|
/* assuan-io.c - Wraps the read and write functions.
|
||||||
* Copyright (C) 2002 Free Software Foundation, Inc.
|
* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of Assuan.
|
* This file is part of Assuan.
|
||||||
@ -18,6 +18,7 @@
|
|||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "assuan-defs.h"
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -28,33 +29,13 @@ extern ssize_t pth_write (int fd, const void *buffer, size_t size);
|
|||||||
#pragma weak pth_write
|
#pragma weak pth_write
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
_assuan_read (int fd, void *buffer, size_t size)
|
_assuan_simple_read (ASSUAN_CONTEXT ctx, void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
static ssize_t (*reader) (int, void *, size_t);
|
return (pth_read ? pth_read : read) (ctx->inbound.fd, buffer, size);
|
||||||
|
|
||||||
if (! reader)
|
|
||||||
{
|
|
||||||
if (pth_read)
|
|
||||||
reader = pth_read;
|
|
||||||
else
|
|
||||||
reader = read;
|
|
||||||
}
|
|
||||||
|
|
||||||
return reader (fd, buffer, size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
_assuan_write (int fd, const void *buffer, size_t size)
|
_assuan_simple_write (ASSUAN_CONTEXT ctx, const void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
static ssize_t (*writer) (int, const void *, size_t);
|
return (pth_write ? pth_write : write) (ctx->outbound.fd, buffer, size);
|
||||||
|
|
||||||
if (! writer)
|
|
||||||
{
|
|
||||||
if (pth_write)
|
|
||||||
writer = pth_write;
|
|
||||||
else
|
|
||||||
writer = write;
|
|
||||||
}
|
|
||||||
|
|
||||||
return writer (fd, buffer, size);
|
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line)
|
|||||||
* assuan_accept:
|
* assuan_accept:
|
||||||
* @ctx: context
|
* @ctx: context
|
||||||
*
|
*
|
||||||
* Cancel any existing connectiion and wait for a connection from a
|
* Cancel any existing connection and wait for a connection from a
|
||||||
* client. The initial handshake is performed which may include an
|
* client. The initial handshake is performed which may include an
|
||||||
* initial authentication or encryption negotiation.
|
* initial authentication or encryption negotiation.
|
||||||
*
|
*
|
||||||
|
42
assuan/assuan-logging.c
Normal file
42
assuan/assuan-logging.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* assuan-logging.c - Default logging function.
|
||||||
|
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of Assuan.
|
||||||
|
*
|
||||||
|
* Assuan is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Assuan is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "assuan-defs.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static FILE *_assuan_log;
|
||||||
|
|
||||||
|
void
|
||||||
|
assuan_set_assuan_log_stream (FILE *fp)
|
||||||
|
{
|
||||||
|
_assuan_log = fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *
|
||||||
|
assuan_get_assuan_log_stream (void)
|
||||||
|
{
|
||||||
|
return _assuan_log ? _assuan_log : stderr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
assuan_get_assuan_log_prefix (void)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/* assuan-pipe-connect.c - Establish a pipe connection (client)
|
/* assuan-pipe-connect.c - Establish a pipe connection (client)
|
||||||
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of Assuan.
|
* This file is part of Assuan.
|
||||||
*
|
*
|
||||||
@ -40,17 +40,13 @@
|
|||||||
#define MAX_OPEN_FDS 20
|
#define MAX_OPEN_FDS 20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_JNLIB_LOGGING
|
#define LOG(format, args...) \
|
||||||
#include "../jnlib/logging.h"
|
fprintf (assuan_get_assuan_log_stream (), \
|
||||||
#define LOGERROR1(a,b) log_error ((a), (b))
|
assuan_get_assuan_log_prefix (), \
|
||||||
#else
|
"%s" format , ## args)
|
||||||
#define LOGERROR1(a,b) fprintf (stderr, (a), (b))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
writen ( int fd, const char *buffer, size_t length )
|
writen (int fd, const char *buffer, size_t length)
|
||||||
{
|
{
|
||||||
while (length)
|
while (length)
|
||||||
{
|
{
|
||||||
@ -177,7 +173,7 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
|
|||||||
{
|
{
|
||||||
if (dup2 (rp[1], STDOUT_FILENO) == -1)
|
if (dup2 (rp[1], STDOUT_FILENO) == -1)
|
||||||
{
|
{
|
||||||
LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno));
|
LOG ("dup2 failed in child: %s\n", strerror (errno));
|
||||||
_exit (4);
|
_exit (4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,7 +181,7 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
|
|||||||
{
|
{
|
||||||
if (dup2 (wp[0], STDIN_FILENO) == -1)
|
if (dup2 (wp[0], STDIN_FILENO) == -1)
|
||||||
{
|
{
|
||||||
LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno));
|
LOG ("dup2 failed in child: %s\n", strerror (errno));
|
||||||
_exit (4);
|
_exit (4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,12 +199,12 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
|
|||||||
int fd = open ("/dev/null", O_WRONLY);
|
int fd = open ("/dev/null", O_WRONLY);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
LOGERROR1 ("can't open `/dev/null': %s\n", strerror (errno));
|
LOG ("can't open `/dev/null': %s\n", strerror (errno));
|
||||||
_exit (4);
|
_exit (4);
|
||||||
}
|
}
|
||||||
if (dup2 (fd, STDERR_FILENO) == -1)
|
if (dup2 (fd, STDERR_FILENO) == -1)
|
||||||
{
|
{
|
||||||
LOGERROR1 ("dup2(dev/null, 2) failed: %s\n", strerror (errno));
|
LOG ("dup2(dev/null, 2) failed: %s\n", strerror (errno));
|
||||||
_exit (4);
|
_exit (4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -253,12 +249,10 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
|
|||||||
|
|
||||||
err = _assuan_read_from_server (*ctx, &okay, &off);
|
err = _assuan_read_from_server (*ctx, &okay, &off);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
LOG ("can't connect server: %s\n", assuan_strerror (err));
|
||||||
LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err));
|
|
||||||
}
|
|
||||||
else if (okay != 1)
|
else if (okay != 1)
|
||||||
{
|
{
|
||||||
LOGERROR1 ("can't connect server: `%s'\n", (*ctx)->inbound.line);
|
LOG ("can't connect server: `%s'\n", (*ctx)->inbound.line);
|
||||||
err = ASSUAN_Connect_Failed;
|
err = ASSUAN_Connect_Failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "assuan-defs.h"
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
@ -44,12 +45,15 @@ finish_connection (ASSUAN_CONTEXT ctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create a new context. Note that the handlers are set up for a pipe
|
/* Create a new context. Note that the handlers are set up for a pipe
|
||||||
server/client - this way we don't need extra dummy functions */
|
server/client - this way we don't need extra dummy functions */
|
||||||
int
|
int
|
||||||
_assuan_new_context (ASSUAN_CONTEXT *r_ctx)
|
_assuan_new_context (ASSUAN_CONTEXT *r_ctx)
|
||||||
{
|
{
|
||||||
|
static struct assuan_io io = { _assuan_simple_read,
|
||||||
|
_assuan_simple_write,
|
||||||
|
0, 0 };
|
||||||
|
|
||||||
ASSUAN_CONTEXT ctx;
|
ASSUAN_CONTEXT ctx;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@ -62,10 +66,11 @@ _assuan_new_context (ASSUAN_CONTEXT *r_ctx)
|
|||||||
|
|
||||||
ctx->inbound.fd = -1;
|
ctx->inbound.fd = -1;
|
||||||
ctx->outbound.fd = -1;
|
ctx->outbound.fd = -1;
|
||||||
|
ctx->io = &io;
|
||||||
|
|
||||||
ctx->listen_fd = -1;
|
ctx->listen_fd = -1;
|
||||||
ctx->client_pid = (pid_t)-1;
|
ctx->client_pid = (pid_t)-1;
|
||||||
/* use the pipe server handler as a default */
|
/* Use the pipe server handler as a default. */
|
||||||
ctx->deinit_handler = deinit_pipe_server;
|
ctx->deinit_handler = deinit_pipe_server;
|
||||||
ctx->accept_handler = accept_connection;
|
ctx->accept_handler = accept_connection;
|
||||||
ctx->finish_handler = finish_connection;
|
ctx->finish_handler = finish_connection;
|
||||||
@ -116,7 +121,7 @@ assuan_deinit_server (ASSUAN_CONTEXT ctx)
|
|||||||
if (ctx)
|
if (ctx)
|
||||||
{
|
{
|
||||||
/* We use this function pointer to avoid linking other server
|
/* We use this function pointer to avoid linking other server
|
||||||
when not needed but still allow for a generic deinit function */
|
when not needed but still allow for a generic deinit function. */
|
||||||
ctx->deinit_handler (ctx);
|
ctx->deinit_handler (ctx);
|
||||||
ctx->deinit_handler = NULL;
|
ctx->deinit_handler = NULL;
|
||||||
_assuan_release_context (ctx);
|
_assuan_release_context (ctx);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* assuan-socket-connect.c - Assuan socket based client
|
/* assuan-socket-connect.c - Assuan socket based client
|
||||||
* Copyright (C) 2002 Free Software Foundation, Inc.
|
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of Assuan.
|
* This file is part of Assuan.
|
||||||
*
|
*
|
||||||
@ -29,20 +29,10 @@
|
|||||||
|
|
||||||
#include "assuan-defs.h"
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
#ifdef HAVE_JNLIB_LOGGING
|
#define LOG(format, args...) \
|
||||||
#include "../jnlib/logging.h"
|
fprintf (assuan_get_assuan_log_stream (), \
|
||||||
#define LOGERROR(a) log_error ((a))
|
assuan_get_assuan_log_prefix (), \
|
||||||
#define LOGERROR1(a,b) log_error ((a), (b))
|
"%s" format , ## args)
|
||||||
#define LOGERROR2(a,b,c) log_error ((a), (b), (c))
|
|
||||||
#define LOGERRORX(a) log_printf ((a))
|
|
||||||
#else
|
|
||||||
#define LOGERROR(a) fprintf (stderr, (a))
|
|
||||||
#define LOGERROR1(a,b) fprintf (stderr, (a), (b))
|
|
||||||
#define LOGERROR2(a,b,c) fprintf (stderr, (a), (b), (c))
|
|
||||||
#define LOGERRORX(a) fputs ((a), stderr)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_finish (ASSUAN_CONTEXT ctx)
|
do_finish (ASSUAN_CONTEXT ctx)
|
||||||
@ -61,9 +51,6 @@ do_deinit (ASSUAN_CONTEXT ctx)
|
|||||||
{
|
{
|
||||||
do_finish (ctx);
|
do_finish (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Make a connection to the Unix domain socket NAME and return a new
|
/* 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
|
Assuan context in CTX. SERVER_PID is currently not used but may
|
||||||
become handy in the future. */
|
become handy in the future. */
|
||||||
@ -71,6 +58,9 @@ AssuanError
|
|||||||
assuan_socket_connect (ASSUAN_CONTEXT *r_ctx,
|
assuan_socket_connect (ASSUAN_CONTEXT *r_ctx,
|
||||||
const char *name, pid_t server_pid)
|
const char *name, pid_t server_pid)
|
||||||
{
|
{
|
||||||
|
static struct assuan_io io = { _assuan_simple_read,
|
||||||
|
_assuan_simple_write };
|
||||||
|
|
||||||
AssuanError err;
|
AssuanError err;
|
||||||
ASSUAN_CONTEXT ctx;
|
ASSUAN_CONTEXT ctx;
|
||||||
int fd;
|
int fd;
|
||||||
@ -95,30 +85,31 @@ assuan_socket_connect (ASSUAN_CONTEXT *r_ctx,
|
|||||||
ctx->deinit_handler = do_deinit;
|
ctx->deinit_handler = do_deinit;
|
||||||
ctx->finish_handler = do_finish;
|
ctx->finish_handler = do_finish;
|
||||||
|
|
||||||
fd = socket (AF_UNIX, SOCK_STREAM, 0);
|
fd = socket (PF_LOCAL, SOCK_STREAM, 0);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
LOGERROR1 ("can't create socket: %s\n", strerror (errno));
|
LOG ("can't create socket: %s\n", strerror (errno));
|
||||||
_assuan_release_context (ctx);
|
_assuan_release_context (ctx);
|
||||||
return ASSUAN_General_Error;
|
return ASSUAN_General_Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (&srvr_addr, 0, sizeof srvr_addr );
|
memset (&srvr_addr, 0, sizeof srvr_addr);
|
||||||
srvr_addr.sun_family = AF_UNIX;
|
srvr_addr.sun_family = AF_LOCAL;
|
||||||
strcpy (srvr_addr.sun_path, name);
|
len = strlen (srvr_addr.sun_path) + 1;
|
||||||
len = (offsetof (struct sockaddr_un, sun_path)
|
memcpy (srvr_addr.sun_path, name, len);
|
||||||
+ strlen (srvr_addr.sun_path) + 1);
|
len += (offsetof (struct sockaddr_un, sun_path));
|
||||||
|
|
||||||
if (connect (fd, (struct sockaddr*)&srvr_addr, len) == -1)
|
if (connect (fd, (struct sockaddr *) &srvr_addr, len) == -1)
|
||||||
{
|
{
|
||||||
LOGERROR2 ("can't connect to `%s': %s\n", name, strerror (errno));
|
LOG ("can't connect to `%s': %s\n", name, strerror (errno));
|
||||||
_assuan_release_context (ctx);
|
_assuan_release_context (ctx);
|
||||||
close (fd );
|
close (fd);
|
||||||
return ASSUAN_Connect_Failed;
|
return ASSUAN_Connect_Failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->inbound.fd = fd;
|
ctx->inbound.fd = fd;
|
||||||
ctx->outbound.fd = fd;
|
ctx->outbound.fd = fd;
|
||||||
|
ctx->io = &io;
|
||||||
|
|
||||||
/* initial handshake */
|
/* initial handshake */
|
||||||
{
|
{
|
||||||
@ -126,14 +117,12 @@ assuan_socket_connect (ASSUAN_CONTEXT *r_ctx,
|
|||||||
|
|
||||||
err = _assuan_read_from_server (ctx, &okay, &off);
|
err = _assuan_read_from_server (ctx, &okay, &off);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
LOG ("can't connect to server: %s\n", assuan_strerror (err));
|
||||||
LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err));
|
|
||||||
}
|
|
||||||
else if (okay != 1)
|
else if (okay != 1)
|
||||||
{
|
{
|
||||||
LOGERROR ("can't connect server: `");
|
LOG ("can't connect to server: `");
|
||||||
_assuan_log_sanitized_string (ctx->inbound.line);
|
_assuan_log_sanitized_string (ctx->inbound.line);
|
||||||
LOGERRORX ("'\n");
|
fprintf (assuan_get_assuan_log_stream (), "'\n");
|
||||||
err = ASSUAN_Connect_Failed;
|
err = ASSUAN_Connect_Failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,5 +135,3 @@ assuan_socket_connect (ASSUAN_CONTEXT *r_ctx,
|
|||||||
*r_ctx = ctx;
|
*r_ctx = ctx;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,7 +98,8 @@ deinit_socket_server (ASSUAN_CONTEXT ctx)
|
|||||||
finish_connection (ctx);
|
finish_connection (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct assuan_io io = { _assuan_simple_read,
|
||||||
|
_assuan_simple_write };
|
||||||
|
|
||||||
/* Initialize a server for the socket LISTEN_FD which has already be
|
/* Initialize a server for the socket LISTEN_FD which has already be
|
||||||
put into listen mode */
|
put into listen mode */
|
||||||
@ -125,6 +126,8 @@ assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd)
|
|||||||
ctx->accept_handler = accept_connection;
|
ctx->accept_handler = accept_connection;
|
||||||
ctx->finish_handler = finish_connection;
|
ctx->finish_handler = finish_connection;
|
||||||
|
|
||||||
|
ctx->io = &io;
|
||||||
|
|
||||||
rc = _assuan_register_std_commands (ctx);
|
rc = _assuan_register_std_commands (ctx);
|
||||||
if (rc)
|
if (rc)
|
||||||
xfree (ctx);
|
xfree (ctx);
|
||||||
@ -145,13 +148,15 @@ assuan_init_connected_socket_server (ASSUAN_CONTEXT *r_ctx, int fd)
|
|||||||
if (!ctx)
|
if (!ctx)
|
||||||
return ASSUAN_Out_Of_Core;
|
return ASSUAN_Out_Of_Core;
|
||||||
ctx->is_server = 1;
|
ctx->is_server = 1;
|
||||||
ctx->pipe_mode = 1; /* we wan't a second accept to indicate EOF */
|
ctx->pipe_mode = 1; /* we want a second accept to indicate EOF */
|
||||||
ctx->input_fd = -1;
|
ctx->input_fd = -1;
|
||||||
ctx->output_fd = -1;
|
ctx->output_fd = -1;
|
||||||
|
|
||||||
ctx->inbound.fd = -1;
|
ctx->inbound.fd = -1;
|
||||||
ctx->outbound.fd = -1;
|
ctx->outbound.fd = -1;
|
||||||
|
|
||||||
|
ctx->io = &io;
|
||||||
|
|
||||||
ctx->listen_fd = -1;
|
ctx->listen_fd = -1;
|
||||||
ctx->connected_fd = fd;
|
ctx->connected_fd = fd;
|
||||||
ctx->deinit_handler = deinit_socket_server;
|
ctx->deinit_handler = deinit_socket_server;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* assuan-util.c - Utility functions for Assuan
|
/* assuan-util.c - Utility functions for Assuan
|
||||||
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of Assuan.
|
* This file is part of Assuan.
|
||||||
*
|
*
|
||||||
@ -26,10 +26,6 @@
|
|||||||
|
|
||||||
#include "assuan-defs.h"
|
#include "assuan-defs.h"
|
||||||
|
|
||||||
#ifdef HAVE_JNLIB_LOGGING
|
|
||||||
#include "../jnlib/logging.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void *(*alloc_func)(size_t n) = malloc;
|
static void *(*alloc_func)(size_t n) = malloc;
|
||||||
static void *(*realloc_func)(void *p, size_t n) = realloc;
|
static void *(*realloc_func)(void *p, size_t n) = realloc;
|
||||||
static void (*free_func)(void*) = free;
|
static void (*free_func)(void*) = free;
|
||||||
@ -159,18 +155,13 @@ _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Log a user supplied string. Escapes non-printable before
|
/* Log a user supplied string. Escapes non-printable before
|
||||||
printing. */
|
printing. */
|
||||||
void
|
void
|
||||||
_assuan_log_sanitized_string (const char *string)
|
_assuan_log_sanitized_string (const char *string)
|
||||||
{
|
{
|
||||||
const unsigned char *s = string;
|
const unsigned char *s = string;
|
||||||
#ifdef HAVE_JNLIB_LOGGING
|
FILE *fp = assuan_get_assuan_log_stream ();
|
||||||
FILE *fp = log_get_stream ();
|
|
||||||
#else
|
|
||||||
FILE *fp = stderr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (! *s)
|
if (! *s)
|
||||||
return;
|
return;
|
||||||
@ -226,5 +217,3 @@ _assuan_log_sanitized_string (const char *string)
|
|||||||
funlockfile (fp);
|
funlockfile (fp);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* assuan.c - Definitions for the Assuan protocol
|
/* assuan.c - Definitions for the Assuan protocol
|
||||||
* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of Assuan.
|
* This file is part of Assuan.
|
||||||
*
|
*
|
||||||
@ -23,16 +23,15 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h> /* for ssize_t */
|
#include <unistd.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C"
|
||||||
#if 0
|
{
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
ASSUAN_No_Error = 0,
|
ASSUAN_No_Error = 0,
|
||||||
ASSUAN_General_Error = 1,
|
ASSUAN_General_Error = 1,
|
||||||
ASSUAN_Out_Of_Core = 2,
|
ASSUAN_Out_Of_Core = 2,
|
||||||
@ -105,7 +104,8 @@ typedef enum {
|
|||||||
} AssuanError;
|
} AssuanError;
|
||||||
|
|
||||||
/* This is a list of pre-registered ASSUAN commands */
|
/* This is a list of pre-registered ASSUAN commands */
|
||||||
typedef enum {
|
typedef enum
|
||||||
|
{
|
||||||
ASSUAN_CMD_NOP = 0,
|
ASSUAN_CMD_NOP = 0,
|
||||||
ASSUAN_CMD_CANCEL, /* cancel the current request */
|
ASSUAN_CMD_CANCEL, /* cancel the current request */
|
||||||
ASSUAN_CMD_BYE,
|
ASSUAN_CMD_BYE,
|
||||||
@ -127,7 +127,7 @@ typedef struct assuan_context_s *ASSUAN_CONTEXT;
|
|||||||
|
|
||||||
/*-- assuan-handler.c --*/
|
/*-- assuan-handler.c --*/
|
||||||
int assuan_register_command (ASSUAN_CONTEXT ctx,
|
int assuan_register_command (ASSUAN_CONTEXT ctx,
|
||||||
int cmd_id, const char *cmd_string,
|
const char *cmd_string,
|
||||||
int (*handler)(ASSUAN_CONTEXT, char *));
|
int (*handler)(ASSUAN_CONTEXT, char *));
|
||||||
int assuan_register_bye_notify (ASSUAN_CONTEXT ctx,
|
int assuan_register_bye_notify (ASSUAN_CONTEXT ctx,
|
||||||
void (*fnc)(ASSUAN_CONTEXT));
|
void (*fnc)(ASSUAN_CONTEXT));
|
||||||
@ -155,6 +155,12 @@ AssuanError assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line);
|
|||||||
void assuan_write_status (ASSUAN_CONTEXT ctx,
|
void assuan_write_status (ASSUAN_CONTEXT ctx,
|
||||||
const char *keyword, const char *text);
|
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,
|
||||||
|
int *rfd);
|
||||||
|
|
||||||
/*-- assuan-listen.c --*/
|
/*-- assuan-listen.c --*/
|
||||||
AssuanError assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line);
|
AssuanError assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line);
|
||||||
@ -181,6 +187,26 @@ AssuanError assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name,
|
|||||||
AssuanError assuan_socket_connect (ASSUAN_CONTEXT *ctx, const char *name,
|
AssuanError assuan_socket_connect (ASSUAN_CONTEXT *ctx, const char *name,
|
||||||
pid_t server_pid);
|
pid_t server_pid);
|
||||||
|
|
||||||
|
/*-- assuan-domain-connect.c --*/
|
||||||
|
|
||||||
|
/* Connect to a Unix domain socket server. RENDEZVOUSFD is
|
||||||
|
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,
|
||||||
|
int rendezvousfd,
|
||||||
|
pid_t server);
|
||||||
|
|
||||||
|
/*-- assuan-domain-server.c --*/
|
||||||
|
|
||||||
|
/* 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,
|
||||||
|
int rendezvousfd,
|
||||||
|
pid_t client);
|
||||||
|
|
||||||
|
|
||||||
/*-- assuan-connect.c --*/
|
/*-- assuan-connect.c --*/
|
||||||
void assuan_disconnect (ASSUAN_CONTEXT ctx);
|
void assuan_disconnect (ASSUAN_CONTEXT ctx);
|
||||||
pid_t assuan_get_pid (ASSUAN_CONTEXT ctx);
|
pid_t assuan_get_pid (ASSUAN_CONTEXT ctx);
|
||||||
@ -209,6 +235,12 @@ AssuanError assuan_write_line (ASSUAN_CONTEXT ctx, const char *line );
|
|||||||
AssuanError assuan_send_data (ASSUAN_CONTEXT ctx,
|
AssuanError assuan_send_data (ASSUAN_CONTEXT ctx,
|
||||||
const void *buffer, size_t length);
|
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-util.c --*/
|
/*-- assuan-util.c --*/
|
||||||
void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
|
void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
|
||||||
@ -225,8 +257,21 @@ void assuan_end_confidential (ASSUAN_CONTEXT ctx);
|
|||||||
/*-- assuan-errors.c (built) --*/
|
/*-- assuan-errors.c (built) --*/
|
||||||
const char *assuan_strerror (AssuanError err);
|
const char *assuan_strerror (AssuanError err);
|
||||||
|
|
||||||
|
/*-- assuan-logging.c --*/
|
||||||
|
|
||||||
|
/* Set the stream to which assuan should log. By default, this is
|
||||||
|
stderr. */
|
||||||
|
extern void assuan_set_assuan_log_stream (FILE *fp);
|
||||||
|
|
||||||
|
/* Return the stream which is currently being using for 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);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif /*ASSUAN_H*/
|
#endif /* ASSUAN_H */
|
||||||
|
@ -40,7 +40,7 @@ const char *
|
|||||||
assuan_strerror (AssuanError err)
|
assuan_strerror (AssuanError err)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
static char buf[25];
|
static char buf[50];
|
||||||
|
|
||||||
switch (err)
|
switch (err)
|
||||||
{
|
{
|
||||||
@ -62,7 +62,18 @@ printf "%s\"; break;\n", tolower(substr(s,8));
|
|||||||
'
|
'
|
||||||
|
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
default: sprintf (buf, "ec=%d", err ); s=buf; break;
|
default:
|
||||||
|
{
|
||||||
|
unsigned int source, code;
|
||||||
|
|
||||||
|
source = ((err >> 24) & 0xff);
|
||||||
|
code = (err & 0x00ffffff);
|
||||||
|
if (source) /* Assume this is an libgpg-error. */
|
||||||
|
sprintf (buf, "ec=%u.%u", source, code );
|
||||||
|
else
|
||||||
|
sprintf (buf, "ec=%d", err );
|
||||||
|
s=buf; break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
53
configure.ac
53
configure.ac
@ -77,8 +77,8 @@ AC_SUBST(VERSION)
|
|||||||
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package])
|
AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package])
|
||||||
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package])
|
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package])
|
||||||
|
|
||||||
dnl Don't default to build static libs.
|
# Don't default to build static libs.
|
||||||
dnl AC_DISABLE_STATIC
|
AC_DISABLE_STATIC
|
||||||
AC_PROG_LIBTOOL
|
AC_PROG_LIBTOOL
|
||||||
|
|
||||||
AC_CANONICAL_HOST
|
AC_CANONICAL_HOST
|
||||||
@ -125,38 +125,31 @@ case "${host}" in
|
|||||||
AC_DEFINE(HAVE_PTHREAD, ,[Define if we have pthread.])
|
AC_DEFINE(HAVE_PTHREAD, ,[Define if we have pthread.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl # XXX: Probably use exec-prefix here?
|
# XXX: Probably use exec-prefix here?
|
||||||
dnl GPG_DEFAULT='/usr/bin/gpg'
|
# GPG_DEFAULT='/usr/bin/gpg'
|
||||||
dnl GPGSM_DEFAULT='/usr/bin/gpgsm'
|
# GPGSM_DEFAULT='/usr/bin/gpgsm'
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = "yes")
|
AM_CONDITIONAL(HAVE_DOSISH_SYSTEM, test "$have_dosish_system" = "yes")
|
||||||
AM_CONDITIONAL(HAVE_PTH, test "$have_pth" = "yes")
|
AM_CONDITIONAL(HAVE_PTH, test "$have_pth" = "yes")
|
||||||
AM_CONDITIONAL(HAVE_PTHREAD, test "$have_pthread" = "yes")
|
AM_CONDITIONAL(HAVE_PTHREAD, test "$have_pthread" = "yes")
|
||||||
|
|
||||||
dnl
|
|
||||||
dnl Checks for header files.
|
# Checks for header files.
|
||||||
dnl
|
|
||||||
AC_CHECK_HEADERS(sys/select.h)
|
AC_CHECK_HEADERS(sys/select.h)
|
||||||
|
|
||||||
dnl
|
|
||||||
dnl Type checks.
|
|
||||||
dnl
|
|
||||||
|
|
||||||
|
# Type checks.
|
||||||
AC_CHECK_SIZEOF(unsigned int)
|
AC_CHECK_SIZEOF(unsigned int)
|
||||||
|
|
||||||
dnl
|
|
||||||
dnl Checks for compiler features.
|
|
||||||
dnl
|
|
||||||
|
|
||||||
|
# Checks for compiler features.
|
||||||
if test "$GCC" = yes; then
|
if test "$GCC" = yes; then
|
||||||
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
|
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl
|
|
||||||
dnl Checks for library functions.
|
|
||||||
dnl
|
|
||||||
|
|
||||||
|
# Checks for library functions.
|
||||||
AC_REPLACE_FUNCS(stpcpy)
|
AC_REPLACE_FUNCS(stpcpy)
|
||||||
|
|
||||||
AC_REPLACE_FUNCS(vasprintf)
|
AC_REPLACE_FUNCS(vasprintf)
|
||||||
@ -164,17 +157,11 @@ if test "$ac_cv_func_vasprintf" != yes; then
|
|||||||
GNUPG_CHECK_VA_COPY
|
GNUPG_CHECK_VA_COPY
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Note: fopencokie is only a dummy stub and not used.
|
|
||||||
# However some code in assuan/ links against it.
|
|
||||||
AC_REPLACE_FUNCS(fopencookie)
|
|
||||||
|
|
||||||
AM_PATH_GPG_ERROR(0.1,, AC_MSG_ERROR([libgpg-error was not found]))
|
AM_PATH_GPG_ERROR(0.1,, AC_MSG_ERROR([libgpg-error was not found]))
|
||||||
AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GPGME,
|
AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GPGME,
|
||||||
[The default error source for GPGME.])
|
[The default error source for GPGME.])
|
||||||
dnl
|
|
||||||
dnl Checks for system services
|
|
||||||
dnl
|
|
||||||
|
|
||||||
|
# Checks for system services
|
||||||
NO_OVERRIDE=no
|
NO_OVERRIDE=no
|
||||||
AC_ARG_WITH(gpg,
|
AC_ARG_WITH(gpg,
|
||||||
AC_HELP_STRING([--with-gpg=PATH], [use GnuPG binary at PATH]),
|
AC_HELP_STRING([--with-gpg=PATH], [use GnuPG binary at PATH]),
|
||||||
@ -235,9 +222,25 @@ AM_CONDITIONAL(HAVE_GPGSM, [test -n "$GPGSM" && test -r "$GPGSM"])
|
|||||||
AM_CONDITIONAL(RUN_GPGSM_TESTS,
|
AM_CONDITIONAL(RUN_GPGSM_TESTS,
|
||||||
[test "$cross_compiling" != "yes" && test -n "$GPGSM" && test -r "$GPGSM"])
|
[test "$cross_compiling" != "yes" && test -n "$GPGSM" && test -r "$GPGSM"])
|
||||||
|
|
||||||
dnl FIXME: Only build if supported.
|
# FIXME: Only build if supported.
|
||||||
AM_CONDITIONAL(BUILD_ASSUAN, test "$GPGSM" != "no")
|
AM_CONDITIONAL(BUILD_ASSUAN, test "$GPGSM" != "no")
|
||||||
|
|
||||||
|
if test "$GPGSM" != "no"; then
|
||||||
|
AC_CHECK_FUNCS(funopen)
|
||||||
|
if test $ac_cv_func_funopen != yes; then
|
||||||
|
# No funopen but we can implement that in terms of fopencookie.
|
||||||
|
AC_CHECK_FUNCS(fopencookie, AC_LIBOBJ(funopen),
|
||||||
|
AC_MSG_ERROR([[
|
||||||
|
No implementation of fopencookie or funopen available.
|
||||||
|
]]))
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_REPLACE_FUNCS(isascii)
|
||||||
|
AC_REPLACE_FUNCS(putc_unlocked)
|
||||||
|
AC_REPLACE_FUNCS(memrchr)
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
AM_CONDITIONAL(BUILD_COMPLUS, test "$component_system" = "COM+")
|
AM_CONDITIONAL(BUILD_COMPLUS, test "$component_system" = "COM+")
|
||||||
|
|
||||||
dnl Make the version number in gpgme/gpgme.h the same as the one here.
|
dnl Make the version number in gpgme/gpgme.h the same as the one here.
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2003-08-18 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
|
* funopen.c, putc_unlocked.c, isascii.c, memrchr.c: New files.
|
||||||
|
* fopencookie.c: File removed.
|
||||||
|
|
||||||
2003-08-15 Marcus Brinkmann <marcus@g10code.de>
|
2003-08-15 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* gpgme-config.in: Put gpg-error related flags after gpgme's.
|
* gpgme-config.in: Put gpg-error related flags after gpgme's.
|
||||||
|
44
gpgme/funopen.c
Normal file
44
gpgme/funopen.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* funopen.c - Replacement for funopen.
|
||||||
|
* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_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)
|
||||||
|
{
|
||||||
|
cookie_io_functions_t io = { read: readfn, write: writefn,
|
||||||
|
seek: seekfn,
|
||||||
|
close: closefn };
|
||||||
|
|
||||||
|
return fopencookie ((void *) cookie,
|
||||||
|
readfn ? ( writefn ? "rw" : "r" )
|
||||||
|
: ( writefn ? "w" : ""), io);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error No known way to implement funopen.
|
||||||
|
#endif
|
@ -63,7 +63,7 @@ extern "C" {
|
|||||||
AM_PATH_GPGME macro) check that this header matches the installed
|
AM_PATH_GPGME macro) check that this header matches the installed
|
||||||
library. Warning: Do not edit the next line. configure will do
|
library. Warning: Do not edit the next line. configure will do
|
||||||
that for you! */
|
that for you! */
|
||||||
#define GPGME_VERSION "0.4.2"
|
#define GPGME_VERSION "0.4.3"
|
||||||
|
|
||||||
|
|
||||||
/* Some opaque data types used by GPGME. */
|
/* Some opaque data types used by GPGME. */
|
||||||
|
29
gpgme/isascii.c
Normal file
29
gpgme/isascii.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* isascii.c - Replacement for isascii.
|
||||||
|
* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
isascii (int c)
|
||||||
|
{
|
||||||
|
return (((c) & ~0x7f) == 0);
|
||||||
|
}
|
36
gpgme/memrchr.c
Normal file
36
gpgme/memrchr.c
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/* memrchr.c - Replacement for memrchr.
|
||||||
|
* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
*
|
||||||
|
* This file is part of GnuPG.
|
||||||
|
*
|
||||||
|
* GnuPG is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* GnuPG is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void *
|
||||||
|
memrchr (const void *block, int c, size_t size)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
for (p = block + size; p != block; p --)
|
||||||
|
if (*p == c)
|
||||||
|
return p;
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
/* fopencookie.c - Dummy glibc replacement
|
/* putc_unlocked.c - Replacement for putc_unlocked.
|
||||||
* Copyright (C) 2002 Free Software Foundation, Inc.
|
* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
@ -21,17 +21,11 @@
|
|||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "util.h"
|
int
|
||||||
|
putc_unlocked (int c, FILE *stream)
|
||||||
FILE *
|
|
||||||
fopencookie (void *cookie, const char *opentype,
|
|
||||||
cookie_io_functions_t funclist)
|
|
||||||
{
|
{
|
||||||
errno = ENOSYS;
|
return putc (c, stream);
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user