assuan/
authorMarcus Brinkmann <mb@g10code.com>
Fri, 6 Mar 2009 22:29:49 +0000 (22:29 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Fri, 6 Mar 2009 22:29:49 +0000 (22:29 +0000)
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.

22 files changed:
ChangeLog
assuan/ChangeLog
assuan/assuan-buffer.c
assuan/assuan-client.c
assuan/assuan-connect.c
assuan/assuan-defs.h
assuan/assuan-handler.c
assuan/assuan-inquire.c
assuan/assuan-io.c
assuan/assuan-listen.c
assuan/assuan-logging.c
assuan/assuan-pipe-connect.c
assuan/assuan-pipe-server.c
assuan/assuan-socket-connect.c
assuan/assuan-socket-server.c
assuan/assuan-socket.c
assuan/assuan-uds.c
assuan/assuan-util.c
assuan/assuan.h
assuan/mkerrors
src/debug.c
src/version.c

index 40966da..fecb981 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
 2009-01-26  Werner Koch  <wk@g10code.com>
 
        * configure.ac (AC_CONFIG_FILES): Add tests/opassuan/Makefile.
index e620d20..3d875fb 100644 (file)
        * assuan-buffer.c (assuan_send_data): Add hack to optionally send
        a final "CAN".
 
        * 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
 
 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-09-03  Marcus Brinkmann  <marcus@g10code.de>
 
        * assuan.h [_ASSUAN_EXT_SYM_PREFIX]: Add missing symbol renames
        with _ASSUAN_PREFIX.
 
 
 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>
+       * 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.
 
 
-       * 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.
+2007-08-24  Werner Koch  <wk@g10code.com>
 
 
-2007-07-12  Werner Koch  <wk@g10code.com>
+       Switched license to back to LGPLv2.1.
 
 
-       * 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.
+2007-08-09  Marcus Brinkmann  <marcus@g10code.de>
 
 
-       * assuan-io.c (_assuan_simple_write, _assuan_simple_read): Map
-       ERROR_BROKEN_PIPE to EPIPE.
+       * 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.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): Return EPIPE on a closed pipe.
+       (_assuan_simple_read): Likewise
+       
 2007-07-08  Marcus Brinkmann  <marcus@g10code.de>
 
 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.
 
        * 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.
 2007-07-04  Marcus Brinkmann  <marcus@g10code.de>
 
        Change _WIN32 to HAVE_W32_SYSTEM for consistency.
        to silence gcc warning.
        * assuan-inquire.c (assuan_inquire): Likewise.
 
        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>
 
        * 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.
+       * mkerrors: Include config.h into assuan-errors.c.  This is
+       required so that assuan.h knows about the W32 macro.
 
 
-       Merged changes for W32 support from libassuan.
-       
        * assuan.h [_ASSUAN_EXT_SYM_PREFIX]: New.
        * assuan-io.c [_ASSUAN_NO_PTH]: New.
        * assuan-pipe-connect.c (fix_signals) [_ASSUAN_NO_FIXED_SIGNALS]: New.
        (assuan_pipe_connect2) [_ASSUAN_USE_DOUBLE_FORK]: Use double fork.
        (fix_signals) [_ASSUAN_USE_DOUBLE_FORK]: Do not wait..
        * assuan.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):
        * assuan-logging.c (_assuan_w32_strerror): New. 
        * assuan-defs.h (w32_strerror): new.
        * assuan-pipe-connect.c (assuan_pipe_connect2, fix_signals):
        (build_w32_commandline, create_inheritable_pipe): New.  Taken
        from gnupg 1.9.
        (assuan_pipe_connect2) [W32]: Implemented for W32.
        (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.
        * assuan-socket.c (_assuan_close): New.
        (_assuan_sock_new): New.
        (_assuan_sock_bind): New.
        * assuan-io.c (_assuan_simple_read, _assuan_simple_write): W32
        support.
        * assuan-socket.c (_assuan_close): New.
        (_assuan_sock_new): New.
        (_assuan_sock_bind): New.
+       
+2004-11-16  Werner Koch  <wk@g10code.com>
 
 
-2005-03-22  Werner Koch  <wk@g10code.com>
+       * assuan-socket-connect.c (LOG): Fixed macro to print not only the
+       prefix.
+       * assuan-domain-connect.c, assuan-socket-connect.c (LOG): Ditto.
 
 
-       * 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√§.
+2004-10-02  Werner Koch  <wk@g10code.com>
+
+       * 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-12-16  Marcus Brinkmann  <marcus@g10code.de>
+2004-06-23  Marcus Brinkmann  <marcus@g10code.de>
 
 
-       * 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.
+       * assuan-domain-connect.c [HAVE_SYS_UIO_H]: Include <sys/uio.h>.
 
 
-2004-12-07  Marcus Brinkmann  <marcus@g10code.de>
+2004-05-11  Werner Koch  <wk@gnupg.org>
 
 
-       * README.1st: Add copyright notice.
+       * assuan-listen.c (assuan_set_hello_line, assuan_accept): Allow
+       for multi line hello strings.
 
 
-2004-06-23  Marcus Brinkmann  <marcus@g10code.de>
+       * assuan-buffer.c (_assuan_write_line): New with parts of ..
+       (assuan_write_line): .. factored out.
 
 
-       * assuan-domain-connect.c [HAVE_SYS_UIO_H]: Include <sys/uio.h>.
+2004-04-29  Werner Koch  <wk@gnupg.org>
 
 
-       * assuan-handler.c: Include <errno.h>.
+       * assuan-socket-connect.c: Include string.h.
+       * assuan-logging.c: Ditto.
 
 
-2004-06-08  Marcus Brinkmann  <marcus@g10code.de>
+2004-04-22  Marcus Brinkmann  <marcus@g10code.de>
 
 
-       * assuan-buffer.c (assuan_write_line): If the line is longer than
-       the maximum line length, bail out early.
+       * libassuan.m4: Quote first argument to AC_DEFUN.
 
 2004-04-21  Werner Koch  <wk@gnupg.org>
 
 
 2004-04-21  Werner Koch  <wk@gnupg.org>
 
        * assuan-defs.h: Add space in the context for this.
 
        
        * 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
 
  This file is free software; as a special exception the author gives
  unlimited permission to copy and/or distribute it, with or without
index 31f3394..b9e3572 100644 (file)
@@ -14,9 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * 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 <config.h>
@@ -53,9 +51,10 @@ writen (assuan_context_t ctx, const char *buffer, size_t length)
   return 0;  /* okay */
 }
 
   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
    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)
 static int
 readline (assuan_context_t ctx, char *buf, size_t buflen,
          int *r_nread, int *r_eof)
@@ -94,7 +93,7 @@ readline (assuan_context_t ctx, char *buf, size_t buflen,
 }
 
 
 }
 
 
-/* Function returns an Assuan error. */
+/* Function returns an Assuan error.  */
 assuan_error_t
 _assuan_read_line (assuan_context_t ctx)
 {
 assuan_error_t
 _assuan_read_line (assuan_context_t ctx)
 {
@@ -134,11 +133,23 @@ _assuan_read_line (assuan_context_t ctx)
                    &nread, &ctx->inbound.eof);
   if (rc)
     {
                    &nread, &ctx->inbound.eof);
   if (rc)
     {
+      int saved_errno = errno;
+
       if (ctx->log_fp)
       if (ctx->log_fp)
-       fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s (%d)]\n",
-                assuan_get_assuan_log_prefix (),
-                 (unsigned int)getpid (), ctx->inbound.fd,
-                 strerror (errno), errno);
+       fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s]\n",
+                 assuan_get_assuan_log_prefix (),
+                 (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)
       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 (),
       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);
     }
 
       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 (),
        {
          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
          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 (),
       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 
       *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);
 
   if (!ctx)
     return _assuan_error (ASSUAN_Invalid_Value);
 
-  err = _assuan_read_line (ctx);
+  do
+    {
+      err = _assuan_read_line (ctx);
+    }
+  while (_assuan_error_is_eagain (err));
+
   *line = ctx->inbound.line;
   *linelen = ctx->inbound.linelen;
   return 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 (),
         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)
       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 (),
     {
       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
       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 (),
     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);
 }
 
   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 (),
             {
              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);
 
               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 (),
        {
          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
          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_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. */
 {
   /* 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
 #ifdef USE_DESCRIPTOR_PASSING
     return 0;
 #else
@@ -543,7 +559,7 @@ assuan_sendfd (assuan_context_t ctx, int fd)
 }
 
 assuan_error_t
 }
 
 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,
 {
   if (! ctx->io->receivefd)
     return set_error (ctx, Not_Implemented,
index 7b3d266..15f4f1c 100644 (file)
@@ -14,9 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * 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 <config.h>
@@ -44,7 +42,11 @@ _assuan_read_from_server (assuan_context_t ctx, int *okay, int *off)
   *off = 0;
   do 
     {
   *off = 0;
   do 
     {
-      rc = _assuan_read_line (ctx);
+      do
+       {
+         rc = _assuan_read_line (ctx);
+       }
+      while (_assuan_error_is_eagain (rc));
       if (rc)
         return rc;
       line = ctx->inbound.line;
       if (rc)
         return rc;
       line = ctx->inbound.line;
index b50b17b..2106ac3 100644 (file)
@@ -14,9 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * 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
  */
 
 #ifdef HAVE_CONFIG_H
@@ -60,8 +58,8 @@ assuan_get_pid (assuan_context_t ctx)
 
 
 #ifndef HAVE_W32_SYSTEM
 
 
 #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)
    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)
index b1d9f3e..e2d0f52 100644 (file)
@@ -1,5 +1,5 @@
 /* assuan-defs.c - Internal definitions to Assuan
 /* 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.
  *
  *
  * This file is part of Assuan.
  *
 #endif
 
 #ifdef HAVE_W32_SYSTEM
 #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; */
 /* 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.  */
   /* 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.  */
   /* 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
 {
 /* 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 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() */
 
   char *hello_line;
   char *okay_line;    /* See assuan_set_okay_line() */
 
@@ -111,7 +112,7 @@ struct assuan_context_s
   FILE *log_fp;
 
   struct {
   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
     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 {
   } inbound;
 
   struct {
-    int fd;
+    assuan_fd_t fd;
     struct {
       FILE *fp;
       char line[LINELENGTH];
     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 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. */
 
   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 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;
 
     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
   /* 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);
 
   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;
 
   /* 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-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);
    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)
 
 #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)
 
    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_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);
 #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
 
 ssize_t _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg);
 #endif
 
+void _assuan_usleep (unsigned int usec);
+
+
 /*-- assuan-socket.c --*/
 /*-- 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. */
 
 #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)
 
 
 #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*/
 #endif /*ASSUAN_DEFS_H*/
index d1b29cf..b940bfd 100644 (file)
@@ -1,5 +1,5 @@
 /* assuan-handler.c - dispatch commands 
 /* 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.
  *
  *
  * 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
  * 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 <config.h>
 static int my_strcasecmp (const char *a, const char *b);
 
 
 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)
 {
 
 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)
 {
 }
 
 
 static int
 std_handler_nop (assuan_context_t ctx, char *line)
 {
-  return 0; /* okay */
+  return PROCESS_DONE (ctx, 0); /* okay */
 }
   
 static int
 }
   
 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);
 {
   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
 }
 
 static int
@@ -65,9 +66,12 @@ std_handler_option (assuan_context_t ctx, char *line)
   for (key=line; spacep (key); key++)
     ;
   if (!*key)
   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 == '=')
   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)
   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)
           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)
         {
         }
       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 == '-')
   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)
 
   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
 }
   
 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);
     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)
 {
 }
   
 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
 }
   
 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);
   assuan_close_input_fd (ctx);
   assuan_close_output_fd (ctx);
   _assuan_uds_close_fds (ctx);
-  return 0;
+  return PROCESS_DONE (ctx, 0);
 }
   
 static int
 }
   
 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)
 {
 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_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;
 
 {
   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");
       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);
       *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));
 
       /* 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);
 }
 
     return assuan_receivefd (ctx, rfd);
 }
 
+
 /* Format is INPUT FD=<n> */
 static int
 std_handler_input (assuan_context_t ctx, char *line)
 {
 /* 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)
 
   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);
   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)
 {
 }
 
 /* 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)
 
   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);
   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 },
   { "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 },
   { "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);
 }
 
     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
 /* 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)
 {
 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;
 
   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 */
   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)
 
   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;
   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)
         }
     }
   if (!s)
-    return set_error (ctx, Unknown_Command, NULL);
+    return PROCESS_DONE (ctx, set_error (ctx, Unknown_Command, NULL));
   line += shift;
   linelen -= shift;
 
   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);
 }
 
   return ctx->cmdtbl[i].handler (ctx, line);
 }
 
-
-
 \f
 \f
-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_inquire)
-    return _assuan_error (ASSUAN_Nested_Commands);
+  if (!ctx->in_command)
+    return _assuan_error (ASSUAN_General_Error);
 
 
-  rc = _assuan_read_line (ctx);
-  if (rc)
-    return rc;
-  if (*ctx->inbound.line == '#' || !ctx->inbound.linelen)
-    return 0; /* comment line - ignore */
+  ctx->in_command = 0;
 
 
-  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)
   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)
       fclose (ctx->outbound.data.fp);
       ctx->outbound.data.fp = NULL;
       if (!rc && ctx->outbound.data.error)
-        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)
       assuan_send_data (ctx, NULL, 0);
       if (!rc && ctx->outbound.data.error)
-        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");
   if (!rc)
     {
       rc = assuan_write_line (ctx, ctx->okay_line? ctx->okay_line : "OK");
@@ -501,26 +537,26 @@ process_request (assuan_context_t ctx)
   else 
     {
       char errline[300];
   else 
     {
       char errline[300];
-
+      
       if (rc < 100)
         sprintf (errline, "ERR %d server fault (%.50s)",
                  _assuan_error (ASSUAN_Server_Fault), assuan_strerror (rc));
       else
         {
           const char *text = ctx->err_no == rc? ctx->err_str:NULL;
       if (rc < 100)
         sprintf (errline, "ERR %d server fault (%.50s)",
                  _assuan_error (ASSUAN_Server_Fault), assuan_strerror (rc));
       else
         {
           const char *text = ctx->err_no == rc? ctx->err_str:NULL;
-
+         
 #if defined(HAVE_W32_SYSTEM)
           unsigned int source, code;
           char ebuf[50];
           const char *esrc;
 #if defined(HAVE_W32_SYSTEM)
           unsigned int source, code;
           char ebuf[50];
           const char *esrc;
-
+         
           source = ((rc >> 24) & 0xff);
           code = (rc & 0x00ffffff);
           if (source
               && !_assuan_gpg_strerror_r (rc, ebuf, sizeof ebuf)
               && (esrc=_assuan_gpg_strsource (rc)))
             {
           source = ((rc >> 24) & 0xff);
           code = (rc & 0x00ffffff);
           if (source
               && !_assuan_gpg_strerror_r (rc, ebuf, sizeof ebuf)
               && (esrc=_assuan_gpg_strsource (rc)))
             {
-              /* Assume this is an libgpg-error. */
+              /* Assume this is an libgpg-error.  */
               sprintf (errline, "ERR %d %.50s <%.30s>%s%.100s",
                        rc, ebuf, esrc,
                        text? " - ":"", text?text:"");
               sprintf (errline, "ERR %d %.50s <%.30s>%s%.100s",
                        rc, ebuf, esrc,
                        text? " - ":"", text?text:"");
@@ -554,7 +590,7 @@ process_request (assuan_context_t ctx)
             {
               /* Assume this is an libgpg-error. */
               char ebuf[50];
             {
               /* Assume this is an libgpg-error. */
               char ebuf[50];
-
+             
               gpg_strerror_r (rc, ebuf, sizeof ebuf );
               sprintf (errline, "ERR %d %.50s <%.30s>%s%.100s",
                        rc,
               gpg_strerror_r (rc, ebuf, sizeof ebuf );
               sprintf (errline, "ERR %d %.50s <%.30s>%s%.100s",
                        rc,
@@ -569,19 +605,123 @@ process_request (assuan_context_t ctx)
         }
       rc = assuan_write_line (ctx, errline);
     }
         }
       rc = assuan_write_line (ctx, errline);
     }
-
+  
   if (ctx->post_cmd_notify_fnc)
     ctx->post_cmd_notify_fnc (ctx, rc);
   if (ctx->post_cmd_notify_fnc)
     ctx->post_cmd_notify_fnc (ctx, rc);
-
+  
   ctx->confidential = 0;
   if (ctx->okay_line)
     {
       xfree (ctx->okay_line);
       ctx->okay_line = NULL;
     }
   ctx->confidential = 0;
   if (ctx->okay_line)
     {
       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;
 }
 
   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;
+}
+
+
+\f
+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
 /**
  * assuan_process:
  * @ctx: assuan context
@@ -610,24 +750,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
  * @what: 0 for read fds, 1 for write fds
  * assuan_get_active_fds:
  * @ctx: Assuan context
  * @what: 0 for read fds, 1 for write fds
@@ -646,7 +768,7 @@ assuan_process_next (assuan_context_t ctx)
  **/
 int 
 assuan_get_active_fds (assuan_context_t ctx, int what,
  **/
 int 
 assuan_get_active_fds (assuan_context_t ctx, int what,
-                       int *fdarray, int fdarraysize)
+                       assuan_fd_t *fdarray, int fdarraysize)
 {
   int n = 0;
 
 {
   int n = 0;
 
@@ -655,16 +777,16 @@ assuan_get_active_fds (assuan_context_t ctx, int what,
 
   if (!what)
     {
 
   if (!what)
     {
-      if (ctx->inbound.fd != -1)
+      if (ctx->inbound.fd != ASSUAN_INVALID_FD)
         fdarray[n++] = ctx->inbound.fd;
     }
   else
     {
         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++] = 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
 #else
         fdarray[n++] = fileno (ctx->outbound.data.fp);
 #endif
index d8c52d0..58b9f02 100644 (file)
@@ -1,5 +1,5 @@
 /* assuan-inquire.c - handle inquire stuff
 /* 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.
  *
  *
  * 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
  * 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 <config.h>
@@ -44,7 +42,7 @@ struct membuf
 
 
 \f
 
 
 \f
-/* 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
    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);
+         do
+           rc = _assuan_read_line (ctx);
+         while (_assuan_error_is_eagain (rc));
           if (rc)
             goto leave;
           line = (unsigned char *) ctx->inbound.line;
           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;
 }
 
   return rc;
 }
 
+\f
+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;
+}
index a7f8449..8d4cbb8 100644 (file)
@@ -1,5 +1,5 @@
 /* assuan-io.c - Wraps the read and write functions.
 /* 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.
  *
  *
  * This file is part of Assuan.
  *
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * 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
 
  */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
+#include <time.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #ifdef HAVE_SYS_SOCKET_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
 
 
 #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
 {
 #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,32 +56,71 @@ _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;
 
      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)
     {
     {
-      DWORD nread = 0;
-
-      n = ReadFile ((HANDLE)ctx->inbound.fd, buffer, size, &nread, NULL);
-      if (!n)
+      switch (WSAGetLastError ())
         {
         {
-          switch (GetLastError())
-            {
-            case ERROR_BROKEN_PIPE: errno = EPIPE; break;
-            default: errno = EIO; 
-            }
-          n = -1;
+        case WSAENOTSOCK:
+          {
+            DWORD nread = 0;
+            
+            n = ReadFile (fd, buffer, size, &nread, NULL);
+            if (!n)
+              {
+                switch (GetLastError())
+                  {
+                  case ERROR_BROKEN_PIPE: errno = EPIPE; break;
+                  default: errno = EIO; 
+                  }
+                n = -1;
+              }
+            else
+              n = (int)nread;
+          }
+          break;
+          
+        case WSAEWOULDBLOCK: errno = EAGAIN; break;
+        case ERROR_BROKEN_PIPE: errno = EPIPE; break;
+        default: errno = EIO; break;
         }
         }
-      else
-        n = (int)nread;
     }
   return n;
 #else /*!HAVE_W32_SYSTEM*/
     }
   return n;
 #else /*!HAVE_W32_SYSTEM*/
-  return read (ctx->inbound.fd, buffer, size);
+  return read (fd, buffer, size);
 #endif /*!HAVE_W32_SYSTEM*/
 }
 
 #endif /*!HAVE_W32_SYSTEM*/
 }
 
+
 ssize_t
 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
 {
 #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;
 
      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;
 
   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 ())
       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 n;
 #else /*!HAVE_W32_SYSTEM*/
-  return write (ctx->outbound.fd, buffer, size);
+  return write (fd, buffer, size);
 #endif /*!HAVE_W32_SYSTEM*/
 }
 
 #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
 
 #ifdef HAVE_W32_SYSTEM
 int
@@ -152,3 +214,32 @@ _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg)
   return ret;
 #endif
 }
   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
+    }
+}
+
index 04db68c..2ef9334 100644 (file)
@@ -14,9 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * 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 <config.h>
@@ -116,17 +114,17 @@ assuan_accept (assuan_context_t ctx)
 
 
 
 
 
 
-int
+assuan_fd_t
 assuan_get_input_fd (assuan_context_t ctx)
 {
 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)
 {
 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)
 {
 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);
     return _assuan_error (ASSUAN_Invalid_Value);
   _assuan_close (ctx->input_fd);
-  ctx->input_fd = -1;
+  ctx->input_fd = ASSUAN_INVALID_FD;
   return 0;
 }
 
   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)
 {
 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);
     return _assuan_error (ASSUAN_Invalid_Value);
 
   _assuan_close (ctx->output_fd);
-  ctx->output_fd = -1;
+  ctx->output_fd = ASSUAN_INVALID_FD;
   return 0;
 }
 
   return 0;
 }
 
index 41ada91..2ebd667 100644 (file)
@@ -14,9 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * 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
  */
 
 #ifdef HAVE_CONFIG_H
 static char prefix_buffer[80];
 static FILE *_assuan_log;
 static int full_logging;
 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)
 
 void
 _assuan_set_default_log_stream (FILE *fp)
@@ -122,9 +103,6 @@ _assuan_log_printf (const char *format, ...)
   FILE *fp;
   const char *prf;
   int save_errno = errno;
   FILE *fp;
   const char *prf;
   int save_errno = errno;
-
-  if (!log_level)
-    return;
   
   fp = assuan_get_assuan_log_stream ();
   prf = assuan_get_assuan_log_prefix ();
   
   fp = assuan_get_assuan_log_stream ();
   prf = assuan_get_assuan_log_prefix ();
@@ -134,29 +112,31 @@ _assuan_log_printf (const char *format, ...)
   va_start (arg_ptr, format);
   vfprintf (fp, format, arg_ptr );
   va_end (arg_ptr);
   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
   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
-   context basis. */
+   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;
 void
 _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
 {
   const unsigned char *s;
-  int n;
-
-  if (!log_level)
-    return;
+  unsigned int n;
 
 
-  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;
       break;
 
   s = buffer;
-  if (!n && *s != '[')
+  if (! n && *s != '[')
     fwrite (buffer, length, 1, fp);
   else
     {
     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);
       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, " %02x", *s);
-          fprintf (fp, " ...(%d bytes skipped)", (int)length - 12);
+          fprintf (fp, " ...(%d bytes skipped)", (int) length - 12);
         }
       else
         {
         }
       else
         {
-          for (n=0; n < length; n++, s++)
+          for (n = 0; n < length; n++, s++)
             fprintf (fp, " %02x", *s);
         }
       putc_unlocked (' ', fp);
             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;
 _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;
 
     return;
 
-  if (!*s)
-    return;
-
-  fp = assuan_get_assuan_log_stream ();
-
 #ifdef HAVE_FLOCKFILE
   flockfile (fp);
 #endif
 #ifdef HAVE_FLOCKFILE
   flockfile (fp);
 #endif
index e355532..7fdfe74 100644 (file)
@@ -1,5 +1,6 @@
 /* assuan-pipe-connect.c - Establish a pipe connection (client) 
 /* 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.
  *
  *
  * 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
  * 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
  */
 
 #ifdef HAVE_CONFIG_H
@@ -75,17 +74,6 @@ int _gpgme_io_spawn (const char *path, char *const argv[],
 #define MAX_OPEN_FDS 20
 #endif
 
 #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
 
 /* 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)
 {
 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)
     {
       _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);
     {
       _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); 
     {
 #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
-#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;
 }
 
     }
   return 0;
 }
 
+
 static void
 do_deinit (assuan_context_t ctx)
 {
 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),
                    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];
 
 {
   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);
 
   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),
                    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;
 {
   assuan_error_t err;
   int res;
@@ -744,9 +738,9 @@ build_w32_commandline (const char * const *argv, char **cmdline)
 
 
 #ifdef HAVE_W32_SYSTEM
 
 
 #ifdef HAVE_W32_SYSTEM
-/* Create pipe where one end is inheritable.  */
+/* Create pipe where one end end is inheritable.  */
 static int
 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;
 {
   HANDLE r, w, h;
   SECURITY_ATTRIBUTES sec_attr;
@@ -781,14 +775,12 @@ create_inheritable_pipe (int filedes[2], int for_write)
       w = h;
     }
 
       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;
 }
   return 0;
 }
-#endif /* HAVE_W32_SYSTEM */
+#endif /*HAVE_W32_SYSTEM*/
+
 
 #ifdef HAVE_W32_SYSTEM
 #define pipe_connect pipe_connect_w32
 
 #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),
                   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;
 {
   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;
   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))
     {
   
   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);
     }
       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)
     {
   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);
     }
       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;
   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. */
 
   /* 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);
       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));
       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;
           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 = 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. */
 
 
   /* 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
   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.  */
                        | 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));
                       ))
     {
       _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);
       if (nullfd != INVALID_HANDLE_VALUE)
         CloseHandle (nullfd);
       xfree (cmdline);
@@ -953,20 +942,17 @@ pipe_connect_w32 (assuan_context_t *ctx,
       nullfd = INVALID_HANDLE_VALUE;
     }
 
       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); 
 
   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);
 }
 
   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)
 {
 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)
 {
                       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.
 
    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
 
    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
 #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);
 }
 
 }
 
index 1b47def..7040414 100644 (file)
@@ -14,9 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * 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 <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 = 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->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;
   /* 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
 #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);
       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) )
 #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;
         }
           _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];
         {
           /* Standard pipe server. */
           ctx->inbound.fd  = filedes[0];
@@ -168,6 +167,7 @@ _assuan_release_context (assuan_context_t ctx)
 {
   if (ctx)
     {
 {
   if (ctx)
     {
+      _assuan_inquire_release (ctx);
       xfree (ctx->hello_line);
       xfree (ctx->okay_line);
       xfree (ctx->cmdtbl);
       xfree (ctx->hello_line);
       xfree (ctx->okay_line);
       xfree (ctx->cmdtbl);
index 5953f1c..8eb6d82 100644 (file)
@@ -14,9 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * 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 <config.h>
 static int
 do_finish (assuan_context_t ctx)
 {
 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);
     }
     {
       _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;
 }
 
   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
 /* 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)
 {
 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;
   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;
   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
 
   /* 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;
   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);
   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);
     {
       _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);
 
   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));
     {
       _assuan_log_printf ("can't connect to `%s': %s\n",
                           name, strerror (errno));
index 5c46164..c536dba 100644 (file)
@@ -1,5 +1,5 @@
 /* assuan-socket-server.c - Assuan socket based server
 /* 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.
  *
  *
  * 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
  * 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 <config.h>
 
 #include "assuan-defs.h"
 
 
 #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)
 {
 
 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
 
   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)
 {
 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;
 
   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);
     }
     {
       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);
 
   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)
 {
 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);
     }
     {
       _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;
 }
 
   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
 /* 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
 {
   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
 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);
 }
 {
   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
               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;
                                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->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))
     {
 
   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 = 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)
     }
   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;
 }
     *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;
+}
index 5566fde..02a6225 100644 (file)
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * 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 <config.h>
 #include <stdio.h>
+#include <stdlib.h>
 #ifdef HAVE_W32_SYSTEM
 #ifdef HAVE_W32_SYSTEM
+#define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <windows.h>
+#include <wincrypt.h>
 #include <io.h>
 #else
 #include <sys/types.h>
 #include <sys/socket.h>
 #endif
 #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.  */
 #include "assuan-defs.h"
 
 /* Hacks for Slowaris.  */
 # define AF_LOCAL AF_UNIX
 #endif
 
 # 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_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
 int
-_assuan_close (int fd)
+_assuan_close (assuan_fd_t fd)
 {
 #if defined (HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN)
 {
 #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)
   if (rc && WSAGetLastError () == WSAENOTSOCK)
-    rc = CloseHandle (fd);
+    {
+      rc = CloseHandle (fd);
+      if (rc)
+       /* FIXME. */
+       errno = EIO;
+    }
   return rc;
 #else
   return close (fd);
   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)
 {
 _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;
   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
   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
-  struct sockaddr_in myaddr;
-  struct sockaddr_un * unaddr;
-  FILE * fp;
-  int port = 0;
-  
-  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)
-      return -1;
+#ifdef HAVE_W32_SYSTEM
+  if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
+    {
+      struct sockaddr_in myaddr;
+      struct sockaddr_un *unaddr;
+      unsigned short port;
+      char nonce[16];
+      int ret;
+      
+      unaddr = (struct sockaddr_un *)addr;
+      if (read_port_and_nonce (unaddr->sun_path, &port, nonce))
+        return -1;
+      
+      myaddr.sin_family = AF_INET;
+      myaddr.sin_port = htons (port); 
+      myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
   
   
-  myaddr.sin_family = AF_INET;
-  myaddr.sin_port = port; 
-  myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-
-  /* 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;
+      /* 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
 #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;
   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;
       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);
 
 
       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");
+      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;
+        }
+      fp = fdopen (filefd, "wb");
       if (!fp)
       if (!fp)
-        return -1;
-      fprintf (fp, "%d", myaddr.sin_port);
+        { 
+          int save_e = errno;
+          close (filefd);
+          errno = save_e;
+          return -1;
+        }
+
+      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);
 
       fclose (fp);
 
-      /* 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;
-      
       return 0;
     }
       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
 }
 
   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);
+}
index 70ec8cc..02f77a5 100644 (file)
@@ -14,9 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * 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
  */
 
 #ifdef HAVE_CONFIG_H
@@ -72,9 +70,9 @@
 static ssize_t
 uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
 {
 static ssize_t
 uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
 {
+#ifndef HAVE_W32_SYSTEM
   int len = ctx->uds.buffersize;
 
   int len = ctx->uds.buffersize;
 
-#ifndef HAVE_W32_SYSTEM
   if (!ctx->uds.bufferallocated)
     {
       ctx->uds.buffer = xtrymalloc (2048);
   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*/
     }
 
 #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.  */
   /* 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;
   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);
   iovec.iov_len = buflen;
 
   len = _assuan_simple_sendmsg (ctx, &msg);
+
+  return len;
 #else /*HAVE_W32_SYSTEM*/
 #else /*HAVE_W32_SYSTEM*/
-  int len;
-  
-  len = sendto (ctx->outbound.fd, buf, buflen, 0,
-                (struct sockaddr *)&ctx->serveraddr,
-                sizeof (struct sockaddr_in));
+  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*/
 #endif /*HAVE_W32_SYSTEM*/
-  return len;
 }
 
 
 static assuan_error_t
 }
 
 
 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;
 {
 #ifdef USE_DESCRIPTOR_PASSING
   struct msghdr msg;
@@ -243,7 +243,7 @@ uds_sendfd (assuan_context_t ctx, int fd)
 
 
 static assuan_error_t
 
 
 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;
 {
 #ifdef USE_DESCRIPTOR_PASSING
   int i;
index d12277f..cefefcb 100644 (file)
@@ -14,9 +14,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * 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 <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;
 
 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),
 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;
 }
 
   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)
 {
 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;
   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;
   switch (flag)
     {
     case ASSUAN_NO_WAITPID: return ctx->flags.no_waitpid;
+    case ASSUAN_CONFIDENTIAL: return ctx->confidential;
     }
   return 0;
 }
 
     }
   return 0;
 }
 
-
index 6df0166..0e5c741 100644 (file)
@@ -1,5 +1,6 @@
 /* assuan.h - Definitions for the Assuan IPC library
 /* 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.
  *
  *
  * 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
  * 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
  */
 
 #ifndef ASSUAN_H
 #include <stdio.h>
 #include <sys/types.h>
 #include <unistd.h>
 #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:
 
      #define _ASSUAN_EXT_SYM_PREFIX _foo_
    
 
 /* To use this file with libraries the following macros are useful:
 
      #define _ASSUAN_EXT_SYM_PREFIX _foo_
    
-     This prefixes all external symbols with "_foo_".
+       This prefixes all external symbols with "_foo_".
 
      #define _ASSUAN_ONLY_GPG_ERRORS
 
 
      #define _ASSUAN_ONLY_GPG_ERRORS
 
-     If this is defined all old-style Assuan error codes are made
-     inactive as well as other dereacted stuff.
+       If this is defined all old-style Assuan error codes are made
+       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:
 
    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);
 
 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
 #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)
   _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)
 #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_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)
 #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_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)
 #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_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)
 
 /* 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)
   _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)
 #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_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 _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_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*/
 
 
 #endif /*_ASSUAN_EXT_SYM_PREFIX*/
 
 
@@ -350,7 +374,8 @@ typedef enum
 
 #else  /*!_ASSUAN_ONLY_GPG_ERRORS*/
 
 
 #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*/
 
 
 #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. */
        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;
 
   } 
 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*/
 
 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,
 /*-- 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 (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 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);
 
 
 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
 /* 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,
 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);
 
 /*-- 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);
 
 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 --*/
 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 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);
                                    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,
 
 /*-- 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);
 /*-- 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
 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,
 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,
                  void *data_cb_arg,
-                 int (*inquire_cb)(void*, const char *),
+                 assuan_error_t (*inquire_cb)(void*, const char *),
                  void *inquire_cb_arg,
                  void *inquire_cb_arg,
-                 int (*status_cb)(void*, const char *),
+                 assuan_error_t (*status_cb)(void*, const char *),
                  void *status_cb_arg);
 
 
                  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 (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);
 /*-- 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")).  */
 /* 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*) );
 
 /*-- 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);
 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 --*/
 
 
 /*-- 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
 /* 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);
 
    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
 #ifdef __cplusplus
 }
 #endif
index 28451f6..79ac23b 100755 (executable)
@@ -31,6 +31,7 @@ cat <<EOF
 
 #undef _ASSUAN_IN_LIBASSUAN /* undef to get all error codes. */
 #include "assuan.h"
 
 #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. */
 
 /* 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:
         {
         case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/  break;
         case EAGAIN:
-          if (errno > 0 && errno < 4096)
-            {
-              n = (EAGAIN | (1 << 15)); 
-              break;
-            }
+          n = (6 | (1 << 15));
+          break;
         default: n = 270;  /*GPG_ERR_ASS_READ_ERROR*/ break;
         }
       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:
         {
         case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/  break;
         case EAGAIN:
-          if (errno > 0 && errno < 4096)
-            {
-              n = (EAGAIN | (1 << 15)); 
-              break;
-            }
+          n = (6 | (1 << 15));
+          break;
         default: n = 271;  /*GPG_ERR_ASS_WRITE_ERROR*/ break;
         }
       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:
           n = 16381; /*GPG_ERR_MISSING_ERRNO*/
           break;
         case ENOMEM:
-          if (errno > 0 && errno < 4096)
-            {
-              n = (ENOMEM | (1 << 15));
-              break;
-            }
+          n = (86 | (1 << 15));
+          break;
         default:  
           n = 16382; /*GPG_ERR_UNKNOWN_ERRNO*/
           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 
 /**
  * assuan_strerror:
  * @err:  Error code 
index bf1ca18..d529653 100644 (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");
         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);
 #endif /* HAVE_ASSUAN_H*/
     }
   UNLOCK (debug_lock);
index 879e2f3..03d9e9a 100644 (file)
@@ -56,7 +56,6 @@ do_subsystem_inits (void)
 
   _gpgme_sema_subsystem_init ();
 #ifdef HAVE_ASSUAN_H
 
   _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 ();
   assuan_set_assuan_err_source (GPG_ERR_SOURCE_GPGME);
 #endif /*HAVE_ASSUAN_H*/
   _gpgme_debug_subsystem_init ();