2009-03-06  Marcus Brinkmann  <marcus@g10code.de>

	* assuan/: Update to libassuan SVN 2009-03-06.

src/
2009-03-06  Marcus Brinkmann  <marcus@g10code.de>

	* version.c (do_subsystem_inits): Do not set assuan log level.
	* debug.c (debug_init): Likewise.
This commit is contained in:
Marcus Brinkmann 2009-03-06 22:29:49 +00:00
parent f0dccac380
commit 9ace1d5642
22 changed files with 1663 additions and 585 deletions

View File

@ -1,3 +1,7 @@
2009-03-06 Marcus Brinkmann <marcus@g10code.de>
* assuan/: Update to libassuan SVN 2009-03-06.
2009-01-26 Werner Koch <wk@g10code.com>
* configure.ac (AC_CONFIG_FILES): Add tests/opassuan/Makefile.

View File

@ -3,68 +3,262 @@
* assuan-buffer.c (assuan_send_data): Add hack to optionally send
a final "CAN".
2008-11-03 Marcus Brinkmann <marcus@g10code.com>
2008-11-03 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (INCLUDES): Replace gpgme path with src.
* assuan-handler.c (std_handler_help): Make I unsigned to silence
gcc -W warning.
* assuan-logging.c (_assuan_log_print_buffer): Likewise for N.
* funopen.c (_assuan_funopen): Remove initializer to silence gcc
-W warning.
* assuan-handler.c (std_cmd_table): Add missing initializer to
silence gcc -W warning.
* assuan-socket-server.c (io): Likewise.
* assuan-socket-connect.c (assuan_socket_connect_ext): Likewise.
2008-10-30 Marcus Brinkmann <marcus@g10code.de>
2008-10-29 Marcus Brinkmann <marcus@g10code.de>
* assuan-pipe-connect.c: Fix prototype for _gpgme_io_spawn. Cast
second argument in its invocation to silence gcc warning.
* assuan.h (assuan_error_t) (_ASSUAN_ONLY_GPG_ERRORS): Make
unsigned int.
(assuan_transact): Change return type of callback handlers to
assuan_error_t.
2008-06-25 Marcus Brinkmann <marcus@g10code.de>
2008-10-15 Werner Koch <wk@g10code.com>
* assuan-pipe-connect.c (struct spawn_fd_item_s): Add new members.
(HANDLE_TRANSLATION): New macro.
(pipe_connect_gpgme): Adjust caller of _gpgme_io_spawn.
[HANDLE_TRANSLATION]: Return translated handles.
* assuan-logging.c (_assuan_log_printf): Flush if the format
string ends with a LF.
2008-02-14 Werner Koch <wk@g10code.com>
2008-09-01 Werner Koch <wk@g10code.com>
* assuan-pipe-connect.c (_gpgme_io_spawn): Adjust prototype.
(pipe_connect_gpgme, pipe_connect_gpgme): Adjust call.
* assuan-io.c: Include time.h. Fixes bug#951.
(_assuan_usleep): Use nanosleep only is available.
2008-01-04 Marcus Brinkmann <marcus@g10code.de>
2008-03-25 Marcus Brinkmann <marcus@g10code.de>
* assuan-pipe-connect.c (_gpgme_io_pipe)
(_gpgme_io_spawn) [_ASSUAN_IN_GPGME_BUILD_ASSUAN]: Add prototypes
to silence compiler warning. Reported by Alon Bar-Lev.
* assuan-inquire.c (assuan_inquire): Loop over _assuan_read_line
for EAGAIN.
2008-03-21 Marcus Brinkmann <marcus@g10code.de>
* assuan-defs.h (_assuan_usleep): New prototype.
* assuan-io.c (_assuan_usleep): New function.
* assuan-io-pth.c (_assuan_usleep): New function.
* mkerrors: Do not incude <windows.h>, but assuan-defs.h.
(_assuan_error_is_eagain): Call _assuan_usleep.
* mkerrors [HAVE_W32_SYSTEM]: Include <windows.h>
(_assuan_error_is_eagain) [HAVE_W32_SYSTEM]: Wait the tenth of a
second.
2007-11-23 Marcus Brinkmann <marcus@g10code.de>
* assuan-inquire.c (_assuan_inquire_ext_cb): Pass through return
value from callback function.
Suggested by Ben Kibbey <bjk@luxsci.net>.
2007-11-14 Werner Koch <wk@g10code.com>
* assuan-pipe-connect.c (pipe_connect_unix): Add dummy arg FLAGS.
(pipe_connect_w32): Add arg FLAGS and start process detached if
requested. Changed callers to pass 0.
(assuan_pipe_connect_ext): Pass FLAG.
2007-11-12 Marcus Brinkmann <marcus@g10code.de>
* assuan-inquire.c (_assuan_inquire_ext_cb): Clear
CTX->inquire_membuf after deallocating it.
2007-10-18 Marcus Brinkmann <marcus@g10code.de>
* assuan-handler.c (std_handler_help): New function.
(std_cmd_table): Add new command HELP.
2007-10-08 Werner Koch <wk@g10code.com>
* assuan-util.c (assuan_set_io_hooks): New.
* assuan.h (struct assuan_io_hooks): New.
(assuan_set_io_hooks, _assuan_io_hooks): Add prefix macros.
* assuan-defs.h (_assuan_io_hooks): New.
* assuan-io.c (do_io_read): Take all code from _assuan_io_read.
(_assuan_io_read, _assuan_simple_read): Add hook feature.
(do_io_write): Take all code from _assuan_io_write.
(_assuan_io_write, _assuan_simple_write): Add hook feature.
* assuan-io-pth.c (_assuan_simple_read, _assuan_simple_write)
(_assuan_io_read, _assuan_io_write): Add hook feature.
2007-10-05 Marcus Brinkmann <marcus@g10code.de>
* assuan.h (_assuan_error_is_eagain): Add prefix macro.
* assuan-defs.h (_assuan_error_is_eagain): New prototype.
* mkerrors (_assuan_error_is_eagain): New function.
* assuan-handler.c (process_next): Leave on EAGAIN.
* assuan-handler.c (process_request),
assuan-client.c (_assuan_read_from_server),
assuan-buffer.c (assuan_read_line): Busy loop over EAGAIN.
2007-10-05 Werner Koch <wk@g10code.com>
* assuan-socket.c (_assuan_sock_wsa2errno): Map WSANOTINITIALISED.
(_assuan_sock_new): Use assuan_fd_t.
* assuan.h (_assuan_sock_wsa2errno): Add prefix macro.
2007-10-05 Marcus Brinkmann <marcus@g10code.de>
* assuan-defs.h (_assuan_sock_wsa2errno) [HAVE_W32_SYSTEM]: Add prototype.
* assuan-uds.c (wsa2errno) [HAVE_W32_SYSTEM]: Move and rename to ...
* assuan-socket.c (_assuan_sock_wsa2errno) [HAVE_W32_SYSTEM]: ... this.
(_assuan_close, _assuan_sock_new, _assuan_sock_connect, _assuan_sock_bind):
Always set errno on error.
* assuan-uds.c (wsa2errno) [HAVE_W32_SYSTEM]: New function.
(uds_reader, uds_writer) [HAVE_W32_SYSTEM]: Set errno.
2007-10-04 Werner Koch <wk@g10code.com>
* mkerrors: Map EAGAIN to GPG_ERR_EAGAIN for read and write
errors.
2007-10-02 Werner Koch <wk@g10code.com>
* assuan-io.c (_assuan_io_read) [W32]: Map WSAEWOULDBLOCK to EAGAIN.
* assuan-socket.c (_assuan_sock_check_nonce): N needs to be signed.
* assuan-defs.h (struct assuan_context_s): Add LISTEN_NONCE.
* assuan-socket-server.c (assuan_set_sock_nonce): New.
(accept_connection): Check the nonce.
2007-10-01 Werner Koch <wk@g10code.com>
* assuan.h (ASSUAN_INT2FD, ASSUAN_FD2INT): New.
* assuan-socket.c: Rewritten.
(assuan_sock_new, assuan_sock_connect, assuan_sock_bind)
(assuan_sock_get_nonce, assuan_sock_check_nonce): New APIs.
* assuan-io.c (_assuan_simple_read, _assuan_simple_write):
Factored code out to ...
(_assuan_io_read, _assuan_io_write): .. new.
* assuan-io-pth.c (_assuan_io_read, _assuan_io_write): New.
2007-09-25 Werner Koch <wk@g10code.com>
* assuan.h (_assuan_gpg_strerror_r, _assuan_gpg_strsource): Add
new wrappers.
wrappers for these new internal functions.
2007-09-24 Marcus Brinkmann <marcus@g10code.de>
* assuan-uds.c (uds_reader) [HAVE_W32_SYSTEM]: Do not touch the
UDS structure in the context. Reported by Frank Osterfeld.
(uds_writer): Clarify code.
2007-09-14 Marcus Brinkmann <marcus@g10code.de>
* assuan-pipe-connect.c (do_finish) [HAVE_W32_SYSTEM]: Close
ctx->pid as handle.
(pipe_connect_w32): Save the spawned processes handle.
2007-09-13 Werner Koch <wk@g10code.com>
* assuan-socket.c (_assuan_close): Add inactive debug outputs.
2007-09-11 Marcus Brinkmann <marcus@g10code.de>
* assuan.h: Use _WIN32 instead of HAVE_W32_SYSTEM.
2007-09-07 Marcus Brinkmann <marcus@g10code.de>
* assuan-inquire.c (assuan_inquire_ext): If MAXLEN is 0, still
initialize MEMBUF.
* assuan-inquire.c (_assuan_inquire_ext_cb): Clear CTX->in_inquire
before invoking callback and returning.
2007-09-05 Marcus Brinkmann <marcus@g10code.de>
* assuan-handler.c (dispatch_command): Return non-critical errors
with PROCESS_DONE ().
2007-09-03 Marcus Brinkmann <marcus@g10code.de>
* assuan.h [_ASSUAN_EXT_SYM_PREFIX]: Add missing symbol renames
with _ASSUAN_PREFIX.
2007-08-02 Werner Koch <wk@g10code.com>
2007-09-03 Marcus Brinkmann <marcus@g10code.de>
* assuan-pipe-connect.c (pipe_connect_w32): A bit more debug output.
(pipe_connect_w32): Use DETACHED_PROCESS flag.
* assuan-logging.c (log_level): New. Use this to disable logging.
(assuan_set_assuan_log_level): New.
* assuan.h: Add prototype.
* assuan.h [_ASSUAN_EXT_SYM_PREFIX]: Add missing symbol renames
with _ASSUAN_PREFIX.
* assuan.h (assuan_inquire_ext): Move buffer and buffer_length
arguments callback in prototype.
* assuan-defs.h (struct assuan_context_s): Remove members
inquire_r_buffer and inquire_r_buffer_len. Add buffer and buffer
length arguments to inquire_cb.
* assuan-inquire.c (_assuan_inquire_ext_cb): Return buffer and
buffer length via callback.
(assuan_inquire_ext): Move buffer and buffer length arguments to
callback.
2007-08-24 Werner Koch <wk@g10code.com>
Switched license to back to LGPLv2.1.
2007-08-09 Marcus Brinkmann <marcus@g10code.de>
* assuan.h (assuan_process_done, assuan_inquire_ext): New
prototypes.
* assuan-defs.h (struct assuan_context_s): New members
in_process_next, in_command, inquire_cb, inquire_cb_data,
inquire_r_buffer, inquire_r_buffer_len, inquire_membuf.
(_assuan_inquire_ext_cb, _assuan_inquire_release): New prototypes.
* assuan-handler.c (PROCESS_DONE): New macro.
(dummy_handler, std_handler_nop, std_handler_cancel)
(std_handler_option, std_handler_bye, std_handler_auth)
(std_handler_reset, std_handler_end): Use PROCESS_DONE to
optionally call assuan_process_done if CTX->in_process_next is
true.
(assuan_process_done, process_next): New functions.
(assuan_process_next): Rewritten to support external event
handling.
* mkerrors: Do not clear high bits of -1 for old style EOF.
* assuan-inquire.c (_assuan_inquire_release)
(_assuan_inquire_ext_cb, assuan_inquire_ext): New functions.
* assuan-pipe-server.c (_assuan_release_context): Call
_assuan_inquire_release.
2007-07-12 Werner Koch <wk@g10code.com>
* assuan-handler.c (assuan_get_active_fds): Use get_osfhandle for
the data fp.
* assuan-socket.c (_assuan_close) [W32]: Use CloseHandle and not close.
* assuan.h (assuan_fd_t): New.
(ASSUAN_INVALID_FD): New. Use it everywhere.
* assuan-defs.h (SOCKET2HANDLE, HANDLE2SOCKET) [W32]: New. Use
them to cast descriptors for socket fucntions.
* assuan-pipe-connect.c (fd_to_handle, handle_to_fd): Remove
definition and all uses.
(pid_to_handle, handle_to_pid): Remove as they are ununsed.
* assuan-io.c (_assuan_simple_write, _assuan_simple_read) [W32]:
Make use of HANDLE2SOCKET.
* assuan-socket.c (_assuan_close) [W32]: Use CloseHandle and not
close.
* assuan-handler.c (assuan_get_active_fds) [W32]: Use
_get_osfhandle for the data fp.
* assuan-io.c (_assuan_simple_write, _assuan_simple_read): Map
ERROR_BROKEN_PIPE to EPIPE.
* assuan-io.c (_assuan_simple_write): Return EPIPE on a closed pipe.
(_assuan_simple_read): Likewise
2007-07-08 Marcus Brinkmann <marcus@g10code.de>
* assuan-defs.h (struct assuan_context_s): Have partial peercred
structure even if HAVE_W32_SYSTEM, and have full peercred
structure only if HAVE_SO_PEERCRED.
* assuan-defs.h (struct assuan_context_s): Have full peercred
structure for HAVE_SO_PEERCRED.
* assuan-connect.c (assuan_get_peercred) [!HAVE_SO_PEERCRED]: Do
not try to set PID, UID and GID.
2007-07-05 Werner Koch <wk@g10code.com>
* assuan-defs.h (struct assuan_context_s): Have peercred.valid
even for Windows. This makes some other code cleaner.
* assuan.h (ASSUAN_CONFIDENTIAL): New flag.
* assuan-util.c (assuan_set_flag, assuan_get_flag): Support flag.
2007-07-04 Marcus Brinkmann <marcus@g10code.de>
Change _WIN32 to HAVE_W32_SYSTEM for consistency.
@ -382,28 +576,63 @@
to silence gcc warning.
* assuan-inquire.c (assuan_inquire): Likewise.
2005-08-19 Werner Koch <wk@g10code.com>
2005-09-08 Marcus Brinkmann <marcus@g10code.com>
* funopen.c, assuan-socket.c: Copied from libassuan CVS.
* assuan-pipe-connect.c (assuan_pipe_connect2): Add missing
declaration of PID.
2005-08-09 Werner Koch <wk@g10code.com>
* README.1st: Adjusted to cope with changes done in upstream Assuan.
Merged changes for W32 support from libassuan.
* mkerrors: Include config.h into assuan-errors.c. This is
required so that assuan.h knows about the W32 macro.
* assuan.h [_ASSUAN_EXT_SYM_PREFIX]: New.
* assuan-io.c [_ASSUAN_NO_PTH]: New.
* assuan-pipe-connect.c (fix_signals) [_ASSUAN_NO_FIXED_SIGNALS]: New.
(assuan_pipe_connect2) [_ASSUAN_USE_DOUBLE_FORK]: Use double fork.
(fix_signals) [_ASSUAN_USE_DOUBLE_FORK]: Do not wait..
* assuan-logging.c, assuan-io.c: Include config.h
Replaced all usages of _WIN32 by the new HAVE_W32_SYSTEM because
there is nothing winning in this API.
* assuan-pipe-connect.c (assuan_pipe_connect2) [_WIN32]: Return
error Not Imlemented.
2005-05-21 Werner Koch <wk@g10code.com>
* assuan-util.c (assuan_set_flag, assuan_get_flag): New.
* assuan-defs.h (struct assuan_context_s): New field flags.
* assuan.h (assuan_flag_t): New with one flag value
ASSUAN_NO_WAITPID for now.
* assuan-pipe-connect.c (do_finish): Take care of the no_waitpid
flag.
2005-04-04 Werner Koch <wk@g10code.com>
* assuan-util.c (_assuan_calloc): Avoid integer overflow.
2005-03-22 Werner Koch <wk@g10code.com>
* assuan-defs.h (struct assuan_io): Renamed elements READ and
WRITE to READFNC and WRITEFNC to avoid problems with read defined
as macros. Changed callers. Noted by Ville Skyttä.
2005-02-24 Werner Koch <wk@g10code.com>
* assuan-client.c (assuan_transact): Handle empty and comment
commands correctly.
2004-12-20 Werner Koch <wk@g10code.com>
* assuan-socket-connect.c (assuan_socket_connect) [W32]: Allow for
a drive letter in the path.
2004-12-19 Werner Koch <wk@g10code.com>
* assuan-pipe-server.c (assuan_init_pipe_server) [W32]: Map file
descriptors using _get_osfhandle.
2004-12-19 Moritz Schulte <moritz@g10code.com>
* assuan-pipe-connect.c (assuan_pipe_connect2): Removed "`"
character at beginning of line 532.
2004-12-18 Werner Koch <wk@g10code.com>
* assuan-logging.c (_assuan_w32_strerror): New.
* assuan-defs.h (w32_strerror): new.
* assuan-pipe-connect.c (assuan_pipe_connect2, fix_signals):
@ -411,23 +640,56 @@
(build_w32_commandline, create_inheritable_pipe): New. Taken
from gnupg 1.9.
(assuan_pipe_connect2) [W32]: Implemented for W32.
* assuan-pipe-server.c (assuan_init_pipe_server) [W32]: Map file
descriptors using _get_osfhandle.
* assuan-socket-connect.c (assuan_socket_connect) [W32]: Allow for
a drive letter in the path.
* assuan-client.c (assuan_transact): Handle empty and comment
commands correctly.
* assuan-util.c (_assuan_calloc): Avoid integer overflow.
* assuan-util.c (assuan_set_flag, assuan_get_flag): New.
* assuan-defs.h (struct assuan_context_s): New field flags.
* assuan.h (assuan_flag_t): New with one flag value
ASSUAN_NO_WAITPID for now.
* assuan-pipe-connect.c (do_finish): Take care of the no_waitpid
flag.
* mkerrors: Include config.h into assuan-errors.c. This is
required so that assuan.h knows about the W32 macro.
2005-08-09 Timo Schulz <twoaday@g10code.com> (ported from libassuan by wk)
2004-12-14 Werner Koch <wk@g10code.com>
* assuan-socket-connect.c (assuan_socket_connect): Always allow
NAME to start with a froward slash.
2004-12-07 Werner Koch <wk@g10code.com>
* assuan-logging.c, assuan-io.c: Include config.h
Replaced all usages of _WIN32 by the new HAVE_W32_SYSTEM because
there is nothing winning in this API.
* assuan-pipe-connect.c (assuan_pipe_connect2) [_WIN32]: Return
error Not Imlemented.
2004-11-27 Werner Koch <wk@g10code.com>
* assuan-socket.c: Include sys/types.h. Noted by Michael
Nottebrock.
2004-11-26 Werner Koch <wk@g10code.com>
* assuan-io.c [_WIN32]: Avoid warnings about unknown pragmas.
2004-11-24 Werner Koch <wk@g10code.com>
* assuan-logging.c (_assuan_log_printf): New.
* assuan-domain-connect.c (LOG): Removed and replaced all callers
by _assuan_log_printf. This is needed for C89 and gcc 2.95 which
both don't have C99 style variable arg macros.
* assuan-pipe-connect.c (LOG): Ditto.
* assuan-socket-connect.c (LOG): Ditto.
* assuan-socket.c[!_WIN32]: Fixed includes.
2004-11-23 Timo Schulz <twoaday@g10code.com>
* assuan-socket.c (_assuan_sock_connect): Get local port from
the sun_path[] file.
(_assuan_sock_bind): Write local port to the sun_path[] file.
* assuan-socket-connect.c (assuan_socket_connect): Use DIRSEP_C
for a better portability.
(assuan-defs.h): Define DIRSEP_C.
2004-11-19 Werner Koch <wk@g10code.com>
* assuan-handler.c (assuan_write_status): Return an error code.
2004-11-22 Timo Schulz <twoaday@g10code.com>
* assuan-io.c (_assuan_simple_read, _assuan_simple_write): W32
support.
@ -435,33 +697,38 @@
(_assuan_sock_new): New.
(_assuan_sock_bind): New.
2005-03-22 Werner Koch <wk@g10code.com>
2004-11-16 Werner Koch <wk@g10code.com>
* assuan-defs.h (struct assuan_io): Renamed elements READ and
WRITE to READFNC and WRITEFNC to avoid problems with read defined
as macro. Changed callers. Noted by Ville Skyttä.
* assuan-socket-connect.c (LOG): Fixed macro to print not only the
prefix.
* assuan-domain-connect.c, assuan-socket-connect.c (LOG): Ditto.
2004-12-16 Marcus Brinkmann <marcus@g10code.de>
2004-10-02 Werner Koch <wk@g10code.com>
* assuan-pipe-connect.c (do_finish): Do not wait for child to finish.
(assuan_pipe_connect): Use double-fork approach.
* assuan-connect.c (assuan_disconnect): Do not write BYE to the
status line.
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
* README.1st: Add copyright notice.
* assuan-socket-connect.c: Define SUN_LEN, AF_LOCAL and PF_LOCAL
if they are not available.
* assuan-domain-connect.c: Define PF_LOCAL and AF_LOCAL if needed.
2004-06-23 Marcus Brinkmann <marcus@g10code.de>
* assuan-domain-connect.c [HAVE_SYS_UIO_H]: Include <sys/uio.h>.
* assuan-handler.c: Include <errno.h>.
2004-05-11 Werner Koch <wk@gnupg.org>
2004-06-08 Marcus Brinkmann <marcus@g10code.de>
* assuan-listen.c (assuan_set_hello_line, assuan_accept): Allow
for multi line hello strings.
* assuan-buffer.c (assuan_write_line): If the line is longer than
the maximum line length, bail out early.
* assuan-buffer.c (_assuan_write_line): New with parts of ..
(assuan_write_line): .. factored out.
2004-04-29 Werner Koch <wk@gnupg.org>
* assuan-socket-connect.c: Include string.h.
* assuan-logging.c: Ditto.
2004-04-22 Marcus Brinkmann <marcus@g10code.de>
* libassuan.m4: Quote first argument to AC_DEFUN.
2004-04-21 Werner Koch <wk@gnupg.org>
@ -1039,7 +1306,7 @@
* assuan-defs.h: Add space in the context for this.
Copyright 2001, 2002, 2006 Free Software Foundation, Inc.
Copyright 2001, 2002, 2006, 2007 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

View File

@ -14,9 +14,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
@ -53,9 +51,10 @@ writen (assuan_context_t ctx, const char *buffer, size_t length)
return 0; /* okay */
}
/* Read an entire line. Returns 0 on success or -1 and ERRNo on
/* Read an entire line. Returns 0 on success or -1 and ERRNO on
failure. EOF is indictated by setting the integer at address
R_EOF. */
R_EOF. Note: BUF, R_NREAD and R_EOF contain a valid result even if
an error is returned. */
static int
readline (assuan_context_t ctx, char *buf, size_t buflen,
int *r_nread, int *r_eof)
@ -134,11 +133,23 @@ _assuan_read_line (assuan_context_t ctx)
&nread, &ctx->inbound.eof);
if (rc)
{
int saved_errno = errno;
if (ctx->log_fp)
fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s (%d)]\n",
fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s]\n",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx->inbound.fd,
strerror (errno), errno);
(unsigned int)getpid (), (int)ctx->inbound.fd,
strerror (errno));
if (saved_errno == EAGAIN)
{
/* We have to save a partial line. */
memcpy (ctx->inbound.attic.line, line, atticlen + nread);
ctx->inbound.attic.pending = 0;
ctx->inbound.attic.linelen = atticlen + nread;
}
errno = saved_errno;
return _assuan_error (ASSUAN_Read_Error);
}
if (!nread)
@ -147,7 +158,7 @@ _assuan_read_line (assuan_context_t ctx)
if (ctx->log_fp)
fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [EOF]\n",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx->inbound.fd);
(unsigned int)getpid (), (int)ctx->inbound.fd);
return _assuan_error (-1);
}
@ -191,7 +202,7 @@ _assuan_read_line (assuan_context_t ctx)
{
fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- ",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx->inbound.fd);
(unsigned int)getpid (), (int)ctx->inbound.fd);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
@ -207,7 +218,7 @@ _assuan_read_line (assuan_context_t ctx)
if (ctx->log_fp)
fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Invalid line]\n",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx->inbound.fd);
(unsigned int)getpid (), (int)ctx->inbound.fd);
*line = 0;
ctx->inbound.linelen = 0;
return _assuan_error (ctx->inbound.eof
@ -234,7 +245,12 @@ assuan_read_line (assuan_context_t ctx, char **line, size_t *linelen)
if (!ctx)
return _assuan_error (ASSUAN_Invalid_Value);
do
{
err = _assuan_read_line (ctx);
}
while (_assuan_error_is_eagain (err));
*line = ctx->inbound.line;
*linelen = ctx->inbound.linelen;
return err;
@ -265,7 +281,7 @@ _assuan_write_line (assuan_context_t ctx, const char *prefix,
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> "
"[supplied line too long -truncated]\n",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx->inbound.fd);
(unsigned int)getpid (), (int)ctx->inbound.fd);
if (prefixlen > 5)
prefixlen = 5;
if (len > ASSUAN_LINELENGTH - prefixlen - 2)
@ -281,7 +297,7 @@ _assuan_write_line (assuan_context_t ctx, const char *prefix,
{
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx->inbound.fd);
(unsigned int)getpid (), (int)ctx->inbound.fd);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
@ -333,7 +349,7 @@ assuan_write_line (assuan_context_t ctx, const char *line)
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> "
"[supplied line contained a LF - truncated]\n",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx->inbound.fd);
(unsigned int)getpid (), (int)ctx->inbound.fd);
return _assuan_write_line (ctx, NULL, line, len);
}
@ -398,7 +414,7 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size)
{
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx->inbound.fd);
(unsigned int)getpid (), (int)ctx->inbound.fd);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
@ -454,7 +470,7 @@ _assuan_cookie_write_flush (void *cookie)
{
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
assuan_get_assuan_log_prefix (),
(unsigned int)getpid (), ctx->inbound.fd);
(unsigned int)getpid (), (int)ctx->inbound.fd);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
@ -524,11 +540,11 @@ assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length)
}
assuan_error_t
assuan_sendfd (assuan_context_t ctx, int fd)
assuan_sendfd (assuan_context_t ctx, assuan_fd_t fd)
{
/* It is explicitly allowed to use (NULL, -1) as a runtime test to
check whether descriptor passing is available. */
if (!ctx && fd == -1)
if (!ctx && fd == ASSUAN_INVALID_FD)
#ifdef USE_DESCRIPTOR_PASSING
return 0;
#else
@ -543,7 +559,7 @@ assuan_sendfd (assuan_context_t ctx, int fd)
}
assuan_error_t
assuan_receivefd (assuan_context_t ctx, int *fd)
assuan_receivefd (assuan_context_t ctx, assuan_fd_t *fd)
{
if (! ctx->io->receivefd)
return set_error (ctx, Not_Implemented,

View File

@ -14,9 +14,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
@ -42,9 +40,13 @@ _assuan_read_from_server (assuan_context_t ctx, int *okay, int *off)
*okay = 0;
*off = 0;
do
{
do
{
rc = _assuan_read_line (ctx);
}
while (_assuan_error_is_eagain (rc));
if (rc)
return rc;
line = ctx->inbound.line;

View File

@ -14,9 +14,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
@ -60,8 +58,8 @@ assuan_get_pid (assuan_context_t ctx)
#ifndef HAVE_W32_SYSTEM
/* Return user credentials. PID, UID and GID amy be gived as NULL if
you are not interested in this value. For getting the pid of the
/* Return user credentials. PID, UID and GID may be given as NULL if
you are not interested in a value. For getting the pid of the
peer the assuan_get_pid is usually better suited. */
assuan_error_t
assuan_get_peercred (assuan_context_t ctx, pid_t *pid, uid_t *uid, gid_t *gid)

View File

@ -1,5 +1,5 @@
/* assuan-defs.c - Internal definitions to Assuan
* Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
* Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -40,17 +40,6 @@
#endif
#ifdef HAVE_W32_SYSTEM
#define AF_LOCAL AF_UNIX
/* We need to prefix the structure with a sockaddr_in header so we can
use it later for sendto and recvfrom. */
struct sockaddr_un
{
short sun_family;
unsigned short sun_port;
struct in_addr sun_addr;
char sun_path[108-2-4]; /* Path name. */
};
/* Not needed anymore because the current mingw32 defines this in
sys/types.h */
/* typedef int ssize_t; */
@ -80,12 +69,16 @@ struct assuan_io
/* Routine to write to output_fd. */
ssize_t (*writefnc) (assuan_context_t, const void *, size_t);
/* Send a file descriptor. */
assuan_error_t (*sendfd) (assuan_context_t, int);
assuan_error_t (*sendfd) (assuan_context_t, assuan_fd_t);
/* Receive a file descriptor. */
assuan_error_t (*receivefd) (assuan_context_t, int *);
assuan_error_t (*receivefd) (assuan_context_t, assuan_fd_t *);
};
/* The global variable with the optional hook fucntions. */
extern struct assuan_io_hooks _assuan_io_hooks;
/* The context we use with most functions. */
struct assuan_context_s
{
@ -103,6 +96,14 @@ struct assuan_context_s
int confidential;
int is_server; /* Set if this is context belongs to a server */
int in_inquire;
int in_process_next;
int in_command;
/* The following members are used by assuan_inquire_ext. */
int (*inquire_cb) (void *cb_data, int rc, unsigned char *buf, size_t len);
void *inquire_cb_data;
void *inquire_membuf;
char *hello_line;
char *okay_line; /* See assuan_set_okay_line() */
@ -111,7 +112,7 @@ struct assuan_context_s
FILE *log_fp;
struct {
int fd;
assuan_fd_t fd;
int eof;
char line[LINELENGTH];
int linelen; /* w/o CR, LF - might not be the same as
@ -125,7 +126,7 @@ struct assuan_context_s
} inbound;
struct {
int fd;
assuan_fd_t fd;
struct {
FILE *fp;
char line[LINELENGTH];
@ -137,8 +138,10 @@ struct assuan_context_s
int pipe_mode; /* We are in pipe mode, i.e. we can handle just one
connection and must terminate then. */
pid_t pid; /* The pid of the peer. */
int listen_fd; /* The fd we are listening on (used by socket servers) */
int connected_fd; /* helper */
assuan_fd_t listen_fd; /* The fd we are listening on (used by
socket servers) */
assuan_sock_nonce_t listen_nonce; /* Used with LISTEN_FD. */
assuan_fd_t connected_fd; /* helper */
struct {
int valid; /* Whether this structure has valid information. */
@ -162,7 +165,7 @@ struct assuan_context_s
int bufferoffset; /* Offset of start of buffer. */
int buffersize; /* Bytes buffered. */
int pendingfds[5]; /* Array to save received descriptors. */
assuan_fd_t pendingfds[5]; /* Array to save received descriptors. */
int pendingfdscount; /* Number of received descriptors. */
} uds;
@ -188,15 +191,15 @@ struct assuan_context_s
/* If set, this is called right before logging an I/O line. With
DIRECTION set to 1 it is called for an output oeration; 0 means
an input operation. If bit 0 is set in the return value, the
logging of the will be suppressed. With bit 1 set, the entire
line will be ignored. */
logging of the line will be suppressed. With bit 1 set, the
entire line will be ignored. */
unsigned int (*io_monitor)(assuan_context_t ctx,
int direction,
const char *line,
size_t linelen);
int input_fd; /* set by INPUT command */
int output_fd; /* set by OUTPUT command */
assuan_fd_t input_fd; /* Set by the INPUT command. */
assuan_fd_t output_fd; /* Set by the OUTPUT command. */
/* io routines. */
struct assuan_io *io;
@ -228,17 +231,22 @@ assuan_error_t _assuan_read_from_server (assuan_context_t ctx,
/*-- assuan-error.c --*/
/*-- assuan-inquire.c --*/
int _assuan_inquire_ext_cb (assuan_context_t ctx);
void _assuan_inquire_release (assuan_context_t ctx);
/* Map error codes as used in this implementaion to the libgpg-error
/* Map error codes as used in this implementation to the libgpg-error
codes. */
assuan_error_t _assuan_error (int oldcode);
/* Check if ERR means EAGAIN. */
int _assuan_error_is_eagain (assuan_error_t err);
/* Extrac the erro code from A. This works for both the old and the
new style error codes. This needs to be whenever an error code is
compared. */
/* Extract the error code from A. This works for both the old and the
new style error codes. This needs to be used whenever an error
code is compared. */
#define err_code(a) ((a) & 0x00ffffff)
/* Check whether A is the erro code for EOF. We allow forold and new
/* Check whether A is the erro code for EOF. We allow for old and new
style EOF error codes here. */
#define err_is_eof(a) ((a) == (-1) || err_code (a) == 16383)
@ -284,6 +292,8 @@ pid_t _assuan_waitpid (pid_t pid, int *status, int options);
ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size);
ssize_t _assuan_simple_write (assuan_context_t ctx, const void *buffer,
size_t size);
ssize_t _assuan_io_read (assuan_fd_t fd, void *buffer, size_t size);
ssize_t _assuan_io_write (assuan_fd_t fd, const void *buffer, size_t size);
#ifdef HAVE_W32_SYSTEM
int _assuan_simple_sendmsg (assuan_context_t ctx, void *msg);
int _assuan_simple_recvmsg (assuan_context_t ctx, void *msg);
@ -292,11 +302,21 @@ ssize_t _assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg);
ssize_t _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg);
#endif
void _assuan_usleep (unsigned int usec);
/*-- assuan-socket.c --*/
int _assuan_close (int fd);
int _assuan_sock_new (int domain, int type, int proto);
int _assuan_sock_bind (int sockfd, struct sockaddr *addr, int addrlen);
int _assuan_sock_connect (int sockfd, struct sockaddr *addr, int addrlen);
int _assuan_close (assuan_fd_t fd);
assuan_fd_t _assuan_sock_new (int domain, int type, int proto);
int _assuan_sock_connect (assuan_fd_t sockfd,
struct sockaddr *addr, int addrlen);
int _assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen);
int _assuan_sock_get_nonce (struct sockaddr *addr, int addrlen,
assuan_sock_nonce_t *nonce);
int _assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce);
#ifdef HAVE_W32_SYSTEM
int _assuan_sock_wsa2errno (int err);
#endif
#ifdef HAVE_FOPENCOOKIE
/* We have to implement funopen in terms of glibc's fopencookie. */
@ -329,4 +349,13 @@ int putc_unlocked (int c, FILE *stream);
#define DIMof(type,member) DIM(((type *)0)->member)
#if HAVE_W32_SYSTEM
#define SOCKET2HANDLE(s) ((void *)(s))
#define HANDLE2SOCKET(h) ((unsigned int)(h))
#else
#define SOCKET2HANDLE(s) (s)
#define HANDLE2SOCKET(h) (h)
#endif
#endif /*ASSUAN_DEFS_H*/

View File

@ -1,5 +1,5 @@
/* assuan-handler.c - dispatch commands
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
* Copyright (C) 2001, 2002, 2003, 2007 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -14,9 +14,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
@ -35,18 +33,21 @@
static int my_strcasecmp (const char *a, const char *b);
#define PROCESS_DONE(ctx, rc) \
((ctx)->in_process_next ? assuan_process_done ((ctx), (rc)) : (rc))
static int
dummy_handler (assuan_context_t ctx, char *line)
{
return set_error (ctx, Server_Fault, "no handler registered");
return
PROCESS_DONE (ctx, set_error (ctx, Server_Fault, "no handler registered"));
}
static int
std_handler_nop (assuan_context_t ctx, char *line)
{
return 0; /* okay */
return PROCESS_DONE (ctx, 0); /* okay */
}
static int
@ -54,7 +55,7 @@ std_handler_cancel (assuan_context_t ctx, char *line)
{
if (ctx->cancel_notify_fnc)
ctx->cancel_notify_fnc (ctx);
return set_error (ctx, Not_Implemented, NULL);
return PROCESS_DONE (ctx, set_error (ctx, Not_Implemented, NULL));
}
static int
@ -65,9 +66,12 @@ std_handler_option (assuan_context_t ctx, char *line)
for (key=line; spacep (key); key++)
;
if (!*key)
return set_error (ctx, Syntax_Error, "argument required");
return
PROCESS_DONE (ctx, set_error (ctx, Syntax_Error, "argument required"));
if (*key == '=')
return set_error (ctx, Syntax_Error, "no option name given");
return
PROCESS_DONE (ctx, set_error (ctx, Syntax_Error,
"no option name given"));
for (value=key; *value && !spacep (value) && *value != '='; value++)
;
if (*value)
@ -82,7 +86,9 @@ std_handler_option (assuan_context_t ctx, char *line)
for (; spacep (value); value++)
;
if (!*value)
return set_error (ctx, Syntax_Error, "option argument expected");
return
PROCESS_DONE (ctx, set_error (ctx, Syntax_Error,
"option argument expected"));
}
if (*value)
{
@ -96,12 +102,13 @@ std_handler_option (assuan_context_t ctx, char *line)
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");
return PROCESS_DONE (ctx,
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;
return PROCESS_DONE (ctx, ctx->option_handler_fnc (ctx, key, value));
return PROCESS_DONE (ctx, 0);
}
static int
@ -111,13 +118,13 @@ std_handler_bye (assuan_context_t ctx, char *line)
ctx->bye_notify_fnc (ctx);
assuan_close_input_fd (ctx);
assuan_close_output_fd (ctx);
return -1; /* pretty simple :-) */
return PROCESS_DONE (ctx, _assuan_error (-1)); /* pretty simple :-) */
}
static int
std_handler_auth (assuan_context_t ctx, char *line)
{
return set_error (ctx, Not_Implemented, NULL);
return PROCESS_DONE (ctx, set_error (ctx, Not_Implemented, NULL));
}
static int
@ -128,17 +135,35 @@ std_handler_reset (assuan_context_t ctx, char *line)
assuan_close_input_fd (ctx);
assuan_close_output_fd (ctx);
_assuan_uds_close_fds (ctx);
return 0;
return PROCESS_DONE (ctx, 0);
}
static int
std_handler_help (assuan_context_t ctx, char *line)
{
unsigned int i;
char buf[ASSUAN_LINELENGTH];
for (i = 0; i < ctx->cmdtbl_used; i++)
{
snprintf (buf, sizeof (buf), "# %s", ctx->cmdtbl[i].name);
buf[ASSUAN_LINELENGTH - 1] = '\0';
assuan_write_line (ctx, buf);
}
return PROCESS_DONE (ctx, 0);
}
static int
std_handler_end (assuan_context_t ctx, char *line)
{
return set_error (ctx, Not_Implemented, NULL);
return PROCESS_DONE (ctx, set_error (ctx, Not_Implemented, NULL));
}
assuan_error_t
assuan_command_parse_fd (assuan_context_t ctx, char *line, int *rfd)
assuan_command_parse_fd (assuan_context_t ctx, char *line, assuan_fd_t *rfd)
{
char *endp;
@ -151,7 +176,13 @@ assuan_command_parse_fd (assuan_context_t ctx, char *line, int *rfd)
line ++;
if (!digitp (*line))
return set_error (ctx, Syntax_Error, "number required");
#ifdef HAVE_W32_SYSTEM
/* Fixme: For a W32/64bit system we will need to change the cast
and the conversion fucntion. */
*rfd = (void*)strtoul (line, &endp, 10);
#else
*rfd = strtoul (line, &endp, 10);
#endif
/* Remove that argument so that a notify handler won't see it. */
memset (line, ' ', endp? (endp-line):strlen(line));
@ -166,34 +197,37 @@ assuan_command_parse_fd (assuan_context_t ctx, char *line, int *rfd)
return assuan_receivefd (ctx, rfd);
}
/* Format is INPUT FD=<n> */
static int
std_handler_input (assuan_context_t ctx, char *line)
{
int rc, fd;
int rc;
assuan_fd_t fd;
rc = assuan_command_parse_fd (ctx, line, &fd);
if (rc)
return rc;
return PROCESS_DONE (ctx, rc);
ctx->input_fd = fd;
if (ctx->input_notify_fnc)
ctx->input_notify_fnc (ctx, line);
return 0;
return PROCESS_DONE (ctx, 0);
}
/* Format is OUTPUT FD=<n> */
static int
std_handler_output (assuan_context_t ctx, char *line)
{
int rc, fd;
int rc;
assuan_fd_t fd;
rc = assuan_command_parse_fd (ctx, line, &fd);
if (rc)
return rc;
return PROCESS_DONE (ctx, rc);
ctx->output_fd = fd;
if (ctx->output_notify_fnc)
ctx->output_notify_fnc (ctx, line);
return 0;
return PROCESS_DONE (ctx, 0);
}
@ -215,11 +249,12 @@ static struct {
{ "AUTH", std_handler_auth, 1 },
{ "RESET", std_handler_reset, 1 },
{ "END", std_handler_end, 1 },
{ "HELP", std_handler_help, 1 },
{ "INPUT", std_handler_input },
{ "OUTPUT", std_handler_output },
{ "INPUT", std_handler_input, 0 },
{ "OUTPUT", std_handler_output, 0 },
{ "OPTION", std_handler_option, 1 },
{ NULL }
{ NULL, NULL, 0 }
};
@ -406,9 +441,10 @@ my_strcasecmp (const char *a, const char *b)
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, call the
handler with the argument line and return the error */
handler with the argument line and return the error. */
static int
dispatch_command (assuan_context_t ctx, char *line, int linelen)
{
@ -416,13 +452,21 @@ dispatch_command (assuan_context_t ctx, char *line, int linelen)
const char *s;
int shift, i;
/* Note that as this function is invoked by assuan_process_next as
well, we need to hide non-critical errors with PROCESS_DONE. */
if (*line == 'D' && line[1] == ' ') /* divert to special handler */
return handle_data_line (ctx, line+2, linelen-2);
/* FIXME: Depending on the final implementation of
handle_data_line, this may be wrong here. For example, if a
user callback is invoked, and that callback is responsible for
calling assuan_process_done, then this is wrong. */
return PROCESS_DONE (ctx, handle_data_line (ctx, line+2, linelen-2));
for (p=line; *p && *p != ' ' && *p != '\t'; p++)
;
if (p==line)
return set_error (ctx, Syntax_Error, "leading white-space");
return PROCESS_DONE
(ctx, set_error (ctx, Syntax_Error, "leading white-space"));
if (*p)
{ /* Skip over leading WS after the keyword */
*p++ = 0;
@ -445,7 +489,7 @@ dispatch_command (assuan_context_t ctx, char *line, int linelen)
}
}
if (!s)
return set_error (ctx, Unknown_Command, NULL);
return PROCESS_DONE (ctx, set_error (ctx, Unknown_Command, NULL));
line += shift;
linelen -= shift;
@ -453,42 +497,34 @@ dispatch_command (assuan_context_t ctx, char *line, int linelen)
return ctx->cmdtbl[i].handler (ctx, line);
}
static int
process_request (assuan_context_t ctx)
/* Call this to acknowledge the current command. */
int
assuan_process_done (assuan_context_t ctx, int rc)
{
int rc;
if (!ctx->in_command)
return _assuan_error (ASSUAN_General_Error);
if (ctx->in_inquire)
return _assuan_error (ASSUAN_Nested_Commands);
ctx->in_command = 0;
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 */
/* Check for data write errors. */
if (ctx->outbound.data.fp)
{ /* Flush the data lines */
{
/* 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 */
else
{
/* Flush any data send without using the data FP. */
assuan_send_data (ctx, NULL, 0);
if (!rc && ctx->outbound.data.error)
rc = ctx->outbound.data.error;
}
/* Error handling */
/* Error handling. */
if (!rc)
{
rc = assuan_write_line (ctx, ctx->okay_line? ctx->okay_line : "OK");
@ -579,9 +615,113 @@ process_request (assuan_context_t ctx)
xfree (ctx->okay_line);
ctx->okay_line = NULL;
}
return rc;
}
static int
process_next (assuan_context_t ctx)
{
int rc;
/* What the next thing to do is depends on the current state.
However, we will always first read the next line. The client is
required to write full lines without blocking long after starting
a partial line. */
rc = _assuan_read_line (ctx);
if (_assuan_error_is_eagain (rc))
return 0;
if (rc)
return rc;
if (*ctx->inbound.line == '#' || !ctx->inbound.linelen)
/* Comment lines are ignored. */
return 0;
/* Now we have a line that really means something. It could be one
of the following things: First, if we are not in a command
already, it is the next command to dispatch. Second, if we are
in a command, it can only be the response to an INQUIRE
reply. */
if (!ctx->in_command)
{
ctx->in_command = 1;
ctx->outbound.data.error = 0;
ctx->outbound.data.linelen = 0;
/* Dispatch command and return reply. */
ctx->in_process_next = 1;
rc = dispatch_command (ctx, ctx->inbound.line, ctx->inbound.linelen);
ctx->in_process_next = 0;
}
else if (ctx->in_inquire)
{
/* FIXME: Pick up the continuation. */
rc = _assuan_inquire_ext_cb (ctx);
}
else
{
/* Should not happen. The client is sending data while we are
in a command and not waiting for an inquire. We log an error
and discard it. */
_assuan_log_printf ("unexpected client data\n");
rc = 0;
}
return rc;
}
/* This function should be invoked when the assuan connected FD is
ready for reading. If the equivalent to EWOULDBLOCK is returned
(this should be done by the command handler), assuan_process_next
should be invoked the next time the connected FD is readable.
Eventually, the caller will finish by invoking
assuan_process_done. */
int
assuan_process_next (assuan_context_t ctx)
{
int rc;
do
{
rc = process_next (ctx);
}
while (!rc && assuan_pending_line (ctx));
return rc;
}
static int
process_request (assuan_context_t ctx)
{
int rc;
if (ctx->in_inquire)
return _assuan_error (ASSUAN_Nested_Commands);
do
{
rc = _assuan_read_line (ctx);
}
while (_assuan_error_is_eagain (rc));
if (rc)
return rc;
if (*ctx->inbound.line == '#' || !ctx->inbound.linelen)
return 0; /* comment line - ignore */
ctx->in_command = 1;
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);
return assuan_process_done (ctx, rc);
}
/**
* assuan_process:
* @ctx: assuan context
@ -609,24 +749,6 @@ assuan_process (assuan_context_t ctx)
}
/**
* 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_t ctx)
{
return process_request (ctx);
}
/**
* assuan_get_active_fds:
* @ctx: Assuan context
@ -646,7 +768,7 @@ assuan_process_next (assuan_context_t ctx)
**/
int
assuan_get_active_fds (assuan_context_t ctx, int what,
int *fdarray, int fdarraysize)
assuan_fd_t *fdarray, int fdarraysize)
{
int n = 0;
@ -655,16 +777,16 @@ assuan_get_active_fds (assuan_context_t ctx, int what,
if (!what)
{
if (ctx->inbound.fd != -1)
if (ctx->inbound.fd != ASSUAN_INVALID_FD)
fdarray[n++] = ctx->inbound.fd;
}
else
{
if (ctx->outbound.fd != -1)
if (ctx->outbound.fd != ASSUAN_INVALID_FD)
fdarray[n++] = ctx->outbound.fd;
if (ctx->outbound.data.fp)
#ifdef HAVE_W32_SYSTEM
fdarray[n++] = _get_osfhandle (fileno (ctx->outbound.data.fp));
fdarray[n++] = (void*)_get_osfhandle (fileno (ctx->outbound.data.fp));
#else
fdarray[n++] = fileno (ctx->outbound.data.fp);
#endif

View File

@ -1,5 +1,5 @@
/* assuan-inquire.c - handle inquire stuff
* Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
* Copyright (C) 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -14,9 +14,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
@ -44,7 +42,7 @@ struct membuf
/* A simple implemnation of a dynamic buffer. Use init_membuf() to
/* A simple implementation 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
@ -171,7 +169,9 @@ assuan_inquire (assuan_context_t ctx, const char *keyword,
{
do
{
do
rc = _assuan_read_line (ctx);
while (_assuan_error_is_eagain (rc));
if (rc)
goto leave;
line = (unsigned char *) ctx->inbound.line;
@ -234,8 +234,154 @@ assuan_inquire (assuan_context_t ctx, const char *keyword,
return rc;
}
void
_assuan_inquire_release (assuan_context_t ctx)
{
if (ctx->in_inquire)
{
if (ctx->inquire_membuf)
{
free_membuf (ctx->inquire_membuf);
free (ctx->inquire_membuf);
}
ctx->in_inquire = 0;
}
}
int
_assuan_inquire_ext_cb (assuan_context_t ctx)
{
int rc;
unsigned char *line;
int linelen;
struct membuf *mb;
unsigned char *p;
line = (unsigned char *) ctx->inbound.line;
linelen = ctx->inbound.linelen;
mb = ctx->inquire_membuf;
if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N')
{
rc = _assuan_error (ASSUAN_Canceled);
goto leave;
}
if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
&& (!line[3] || line[3] == ' '))
{
rc = 0;
goto leave;
}
if (line[0] != 'D' || line[1] != ' ' || mb == NULL)
{
rc = _assuan_error (ASSUAN_Unexpected_Command);
goto leave;
}
if (linelen < 3)
return 0;
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_error (ASSUAN_Too_Much_Data);
goto leave;
}
return 0;
leave:
{
size_t buf_len = 0;
unsigned char *buf = NULL;
if (mb)
{
buf = get_membuf (mb, &buf_len);
if (!buf)
rc = _assuan_error (ASSUAN_Out_Of_Core);
free_membuf (mb);
free (mb);
ctx->inquire_membuf = NULL;
}
ctx->in_inquire = 0;
rc = (ctx->inquire_cb) (ctx->inquire_cb_data, rc, buf, buf_len);
}
return rc;
}
/**
* assuan_inquire_ext:
* @ctx: An assuan context
* @keyword: The keyword used for the inquire
* @maxlen: If not 0, the size limit of the inquired data.
* @cb: A callback handler which is invoked after the operation completed.
* @cb_data: A user-provided value passed to the callback handler.
*
* 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.
* When this function returns,
*
* Return value: 0 on success or an ASSUAN error code
**/
assuan_error_t
assuan_inquire_ext (assuan_context_t ctx, const char *keyword, size_t maxlen,
int (*cb) (void *cb_data, int rc, unsigned char *buf,
size_t len),
void *cb_data)
{
assuan_error_t rc;
struct membuf *mb = NULL;
char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */
if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf)))
return _assuan_error (ASSUAN_Invalid_Value);
if (!ctx->is_server)
return _assuan_error (ASSUAN_Not_A_Server);
if (ctx->in_inquire)
return _assuan_error (ASSUAN_Nested_Commands);
mb = malloc (sizeof (struct membuf));
if (!mb)
return _assuan_error (ASSUAN_Out_Of_Core);
init_membuf (mb, maxlen ? maxlen : 1024, maxlen);
strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword);
rc = assuan_write_line (ctx, cmdbuf);
if (rc)
{
free_membuf (mb);
free (mb);
return rc;
}
ctx->in_inquire = 1;
/* Set up the continuation. */
ctx->inquire_cb = cb;
ctx->inquire_cb_data = cb_data;
ctx->inquire_membuf = mb;
return 0;
}

View File

@ -1,5 +1,5 @@
/* assuan-io.c - Wraps the read and write functions.
* Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
* Copyright (C) 2002, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -14,15 +14,14 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
@ -48,8 +47,8 @@ _assuan_waitpid (pid_t pid, int *status, int options)
#endif
ssize_t
_assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size)
static ssize_t
do_io_read (assuan_fd_t fd, void *buffer, size_t size)
{
#if defined(HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN)
/* Due to the peculiarities of the W32 API we can't use read for a
@ -57,12 +56,16 @@ _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size)
read if recv detects that it is not a network socket. */
int n;
n = recv (ctx->inbound.fd, buffer, size, 0);
if (n == -1 && WSAGetLastError () == WSAENOTSOCK)
n = recv (HANDLE2SOCKET(fd), buffer, size, 0);
if (n == -1)
{
switch (WSAGetLastError ())
{
case WSAENOTSOCK:
{
DWORD nread = 0;
n = ReadFile ((HANDLE)ctx->inbound.fd, buffer, size, &nread, NULL);
n = ReadFile (fd, buffer, size, &nread, NULL);
if (!n)
{
switch (GetLastError())
@ -75,14 +78,49 @@ _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size)
else
n = (int)nread;
}
break;
case WSAEWOULDBLOCK: errno = EAGAIN; break;
case ERROR_BROKEN_PIPE: errno = EPIPE; break;
default: errno = EIO; break;
}
}
return n;
#else /*!HAVE_W32_SYSTEM*/
return read (ctx->inbound.fd, buffer, size);
return read (fd, buffer, size);
#endif /*!HAVE_W32_SYSTEM*/
}
ssize_t
_assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size)
_assuan_io_read (assuan_fd_t fd, void *buffer, size_t size)
{
ssize_t retval;
if (_assuan_io_hooks.read_hook
&& _assuan_io_hooks.read_hook (NULL, fd, buffer, size, &retval) == 1)
return retval;
return do_io_read (fd, buffer, size);
}
ssize_t
_assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size)
{
ssize_t retval;
if (_assuan_io_hooks.read_hook
&& _assuan_io_hooks.read_hook (ctx, ctx->inbound.fd,
buffer, size, &retval) == 1)
return retval;
return do_io_read (ctx->inbound.fd, buffer, size);
}
static ssize_t
do_io_write (assuan_fd_t fd, const void *buffer, size_t size)
{
#if defined(HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN)
/* Due to the peculiarities of the W32 API we can't use write for a
@ -90,12 +128,12 @@ _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size)
write if send detects that it is not a network socket. */
int n;
n = send (ctx->outbound.fd, buffer, size, 0);
n = send (HANDLE2SOCKET(fd), buffer, size, 0);
if (n == -1 && WSAGetLastError () == WSAENOTSOCK)
{
DWORD nwrite;
n = WriteFile ((HANDLE)ctx->outbound.fd, buffer, size, &nwrite, NULL);
n = WriteFile (fd, buffer, size, &nwrite, NULL);
if (!n)
{
switch (GetLastError ())
@ -111,10 +149,34 @@ _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size)
}
return n;
#else /*!HAVE_W32_SYSTEM*/
return write (ctx->outbound.fd, buffer, size);
return write (fd, buffer, size);
#endif /*!HAVE_W32_SYSTEM*/
}
ssize_t
_assuan_io_write (assuan_fd_t fd, const void *buffer, size_t size)
{
ssize_t retval;
if (_assuan_io_hooks.write_hook
&& _assuan_io_hooks.write_hook (NULL, fd, buffer, size, &retval) == 1)
return retval;
return do_io_write (fd, buffer, size);
}
ssize_t
_assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size)
{
ssize_t retval;
if (_assuan_io_hooks.write_hook
&& _assuan_io_hooks.write_hook (ctx, ctx->outbound.fd,
buffer, size, &retval) == 1)
return retval;
return do_io_write (ctx->outbound.fd, buffer, size);
}
#ifdef HAVE_W32_SYSTEM
int
@ -152,3 +214,32 @@ _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg)
return ret;
#endif
}
void
_assuan_usleep (unsigned int usec)
{
if (usec)
{
#ifdef HAVE_NANOSLEEP
struct timespec req;
struct timespec rem;
req.tv_sec = 0;
req.tv_nsec = usec * 1000;
while (nanosleep (&req, &rem) < 0 && errno == EINTR)
req = rem;
#elif defined(HAVE_W32_SYSTEM)
Sleep (usec / 1000);
#else
struct timeval tv;
tv.tv_sec = usec / 1000000;
tv.tv_usec = usec % 1000000;
select (0, NULL, NULL, NULL, &tv);
#endif
}
}

View File

@ -14,9 +14,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
@ -116,17 +114,17 @@ assuan_accept (assuan_context_t ctx)
int
assuan_fd_t
assuan_get_input_fd (assuan_context_t ctx)
{
return ctx? ctx->input_fd : -1;
return ctx? ctx->input_fd : ASSUAN_INVALID_FD;
}
int
assuan_fd_t
assuan_get_output_fd (assuan_context_t ctx)
{
return ctx? ctx->output_fd : -1;
return ctx? ctx->output_fd : ASSUAN_INVALID_FD;
}
@ -135,10 +133,10 @@ assuan_get_output_fd (assuan_context_t ctx)
assuan_error_t
assuan_close_input_fd (assuan_context_t ctx)
{
if (!ctx || ctx->input_fd == -1)
if (!ctx || ctx->input_fd == ASSUAN_INVALID_FD)
return _assuan_error (ASSUAN_Invalid_Value);
_assuan_close (ctx->input_fd);
ctx->input_fd = -1;
ctx->input_fd = ASSUAN_INVALID_FD;
return 0;
}
@ -147,11 +145,11 @@ assuan_close_input_fd (assuan_context_t ctx)
assuan_error_t
assuan_close_output_fd (assuan_context_t ctx)
{
if (!ctx || ctx->output_fd == -1)
if (!ctx || ctx->output_fd == ASSUAN_INVALID_FD)
return _assuan_error (ASSUAN_Invalid_Value);
_assuan_close (ctx->output_fd);
ctx->output_fd = -1;
ctx->output_fd = ASSUAN_INVALID_FD;
return 0;
}

View File

@ -14,9 +14,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
@ -37,23 +35,6 @@
static char prefix_buffer[80];
static FILE *_assuan_log;
static int full_logging;
static int log_level = 1; /* Defaults to logging enabled. */
/* Set the log level for general assuan commands. 0 is no logging at
all, 1 is the standard logging and the default. Higher leveles may
be defined in the future. Passing a level of -1 will not change
the current log level. Returns previosu log level. */
int
assuan_set_assuan_log_level (int level)
{
int old = log_level;
if (level != -1)
log_level = level;
return old;
}
void
_assuan_set_default_log_stream (FILE *fp)
@ -123,9 +104,6 @@ _assuan_log_printf (const char *format, ...)
const char *prf;
int save_errno = errno;
if (!log_level)
return;
fp = assuan_get_assuan_log_stream ();
prf = assuan_get_assuan_log_prefix ();
if (*prf)
@ -134,29 +112,31 @@ _assuan_log_printf (const char *format, ...)
va_start (arg_ptr, format);
vfprintf (fp, format, arg_ptr );
va_end (arg_ptr);
/* If the log stream is a file, the output would be buffered. This
is bad for debugging, thus we flush the stream if FORMAT ends
with a LF. */
if (format && *format && format[strlen(format)-1] == '\n')
fflush (fp);
errno = save_errno;
}
/* Dump a possibly binary string (used for debugging). Distinguish
ascii text from binary and print it accordingly. This function
takes FILE pointer arg becuase logging may be enabled on a per
takes FILE pointer arg because logging may be enabled on a per
context basis. */
void
_assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
{
const unsigned char *s;
int n;
unsigned int n;
if (!log_level)
return;
for (n=length,s=buffer; n; n--, s++)
if ((!isascii (*s) || iscntrl (*s) || !isprint (*s)) && !(*s >= 0x80))
for (n = length, s = buffer; n; n--, s++)
if ((! isascii (*s) || iscntrl (*s) || ! isprint (*s)) && !(*s >= 0x80))
break;
s = buffer;
if (!n && *s != '[')
if (! n && *s != '[')
fwrite (buffer, length, 1, fp);
else
{
@ -164,15 +144,15 @@ _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
flockfile (fp);
#endif
putc_unlocked ('[', fp);
if ( length > 16 && !full_logging)
if (length > 16 && ! full_logging)
{
for (n=0; n < 12; n++, s++)
for (n = 0; n < 12; n++, s++)
fprintf (fp, " %02x", *s);
fprintf (fp, " ...(%d bytes skipped)", (int)length - 12);
fprintf (fp, " ...(%d bytes skipped)", (int) length - 12);
}
else
{
for (n=0; n < length; n++, s++)
for (n = 0; n < length; n++, s++)
fprintf (fp, " %02x", *s);
}
putc_unlocked (' ', fp);
@ -189,16 +169,11 @@ void
_assuan_log_sanitized_string (const char *string)
{
const unsigned char *s = (const unsigned char *) string;
FILE *fp;
FILE *fp = assuan_get_assuan_log_stream ();
if (!log_level)
if (! *s)
return;
if (!*s)
return;
fp = assuan_get_assuan_log_stream ();
#ifdef HAVE_FLOCKFILE
flockfile (fp);
#endif

View File

@ -1,5 +1,6 @@
/* assuan-pipe-connect.c - Establish a pipe connection (client)
* Copyright (C) 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
* Copyright (C) 2001, 2002, 2003, 2005, 2006,
* 2007 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -14,9 +15,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
@ -75,17 +74,6 @@ int _gpgme_io_spawn (const char *path, char *const argv[],
#define MAX_OPEN_FDS 20
#endif
#ifdef HAVE_W32_SYSTEM
/* We assume that a HANDLE can be represented by an int which should
be true for all i386 systems (HANDLE is defined as void *) and
these are the only systems for which Windows is available. Further
we assume that -1 denotes an invalid handle. */
#define fd_to_handle(a) ((HANDLE)(a))
#define handle_to_fd(a) ((int)(a))
#define pid_to_handle(a) ((HANDLE)(a))
#define handle_to_pid(a) ((int)(a))
#endif /*HAVE_W32_SYSTEM*/
/* This should be called to make sure that SIGPIPE gets ignored. */
static void
@ -139,31 +127,35 @@ writen (int fd, const char *buffer, size_t length)
static int
do_finish (assuan_context_t ctx)
{
if (ctx->inbound.fd != -1)
if (ctx->inbound.fd != ASSUAN_INVALID_FD)
{
_assuan_close (ctx->inbound.fd);
if (ctx->inbound.fd == ctx->outbound.fd)
ctx->outbound.fd = -1;
ctx->inbound.fd = -1;
ctx->outbound.fd = ASSUAN_INVALID_FD;
ctx->inbound.fd = ASSUAN_INVALID_FD;
}
if (ctx->outbound.fd != -1)
if (ctx->outbound.fd != ASSUAN_INVALID_FD)
{
_assuan_close (ctx->outbound.fd);
ctx->outbound.fd = -1;
ctx->outbound.fd = ASSUAN_INVALID_FD;
}
if (ctx->pid != -1 && ctx->pid)
if (ctx->pid != (pid_t)(-1) && ctx->pid)
{
#ifndef HAVE_W32_SYSTEM
#ifndef _ASSUAN_USE_DOUBLE_FORK
if (!ctx->flags.no_waitpid)
_assuan_waitpid (ctx->pid, NULL, 0);
ctx->pid = -1;
ctx->pid =(pid_t)(-1);
#endif
#endif /*!HAVE_W32_SYSTEM*/
#else /*!HAVE_W32_SYSTEM*/
CloseHandle ((HANDLE) ctx->pid);
ctx->pid = (pid_t) INVALID_HANDLE_VALUE;
#endif /*HAVE_W32_SYSTEM*/
}
return 0;
}
static void
do_deinit (assuan_context_t ctx)
{
@ -209,13 +201,15 @@ pipe_connect_unix (assuan_context_t *ctx,
const char *name, const char *const argv[],
int *fd_child_list,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue)
void *atforkvalue, unsigned int flags)
{
assuan_error_t err;
int rp[2];
int wp[2];
char mypidstr[50];
(void)flags;
if (!ctx || !name || !argv || !argv[0])
return _assuan_error (ASSUAN_Invalid_Value);
@ -581,7 +575,7 @@ pipe_connect_gpgme (assuan_context_t *ctx,
const char *name, const char *const argv[],
int *fd_child_list,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue)
void *atforkvalue, unsigned int flags)
{
assuan_error_t err;
int res;
@ -744,9 +738,9 @@ build_w32_commandline (const char * const *argv, char **cmdline)
#ifdef HAVE_W32_SYSTEM
/* Create pipe where one end is inheritable. */
/* Create pipe where one end end is inheritable. */
static int
create_inheritable_pipe (int filedes[2], int for_write)
create_inheritable_pipe (assuan_fd_t filedes[2], int for_write)
{
HANDLE r, w, h;
SECURITY_ATTRIBUTES sec_attr;
@ -781,14 +775,12 @@ create_inheritable_pipe (int filedes[2], int for_write)
w = h;
}
_assuan_log_printf ("created pipe: read=%p%s, write=%p%s\n",
r, for_write? " (inherit)":"",
w, for_write? "":" (inherit)");
filedes[0] = handle_to_fd (r);
filedes[1] = handle_to_fd (w);
filedes[0] = r;
filedes[1] = w;
return 0;
}
#endif /* HAVE_W32_SYSTEM */
#endif /*HAVE_W32_SYSTEM*/
#ifdef HAVE_W32_SYSTEM
#define pipe_connect pipe_connect_w32
@ -798,11 +790,11 @@ pipe_connect_w32 (assuan_context_t *ctx,
const char *name, const char *const argv[],
int *fd_child_list,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue)
void *atforkvalue, unsigned int flags)
{
assuan_error_t err;
int rp[2];
int wp[2];
assuan_fd_t rp[2];
assuan_fd_t wp[2];
char mypidstr[50];
char *cmdline;
SECURITY_ATTRIBUTES sec_attr;
@ -837,8 +829,8 @@ pipe_connect_w32 (assuan_context_t *ctx,
if (create_inheritable_pipe (wp, 1))
{
CloseHandle (fd_to_handle (rp[0]));
CloseHandle (fd_to_handle (rp[1]));
CloseHandle (rp[0]);
CloseHandle (rp[1]);
xfree (cmdline);
return _assuan_error (ASSUAN_General_Error);
}
@ -847,10 +839,10 @@ pipe_connect_w32 (assuan_context_t *ctx,
err = _assuan_new_context (ctx);
if (err)
{
CloseHandle (fd_to_handle (rp[0]));
CloseHandle (fd_to_handle (rp[1]));
CloseHandle (fd_to_handle (wp[0]));
CloseHandle (fd_to_handle (wp[1]));
CloseHandle (rp[0]);
CloseHandle (rp[1]);
CloseHandle (wp[0]);
CloseHandle (wp[1]);
xfree (cmdline);
return _assuan_error (ASSUAN_General_Error);
}
@ -877,8 +869,8 @@ pipe_connect_w32 (assuan_context_t *ctx,
memset (&si, 0, sizeof si);
si.cb = sizeof (si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = fd_to_handle (wp[0]);
si.hStdOutput = fd_to_handle (rp[1]);
si.hStdInput = wp[0];
si.hStdOutput = rp[1];
/* Dup stderr to /dev/null unless it is in the list of FDs to be
passed to the child. */
@ -894,14 +886,13 @@ pipe_connect_w32 (assuan_context_t *ctx,
nullfd = CreateFile ("nul", GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
_assuan_log_printf ("created nul device, hd=%p\n", nullfd);
if (nullfd == INVALID_HANDLE_VALUE)
{
_assuan_log_printf ("can't open `nul': %s\n", w32_strerror (-1));
CloseHandle (fd_to_handle (rp[0]));
CloseHandle (fd_to_handle (rp[1]));
CloseHandle (fd_to_handle (wp[0]));
CloseHandle (fd_to_handle (wp[1]));
CloseHandle (rp[0]);
CloseHandle (rp[1]);
CloseHandle (wp[0]);
CloseHandle (wp[1]);
xfree (cmdline);
_assuan_release_context (*ctx);
return -1;
@ -909,23 +900,21 @@ pipe_connect_w32 (assuan_context_t *ctx,
si.hStdError = nullfd;
}
else
si.hStdError = fd_to_handle (_get_osfhandle (fd));
si.hStdError = (void*)_get_osfhandle (fd);
/* Note: We inherit all handles flagged as inheritable. This seems
to be a security flaw but there seems to be no way of selecting
handles to inherit. */
_assuan_log_printf ("CreateProcess, path=`%s' cmdline=`%s'\n",
name, cmdline);
_assuan_log_printf (" stdin=%p stdout=%p stderr=%p\n",
si.hStdInput, si.hStdOutput, si.hStdError);
/* _assuan_log_printf ("CreateProcess, path=`%s' cmdline=`%s'\n", */
/* name, cmdline); */
if (!CreateProcess (name, /* Program to start. */
cmdline, /* Command line arguments. */
&sec_attr, /* Process security attributes. */
&sec_attr, /* Thread security attributes. */
TRUE, /* Inherit handles. */
(CREATE_DEFAULT_ERROR_MODE
| DETACHED_PROCESS
| ((flags & 128)? DETACHED_PROCESS : 0)
| GetPriorityClass (GetCurrentProcess ())
| CREATE_SUSPENDED), /* Creation flags. */
NULL, /* Environment. */
@ -935,10 +924,10 @@ pipe_connect_w32 (assuan_context_t *ctx,
))
{
_assuan_log_printf ("CreateProcess failed: %s\n", w32_strerror (-1));
CloseHandle (fd_to_handle (rp[0]));
CloseHandle (fd_to_handle (rp[1]));
CloseHandle (fd_to_handle (wp[0]));
CloseHandle (fd_to_handle (wp[1]));
CloseHandle (rp[0]);
CloseHandle (rp[1]);
CloseHandle (wp[0]);
CloseHandle (wp[1]);
if (nullfd != INVALID_HANDLE_VALUE)
CloseHandle (nullfd);
xfree (cmdline);
@ -953,20 +942,17 @@ pipe_connect_w32 (assuan_context_t *ctx,
nullfd = INVALID_HANDLE_VALUE;
}
_assuan_log_printf ("closing handles %p and %p\n",
fd_to_handle (rp[1]), fd_to_handle (wp[0]) );
CloseHandle (fd_to_handle (rp[1]));
CloseHandle (fd_to_handle (wp[0]));
CloseHandle (rp[1]);
CloseHandle (wp[0]);
_assuan_log_printf ("CreateProcess ready: hProcess=%p hThread=%p"
" dwProcessID=%d dwThreadId=%d\n",
pi.hProcess, pi.hThread,
(int) pi.dwProcessId, (int) pi.dwThreadId);
/* _assuan_log_printf ("CreateProcess ready: hProcess=%p hThread=%p" */
/* " dwProcessID=%d dwThreadId=%d\n", */
/* pi.hProcess, pi.hThread, */
/* (int) pi.dwProcessId, (int) pi.dwThreadId); */
ResumeThread (pi.hThread);
CloseHandle (pi.hThread);
(*ctx)->pid = 0; /* We don't use the PID. */
CloseHandle (pi.hProcess); /* We don't need to wait for the process. */
(*ctx)->pid = (pid_t) pi.hProcess;
return initial_handshake (ctx);
}
@ -982,7 +968,7 @@ assuan_error_t
assuan_pipe_connect (assuan_context_t *ctx, const char *name,
const char *const argv[], int *fd_child_list)
{
return pipe_connect (ctx, name, argv, fd_child_list, NULL, NULL);
return pipe_connect (ctx, name, argv, fd_child_list, NULL, NULL, 0);
}
@ -994,7 +980,7 @@ assuan_pipe_connect2 (assuan_context_t *ctx,
void (*atfork) (void *opaque, int reserved),
void *atforkvalue)
{
return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue);
return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue, 0);
}
@ -1007,9 +993,19 @@ assuan_pipe_connect2 (assuan_context_t *ctx,
as the second argument. The ATFORK function should only act if the
second value is 0.
For now FLAGS may either take the value 0 to behave like
assuan_pipe_connect2 or 1 to enable the described full-duplex
socket behaviour.
FLAGS is a bit vector and controls how the function acts:
Bit 0: If cleared a simple pipe based server is expected and the
function behaves similar to `assuan_pipe_connect'.
If set a server based on full-duplex pipes is expected. Such
pipes are usually created using the `socketpair' function.
It also enables features only available with such servers.
Bit 7: If set and there is a need to start ther server it will be
started as a background process. This flag is useful under
W32 systems, so that no new console is created and pops up a
console window when starting the server
If NAME as well as ARGV are NULL, no exec is done but the same
process is continued. However all file descriptors are closed and
@ -1033,6 +1029,7 @@ assuan_pipe_connect_ext (assuan_context_t *ctx,
#endif
}
else
return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue);
return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue,
flags);
}

View File

@ -14,9 +14,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
@ -69,14 +67,14 @@ _assuan_new_context (assuan_context_t *r_ctx)
ctx = xtrycalloc (1, sizeof *ctx);
if (!ctx)
return _assuan_error (ASSUAN_Out_Of_Core);
ctx->input_fd = -1;
ctx->output_fd = -1;
ctx->input_fd = ASSUAN_INVALID_FD;
ctx->output_fd = ASSUAN_INVALID_FD;
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
ctx->inbound.fd = ASSUAN_INVALID_FD;
ctx->outbound.fd = ASSUAN_INVALID_FD;
ctx->io = &io;
ctx->listen_fd = -1;
ctx->listen_fd = ASSUAN_INVALID_FD;
/* Use the pipe server handler as a default. */
ctx->deinit_handler = deinit_pipe_server;
ctx->accept_handler = accept_connection;
@ -121,11 +119,11 @@ assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2])
#ifdef HAVE_W32_SYSTEM
/* MS Windows has so many different types of handle that one
needs to tranlsate them at many place forth and back. Also
make sure that the fiel descriptos are in binary mode. */
make sure that the file descriptors are in binary mode. */
setmode (filedes[0], O_BINARY);
setmode (filedes[1], O_BINARY);
ctx->inbound.fd = _get_osfhandle (filedes[0]);
ctx->outbound.fd = _get_osfhandle (filedes[1]);
ctx->inbound.fd = (void*)_get_osfhandle (filedes[0]);
ctx->outbound.fd = (void*)_get_osfhandle (filedes[1]);
#else
s = getenv ("_assuan_connection_fd");
if (s && *s && is_valid_socket (s) )
@ -137,7 +135,8 @@ assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2])
_assuan_init_uds_io (ctx);
ctx->deinit_handler = _assuan_uds_deinit;
}
else if (filedes && filedes[0] != -1 && filedes[1] != -1 )
else if (filedes && filedes[0] != ASSUAN_INVALID_FD
&& filedes[1] != ASSUAN_INVALID_FD )
{
/* Standard pipe server. */
ctx->inbound.fd = filedes[0];
@ -168,6 +167,7 @@ _assuan_release_context (assuan_context_t ctx)
{
if (ctx)
{
_assuan_inquire_release (ctx);
xfree (ctx->hello_line);
xfree (ctx->okay_line);
xfree (ctx->cmdtbl);

View File

@ -14,9 +14,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
@ -57,12 +55,12 @@
static int
do_finish (assuan_context_t ctx)
{
if (ctx->inbound.fd != -1)
if (ctx->inbound.fd != ASSUAN_INVALID_FD)
{
_assuan_close (ctx->inbound.fd);
}
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
ctx->inbound.fd = ASSUAN_INVALID_FD;
ctx->outbound.fd = ASSUAN_INVALID_FD;
return 0;
}
@ -87,18 +85,17 @@ assuan_socket_connect (assuan_context_t *r_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. With flags set to 1 sendmsg and
recvmesg are used. */
recvmsg are used. */
assuan_error_t
assuan_socket_connect_ext (assuan_context_t *r_ctx,
const char *name, pid_t server_pid,
unsigned int flags)
{
static struct assuan_io io = { _assuan_simple_read,
_assuan_simple_write };
static struct assuan_io io = { _assuan_simple_read, _assuan_simple_write,
NULL, NULL };
assuan_error_t err;
assuan_context_t ctx;
int fd;
assuan_fd_t fd;
struct sockaddr_un srvr_addr;
size_t len;
const char *s;
@ -109,7 +106,7 @@ assuan_socket_connect_ext (assuan_context_t *r_ctx,
/* We require that the name starts with a slash, so that we
eventually can reuse this function for other socket types. To
make things easier we allow an optional dirver prefix. */
make things easier we allow an optional driver prefix. */
s = name;
if (*s && s[1] == ':')
s += 2;
@ -126,7 +123,7 @@ assuan_socket_connect_ext (assuan_context_t *r_ctx,
ctx->finish_handler = do_finish;
fd = _assuan_sock_new (PF_LOCAL, SOCK_STREAM, 0);
if (fd == -1)
if (fd == ASSUAN_INVALID_FD)
{
_assuan_log_printf ("can't create socket: %s\n", strerror (errno));
_assuan_release_context (ctx);
@ -139,8 +136,7 @@ assuan_socket_connect_ext (assuan_context_t *r_ctx,
srvr_addr.sun_path[sizeof (srvr_addr.sun_path) - 1] = 0;
len = SUN_LEN (&srvr_addr);
if (_assuan_sock_connect (fd, (struct sockaddr *) &srvr_addr, len) == -1)
if ( _assuan_sock_connect (fd, (struct sockaddr *) &srvr_addr, len) == -1 )
{
_assuan_log_printf ("can't connect to `%s': %s\n",
name, strerror (errno));

View File

@ -1,5 +1,5 @@
/* assuan-socket-server.c - Assuan socket based server
* Copyright (C) 2002 Free Software Foundation, Inc.
* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -14,9 +14,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
@ -40,14 +38,13 @@
#include "assuan-defs.h"
static struct assuan_io io = { _assuan_simple_read,
_assuan_simple_write };
static struct assuan_io io = { _assuan_simple_read, _assuan_simple_write,
NULL, NULL };
static int
accept_connection_bottom (assuan_context_t ctx)
{
int fd = ctx->connected_fd;
assuan_fd_t fd = ctx->connected_fd;
ctx->peercred.valid = 0;
#ifdef HAVE_SO_PEERCRED
@ -89,16 +86,23 @@ accept_connection_bottom (assuan_context_t ctx)
static int
accept_connection (assuan_context_t ctx)
{
int fd;
assuan_fd_t fd;
struct sockaddr_un clnt_addr;
socklen_t len = sizeof clnt_addr;
fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
if (fd == -1)
fd = SOCKET2HANDLE(accept (HANDLE2SOCKET(ctx->listen_fd),
(struct sockaddr*)&clnt_addr, &len ));
if (fd == ASSUAN_INVALID_FD)
{
ctx->os_errno = errno;
return _assuan_error (ASSUAN_Accept_Failed);
}
if (_assuan_sock_check_nonce (fd, &ctx->listen_nonce))
{
_assuan_close (fd);
ctx->os_errno = EACCES;
return _assuan_error (ASSUAN_Accept_Failed);
}
ctx->connected_fd = fd;
return accept_connection_bottom (ctx);
@ -107,12 +111,12 @@ accept_connection (assuan_context_t ctx)
static int
finish_connection (assuan_context_t ctx)
{
if (ctx->inbound.fd != -1)
if (ctx->inbound.fd != ASSUAN_INVALID_FD)
{
_assuan_close (ctx->inbound.fd);
}
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
ctx->inbound.fd = ASSUAN_INVALID_FD;
ctx->outbound.fd = ASSUAN_INVALID_FD;
return 0;
}
@ -126,15 +130,15 @@ deinit_socket_server (assuan_context_t ctx)
/* Initialize a server for the socket LISTEN_FD which has already be
put into listen mode */
int
assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd)
assuan_init_socket_server (assuan_context_t *r_ctx, assuan_fd_t listen_fd)
{
return assuan_init_socket_server_ext (r_ctx, listen_fd, 0);
}
/* Initialize a server using the already accepted socket FD. This
fucntion is deprecated. */
function is deprecated. */
int
assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd)
assuan_init_connected_socket_server (assuan_context_t *r_ctx, assuan_fd_t fd)
{
return assuan_init_socket_server_ext (r_ctx, fd, 2);
}
@ -145,7 +149,7 @@ assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd)
1 - FD has already been accepted.
*/
int
assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd,
assuan_init_socket_server_ext (assuan_context_t *r_ctx, assuan_fd_t fd,
unsigned int flags)
{
assuan_context_t ctx;
@ -158,21 +162,21 @@ assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd,
ctx->is_server = 1;
if ((flags & 2))
ctx->pipe_mode = 1; /* We want a second accept to indicate EOF. */
ctx->input_fd = -1;
ctx->output_fd = -1;
ctx->input_fd = ASSUAN_INVALID_FD;
ctx->output_fd = ASSUAN_INVALID_FD;
ctx->inbound.fd = -1;
ctx->outbound.fd = -1;
ctx->inbound.fd = ASSUAN_INVALID_FD;
ctx->outbound.fd = ASSUAN_INVALID_FD;
if ((flags & 2))
{
ctx->listen_fd = -1;
ctx->listen_fd = ASSUAN_INVALID_FD;
ctx->connected_fd = fd;
}
else
{
ctx->listen_fd = fd;
ctx->connected_fd = -1;
ctx->connected_fd = ASSUAN_INVALID_FD;
}
ctx->deinit_handler = (flags & 1)? _assuan_uds_deinit:deinit_socket_server;
ctx->accept_handler = ((flags & 2)
@ -191,3 +195,14 @@ assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd,
*r_ctx = ctx;
return rc;
}
/* Save a copy of NONCE in context CTX. This should be used to
register the server's nonce with an context established by
assuan_init_socket_server. */
void
assuan_set_sock_nonce (assuan_context_t ctx, assuan_sock_nonce_t *nonce)
{
if (ctx && nonce)
ctx->listen_nonce = *nonce;
}

View File

@ -14,20 +14,26 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_W32_SYSTEM
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <wincrypt.h>
#include <io.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#endif
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include "assuan-defs.h"
/* Hacks for Slowaris. */
@ -42,13 +48,114 @@
# define AF_LOCAL AF_UNIX
#endif
#ifdef HAVE_W32_SYSTEM
#ifndef S_IRGRP
# define S_IRGRP 0
# define S_IWGRP 0
#endif
#endif
#ifdef HAVE_W32_SYSTEM
int
_assuan_close (int fd)
_assuan_sock_wsa2errno (int err)
{
switch (err)
{
case WSAENOTSOCK:
return EINVAL;
case WSAEWOULDBLOCK:
return EAGAIN;
case ERROR_BROKEN_PIPE:
return EPIPE;
case WSANOTINITIALISED:
return ENOSYS;
default:
return EIO;
}
}
/* W32: Fill BUFFER with LENGTH bytes of random. Returns -1 on
failure, 0 on success. Sets errno on failure. */
static int
get_nonce (char *buffer, size_t nbytes)
{
HCRYPTPROV prov;
int ret = -1;
if (!CryptAcquireContext (&prov, NULL, NULL, PROV_RSA_FULL,
(CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) )
errno = ENODEV;
else
{
if (!CryptGenRandom (prov, nbytes, buffer))
errno = ENODEV;
else
ret = 0;
CryptReleaseContext (prov, 0);
}
return ret;
}
/* W32: The buffer for NONCE needs to be at least 16 bytes. Returns 0 on
success and sets errno on failure. */
static int
read_port_and_nonce (const char *fname, unsigned short *port, char *nonce)
{
FILE *fp;
char buffer[50], *p;
size_t nread;
int aval;
fp = fopen (fname, "rb");
if (!fp)
return -1;
nread = fread (buffer, 1, sizeof buffer - 1, fp);
fclose (fp);
if (!nread)
{
errno = ENOFILE;
return -1;
}
buffer[nread] = 0;
aval = atoi (buffer);
if (aval < 1 || aval > 65535)
{
errno = EINVAL;
return -1;
}
*port = (unsigned int)aval;
for (p=buffer; nread && *p != '\n'; p++, nread--)
;
if (*p != '\n' || nread != 17)
{
errno = EINVAL;
return -1;
}
p++; nread--;
memcpy (nonce, p, 16);
return 0;
}
#endif /*HAVE_W32_SYSTEM*/
int
_assuan_close (assuan_fd_t fd)
{
#if defined (HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN)
int rc = closesocket (fd);
int rc = closesocket (HANDLE2SOCKET(fd));
if (rc)
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
if (rc && WSAGetLastError () == WSAENOTSOCK)
{
rc = CloseHandle (fd);
if (rc)
/* FIXME. */
errno = EIO;
}
return rc;
#else
return close (fd);
@ -56,93 +163,277 @@ _assuan_close (int fd)
}
int
/* Return a new socket. Note that under W32 we consider a socket the
same as an System Handle; all functions using such a handle know
about this dual use and act accordingly. */
assuan_fd_t
_assuan_sock_new (int domain, int type, int proto)
{
#ifndef HAVE_W32_SYSTEM
return socket (domain, type, proto);
#else
#ifdef HAVE_W32_SYSTEM
assuan_fd_t res;
if (domain == AF_UNIX || domain == AF_LOCAL)
domain = AF_INET;
res = SOCKET2HANDLE(socket (domain, type, proto));
if (res == ASSUAN_INVALID_FD)
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
return res;
#else
return socket (domain, type, proto);
#endif
}
int
_assuan_sock_connect (int sockfd, struct sockaddr * addr, int addrlen)
_assuan_sock_connect (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
{
#ifndef HAVE_W32_SYSTEM
return connect (sockfd, addr, addrlen);
#else
#ifdef HAVE_W32_SYSTEM
if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
{
struct sockaddr_in myaddr;
struct sockaddr_un * unaddr;
FILE * fp;
int port = 0;
struct sockaddr_un *unaddr;
unsigned short port;
char nonce[16];
int ret;
unaddr = (struct sockaddr_un *)addr;
fp = fopen (unaddr->sun_path, "rb");
if (!fp)
return -1;
fscanf (fp, "%d", &port);
fclose (fp);
/* XXX: set errno in this case */
if (port < 0 || port > 65535)
if (read_port_and_nonce (unaddr->sun_path, &port, nonce))
return -1;
myaddr.sin_family = AF_INET;
myaddr.sin_port = port;
myaddr.sin_port = htons (port);
myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
/* we need this later. */
/* Set return values. */
unaddr->sun_family = myaddr.sin_family;
unaddr->sun_port = myaddr.sin_port;
unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
return connect (sockfd, (struct sockaddr *)&myaddr, sizeof myaddr);
ret = connect (HANDLE2SOCKET(sockfd),
(struct sockaddr *)&myaddr, sizeof myaddr);
if (!ret)
{
/* Send the nonce. */
ret = _assuan_io_write (sockfd, nonce, 16);
if (ret >= 0 && ret != 16)
{
errno = EIO;
ret = -1;
}
}
return ret;
}
else
{
int res;
res = connect (HANDLE2SOCKET (sockfd), addr, addrlen);
if (res < 0)
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
return res;
}
#else
return connect (sockfd, addr, addrlen);
#endif
}
int
_assuan_sock_bind (int sockfd, struct sockaddr * addr, int addrlen)
_assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
{
#ifndef HAVE_W32_SYSTEM
return bind (sockfd, addr, addrlen);
#else
#ifdef HAVE_W32_SYSTEM
if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
{
struct sockaddr_in myaddr;
struct sockaddr_un * unaddr;
FILE * fp;
struct sockaddr_un *unaddr;
int filefd;
FILE *fp;
int len = sizeof myaddr;
int rc;
char nonce[16];
if (get_nonce (nonce, 16))
return -1;
unaddr = (struct sockaddr_un *)addr;
myaddr.sin_port = 0;
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
rc = bind (sockfd, (struct sockaddr *)&myaddr, len);
if (rc)
return rc;
rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len);
if (rc)
return rc;
unaddr = (struct sockaddr_un *)addr;
fp = fopen (unaddr->sun_path, "wb");
if (!fp)
filefd = open (unaddr->sun_path,
(O_WRONLY|O_CREAT|O_EXCL|O_BINARY),
(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP));
if (filefd == -1)
{
if (errno == EEXIST)
errno = WSAEADDRINUSE;
return -1;
fprintf (fp, "%d", myaddr.sin_port);
fclose (fp);
}
fp = fdopen (filefd, "wb");
if (!fp)
{
int save_e = errno;
close (filefd);
errno = save_e;
return -1;
}
/* we need this later. */
unaddr->sun_family = myaddr.sin_family;
unaddr->sun_port = myaddr.sin_port;
unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr;
rc = bind (HANDLE2SOCKET (sockfd), (struct sockaddr *)&myaddr, len);
if (!rc)
rc = getsockname (HANDLE2SOCKET (sockfd),
(struct sockaddr *)&myaddr, &len);
if (rc)
{
int save_e = errno;
fclose (fp);
remove (unaddr->sun_path);
errno = save_e;
return rc;
}
fprintf (fp, "%d\n", ntohs (myaddr.sin_port));
fwrite (nonce, 16, 1, fp);
fclose (fp);
return 0;
}
else
{
int res = bind (HANDLE2SOCKET(sockfd), addr, addrlen);
if (res < 0)
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
return res;
}
#else
return bind (sockfd, addr, addrlen);
#endif
}
int
_assuan_sock_get_nonce (struct sockaddr *addr, int addrlen,
assuan_sock_nonce_t *nonce)
{
#ifdef HAVE_W32_SYSTEM
if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
{
struct sockaddr_un *unaddr;
unsigned short port;
if (sizeof nonce->nonce != 16)
{
errno = EINVAL;
return -1;
}
nonce->length = 16;
unaddr = (struct sockaddr_un *)addr;
if (read_port_and_nonce (unaddr->sun_path, &port, nonce->nonce))
return -1;
}
else
{
nonce->length = 42; /* Arbitrary valuie to detect unitialized nonce. */
nonce->nonce[0] = 42;
}
#else
(void)addr;
(void)addrlen;
nonce->length = 0;
#endif
return 0;
}
int
_assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
{
#ifdef HAVE_W32_SYSTEM
char buffer[16], *p;
size_t nleft;
int n;
if (sizeof nonce->nonce != 16)
{
errno = EINVAL;
return -1;
}
if (nonce->length == 42 && nonce->nonce[0] == 42)
return 0; /* Not a Unix domain socket. */
if (nonce->length != 16)
{
errno = EINVAL;
return -1;
}
p = buffer;
nleft = 16;
while (nleft)
{
n = _assuan_io_read (SOCKET2HANDLE(fd), p, nleft);
if (n < 0 && errno == EINTR)
;
else if (n < 0 && errno == EAGAIN)
Sleep (100);
else if (n < 0)
return -1;
else if (!n)
{
errno = EIO;
return -1;
}
else
{
p += n;
nleft -= n;
}
}
if (memcmp (buffer, nonce->nonce, 16))
{
errno = EACCES;
return -1;
}
#else
(void)fd;
(void)nonce;
#endif
return 0;
}
/* Public API. */
int
assuan_sock_close (assuan_fd_t fd)
{
return _assuan_close (fd);
}
assuan_fd_t
assuan_sock_new (int domain, int type, int proto)
{
return _assuan_sock_new (domain, type, proto);
}
int
assuan_sock_connect (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
{
return _assuan_sock_connect (sockfd, addr, addrlen);
}
int
assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
{
return _assuan_sock_bind (sockfd, addr, addrlen);
}
int
assuan_sock_get_nonce (struct sockaddr *addr, int addrlen,
assuan_sock_nonce_t *nonce)
{
return _assuan_sock_get_nonce (addr, addrlen, nonce);
}
int
assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
{
return _assuan_sock_check_nonce (fd, nonce);
}

View File

@ -14,9 +14,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
@ -72,9 +70,9 @@
static ssize_t
uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
{
#ifndef HAVE_W32_SYSTEM
int len = ctx->uds.buffersize;
#ifndef HAVE_W32_SYSTEM
if (!ctx->uds.bufferallocated)
{
ctx->uds.buffer = xtrymalloc (2048);
@ -141,12 +139,6 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
#endif /*USE_DESCRIPTOR_PASSING*/
}
#else /*HAVE_W32_SYSTEM*/
len = recvfrom (ctx->inbound.fd, buf, buflen, 0, NULL, NULL);
#endif /*HAVE_W32_SYSTEM*/
/* Return some data to the user. */
if (len > buflen) /* We have more than the user requested. */
@ -159,6 +151,12 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
assert (ctx->uds.bufferoffset <= ctx->uds.bufferallocated);
return len;
#else /*HAVE_W32_SYSTEM*/
int res = recvfrom (HANDLE2SOCKET(ctx->inbound.fd), buf, buflen, 0, NULL, NULL);
if (res < 0)
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
return res;
#endif /*HAVE_W32_SYSTEM*/
}
@ -181,19 +179,21 @@ uds_writer (assuan_context_t ctx, const void *buf, size_t buflen)
iovec.iov_len = buflen;
len = _assuan_simple_sendmsg (ctx, &msg);
#else /*HAVE_W32_SYSTEM*/
int len;
len = sendto (ctx->outbound.fd, buf, buflen, 0,
return len;
#else /*HAVE_W32_SYSTEM*/
int res = sendto (HANDLE2SOCKET(ctx->outbound.fd), buf, buflen, 0,
(struct sockaddr *)&ctx->serveraddr,
sizeof (struct sockaddr_in));
if (res < 0)
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
return res;
#endif /*HAVE_W32_SYSTEM*/
return len;
}
static assuan_error_t
uds_sendfd (assuan_context_t ctx, int fd)
uds_sendfd (assuan_context_t ctx, assuan_fd_t fd)
{
#ifdef USE_DESCRIPTOR_PASSING
struct msghdr msg;
@ -243,7 +243,7 @@ uds_sendfd (assuan_context_t ctx, int fd)
static assuan_error_t
uds_receivefd (assuan_context_t ctx, int *fd)
uds_receivefd (assuan_context_t ctx, assuan_fd_t *fd)
{
#ifdef USE_DESCRIPTOR_PASSING
int i;

View File

@ -14,9 +14,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
@ -32,6 +30,10 @@ static void *(*alloc_func)(size_t n) = malloc;
static void *(*realloc_func)(void *p, size_t n) = realloc;
static void (*free_func)(void*) = free;
struct assuan_io_hooks _assuan_io_hooks;
void
assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
void *(*new_realloc_func)(void *p, size_t n),
@ -42,6 +44,20 @@ assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
free_func = new_free_func;
}
void
assuan_set_io_hooks (assuan_io_hooks_t io_hooks)
{
_assuan_io_hooks.read_hook = NULL;
_assuan_io_hooks.write_hook = NULL;
if (io_hooks)
{
_assuan_io_hooks.read_hook = io_hooks->read_hook;
_assuan_io_hooks.write_hook = io_hooks->write_hook;
}
}
void *
_assuan_malloc (size_t n)
{
@ -152,6 +168,7 @@ assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value)
switch (flag)
{
case ASSUAN_NO_WAITPID: ctx->flags.no_waitpid = value; break;
case ASSUAN_CONFIDENTIAL: ctx->confidential = value; break;
}
}
@ -164,8 +181,8 @@ assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag)
switch (flag)
{
case ASSUAN_NO_WAITPID: return ctx->flags.no_waitpid;
case ASSUAN_CONFIDENTIAL: return ctx->confidential;
}
return 0;
}

View File

@ -1,5 +1,6 @@
/* assuan.h - Definitions for the Assuan IPC library
* Copyright (C) 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
* Copyright (C) 2001, 2002, 2003, 2005, 2007,
* 2008 Free Software Foundation, Inc.
*
* This file is part of Assuan.
*
@ -14,9 +15,7 @@
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ASSUAN_H
@ -25,7 +24,13 @@
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#ifndef _ASSUAN_NO_SOCKET_WRAPPER
#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <sys/socket.h>
#endif
#endif /*!_ASSUAN_NO_SOCKET_WRAPPER*/
/* To use this file with libraries the following macros are useful:
@ -36,7 +41,11 @@
#define _ASSUAN_ONLY_GPG_ERRORS
If this is defined all old-style Assuan error codes are made
inactive as well as other dereacted stuff.
inactive as well as other deprecated stuff.
#define _ASSUAN_NO_SOCKET_WRAPPER
Do not include the definitions for the socket wrapper feature.
The follwing macros are used internally in the implementation of
libassuan:
@ -69,6 +78,8 @@ int _gpgme_io_write (int fd, const void *buffer, size_t count);
int _gpgme_io_sendmsg (int sock, const struct msghdr *msg, int flags);
int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
#define _assuan_funopen _gpgme_funopen
#define close _gpgme_io_close
#define read _gpgme_io_read
#define write _gpgme_io_write
@ -103,6 +114,7 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
_ASSUAN_PREFIX(assuan_register_option_handler)
#define assuan_process _ASSUAN_PREFIX(assuan_process)
#define assuan_process_next _ASSUAN_PREFIX(assuan_process_next)
#define assuan_process_done _ASSUAN_PREFIX(assuan_process_done)
#define assuan_get_active_fds _ASSUAN_PREFIX(assuan_get_active_fds)
#define assuan_get_data_fp _ASSUAN_PREFIX(assuan_get_data_fp)
#define assuan_set_okay_line _ASSUAN_PREFIX(assuan_set_okay_line)
@ -130,6 +142,7 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
#define assuan_get_peercred _ASSUAN_PREFIX(assuan_get_peercred)
#define assuan_transact _ASSUAN_PREFIX(assuan_transact)
#define assuan_inquire _ASSUAN_PREFIX(assuan_inquire)
#define assuan_inquire_ext _ASSUAN_PREFIX(assuan_inquire_ext)
#define assuan_read_line _ASSUAN_PREFIX(assuan_read_line)
#define assuan_pending_line _ASSUAN_PREFIX(assuan_pending_line)
#define assuan_write_line _ASSUAN_PREFIX(assuan_write_line)
@ -137,7 +150,7 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
#define assuan_sendfd _ASSUAN_PREFIX(assuan_sendfd)
#define assuan_receivefd _ASSUAN_PREFIX(assuan_receivefd)
#define assuan_set_malloc_hooks _ASSUAN_PREFIX(assuan_set_malloc_hooks)
#define assuan_set_assuan_log_level _ASSUAN_PREFIX(assuan_set_assuan_log_level)
#define assuan_set_io_hooks _ASSUAN_PREFIX(assuan_set_io_hooks)
#define assuan_set_log_stream _ASSUAN_PREFIX(assuan_set_log_stream)
#define assuan_set_error _ASSUAN_PREFIX(assuan_set_error)
#define assuan_set_pointer _ASSUAN_PREFIX(assuan_set_pointer)
@ -159,6 +172,13 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
#define assuan_pipe_connect2 _ASSUAN_PREFIX(assuan_pipe_connect2)
#define assuan_set_assuan_log_prefix \
_ASSUAN_PREFIX(assuan_set_assuan_log_prefix)
#define assuan_sock_close _ASSUAN_PREFIX(assuan_sock_close)
#define assuan_sock_new _ASSUAN_PREFIX(assuan_sock_new)
#define assuan_sock_connect _ASSUAN_PREFIX(assuan_sock_connect)
#define assuan_sock_bind _ASSUAN_PREFIX(assuan_sock_bind)
#define assuan_sock_get_nonce _ASSUAN_PREFIX(assuan_sock_get_nonce)
#define assuan_sock_check_nonce _ASSUAN_PREFIX(assuan_sock_check_nonce)
/* And now the internal functions, argh... */
#define _assuan_read_line _ASSUAN_PREFIX(_assuan_read_line)
@ -170,8 +190,9 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
_ASSUAN_PREFIX(_assuan_register_std_commands)
#define _assuan_simple_read _ASSUAN_PREFIX(_assuan_simple_read)
#define _assuan_simple_write _ASSUAN_PREFIX(_assuan_simple_write)
#define _assuan_simple_read _ASSUAN_PREFIX(_assuan_simple_read)
#define _assuan_simple_write _ASSUAN_PREFIX(_assuan_simple_write)
#define _assuan_io_read _ASSUAN_PREFIX(_assuan_io_read)
#define _assuan_io_write _ASSUAN_PREFIX(_assuan_io_write)
#define _assuan_io_hooks _ASSUAN_PREFIX(_assuan_io_hooks)
#define _assuan_new_context _ASSUAN_PREFIX(_assuan_new_context)
#define _assuan_release_context _ASSUAN_PREFIX(_assuan_release_context)
#define _assuan_malloc _ASSUAN_PREFIX(_assuan_malloc)
@ -188,19 +209,22 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
#define _assuan_gpg_strerror_r _ASSUAN_PREFIX(_assuan_gpg_strerror_r)
#define _assuan_gpg_strsource _ASSUAN_PREFIX(_assuan_gpg_strsource)
#define _assuan_write_line _ASSUAN_PREFIX(_assuan_write_line)
#define _assuan_close _ASSUAN_PREFIX(_assuan_close)
#define _assuan_sock_new _ASSUAN_PREFIX(_assuan_sock_new)
#define _assuan_sock_bind _ASSUAN_PREFIX(_assuan_sock_bind)
#define _assuan_sock_connect _ASSUAN_PREFIX(_assuan_sock_connect)
#define _assuan_error _ASSUAN_PREFIX(_assuan_error)
#define _assuan_error_is_eagain _ASSUAN_PREFIX(_assuan_error_is_eagain)
#define _assuan_init_uds_io _ASSUAN_PREFIX(_assuan_init_uds_io)
#define _assuan_uds_close_fds _ASSUAN_PREFIX(_assuan_uds_close_fds)
#define _assuan_uds_deinit _ASSUAN_PREFIX(_assuan_uds_deinit)
#define _assuan_simple_recvmsg _ASSUAN_PREFIX(_assuan_simple_recvmsg)
#define _assuan_simple_sendmsg _ASSUAN_PREFIX(_assuan_simple_sendmsg)
#define _assuan_waitpid _ASSUAN_PREFIX(_assuan_waitpid)
#define _assuan_sock_wsa2errno _ASSUAN_PREFIX(_assuan_sock_wsa2errno)
#define _assuan_sock_close _ASSUAN_PREFIX(_assuan_sock_close)
#define _assuan_sock_new _ASSUAN_PREFIX(_assuan_sock_new)
#define _assuan_sock_connect _ASSUAN_PREFIX(_assuan_sock_connect)
#define _assuan_sock_bind _ASSUAN_PREFIX(_assuan_sock_bind)
#define _assuan_sock_get_nonce _ASSUAN_PREFIX(_assuan_sock_get_nonce)
#define _assuan_sock_check_nonce _ASSUAN_PREFIX(_assuan_sock_check_nonce)
#define _assuan_funopen _gpgme_funopen
#endif /*_ASSUAN_EXT_SYM_PREFIX*/
@ -350,7 +374,8 @@ typedef enum
#else /*!_ASSUAN_ONLY_GPG_ERRORS*/
typedef int assuan_error_t;
/* Choose a type compatible with gpg_error_t. */
typedef unsigned int assuan_error_t;
#endif /*!_ASSUAN_ONLY_GPG_ERRORS*/
@ -363,7 +388,11 @@ typedef enum
this is not desirable. By setting this flag, the waitpid will
be skipped and the caller is responsible to cleanup a forked
process. */
ASSUAN_NO_WAITPID = 1
ASSUAN_NO_WAITPID = 1,
/* This flag indicates whether Assuan logging is in confidential
mode. Use assuan_{begin,end}_condidential to change the
mode. */
ASSUAN_CONFIDENTIAL = 2
}
assuan_flag_t;
@ -375,6 +404,66 @@ typedef struct assuan_context_s *assuan_context_t;
typedef struct assuan_context_s *ASSUAN_CONTEXT _ASSUAN_DEPRECATED;
#endif /*_ASSUAN_ONLY_GPG_ERRORS*/
/* Because we use system handles and not libc low level file
descriptors on W32, we need to declare them as HANDLE (which
actually is a plain pointer). This is required to eventually
support 64 bit Windows systems. */
#ifdef _WIN32
typedef void *assuan_fd_t;
#define ASSUAN_INVALID_FD ((void*)(-1))
#define ASSUAN_INT2FD(s) ((void *)(s))
#define ASSUAN_FD2INT(h) ((unsigned int)(h))
#else
typedef int assuan_fd_t;
#define ASSUAN_INVALID_FD (-1)
#define ASSUAN_INT2FD(s) ((s))
#define ASSUAN_FD2INT(h) ((h))
#endif
/* Assuan features an emulation of Unix domain sockets based on a
local TCP connections. To implement access permissions based on
file permissions a nonce is used which is expected by th server as
the first bytes received. This structure is used by the server to
save the nonce created initially by bind. On POSIX systems this is
a dummy operation. */
struct assuan_sock_nonce_s
{
size_t length;
#ifdef _WIN32
char nonce[16];
#endif
};
typedef struct assuan_sock_nonce_s assuan_sock_nonce_t;
/* Define the Unix domain socket structure for Windows. */
#if defined(_WIN32) && !defined(_ASSUAN_NO_SOCKET_WRAPPER)
#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
#endif
#define EADDRINUSE WSAEADDRINUSE
struct sockaddr_un
{
short sun_family;
unsigned short sun_port;
struct in_addr sun_addr;
char sun_path[108-2-4];
};
#endif
/* Definition of hook functions used to conditionally replace the
default I/O functions. */
struct assuan_io_hooks
{
int (*read_hook)(assuan_context_t, assuan_fd_t, void *, size_t, ssize_t *);
int (*write_hook)(assuan_context_t, assuan_fd_t fd,
const void *, size_t, ssize_t *);
};
typedef struct assuan_io_hooks *assuan_io_hooks_t;
/*-- assuan-handler.c --*/
int assuan_register_command (assuan_context_t ctx,
const char *cmd_string,
@ -398,8 +487,9 @@ int assuan_register_option_handler (assuan_context_t ctx,
int assuan_process (assuan_context_t ctx);
int assuan_process_next (assuan_context_t ctx);
int assuan_process_done (assuan_context_t ctx, int rc);
int assuan_get_active_fds (assuan_context_t ctx, int what,
int *fdarray, int fdarraysize);
assuan_fd_t *fdarray, int fdarraysize);
FILE *assuan_get_data_fp (assuan_context_t ctx);
@ -410,15 +500,17 @@ assuan_error_t assuan_write_status (assuan_context_t ctx,
/* Negotiate a file descriptor. If LINE contains "FD=N", returns N
assuming a local file descriptor. If LINE contains "FD" reads a
file descriptor via CTX and stores it in *RDF (the CTX must be
capable of passing file descriptors). */
capable of passing file descriptors). Under W32 the returned FD is
a libc-type one. */
assuan_error_t assuan_command_parse_fd (assuan_context_t ctx, char *line,
int *rfd);
assuan_fd_t *rfd);
/*-- assuan-listen.c --*/
assuan_error_t assuan_set_hello_line (assuan_context_t ctx, const char *line);
assuan_error_t assuan_accept (assuan_context_t ctx);
int assuan_get_input_fd (assuan_context_t ctx);
int assuan_get_output_fd (assuan_context_t ctx);
assuan_fd_t assuan_get_input_fd (assuan_context_t ctx);
assuan_fd_t assuan_get_output_fd (assuan_context_t ctx);
assuan_error_t assuan_close_input_fd (assuan_context_t ctx);
assuan_error_t assuan_close_output_fd (assuan_context_t ctx);
@ -428,11 +520,12 @@ int assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2]);
void assuan_deinit_server (assuan_context_t ctx);
/*-- assuan-socket-server.c --*/
int assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd);
int assuan_init_socket_server (assuan_context_t *r_ctx, assuan_fd_t listen_fd);
int assuan_init_connected_socket_server (assuan_context_t *r_ctx,
int fd) _ASSUAN_DEPRECATED;
int assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd,
assuan_fd_t fd) _ASSUAN_DEPRECATED;
int assuan_init_socket_server_ext (assuan_context_t *r_ctx, assuan_fd_t fd,
unsigned int flags);
void assuan_set_sock_nonce (assuan_context_t ctx, assuan_sock_nonce_t *nonce);
/*-- assuan-pipe-connect.c --*/
assuan_error_t assuan_pipe_connect (assuan_context_t *ctx,
@ -465,7 +558,7 @@ assuan_error_t assuan_socket_connect_ext (assuan_context_t *ctx,
/*-- assuan-connect.c --*/
void assuan_disconnect (assuan_context_t ctx);
pid_t assuan_get_pid (assuan_context_t ctx);
#ifndef HAVE_W32_SYSTEM
#ifndef _WIN32
assuan_error_t assuan_get_peercred (assuan_context_t ctx,
pid_t *pid, uid_t *uid, gid_t *gid);
#endif
@ -474,11 +567,11 @@ assuan_error_t assuan_get_peercred (assuan_context_t ctx,
assuan_error_t
assuan_transact (assuan_context_t ctx,
const char *command,
int (*data_cb)(void *, const void *, size_t),
assuan_error_t (*data_cb)(void *, const void *, size_t),
void *data_cb_arg,
int (*inquire_cb)(void*, const char *),
assuan_error_t (*inquire_cb)(void*, const char *),
void *inquire_cb_arg,
int (*status_cb)(void*, const char *),
assuan_error_t (*status_cb)(void*, const char *),
void *status_cb_arg);
@ -486,7 +579,12 @@ assuan_transact (assuan_context_t ctx,
assuan_error_t assuan_inquire (assuan_context_t ctx, const char *keyword,
unsigned char **r_buffer, size_t *r_length,
size_t maxlen);
assuan_error_t assuan_inquire_ext (assuan_context_t ctx, const char *keyword,
size_t maxlen,
int (*cb) (void *cb_data, int rc,
unsigned char *buf,
size_t buf_len),
void *cb_data);
/*-- assuan-buffer.c --*/
assuan_error_t assuan_read_line (assuan_context_t ctx,
char **line, size_t *linelen);
@ -498,13 +596,15 @@ assuan_error_t assuan_send_data (assuan_context_t ctx,
/* The file descriptor must be pending before assuan_receivefd is
called. This means that assuan_sendfd should be called *before* the
trigger is sent (normally via assuan_write_line ("INPUT FD")). */
assuan_error_t assuan_sendfd (assuan_context_t ctx, int fd);
assuan_error_t assuan_receivefd (assuan_context_t ctx, int *fd);
assuan_error_t assuan_sendfd (assuan_context_t ctx, assuan_fd_t fd);
assuan_error_t assuan_receivefd (assuan_context_t ctx, assuan_fd_t *fd);
/*-- assuan-util.c --*/
void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
void *(*new_realloc_func)(void *p, size_t n),
void (*new_free_func)(void*) );
void assuan_set_io_hooks (assuan_io_hooks_t io_hooks);
void assuan_set_log_stream (assuan_context_t ctx, FILE *fp);
int assuan_set_error (assuan_context_t ctx, int err, const char *text);
void assuan_set_pointer (assuan_context_t ctx, void *pointer);
@ -545,14 +645,6 @@ void assuan_set_assuan_err_source (int errsource);
/*-- assuan-logging.c --*/
/* Set the log level for general assuan commands. 0 is no logging at
all, 1 is the standard logging and the default. Higher leveles may
be defined in the future. Passing a level of -1 will not change
the current log level. Returns previous log level. Note, that
this function is not thread-safe and should in general be used
right at startup. */
int assuan_set_assuan_log_level (int level);
/* Set the stream to which assuan should log message not associated
with a context. By default, this is stderr. The default value
will be changed when the first log stream is associated with a
@ -574,6 +666,21 @@ void assuan_set_assuan_log_prefix (const char *text);
string, i.e. "" */
const char *assuan_get_assuan_log_prefix (void);
/*-- assuan-socket.c --*/
/* These are socket wrapper functions to support an emulation of Unix
domain sockets on Windows W32. */
int assuan_sock_close (assuan_fd_t fd);
assuan_fd_t assuan_sock_new (int domain, int type, int proto);
int assuan_sock_connect (assuan_fd_t sockfd,
struct sockaddr *addr, int addrlen);
int assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen);
int assuan_sock_get_nonce (struct sockaddr *addr, int addrlen,
assuan_sock_nonce_t *nonce);
int assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce);
#ifdef __cplusplus
}
#endif

View File

@ -31,6 +31,7 @@ cat <<EOF
#undef _ASSUAN_IN_LIBASSUAN /* undef to get all error codes. */
#include "assuan.h"
#include "assuan-defs.h"
/* If true the modern gpg-error style error codes are used in the
API. */
@ -94,11 +95,8 @@ _assuan_error (int oldcode)
{
case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/ break;
case EAGAIN:
if (errno > 0 && errno < 4096)
{
n = (EAGAIN | (1 << 15));
n = (6 | (1 << 15));
break;
}
default: n = 270; /*GPG_ERR_ASS_READ_ERROR*/ break;
}
break;
@ -108,11 +106,8 @@ _assuan_error (int oldcode)
{
case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/ break;
case EAGAIN:
if (errno > 0 && errno < 4096)
{
n = (EAGAIN | (1 << 15));
n = (6 | (1 << 15));
break;
}
default: n = 271; /*GPG_ERR_ASS_WRITE_ERROR*/ break;
}
break;
@ -127,11 +122,8 @@ _assuan_error (int oldcode)
n = 16381; /*GPG_ERR_MISSING_ERRNO*/
break;
case ENOMEM:
if (errno > 0 && errno < 4096)
{
n = (ENOMEM | (1 << 15));
n = (86 | (1 << 15));
break;
}
default:
n = 16382; /*GPG_ERR_UNKNOWN_ERRNO*/
break;
@ -150,6 +142,23 @@ _assuan_error (int oldcode)
}
/* A small helper function to treat EAGAIN transparently to the
caller. */
int
_assuan_error_is_eagain (assuan_error_t err)
{
if ((!err_source && err == ASSUAN_Read_Error && errno == EAGAIN)
|| (err_source && (err & ((1 << 24) - 1)) == (6 | (1 << 15))))
{
/* Avoid spinning by sleeping for one tenth of a second. */
_assuan_usleep (100000);
return 1;
}
else
return 0;
}
/**
* assuan_strerror:
* @err: Error code

View File

@ -145,8 +145,7 @@ debug_init (void)
fprintf (errfp, "gpgme_debug: level=%d\n", debug_level);
#ifdef HAVE_ASSUAN_H
assuan_set_assuan_log_prefix ("gpgme-assuan");
assuan_set_assuan_log_stream (errfp);
assuan_set_assuan_log_level (debug_level >= 0? debug_level:0);
assuan_set_assuan_log_stream (debug_level > 0 ? errfp : NULL);
#endif /* HAVE_ASSUAN_H*/
}
UNLOCK (debug_lock);

View File

@ -56,7 +56,6 @@ do_subsystem_inits (void)
_gpgme_sema_subsystem_init ();
#ifdef HAVE_ASSUAN_H
assuan_set_assuan_log_level (0);
assuan_set_assuan_err_source (GPG_ERR_SOURCE_GPGME);
#endif /*HAVE_ASSUAN_H*/
_gpgme_debug_subsystem_init ();