mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-23 10:29:58 +01:00
Removed assuan because we now use libassuan
This commit is contained in:
parent
7fe578ce22
commit
fd959cdb59
283
assuan/ChangeLog
283
assuan/ChangeLog
@ -1,283 +0,0 @@
|
||||
2002-11-10 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-pipe-connect.c (assuan_pipe_connect): Changed the order
|
||||
of the dups to handle cases where we have already used fd 2 for
|
||||
other things.
|
||||
|
||||
2002-10-31 Neal H. Walfield <neal@g10code.de>
|
||||
|
||||
* assuan-util.c: Include <ctype.h>.
|
||||
(_assuan_log_print_buffer): Elide the magic numbers preferring the
|
||||
standard isfoo functions. Use putc_unlocked where possible.
|
||||
(_assuan_log_sanitized_string): Rewrite to use putc_unlocked and
|
||||
the isfoo functions.
|
||||
|
||||
2002-09-05 Neal H. Walfield <neal@g10code.de>
|
||||
|
||||
* assuan-defs.h (_assuan_read_wrapper): Depreciated.
|
||||
* assuan-util.c (_assuan_read_wrapper): Removed.
|
||||
* assuan-defs.h (_assuan_write_wrapper): Depreciated.
|
||||
* assuan-util.c (_assuan_write_wrapper): Removed.
|
||||
* assuan.h (assuan_set_io_fun): Depreciated.
|
||||
* assuan-util.c (assuan_set_io_fun): Removed.
|
||||
|
||||
* assuan-defs.h (_assuan_read): New function.
|
||||
(_assuan_write): Likewise.
|
||||
* assuan-io.c: New file.
|
||||
|
||||
* assuan-buffer.c (writen): Use _assuan_write rather than doing
|
||||
the work here.
|
||||
(readline): Likewise for _assuan_read.
|
||||
|
||||
* Makefile.am (libassuan_a_SOURCES): Add assuan-io.c.
|
||||
|
||||
2002-08-16 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan.h: Renamed Bad_Certificate_Path to Bad_Certificate_Chain.
|
||||
|
||||
2002-07-30 Werner Koch <wk@gnupg.org>
|
||||
|
||||
Changed the license from GPL to LGPL.
|
||||
|
||||
2002-07-23 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-handler.c (_IO_cookie_io_functions_t): Define it here if
|
||||
it does not exists.
|
||||
|
||||
2002-06-27 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-pipe-connect.c (assuan_pipe_connect): No special handling
|
||||
for the log_fd and stderr. Connect stderr to /dev/null if it
|
||||
should not be retained.
|
||||
|
||||
2002-06-26 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-buffer.c (assuan_write_line): Make sure we never
|
||||
accidently print an extra LF.
|
||||
|
||||
2002-05-23 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-util.c (assuan_set_io_func): New.
|
||||
* assuan-buffer.c (writen, readline): Use the new functions
|
||||
instead of pth.
|
||||
* assuan-socket-server.c (accept_connection): Don't use the
|
||||
pth_accept - using the assuan included accept code would be a bad
|
||||
idea within Pth so we don't need a replacement function.
|
||||
|
||||
2002-05-22 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-socket-server.c (assuan_init_connected_socket_server): New.
|
||||
(accept_connection): Factored most code out to..
|
||||
(accept_connection_bottom): .. new function.
|
||||
|
||||
2002-04-04 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-buffer.c (my_log_prefix): New. Use it for all i/o debug
|
||||
output.
|
||||
|
||||
2002-03-06 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-client.c (_assuan_read_from_server): Detect END.
|
||||
(assuan_transact): Pass it to the data callback.
|
||||
|
||||
2002-02-27 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-client.c (assuan_transact): Add 2 more arguments to
|
||||
support status lines. Passing NULL yields the old behaviour.
|
||||
|
||||
* assuan-handler.c (process_request): Flush data lines send
|
||||
without using the data fp.
|
||||
|
||||
2002-02-14 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-inquire.c (assuan_inquire): Check for a cancel command
|
||||
and return ASSUAN_Canceled. Allow for non-data inquiry.
|
||||
|
||||
* assuan.h: Add a few token specific error codes.
|
||||
|
||||
2002-02-13 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-defs.h (assuan_context_s): New var CLIENT_PID.
|
||||
* assuan-pipe-server.c (_assuan_new_context): set default value.
|
||||
* assuan-socket-server.c (accept_connection): get the actual pid.
|
||||
|
||||
2002-02-12 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-buffer.c (writen,readline) [USE_GNU_PT]: Use pth_read/write.
|
||||
* assuan-socket-server.c (accept_connection) [USE_GNU_PTH]: Ditto.
|
||||
|
||||
2002-02-01 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* Makefile.am (MOSTLYCLEANFILES): New variable.
|
||||
|
||||
2002-01-23 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-socket-connect.c (LOGERRORX): and removed typo.
|
||||
|
||||
2002-01-22 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-socket-connect.c (LOGERRORX): Reverse arguments to fputs.
|
||||
|
||||
2002-01-21 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-connect.c: Move all except assuan_get_pid to...
|
||||
* assuan-pipe-connect.c: this.
|
||||
(assuan_pipe_disconnect): Removed.
|
||||
(do_finish, do_deinit): New
|
||||
(assuan_pipe_connect): and set them into the context.
|
||||
* assuan-socket-connect.c: New.
|
||||
|
||||
* assuan-util.c (_assuan_log_sanitized_string): New.
|
||||
|
||||
* assuan-pipe-server.c (assuan_init_pipe_server): Factored most
|
||||
code out to ...
|
||||
(_assuan_new_context): new func.
|
||||
(_assuan_release_context): New
|
||||
* assuan-connect.c (assuan_pipe_connect): Use the new functions.
|
||||
|
||||
2002-01-20 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan.h: Added Invalid Option error code.
|
||||
|
||||
* assuan-handler.c (std_handler_option): New.
|
||||
(std_cmd_tbl): Add OPTION as standard command.
|
||||
(assuan_register_option_handler): New.
|
||||
(dispatch_command): Use case insensitive matching as a fallback.
|
||||
(my_strcasecmp): New.
|
||||
|
||||
2002-01-19 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-buffer.c (_assuan_read_line): Add output logging.
|
||||
(assuan_write_line): Ditto.
|
||||
(_assuan_cookie_write_data): Ditto.
|
||||
(_assuan_cookie_write_flush): Ditto.
|
||||
* assuan-util.c (_assuan_log_print_buffer): New.
|
||||
(assuan_set_log_stream): New.
|
||||
(assuan_begin_confidential): New.
|
||||
(assuan_end_confidential): New.
|
||||
|
||||
* assuan-defs.h: Add a few handler variables.
|
||||
* assuan-pipe-server.c (assuan_deinit_pipe_server): Removed.
|
||||
(deinit_pipe_server): New.
|
||||
(assuan_deinit_server): New. Changed all callers to use this.
|
||||
* assuan-listen.c (assuan_accept): Use the accept handler.
|
||||
* assuan-handler.c (process_request): Use the close Handler.
|
||||
* assuan-socket-server.c: New.
|
||||
|
||||
2002-01-14 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-client.c (_assuan_read_from_server): Skip spaces after
|
||||
the keyword.
|
||||
|
||||
2002-01-03 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-handler.c (assuan_set_okay_line): New.
|
||||
(process_request): And use it here.
|
||||
|
||||
2002-01-02 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-inquire.c (init_membuf,put_membuf,get_membuf): Apply a
|
||||
hidden 0 behind the buffer so that the buffer can be used as a
|
||||
string in certain contexts.
|
||||
|
||||
2001-12-14 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-connect.c (assuan_pipe_connect): New argument
|
||||
FD_CHILD_LIST. Don't close those fds.
|
||||
* assuan.h: Likewise for prototype.
|
||||
|
||||
2001-12-14 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-listen.c (assuan_close_input_fd): New.
|
||||
(assuan_close_output_fd): New.
|
||||
* assuan-handler.c (std_handler_reset): Always close them after a
|
||||
reset command.
|
||||
(std_handler_bye): Likewise.
|
||||
|
||||
2001-12-14 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-buffer.c (_assuan_read_line): New variable ATTICLEN, use
|
||||
it to save the length of the attic line.
|
||||
Rediddle the code a bit to make it more clear what happens.
|
||||
|
||||
2001-12-14 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-defs.h (LINELENGTH): Define as ASSUAN_LINELENGTH.
|
||||
assuan.h: Define ASSUAN_LINELENGTH.
|
||||
|
||||
2001-12-13 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-buffer.c (assuan_read_line): Fix order of execution to
|
||||
get correct return values.
|
||||
|
||||
2001-12-13 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-handler.c (assuan_get_active_fds): Fixed silly bug,
|
||||
pretty obvious that nobody ever tested this function.
|
||||
|
||||
2001-12-12 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-connect.c (assuan_pipe_connect): Implemented the inital
|
||||
handshake.
|
||||
* assuan-client.c (read_from_server): Renamed to
|
||||
(_assuan_read_from_server): this and made external.
|
||||
|
||||
* assuan-listen.c (assuan_set_hello_line): New.
|
||||
(assuan_accept): Use a custom hello line is available.
|
||||
|
||||
* assuan-buffer.c (assuan_read_line): New.
|
||||
(assuan_pending_line): New.
|
||||
(_assuan_write_line): Renamed to ..
|
||||
(assuan_write_line): this, made public and changed all callers.
|
||||
|
||||
2001-12-04 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-connect.c (assuan_pipe_connect): Add more error reporting.
|
||||
* assuan-client.c: New.
|
||||
|
||||
* assuan-inquire.c: New.
|
||||
* assuan-handler.c (process_request): Check for nested invocations.
|
||||
|
||||
2001-11-27 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-handler.c (assuan_register_input_notify): New.
|
||||
(assuan_register_output_notify): New.
|
||||
|
||||
2001-11-26 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan.h: Added more status codes.
|
||||
|
||||
2001-11-25 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-handler.c (assuan_register_bye_notify)
|
||||
(assuan_register_reset_notify)
|
||||
(assuan_register_cancel_notify): New and call them from the
|
||||
standard handlers.
|
||||
(assuan_process): Moved bulk of function to ..
|
||||
(process_request): .. new.
|
||||
(assuan_process_next): One shot version of above.
|
||||
(assuan_get_active_fds): New.
|
||||
|
||||
2001-11-24 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-connect.c (assuan_get_pid): New.
|
||||
|
||||
* assuan-buffer.c (_assuan_read_line): Deal with reads of more
|
||||
than a line.
|
||||
* 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.
|
||||
|
||||
This file is free software; as a special exception the author gives
|
||||
unlimited permission to copy and/or distribute it, with or without
|
||||
modifications, as long as this notice is preserved.
|
||||
|
||||
This file is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
|
||||
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
@ -1,50 +0,0 @@
|
||||
# Assuan Makefile
|
||||
# Copyright (C) 2001, 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
|
||||
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
EXTRA_DIST = mkerrors
|
||||
INCLUDES = -I.. -I$(top_srcdir)/include
|
||||
BUILT_SOURCES = assuan-errors.c
|
||||
MOSTLYCLEANFILES = assuan-errors.c
|
||||
|
||||
noinst_LIBRARIES = libassuan.a
|
||||
|
||||
|
||||
#libassuan_a_LDFLAGS =
|
||||
libassuan_a_SOURCES = \
|
||||
assuan.h \
|
||||
assuan-defs.h \
|
||||
assuan-util.c \
|
||||
assuan-errors.c \
|
||||
assuan-buffer.c \
|
||||
assuan-handler.c \
|
||||
assuan-inquire.c \
|
||||
assuan-listen.c \
|
||||
assuan-connect.c \
|
||||
assuan-client.c \
|
||||
assuan-pipe-server.c \
|
||||
assuan-socket-server.c \
|
||||
assuan-pipe-connect.c \
|
||||
assuan-socket-connect.c \
|
||||
assuan-io.c
|
||||
|
||||
|
||||
assuan-errors.c : assuan.h
|
||||
$(srcdir)/mkerrors < $(srcdir)/assuan.h > assuan-errors.c
|
@ -1,434 +0,0 @@
|
||||
/* assuan-buffer.c - read and send data
|
||||
* Copyright (C) 2001, 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
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.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
|
||||
writen ( int fd, const char *buffer, size_t length )
|
||||
{
|
||||
while (length)
|
||||
{
|
||||
ssize_t nwritten = _assuan_write (fd, buffer, length);
|
||||
|
||||
if (nwritten < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return -1; /* write error */
|
||||
}
|
||||
length -= nwritten;
|
||||
buffer += nwritten;
|
||||
}
|
||||
return 0; /* okay */
|
||||
}
|
||||
|
||||
/* read an entire line */
|
||||
static int
|
||||
readline (int fd, char *buf, size_t buflen, int *r_nread, int *eof)
|
||||
{
|
||||
size_t nleft = buflen;
|
||||
char *p;
|
||||
|
||||
*eof = 0;
|
||||
*r_nread = 0;
|
||||
while (nleft > 0)
|
||||
{
|
||||
ssize_t n = _assuan_read (fd, buf, nleft);
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return -1; /* read error */
|
||||
}
|
||||
else if (!n)
|
||||
{
|
||||
*eof = 1;
|
||||
break; /* allow incomplete lines */
|
||||
}
|
||||
p = buf;
|
||||
nleft -= n;
|
||||
buf += n;
|
||||
*r_nread += n;
|
||||
|
||||
for (; n && *p != '\n'; n--, p++)
|
||||
;
|
||||
if (n)
|
||||
break; /* at least one full line available - that's enough for now */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_assuan_read_line (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
char *line = ctx->inbound.line;
|
||||
int n, nread, atticlen;
|
||||
int rc;
|
||||
|
||||
if (ctx->inbound.eof)
|
||||
return -1;
|
||||
|
||||
atticlen = ctx->inbound.attic.linelen;
|
||||
if (atticlen)
|
||||
{
|
||||
memcpy (line, ctx->inbound.attic.line, atticlen);
|
||||
ctx->inbound.attic.linelen = 0;
|
||||
for (n=0; n < atticlen && line[n] != '\n'; n++)
|
||||
;
|
||||
if (n < atticlen)
|
||||
{
|
||||
rc = 0; /* found another line in the attic */
|
||||
nread = atticlen;
|
||||
atticlen = 0;
|
||||
}
|
||||
else
|
||||
{ /* read the rest */
|
||||
assert (atticlen < LINELENGTH);
|
||||
rc = readline (ctx->inbound.fd, line + atticlen,
|
||||
LINELENGTH - atticlen, &nread, &ctx->inbound.eof);
|
||||
}
|
||||
}
|
||||
else
|
||||
rc = readline (ctx->inbound.fd, line, LINELENGTH,
|
||||
&nread, &ctx->inbound.eof);
|
||||
if (rc)
|
||||
{
|
||||
if (ctx->log_fp)
|
||||
fprintf (ctx->log_fp, "%s[%p] <- [Error: %s]\n",
|
||||
my_log_prefix (), ctx, strerror (errno));
|
||||
return ASSUAN_Read_Error;
|
||||
}
|
||||
if (!nread)
|
||||
{
|
||||
assert (ctx->inbound.eof);
|
||||
if (ctx->log_fp)
|
||||
fprintf (ctx->log_fp, "%s[%p] <- [EOF]\n", my_log_prefix (),ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->inbound.attic.pending = 0;
|
||||
nread += atticlen;
|
||||
for (n=0; n < nread; n++)
|
||||
{
|
||||
if (line[n] == '\n')
|
||||
{
|
||||
if (n+1 < nread)
|
||||
{
|
||||
char *s, *d;
|
||||
int i;
|
||||
|
||||
n++;
|
||||
/* we have to copy the rest because the handlers are
|
||||
allowed to modify the passed buffer */
|
||||
for (d=ctx->inbound.attic.line, s=line+n, i=nread-n; i; i--)
|
||||
{
|
||||
if (*s=='\n')
|
||||
ctx->inbound.attic.pending = 1;
|
||||
*d++ = *s++;
|
||||
}
|
||||
ctx->inbound.attic.linelen = nread-n;
|
||||
n--;
|
||||
}
|
||||
if (n && line[n-1] == '\r')
|
||||
n--;
|
||||
line[n] = 0;
|
||||
ctx->inbound.linelen = n;
|
||||
if (ctx->log_fp)
|
||||
{
|
||||
fprintf (ctx->log_fp, "%s[%p] <- ", my_log_prefix (), ctx);
|
||||
if (ctx->confidential)
|
||||
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||
else
|
||||
_assuan_log_print_buffer (ctx->log_fp,
|
||||
ctx->inbound.line,
|
||||
ctx->inbound.linelen);
|
||||
putc ('\n', ctx->log_fp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->log_fp)
|
||||
fprintf (ctx->log_fp, "%s[%p] <- [Invalid line]\n", my_log_prefix (), ctx);
|
||||
*line = 0;
|
||||
ctx->inbound.linelen = 0;
|
||||
return ctx->inbound.eof? ASSUAN_Line_Not_Terminated : ASSUAN_Line_Too_Long;
|
||||
}
|
||||
|
||||
|
||||
/* Read the next line from the client or server and return a pointer
|
||||
in *LINE to a buffer holding the line. LINELEN is the length of
|
||||
*LINE. The buffer is valid until the next read operation on it.
|
||||
The caller may modify the buffer. The buffer is invalid (i.e. must
|
||||
not be used) if an error is returned.
|
||||
|
||||
Returns 0 on success or an assuan error code.
|
||||
See also: assuan_pending_line().
|
||||
*/
|
||||
AssuanError
|
||||
assuan_read_line (ASSUAN_CONTEXT ctx, char **line, size_t *linelen)
|
||||
{
|
||||
AssuanError err;
|
||||
|
||||
if (!ctx)
|
||||
return ASSUAN_Invalid_Value;
|
||||
|
||||
err = _assuan_read_line (ctx);
|
||||
*line = ctx->inbound.line;
|
||||
*linelen = ctx->inbound.linelen;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if a full line is buffered (i.e. an entire line may be
|
||||
read without any I/O). */
|
||||
int
|
||||
assuan_pending_line (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
return ctx && ctx->inbound.attic.pending;
|
||||
}
|
||||
|
||||
|
||||
AssuanError
|
||||
assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
|
||||
{
|
||||
int rc;
|
||||
size_t len;
|
||||
const char *s;
|
||||
|
||||
if (!ctx)
|
||||
return ASSUAN_Invalid_Value;
|
||||
|
||||
/* Make sure that we never take a LF from the user - this might
|
||||
violate the protocol. */
|
||||
s = strchr (line, '\n');
|
||||
len = s? (s-line) : strlen (line);
|
||||
|
||||
/* fixme: we should do some kind of line buffering. */
|
||||
if (ctx->log_fp)
|
||||
{
|
||||
fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
|
||||
if (s)
|
||||
fputs ("[supplied line contained a LF]", ctx->log_fp);
|
||||
if (ctx->confidential)
|
||||
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||
else
|
||||
_assuan_log_print_buffer (ctx->log_fp, line, len);
|
||||
putc ('\n', ctx->log_fp);
|
||||
}
|
||||
|
||||
rc = writen (ctx->outbound.fd, line, len);
|
||||
if (rc)
|
||||
rc = ASSUAN_Write_Error;
|
||||
if (!rc)
|
||||
{
|
||||
rc = writen (ctx->outbound.fd, "\n", 1);
|
||||
if (rc)
|
||||
rc = ASSUAN_Write_Error;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Write out the data in buffer as datalines with line wrapping and
|
||||
percent escaping. This fucntion is used for GNU's custom streams */
|
||||
int
|
||||
_assuan_cookie_write_data (void *cookie, const char *buffer, size_t size)
|
||||
{
|
||||
ASSUAN_CONTEXT ctx = cookie;
|
||||
char *line;
|
||||
size_t linelen;
|
||||
|
||||
if (ctx->outbound.data.error)
|
||||
return 0;
|
||||
|
||||
line = ctx->outbound.data.line;
|
||||
linelen = ctx->outbound.data.linelen;
|
||||
line += linelen;
|
||||
while (size)
|
||||
{
|
||||
/* insert data line header */
|
||||
if (!linelen)
|
||||
{
|
||||
*line++ = 'D';
|
||||
*line++ = ' ';
|
||||
linelen += 2;
|
||||
}
|
||||
|
||||
/* copy data, keep some space for the CRLF and to escape one character */
|
||||
while (size && linelen < LINELENGTH-2-2)
|
||||
{
|
||||
if (*buffer == '%' || *buffer == '\r' || *buffer == '\n')
|
||||
{
|
||||
sprintf (line, "%%%02X", *(unsigned char*)buffer);
|
||||
line += 3;
|
||||
linelen += 3;
|
||||
buffer++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*line++ = *buffer++;
|
||||
linelen++;
|
||||
}
|
||||
size--;
|
||||
}
|
||||
|
||||
if (linelen >= LINELENGTH-2-2)
|
||||
{
|
||||
if (ctx->log_fp)
|
||||
{
|
||||
fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
|
||||
if (ctx->confidential)
|
||||
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||
else
|
||||
_assuan_log_print_buffer (ctx->log_fp,
|
||||
ctx->outbound.data.line,
|
||||
linelen);
|
||||
putc ('\n', ctx->log_fp);
|
||||
}
|
||||
*line++ = '\n';
|
||||
linelen++;
|
||||
if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
|
||||
{
|
||||
ctx->outbound.data.error = ASSUAN_Write_Error;
|
||||
return 0;
|
||||
}
|
||||
line = ctx->outbound.data.line;
|
||||
linelen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->outbound.data.linelen = linelen;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Write out any buffered data
|
||||
This fucntion is used for GNU's custom streams */
|
||||
int
|
||||
_assuan_cookie_write_flush (void *cookie)
|
||||
{
|
||||
ASSUAN_CONTEXT ctx = cookie;
|
||||
char *line;
|
||||
size_t linelen;
|
||||
|
||||
if (ctx->outbound.data.error)
|
||||
return 0;
|
||||
|
||||
line = ctx->outbound.data.line;
|
||||
linelen = ctx->outbound.data.linelen;
|
||||
line += linelen;
|
||||
if (linelen)
|
||||
{
|
||||
if (ctx->log_fp)
|
||||
{
|
||||
fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
|
||||
if (ctx->confidential)
|
||||
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||
else
|
||||
_assuan_log_print_buffer (ctx->log_fp,
|
||||
ctx->outbound.data.line,
|
||||
linelen);
|
||||
putc ('\n', ctx->log_fp);
|
||||
}
|
||||
*line++ = '\n';
|
||||
linelen++;
|
||||
if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
|
||||
{
|
||||
ctx->outbound.data.error = ASSUAN_Write_Error;
|
||||
return 0;
|
||||
}
|
||||
ctx->outbound.data.linelen = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* assuan_send_data:
|
||||
* @ctx: An assuan context
|
||||
* @buffer: Data to send or NULL to flush
|
||||
* @length: length of the data to send/
|
||||
*
|
||||
* This function may be used by the server or the client to send data
|
||||
* lines. The data will be escaped as required by the Assuan protocol
|
||||
* and may get buffered until a line is full. To force sending the
|
||||
* data out @buffer may be passed as NULL (in which case @length must
|
||||
* also be 0); however when used by a client this flush operation does
|
||||
* also send the terminating "END" command to terminate the reponse on
|
||||
* a INQUIRE response. However, when assuan_transact() is used, this
|
||||
* function takes care of sending END itself.
|
||||
*
|
||||
* Return value: 0 on success or an error code
|
||||
**/
|
||||
|
||||
AssuanError
|
||||
assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length)
|
||||
{
|
||||
if (!ctx)
|
||||
return ASSUAN_Invalid_Value;
|
||||
if (!buffer && length)
|
||||
return ASSUAN_Invalid_Value;
|
||||
|
||||
if (!buffer)
|
||||
{ /* flush what we have */
|
||||
_assuan_cookie_write_flush (ctx);
|
||||
if (ctx->outbound.data.error)
|
||||
return ctx->outbound.data.error;
|
||||
if (!ctx->is_server)
|
||||
return assuan_write_line (ctx, "END");
|
||||
}
|
||||
else
|
||||
{
|
||||
_assuan_cookie_write_data (ctx, buffer, length);
|
||||
if (ctx->outbound.data.error)
|
||||
return ctx->outbound.data.error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,225 +0,0 @@
|
||||
/* assuan-client.c - client functions
|
||||
* Copyright (C) 2001, 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
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "assuan-defs.h"
|
||||
|
||||
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
|
||||
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
|
||||
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
|
||||
|
||||
|
||||
AssuanError
|
||||
_assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
|
||||
{
|
||||
char *line;
|
||||
int linelen;
|
||||
AssuanError rc;
|
||||
|
||||
*okay = 0;
|
||||
*off = 0;
|
||||
do
|
||||
{
|
||||
rc = _assuan_read_line (ctx);
|
||||
if (rc)
|
||||
return rc;
|
||||
line = ctx->inbound.line;
|
||||
linelen = ctx->inbound.linelen;
|
||||
}
|
||||
while (*line == '#' || !linelen);
|
||||
|
||||
if (linelen >= 1
|
||||
&& line[0] == 'D' && line[1] == ' ')
|
||||
{
|
||||
*okay = 2; /* data line */
|
||||
*off = 2;
|
||||
}
|
||||
else if (linelen >= 1
|
||||
&& line[0] == 'S'
|
||||
&& (line[1] == '\0' || line[1] == ' '))
|
||||
{
|
||||
*okay = 4;
|
||||
*off = 1;
|
||||
while (line[*off] == ' ')
|
||||
++*off;
|
||||
}
|
||||
else if (linelen >= 2
|
||||
&& line[0] == 'O' && line[1] == 'K'
|
||||
&& (line[2] == '\0' || line[2] == ' '))
|
||||
{
|
||||
*okay = 1;
|
||||
*off = 2;
|
||||
while (line[*off] == ' ')
|
||||
++*off;
|
||||
}
|
||||
else if (linelen >= 3
|
||||
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
|
||||
&& (line[3] == '\0' || line[3] == ' '))
|
||||
{
|
||||
*okay = 0;
|
||||
*off = 3;
|
||||
while (line[*off] == ' ')
|
||||
++*off;
|
||||
}
|
||||
else if (linelen >= 7
|
||||
&& line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
|
||||
&& line[3] == 'U' && line[4] == 'I' && line[5] == 'R'
|
||||
&& line[6] == 'E'
|
||||
&& (line[7] == '\0' || line[7] == ' '))
|
||||
{
|
||||
*okay = 3;
|
||||
*off = 7;
|
||||
while (line[*off] == ' ')
|
||||
++*off;
|
||||
}
|
||||
else if (linelen >= 3
|
||||
&& line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
|
||||
&& (line[3] == '\0' || line[3] == ' '))
|
||||
{
|
||||
*okay = 5; /* end line */
|
||||
*off = 3;
|
||||
}
|
||||
else
|
||||
rc = ASSUAN_Invalid_Response;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* assuan_transact:
|
||||
* @ctx: The Assuan context
|
||||
* @command: Coimmand line to be send to server
|
||||
* @data_cb: Callback function for data lines
|
||||
* @data_cb_arg: first argument passed to @data_cb
|
||||
* @inquire_cb: Callback function for a inquire response
|
||||
* @inquire_cb_arg: first argument passed to @inquire_cb
|
||||
* @status_cb: Callback function for a status response
|
||||
* @status_cb_arg: first argument passed to @status_cb
|
||||
*
|
||||
* FIXME: Write documentation
|
||||
*
|
||||
* Return value: 0 on success or error code. The error code may be
|
||||
* the one one returned by the server in error lines or from the
|
||||
* callback functions.
|
||||
**/
|
||||
AssuanError
|
||||
assuan_transact (ASSUAN_CONTEXT ctx,
|
||||
const char *command,
|
||||
AssuanError (*data_cb)(void *, const void *, size_t),
|
||||
void *data_cb_arg,
|
||||
AssuanError (*inquire_cb)(void*, const char *),
|
||||
void *inquire_cb_arg,
|
||||
AssuanError (*status_cb)(void*, const char *),
|
||||
void *status_cb_arg)
|
||||
{
|
||||
int rc, okay, off;
|
||||
unsigned char *line;
|
||||
int linelen;
|
||||
|
||||
rc = assuan_write_line (ctx, command);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
again:
|
||||
rc = _assuan_read_from_server (ctx, &okay, &off);
|
||||
if (rc)
|
||||
return rc; /* error reading from server */
|
||||
|
||||
line = ctx->inbound.line + off;
|
||||
linelen = ctx->inbound.linelen - off;
|
||||
|
||||
if (!okay)
|
||||
{
|
||||
rc = atoi (line);
|
||||
if (rc < 100)
|
||||
rc = ASSUAN_Server_Fault;
|
||||
}
|
||||
else if (okay == 2)
|
||||
{
|
||||
if (!data_cb)
|
||||
rc = ASSUAN_No_Data_Callback;
|
||||
else
|
||||
{
|
||||
unsigned char *s, *d;
|
||||
|
||||
for (s=d=line; linelen; linelen--)
|
||||
{
|
||||
if (*s == '%' && linelen > 2)
|
||||
{ /* handle escaping */
|
||||
s++;
|
||||
*d++ = xtoi_2 (s);
|
||||
s += 2;
|
||||
linelen -= 2;
|
||||
}
|
||||
else
|
||||
*d++ = *s++;
|
||||
}
|
||||
*d = 0; /* add a hidden string terminator */
|
||||
rc = data_cb (data_cb_arg, line, d - line);
|
||||
if (!rc)
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
else if (okay == 3)
|
||||
{
|
||||
if (!inquire_cb)
|
||||
{
|
||||
assuan_write_line (ctx, "END"); /* get out of inquire mode */
|
||||
_assuan_read_from_server (ctx, &okay, &off); /* dummy read */
|
||||
rc = ASSUAN_No_Inquire_Callback;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = inquire_cb (inquire_cb_arg, line);
|
||||
if (!rc)
|
||||
rc = assuan_send_data (ctx, NULL, 0); /* flush and send END */
|
||||
if (!rc)
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
else if (okay == 4)
|
||||
{
|
||||
if (status_cb)
|
||||
rc = status_cb (status_cb_arg, line);
|
||||
if (!rc)
|
||||
goto again;
|
||||
}
|
||||
else if (okay == 5)
|
||||
{
|
||||
if (!data_cb)
|
||||
rc = ASSUAN_No_Data_Callback;
|
||||
else
|
||||
{
|
||||
rc = data_cb (data_cb_arg, NULL, 0);
|
||||
if (!rc)
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -1,54 +0,0 @@
|
||||
/* assuan-connect.c - Establish a connection (client)
|
||||
* Copyright (C) 2001, 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "assuan-defs.h"
|
||||
|
||||
/* Disconnect and release the context CTX. */
|
||||
void
|
||||
assuan_disconnect (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
assuan_write_line (ctx, "BYE");
|
||||
ctx->finish_handler (ctx);
|
||||
ctx->deinit_handler (ctx);
|
||||
ctx->deinit_handler = NULL;
|
||||
_assuan_release_context (ctx);
|
||||
}
|
||||
}
|
||||
|
||||
pid_t
|
||||
assuan_get_pid (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
return ctx ? ctx->pid : -1;
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
/* assuan-defs.c - Internal definitions to Assuan
|
||||
* Copyright (C) 2001, 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
|
||||
*/
|
||||
|
||||
#ifndef ASSUAN_DEFS_H
|
||||
#define ASSUAN_DEFS_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "assuan.h"
|
||||
|
||||
#define LINELENGTH ASSUAN_LINELENGTH
|
||||
|
||||
struct cmdtbl_s {
|
||||
const char *name;
|
||||
int cmd_id;
|
||||
int (*handler)(ASSUAN_CONTEXT, char *line);
|
||||
};
|
||||
|
||||
struct assuan_context_s {
|
||||
AssuanError err_no;
|
||||
const char *err_str;
|
||||
int os_errno; /* last system error number used with certain error codes*/
|
||||
|
||||
int confidential;
|
||||
int is_server; /* set if this is context belongs to a server */
|
||||
int in_inquire;
|
||||
char *hello_line;
|
||||
char *okay_line; /* see assan_set_okay_line() */
|
||||
|
||||
void *user_pointer; /* for assuan_[gs]et_pointer () */
|
||||
|
||||
FILE *log_fp;
|
||||
|
||||
struct {
|
||||
int fd;
|
||||
int eof;
|
||||
char line[LINELENGTH];
|
||||
int linelen; /* w/o CR, LF - might not be the same as
|
||||
strlen(line) due to embedded nuls. However a nul
|
||||
is always written at this pos */
|
||||
struct {
|
||||
char line[LINELENGTH];
|
||||
int linelen ;
|
||||
int pending; /* i.e. at least one line is available in the attic */
|
||||
} attic;
|
||||
} inbound;
|
||||
|
||||
struct {
|
||||
int fd;
|
||||
struct {
|
||||
FILE *fp;
|
||||
char line[LINELENGTH];
|
||||
int linelen;
|
||||
int error;
|
||||
} data;
|
||||
} outbound;
|
||||
|
||||
int pipe_mode; /* We are in pipe mode, i.e. we can handle just one
|
||||
connection and must terminate then */
|
||||
pid_t pid; /* In pipe mode, the pid of the child server process.
|
||||
In socket mode, the pid of the server */
|
||||
int listen_fd; /* The fd we are listening on (used by socket servers) */
|
||||
int connected_fd; /* helper */
|
||||
|
||||
pid_t client_pid; /* for a socket server the PID of the client or -1
|
||||
if not available */
|
||||
|
||||
void (*deinit_handler)(ASSUAN_CONTEXT);
|
||||
int (*accept_handler)(ASSUAN_CONTEXT);
|
||||
int (*finish_handler)(ASSUAN_CONTEXT);
|
||||
|
||||
struct cmdtbl_s *cmdtbl;
|
||||
size_t cmdtbl_used; /* used entries */
|
||||
size_t cmdtbl_size; /* allocated size of table */
|
||||
|
||||
void (*bye_notify_fnc)(ASSUAN_CONTEXT);
|
||||
void (*reset_notify_fnc)(ASSUAN_CONTEXT);
|
||||
void (*cancel_notify_fnc)(ASSUAN_CONTEXT);
|
||||
int (*option_handler_fnc)(ASSUAN_CONTEXT,const char*, const char*);
|
||||
void (*input_notify_fnc)(ASSUAN_CONTEXT, const char *);
|
||||
void (*output_notify_fnc)(ASSUAN_CONTEXT, const char *);
|
||||
|
||||
int input_fd; /* set by INPUT command */
|
||||
int output_fd; /* set by OUTPUT command */
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*-- assuan-pipe-server.c --*/
|
||||
int _assuan_new_context (ASSUAN_CONTEXT *r_ctx);
|
||||
void _assuan_release_context (ASSUAN_CONTEXT ctx);
|
||||
|
||||
|
||||
/*-- assuan-handler.c --*/
|
||||
int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
|
||||
|
||||
/*-- assuan-buffer.c --*/
|
||||
int _assuan_read_line (ASSUAN_CONTEXT ctx);
|
||||
int _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size);
|
||||
int _assuan_cookie_write_flush (void *cookie);
|
||||
|
||||
/*-- assuan-client.c --*/
|
||||
AssuanError _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off);
|
||||
|
||||
|
||||
/*-- assuan-util.c --*/
|
||||
void *_assuan_malloc (size_t n);
|
||||
void *_assuan_calloc (size_t n, size_t m);
|
||||
void *_assuan_realloc (void *p, size_t n);
|
||||
void _assuan_free (void *p);
|
||||
|
||||
#define xtrymalloc(a) _assuan_malloc ((a))
|
||||
#define xtrycalloc(a,b) _assuan_calloc ((a),(b))
|
||||
#define xtryrealloc(a,b) _assuan_realloc((a),(b))
|
||||
#define xfree(a) _assuan_free ((a))
|
||||
|
||||
#define set_error(c,e,t) assuan_set_error ((c), ASSUAN_ ## e, (t))
|
||||
|
||||
void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length);
|
||||
void _assuan_log_sanitized_string (const char *string);
|
||||
|
||||
/*-- assuan-io.c --*/
|
||||
|
||||
/* Wraps the standard read and write functions to do the Right
|
||||
Thing depending on our linkage. */
|
||||
ssize_t _assuan_read (int fd, void *buffer, size_t size);
|
||||
ssize_t _assuan_write (int fd, const void *buffer, size_t size);
|
||||
|
||||
#endif /*ASSUAN_DEFS_H*/
|
||||
|
@ -1,708 +0,0 @@
|
||||
/* assuan-handler.c - dispatch commands
|
||||
* Copyright (C) 2001, 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
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "assuan-defs.h"
|
||||
|
||||
#define spacep(p) (*(p) == ' ' || *(p) == '\t')
|
||||
#define digitp(a) ((a) >= '0' && (a) <= '9')
|
||||
|
||||
|
||||
#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*/
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
dummy_handler (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
return set_error (ctx, Server_Fault, "no handler registered");
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
std_handler_nop (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
return 0; /* okay */
|
||||
}
|
||||
|
||||
static int
|
||||
std_handler_cancel (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
if (ctx->cancel_notify_fnc)
|
||||
ctx->cancel_notify_fnc (ctx);
|
||||
return set_error (ctx, Not_Implemented, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
std_handler_option (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
char *key, *value, *p;
|
||||
|
||||
for (key=line; spacep (key); key++)
|
||||
;
|
||||
if (!*key)
|
||||
return set_error (ctx, Syntax_Error, "argument required");
|
||||
if (*key == '=')
|
||||
return set_error (ctx, Syntax_Error, "no option name given");
|
||||
for (value=key; *value && !spacep (value) && *value != '='; value++)
|
||||
;
|
||||
if (*value)
|
||||
{
|
||||
if (spacep (value))
|
||||
*value++ = 0; /* terminate key */
|
||||
for (; spacep (value); value++)
|
||||
;
|
||||
if (*value == '=')
|
||||
{
|
||||
*value++ = 0; /* terminate key */
|
||||
for (; spacep (value); value++)
|
||||
;
|
||||
if (!*value)
|
||||
return set_error (ctx, Syntax_Error, "option argument expected");
|
||||
}
|
||||
if (*value)
|
||||
{
|
||||
for (p = value + strlen(value) - 1; p > value && spacep (p); p--)
|
||||
;
|
||||
if (p > value)
|
||||
*++p = 0; /* strip trailing spaces */
|
||||
}
|
||||
}
|
||||
|
||||
if (*key == '-' && key[1] == '-' && key[2])
|
||||
key += 2; /* the double dashes are optional */
|
||||
if (*key == '-')
|
||||
return set_error (ctx, Syntax_Error,
|
||||
"option should not begin with one dash");
|
||||
|
||||
if (ctx->option_handler_fnc)
|
||||
return ctx->option_handler_fnc (ctx, key, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
std_handler_bye (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
if (ctx->bye_notify_fnc)
|
||||
ctx->bye_notify_fnc (ctx);
|
||||
assuan_close_input_fd (ctx);
|
||||
assuan_close_output_fd (ctx);
|
||||
return -1; /* pretty simple :-) */
|
||||
}
|
||||
|
||||
static int
|
||||
std_handler_auth (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
return set_error (ctx, Not_Implemented, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
std_handler_reset (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
if (ctx->reset_notify_fnc)
|
||||
ctx->reset_notify_fnc (ctx);
|
||||
assuan_close_input_fd (ctx);
|
||||
assuan_close_output_fd (ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
std_handler_end (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
return set_error (ctx, Not_Implemented, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
parse_cmd_input_output (ASSUAN_CONTEXT ctx, char *line, int *rfd)
|
||||
{
|
||||
char *endp;
|
||||
|
||||
if (strncmp (line, "FD=", 3))
|
||||
return set_error (ctx, Syntax_Error, "FD=<n> expected");
|
||||
line += 3;
|
||||
if (!digitp (*line))
|
||||
return set_error (ctx, Syntax_Error, "number required");
|
||||
*rfd = strtoul (line, &endp, 10);
|
||||
/* remove that argument so that a notify handler won't see it */
|
||||
memset (line, ' ', endp? (endp-line):strlen(line));
|
||||
|
||||
if (*rfd == ctx->inbound.fd)
|
||||
return set_error (ctx, Parameter_Conflict, "fd same as inbound fd");
|
||||
if (*rfd == ctx->outbound.fd)
|
||||
return set_error (ctx, Parameter_Conflict, "fd same as outbound fd");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Format is INPUT FD=<n> */
|
||||
static int
|
||||
std_handler_input (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
int rc, fd;
|
||||
|
||||
rc = parse_cmd_input_output (ctx, line, &fd);
|
||||
if (rc)
|
||||
return rc;
|
||||
ctx->input_fd = fd;
|
||||
if (ctx->input_notify_fnc)
|
||||
ctx->input_notify_fnc (ctx, line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Format is OUTPUT FD=<n> */
|
||||
static int
|
||||
std_handler_output (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
int rc, fd;
|
||||
|
||||
rc = parse_cmd_input_output (ctx, line, &fd);
|
||||
if (rc)
|
||||
return rc;
|
||||
ctx->output_fd = fd;
|
||||
if (ctx->output_notify_fnc)
|
||||
ctx->output_notify_fnc (ctx, line);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* This is a table with the standard commands and handler for them.
|
||||
The table is used to initialize a new context and assuciate strings
|
||||
and handlers with cmd_ids */
|
||||
static struct {
|
||||
const char *name;
|
||||
int cmd_id;
|
||||
int (*handler)(ASSUAN_CONTEXT, char *line);
|
||||
int always; /* always initialize this command */
|
||||
} std_cmd_table[] = {
|
||||
{ "NOP", ASSUAN_CMD_NOP, std_handler_nop, 1 },
|
||||
{ "CANCEL", ASSUAN_CMD_CANCEL, std_handler_cancel, 1 },
|
||||
{ "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 },
|
||||
{ "BYE", ASSUAN_CMD_BYE, std_handler_bye, 1 },
|
||||
{ "AUTH", ASSUAN_CMD_AUTH, std_handler_auth, 1 },
|
||||
{ "RESET", ASSUAN_CMD_RESET, std_handler_reset, 1 },
|
||||
{ "END", ASSUAN_CMD_END, std_handler_end, 1 },
|
||||
|
||||
{ "INPUT", ASSUAN_CMD_INPUT, std_handler_input },
|
||||
{ "OUTPUT", ASSUAN_CMD_OUTPUT, std_handler_output },
|
||||
{ "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* assuan_register_command:
|
||||
* @ctx: the server context
|
||||
* @cmd_id: An ID value for the command
|
||||
* @cmd_name: A string with the command name
|
||||
* @handler: The handler function to be called
|
||||
*
|
||||
* Register a handler to be used for a given command.
|
||||
*
|
||||
* The @cmd_name must be %NULL or an empty string for all @cmd_ids
|
||||
* below %ASSUAN_CMD_USER because predefined values are used.
|
||||
*
|
||||
* Return value:
|
||||
**/
|
||||
int
|
||||
assuan_register_command (ASSUAN_CONTEXT ctx,
|
||||
int cmd_id, const char *cmd_name,
|
||||
int (*handler)(ASSUAN_CONTEXT, char *))
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cmd_name && !*cmd_name)
|
||||
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)
|
||||
return ASSUAN_Invalid_Value;
|
||||
|
||||
/* fprintf (stderr, "DBG-assuan: registering %d as `%s'\n", cmd_id, cmd_name); */
|
||||
|
||||
if (!ctx->cmdtbl)
|
||||
{
|
||||
ctx->cmdtbl_size = 50;
|
||||
ctx->cmdtbl = xtrycalloc ( ctx->cmdtbl_size, sizeof *ctx->cmdtbl);
|
||||
if (!ctx->cmdtbl)
|
||||
return ASSUAN_Out_Of_Core;
|
||||
ctx->cmdtbl_used = 0;
|
||||
}
|
||||
else if (ctx->cmdtbl_used >= ctx->cmdtbl_size)
|
||||
{
|
||||
struct cmdtbl_s *x;
|
||||
|
||||
x = xtryrealloc ( ctx->cmdtbl, (ctx->cmdtbl_size+10) * sizeof *x);
|
||||
if (!x)
|
||||
return ASSUAN_Out_Of_Core;
|
||||
ctx->cmdtbl = x;
|
||||
ctx->cmdtbl_size += 50;
|
||||
}
|
||||
|
||||
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_used++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
assuan_register_bye_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
|
||||
{
|
||||
if (!ctx)
|
||||
return ASSUAN_Invalid_Value;
|
||||
ctx->bye_notify_fnc = fnc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
assuan_register_reset_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
|
||||
{
|
||||
if (!ctx)
|
||||
return ASSUAN_Invalid_Value;
|
||||
ctx->reset_notify_fnc = fnc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
assuan_register_cancel_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
|
||||
{
|
||||
if (!ctx)
|
||||
return ASSUAN_Invalid_Value;
|
||||
ctx->cancel_notify_fnc = fnc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
assuan_register_option_handler (ASSUAN_CONTEXT ctx,
|
||||
int (*fnc)(ASSUAN_CONTEXT,
|
||||
const char*, const char*))
|
||||
{
|
||||
if (!ctx)
|
||||
return ASSUAN_Invalid_Value;
|
||||
ctx->option_handler_fnc = fnc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
assuan_register_input_notify (ASSUAN_CONTEXT ctx,
|
||||
void (*fnc)(ASSUAN_CONTEXT, const char *))
|
||||
{
|
||||
if (!ctx)
|
||||
return ASSUAN_Invalid_Value;
|
||||
ctx->input_notify_fnc = fnc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
assuan_register_output_notify (ASSUAN_CONTEXT ctx,
|
||||
void (*fnc)(ASSUAN_CONTEXT, const char *))
|
||||
{
|
||||
if (!ctx)
|
||||
return ASSUAN_Invalid_Value;
|
||||
ctx->output_notify_fnc = fnc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Helper to register the standards commands */
|
||||
int
|
||||
_assuan_register_std_commands (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
for (i=0; std_cmd_table[i].name; i++)
|
||||
{
|
||||
if (std_cmd_table[i].always)
|
||||
{
|
||||
rc = assuan_register_command (ctx, std_cmd_table[i].cmd_id,
|
||||
NULL, NULL);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Process the special data lines. The "D " has already been removed
|
||||
from the line. As all handlers this function may modify the line. */
|
||||
static int
|
||||
handle_data_line (ASSUAN_CONTEXT ctx, char *line, int linelen)
|
||||
{
|
||||
return set_error (ctx, Not_Implemented, NULL);
|
||||
}
|
||||
|
||||
/* like ascii_strcasecmp but assume that B is already uppercase */
|
||||
static int
|
||||
my_strcasecmp (const char *a, const char *b)
|
||||
{
|
||||
if (a == b)
|
||||
return 0;
|
||||
|
||||
for (; *a && *b; a++, b++)
|
||||
{
|
||||
if (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) != *b)
|
||||
break;
|
||||
}
|
||||
return *a == *b? 0 : (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) - *b);
|
||||
}
|
||||
|
||||
/* Parse the line, break out the command, find it in the command
|
||||
table, remove leading and white spaces from the arguments, all the
|
||||
handler with the argument line and return the error */
|
||||
static int
|
||||
dispatch_command (ASSUAN_CONTEXT ctx, char *line, int linelen)
|
||||
{
|
||||
char *p;
|
||||
const char *s;
|
||||
int shift, i;
|
||||
|
||||
if (*line == 'D' && line[1] == ' ') /* divert to special handler */
|
||||
return handle_data_line (ctx, line+2, linelen-2);
|
||||
|
||||
for (p=line; *p && *p != ' ' && *p != '\t'; p++)
|
||||
;
|
||||
if (p==line)
|
||||
return set_error (ctx, Invalid_Command, "leading white-space");
|
||||
if (*p)
|
||||
{ /* Skip over leading WS after the keyword */
|
||||
*p++ = 0;
|
||||
while ( *p == ' ' || *p == '\t')
|
||||
p++;
|
||||
}
|
||||
shift = p - line;
|
||||
|
||||
for (i=0; (s=ctx->cmdtbl[i].name); i++)
|
||||
{
|
||||
if (!strcmp (line, s))
|
||||
break;
|
||||
}
|
||||
if (!s)
|
||||
{ /* and try case insensitive */
|
||||
for (i=0; (s=ctx->cmdtbl[i].name); i++)
|
||||
{
|
||||
if (!my_strcasecmp (line, s))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!s)
|
||||
return set_error (ctx, Unknown_Command, NULL);
|
||||
line += shift;
|
||||
linelen -= shift;
|
||||
|
||||
/* fprintf (stderr, "DBG-assuan: processing %s `%s'\n", s, line); */
|
||||
return ctx->cmdtbl[i].handler (ctx, line);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
process_request (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (ctx->in_inquire)
|
||||
return ASSUAN_Nested_Commands;
|
||||
|
||||
rc = _assuan_read_line (ctx);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (*ctx->inbound.line == '#' || !ctx->inbound.linelen)
|
||||
return 0; /* comment line - ignore */
|
||||
|
||||
ctx->outbound.data.error = 0;
|
||||
ctx->outbound.data.linelen = 0;
|
||||
/* dispatch command and return reply */
|
||||
rc = dispatch_command (ctx, ctx->inbound.line, ctx->inbound.linelen);
|
||||
/* check from data write errors */
|
||||
if (ctx->outbound.data.fp)
|
||||
{ /* Flush the data lines */
|
||||
fclose (ctx->outbound.data.fp);
|
||||
ctx->outbound.data.fp = NULL;
|
||||
if (!rc && ctx->outbound.data.error)
|
||||
rc = ctx->outbound.data.error;
|
||||
}
|
||||
else /* flush any data send w/o using the data fp */
|
||||
{
|
||||
assuan_send_data (ctx, NULL, 0);
|
||||
if (!rc && ctx->outbound.data.error)
|
||||
rc = ctx->outbound.data.error;
|
||||
}
|
||||
/* Error handling */
|
||||
if (!rc)
|
||||
{
|
||||
rc = assuan_write_line (ctx, ctx->okay_line? ctx->okay_line : "OK");
|
||||
}
|
||||
else if (rc == -1)
|
||||
{ /* No error checking because the peer may have already disconnect */
|
||||
assuan_write_line (ctx, "OK closing connection");
|
||||
ctx->finish_handler (ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
char errline[256];
|
||||
|
||||
if (rc < 100)
|
||||
sprintf (errline, "ERR %d server fault (%.50s)",
|
||||
ASSUAN_Server_Fault, assuan_strerror (rc));
|
||||
else
|
||||
{
|
||||
const char *text = ctx->err_no == rc? ctx->err_str:NULL;
|
||||
|
||||
sprintf (errline, "ERR %d %.50s%s%.100s",
|
||||
rc, assuan_strerror (rc), text? " - ":"", text?text:"");
|
||||
}
|
||||
rc = assuan_write_line (ctx, errline);
|
||||
}
|
||||
|
||||
ctx->confidential = 0;
|
||||
if (ctx->okay_line)
|
||||
{
|
||||
xfree (ctx->okay_line);
|
||||
ctx->okay_line = NULL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* assuan_process:
|
||||
* @ctx: assuan context
|
||||
*
|
||||
* This fucntion is used to handle the assuan protocol after a
|
||||
* connection has been established using assuan_accept(). This is the
|
||||
* main protocol handler.
|
||||
*
|
||||
* Return value: 0 on success or an error code if the assuan operation
|
||||
* failed. Note, that no error is returned for operational errors.
|
||||
**/
|
||||
int
|
||||
assuan_process (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
do {
|
||||
rc = process_request (ctx);
|
||||
} while (!rc);
|
||||
|
||||
if (rc == -1)
|
||||
rc = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* assuan_process_next:
|
||||
* @ctx: Assuan context
|
||||
*
|
||||
* Same as assuan_process() but the user has to provide the outer
|
||||
* loop. He should loop as long as the return code is zero and stop
|
||||
* otherwise; -1 is regular end.
|
||||
*
|
||||
* See also: assuan_get_active_fds()
|
||||
* Return value: -1 for end of server, 0 on success or an error code
|
||||
**/
|
||||
int
|
||||
assuan_process_next (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
return process_request (ctx);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* assuan_get_active_fds:
|
||||
* @ctx: Assuan context
|
||||
* @what: 0 for read fds, 1 for write fds
|
||||
* @fdarray: Caller supplied array to store the FDs
|
||||
* @fdarraysize: size of that array
|
||||
*
|
||||
* Return all active filedescriptors for the given context. This
|
||||
* function can be used to select on the fds and call
|
||||
* assuan_process_next() if there is an active one. The first fd in
|
||||
* the array is the one used for the command connection.
|
||||
*
|
||||
* Note, that write FDs are not yet supported.
|
||||
*
|
||||
* Return value: number of FDs active and put into @fdarray or -1 on
|
||||
* error which is most likely a too small fdarray.
|
||||
**/
|
||||
int
|
||||
assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what,
|
||||
int *fdarray, int fdarraysize)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
if (!ctx || fdarraysize < 2 || what < 0 || what > 1)
|
||||
return -1;
|
||||
|
||||
if (!what)
|
||||
{
|
||||
if (ctx->inbound.fd != -1)
|
||||
fdarray[n++] = ctx->inbound.fd;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ctx->outbound.fd != -1)
|
||||
fdarray[n++] = ctx->outbound.fd;
|
||||
if (ctx->outbound.data.fp)
|
||||
fdarray[n++] = fileno (ctx->outbound.data.fp);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Return a FP to be used for data output. The FILE pointer is valid
|
||||
until the end of a handler. So a close is not needed. Assuan does
|
||||
all the buffering needed to insert the status line as well as the
|
||||
required line wappping and quoting for data lines.
|
||||
|
||||
We use GNU's custom streams here. There should be an alternative
|
||||
implementaion for systems w/o a glibc, a simple implementation
|
||||
could use a child process */
|
||||
FILE *
|
||||
assuan_get_data_fp (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
cookie_io_functions_t cookie_fnc;
|
||||
|
||||
if (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.error = 0;
|
||||
return ctx->outbound.data.fp;
|
||||
}
|
||||
|
||||
|
||||
/* Set the text used for the next OK reponse. This string is
|
||||
automatically reset to NULL after the next command. */
|
||||
AssuanError
|
||||
assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line)
|
||||
{
|
||||
if (!ctx)
|
||||
return ASSUAN_Invalid_Value;
|
||||
if (!line)
|
||||
{
|
||||
xfree (ctx->okay_line);
|
||||
ctx->okay_line = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: we need to use gcry_is_secure() to test whether
|
||||
we should allocate the entire line in secure memory */
|
||||
char *buf = xtrymalloc (3+strlen(line)+1);
|
||||
if (!buf)
|
||||
return ASSUAN_Out_Of_Core;
|
||||
strcpy (buf, "OK ");
|
||||
strcpy (buf+3, line);
|
||||
xfree (ctx->okay_line);
|
||||
ctx->okay_line = buf;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text)
|
||||
{
|
||||
char buffer[256];
|
||||
char *helpbuf;
|
||||
size_t n;
|
||||
|
||||
if ( !ctx || !keyword)
|
||||
return;
|
||||
if (!text)
|
||||
text = "";
|
||||
|
||||
n = 2 + strlen (keyword) + 1 + strlen (text) + 1;
|
||||
if (n < sizeof (buffer))
|
||||
{
|
||||
strcpy (buffer, "S ");
|
||||
strcat (buffer, keyword);
|
||||
if (*text)
|
||||
{
|
||||
strcat (buffer, " ");
|
||||
strcat (buffer, text);
|
||||
}
|
||||
assuan_write_line (ctx, buffer);
|
||||
}
|
||||
else if ( (helpbuf = xtrymalloc (n)) )
|
||||
{
|
||||
strcpy (helpbuf, "S ");
|
||||
strcat (helpbuf, keyword);
|
||||
if (*text)
|
||||
{
|
||||
strcat (helpbuf, " ");
|
||||
strcat (helpbuf, text);
|
||||
}
|
||||
assuan_write_line (ctx, helpbuf);
|
||||
xfree (helpbuf);
|
||||
}
|
||||
}
|
@ -1,239 +0,0 @@
|
||||
/* assuan-inquire.c - handle inquire stuff
|
||||
* Copyright (C) 2001, 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
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "assuan-defs.h"
|
||||
|
||||
#define digitp(a) ((a) >= '0' && (a) <= '9')
|
||||
#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
|
||||
*(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
|
||||
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
|
||||
|
||||
|
||||
struct membuf {
|
||||
size_t len;
|
||||
size_t size;
|
||||
char *buf;
|
||||
int out_of_core;
|
||||
int too_large;
|
||||
size_t maxlen;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* A simple implemnation of a dynamic buffer. Use init_membuf() to
|
||||
create a buffer, put_membuf to append bytes and get_membuf to
|
||||
release and return the buffer. Allocation errors are detected but
|
||||
only returned at the final get_membuf(), this helps not to clutter
|
||||
the code with out of core checks. */
|
||||
|
||||
static void
|
||||
init_membuf (struct membuf *mb, int initiallen, size_t maxlen)
|
||||
{
|
||||
mb->len = 0;
|
||||
mb->size = initiallen;
|
||||
mb->out_of_core = 0;
|
||||
mb->too_large = 0;
|
||||
mb->maxlen = maxlen;
|
||||
/* we need to allocate one byte more for get_membuf */
|
||||
mb->buf = xtrymalloc (initiallen+1);
|
||||
if (!mb->buf)
|
||||
mb->out_of_core = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
put_membuf (struct membuf *mb, const void *buf, size_t len)
|
||||
{
|
||||
if (mb->out_of_core || mb->too_large)
|
||||
return;
|
||||
|
||||
if (mb->maxlen && mb->len + len > mb->maxlen)
|
||||
{
|
||||
mb->too_large = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mb->len + len >= mb->size)
|
||||
{
|
||||
char *p;
|
||||
|
||||
mb->size += len + 1024;
|
||||
/* we need to allocate one byte more for get_membuf */
|
||||
p = xtryrealloc (mb->buf, mb->size+1);
|
||||
if (!p)
|
||||
{
|
||||
mb->out_of_core = 1;
|
||||
return;
|
||||
}
|
||||
mb->buf = p;
|
||||
}
|
||||
memcpy (mb->buf + mb->len, buf, len);
|
||||
mb->len += len;
|
||||
}
|
||||
|
||||
static void *
|
||||
get_membuf (struct membuf *mb, size_t *len)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (mb->out_of_core || mb->too_large)
|
||||
{
|
||||
xfree (mb->buf);
|
||||
mb->buf = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mb->buf[mb->len] = 0; /* there is enough space for the hidden eos */
|
||||
p = mb->buf;
|
||||
*len = mb->len;
|
||||
mb->buf = NULL;
|
||||
mb->out_of_core = 1; /* don't allow a reuse */
|
||||
return p;
|
||||
}
|
||||
|
||||
static void
|
||||
free_membuf (struct membuf *mb)
|
||||
{
|
||||
xfree (mb->buf);
|
||||
mb->buf = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* assuan_inquire:
|
||||
* @ctx: An assuan context
|
||||
* @keyword: The keyword used for the inquire
|
||||
* @r_buffer: Returns an allocated buffer
|
||||
* @r_length: Returns the length of this buffer
|
||||
* @maxlen: If not 0, the size limit of the inquired data.
|
||||
*
|
||||
* A Server may use this to Send an inquire. r_buffer, r_length and
|
||||
* maxlen may all be NULL/0 to indicate that no real data is expected.
|
||||
*
|
||||
* Return value: 0 on success or an ASSUAN error code
|
||||
**/
|
||||
AssuanError
|
||||
assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
|
||||
char **r_buffer, size_t *r_length, size_t maxlen)
|
||||
{
|
||||
AssuanError rc;
|
||||
struct membuf mb;
|
||||
char cmdbuf[100];
|
||||
unsigned char *line, *p;
|
||||
int linelen;
|
||||
int nodataexpected;
|
||||
|
||||
if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf)))
|
||||
return ASSUAN_Invalid_Value;
|
||||
nodataexpected = !r_buffer && !r_length && !maxlen;
|
||||
if (!nodataexpected && (!r_buffer || !r_length))
|
||||
return ASSUAN_Invalid_Value;
|
||||
if (!ctx->is_server)
|
||||
return ASSUAN_Not_A_Server;
|
||||
if (ctx->in_inquire)
|
||||
return ASSUAN_Nested_Commands;
|
||||
|
||||
ctx->in_inquire = 1;
|
||||
if (nodataexpected)
|
||||
memset (&mb, 0, sizeof mb); /* avoid compiler warnings */
|
||||
else
|
||||
init_membuf (&mb, maxlen? maxlen:1024, maxlen);
|
||||
|
||||
strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword);
|
||||
rc = assuan_write_line (ctx, cmdbuf);
|
||||
if (rc)
|
||||
goto leave;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
do
|
||||
{
|
||||
rc = _assuan_read_line (ctx);
|
||||
if (rc)
|
||||
goto leave;
|
||||
line = ctx->inbound.line;
|
||||
linelen = ctx->inbound.linelen;
|
||||
}
|
||||
while (*line == '#' || !linelen);
|
||||
if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
|
||||
&& (!line[3] || line[3] == ' '))
|
||||
break; /* END command received*/
|
||||
if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N')
|
||||
{
|
||||
rc = ASSUAN_Canceled;
|
||||
goto leave;
|
||||
}
|
||||
if (line[0] != 'D' || line[1] != ' ' || nodataexpected)
|
||||
{
|
||||
rc = ASSUAN_Unexpected_Command;
|
||||
goto leave;
|
||||
}
|
||||
if (linelen < 3)
|
||||
continue;
|
||||
line += 2;
|
||||
linelen -= 2;
|
||||
|
||||
p = line;
|
||||
while (linelen)
|
||||
{
|
||||
for (;linelen && *p != '%'; linelen--, p++)
|
||||
;
|
||||
put_membuf (&mb, line, p-line);
|
||||
if (linelen > 2)
|
||||
{ /* handle escaping */
|
||||
unsigned char tmp[1];
|
||||
p++;
|
||||
*tmp = xtoi_2 (p);
|
||||
p += 2;
|
||||
linelen -= 3;
|
||||
put_membuf (&mb, tmp, 1);
|
||||
}
|
||||
line = p;
|
||||
}
|
||||
if (mb.too_large)
|
||||
{
|
||||
rc = ASSUAN_Too_Much_Data;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nodataexpected)
|
||||
{
|
||||
*r_buffer = get_membuf (&mb, r_length);
|
||||
if (!*r_buffer)
|
||||
rc = ASSUAN_Out_Of_Core;
|
||||
}
|
||||
|
||||
leave:
|
||||
if (!nodataexpected)
|
||||
free_membuf (&mb);
|
||||
ctx->in_inquire = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,60 +0,0 @@
|
||||
/* assuan-buffer.c - Wraps the read and write functions.
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern ssize_t pth_read (int fd, void *buffer, size_t size);
|
||||
extern ssize_t pth_write (int fd, const void *buffer, size_t size);
|
||||
|
||||
#pragma weak pth_read
|
||||
#pragma weak pth_write
|
||||
|
||||
ssize_t
|
||||
_assuan_read (int fd, void *buffer, size_t size)
|
||||
{
|
||||
static ssize_t (*reader) (int, void *, size_t);
|
||||
|
||||
if (! reader)
|
||||
{
|
||||
if (pth_read)
|
||||
reader = pth_read;
|
||||
else
|
||||
reader = read;
|
||||
}
|
||||
|
||||
return reader (fd, buffer, size);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
_assuan_write (int fd, const void *buffer, size_t size)
|
||||
{
|
||||
static ssize_t (*writer) (int, const void *, size_t);
|
||||
|
||||
if (! writer)
|
||||
{
|
||||
if (pth_write)
|
||||
writer = pth_write;
|
||||
else
|
||||
writer = write;
|
||||
}
|
||||
|
||||
return writer (fd, buffer, size);
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
/* assuan-listen.c - Wait for a connection (server)
|
||||
* Copyright (C) 2001, 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
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "assuan-defs.h"
|
||||
|
||||
AssuanError
|
||||
assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line)
|
||||
{
|
||||
if (!ctx)
|
||||
return ASSUAN_Invalid_Value;
|
||||
if (!line)
|
||||
{
|
||||
xfree (ctx->hello_line);
|
||||
ctx->hello_line = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *buf = xtrymalloc (3+strlen(line)+1);
|
||||
if (!buf)
|
||||
return ASSUAN_Out_Of_Core;
|
||||
strcpy (buf, "OK ");
|
||||
strcpy (buf+3, line);
|
||||
xfree (ctx->hello_line);
|
||||
ctx->hello_line = buf;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* assuan_accept:
|
||||
* @ctx: context
|
||||
*
|
||||
* Cancel any existing connectiion and wait for a connection from a
|
||||
* client. The initial handshake is performed which may include an
|
||||
* initial authentication or encryption negotiation.
|
||||
*
|
||||
* Return value: 0 on success or an error if the connection could for
|
||||
* some reason not be established.
|
||||
**/
|
||||
AssuanError
|
||||
assuan_accept (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!ctx)
|
||||
return ASSUAN_Invalid_Value;
|
||||
|
||||
if (ctx->pipe_mode > 1)
|
||||
return -1; /* second invocation for pipemode -> terminate */
|
||||
ctx->finish_handler (ctx);
|
||||
|
||||
rc = ctx->accept_handler (ctx);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* send the hello */
|
||||
rc = assuan_write_line (ctx, ctx->hello_line? ctx->hello_line
|
||||
: "OK Your orders please");
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (ctx->pipe_mode)
|
||||
ctx->pipe_mode = 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
assuan_get_input_fd (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
return ctx? ctx->input_fd : -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
assuan_get_output_fd (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
return ctx? ctx->output_fd : -1;
|
||||
}
|
||||
|
||||
|
||||
/* Close the fd descriptor set by the command INPUT FD=n. We handle
|
||||
this fd inside assuan so that we can do some initial checks */
|
||||
AssuanError
|
||||
assuan_close_input_fd (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
if (!ctx || ctx->input_fd == -1)
|
||||
return ASSUAN_Invalid_Value;
|
||||
close (ctx->input_fd);
|
||||
ctx->input_fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Close the fd descriptor set by the command OUTPUT FD=n. We handle
|
||||
this fd inside assuan so that we can do some initial checks */
|
||||
AssuanError
|
||||
assuan_close_output_fd (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
if (!ctx || ctx->output_fd == -1)
|
||||
return ASSUAN_Invalid_Value;
|
||||
|
||||
close (ctx->output_fd);
|
||||
ctx->output_fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,287 +0,0 @@
|
||||
/* assuan-pipe-connect.c - Establish a pipe connection (client)
|
||||
* Copyright (C) 2001, 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "assuan-defs.h"
|
||||
|
||||
#ifdef _POSIX_OPEN_MAX
|
||||
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
|
||||
#else
|
||||
#define MAX_OPEN_FDS 20
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_JNLIB_LOGGING
|
||||
#include "../jnlib/logging.h"
|
||||
#define LOGERROR1(a,b) log_error ((a), (b))
|
||||
#else
|
||||
#define LOGERROR1(a,b) fprintf (stderr, (a), (b))
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static int
|
||||
writen ( int fd, const char *buffer, size_t length )
|
||||
{
|
||||
while (length)
|
||||
{
|
||||
int nwritten = write (fd, buffer, length);
|
||||
|
||||
if (nwritten < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
return -1; /* write error */
|
||||
}
|
||||
length -= nwritten;
|
||||
buffer += nwritten;
|
||||
}
|
||||
return 0; /* okay */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_finish (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
if (ctx->inbound.fd != -1)
|
||||
{
|
||||
close (ctx->inbound.fd);
|
||||
ctx->inbound.fd = -1;
|
||||
}
|
||||
if (ctx->outbound.fd != -1)
|
||||
{
|
||||
close (ctx->outbound.fd);
|
||||
ctx->outbound.fd = -1;
|
||||
}
|
||||
if (ctx->pid != -1)
|
||||
{
|
||||
waitpid (ctx->pid, NULL, 0); /* FIXME Check return value. */
|
||||
ctx->pid = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
do_deinit (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
do_finish (ctx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Connect to a server over a pipe, creating the assuan context and
|
||||
returning it in CTX. The server filename is NAME, the argument
|
||||
vector in ARGV. FD_CHILD_LIST is a -1 terminated list of file
|
||||
descriptors not to close in the child. */
|
||||
AssuanError
|
||||
assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
|
||||
int *fd_child_list)
|
||||
{
|
||||
static int fixed_signals = 0;
|
||||
AssuanError err;
|
||||
int rp[2];
|
||||
int wp[2];
|
||||
|
||||
if (!ctx || !name || !argv || !argv[0])
|
||||
return ASSUAN_Invalid_Value;
|
||||
|
||||
if (!fixed_signals)
|
||||
{
|
||||
struct sigaction act;
|
||||
|
||||
sigaction (SIGPIPE, NULL, &act);
|
||||
if (act.sa_handler == SIG_DFL)
|
||||
{
|
||||
act.sa_handler = SIG_IGN;
|
||||
sigemptyset (&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
sigaction (SIGPIPE, &act, NULL);
|
||||
}
|
||||
fixed_signals = 1;
|
||||
/* FIXME: This is not MT safe */
|
||||
}
|
||||
|
||||
if (pipe (rp) < 0)
|
||||
return ASSUAN_General_Error;
|
||||
|
||||
if (pipe (wp) < 0)
|
||||
{
|
||||
close (rp[0]);
|
||||
close (rp[1]);
|
||||
return ASSUAN_General_Error;
|
||||
}
|
||||
|
||||
err = _assuan_new_context (ctx);
|
||||
if (err)
|
||||
{
|
||||
close (rp[0]);
|
||||
close (rp[1]);
|
||||
close (wp[0]);
|
||||
close (wp[1]);
|
||||
return err;
|
||||
}
|
||||
(*ctx)->pipe_mode = 1;
|
||||
(*ctx)->inbound.fd = rp[0]; /* Our inbound is read end of read pipe. */
|
||||
(*ctx)->outbound.fd = wp[1]; /* Our outbound is write end of write pipe. */
|
||||
(*ctx)->deinit_handler = do_deinit;
|
||||
(*ctx)->finish_handler = do_finish;
|
||||
|
||||
(*ctx)->pid = fork ();
|
||||
if ((*ctx)->pid < 0)
|
||||
{
|
||||
close (rp[0]);
|
||||
close (rp[1]);
|
||||
close (wp[0]);
|
||||
close (wp[1]);
|
||||
_assuan_release_context (*ctx);
|
||||
return ASSUAN_General_Error;
|
||||
}
|
||||
|
||||
if ((*ctx)->pid == 0)
|
||||
{
|
||||
int i, n;
|
||||
char errbuf[512];
|
||||
int *fdp;
|
||||
|
||||
/* Dup handles to stdin/stdout. */
|
||||
if (rp[1] != STDOUT_FILENO)
|
||||
{
|
||||
if (dup2 (rp[1], STDOUT_FILENO) == -1)
|
||||
{
|
||||
LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno));
|
||||
_exit (4);
|
||||
}
|
||||
}
|
||||
if (wp[0] != STDIN_FILENO)
|
||||
{
|
||||
if (dup2 (wp[0], STDIN_FILENO) == -1)
|
||||
{
|
||||
LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno));
|
||||
_exit (4);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dup stderr to /dev/null unless it is in the list of FDs to be
|
||||
passed to the child. */
|
||||
fdp = fd_child_list;
|
||||
if (fdp)
|
||||
{
|
||||
for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++)
|
||||
;
|
||||
}
|
||||
if (!fdp || *fdp == -1)
|
||||
{
|
||||
int fd = open ("/dev/null", O_WRONLY);
|
||||
if (fd == -1)
|
||||
{
|
||||
LOGERROR1 ("can't open `/dev/null': %s\n", strerror (errno));
|
||||
_exit (4);
|
||||
}
|
||||
if (dup2 (fd, STDERR_FILENO) == -1)
|
||||
{
|
||||
LOGERROR1 ("dup2(dev/null, 2) failed: %s\n", strerror (errno));
|
||||
_exit (4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Close all files which will not be duped and are not in the
|
||||
fd_child_list. */
|
||||
n = sysconf (_SC_OPEN_MAX);
|
||||
if (n < 0)
|
||||
n = MAX_OPEN_FDS;
|
||||
for (i=0; i < n; i++)
|
||||
{
|
||||
if ( i == STDIN_FILENO || i == STDOUT_FILENO || i == STDERR_FILENO)
|
||||
continue;
|
||||
fdp = fd_child_list;
|
||||
if (fdp)
|
||||
{
|
||||
while (*fdp != -1 && *fdp != i)
|
||||
fdp++;
|
||||
}
|
||||
|
||||
if (!(fdp && *fdp != -1))
|
||||
close(i);
|
||||
}
|
||||
errno = 0;
|
||||
|
||||
execv (name, argv);
|
||||
/* oops - use the pipe to tell the parent about it */
|
||||
snprintf (errbuf, sizeof(errbuf)-1, "ERR %d can't exec `%s': %.50s\n",
|
||||
ASSUAN_Problem_Starting_Server, name, strerror (errno));
|
||||
errbuf[sizeof(errbuf)-1] = 0;
|
||||
writen (1, errbuf, strlen (errbuf));
|
||||
_exit (4);
|
||||
}
|
||||
|
||||
close (rp[1]);
|
||||
close (wp[0]);
|
||||
|
||||
/* initial handshake */
|
||||
{
|
||||
int okay, off;
|
||||
|
||||
err = _assuan_read_from_server (*ctx, &okay, &off);
|
||||
if (err)
|
||||
{
|
||||
LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err));
|
||||
}
|
||||
else if (okay != 1)
|
||||
{
|
||||
LOGERROR1 ("can't connect server: `%s'\n", (*ctx)->inbound.line);
|
||||
err = ASSUAN_Connect_Failed;
|
||||
}
|
||||
}
|
||||
|
||||
if (err)
|
||||
{
|
||||
assuan_disconnect (*ctx);
|
||||
*ctx = NULL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,124 +0,0 @@
|
||||
/* assuan-pipe-server.c - Assuan server working over a pipe
|
||||
* Copyright (C) 2001, 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
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "assuan-defs.h"
|
||||
|
||||
static void
|
||||
deinit_pipe_server (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
/* nothing to do for this simple server */
|
||||
}
|
||||
|
||||
static int
|
||||
accept_connection (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
/* This is a NOP for a pipe server */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
finish_connection (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
/* This is a NOP for a pipe server */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* 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 */
|
||||
int
|
||||
_assuan_new_context (ASSUAN_CONTEXT *r_ctx)
|
||||
{
|
||||
ASSUAN_CONTEXT ctx;
|
||||
int rc;
|
||||
|
||||
*r_ctx = NULL;
|
||||
ctx = xtrycalloc (1, sizeof *ctx);
|
||||
if (!ctx)
|
||||
return ASSUAN_Out_Of_Core;
|
||||
ctx->input_fd = -1;
|
||||
ctx->output_fd = -1;
|
||||
|
||||
ctx->inbound.fd = -1;
|
||||
ctx->outbound.fd = -1;
|
||||
|
||||
ctx->listen_fd = -1;
|
||||
ctx->client_pid = (pid_t)-1;
|
||||
/* use the pipe server handler as a default */
|
||||
ctx->deinit_handler = deinit_pipe_server;
|
||||
ctx->accept_handler = accept_connection;
|
||||
ctx->finish_handler = finish_connection;
|
||||
|
||||
rc = _assuan_register_std_commands (ctx);
|
||||
if (rc)
|
||||
xfree (ctx);
|
||||
else
|
||||
*r_ctx = ctx;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = _assuan_new_context (r_ctx);
|
||||
if (!rc)
|
||||
{
|
||||
ASSUAN_CONTEXT ctx = *r_ctx;
|
||||
|
||||
ctx->is_server = 1;
|
||||
ctx->inbound.fd = filedes[0];
|
||||
ctx->outbound.fd = filedes[1];
|
||||
ctx->pipe_mode = 1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_assuan_release_context (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
xfree (ctx->hello_line);
|
||||
xfree (ctx->okay_line);
|
||||
xfree (ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
assuan_deinit_server (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
/* We use this function pointer to avoid linking other server
|
||||
when not needed but still allow for a generic deinit function */
|
||||
ctx->deinit_handler (ctx);
|
||||
ctx->deinit_handler = NULL;
|
||||
_assuan_release_context (ctx);
|
||||
}
|
||||
}
|
@ -1,150 +0,0 @@
|
||||
/* assuan-socket-connect.c - Assuan socket based client
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "assuan-defs.h"
|
||||
|
||||
#ifdef HAVE_JNLIB_LOGGING
|
||||
#include "../jnlib/logging.h"
|
||||
#define LOGERROR(a) log_error ((a))
|
||||
#define LOGERROR1(a,b) log_error ((a), (b))
|
||||
#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
|
||||
do_finish (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
if (ctx->inbound.fd != -1)
|
||||
{
|
||||
close (ctx->inbound.fd);
|
||||
}
|
||||
ctx->inbound.fd = -1;
|
||||
ctx->outbound.fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
do_deinit (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
do_finish (ctx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Make a connection to the Unix domain socket NAME and return a new
|
||||
Assuan context in CTX. SERVER_PID is currently not used but may
|
||||
become handy in the future. */
|
||||
AssuanError
|
||||
assuan_socket_connect (ASSUAN_CONTEXT *r_ctx,
|
||||
const char *name, pid_t server_pid)
|
||||
{
|
||||
AssuanError err;
|
||||
ASSUAN_CONTEXT ctx;
|
||||
int fd;
|
||||
struct sockaddr_un srvr_addr;
|
||||
size_t len;
|
||||
|
||||
if (!r_ctx || !name)
|
||||
return ASSUAN_Invalid_Value;
|
||||
*r_ctx = NULL;
|
||||
|
||||
/* we require that the name starts with a slash, so that we can
|
||||
alter reuse this function for other socket types */
|
||||
if (*name != '/')
|
||||
return ASSUAN_Invalid_Value;
|
||||
if (strlen (name)+1 >= sizeof srvr_addr.sun_path)
|
||||
return ASSUAN_Invalid_Value;
|
||||
|
||||
err = _assuan_new_context (&ctx);
|
||||
if (err)
|
||||
return err;
|
||||
ctx->pid = server_pid; /* save it in case we need it later */
|
||||
ctx->deinit_handler = do_deinit;
|
||||
ctx->finish_handler = do_finish;
|
||||
|
||||
fd = socket (AF_UNIX, SOCK_STREAM, 0);
|
||||
if (fd == -1)
|
||||
{
|
||||
LOGERROR1 ("can't create socket: %s\n", strerror (errno));
|
||||
_assuan_release_context (ctx);
|
||||
return ASSUAN_General_Error;
|
||||
}
|
||||
|
||||
memset (&srvr_addr, 0, sizeof srvr_addr );
|
||||
srvr_addr.sun_family = AF_UNIX;
|
||||
strcpy (srvr_addr.sun_path, name);
|
||||
len = (offsetof (struct sockaddr_un, sun_path)
|
||||
+ strlen (srvr_addr.sun_path) + 1);
|
||||
|
||||
if (connect (fd, (struct sockaddr*)&srvr_addr, len) == -1)
|
||||
{
|
||||
LOGERROR2 ("can't connect to `%s': %s\n", name, strerror (errno));
|
||||
_assuan_release_context (ctx);
|
||||
close (fd );
|
||||
return ASSUAN_Connect_Failed;
|
||||
}
|
||||
|
||||
ctx->inbound.fd = fd;
|
||||
ctx->outbound.fd = fd;
|
||||
|
||||
/* initial handshake */
|
||||
{
|
||||
int okay, off;
|
||||
|
||||
err = _assuan_read_from_server (ctx, &okay, &off);
|
||||
if (err)
|
||||
{
|
||||
LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err));
|
||||
}
|
||||
else if (okay != 1)
|
||||
{
|
||||
LOGERROR ("can't connect server: `");
|
||||
_assuan_log_sanitized_string (ctx->inbound.line);
|
||||
LOGERRORX ("'\n");
|
||||
err = ASSUAN_Connect_Failed;
|
||||
}
|
||||
}
|
||||
|
||||
if (err)
|
||||
{
|
||||
assuan_disconnect (ctx);
|
||||
}
|
||||
else
|
||||
*r_ctx = ctx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,169 +0,0 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "assuan-defs.h"
|
||||
|
||||
static int
|
||||
accept_connection_bottom (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
int fd = ctx->connected_fd;
|
||||
|
||||
ctx->client_pid = (pid_t)-1;
|
||||
#ifdef HAVE_SO_PEERCRED
|
||||
{
|
||||
struct ucred cr;
|
||||
int cl = sizeof cr;
|
||||
|
||||
if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) )
|
||||
ctx->client_pid = cr.pid;
|
||||
}
|
||||
#endif
|
||||
|
||||
ctx->inbound.fd = fd;
|
||||
ctx->inbound.eof = 0;
|
||||
ctx->inbound.linelen = 0;
|
||||
ctx->inbound.attic.linelen = 0;
|
||||
ctx->inbound.attic.pending = 0;
|
||||
|
||||
ctx->outbound.fd = fd;
|
||||
ctx->outbound.data.linelen = 0;
|
||||
ctx->outbound.data.error = 0;
|
||||
|
||||
ctx->confidential = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
accept_connection (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
int fd;
|
||||
struct sockaddr_un clnt_addr;
|
||||
size_t len = sizeof clnt_addr;
|
||||
|
||||
ctx->client_pid = (pid_t)-1;
|
||||
fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
|
||||
if (fd == -1)
|
||||
{
|
||||
ctx->os_errno = errno;
|
||||
return ASSUAN_Accept_Failed;
|
||||
}
|
||||
|
||||
ctx->connected_fd = fd;
|
||||
return accept_connection_bottom (ctx);
|
||||
}
|
||||
|
||||
static int
|
||||
finish_connection (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
if (ctx->inbound.fd != -1)
|
||||
{
|
||||
close (ctx->inbound.fd);
|
||||
}
|
||||
ctx->inbound.fd = -1;
|
||||
ctx->outbound.fd = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
deinit_socket_server (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
finish_connection (ctx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize a server for the socket LISTEN_FD which has already be
|
||||
put into listen mode */
|
||||
int
|
||||
assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd)
|
||||
{
|
||||
ASSUAN_CONTEXT ctx;
|
||||
int rc;
|
||||
|
||||
*r_ctx = NULL;
|
||||
ctx = xtrycalloc (1, sizeof *ctx);
|
||||
if (!ctx)
|
||||
return ASSUAN_Out_Of_Core;
|
||||
ctx->is_server = 1;
|
||||
ctx->input_fd = -1;
|
||||
ctx->output_fd = -1;
|
||||
|
||||
ctx->inbound.fd = -1;
|
||||
ctx->outbound.fd = -1;
|
||||
|
||||
ctx->listen_fd = listen_fd;
|
||||
ctx->connected_fd = -1;
|
||||
ctx->deinit_handler = deinit_socket_server;
|
||||
ctx->accept_handler = accept_connection;
|
||||
ctx->finish_handler = finish_connection;
|
||||
|
||||
rc = _assuan_register_std_commands (ctx);
|
||||
if (rc)
|
||||
xfree (ctx);
|
||||
else
|
||||
*r_ctx = ctx;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Initialize a server using the already accepted socket FD. */
|
||||
int
|
||||
assuan_init_connected_socket_server (ASSUAN_CONTEXT *r_ctx, int fd)
|
||||
{
|
||||
ASSUAN_CONTEXT ctx;
|
||||
int rc;
|
||||
|
||||
*r_ctx = NULL;
|
||||
ctx = xtrycalloc (1, sizeof *ctx);
|
||||
if (!ctx)
|
||||
return ASSUAN_Out_Of_Core;
|
||||
ctx->is_server = 1;
|
||||
ctx->pipe_mode = 1; /* we wan't a second accept to indicate EOF */
|
||||
ctx->input_fd = -1;
|
||||
ctx->output_fd = -1;
|
||||
|
||||
ctx->inbound.fd = -1;
|
||||
ctx->outbound.fd = -1;
|
||||
|
||||
ctx->listen_fd = -1;
|
||||
ctx->connected_fd = fd;
|
||||
ctx->deinit_handler = deinit_socket_server;
|
||||
ctx->accept_handler = accept_connection_bottom;
|
||||
ctx->finish_handler = finish_connection;
|
||||
|
||||
rc = _assuan_register_std_commands (ctx);
|
||||
if (rc)
|
||||
xfree (ctx);
|
||||
else
|
||||
*r_ctx = ctx;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1,230 +0,0 @@
|
||||
/* assuan-util.c - Utility functions for Assuan
|
||||
* Copyright (C) 2001, 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
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "assuan-defs.h"
|
||||
|
||||
#ifdef HAVE_JNLIB_LOGGING
|
||||
#include "../jnlib/logging.h"
|
||||
#endif
|
||||
|
||||
static void *(*alloc_func)(size_t n) = malloc;
|
||||
static void *(*realloc_func)(void *p, size_t n) = realloc;
|
||||
static void (*free_func)(void*) = free;
|
||||
|
||||
void
|
||||
assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
|
||||
void *(*new_realloc_func)(void *p, size_t n),
|
||||
void (*new_free_func)(void*) )
|
||||
{
|
||||
alloc_func = new_alloc_func;
|
||||
realloc_func = new_realloc_func;
|
||||
free_func = new_free_func;
|
||||
}
|
||||
|
||||
void *
|
||||
_assuan_malloc (size_t n)
|
||||
{
|
||||
return alloc_func (n);
|
||||
}
|
||||
|
||||
void *
|
||||
_assuan_realloc (void *a, size_t n)
|
||||
{
|
||||
return realloc_func (a, n);
|
||||
}
|
||||
|
||||
void *
|
||||
_assuan_calloc (size_t n, size_t m)
|
||||
{
|
||||
void *p = _assuan_malloc (n*m);
|
||||
if (p)
|
||||
memset (p, 0, n* m);
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
_assuan_free (void *p)
|
||||
{
|
||||
if (p)
|
||||
free_func (p);
|
||||
}
|
||||
|
||||
|
||||
/* Store the error in the context so that the error sending function
|
||||
can take out a descriptive text. Inside the assuan code, use the
|
||||
macro set_error instead of this function. */
|
||||
int
|
||||
assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text)
|
||||
{
|
||||
ctx->err_no = err;
|
||||
ctx->err_str = text;
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer)
|
||||
{
|
||||
if (ctx)
|
||||
ctx->user_pointer = pointer;
|
||||
}
|
||||
|
||||
void *
|
||||
assuan_get_pointer (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
return ctx? ctx->user_pointer : NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp)
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
if (ctx->log_fp)
|
||||
fflush (ctx->log_fp);
|
||||
ctx->log_fp = fp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
assuan_begin_confidential (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
ctx->confidential = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
assuan_end_confidential (ASSUAN_CONTEXT ctx)
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
ctx->confidential = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump a possibly binary string (used for debugging). Distinguish
|
||||
ascii text from binary and print it accordingly. */
|
||||
void
|
||||
_assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
|
||||
{
|
||||
const unsigned char *s;
|
||||
int n;
|
||||
|
||||
for (n=length,s=buffer; n; n--, s++)
|
||||
if (!isascii (*s) || iscntrl (*s) || !isprint (*s))
|
||||
break;
|
||||
|
||||
s = buffer;
|
||||
if (!n && *s != '[')
|
||||
fwrite (buffer, length, 1, fp);
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_FLOCKFILE
|
||||
flockfile (fp);
|
||||
#endif
|
||||
putc_unlocked ('[', fp);
|
||||
for (n=0; n < length; n++, s++)
|
||||
fprintf (fp, " %02x", *s);
|
||||
putc_unlocked (' ', fp);
|
||||
putc_unlocked (']', fp);
|
||||
#ifdef HAVE_FUNLOCKFILE
|
||||
funlockfile (fp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Log a user supplied string. Escapes non-printable before
|
||||
printing. */
|
||||
void
|
||||
_assuan_log_sanitized_string (const char *string)
|
||||
{
|
||||
const unsigned char *s = string;
|
||||
#ifdef HAVE_JNLIB_LOGGING
|
||||
FILE *fp = log_get_stream ();
|
||||
#else
|
||||
FILE *fp = stderr;
|
||||
#endif
|
||||
|
||||
if (! *s)
|
||||
return;
|
||||
|
||||
#ifdef HAVE_FLOCKFILE
|
||||
flockfile (fp);
|
||||
#endif
|
||||
|
||||
for (; *s; s++)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
switch (*s)
|
||||
{
|
||||
case '\r':
|
||||
c = 'r';
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
c = 'n';
|
||||
break;
|
||||
|
||||
case '\f':
|
||||
c = 'f';
|
||||
break;
|
||||
|
||||
case '\v':
|
||||
c = 'v';
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
c = 'b';
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isascii (*s) && isprint (*s))
|
||||
putc_unlocked (*s, fp);
|
||||
else
|
||||
{
|
||||
putc_unlocked ('\\', fp);
|
||||
fprintf (fp, "x%02x", *s);
|
||||
}
|
||||
}
|
||||
|
||||
if (c)
|
||||
{
|
||||
putc_unlocked ('\\', fp);
|
||||
putc_unlocked (c, fp);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_FUNLOCKFILE
|
||||
funlockfile (fp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
232
assuan/assuan.h
232
assuan/assuan.h
@ -1,232 +0,0 @@
|
||||
/* assuan.c - Definitions for the Assuan protocol
|
||||
* Copyright (C) 2001, 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
|
||||
*/
|
||||
|
||||
#ifndef ASSUAN_H
|
||||
#define ASSUAN_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h> /* for ssize_t */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ASSUAN_No_Error = 0,
|
||||
ASSUAN_General_Error = 1,
|
||||
ASSUAN_Out_Of_Core = 2,
|
||||
ASSUAN_Invalid_Value = 3,
|
||||
ASSUAN_Timeout = 4,
|
||||
ASSUAN_Read_Error = 5,
|
||||
ASSUAN_Write_Error = 6,
|
||||
ASSUAN_Problem_Starting_Server = 7,
|
||||
ASSUAN_Not_A_Server = 8,
|
||||
ASSUAN_Not_A_Client = 9,
|
||||
ASSUAN_Nested_Commands = 10,
|
||||
ASSUAN_Invalid_Response = 11,
|
||||
ASSUAN_No_Data_Callback = 12,
|
||||
ASSUAN_No_Inquire_Callback = 13,
|
||||
ASSUAN_Connect_Failed = 14,
|
||||
ASSUAN_Accept_Failed = 15,
|
||||
|
||||
/* error codes above 99 are meant as status codes */
|
||||
ASSUAN_Not_Implemented = 100,
|
||||
ASSUAN_Server_Fault = 101,
|
||||
ASSUAN_Invalid_Command = 102,
|
||||
ASSUAN_Unknown_Command = 103,
|
||||
ASSUAN_Syntax_Error = 104,
|
||||
ASSUAN_Parameter_Error = 105,
|
||||
ASSUAN_Parameter_Conflict = 106,
|
||||
ASSUAN_Line_Too_Long = 107,
|
||||
ASSUAN_Line_Not_Terminated = 108,
|
||||
ASSUAN_No_Input = 109,
|
||||
ASSUAN_No_Output = 110,
|
||||
ASSUAN_Canceled = 111,
|
||||
ASSUAN_Unsupported_Algorithm = 112,
|
||||
ASSUAN_Server_Resource_Problem = 113,
|
||||
ASSUAN_Server_IO_Error = 114,
|
||||
ASSUAN_Server_Bug = 115,
|
||||
ASSUAN_No_Data_Available = 116,
|
||||
ASSUAN_Invalid_Data = 117,
|
||||
ASSUAN_Unexpected_Command = 118,
|
||||
ASSUAN_Too_Much_Data = 119,
|
||||
ASSUAN_Inquire_Unknown = 120,
|
||||
ASSUAN_Inquire_Error = 121,
|
||||
ASSUAN_Invalid_Option = 122,
|
||||
ASSUAN_Invalid_Index = 123,
|
||||
ASSUAN_Unexpected_Status = 124,
|
||||
ASSUAN_Unexpected_Data = 125,
|
||||
ASSUAN_Invalid_Status = 126,
|
||||
|
||||
ASSUAN_Not_Confirmed = 128,
|
||||
|
||||
ASSUAN_Bad_Certificate = 201,
|
||||
ASSUAN_Bad_Certificate_Chain = 202,
|
||||
ASSUAN_Missing_Certificate = 203,
|
||||
ASSUAN_Bad_Signature = 204,
|
||||
ASSUAN_No_Agent = 205,
|
||||
ASSUAN_Agent_Error = 206,
|
||||
ASSUAN_No_Public_Key = 207,
|
||||
ASSUAN_No_Secret_Key = 208,
|
||||
ASSUAN_Invalid_Name = 209,
|
||||
|
||||
ASSUAN_Cert_Revoked = 301,
|
||||
ASSUAN_No_CRL_For_Cert = 302,
|
||||
ASSUAN_CRL_Too_Old = 303,
|
||||
ASSUAN_Not_Trusted = 304,
|
||||
|
||||
ASSUAN_Card_Error = 401,
|
||||
ASSUAN_Invalid_Card = 402,
|
||||
ASSUAN_No_PKCS15_App = 403,
|
||||
ASSUAN_Card_Not_Present = 404,
|
||||
ASSUAN_Invalid_Id = 405
|
||||
|
||||
} AssuanError;
|
||||
|
||||
/* This is a list of pre-registered ASSUAN commands */
|
||||
typedef enum {
|
||||
ASSUAN_CMD_NOP = 0,
|
||||
ASSUAN_CMD_CANCEL, /* cancel the current request */
|
||||
ASSUAN_CMD_BYE,
|
||||
ASSUAN_CMD_AUTH,
|
||||
ASSUAN_CMD_RESET,
|
||||
ASSUAN_CMD_OPTION,
|
||||
ASSUAN_CMD_DATA,
|
||||
ASSUAN_CMD_END,
|
||||
ASSUAN_CMD_INPUT,
|
||||
ASSUAN_CMD_OUTPUT,
|
||||
|
||||
ASSUAN_CMD_USER = 256 /* Other commands should be used with this offset*/
|
||||
} AssuanCommand;
|
||||
|
||||
#define ASSUAN_LINELENGTH 1002 /* 1000 + [CR,]LF */
|
||||
|
||||
struct assuan_context_s;
|
||||
typedef struct assuan_context_s *ASSUAN_CONTEXT;
|
||||
|
||||
/*-- assuan-handler.c --*/
|
||||
int assuan_register_command (ASSUAN_CONTEXT ctx,
|
||||
int cmd_id, const char *cmd_string,
|
||||
int (*handler)(ASSUAN_CONTEXT, char *));
|
||||
int assuan_register_bye_notify (ASSUAN_CONTEXT ctx,
|
||||
void (*fnc)(ASSUAN_CONTEXT));
|
||||
int assuan_register_reset_notify (ASSUAN_CONTEXT ctx,
|
||||
void (*fnc)(ASSUAN_CONTEXT));
|
||||
int assuan_register_cancel_notify (ASSUAN_CONTEXT ctx,
|
||||
void (*fnc)(ASSUAN_CONTEXT));
|
||||
int assuan_register_input_notify (ASSUAN_CONTEXT ctx,
|
||||
void (*fnc)(ASSUAN_CONTEXT, const char *));
|
||||
int assuan_register_output_notify (ASSUAN_CONTEXT ctx,
|
||||
void (*fnc)(ASSUAN_CONTEXT, const char *));
|
||||
|
||||
int assuan_register_option_handler (ASSUAN_CONTEXT ctx,
|
||||
int (*fnc)(ASSUAN_CONTEXT,
|
||||
const char*, const char*));
|
||||
|
||||
int assuan_process (ASSUAN_CONTEXT ctx);
|
||||
int assuan_process_next (ASSUAN_CONTEXT ctx);
|
||||
int assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what,
|
||||
int *fdarray, int fdarraysize);
|
||||
|
||||
|
||||
FILE *assuan_get_data_fp (ASSUAN_CONTEXT ctx);
|
||||
AssuanError assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line);
|
||||
void assuan_write_status (ASSUAN_CONTEXT ctx,
|
||||
const char *keyword, const char *text);
|
||||
|
||||
|
||||
/*-- assuan-listen.c --*/
|
||||
AssuanError assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line);
|
||||
AssuanError assuan_accept (ASSUAN_CONTEXT ctx);
|
||||
int assuan_get_input_fd (ASSUAN_CONTEXT ctx);
|
||||
int assuan_get_output_fd (ASSUAN_CONTEXT ctx);
|
||||
AssuanError assuan_close_input_fd (ASSUAN_CONTEXT ctx);
|
||||
AssuanError assuan_close_output_fd (ASSUAN_CONTEXT ctx);
|
||||
|
||||
|
||||
/*-- assuan-pipe-server.c --*/
|
||||
int assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2]);
|
||||
void assuan_deinit_server (ASSUAN_CONTEXT ctx);
|
||||
|
||||
/*-- assuan-socket-server.c --*/
|
||||
int assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd);
|
||||
int assuan_init_connected_socket_server (ASSUAN_CONTEXT *r_ctx, int fd);
|
||||
|
||||
|
||||
/*-- assuan-pipe-connect.c --*/
|
||||
AssuanError assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name,
|
||||
char *const argv[], int *fd_child_list);
|
||||
/*-- assuan-socket-connect.c --*/
|
||||
AssuanError assuan_socket_connect (ASSUAN_CONTEXT *ctx, const char *name,
|
||||
pid_t server_pid);
|
||||
|
||||
/*-- assuan-connect.c --*/
|
||||
void assuan_disconnect (ASSUAN_CONTEXT ctx);
|
||||
pid_t assuan_get_pid (ASSUAN_CONTEXT ctx);
|
||||
|
||||
/*-- assuan-client.c --*/
|
||||
AssuanError
|
||||
assuan_transact (ASSUAN_CONTEXT ctx,
|
||||
const char *command,
|
||||
AssuanError (*data_cb)(void *, const void *, size_t),
|
||||
void *data_cb_arg,
|
||||
AssuanError (*inquire_cb)(void*, const char *),
|
||||
void *inquire_cb_arg,
|
||||
AssuanError (*status_cb)(void*, const char *),
|
||||
void *status_cb_arg);
|
||||
|
||||
|
||||
/*-- assuan-inquire.c --*/
|
||||
AssuanError assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
|
||||
char **r_buffer, size_t *r_length, size_t maxlen);
|
||||
|
||||
/*-- assuan-buffer.c --*/
|
||||
AssuanError assuan_read_line (ASSUAN_CONTEXT ctx,
|
||||
char **line, size_t *linelen);
|
||||
int assuan_pending_line (ASSUAN_CONTEXT ctx);
|
||||
AssuanError assuan_write_line (ASSUAN_CONTEXT ctx, const char *line );
|
||||
AssuanError assuan_send_data (ASSUAN_CONTEXT ctx,
|
||||
const void *buffer, size_t length);
|
||||
|
||||
|
||||
/*-- assuan-util.c --*/
|
||||
void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
|
||||
void *(*new_realloc_func)(void *p, size_t n),
|
||||
void (*new_free_func)(void*) );
|
||||
void assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp);
|
||||
int assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text);
|
||||
void assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer);
|
||||
void *assuan_get_pointer (ASSUAN_CONTEXT ctx);
|
||||
|
||||
void assuan_begin_confidential (ASSUAN_CONTEXT ctx);
|
||||
void assuan_end_confidential (ASSUAN_CONTEXT ctx);
|
||||
|
||||
/*-- assuan-errors.c (built) --*/
|
||||
const char *assuan_strerror (AssuanError err);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /*ASSUAN_H*/
|
@ -1,71 +0,0 @@
|
||||
#!/bin/sh
|
||||
# mkerrors - Extract error strings from assuan.h
|
||||
# and create C source for assuan_strerror
|
||||
# Copyright (C) 2001, 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
|
||||
|
||||
cat <<EOF
|
||||
/* Generated automatically by mkerrors */
|
||||
/* Do not edit! */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "assuan.h"
|
||||
|
||||
/**
|
||||
* assuan_strerror:
|
||||
* @err: Error code
|
||||
*
|
||||
* This function returns a textual representaion of the given
|
||||
* errorcode. If this is an unknown value, a string with the value
|
||||
* is returned (Beware: it is hold in a static buffer).
|
||||
*
|
||||
* Return value: String with the error description.
|
||||
**/
|
||||
const char *
|
||||
assuan_strerror (AssuanError err)
|
||||
{
|
||||
const char *s;
|
||||
static char buf[25];
|
||||
|
||||
switch (err)
|
||||
{
|
||||
EOF
|
||||
|
||||
awk '
|
||||
/ASSUAN_No_Error/ { okay=1 }
|
||||
!okay {next}
|
||||
/}/ { exit 0 }
|
||||
/ASSUAN_[A-Za-z_]*/ { print_code($1) }
|
||||
|
||||
|
||||
function print_code( s )
|
||||
{
|
||||
printf " case %s: s=\"", s ;
|
||||
gsub(/_/, " ", s );
|
||||
printf "%s\"; break;\n", tolower(substr(s,8));
|
||||
}
|
||||
'
|
||||
|
||||
cat <<EOF
|
||||
default: sprintf (buf, "ec=%d", err ); s=buf; break;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
EOF
|
Loading…
x
Reference in New Issue
Block a user